From de4f3fe8327ad2058c0f54cea9f252fd555d2298 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:52:54 +0800 Subject: [PATCH] 1.21.3 (#382) --------- Co-authored-by: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> --- .editorconfig | 12 +- README.md | 4 +- README_cn.md | 4 +- build.gradle.kts | 2 +- gradle.properties | 9 +- gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 9 +- gradlew.bat | 4 +- patches/api/0001-Leaves-Server-Config.patch | 4 +- patches/api/0003-Add-fakeplayer-api.patch | 12 +- ...Hide-irrelevant-compilation-warnings.patch | 6 +- patches/api/0006-SIMD-support.patch | 6 +- patches/api/0007-Delete-Timings.patch | 33 +- .../api/0008-Force-peaceful-mode-switch.patch | 4 +- patches/api/0009-Replay-Mod-API.patch | 8 +- patches/api/0010-Bytebuf-API.patch | 31 +- .../0020-Optimize-entity-coordinate-key.patch | 20 - ...turn-optimization-for-target-finding.patch | 0 ...ve-ThreadUnsafeRandom-Initialization.patch | 0 ...hread-unsafe-random-for-mob-spawning.patch | 0 ...reams-and-iterators-from-range-check.patch | 0 ...ce-entity-fluid-lookups-if-no-fluids.patch | 218 --- ...0041-Improve-fluid-direction-caching.patch | 0 .../0077-Cache-BlockStatePairKey-hash.patch | 0 ...078-Cache-CubeVoxelShape-shape-array.patch | 41 - ...099-Disable-moved-wrongly-threshold.patch} | 10 +- ...timize-random-calls-in-chunk-ticking.patch | 0 patches/server/0001-Build-changes.patch | 92 +- patches/server/0003-Delete-Timings.patch | 1722 +---------------- patches/server/0004-Leaves-Server-Utils.patch | 36 +- .../0005-Update-version-fetcher-repo.patch | 6 +- ...006-Leaves-Server-Config-And-Command.patch | 1647 ++++++++-------- .../server/0007-Leaves-Protocol-Core.patch | 47 +- .../0008-Fix-trading-with-the-void.patch | 4 +- ...nowball-and-egg-can-knockback-player.patch | 10 +- patches/server/0010-Fakeplayer-support.patch | 336 ++-- ...hears-in-dispenser-can-unlimited-use.patch | 6 +- .../server/0012-Redstone-Shears-Wrench.patch | 10 +- ...Add-isShrink-to-EntityResurrectEvent.patch | 8 +- ...-Budding-Amethyst-can-push-by-piston.patch | 22 +- .../0015-Spectator-dont-get-Advancement.patch | 4 +- ...ick-can-change-ArmorStand-arm-status.patch | 10 +- .../server/0017-Configurable-MC-59471.patch | 42 + patches/server/0017-Fix-tripwire-update.patch | 30 - patches/server/0018-No-chat-sign.patch | 40 +- ...019-Dont-send-useless-entity-packets.patch | 26 +- .../server/0020-Optimize-suffocation.patch | 20 +- ...check-for-spooky-season-once-an-hour.patch | 6 +- ...22-Config-to-disable-method-profiler.patch | 32 + ...23-Config-to-disable-method-profiler.patch | 39 - ...al-selector-during-inactive-ticking.patch} | 6 +- ...h => 0024-Reduce-entity-allocations.patch} | 4 +- ...25-Remove-lambda-from-ticking-guard.patch} | 6 +- ...e-iterators-from-inventory-contains.patch} | 14 +- ...Cache-climbing-check-for-activation.patch} | 8 +- ...> 0028-Reduce-chunk-loading-lookups.patch} | 12 +- ...29-InstantBlockUpdater-Reintroduced.patch} | 6 +- ...dom-flatten-triangular-distribution.patch} | 6 +- ...rotocol.patch => 0031-BBOR-Protocol.patch} | 30 +- ...col.patch => 0032-PCA-sync-protocol.patch} | 88 +- ...rotocol.patch => 0033-Jade-Protocol.patch} | 65 +- ...lternative-block-placement-Protocol.patch} | 58 +- ...ch => 0035-Player-operation-limiter.patch} | 20 +- ...ytra.patch => 0036-Renewable-Elytra.patch} | 14 +- ...atch => 0037-Stackable-ShulkerBoxes.patch} | 105 +- ... => 0038-MC-Technical-Survival-Mode.patch} | 66 +- ...ch => 0039-Return-nether-portal-fix.patch} | 26 +- patches/server/0040-Appleskin-Protocol.patch | 139 ++ ...ol.patch => 0041-Xaero-Map-Protocol.patch} | 12 +- ...0042-Leaves-Extra-Yggdrasil-Service.patch} | 16 +- ...h => 0043-Use-vanilla-random-config.patch} | 28 +- patches/server/0044-Appleskin-Protocol.patch | 118 -- ...> 0044-Fix-update-suppression-crash.patch} | 45 +- ...st.patch => 0045-Bedrock-break-list.patch} | 22 +- ....patch => 0046-Fix-trapdoor-feature.patch} | 6 +- ...-distance-check-for-UseItemOnPacket.patch} | 6 +- .../0048-No-feather-falling-trample.patch | 24 + ...l.patch => 0049-Syncmatica-Protocol.patch} | 18 +- ...h => 0050-Shared-villager-discounts.patch} | 4 +- ...one-wire-dont-connect-if-on-trapdoor.patch | 28 + ...-Disable-check-out-of-order-command.patch} | 4 +- .../0052-No-feather-falling-trample.patch | 24 - ...=> 0053-Despawn-enderman-with-block.patch} | 6 +- ...patch => 0054-Leaves-carpet-support.patch} | 6 +- ....patch => 0055-Creative-fly-no-clip.patch} | 26 +- ...one-wire-dont-connect-if-on-trapdoor.patch | 28 - ...ch => 0056-Optimized-dragon-respawn.patch} | 8 +- ...ers.patch => 0057-Shave-snow-layers.patch} | 6 +- ...58-Elytra-aeronautics-no-chunk-load.patch} | 46 +- ...dds.patch => 0059-Cache-ignite-odds.patch} | 4 +- patches/server/0060-Lava-riptide.patch | 28 + ...tch => 0061-No-block-update-command.patch} | 56 +- ...062-Raider-die-skip-self-raid-check.patch} | 6 +- ... => 0063-Container-open-passthrough.patch} | 22 +- ...-support.patch => 0064-SIMD-support.patch} | 6 +- ...ont-respond-ping-before-start-fully.patch} | 4 +- patches/server/0065-Lava-riptide.patch | 28 - ... => 0066-Faster-chunk-serialization.patch} | 26 +- ...067-Cache-world-generator-sea-level.patch} | 4 +- ...col.patch => 0068-Bladeren-Protocol.patch} | 8 +- ...Skip-secondary-POI-sensor-if-absent.patch} | 4 +- ...=> 0070-Bladeren-mspt-sync-protocol.patch} | 10 +- ...> 0071-Store-mob-counts-in-an-array.patch} | 6 +- ...h => 0072-Optimize-noise-generation.patch} | 16 +- ....patch => 0073-Disable-packet-limit.patch} | 6 +- ...ch => 0074-Reduce-array-allocations.patch} | 206 +- ...atch => 0075-Optimize-sun-burn-tick.patch} | 12 +- ...-Optional-allocation-in-EntityBased.patch} | 4 +- ...ignableFrom-call-in-ClassInstanceMu.patch} | 0 ...ch => 0078-Optimized-CubePointRange.patch} | 6 +- ...k-frozen-ticks-before-landing-block.patch} | 8 +- ...kip-entity-move-if-movement-is-zero.patch} | 12 +- ...1-Skip-cloning-advancement-criteria.patch} | 4 +- ...82-Fix-villagers-dont-release-memory.patch | 43 + ...h => 0083-Avoid-anvil-too-expensive.patch} | 8 +- ...-fix.patch => 0084-Bow-infinity-fix.patch} | 6 +- ...ants.patch => 0085-Zero-tick-plants.patch} | 24 +- ...pdater.patch => 0086-Leaves-Updater.patch} | 10 +- ... => 0087-Force-peaceful-mode-switch.patch} | 97 +- ...od-API.patch => 0088-Replay-Mod-API.patch} | 85 +- ...89-Fix-villagers-dont-release-memory.patch | 31 - ...aves-I18n.patch => 0089-Leaves-I18n.patch} | 35 +- ...raft-hopper-not-work-without-player.patch} | 4 +- ...G-Fishing.patch => 0091-RNG-Fishing.patch} | 6 +- ...r.patch => 0092-Wool-Hopper-Counter.patch} | 340 ++-- ...patch => 0093-Leaves-Reload-Command.patch} | 0 ...=> 0094-Spider-jockeys-drop-gapples.patch} | 14 +- ...rade.patch => 0095-Force-Void-Trade.patch} | 22 +- ...=> 0096-Villager-infinite-discounts.patch} | 0 ...atch => 0097-CCE-update-suppression.patch} | 21 +- ...8-Disable-offline-warn-if-use-proxy.patch} | 4 +- ...r-stand-cant-kill-by-mob-projectile.patch} | 16 +- ...atch => 0100-Make-Item-tick-vanilla.patch} | 6 +- ...atch => 0101-Copper-Bulb-1-gt-delay.patch} | 14 +- ...ay.patch => 0102-Crafter-1-gt-delay.patch} | 10 +- ...h => 0103-Linear-region-file-format.patch} | 220 ++- ...e.patch => 0104-No-TNT-place-update.patch} | 6 +- ...tocol.patch => 0105-Servux-Protocol.patch} | 94 +- ...ed-hopper-no-longer-send-NC-updates.patch} | 4 +- ...e.patch => 0107-Renewable-deepslate.patch} | 12 +- ...ges.patch => 0108-Renewable-sponges.patch} | 8 +- ...coral.patch => 0109-Renewable-coral.patch} | 24 +- ...st-resume.patch => 0110-Fast-resume.patch} | 20 +- ...hopper.patch => 0111-Vanilla-hopper.patch} | 6 +- ...tch => 0112-Force-minecraft-command.patch} | 4 +- ...-Fix-falling-block-s-block-location.patch} | 4 +- ...tebuf-API.patch => 0114-Bytebuf-API.patch} | 94 +- ... 0115-Allow-grindstone-overstacking.patch} | 10 +- patches/server/0116-Configurable-MC-67.patch | 18 + ...le-end-gateway-portal-entity-ticking.patch | 22 + ...able-crystal-portal-proximity-check.patch} | 10 +- ...ble-LivingEntity-aiStep-alive-check.patch} | 6 +- ...lugins.patch => 0120-Leaves-plugins.patch} | 4 +- ...atch => 0121-Fix-fortress-mob-spawn.patch} | 4 +- ...22-Fix-FallingBlockEntity-Duplicate.patch} | 6 +- ...h => 0123-Old-BlockEntity-behaviour.patch} | 39 +- patches/server/0124-Configurable-MC-67.patch | 19 - patches/server/0124-Revert-raid-changes.patch | 98 + ...5-Allow-anvil-destroy-item-entities.patch} | 6 +- ...le-end-gateway-portal-entity-ticking.patch | 19 - ...-Collision-Behavior-for-Block-Shape.patch} | 10 +- ...tch => 0127-Disable-vault-blacklist.patch} | 10 +- patches/server/0132-Revert-raid-changes.patch | 113 -- ...e-aging-cache-for-biome-temperatures.patch | 0 .../server/0058-Spawn-ignore-lc.patch} | 12 +- ...gible-planar-movement-multiplication.patch | 0 167 files changed, 3015 insertions(+), 4957 deletions(-) delete mode 100644 patches/removed/server/0020-Optimize-entity-coordinate-key.patch rename patches/{ => removed}/server/0022-Early-return-optimization-for-target-finding.patch (100%) rename patches/{unapplied => removed}/server/0024-Move-ThreadUnsafeRandom-Initialization.patch (100%) rename patches/{unapplied => removed}/server/0026-Use-thread-unsafe-random-for-mob-spawning.patch (100%) rename patches/{ => removed}/server/0028-Remove-streams-and-iterators-from-range-check.patch (100%) delete mode 100644 patches/removed/server/0032-Reduce-entity-fluid-lookups-if-no-fluids.patch rename patches/{ => removed}/server/0041-Improve-fluid-direction-caching.patch (100%) rename patches/{ => removed}/server/0077-Cache-BlockStatePairKey-hash.patch (100%) delete mode 100644 patches/removed/server/0078-Cache-CubeVoxelShape-shape-array.patch rename patches/{server/0106-Disable-moved-wrongly-threshold.patch => removed/server/0099-Disable-moved-wrongly-threshold.patch} (92%) rename patches/{unapplied => removed}/server/0131-Optimize-random-calls-in-chunk-ticking.patch (100%) create mode 100644 patches/server/0017-Configurable-MC-59471.patch delete mode 100644 patches/server/0017-Fix-tripwire-update.patch create mode 100644 patches/server/0022-Config-to-disable-method-profiler.patch delete mode 100644 patches/server/0023-Config-to-disable-method-profiler.patch rename patches/server/{0024-Throttle-goal-selector-during-inactive-ticking.patch => 0023-Throttle-goal-selector-during-inactive-ticking.patch} (79%) rename patches/server/{0025-Reduce-entity-allocations.patch => 0024-Reduce-entity-allocations.patch} (92%) rename patches/server/{0026-Remove-lambda-from-ticking-guard.patch => 0025-Remove-lambda-from-ticking-guard.patch} (90%) rename patches/server/{0027-Remove-iterators-from-inventory-contains.patch => 0026-Remove-iterators-from-inventory-contains.patch} (89%) rename patches/server/{0029-Cache-climbing-check-for-activation.patch => 0027-Cache-climbing-check-for-activation.patch} (85%) rename patches/server/{0031-Reduce-chunk-loading-lookups.patch => 0028-Reduce-chunk-loading-lookups.patch} (77%) rename patches/server/{0032-InstantBlockUpdater-Reintroduced.patch => 0029-InstantBlockUpdater-Reintroduced.patch} (82%) rename patches/server/{0033-Random-flatten-triangular-distribution.patch => 0030-Random-flatten-triangular-distribution.patch} (82%) rename patches/server/{0034-BBOR-Protocol.patch => 0031-BBOR-Protocol.patch} (91%) rename patches/server/{0035-PCA-sync-protocol.patch => 0032-PCA-sync-protocol.patch} (90%) rename patches/server/{0036-Jade-Protocol.patch => 0033-Jade-Protocol.patch} (98%) rename patches/server/{0037-Alternative-block-placement-Protocol.patch => 0034-Alternative-block-placement-Protocol.patch} (90%) rename patches/server/{0038-Player-operation-limiter.patch => 0035-Player-operation-limiter.patch} (87%) rename patches/server/{0039-Renewable-Elytra.patch => 0036-Renewable-Elytra.patch} (67%) rename patches/server/{0040-Stackable-ShulkerBoxes.patch => 0037-Stackable-ShulkerBoxes.patch} (85%) rename patches/server/{0042-MC-Technical-Survival-Mode.patch => 0038-MC-Technical-Survival-Mode.patch} (56%) rename patches/server/{0043-Return-nether-portal-fix.patch => 0039-Return-nether-portal-fix.patch} (89%) create mode 100644 patches/server/0040-Appleskin-Protocol.patch rename patches/server/{0045-Xaero-Map-Protocol.patch => 0041-Xaero-Map-Protocol.patch} (86%) rename patches/server/{0046-Leaves-Extra-Yggdrasil-Service.patch => 0042-Leaves-Extra-Yggdrasil-Service.patch} (93%) rename patches/server/{0047-Use-vanilla-random-config.patch => 0043-Use-vanilla-random-config.patch} (70%) delete mode 100644 patches/server/0044-Appleskin-Protocol.patch rename patches/server/{0048-Fix-update-suppression-crash.patch => 0044-Fix-update-suppression-crash.patch} (77%) rename patches/server/{0049-Bedrock-break-list.patch => 0045-Bedrock-break-list.patch} (92%) rename patches/server/{0050-Fix-trapdoor-feature.patch => 0046-Fix-trapdoor-feature.patch} (86%) rename patches/server/{0051-Disable-distance-check-for-UseItemOnPacket.patch => 0047-Disable-distance-check-for-UseItemOnPacket.patch} (73%) create mode 100644 patches/server/0048-No-feather-falling-trample.patch rename patches/server/{0053-Syncmatica-Protocol.patch => 0049-Syncmatica-Protocol.patch} (99%) rename patches/server/{0054-Shared-villager-discounts.patch => 0050-Shared-villager-discounts.patch} (86%) create mode 100644 patches/server/0051-Redstone-wire-dont-connect-if-on-trapdoor.patch rename patches/server/{0056-Disable-check-out-of-order-command.patch => 0052-Disable-check-out-of-order-command.patch} (83%) delete mode 100644 patches/server/0052-No-feather-falling-trample.patch rename patches/server/{0057-Despawn-enderman-with-block.patch => 0053-Despawn-enderman-with-block.patch} (73%) rename patches/server/{0058-Leaves-carpet-support.patch => 0054-Leaves-carpet-support.patch} (95%) rename patches/server/{0059-Creative-fly-no-clip.patch => 0055-Creative-fly-no-clip.patch} (86%) delete mode 100644 patches/server/0055-Redstone-wire-dont-connect-if-on-trapdoor.patch rename patches/server/{0060-Optimized-dragon-respawn.patch => 0056-Optimized-dragon-respawn.patch} (96%) rename patches/server/{0061-Shave-snow-layers.patch => 0057-Shave-snow-layers.patch} (88%) rename patches/server/{0063-Elytra-aeronautics-no-chunk-load.patch => 0058-Elytra-aeronautics-no-chunk-load.patch} (75%) rename patches/server/{0064-Cache-ignite-odds.patch => 0059-Cache-ignite-odds.patch} (94%) create mode 100644 patches/server/0060-Lava-riptide.patch rename patches/server/{0066-No-block-update-command.patch => 0061-No-block-update-command.patch} (73%) rename patches/server/{0067-Raider-die-skip-self-raid-check.patch => 0062-Raider-die-skip-self-raid-check.patch} (69%) rename patches/server/{0068-Container-open-passthrough.patch => 0063-Container-open-passthrough.patch} (78%) rename patches/server/{0069-SIMD-support.patch => 0064-SIMD-support.patch} (79%) rename patches/server/{0070-Dont-respond-ping-before-start-fully.patch => 0065-Dont-respond-ping-before-start-fully.patch} (83%) delete mode 100644 patches/server/0065-Lava-riptide.patch rename patches/server/{0071-Faster-chunk-serialization.patch => 0066-Faster-chunk-serialization.patch} (94%) rename patches/server/{0072-Cache-world-generator-sea-level.patch => 0067-Cache-world-generator-sea-level.patch} (92%) rename patches/server/{0073-Bladeren-Protocol.patch => 0068-Bladeren-Protocol.patch} (95%) rename patches/server/{0074-Skip-secondary-POI-sensor-if-absent.patch => 0069-Skip-secondary-POI-sensor-if-absent.patch} (87%) rename patches/server/{0075-Bladeren-mspt-sync-protocol.patch => 0070-Bladeren-mspt-sync-protocol.patch} (88%) rename patches/server/{0076-Store-mob-counts-in-an-array.patch => 0071-Store-mob-counts-in-an-array.patch} (87%) rename patches/server/{0078-Optimize-noise-generation.patch => 0072-Optimize-noise-generation.patch} (94%) rename patches/server/{0079-Disable-packet-limit.patch => 0073-Disable-packet-limit.patch} (68%) rename patches/server/{0080-Reduce-array-allocations.patch => 0074-Reduce-array-allocations.patch} (67%) rename patches/server/{0081-Optimize-sun-burn-tick.patch => 0075-Optimize-sun-burn-tick.patch} (89%) rename patches/server/{0082-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch => 0076-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch} (92%) rename patches/server/{0083-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch => 0077-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch} (100%) rename patches/server/{0084-Optimized-CubePointRange.patch => 0078-Optimized-CubePointRange.patch} (83%) rename patches/server/{0085-Check-frozen-ticks-before-landing-block.patch => 0079-Check-frozen-ticks-before-landing-block.patch} (63%) rename patches/server/{0086-Skip-entity-move-if-movement-is-zero.patch => 0080-Skip-entity-move-if-movement-is-zero.patch} (80%) rename patches/server/{0087-Skip-cloning-advancement-criteria.patch => 0081-Skip-cloning-advancement-criteria.patch} (76%) create mode 100644 patches/server/0082-Fix-villagers-dont-release-memory.patch rename patches/server/{0090-Avoid-anvil-too-expensive.patch => 0083-Avoid-anvil-too-expensive.patch} (63%) rename patches/server/{0091-Bow-infinity-fix.patch => 0084-Bow-infinity-fix.patch} (64%) rename patches/server/{0092-Zero-tick-plants.patch => 0085-Zero-tick-plants.patch} (79%) rename patches/server/{0093-Leaves-Updater.patch => 0086-Leaves-Updater.patch} (97%) rename patches/server/{0094-Force-peaceful-mode-switch.patch => 0087-Force-peaceful-mode-switch.patch} (71%) rename patches/server/{0095-Replay-Mod-API.patch => 0088-Replay-Mod-API.patch} (95%) delete mode 100644 patches/server/0089-Fix-villagers-dont-release-memory.patch rename patches/server/{0096-Leaves-I18n.patch => 0089-Leaves-I18n.patch} (99%) rename patches/server/{0097-Fix-minecraft-hopper-not-work-without-player.patch => 0090-Fix-minecraft-hopper-not-work-without-player.patch} (84%) rename patches/server/{0098-RNG-Fishing.patch => 0091-RNG-Fishing.patch} (81%) rename patches/server/{0099-Wool-Hopper-Counter.patch => 0092-Wool-Hopper-Counter.patch} (64%) rename patches/server/{0100-Leaves-Reload-Command.patch => 0093-Leaves-Reload-Command.patch} (100%) rename patches/server/{0101-Spider-jockeys-drop-gapples.patch => 0094-Spider-jockeys-drop-gapples.patch} (58%) rename patches/server/{0102-Force-Void-Trade.patch => 0095-Force-Void-Trade.patch} (87%) rename patches/server/{0103-Villager-infinite-discounts.patch => 0096-Villager-infinite-discounts.patch} (100%) rename patches/server/{0104-CCE-update-suppression.patch => 0097-CCE-update-suppression.patch} (60%) rename patches/server/{0105-Disable-offline-warn-if-use-proxy.patch => 0098-Disable-offline-warn-if-use-proxy.patch} (89%) rename patches/server/{0107-Armor-stand-cant-kill-by-mob-projectile.patch => 0099-Armor-stand-cant-kill-by-mob-projectile.patch} (61%) rename patches/server/{0108-Make-Item-tick-vanilla.patch => 0100-Make-Item-tick-vanilla.patch} (83%) rename patches/server/{0109-Copper-Bulb-1-gt-delay.patch => 0101-Copper-Bulb-1-gt-delay.patch} (78%) rename patches/server/{0110-Crafter-1-gt-delay.patch => 0102-Crafter-1-gt-delay.patch} (75%) rename patches/server/{0111-Linear-region-file-format.patch => 0103-Linear-region-file-format.patch} (78%) rename patches/server/{0112-No-TNT-place-update.patch => 0104-No-TNT-place-update.patch} (73%) rename patches/server/{0113-Servux-Protocol.patch => 0105-Servux-Protocol.patch} (90%) rename patches/server/{0114-Placing-locked-hopper-no-longer-send-NC-updates.patch => 0106-Placing-locked-hopper-no-longer-send-NC-updates.patch} (88%) rename patches/server/{0115-Renewable-deepslate.patch => 0107-Renewable-deepslate.patch} (70%) rename patches/server/{0116-Renewable-sponges.patch => 0108-Renewable-sponges.patch} (80%) rename patches/server/{0117-Renewable-coral.patch => 0109-Renewable-coral.patch} (85%) rename patches/server/{0118-Fast-resume.patch => 0110-Fast-resume.patch} (93%) rename patches/server/{0119-Vanilla-hopper.patch => 0111-Vanilla-hopper.patch} (94%) rename patches/server/{0120-Force-minecraft-command.patch => 0112-Force-minecraft-command.patch} (81%) rename patches/server/{0121-Fix-falling-block-s-block-location.patch => 0113-Fix-falling-block-s-block-location.patch} (87%) rename patches/server/{0122-Bytebuf-API.patch => 0114-Bytebuf-API.patch} (87%) rename patches/server/{0123-Allow-grindstone-overstacking.patch => 0115-Allow-grindstone-overstacking.patch} (64%) create mode 100644 patches/server/0116-Configurable-MC-67.patch create mode 100644 patches/server/0117-Disable-end-gateway-portal-entity-ticking.patch rename patches/server/{0126-Disable-crystal-portal-proximity-check.patch => 0118-Disable-crystal-portal-proximity-check.patch} (90%) rename patches/server/{0127-Can-disable-LivingEntity-aiStep-alive-check.patch => 0119-Can-disable-LivingEntity-aiStep-alive-check.patch} (67%) rename patches/server/{0128-Leaves-plugins.patch => 0120-Leaves-plugins.patch} (99%) rename patches/server/{0129-Fix-fortress-mob-spawn.patch => 0121-Fix-fortress-mob-spawn.patch} (81%) rename patches/server/{0130-Fix-FallingBlockEntity-Duplicate.patch => 0122-Fix-FallingBlockEntity-Duplicate.patch} (81%) rename patches/server/{0131-Old-BlockEntity-behaviour.patch => 0123-Old-BlockEntity-behaviour.patch} (59%) delete mode 100644 patches/server/0124-Configurable-MC-67.patch create mode 100644 patches/server/0124-Revert-raid-changes.patch rename patches/server/{0133-Allow-anvil-destroy-item-entities.patch => 0125-Allow-anvil-destroy-item-entities.patch} (69%) delete mode 100644 patches/server/0125-Disable-end-gateway-portal-entity-ticking.patch rename patches/server/{0134-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch => 0126-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch} (78%) rename patches/server/{0135-Disable-vault-blacklist.patch => 0127-Disable-vault-blacklist.patch} (74%) delete mode 100644 patches/server/0132-Revert-raid-changes.patch rename patches/{ => unapplied}/server/0030-Use-aging-cache-for-biome-temperatures.patch (100%) rename patches/{server/0062-Spawn-ignore-lc.patch => unapplied/server/0058-Spawn-ignore-lc.patch} (78%) rename patches/{ => unapplied}/server/0088-Skip-negligible-planar-movement-multiplication.patch (100%) diff --git a/.editorconfig b/.editorconfig index c605f877..227a561f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,5 @@ +root = true + [*] charset = utf-8 end_of_line = lf @@ -54,6 +56,7 @@ ij_java_blank_lines_after_package = 1 ij_java_blank_lines_around_class = 1 ij_java_blank_lines_around_field = 0 ij_java_blank_lines_around_field_in_interface = 0 +ij_java_blank_lines_around_field_with_annotations = 0 ij_java_blank_lines_around_initializer = 1 ij_java_blank_lines_around_method = 1 ij_java_blank_lines_around_method_in_interface = 1 @@ -131,6 +134,7 @@ ij_java_for_statement_right_paren_on_new_line = false ij_java_for_statement_wrap = off ij_java_generate_final_locals = false ij_java_generate_final_parameters = false +ij_java_generate_use_type_annotation_before_type = true ij_java_if_brace_force = never ij_java_imports_layout = *, |, javax.**, java.**, |, $* ij_java_indent_case_from_switch = true @@ -276,6 +280,7 @@ ij_java_spaces_around_relational_operators = true ij_java_spaces_around_shift_operators = true ij_java_spaces_around_type_bounds_in_type_parameters = true ij_java_spaces_around_unary_operator = false +ij_java_spaces_inside_block_braces_when_body_is_present = false ij_java_spaces_within_angle_brackets = false ij_java_spaces_within_annotation_parentheses = false ij_java_spaces_within_array_initializer_braces = false @@ -307,7 +312,7 @@ ij_java_test_name_suffix = Test ij_java_throws_keyword_wrap = off ij_java_throws_list_wrap = off ij_java_use_external_annotations = false -ij_java_use_fq_class_names = false +ij_java_use_fq_class_names = true ij_java_use_relative_indents = false ij_java_use_single_class_imports = true ij_java_variable_annotation_wrap = off @@ -393,6 +398,7 @@ ij_kotlin_finally_on_new_line = false ij_kotlin_if_rparen_on_new_line = true ij_kotlin_import_nested_classes = false ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, ^ +ij_kotlin_indent_before_arrow_on_new_line = true ij_kotlin_insert_whitespaces_in_simple_one_line_method = true ij_kotlin_keep_blank_lines_before_right_brace = 2 ij_kotlin_keep_blank_lines_in_code = 2 @@ -428,6 +434,7 @@ ij_kotlin_space_before_when_parentheses = true ij_kotlin_space_before_while_parentheses = true ij_kotlin_spaces_around_additive_operators = true ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_elvis = true ij_kotlin_spaces_around_equality_operators = true ij_kotlin_spaces_around_function_type_arrow = true ij_kotlin_spaces_around_logical_operators = true @@ -521,6 +528,9 @@ ij_yaml_block_mapping_on_new_line = false ij_yaml_indent_sequence_value = true ij_yaml_keep_indents_on_empty_lines = false ij_yaml_keep_line_breaks = true +ij_yaml_line_comment_add_space = false +ij_yaml_line_comment_add_space_on_reformat = false +ij_yaml_line_comment_at_first_column = true ij_yaml_sequence_on_new_line = false ij_yaml_space_before_colon = false ij_yaml_spaces_within_braces = true diff --git a/README.md b/README.md index 8cd6bb30..6d2e3e05 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ maven { } dependencies { - compileOnly("org.leavesmc.leaves:leaves-api:1.21.1-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves-api:1.21.3-R0.1-SNAPSHOT") } ``` @@ -40,7 +40,7 @@ Each time you want to update your dependency, you must re-build Leaves. Leaves-Server: ```kotlin dependencies { - compileOnly("org.leavesmc.leaves:leaves:1.21.1-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves:1.21.3-R0.1-SNAPSHOT") } ``` diff --git a/README_cn.md b/README_cn.md index 386918bd..c9fba87e 100644 --- a/README_cn.md +++ b/README_cn.md @@ -30,7 +30,7 @@ maven { } dependencies { - compileOnly("org.leavesmc.leaves:leaves-api:1.21.1-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves-api:1.21.3-R0.1-SNAPSHOT") } ``` @@ -39,7 +39,7 @@ dependencies { Leaves-Server: ```kotlin dependencies { - compileOnly("org.leavesmc.leaves:leaves:1.21.1-R0.1-SNAPSHOT") + compileOnly("org.leavesmc.leaves:leaves:1.21.3-R0.1-SNAPSHOT") } ``` diff --git a/build.gradle.kts b/build.gradle.kts index 69d35959..e5f66e26 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { java `maven-publish` - id("org.leavesmc.leavesweight.patcher") version "1.0.0-SNAPSHOT" + id("org.leavesmc.leavesweight.patcher") version "1.0.1-SNAPSHOT" } allprojects { diff --git a/gradle.properties b/gradle.properties index d1da3a8d..f38476f5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,8 @@ group=org.leavesmc.leaves -version=1.21.1-R0.1-SNAPSHOT -mcVersion=1.21.1 -paperRef=84281ceeefb9d294758a9a292ba6c01da40e8409 -preVersion=false -updatingMinecraft=false +version=1.21.3-R0.1-SNAPSHOT +mcVersion=1.21.3 +paperRef=27e4ddcd067d4825eb01cb05d6975c46252eeafa +preVersion=true org.gradle.jvmargs=-Xmx2G org.gradle.caching=true org.gradle.parallel=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch literal 43583 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 yu?e%!_ptzGB|8GrCfu%p?(_ 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 GZ~q4|mN%#X literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 20db9ad5..5c40527d 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.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 31042a67..f5feea6d 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 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -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 @@ -246,4 +249,4 @@ eval "set -- $( tr '\n' ' ' )" '"$@"' -exec "$JAVACMD" "$@" \ No newline at end of file +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 0faad1ae..9d21a218 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 ########################################################################## @@ -89,4 +91,4 @@ exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal -:omega \ No newline at end of file +:omega diff --git a/patches/api/0001-Leaves-Server-Config.patch b/patches/api/0001-Leaves-Server-Config.patch index 597df93d..c69a7992 100644 --- a/patches/api/0001-Leaves-Server-Config.patch +++ b/patches/api/0001-Leaves-Server-Config.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Server Config diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 6246251caf2c6f025c824b8e7a944b8d48751fa1..80949894308e597676745e312474fe0c9672a23e 100644 +index 0b78564256ebc647ebac402e549d86ab6e307c8d..cbe69a0267981173fe8f7d715764d982bd9dcc8d 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2264,6 +2264,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2282,6 +2282,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi throw new UnsupportedOperationException("Not supported yet."); } // Paper end diff --git a/patches/api/0003-Add-fakeplayer-api.patch b/patches/api/0003-Add-fakeplayer-api.patch index 9e9e1386..69a2ab0e 100644 --- a/patches/api/0003-Add-fakeplayer-api.patch +++ b/patches/api/0003-Add-fakeplayer-api.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add fakeplayer api diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index e20e4239a5a1f952e1c70e899549989d5e42f73c..5f6078bc80e20c9482a96d2bf1095bb32fbfc28c 100644 +index 5ce98e09e9bfcae45896401c69578aa879222893..cb7e06ad207239a5626fc475c46d991fabb48293 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2917,6 +2917,17 @@ public final class Bukkit { +@@ -2964,6 +2964,17 @@ public final class Bukkit { } // Paper end - Folia region threading API @@ -27,7 +27,7 @@ index e20e4239a5a1f952e1c70e899549989d5e42f73c..5f6078bc80e20c9482a96d2bf1095bb3 public static Server.Spigot spigot() { return server.spigot(); diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 80949894308e597676745e312474fe0c9672a23e..133ae299ba12e0da9c5fa252a06bbf4f2b7b9016 100644 +index 0bae85d3489b628d2a2542f3c7b6f91f4a7c4af5..967bb7ba476f494ac8bfebb599f260017176f3e3 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -62,6 +62,7 @@ import org.jetbrains.annotations.ApiStatus; @@ -38,10 +38,10 @@ index 80949894308e597676745e312474fe0c9672a23e..133ae299ba12e0da9c5fa252a06bbf4f /** * Represents a server implementation. -@@ -2562,4 +2563,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2615,4 +2616,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ - boolean isOwnedByCurrentRegion(@NotNull Entity entity); - // Paper end - Folia region threading API + void allowPausing(@NotNull org.bukkit.plugin.Plugin plugin, boolean value); + // Paper end - API to check if the server is sleeping + + // Leaves start - Bot API + /** diff --git a/patches/api/0005-Hide-irrelevant-compilation-warnings.patch b/patches/api/0005-Hide-irrelevant-compilation-warnings.patch index 6882fbca..038c8e02 100644 --- a/patches/api/0005-Hide-irrelevant-compilation-warnings.patch +++ b/patches/api/0005-Hide-irrelevant-compilation-warnings.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Hide irrelevant compilation warnings diff --git a/build.gradle.kts b/build.gradle.kts -index ab84a1405acc1f0d5f267892243b82b8dab03e21..beee863333fa8ebb31cd83d6a1451b51c770bf2d 100644 +index e29e5024fa693baae469d47fe77b57118f14627c..7a60cd45449950cfb116b1cb29bc3da4ba074e7d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -131,6 +131,15 @@ val generateApiVersioningFile by tasks.registering { +@@ -148,6 +148,15 @@ val generateApiVersioningFile by tasks.registering { } } @@ -24,7 +24,7 @@ index ab84a1405acc1f0d5f267892243b82b8dab03e21..beee863333fa8ebb31cd83d6a1451b51 tasks.jar { from(generateApiVersioningFile.map { it.outputs.files.singleFile }) { into("META-INF/maven/${project.group}/${project.name}") -@@ -190,6 +199,8 @@ tasks.withType { +@@ -207,6 +216,8 @@ tasks.withType { into("build/docs/javadoc") } } diff --git a/patches/api/0006-SIMD-support.patch b/patches/api/0006-SIMD-support.patch index 43c089fe..ffb5cf41 100644 --- a/patches/api/0006-SIMD-support.patch +++ b/patches/api/0006-SIMD-support.patch @@ -5,10 +5,10 @@ Subject: [PATCH] SIMD support diff --git a/build.gradle.kts b/build.gradle.kts -index beee863333fa8ebb31cd83d6a1451b51c770bf2d..1491188671ce741afbbc4006c03510a328e92dbd 100644 +index 7a60cd45449950cfb116b1cb29bc3da4ba074e7d..caaffd1d0a323a2b292fb9c8ceeac271ba9dd635 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -137,6 +137,7 @@ tasks.withType { +@@ -154,6 +154,7 @@ tasks.withType { compilerArgs.add("-Xlint:-module") compilerArgs.add("-Xlint:-removal") compilerArgs.add("-Xlint:-dep-ann") @@ -16,7 +16,7 @@ index beee863333fa8ebb31cd83d6a1451b51c770bf2d..1491188671ce741afbbc4006c03510a3 } // Leaves end - hide irrelevant compilation warnings -@@ -201,6 +202,7 @@ tasks.withType { +@@ -218,6 +219,7 @@ tasks.withType { } options.addStringOption("Xdoclint:none", "-quiet") // Leaves - hide irrelevant compilation warnings diff --git a/patches/api/0007-Delete-Timings.patch b/patches/api/0007-Delete-Timings.patch index 21d33c3f..0f0a1916 100644 --- a/patches/api/0007-Delete-Timings.patch +++ b/patches/api/0007-Delete-Timings.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Delete Timings diff --git a/src/main/java/co/aikar/timings/FullServerTickHandler.java b/src/main/java/co/aikar/timings/FullServerTickHandler.java deleted file mode 100644 -index 3e747abde6fefae90f1c15cb00158bc5303cbe50..0000000000000000000000000000000000000000 +index 73b125979e2f2dfd13cbf689a90b29cc68a36e09..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/FullServerTickHandler.java +++ /dev/null @@ -1,89 +0,0 @@ @@ -92,7 +92,7 @@ index 3e747abde6fefae90f1c15cb00158bc5303cbe50..00000000000000000000000000000000 - TimingsManager.HISTORY.add(new TimingHistory()); - TimingsManager.resetTimings(); - } -- Bukkit.getUnsafe().reportTimings(); +- //Bukkit.getUnsafe().reportTimings(); - } - - boolean isViolated() { @@ -1279,10 +1279,10 @@ index df142a89b8c43acb81eb383eac0ef048a1f49a6e..00000000000000000000000000000000 -} diff --git a/src/main/java/co/aikar/timings/Timings.java b/src/main/java/co/aikar/timings/Timings.java deleted file mode 100644 -index e81d0bc309de877ed2b5da6122f55c162e9b5f10..0000000000000000000000000000000000000000 +index 95b7cdf0677ef71e6885fa78aa5c75bb500f5f53..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/Timings.java +++ /dev/null -@@ -1,331 +0,0 @@ +@@ -1,325 +0,0 @@ -/* - * This file is licensed under the MIT License (MIT). - * @@ -1430,14 +1430,8 @@ index e81d0bc309de877ed2b5da6122f55c162e9b5f10..00000000000000000000000000000000 - * @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; - } - } @@ -1445,7 +1439,7 @@ index e81d0bc309de877ed2b5da6122f55c162e9b5f10..00000000000000000000000000000000 - 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()) @@ -1616,10 +1610,10 @@ index e81d0bc309de877ed2b5da6122f55c162e9b5f10..00000000000000000000000000000000 - diff --git a/src/main/java/co/aikar/timings/TimingsCommand.java b/src/main/java/co/aikar/timings/TimingsCommand.java deleted file mode 100644 -index 95d87c9dbf2b237787294dfbe7fed87a36e6dedf..0000000000000000000000000000000000000000 +index b83e5ff7ada8771fdf27ba9807c77ba6a4ce12da..0000000000000000000000000000000000000000 --- a/src/main/java/co/aikar/timings/TimingsCommand.java +++ /dev/null -@@ -1,126 +0,0 @@ +@@ -1,127 +0,0 @@ -/* - * This file is licensed under the MIT License (MIT). - * @@ -1678,8 +1672,9 @@ index 95d87c9dbf2b237787294dfbe7fed87a36e6dedf..00000000000000000000000000000000 - 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)); @@ -2182,7 +2177,7 @@ index 5df19bd701c67506689fc7f49d91f99ebfbc83f0..940565704d0e8914a76cf25daf7d1f5e server.getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerCommandException(ex, target, sender, args))); // Paper //target.timings.stopTiming(); // Spigot // Paper diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java -index 003bece642b682985625db93cad93026352bfc66..308245714a0a830d92568f7bb1f4bb9c45828345 100644 +index b878e7167cfcdea0e224c182b40abeadd339d3b3..fc0239bca93e3dfb740af3239c1276b004607643 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -720,12 +720,7 @@ public final class SimplePluginManager implements PluginManager { @@ -2209,9 +2204,9 @@ index 003bece642b682985625db93cad93026352bfc66..308245714a0a830d92568f7bb1f4bb9c } /** -@@ -965,7 +959,6 @@ public final class SimplePluginManager implements PluginManager { - * @param use True if per event timing code should be used +@@ -966,7 +960,6 @@ public final class SimplePluginManager implements PluginManager { */ + @Deprecated(forRemoval = true) public void useTimings(boolean use) { - co.aikar.timings.Timings.setTimingsEnabled(use); // Paper } diff --git a/patches/api/0008-Force-peaceful-mode-switch.patch b/patches/api/0008-Force-peaceful-mode-switch.patch index 7e50606d..3d80f0cc 100644 --- a/patches/api/0008-Force-peaceful-mode-switch.patch +++ b/patches/api/0008-Force-peaceful-mode-switch.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Force peaceful mode switch diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index ef32a937e6faf1e8a5d6b1207986715bae5a246c..29343b0f5c5b91e66e13c2d8d5e1952762af8526 100644 +index 7a439c99fc4c5ee17d674460c8e58a9fe0c64e02..3d5893c4cb6fc914ff2dbbb2267420ec8653dac3 100644 --- a/src/main/java/org/bukkit/World.java +++ b/src/main/java/org/bukkit/World.java -@@ -4277,6 +4277,12 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient +@@ -4314,6 +4314,12 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient void setSendViewDistance(int viewDistance); // Paper end - view distance api diff --git a/patches/api/0009-Replay-Mod-API.patch b/patches/api/0009-Replay-Mod-API.patch index ebb9b1f0..17236070 100644 --- a/patches/api/0009-Replay-Mod-API.patch +++ b/patches/api/0009-Replay-Mod-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Replay Mod API diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 5f6078bc80e20c9482a96d2bf1095bb32fbfc28c..d0a9b96f4ab200892d589a68b27585a08780f7ac 100644 +index cb7e06ad207239a5626fc475c46d991fabb48293..e37015328e3e53ae5f960c8235ef827b7abe329d 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2927,6 +2927,11 @@ public final class Bukkit { +@@ -2974,6 +2974,11 @@ public final class Bukkit { return server.getBotManager(); } // Leaves end - Bot API @@ -21,7 +21,7 @@ index 5f6078bc80e20c9482a96d2bf1095bb32fbfc28c..d0a9b96f4ab200892d589a68b27585a0 @NotNull public static Server.Spigot spigot() { diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 133ae299ba12e0da9c5fa252a06bbf4f2b7b9016..f752dbd0ed8a62cb2b7c812925dde645c3ecb85c 100644 +index 967bb7ba476f494ac8bfebb599f260017176f3e3..cc86476f68e6934a3f8e6a5404876a39b943a926 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java @@ -63,6 +63,7 @@ import org.jetbrains.annotations.Contract; @@ -32,7 +32,7 @@ index 133ae299ba12e0da9c5fa252a06bbf4f2b7b9016..f752dbd0ed8a62cb2b7c812925dde645 /** * Represents a server implementation. -@@ -2572,4 +2573,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2625,4 +2626,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi */ @NotNull BotManager getBotManager(); // Leaves end - Bot API diff --git a/patches/api/0010-Bytebuf-API.patch b/patches/api/0010-Bytebuf-API.patch index 19268959..9a0d303c 100644 --- a/patches/api/0010-Bytebuf-API.patch +++ b/patches/api/0010-Bytebuf-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Bytebuf API diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index d0a9b96f4ab200892d589a68b27585a08780f7ac..7fbd9d2b533e8791132ba6ac21fad83d704922a0 100644 +index e37015328e3e53ae5f960c8235ef827b7abe329d..d4d30b4da5e05d1f60f9fbb41a7a11b98d7cf6a0 100644 --- a/src/main/java/org/bukkit/Bukkit.java +++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2933,6 +2933,12 @@ public final class Bukkit { +@@ -2980,6 +2980,12 @@ public final class Bukkit { } // Leaves end - Photographer API @@ -22,10 +22,10 @@ index d0a9b96f4ab200892d589a68b27585a08780f7ac..7fbd9d2b533e8791132ba6ac21fad83d public static Server.Spigot spigot() { return server.spigot(); diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index f752dbd0ed8a62cb2b7c812925dde645c3ecb85c..90fbc5fb7b8936af365e8f4cbbd7bff6d1b4cf68 100644 +index cc86476f68e6934a3f8e6a5404876a39b943a926..6a5afc818073989b6d3a108261aeff285409cfc0 100644 --- a/src/main/java/org/bukkit/Server.java +++ b/src/main/java/org/bukkit/Server.java -@@ -2576,4 +2576,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi +@@ -2629,4 +2629,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi // Leaves start - Photographer API @NotNull PhotographerManager getPhotographerManager(); // Leaves end - Photographer API @@ -35,10 +35,10 @@ index f752dbd0ed8a62cb2b7c812925dde645c3ecb85c..90fbc5fb7b8936af365e8f4cbbd7bff6 + // Leaves end - Bytebuf API } diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 7c56182acaf827f4b1a986a61cea8e9960604c98..45f820485e6f6e3a6a37a30a30c1c6a65b4615bb 100644 +index 95f0b3186e313c7fbd5c8531d52b82a69e525f94..ec2a5f77c135706a544a870808241ea1d6b6e814 100644 --- a/src/main/java/org/bukkit/entity/Player.java +++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3855,6 +3855,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM +@@ -3895,6 +3895,12 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM boolean isChunkSent(long chunkKey); // Paper end @@ -53,10 +53,10 @@ index 7c56182acaf827f4b1a986a61cea8e9960604c98..45f820485e6f6e3a6a37a30a30c1c6a6 Spigot spigot(); diff --git a/src/main/java/org/leavesmc/leaves/bytebuf/Bytebuf.java b/src/main/java/org/leavesmc/leaves/bytebuf/Bytebuf.java new file mode 100644 -index 0000000000000000000000000000000000000000..657eee1d4a18f765480135ef50f5ef65fdc3ed28 +index 0000000000000000000000000000000000000000..7038b2a5090154fe8d75ba9c9413952d834bb609 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bytebuf/Bytebuf.java -@@ -0,0 +1,102 @@ +@@ -0,0 +1,107 @@ +package org.leavesmc.leaves.bytebuf; + +import com.google.gson.JsonElement; @@ -64,6 +64,7 @@ index 0000000000000000000000000000000000000000..657eee1d4a18f765480135ef50f5ef65 +import org.bukkit.inventory.ItemStack; + +import java.util.UUID; ++import java.util.List; + +public interface Bytebuf { + @@ -155,6 +156,10 @@ index 0000000000000000000000000000000000000000..657eee1d4a18f765480135ef50f5ef65 + + ItemStack readItemStack(); + ++ Bytebuf writeItemStackList(List itemStacks); ++ ++ List readItemStackList(); ++ + Bytebuf copy(); + + boolean release(); @@ -210,10 +215,10 @@ index 0000000000000000000000000000000000000000..e246c0a8725fa3b2be065433652a19a5 +} diff --git a/src/main/java/org/leavesmc/leaves/bytebuf/packet/PacketType.java b/src/main/java/org/leavesmc/leaves/bytebuf/packet/PacketType.java new file mode 100644 -index 0000000000000000000000000000000000000000..4f8ea5c78df6429358dbbc75042521b657d50d3c +index 0000000000000000000000000000000000000000..ceebd752f4c3e50943b22902e01eaf9648941785 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bytebuf/packet/PacketType.java -@@ -0,0 +1,185 @@ +@@ -0,0 +1,191 @@ +package org.leavesmc.leaves.bytebuf.packet; + +public enum PacketType { @@ -382,6 +387,12 @@ index 0000000000000000000000000000000000000000..4f8ea5c78df6429358dbbc75042521b6 + ClientboundTickingStep, + ClientboundCustomPayload, + ClientboundCustomDetails, ++ ClientboundRecipeBookAdd, ++ ServerboundClientTickEnd, ++ ClientboundSetHeldSlot, ++ ServerboundSelectBundleItem, ++ ClientboundSetPlayerInventory, ++ ClientboundSetCursorItem, + ClientboundDisconnect, + ClientboundKeepAlive, + ClientboundPing, diff --git a/patches/removed/server/0020-Optimize-entity-coordinate-key.patch b/patches/removed/server/0020-Optimize-entity-coordinate-key.patch deleted file mode 100644 index 8b9f4d60..00000000 --- a/patches/removed/server/0020-Optimize-entity-coordinate-key.patch +++ /dev/null @@ -1,20 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Sun, 14 Aug 2022 08:17:28 +0800 -Subject: [PATCH] Optimize entity coordinate key - -This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1beefbd05c13181214e188f50e88fb67f6712a45..a95fd8164ddd2992525e1f453df2094ed2108cf7 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -315,7 +315,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - public double yo; - public double zo; - private Vec3 position; -- private BlockPos blockPosition; -+ public BlockPos blockPosition; // Leaves - private -> public - private ChunkPos chunkPosition; - private Vec3 deltaMovement; - private float yRot; diff --git a/patches/server/0022-Early-return-optimization-for-target-finding.patch b/patches/removed/server/0022-Early-return-optimization-for-target-finding.patch similarity index 100% rename from patches/server/0022-Early-return-optimization-for-target-finding.patch rename to patches/removed/server/0022-Early-return-optimization-for-target-finding.patch diff --git a/patches/unapplied/server/0024-Move-ThreadUnsafeRandom-Initialization.patch b/patches/removed/server/0024-Move-ThreadUnsafeRandom-Initialization.patch similarity index 100% rename from patches/unapplied/server/0024-Move-ThreadUnsafeRandom-Initialization.patch rename to patches/removed/server/0024-Move-ThreadUnsafeRandom-Initialization.patch diff --git a/patches/unapplied/server/0026-Use-thread-unsafe-random-for-mob-spawning.patch b/patches/removed/server/0026-Use-thread-unsafe-random-for-mob-spawning.patch similarity index 100% rename from patches/unapplied/server/0026-Use-thread-unsafe-random-for-mob-spawning.patch rename to patches/removed/server/0026-Use-thread-unsafe-random-for-mob-spawning.patch diff --git a/patches/server/0028-Remove-streams-and-iterators-from-range-check.patch b/patches/removed/server/0028-Remove-streams-and-iterators-from-range-check.patch similarity index 100% rename from patches/server/0028-Remove-streams-and-iterators-from-range-check.patch rename to patches/removed/server/0028-Remove-streams-and-iterators-from-range-check.patch diff --git a/patches/removed/server/0032-Reduce-entity-fluid-lookups-if-no-fluids.patch b/patches/removed/server/0032-Reduce-entity-fluid-lookups-if-no-fluids.patch deleted file mode 100644 index aa26e8b3..00000000 --- a/patches/removed/server/0032-Reduce-entity-fluid-lookups-if-no-fluids.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Sat, 20 Aug 2022 22:52:31 +0800 -Subject: [PATCH] Reduce entity fluid lookups if no fluids - -This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 2563e077ceaf6c21e20f00c59341abcca39c91eb..decc1d6be70eb501ebf75dd5907fabfbc2584928 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4455,16 +4455,18 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - public boolean updateFluidHeightAndDoFluidPushing(TagKey tag, double speed) { -- if (this.touchingUnloadedChunk()) { -+ if (!org.leavesmc.leaves.LeavesConfig.reduceEntityFluidLookup && this.touchingUnloadedChunk()) { // Leaves - cost of a lookup here is the same cost as below, so skip - 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); -+ // Leaves start - rename -+ int minBlockX = Mth.floor(axisalignedbb.minX); -+ int maxBlockX = Mth.ceil(axisalignedbb.maxX); -+ int minBlockY = Mth.floor(axisalignedbb.minY); -+ int maxBlockY = Mth.ceil(axisalignedbb.maxY); -+ int minBlockZ = Mth.floor(axisalignedbb.minZ); -+ int maxBlockZ = Mth.ceil(axisalignedbb.maxZ); -+ // Leaves end - double d1 = 0.0D; - boolean flag = this.isPushedByFluid(); - boolean flag1 = false; -@@ -4472,38 +4474,123 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - 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); -+ // Leaves start - based off CollisionUtil.getCollisionsForBlocksOrWorldBorder -+ if (org.leavesmc.leaves.LeavesConfig.reduceEntityFluidLookup) { -+ final int minSection = this.level.getMinSection() - 1; -+ final int maxSection = this.level.getMaxSection() - 1; -+ final int minBlock = minSection << 4; -+ final int maxBlock = (maxSection << 4) | 15; - -- if (fluid.is(tag)) { -- double d2 = (double) ((float) i2 + fluid.getHeight(this.level(), blockposition_mutableblockposition)); -+ // special cases: -+ if (minBlockY > maxBlock || maxBlockY < minBlock) { -+ // no point in checking -+ return false; -+ } - -- if (d2 >= axisalignedbb.minY) { -- flag1 = true; -- d1 = Math.max(d2 - axisalignedbb.minY, d1); -- if (flag) { -- Vec3 vec3d1 = fluid.getFlow(this.level(), blockposition_mutableblockposition); -+ int minYIterate = Math.max(minBlock, minBlockY); -+ int maxYIterate = Math.min(maxBlock, maxBlockY); - -- if (d1 < 0.4D) { -- vec3d1 = vec3d1.scale(d1); -- } -+ int minChunkX = minBlockX >> 4; -+ int maxChunkX = maxBlockX >> 4; -+ -+ int minChunkZ = minBlockZ >> 4; -+ int maxChunkZ = maxBlockZ >> 4; -+ -+ for (int currChunkZ = minChunkZ; currChunkZ <= maxChunkZ; ++currChunkZ) { -+ int minZ = currChunkZ == minChunkZ ? minBlockZ & 15 : 0; // coordinate in chunk -+ int maxZ = currChunkZ == maxChunkZ ? maxBlockZ & 15 : 16; // coordinate in chunk -+ -+ for (int currChunkX = minChunkX; currChunkX <= maxChunkX; ++currChunkX) { -+ int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk -+ int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 16; // coordinate in chunk -+ -+ net.minecraft.world.level.chunk.ChunkAccess chunk = this.level.getChunkIfLoadedImmediately(currChunkX, currChunkZ); -+ if (chunk == null) { -+ return false; // if we're touching an unloaded chunk then it's false -+ } -+ -+ net.minecraft.world.level.chunk.LevelChunkSection[] sections = chunk.getSections(); -+ -+ for (int currY = minYIterate; currY < maxYIterate; ++currY) { -+ net.minecraft.world.level.chunk.LevelChunkSection section = sections[(currY >> 4) - minSection]; - -- vec3d = vec3d.add(vec3d1); -- ++k1; -+ if (section == null || section.hasOnlyAir() || section.fluidStateCount == 0) { // if no fluids, nothing in this section -+ // empty -+ // skip to next section -+ currY = (currY & ~(15)) + 15; // increment by 15: iterator loop increments by the extra one -+ continue; -+ } -+ -+ net.minecraft.world.level.chunk.PalettedContainer blocks = section.states; -+ -+ for (int currZ = minZ; currZ < maxZ; ++currZ) { -+ for (int currX = minX; currX < maxX; ++currX) { -+ FluidState fluid = blocks.get(currX & 15, currY & 15, currZ & 15).getFluidState(); -+ -+ if (fluid.is(tag)) { -+ blockposition_mutableblockposition.set((currChunkX << 4) + currX, currY, (currChunkZ << 4) + currZ); -+ double d2 = (double) ((float) currY + 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); -+ } -+ -+ vec3d = vec3d.add(vec3d1); -+ ++k1; -+ } -+ // CraftBukkit start - store last lava contact location -+ if (tag == FluidTags.LAVA) { -+ this.lastLavaContact = blockposition_mutableblockposition.immutable(); -+ } -+ // CraftBukkit end -+ } -+ } - } -- // CraftBukkit start - store last lava contact location -- if (tag == FluidTags.LAVA) { -- this.lastLavaContact = blockposition_mutableblockposition.immutable(); -+ } -+ } -+ } -+ } -+ } else { -+ for (int l1 = minBlockX; l1 < maxBlockX; ++l1) { -+ for (int i2 = minBlockY; i2 < maxBlockY; ++i2) { -+ for (int j2 = minBlockZ; j2 < maxBlockZ; ++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); -+ } -+ -+ vec3d = vec3d.add(vec3d1); -+ ++k1; -+ } -+ // CraftBukkit start - store last lava contact location -+ if (tag == FluidTags.LAVA) { -+ this.lastLavaContact = blockposition_mutableblockposition.immutable(); -+ } -+ // CraftBukkit end - } -- // CraftBukkit end - } - } - } - } - } -+ // Leaves end - - if (vec3d.length() > 0.0D) { - if (k1 > 0) { -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..95921cc65ebb0d41a52a662130e0e265b4f5afa6 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java -@@ -25,6 +25,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - public final PalettedContainer states; - // CraftBukkit start - read/write - private PalettedContainer> biomes; -+ public short fluidStateCount; // Leaves - - // 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); -@@ -104,6 +105,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - - if (!fluid.isEmpty()) { - --this.tickingFluidCount; -+ --this.fluidStateCount; // Leaves - } - - if (!state.isAir()) { -@@ -115,6 +117,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - - if (!fluid1.isEmpty()) { - ++this.tickingFluidCount; -+ --this.fluidStateCount; // Leaves - } - - // Paper start - block counting -@@ -208,6 +211,7 @@ public class LevelChunkSection implements ca.spottedleaf.moonrise.patches.block_ - if (fluid.isRandomlyTicking()) { - this.tickingFluidCount += paletteCount; - } -+ LevelChunkSection.this.fluidStateCount++; // Leaves - } - } - } diff --git a/patches/server/0041-Improve-fluid-direction-caching.patch b/patches/removed/server/0041-Improve-fluid-direction-caching.patch similarity index 100% rename from patches/server/0041-Improve-fluid-direction-caching.patch rename to patches/removed/server/0041-Improve-fluid-direction-caching.patch diff --git a/patches/server/0077-Cache-BlockStatePairKey-hash.patch b/patches/removed/server/0077-Cache-BlockStatePairKey-hash.patch similarity index 100% rename from patches/server/0077-Cache-BlockStatePairKey-hash.patch rename to patches/removed/server/0077-Cache-BlockStatePairKey-hash.patch diff --git a/patches/removed/server/0078-Cache-CubeVoxelShape-shape-array.patch b/patches/removed/server/0078-Cache-CubeVoxelShape-shape-array.patch deleted file mode 100644 index 8b92249d..00000000 --- a/patches/removed/server/0078-Cache-CubeVoxelShape-shape-array.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Tue, 18 Jul 2023 14:43:18 +0800 -Subject: [PATCH] Cache CubeVoxelShape shape array - -This patch is Powered by Gale(https://github.com/GaleMC/Gale) - -diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java -index d812949c7329ae2696b38dc792fa011ba87decb9..17781089b96a8ba54e06a4c8ead58cc31151be47 100644 ---- a/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java -+++ b/src/main/java/net/minecraft/world/phys/shapes/CubeVoxelShape.java -@@ -5,13 +5,28 @@ import net.minecraft.core.Direction; - import net.minecraft.util.Mth; - - public final class CubeVoxelShape extends VoxelShape { -+ -+ private DoubleList[] list = null; // Leaves - cache CubeVoxelShape shape array -+ - protected CubeVoxelShape(DiscreteVoxelShape voxels) { - super(voxels); - } - - @Override - public DoubleList getCoords(Direction.Axis axis) { -- return new CubePointRange(this.shape.getSize(axis)); -+ // Leaves start - cache CubeVoxelShape shape array -+ if (!org.leavesmc.leaves.LeavesConfig.cacheCubeVoxelShapeShapeArray) { -+ return new CubePointRange(this.shape.getSize(axis)); -+ } else { -+ if (this.list == null) { -+ this.list = new DoubleList[Direction.Axis.VALUES.length]; -+ for (Direction.Axis existingAxis : Direction.Axis.VALUES) { -+ this.list[existingAxis.ordinal()] = new CubePointRange(this.shape.getSize(axis)); -+ } -+ } -+ return this.list[axis.ordinal()]; -+ } -+ // Leaves end - cache CubeVoxelShape shape array - } - - @Override diff --git a/patches/server/0106-Disable-moved-wrongly-threshold.patch b/patches/removed/server/0099-Disable-moved-wrongly-threshold.patch similarity index 92% rename from patches/server/0106-Disable-moved-wrongly-threshold.patch rename to patches/removed/server/0099-Disable-moved-wrongly-threshold.patch index 3f9d4d01..097d97d0 100644 --- a/patches/server/0106-Disable-moved-wrongly-threshold.patch +++ b/patches/removed/server/0099-Disable-moved-wrongly-threshold.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable moved wrongly threshold diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 2e08a927f9c3c4a4cfcad16b7a835b80efefdfca..614907d64362ae51b3f19a6d5652e23be28f795c 100644 +index a0b0bee8c2c0452d41872722875dbb131ccceacf..fd05c29b888f7979e208e51cfc8a4110f3324eb9 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -569,7 +569,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -574,7 +574,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl } // Paper end - Prevent moving into unloaded chunks @@ -17,7 +17,7 @@ index 2e08a927f9c3c4a4cfcad16b7a835b80efefdfca..614907d64362ae51b3f19a6d5652e23b // CraftBukkit end ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8}); this.send(new ClientboundMoveVehiclePacket(entity)); -@@ -605,7 +605,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -610,7 +610,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean flag2 = false; @@ -26,7 +26,7 @@ index 2e08a927f9c3c4a4cfcad16b7a835b80efefdfca..614907d64362ae51b3f19a6d5652e23b flag2 = true; // Paper - diff on change, this should be moved wrongly ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", new Object[]{entity.getName().getString(), this.player.getName().getString(), Math.sqrt(d10)}); } -@@ -1414,7 +1414,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1426,7 +1426,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY, toX, toY, toZ, toYaw, toPitch, true); if (!event.isAllowed()) { @@ -35,7 +35,7 @@ index 2e08a927f9c3c4a4cfcad16b7a835b80efefdfca..614907d64362ae51b3f19a6d5652e23b 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()); return; -@@ -1484,7 +1484,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1496,7 +1496,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl d10 = d6 * d6 + d7 * d7 + d8 * d8; boolean movedWrongly = false; // Paper - Add fail move event; rename diff --git a/patches/unapplied/server/0131-Optimize-random-calls-in-chunk-ticking.patch b/patches/removed/server/0131-Optimize-random-calls-in-chunk-ticking.patch similarity index 100% rename from patches/unapplied/server/0131-Optimize-random-calls-in-chunk-ticking.patch rename to patches/removed/server/0131-Optimize-random-calls-in-chunk-ticking.patch diff --git a/patches/server/0001-Build-changes.patch b/patches/server/0001-Build-changes.patch index 40b8e47b..f2c3d8ec 100644 --- a/patches/server/0001-Build-changes.patch +++ b/patches/server/0001-Build-changes.patch @@ -5,20 +5,20 @@ Subject: [PATCH] Build changes diff --git a/build.gradle.kts b/build.gradle.kts -index de0474b8dce58cb419c00b7614d7dd66be832a02..0c537cd70a1b8a7d7ccd78ba212de0cae8cb6bbc 100644 +index faf3e3fd72e8c915e7a4803dacbe1bb576c6663e..d88a9d1908373ba44143013cda1ae51477a835cf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -13,7 +13,7 @@ configurations.named(log4jPlugins.compileClasspathConfigurationName) { - val alsoShade: Configuration by configurations.creating +@@ -25,7 +25,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider { + // Paper end - configure mockito agent that is needed in newer java versions dependencies { - implementation(project(":paper-api")) + implementation(project(":leaves-api")) // Leaves - build change // Paper start - implementation("org.jline:jline-terminal-jansi:3.21.0") - implementation("net.minecrell:terminalconsoleappender:1.3.0") -@@ -72,6 +72,15 @@ paperweight { - craftBukkitPackageVersion.set("v1_21_R1") // also needs to be updated in MappingEnvironment + implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ + implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 +@@ -86,6 +86,15 @@ paperweight { + craftBukkitPackageVersion.set("v1_21_R2") // also needs to be updated in MappingEnvironment } +// Leaves start - hide irrelevant compilation warnings @@ -33,7 +33,7 @@ index de0474b8dce58cb419c00b7614d7dd66be832a02..0c537cd70a1b8a7d7ccd78ba212de0ca tasks.jar { archiveClassifier.set("dev") -@@ -85,14 +94,14 @@ tasks.jar { +@@ -99,14 +108,14 @@ tasks.jar { val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper attributes( "Main-Class" to "org.bukkit.craftbukkit.Main", @@ -53,7 +53,7 @@ index de0474b8dce58cb419c00b7614d7dd66be832a02..0c537cd70a1b8a7d7ccd78ba212de0ca "Build-Number" to (build ?: ""), "Build-Time" to Instant.now().toString(), "Git-Branch" to gitBranch, // Paper -@@ -153,7 +162,7 @@ fun TaskContainer.registerRunTask( +@@ -172,7 +181,7 @@ fun TaskContainer.registerRunTask( name: String, block: JavaExec.() -> Unit ): TaskProvider = register(name) { @@ -62,7 +62,7 @@ index de0474b8dce58cb419c00b7614d7dd66be832a02..0c537cd70a1b8a7d7ccd78ba212de0ca mainClass.set("org.bukkit.craftbukkit.Main") standardInput = System.`in` workingDir = rootProject.layout.projectDirectory -@@ -222,13 +231,13 @@ tasks.registerRunTask("runReobfBundler") { +@@ -241,13 +250,13 @@ tasks.registerRunTask("runReobfBundler") { classpath(rootProject.tasks.named("createReobfBundlerJar").flatMap { it.outputZip }) mainClass.set(null as String?) } @@ -82,8 +82,21 @@ index de0474b8dce58cb419c00b7614d7dd66be832a02..0c537cd70a1b8a7d7ccd78ba212de0ca + classpath(rootProject.tasks.named("createReobfLeavesclipJar").flatMap { it.outputZip }) mainClass.set(null as String?) } +diff --git a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +index ca8b6a926dfff3fdd6b04228809a4480366120b2..f77f04f7312a528d3f898c6c4b8603ab295c14fd 100644 +--- a/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java ++++ b/src/main/java/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -25,7 +25,7 @@ import net.minecraft.world.phys.AABB; + import java.util.List; + import java.util.function.Predicate; + +-public final class PaperHooks implements PlatformHooks { ++public class PaperHooks implements PlatformHooks { // Leaves - not final + + @Override + public String getBrand() { diff --git a/src/main/java/com/destroystokyo/paper/Metrics.java b/src/main/java/com/destroystokyo/paper/Metrics.java -index 4b002e8b75d117b726b0de274a76d3596fce015b..03373e5a37a5f90d31434aab921ec8c6b6efef70 100644 +index 4b002e8b75d117b726b0de274a76d3596fce015b..f6b362894bbd0f0f09f0f51a931529d708ca9b9e 100644 --- a/src/main/java/com/destroystokyo/paper/Metrics.java +++ b/src/main/java/com/destroystokyo/paper/Metrics.java @@ -593,7 +593,8 @@ public class Metrics { @@ -109,7 +122,7 @@ index 4b002e8b75d117b726b0de274a76d3596fce015b..03373e5a37a5f90d31434aab921ec8c6 + return "unknown"; + })); + -+ if (org.leavesmc.leaves.LeavesConfig.bstatsPrivacyMode) { ++ if (org.leavesmc.leaves.LeavesConfig.mics.bstatsPrivacyMode) { + return; + } + @@ -184,10 +197,10 @@ index 790bad0494454ca12ee152e3de6da3da634d9b20..c060857cb0551fff8f5033553b887f3a private static final String BUILD_DEV = "DEV"; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 696d075ca2883f3c37e35f983c4d020e5db89d16..f1b28f4f383c682a52b6aa44dfbdf30944537ecf 100644 +index 780582ebaa8deb0c0b0c8de17de5abcebafa4bd3..5201b1aaedabdf6021ea9ac3f84be70a6d03aa8f 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1243,7 +1243,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop, 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); -- } -- -- 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 -- * @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 -deleted file mode 100644 -index 7620c72a4c243cbeea245203ce03a97cbfa7d922..0000000000000000000000000000000000000000 ---- a/src/main/java/co/aikar/timings/TimingsExport.java -+++ /dev/null -@@ -1,388 +0,0 @@ --/* -- * 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") || key.equals("feature-seeds")) { -- 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 -deleted file mode 100644 -index 2f0d9b953802dee821cfde82d22b0567cce8ee91..0000000000000000000000000000000000000000 ---- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java -+++ /dev/null -@@ -1,120 +0,0 @@ --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/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java -index 0c3c82b28e581286b798ee58ca4193efc2faff4a..fe6a5a6377bcb577b21471ae93639f8dc5fa0f39 100644 ---- a/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java -+++ b/src/main/java/io/papermc/paper/command/brigadier/bukkit/BukkitCommandNode.java -@@ -1,6 +1,5 @@ - 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; -@@ -78,18 +77,11 @@ public class BukkitCommandNode extends LiteralCommandNode { - 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; -diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index a9dd0e5216e95afd98fd2200d110e2cc0b1b0dca..53913dfa4d9b73862179dcdef080c7e3adfe3b0f 100644 ---- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -+++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -1,6 +1,5 @@ - 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; -@@ -119,7 +118,6 @@ public class GlobalConfiguration extends ConfigurationPart { - - @PostProcess - private void postProcess() { -- MinecraftTimings.processConfig(this); - } - } - diff --git a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java b/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java index 7ce9ebba8ce304d1f3f21d4f15ee5f3560d7700b..a1c9726d25479b5326fe2fa2b0f5a98d6b2da4c5 100644 --- a/src/main/java/io/papermc/paper/plugin/manager/PaperEventManager.java @@ -800,22 +45,8 @@ index 097500a59336db1bbfffcd1aa4cff7a8586e46ec..35b00c139864dd7925d46a2d6a317d7e } @Override -diff --git a/src/main/java/net/minecraft/network/protocol/PacketUtils.java b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -index e2c24813f59c2fd075c740ac1842a38f20ed8554..1f7f68aad97ee73763c042837f239bdc7167db55 100644 ---- a/src/main/java/net/minecraft/network/protocol/PacketUtils.java -+++ b/src/main/java/net/minecraft/network/protocol/PacketUtils.java -@@ -51,8 +51,7 @@ public class PacketUtils { - try { // Paper - detailed watchdog information - if (listener instanceof ServerCommonPacketListenerImpl serverCommonPacketListener && serverCommonPacketListener.processedDisconnect) return; // CraftBukkit - Don't handle sync packets for kicked players - if (listener.shouldHandleMessage(packet)) { -- co.aikar.timings.Timing timing = co.aikar.timings.MinecraftTimings.getPacketTiming(packet); // Paper - timings -- try (co.aikar.timings.Timing ignored = timing.startTiming()) { // Paper - timings -+ try { - 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 f1b28f4f383c682a52b6aa44dfbdf30944537ecf..4464ce6ff4fd8eb9570205c7326c9a47b67d634d 100644 +index 7f0d05c242c649b3f0482334306898dedd1d5c43..aed5d75b170612960997dc34463fafd3a6283d92 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -3,9 +3,6 @@ package net.minecraft.server; @@ -828,954 +59,3 @@ index f1b28f4f383c682a52b6aa44dfbdf30944537ecf..4464ce6ff4fd8eb9570205c7326c9a47 import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -@@ -196,8 +193,6 @@ import org.bukkit.craftbukkit.CraftRegistry; - import org.bukkit.event.server.ServerLoadEvent; - // CraftBukkit end - --import co.aikar.timings.MinecraftTimings; // Paper -- - public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource, AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.server.ChunkSystemMinecraftServer { // Paper - rewrite chunk system - - private static MinecraftServer SERVER; // Paper -@@ -1038,7 +1033,6 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { - return !this.canOversleep(); - }); -- isOversleep = false;MinecraftTimings.serverOversleep.stopTiming(); -+ isOversleep = false; - // Paper end - this.server.spark.tickStart(); // Paper - spark - new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper - Server Tick Events -@@ -1623,9 +1616,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop { - entityplayer.connection.suspendFlushing(); - }); -- MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper - this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit -- MinecraftTimings.bukkitSchedulerTimer.stopTiming(); // Spigot // Paper - // Paper start - Folia scheduler API - ((io.papermc.paper.threadedregions.scheduler.FoliaGlobalRegionScheduler) Bukkit.getGlobalRegionScheduler()).tick(); - getAllLevels().forEach(level -> { -@@ -1739,21 +1727,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 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) { -diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index af8cb316ac169aa8d98a88765b85bb013b9ba961..50e79870db5424e47c9cb5f3866557008f580071 100644 ---- a/src/main/java/net/minecraft/server/level/ChunkMap.java -+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -1,6 +1,5 @@ - 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; -@@ -958,7 +957,6 @@ 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; - -@@ -983,17 +981,14 @@ 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 dcb5651d1d9b10b40430fb2f713beedf68336704..68e445c21e0acbdf6bb74d50ddd32e0ef2c0e9ad 100644 ---- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java -+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -356,9 +356,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - - public void save(boolean flush) { - // Paper - rewrite chunk system -- try (co.aikar.timings.Timing timed = level.timings.chunkSaveData.startTiming()) { // Paper - Timings - this.chunkMap.saveAllChunks(flush); -- } // Paper - Timings - } - - @Override -@@ -394,26 +392,20 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - @Override - public void tick(BooleanSupplier shouldKeepTicking, boolean tickChunks) { - this.level.getProfiler().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 - this.level.getProfiler().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(); - } - -- this.level.timings.doChunkUnload.startTiming(); // Spigot - this.level.getProfiler().popPush("unload"); - this.chunkMap.tick(shouldKeepTicking); -- this.level.timings.doChunkUnload.stopTiming(); // Spigot - this.level.getProfiler().pop(); - this.clearCache(); - } -@@ -449,13 +441,11 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - } - // 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"); -- this.level.timings.countNaturalMobs.startTiming(); // Paper - timings - int k = this.distanceManager.getNaturalSpawnChunkCount(); - // Paper start - Optional per player mob spawns - int naturalSpawnChunkCount = k; -@@ -480,7 +470,6 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - 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"); -@@ -521,19 +510,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - } - } - } -- this.level.timings.chunkTicks.stopTiming(); // Paper - - 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 - } - } - - gameprofilerfiller.popPush("broadcast"); - // 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(); -@@ -547,7 +532,6 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - holder.holder().broadcastChanges(holder.chunk()); - } - } -- this.level.timings.broadcastChunkUpdates.stopTiming(); // Paper - timing - // Paper end - chunk tick iteration optimisations - gameprofilerfiller.pop(); - gameprofilerfiller.pop(); -diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index f9abf63e12ea930275121b470e4e4906cff0fc12..14e9140c9a18906c249e8cef39988ed7f81738f7 100644 ---- a/src/main/java/net/minecraft/server/level/ServerLevel.java -+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -1,7 +1,6 @@ - package net.minecraft.server.level; - - import com.google.common.annotations.VisibleForTesting; --import co.aikar.timings.TimingHistory; // Paper - import com.google.common.collect.Lists; - import com.mojang.datafixers.DataFixer; - import com.mojang.datafixers.util.Pair; -@@ -666,7 +665,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - } - - gameprofilerfiller.popPush("tickPending"); -- this.timings.scheduledBlocks.startTiming(); // Paper - if (!this.isDebug() && flag) { - j = this.getGameTime(); - gameprofilerfiller.push("blockTicks"); -@@ -675,24 +673,17 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - this.fluidTicks.tick(j, paperConfig().environment.maxFluidTicks, this::tickFluid); // Paper - configurable max fluid ticks - gameprofilerfiller.pop(); - } -- 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 - this.runBlockEvents(); -- this.timings.doSounds.stopTiming(); // Spigot - } - - this.handlingTick = false; -@@ -705,7 +696,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - - if (flag1 || this.emptyTime++ < 300) { - gameprofilerfiller.push("entities"); -- this.timings.tickEntities.startTiming(); // Spigot - if (this.dragonFight != null && flag) { - gameprofilerfiller.push("dragonFight"); - this.dragonFight.tick(); -@@ -713,7 +703,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - } - - org.spigotmc.ActivationRange.activateEntities(this); // Spigot -- this.timings.entityTick.startTiming(); // Spigot - this.entityTickList.forEach((entity) -> { - if (!entity.isRemoved()) { - if (false && this.shouldDiscardEntity(entity)) { // CraftBukkit - We prevent spawning in general, so this butchering is not needed -@@ -740,8 +729,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - } - } - }); -- this.timings.entityTick.stopTiming(); // Spigot -- this.timings.tickEntities.stopTiming(); // Spigot - gameprofilerfiller.pop(); - this.tickBlockEntities(); - } -@@ -902,12 +889,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - } // Paper - Option to disable ice and snow - - gameprofilerfiller.popPush("tickBlocks"); -- timings.chunkTicksBlocks.startTiming(); // Paper - if (randomTickSpeed > 0) { - this.optimiseRandomTick(chunk, randomTickSpeed); // Paper - optimise random ticking - } - -- timings.chunkTicksBlocks.stopTiming(); // Paper - gameprofilerfiller.pop(); - } - -@@ -1219,9 +1204,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - currentlyTickingEntity.lazySet(entity); - } - // Paper end - log detailed entity tick information -- ++TimingHistory.entityTicks; // Paper - timings - // Spigot start -- co.aikar.timings.Timing timer; // Paper - /*if (!org.spigotmc.ActivationRange.checkIfActive(entity)) { // Paper - comment out - EAR 2, reimplement below - entity.tickCount++; - timer = entity.getType().inactiveTickTimer.startTiming(); try { // Paper - timings -@@ -1230,11 +1213,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - return; - }*/ // Paper - comment out EAR 2 - // Spigot end -- // Paper start- timings - final boolean isActive = org.spigotmc.ActivationRange.checkIfActive(entity); -- timer = isActive ? entity.getType().tickTimer.startTiming() : entity.getType().inactiveTickTimer.startTiming(); // Paper -- try { -- // Paper end - timings - entity.setOldPosAndRot(); - ProfilerFiller gameprofilerfiller = this.getProfiler(); - -@@ -1244,12 +1223,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - }); - 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 - Iterator iterator = entity.getPassengers().iterator(); - - while (iterator.hasNext()) { -@@ -1272,8 +1249,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - 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; -@@ -1302,8 +1277,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - - this.tickPassenger(passenger, entity2); - } -- -- } finally { timer.stopTiming(); }// Paper - EAR2 timings - } - } else { - passenger.stopRiding(); -@@ -1323,24 +1296,23 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); - } - -- try (co.aikar.timings.Timing ignored = this.timings.worldSave.startTiming()) { -- if (doFull) { -- this.saveLevelData(true); -- } -+ if (doFull) { -+ this.saveLevelData(true); -+ } - -- // chunk autosave is already called by the ChunkSystem during unload processing (ChunkMap#processUnloads) -+ // chunk autosave is already called by the ChunkSystem during unload processing (ChunkMap#processUnloads) - -- // Copied from save() -- // CraftBukkit start - moved from MinecraftServer.saveChunks -- if (doFull) { // Paper -- ServerLevel worldserver1 = this; -+ // Copied from save() -+ // CraftBukkit start - moved from MinecraftServer.saveChunks -+ if (doFull) { // Paper -+ ServerLevel worldserver1 = this; - -- this.serverLevelData.setWorldBorder(worldserver1.getWorldBorder().createSettings()); -- this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save(this.registryAccess())); -- this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); -- } -- // CraftBukkit end -+ this.serverLevelData.setWorldBorder(worldserver1.getWorldBorder().createSettings()); -+ this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save(this.registryAccess())); -+ this.convertable.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); - } -+ // CraftBukkit end -+ - } - // Paper end - Incremental chunk and player saving - -@@ -1354,7 +1326,6 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - - 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")); - } -@@ -1364,12 +1335,8 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. - progressListener.progressStage(Component.translatable("menu.savingChunks")); - } - -- timings.worldSaveChunks.startTiming(); // Paper - if (!close) { chunkproviderserver.save(flush); } // Paper - add close param -- timings.worldSaveChunks.stopTiming(); // Paper -- }// Paper - // Paper - rewrite chunk system -- - } - // Paper start - add close param - if (close) { -diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index b0e8fe11e7f5d1fd803fa34187c9fa77245ad79b..aca89b47378c4d1b2f3f3805cf743f6d838487c5 100644 ---- a/src/main/java/net/minecraft/server/players/PlayerList.java -+++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1,6 +1,5 @@ - 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; -@@ -1200,7 +1199,6 @@ public abstract class PlayerList { - - public void saveAll(int interval) { - io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main -- MinecraftTimings.savePlayers.startTiming(); // Paper - int numSaved = 0; - long now = MinecraftServer.currentTick; - for (int i = 0; i < this.players.size(); ++i) { -@@ -1211,7 +1209,6 @@ public abstract class PlayerList { - } - // Paper end - Incremental chunk and player saving - } -- MinecraftTimings.savePlayers.stopTiming(); // Paper - return null; }); // Paper - ensure main - } - -diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java -index cb61462d4691a055a4b25f7b953609d8a154fdfe..b2b97c4c61ea5b6f7ec199fabbd1bd1c86647ccc 100644 ---- a/src/main/java/net/minecraft/world/entity/EntityType.java -+++ b/src/main/java/net/minecraft/world/entity/EntityType.java -@@ -343,10 +343,6 @@ public class EntityType implements FeatureElement, EntityTypeT - this(factory, spawnGroup, saveable, summonable, fireImmune, spawnableFarFromPlayer, canSpawnInside, dimensions, spawnBoxScale, maxTrackDistance, trackTickInterval, 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) { -- 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; -@@ -700,12 +696,6 @@ 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 2aa6374cd4a96efd85899be8cd3172a8257bfe6b..03e424afddbdcdcb6ea88ab9ee4e0bbcc05f983d 100644 ---- a/src/main/java/net/minecraft/world/entity/LivingEntity.java -+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -157,7 +157,6 @@ import org.bukkit.event.entity.EntityTeleportEvent; - import org.bukkit.event.player.PlayerItemConsumeEvent; - // CraftBukkit end - --import co.aikar.timings.MinecraftTimings; // Paper - - public abstract class LivingEntity extends Entity implements Attackable { - -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 9379dd4056018b52c93ed4888dcdc94579bd9691..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 -@@ -16,7 +16,6 @@ public abstract class Behavior implements BehaviorContro - 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) { -@@ -38,7 +37,6 @@ public abstract class Behavior implements BehaviorContro - 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 - } - -@@ -59,9 +57,7 @@ public abstract class Behavior implements BehaviorContro - 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; -@@ -73,13 +69,11 @@ 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 85b4b24361e785acf75571ff98f924c00ae80748..1f3e0392f88a7cb3fb5c0767cdd1b4bc4ffcae4e 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 -@@ -28,7 +28,6 @@ public abstract class Sensor { - 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) { -@@ -39,7 +38,6 @@ public abstract class Sensor { - 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); -@@ -53,10 +51,8 @@ public abstract class Sensor { - if (--this.timeToTick <= 0L) { - // 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(); - // Paper end - this.doTick(world, entity); -- this.timing.stopTiming(); // Paper - sensor timings - } - } - -diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 507671476c3d2d92a2fdb05be24443af27d26dcf..73b1b5b8b3723f068e45874eb251f08ef0a93017 100644 ---- a/src/main/java/net/minecraft/world/level/Level.java -+++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -173,7 +173,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - // 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; - private org.spigotmc.TickLimiter tileLimiter; -@@ -763,7 +762,6 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - public void onBorderSetDamageSafeZOne(WorldBorder border, double safeZoneRadius) {} - }); - // CraftBukkit end -- 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 -@@ -1369,15 +1367,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - ProfilerFiller gameprofilerfiller = this.getProfiler(); - - 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(); -@@ -1408,9 +1403,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl - } - this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075 - -- this.timings.tileEntityTick.stopTiming(); // Spigot - this.tickingBlockEntities = false; -- co.aikar.timings.TimingHistory.tileEntityTicks += this.blockEntityTickers.size(); // Paper - gameprofilerfiller.pop(); - this.spigotConfig.currentPrimedTnt = 0; // Spigot - } -diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 743a33ae2814c513b84b1a60e50a3c24527568f8..8af3f6c47e05968e7e5c461c3a1607ef45a700a4 100644 ---- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java -+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -128,7 +128,6 @@ public final class NaturalSpawner { - - public static void spawnForChunk(ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnState info, boolean spawnAnimals, boolean spawnMonsters, boolean rareSpawn) { - world.getProfiler().push("spawner"); -- world.timings.mobSpawn.startTiming(); // Spigot - MobCategory[] aenumcreaturetype = NaturalSpawner.SPAWNING_CATEGORIES; - int i = aenumcreaturetype.length; - -@@ -180,7 +179,6 @@ public final class NaturalSpawner { - } - } - -- world.timings.mobSpawn.stopTiming(); // Spigot - world.getProfiler().pop(); - } - -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 29947de9eb6887f2e61516523ff08d8b581b0f53..ae86e1edde015e2ff6cd10c31e0a6065708241af 100644 ---- a/src/main/java/net/minecraft/world/level/block/Block.java -+++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -102,13 +102,6 @@ public class Block extends BlockBehaviour implements ItemLike { - this != Blocks.STRUCTURE_BLOCK && - this != Blocks.JIGSAW; - } -- 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 String descriptionId; -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 7dfabb11d3c8112f6daef35d204a2e324f4ddb5e..f2ef63d69bfc6fb3b3dc4b3b2938733d1c371746 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,14 +33,9 @@ import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry; - 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 { - static boolean ignoreTileUpdates; // Paper - Perf: Optimize Hoppers - -- 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 7c11853c5090fbc4fa5b3e73a69acf166158fdec..c0ce5d4c3189337b06476c16558e12d3f8127797 100644 ---- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -666,7 +666,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(this.locX, this.locZ).getEntityChunk().callEntitiesLoadEvent(); // Paper - rewrite chunk system - - 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()); -@@ -686,7 +685,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - } - } - server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(bukkitChunk)); -- } // Paper - } - } - } -@@ -1026,7 +1024,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - ProfilerFiller gameprofilerfiller = LevelChunk.this.level.getProfiler(); - - gameprofilerfiller.push(this::getType); -- this.blockEntity.tickTimer.startTiming(); // Spigot - BlockState iblockdata = LevelChunk.this.getBlockState(blockposition); - - if (this.blockEntity.getType().isValid(iblockdata)) { -@@ -1052,9 +1049,6 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p - LevelChunk.this.removeBlockEntity(this.getPos()); - // Paper end - Prevent block entity and entity crashes - // Spigot start -- } finally { -- this.blockEntity.tickTimer.stopTiming(); -- // Spigot end - } - } - } -diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -index 2f4d6b56301195f8d39ed50dffe842464065bfe1..22f1ed383313829b8af4badda9ef8dc85cae8fd1 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java -@@ -1,6 +1,5 @@ - 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; -@@ -297,7 +296,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) { -@@ -337,7 +336,7 @@ public class CraftScheduler implements BukkitScheduler { - } - } - } -- }){{this.timings=co.aikar.timings.MinecraftTimings.getCancelTasksTimer(plugin);}}; // Paper -+ }); // Paper - this.handle(task, 0L); - for (CraftTask taskPending = this.head.getNext(); taskPending != null; taskPending = taskPending.getNext()) { - if (taskPending == task) { -@@ -504,10 +503,8 @@ 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(currentTick); // Paper - } - -@@ -550,7 +547,6 @@ public class CraftScheduler implements BukkitScheduler { - } - - void parsePending() { // Paper -- if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); // Paper - CraftTask head = this.head; - CraftTask task = head.getNext(); - CraftTask lastTask = head; -@@ -569,7 +565,6 @@ public class CraftScheduler implements BukkitScheduler { - task.setNext(null); - } - this.head = lastTask; -- if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); // Paper - } - - 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 ba369f3dcfdf498e971dc4405d39657a9b6e97cc..8870bfa9df854173d105326ebd6bb3c0ea1bdb88 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java -+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java -@@ -2,14 +2,10 @@ 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.spigotmc.CustomTimingsHandler; // Spigot --import co.aikar.timings.MinecraftTimings; // Paper --import co.aikar.timings.Timing; // Paper - - public class CraftTask implements BukkitTask, Runnable { // Spigot - -@@ -31,7 +27,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot - private long nextRun; - 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(); -@@ -61,7 +56,6 @@ public class CraftTask implements BukkitTask, Runnable { // Spigot - } - this.id = id; - this.period = period; -- timings = task != null ? MinecraftTimings.getPluginTaskTimings(this, period) : NullTimingHandler.NULL; // Paper - } - - @Override -@@ -81,13 +75,11 @@ 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() { -diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -index b3e1adeb932da9b3bed16acd94e2f16da48a7c72..e9798517b9211c50a20ea5c69603aab35f614f02 100644 ---- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java -@@ -115,16 +115,9 @@ public final class CraftScoreboardManager implements ScoreboardManager { - 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/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index d06aab9bd5cd901c8367f9680f5d27ddb17b3dc4..0d8a128b0506b903e2cc200d6e684fd570217aec 100644 ---- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -202,7 +202,6 @@ public final class CraftMagicNumbers implements UnsafeValues { - // Paper start - @Override - public void reportTimings() { -- co.aikar.timings.TimingsExport.reportTimings(); - } - // Paper end - -diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index c7efdd1483b309ed8121e2203216ab288daa3117..dfcb161a77e9a7cce6488d24815cb82ff520dfa2 100644 ---- a/src/main/java/org/spigotmc/ActivationRange.java -+++ b/src/main/java/org/spigotmc/ActivationRange.java -@@ -34,7 +34,6 @@ 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; -@@ -167,7 +166,6 @@ public class ActivationRange - */ - public static void activateEntities(Level world) - { -- MinecraftTimings.entityActivationCheckTimer.startTiming(); - final int miscActivationRange = world.spigotConfig.miscActivationRange; - final int raiderActivationRange = world.spigotConfig.raiderActivationRange; - final int animalActivationRange = world.spigotConfig.animalActivationRange; -@@ -226,7 +224,6 @@ public class ActivationRange - } - // Paper end - } -- MinecraftTimings.entityActivationCheckTimer.stopTiming(); - } - - /** diff --git a/patches/server/0004-Leaves-Server-Utils.patch b/patches/server/0004-Leaves-Server-Utils.patch index ab1f933a..e9bf2e11 100644 --- a/patches/server/0004-Leaves-Server-Utils.patch +++ b/patches/server/0004-Leaves-Server-Utils.patch @@ -5,18 +5,18 @@ Subject: [PATCH] Leaves Server Utils diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..b5283b7a59c76e75ba9a822f315ba0d813df8cfb 100644 +index a15546e433ebba6c0de01bdaaef201a3d99a87b5..922996adcf2b85e55a934191e90a12c42f169b0f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -429,6 +429,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - private UUID originWorld; +@@ -389,6 +389,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean freezeLocked = false; // Paper - Freeze Tick Lock API public boolean fixedPose = false; // Paper - Expand Pose API + private final int despawnTime; // Paper - entity despawn time limit + private CompoundTag leavesData = new CompoundTag(); // Leaves - Leaves ex data public void setOrigin(@javax.annotation.Nonnull Location location) { this.origin = location.toVector(); -@@ -2558,6 +2559,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2690,6 +2691,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess nbttagcompound.putBoolean("Paper.FreezeLock", true); } // Paper end @@ -24,7 +24,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..b5283b7a59c76e75ba9a822f315ba0d8 return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT"); -@@ -2705,6 +2707,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2838,6 +2840,11 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess freezeLocked = nbt.getBoolean("Paper.FreezeLock"); } // Paper end @@ -36,8 +36,8 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..b5283b7a59c76e75ba9a822f315ba0d8 } catch (Throwable throwable) { CrashReport crashreport = CrashReport.forThrowable(throwable, "Loading entity NBT"); -@@ -4992,4 +4999,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return ((net.minecraft.server.level.ServerChunkCache) level.getChunkSource()).isPositionTicking(this); +@@ -5325,4 +5332,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return ((net.minecraft.server.level.ServerLevel) this.level).isPositionEntityTicking(this.blockPosition()); } // Paper end - Expose entity id counter + @@ -49,7 +49,7 @@ index 4b54d0ea31062972e68ee8fafe3cfaf68f65a5cd..b5283b7a59c76e75ba9a822f315ba0d8 } diff --git a/src/main/java/org/leavesmc/leaves/LeavesLogger.java b/src/main/java/org/leavesmc/leaves/LeavesLogger.java new file mode 100644 -index 0000000000000000000000000000000000000000..47347a3bdab2ff9818bf8198291d2dabec7da8c6 +index 0000000000000000000000000000000000000000..bc45935c96553c9bd9d9b6ab3a64e28f52862198 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/LeavesLogger.java @@ -0,0 +1,24 @@ @@ -70,11 +70,11 @@ index 0000000000000000000000000000000000000000..47347a3bdab2ff9818bf8198291d2dab + } + + public void severe(String msg, Exception exception) { -+ this.severe(msg + ", " + exception.getCause() + ": " + exception.getMessage()); ++ this.log(Level.SEVERE, msg, exception); + } + + public void warning(String msg, Exception exception) { -+ this.warning(msg + ", " + exception.getCause() + ": " + exception.getMessage()); ++ this.log(Level.WARNING, msg, exception); + } +} diff --git a/src/main/java/org/leavesmc/leaves/command/LeavesCommandUtil.java b/src/main/java/org/leavesmc/leaves/command/LeavesCommandUtil.java @@ -324,24 +324,19 @@ index 0000000000000000000000000000000000000000..440c4d903e145229bc54eb5b6f3578fd +} diff --git a/src/main/java/org/leavesmc/leaves/util/MathUtils.java b/src/main/java/org/leavesmc/leaves/util/MathUtils.java new file mode 100644 -index 0000000000000000000000000000000000000000..a6a4fd61644815a7fb01ab1a5844a34f39e57e6d +index 0000000000000000000000000000000000000000..56050158a7e2217f4fdad11067cc377dda9ca770 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/MathUtils.java -@@ -0,0 +1,100 @@ +@@ -0,0 +1,96 @@ +package org.leavesmc.leaves.util; + +import org.bukkit.util.NumberConversions; +import org.bukkit.util.Vector; ++import org.jetbrains.annotations.NotNull; + +import java.util.regex.Pattern; + +public class MathUtils { -+ // Lag ? -+ public static void clean(Vector vector) { -+ if (!NumberConversions.isFinite(vector.getX())) vector.setX(0); -+ if (!NumberConversions.isFinite(vector.getY())) vector.setY(0); -+ if (!NumberConversions.isFinite(vector.getZ())) vector.setZ(0); -+ } + + private static final Pattern numericPattern = Pattern.compile("^-?[1-9]\\d*$|^0$"); + @@ -349,7 +344,7 @@ index 0000000000000000000000000000000000000000..a6a4fd61644815a7fb01ab1a5844a34f + return numericPattern.matcher(str).matches(); + } + -+ public static float[] fetchYawPitch(Vector dir) { ++ public static float @NotNull [] fetchYawPitch(@NotNull Vector dir) { + double x = dir.getX(); + double z = dir.getZ(); + @@ -370,7 +365,7 @@ index 0000000000000000000000000000000000000000..a6a4fd61644815a7fb01ab1a5844a34f + return out; + } + -+ public static float fetchPitch(Vector dir) { ++ public static float fetchPitch(@NotNull Vector dir) { + double x = dir.getX(); + double z = dir.getZ(); + @@ -388,6 +383,7 @@ index 0000000000000000000000000000000000000000..a6a4fd61644815a7fb01ab1a5844a34f + return result; + } + ++ @NotNull + public static Vector getDirection(double rotX, double rotY) { + Vector vector = new Vector(); + diff --git a/patches/server/0005-Update-version-fetcher-repo.patch b/patches/server/0005-Update-version-fetcher-repo.patch index a2976ff7..84e36586 100644 --- a/patches/server/0005-Update-version-fetcher-repo.patch +++ b/patches/server/0005-Update-version-fetcher-repo.patch @@ -27,11 +27,11 @@ index 532306cacd52579cdf37e4aca25887b1ed3ba6a1..917ffaae401f3374d07d7fb7c024234a if (data == null) { return null; diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -index 0d8a128b0506b903e2cc200d6e684fd570217aec..cf30f051272b7548b5674a3d059bbcacabec963c 100644 +index 83020837e29ee627b1081daddb4bdee147b95af3..b0f9010e28d865f059675954cd1db575c61d675e 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java -@@ -488,7 +488,7 @@ public final class CraftMagicNumbers implements UnsafeValues { - +@@ -505,7 +505,7 @@ public final class CraftMagicNumbers implements UnsafeValues { + // Paper start @Override public com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() { - return new com.destroystokyo.paper.PaperVersionFetcher(); diff --git a/patches/server/0006-Leaves-Server-Config-And-Command.patch b/patches/server/0006-Leaves-Server-Config-And-Command.patch index ec3fd56e..ce350737 100644 --- a/patches/server/0006-Leaves-Server-Config-And-Command.patch +++ b/patches/server/0006-Leaves-Server-Config-And-Command.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Server Config And Command diff --git a/build.gradle.kts b/build.gradle.kts -index 0c537cd70a1b8a7d7ccd78ba212de0cae8cb6bbc..d3bc2ed92763b701d91a8c705818e7f4e12e45f0 100644 +index d88a9d1908373ba44143013cda1ae51477a835cf..b8132401ddaedf13bc9ddc74524166d0e0dcf419 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -221,6 +221,14 @@ tasks.registerRunTask("runDevServer") { +@@ -240,6 +240,14 @@ tasks.registerRunTask("runDevServer") { jvmArgs("-DPaper.pushPaperAssetsRoot=true") } @@ -24,10 +24,10 @@ index 0c537cd70a1b8a7d7ccd78ba212de0cae8cb6bbc..d3bc2ed92763b701d91a8c705818e7f4 description = "Spin up a test server from the Mojang mapped bundler jar" classpath(rootProject.tasks.named("createMojmapBundlerJar").flatMap { it.outputZip }) diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index a108ebfe472c908e86e0af2cfd9cb63083f58eb5..f97b2cb3ea855e6e250cabf357a050cd52be8f70 100644 +index faeb700647522379046f3cb3abcf478ff5aae95d..a8c5fa172b01b85df51fa3b4d20b6c4f734dfdda 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -238,6 +238,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -236,6 +236,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface this.server.spark.registerCommandBeforePlugins(this.server); // Paper - spark com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - load version history now @@ -38,10 +38,10 @@ index a108ebfe472c908e86e0af2cfd9cb63083f58eb5..f97b2cb3ea855e6e250cabf357a050cd this.setPvpAllowed(dedicatedserverproperties.pvp); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index c7df339aeb62ee627edaf1bb4c8474b61e357ba6..25e8b14e79edcf0ad2bcd224e049e0c04f8a5e5c 100644 +index ac8af406180bc680d46e8edc3da0fc2e5211345a..3d18ffbf3604705d8b99f69df156392dfed1863b 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1100,6 +1100,7 @@ public final class CraftServer implements Server { +@@ -1114,6 +1114,7 @@ public final class CraftServer implements Server { playerMetadata.removeAll(plugin); } // Paper end @@ -49,7 +49,7 @@ index c7df339aeb62ee627edaf1bb4c8474b61e357ba6..25e8b14e79edcf0ad2bcd224e049e0c0 this.reloadData(); org.spigotmc.SpigotConfig.registerCommands(); // Spigot io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper -@@ -2989,6 +2990,14 @@ public final class CraftServer implements Server { +@@ -3030,6 +3031,14 @@ public final class CraftServer implements Server { { return CraftServer.this.console.paperConfigurations.createLegacyObject(CraftServer.this.console); } @@ -65,7 +65,7 @@ index c7df339aeb62ee627edaf1bb4c8474b61e357ba6..25e8b14e79edcf0ad2bcd224e049e0c0 @Override public void restart() { diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 3f81f87def8e591938618c3ade8daaf5ab0f84a7..4f3c67cd469dd9c05cf8b917fe890451d1219a9c 100644 +index a41e6f5dc2d5516f081d7340e2dacffaf5663485..8f1230fcfa4fc27b513a4eb1023f107c8c7dd818 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 { @@ -85,32 +85,39 @@ index 3f81f87def8e591938618c3ade8daaf5ab0f84a7..4f3c67cd469dd9c05cf8b917fe890451 .withRequiredArg() diff --git a/src/main/java/org/leavesmc/leaves/LeavesConfig.java b/src/main/java/org/leavesmc/leaves/LeavesConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..313beaa7eef481bfc42d89959e227dac6558fab9 +index 0000000000000000000000000000000000000000..248536658e094ce5b035c16da54658b80e967829 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/LeavesConfig.java -@@ -0,0 +1,901 @@ +@@ -0,0 +1,961 @@ +package org.leavesmc.leaves; + +import com.destroystokyo.paper.util.SneakyThrow; +import io.papermc.paper.configuration.GlobalConfiguration; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; -+import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.configuration.file.YamlConfiguration; ++import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.command.LeavesCommand; -+import org.leavesmc.leaves.config.ConfigVerifyImpl; +import org.leavesmc.leaves.config.GlobalConfig; -+import org.leavesmc.leaves.config.GlobalConfigManager; ++import org.leavesmc.leaves.config.GlobalConfigCategory; +import org.leavesmc.leaves.config.RemovedConfig; ++import org.leavesmc.leaves.config.GlobalConfigManager; ++import org.leavesmc.leaves.region.RegionFileFormat; +import org.leavesmc.leaves.util.MathUtils; + ++import org.leavesmc.leaves.config.ConfigValidatorImpl.BooleanConfigValidator; ++import org.leavesmc.leaves.config.ConfigValidatorImpl.IntConfigValidator; ++import org.leavesmc.leaves.config.ConfigValidatorImpl.StringConfigValidator; ++import org.leavesmc.leaves.config.ConfigValidatorImpl.DoubleConfigValidator; ++import org.leavesmc.leaves.config.ConfigValidatorImpl.ListConfigValidator; ++import org.leavesmc.leaves.config.ConfigValidatorImpl.EnumConfigValidator; ++ +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Locale; -+import java.util.logging.Level; +import java.util.Random; + +import org.leavesmc.leaves.protocol.CarpetServerProtocol.CarpetRule; @@ -127,7 +134,7 @@ index 0000000000000000000000000000000000000000..313beaa7eef481bfc42d89959e227dac + private static File configFile; + public static YamlConfiguration config; + -+ public static void init(final File file) { ++ public static void init(final @NotNull File file) { + LeavesConfig.configFile = file; + config = new YamlConfiguration(); + config.options().setHeader(Collections.singletonList(CONFIG_HEADER)); @@ -140,15 +147,15 @@ index 0000000000000000000000000000000000000000..313beaa7eef481bfc42d89959e227dac + throw new IOException("Can't create file"); + } + } catch (final Exception ex) { -+ Bukkit.getLogger().log(Level.SEVERE, "Failure to create leaves config", ex); ++ LeavesLogger.LOGGER.severe("Failure to create leaves config", ex); + } + } else { + try { + config.load(file); + } catch (final Exception ex) { -+ Bukkit.getLogger().log(Level.SEVERE, "Failure to load leaves config", ex); -+ SneakyThrow.sneaky(ex); /* Rethrow, this is critical */ -+ throw new RuntimeException(ex); // unreachable ++ LeavesLogger.LOGGER.severe("Failure to load leaves config", ex); ++ SneakyThrow.sneaky(ex); ++ throw new RuntimeException(ex); + } + } + @@ -163,7 +170,7 @@ index 0000000000000000000000000000000000000000..313beaa7eef481bfc42d89959e227dac + try { + config.save(LeavesConfig.configFile); + } catch (final Exception ex) { -+ Bukkit.getLogger().log(Level.SEVERE, "Unable to save leaves config", ex); ++ LeavesLogger.LOGGER.severe("Unable to save leaves config", ex); + } + } + @@ -179,816 +186,869 @@ index 0000000000000000000000000000000000000000..313beaa7eef481bfc42d89959e227dac + MinecraftServer.getServer().server.syncCommands(); + } + -+ // Leaves start - modify ++ public static ModifyConfig modify = new ModifyConfig(); + -+ // Leaves start - modify - fakeplayer ++ @GlobalConfigCategory("modify") ++ public static class ModifyConfig { + -+ @RemovedConfig(name = "enable", category = "fakeplayer", transform = true) -+ @GlobalConfig(name = "enable", category = {"modify", "fakeplayer"}, verify = FakeplayerVerify.class) -+ public static boolean fakeplayerSupport = true; ++ public FakeplayerConfig fakeplayer = new FakeplayerConfig(); + -+ private static class FakeplayerVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ if (value) { -+ registerCommand("bot", new org.leavesmc.leaves.bot.BotCommand("bot")); -+ org.leavesmc.leaves.bot.agent.Actions.registerAll(); -+ } else { -+ unregisterCommand("bot"); ++ @GlobalConfigCategory("fakeplayer") ++ public static class FakeplayerConfig { ++ ++ @RemovedConfig(name = "enable", category = "fakeplayer", transform = true) ++ @GlobalConfig(value = "enable", validator = FakeplayerValidator.class) ++ public boolean enable = true; ++ ++ private static class FakeplayerValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ if (value) { ++ registerCommand("bot", new org.leavesmc.leaves.bot.BotCommand("bot")); ++ org.leavesmc.leaves.bot.agent.Actions.registerAll(); ++ } else { ++ unregisterCommand("bot"); ++ } ++ } + } -+ } -+ } + -+ @RemovedConfig(name = "unable-fakeplayer-names", category = "fakeplayer", convert = ConfigVerifyImpl.ListConfigVerify.STRING.class, transform = true) -+ @GlobalConfig(name = "unable-fakeplayer-names", category = {"modify", "fakeplayer"}, verify = ConfigVerifyImpl.ListConfigVerify.STRING.class) -+ public static List unableFakeplayerNames = List.of("player-name"); ++ @RemovedConfig(name = "unable-fakeplayer-names", category = "fakeplayer", convert = ListConfigValidator.STRING.class, transform = true) ++ @GlobalConfig(value = "unable-fakeplayer-names", validator = ListConfigValidator.STRING.class) ++ public List unableNames = List.of("player-name"); + -+ @GlobalConfig(name = "limit", category = {"modify", "fakeplayer"}, verify = ConfigVerifyImpl.IntConfigVerify.class) -+ public static int fakeplayerLimit = 10; ++ @GlobalConfig(value = "limit", validator = IntConfigValidator.class) ++ public int limit = 10; + -+ @GlobalConfig(name = "prefix", category = {"modify", "fakeplayer"}, verify = ConfigVerifyImpl.StringConfigVerify.class) -+ public static String fakeplayerPrefix = ""; ++ @GlobalConfig(value = "prefix", validator = StringConfigValidator.class) ++ public String prefix = ""; + -+ @GlobalConfig(name = "suffix", category = {"modify", "fakeplayer"}, verify = ConfigVerifyImpl.StringConfigVerify.class) -+ public static String fakeplayerSuffix = ""; ++ @GlobalConfig(value = "suffix", validator = StringConfigValidator.class) ++ public String suffix = ""; + -+ @GlobalConfig(name = "always-send-data", category = {"modify", "fakeplayer"}) -+ public static boolean alwaysSendFakeplayerData = true; ++ @GlobalConfig(value = "regen-amount", validator = RegenAmountValidator.class) ++ public double regenAmount = 0.0; + -+ @GlobalConfig(name = "resident-fakeplayer", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerResident = false; ++ private static class RegenAmountValidator extends DoubleConfigValidator { ++ @Override ++ public void verify(Double old, Double value) throws IllegalArgumentException { ++ if (value < 0.0) { ++ throw new IllegalArgumentException("regen-amount need >= 0.0"); ++ } ++ } ++ } + -+ @GlobalConfig(name = "open-fakeplayer-inventory", category = {"modify", "fakeplayer"}) -+ public static boolean openFakeplayerInventory = false; ++ @GlobalConfig("always-send-data") ++ public boolean canSendDataAlways = true; + -+ @GlobalConfig(name = "skip-sleep-check", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerSkipSleep = false; ++ @GlobalConfig("resident-fakeplayer") ++ public boolean canResident = false; + -+ @GlobalConfig(name = "spawn-phantom", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerSpawnPhantom = false; ++ @GlobalConfig("open-fakeplayer-inventory") ++ public boolean canOpenInventory = false; + -+ @GlobalConfig(name = "regen-amount", category = {"modify", "fakeplayer"}, verify = RegenAmountVerify.class) -+ public static double fakeplayerRegenAmount = 0.0; ++ @GlobalConfig("skip-sleep-check") ++ public boolean canSkipSleep = false; + -+ private static class RegenAmountVerify extends ConfigVerifyImpl.DoubleConfigVerify { -+ @Override -+ public void check(Double old, Double value) throws IllegalArgumentException { -+ if (value < 0.0) { -+ throw new IllegalArgumentException("regen-amount need >= 0.0"); -+ } -+ } -+ } ++ @GlobalConfig("spawn-phantom") ++ public boolean canSpawnPhantom = false; + -+ @GlobalConfig(name = "use-action", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerUseAction = true; ++ @GlobalConfig("use-action") ++ public boolean canUseAction = true; + -+ @GlobalConfig(name = "modify-config", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerModifyConfig = false; ++ @GlobalConfig("modify-config") ++ public boolean canModifyConfig = false; + -+ @GlobalConfig(name = "manual-save-and-load", category = {"modify", "fakeplayer"}) -+ public static boolean fakeplayerManualSaveAndLoad = false; ++ @GlobalConfig("manual-save-and-load") ++ public boolean canManualSaveAndLoad = false; + -+ @GlobalConfig(name = "cache-skin", category = {"modify", "fakeplayer"}, lock = true) -+ public static boolean fakeplayerCacheSkin = false; ++ @GlobalConfig(value = "cache-skin", lock = true) ++ public boolean useSkinCache = false; ++ } + -+ // Leaves end - modify - fakeplayer ++ public MinecraftOLDConfig oldMC = new MinecraftOLDConfig(); + -+ // Leaves start - modify - minecraft-old ++ @GlobalConfigCategory("minecraft-old") ++ public static class MinecraftOLDConfig { + -+ @RemovedConfig(name = "shears-in-dispenser-can-zero-amount", category = {}, transform = true) -+ @RemovedConfig(name = "shears-in-dispenser-can-zero-amount", category = "modify", transform = true) -+ @GlobalConfig(name = "shears-in-dispenser-can-zero-amount", category = {"modify", "minecraft-old"}) -+ public static boolean shearsInDispenserCanZeroAmount = false; ++ public BlockUpdaterConfig updater = new BlockUpdaterConfig(); + -+ @RemovedConfig(name = "instant-block-updater-reintroduced", category = "modify", transform = true) -+ @GlobalConfig(name = "instant-block-updater-reintroduced", category = {"modify", "minecraft-old"}, lock = true) -+ public static boolean instantBlockUpdaterReintroduced = false; ++ @GlobalConfigCategory("block-updater") ++ public static class BlockUpdaterConfig { ++ @RemovedConfig(name = "instant-block-updater-reintroduced", category = "modify", transform = true) ++ @RemovedConfig(name = "instant-block-updater-reintroduced", category = {"modify", "minecraft-old"}, transform = true) ++ @GlobalConfig(value = "instant-block-updater-reintroduced", lock = true) ++ public boolean instantBlockUpdaterReintroduced = false; + -+ @GlobalConfig(name = "armor-stand-cant-kill-by-mob-projectile", category = {"modify", "minecraft-old"}) -+ public static boolean armorStandCantKillByMobProjectile = false; ++ @RemovedConfig(name = "cce-update-suppression", category = {"modify", "minecraft-old"}, transform = true) ++ @GlobalConfig("cce-update-suppression") ++ public boolean cceUpdateSuppression = false; + -+ @GlobalConfig(name = "cce-update-suppression", category = {"modify", "minecraft-old"}) -+ public static boolean cceUpdateSuppression = false; ++ @RemovedConfig(name = "redstone-wire-dont-connect-if-on-trapdoor", category = "modify", transform = true) ++ @RemovedConfig(name = "redstone-wire-dont-connect-if-on-trapdoor", category = {"modify", "minecraft-old"}, transform = true) ++ @GlobalConfig("redstone-wire-dont-connect-if-on-trapdoor") ++ public boolean redstoneDontCantOnTrapDoor = false; ++ } + -+ @GlobalConfig(name = "villager-infinite-discounts", category = {"modify", "minecraft-old"}, verify = VillagerInfiniteDiscountsVerify.class) -+ public static boolean villagerInfiniteDiscounts = false; ++ @RemovedConfig(name = "shears-in-dispenser-can-zero-amount", category = {}, transform = true) ++ @RemovedConfig(name = "shears-in-dispenser-can-zero-amount", category = "modify", transform = true) ++ @GlobalConfig("shears-in-dispenser-can-zero-amount") ++ public boolean shearsInDispenserCanZeroAmount = false; + -+ private static class VillagerInfiniteDiscountsVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ org.leavesmc.leaves.util.VillagerInfiniteDiscountHelper.doVillagerInfiniteDiscount(value); -+ } -+ } ++ @GlobalConfig("armor-stand-cant-kill-by-mob-projectile") ++ public boolean armorStandCantKillByMobProjectile = false; + -+ @GlobalConfig(name = "copper-bulb-1gt-delay", category = {"modify", "minecraft-old"}) -+ public static boolean copperBulb1gt = false; ++ @GlobalConfig(value = "villager-infinite-discounts", validator = VillagerInfiniteDiscountsValidator.class) ++ public boolean villagerInfiniteDiscounts = false; + -+ @GlobalConfig(name = "crafter-1gt-delay", category = {"modify", "minecraft-old"}) -+ public static boolean crafter1gt = false; ++ private static class VillagerInfiniteDiscountsValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ org.leavesmc.leaves.util.VillagerInfiniteDiscountHelper.doVillagerInfiniteDiscount(value); ++ } ++ } + -+ @RemovedConfig(name = "redstone-wire-dont-connect-if-on-trapdoor", category = "modify", transform = true) -+ @GlobalConfig(name = "redstone-wire-dont-connect-if-on-trapdoor", category = {"modify", "minecraft-old"}) -+ public static boolean redstoneDontCantOnTrapDoor = false; ++ @GlobalConfig("copper-bulb-1gt-delay") ++ public boolean copperBulb1gt = false; + -+ @RemovedConfig(name = "zero-tick-plants", category = "modify", transform = true) -+ @GlobalConfig(name = "zero-tick-plants", category = {"modify", "minecraft-old"}) -+ public static boolean zeroTickPlants = false; ++ @GlobalConfig("crafter-1gt-delay") ++ public boolean crafter1gt = false; + -+ @RemovedConfig(name = "loot-world-random", category = {"modify", "minecraft-old"}, transform = true) -+ @GlobalConfig(name = "rng-fishing", category = {"modify", "minecraft-old"}, lock = true, verify = RNGFishingVerify.class) -+ public static boolean rngFishing = false; ++ @RemovedConfig(name = "zero-tick-plants", category = "modify", transform = true) ++ @GlobalConfig("zero-tick-plants") ++ public boolean zeroTickPlants = false; + -+ private static class RNGFishingVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ LeavesFeatureSet.register(LeavesFeature.of("rng_fishing", value)); -+ } -+ } ++ @RemovedConfig(name = "loot-world-random", category = {"modify", "minecraft-old"}, transform = true) ++ @GlobalConfig(value = "rng-fishing", lock = true, validator = RNGFishingValidator.class) ++ public boolean rngFishing = false; + -+ @GlobalConfig(name = "allow-grindstone-overstacking", category = {"modify", "minecraft-old"}) -+ public static boolean allowGrindstoneOverstacking = false; ++ private static class RNGFishingValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ LeavesFeatureSet.register(LeavesFeature.of("rng_fishing", value)); ++ } ++ } + -+ @GlobalConfig(name = "allow-entity-portal-with-passenger", category = {"modify", "minecraft-old"}) -+ public static boolean allowEntityPortalWithPassenger = true; ++ @GlobalConfig("allow-grindstone-overstacking") ++ public boolean allowGrindstoneOverstacking = false; + -+ @GlobalConfig(name = "disable-gateway-portal-entity-ticking", category = {"modify", "minecraft-old"}) -+ public static boolean disableGatewayPortalEntityTicking = false; ++ @GlobalConfig("allow-entity-portal-with-passenger") ++ public boolean allowEntityPortalWithPassenger = true; + -+ @GlobalConfig(name = "disable-LivingEntity-ai-step-alive-check", category = {"modify", "minecraft-old"}) -+ public static boolean disableLivingEntityAiStepAliveCheck = false; ++ @GlobalConfig("disable-gateway-portal-entity-ticking") ++ public boolean disableGatewayPortalEntityTicking = false; + -+ @GlobalConfig(name = "fix-fortress-mob-spawn", category = {"modify", "minecraft-old"}) -+ public static boolean fixFortressMobSpawn = false; ++ @GlobalConfig("disable-LivingEntity-ai-step-alive-check") ++ public boolean disableLivingEntityAiStepAliveCheck = false; + -+ @GlobalConfig(name = "old-block-entity-behaviour", category = {"modify", "minecraft-old"}) -+ public static boolean oldBlockEntityBehaviour = false; ++ @GlobalConfig("fix-fortress-mob-spawn") ++ public boolean fixFortressMobSpawn = false; + -+ @GlobalConfig(name = "allow-bad-omen-trigger-raid", category = {"modify", "minecraft-old", "revert-raid-changes"}) -+ public static boolean allowBadOmenTriggerRaid = false; ++ @GlobalConfig("old-block-entity-behaviour") ++ public boolean oldBlockEntityBehaviour = false; + -+ @GlobalConfig(name = "give-bad-omen-when-kill-patrol-leader", category = {"modify", "minecraft-old", "revert-raid-changes"}) -+ public static boolean giveBadOmenWhenKillPatrolLeader = false; ++ public RaidConfig raid = new RaidConfig(); + -+ @GlobalConfig(name = "allow-anvil-destroy-item-entities", category = {"modify", "minecraft-old"}) -+ public static boolean allowAnvilDestroyItemEntities = false; ++ @GlobalConfigCategory("revert-raid-changes") ++ public static class RaidConfig { ++ @GlobalConfig("allow-bad-omen-trigger-raid") ++ public boolean allowBadOmenTriggerRaid = false; + -+ // Leaves end - modify - minecraft-old ++ @GlobalConfig("give-bad-omen-when-kill-patrol-leader") ++ public boolean giveBadOmenWhenKillPatrolLeader = false; ++ } + -+ // Leaves start - modify - elytra-aeronautics ++ @GlobalConfig("allow-anvil-destroy-item-entities") ++ public boolean allowAnvilDestroyItemEntities = false; + -+ @GlobalConfig(name = "no-chunk-load", category = {"modify", "elytra-aeronautics"}) -+ public static boolean elytraAeronauticsNoChunk = false; ++ @GlobalConfig("string-tripwire-hook-duplicate") ++ public boolean stringTripwireHookDuplicate = false; ++ } + -+ @GlobalConfig(name = "no-chunk-height", category = {"modify", "elytra-aeronautics"}, verify = ConfigVerifyImpl.DoubleConfigVerify.class) -+ public static double elytraAeronauticsNoChunkHeight = 500.0D; ++ public ElytraAeronauticsConfig elytraAeronautics = new ElytraAeronauticsConfig(); + -+ @GlobalConfig(name = "no-chunk-speed", category = {"modify", "elytra-aeronautics"}, verify = ConfigVerifyImpl.DoubleConfigVerify.class) -+ public static double elytraAeronauticsNoChunkSpeed = -1.0D; ++ @GlobalConfigCategory("elytra-aeronautics") ++ public static class ElytraAeronauticsConfig { ++ @GlobalConfig("no-chunk-load") ++ public boolean noChunk = false; + -+ @GlobalConfig(name = "message", category = {"modify", "elytra-aeronautics"}) -+ public static boolean elytraAeronauticsNoChunkMes = true; ++ @GlobalConfig(value = "no-chunk-height", validator = DoubleConfigValidator.class) ++ public double noChunkHeight = 500.0D; + -+ @GlobalConfig(name = "message-start", category = {"modify", "elytra-aeronautics"}, verify = ConfigVerifyImpl.StringConfigVerify.class) -+ public static String elytraAeronauticsNoChunkStartMes = "Flight enter cruise mode"; ++ @GlobalConfig(value = "no-chunk-speed", validator = DoubleConfigValidator.class) ++ public double noChunkSpeed = -1.0D; + -+ @GlobalConfig(name = "message-end", category = {"modify", "elytra-aeronautics"}, verify = ConfigVerifyImpl.StringConfigVerify.class) -+ public static String elytraAeronauticsNoChunkEndMes = "Flight exit cruise mode"; ++ @GlobalConfig("message") ++ public boolean noChunkMes = true; + -+ // Leaves end - modify - elytra-aeronautics ++ @GlobalConfig(value = "message-start", validator = StringConfigValidator.class) ++ public String noChunkStartMes = "Flight enter cruise mode"; + -+ @RemovedConfig(name = "redstone-shears-wrench", category = {}, transform = true) -+ @GlobalConfig(name = "redstone-shears-wrench", category = "modify") -+ public static boolean redstoneShearsWrench = true; ++ @GlobalConfig(value = "message-end", validator = StringConfigValidator.class) ++ public String noChunkEndMes = "Flight exit cruise mode"; ++ } + -+ @RemovedConfig(name = "budding-amethyst-can-push-by-piston", category = {}, transform = true) -+ @GlobalConfig(name = "budding-amethyst-can-push-by-piston", category = "modify") -+ public static boolean buddingAmethystCanPushByPiston = false; ++ @RemovedConfig(name = "redstone-shears-wrench", category = {}, transform = true) ++ @GlobalConfig("redstone-shears-wrench") ++ public boolean redstoneShearsWrench = true; + -+ @RemovedConfig(name = "spectator-dont-get-advancement", category = {}, transform = true) -+ @GlobalConfig(name = "spectator-dont-get-advancement", category = "modify") -+ public static boolean spectatorDontGetAdvancement = false; ++ @RemovedConfig(name = "budding-amethyst-can-push-by-piston", category = {}, transform = true) ++ @GlobalConfig("budding-amethyst-can-push-by-piston") ++ public boolean buddingAmethystCanPushByPiston = false; + -+ @RemovedConfig(name = "stick-change-armorstand-arm-status", category = {}, transform = true) -+ @GlobalConfig(name = "stick-change-armorstand-arm-status", category = "modify") -+ public static boolean stickChangeArmorStandArmStatus = true; ++ @RemovedConfig(name = "spectator-dont-get-advancement", category = {}, transform = true) ++ @GlobalConfig("spectator-dont-get-advancement") ++ public boolean spectatorDontGetAdvancement = false; + -+ @RemovedConfig(name = "snowball-and-egg-can-knockback-player", category = {}, transform = true) -+ @GlobalConfig(name = "snowball-and-egg-can-knockback-player", category = "modify") -+ public static boolean snowballAndEggCanKnockback = true; ++ @RemovedConfig(name = "stick-change-armorstand-arm-status", category = {}, transform = true) ++ @GlobalConfig("stick-change-armorstand-arm-status") ++ public boolean stickChangeArmorStandArmStatus = true; + -+ @GlobalConfig(name = "flatten-triangular-distribution", category = "modify") -+ public static boolean flattenTriangularDistribution = false; ++ @RemovedConfig(name = "snowball-and-egg-can-knockback-player", category = {}, transform = true) ++ @GlobalConfig("snowball-and-egg-can-knockback-player") ++ public boolean snowballAndEggCanKnockback = true; + -+ @GlobalConfig(name = "player-operation-limiter", category = "modify") -+ public static boolean playerOperationLimiter = false; ++ @GlobalConfig("flatten-triangular-distribution") ++ public boolean flattenTriangularDistribution = false; + -+ @GlobalConfig(name = "renewable-elytra", category = "modify", verify = RenewableElytraVerify.class) -+ public static double renewableElytra = -1.0F; ++ @GlobalConfig("player-operation-limiter") ++ public boolean playerOperationLimiter = false; + -+ private static class RenewableElytraVerify extends ConfigVerifyImpl.DoubleConfigVerify { -+ @Override -+ public void check(Double old, Double value) throws IllegalArgumentException { -+ if (value > 1.0) { -+ throw new IllegalArgumentException("renewable-elytra need <= 1.0f"); ++ @GlobalConfig(value = "renewable-elytra", validator = RenewableElytraValidator.class) ++ public double renewableElytra = -1.0F; ++ ++ private static class RenewableElytraValidator extends DoubleConfigValidator { ++ @Override ++ public void verify(Double old, Double value) throws IllegalArgumentException { ++ if (value > 1.0) { ++ throw new IllegalArgumentException("renewable-elytra need <= 1.0f"); ++ } + } + } -+ } + -+ public static int shulkerBoxStackSize = 1; -+ @GlobalConfig(name = "stackable-shulker-boxes", category = "modify", verify = StackableShulkerVerify.class) -+ private static String stackableShulkerBoxes = "false"; ++ public int shulkerBoxStackSize = 1; ++ @GlobalConfig(value = "stackable-shulker-boxes", validator = StackableShulkerValidator.class) ++ private String stackableShulkerBoxes = "false"; + -+ private static class StackableShulkerVerify extends ConfigVerifyImpl.StringConfigVerify { -+ @Override -+ public void check(String old, String value) throws IllegalArgumentException { -+ String realValue = MathUtils.isNumeric(value) ? value : value.equals("true") ? "2" : "1"; -+ shulkerBoxStackSize = Integer.parseInt(realValue); ++ private static class StackableShulkerValidator extends StringConfigValidator { ++ @Override ++ public void verify(String old, String value) throws IllegalArgumentException { ++ String realValue = MathUtils.isNumeric(value) ? value : value.equals("true") ? "2" : "1"; ++ LeavesConfig.modify.shulkerBoxStackSize = Integer.parseInt(realValue); ++ } + } -+ } -+ -+ @GlobalConfig(name = "force-void-trade", category = "modify") -+ public static boolean forceVoidTrade = false; + -+ @GlobalConfig(name = "disable-moved-wrongly-threshold", category = "modify") -+ public static boolean disableMovedWronglyThreshold = false; ++ @GlobalConfig("force-void-trade") ++ public boolean forceVoidTrade = false; + -+ @GlobalConfig(name = "mc-technical-survival-mode", category = "modify", verify = McTechnicalModeVerify.class, lock = true) -+ public static boolean mcTechnicalMode = true; ++ @GlobalConfig(value = "mc-technical-survival-mode", validator = McTechnicalModeValidator.class, lock = true) ++ public boolean mcTechnicalMode = true; + -+ private static class McTechnicalModeVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ if (value) { -+ org.leavesmc.leaves.util.McTechnicalModeHelper.doMcTechnicalMode(); ++ private static class McTechnicalModeValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ if (value) { ++ org.leavesmc.leaves.util.McTechnicalModeHelper.doMcTechnicalMode(); ++ } + } + } -+ } + -+ @GlobalConfig(name = "return-nether-portal-fix", category = "modify") -+ public static boolean netherPortalFix = false; ++ @GlobalConfig("return-nether-portal-fix") ++ public boolean netherPortalFix = false; + -+ @GlobalConfig(name = "use-vanilla-random", category = "modify", lock = true, verify = UseVanillaRandomVerify.class) -+ public static boolean useVanillaRandom = false; ++ @GlobalConfig(value = "use-vanilla-random", lock = true, validator = UseVanillaRandomValidator.class) ++ public boolean useVanillaRandom = false; + -+ private static class UseVanillaRandomVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ LeavesFeatureSet.register(LeavesFeature.of("use_vanilla_random", value)); ++ private static class UseVanillaRandomValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ LeavesFeatureSet.register(LeavesFeature.of("use_vanilla_random", value)); ++ } + } -+ } + -+ @GlobalConfig(name = "fix-update-suppression-crash", category = "modify") -+ public static boolean updateSuppressionCrashFix = true; ++ @GlobalConfig("fix-update-suppression-crash") ++ public boolean updateSuppressionCrashFix = true; + -+ @GlobalConfig(name = "bedrock-break-list", category = "modify", lock = true) -+ public static boolean bedrockBreakList = false; ++ @GlobalConfig(value = "bedrock-break-list", lock = true) ++ public boolean bedrockBreakList = false; + -+ @GlobalConfig(name = "disable-distance-check-for-use-item", category = "modify", verify = DisableDistanceCheckForUseItemVerify.class) -+ public static boolean disableDistanceCheckForUseItem = false; ++ @GlobalConfig(value = "disable-distance-check-for-use-item", validator = DisableDistanceCheckForUseItemValidator.class) ++ public boolean disableDistanceCheckForUseItem = false; + -+ private static class DisableDistanceCheckForUseItemVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ if (alternativeBlockPlacement != AlternativePlaceType.NONE && !value) { -+ throw new IllegalArgumentException("alternative-block-placement is enable, disable-distance-check-for-use-item always need true"); ++ private static class DisableDistanceCheckForUseItemValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ if (!value && old != null && LeavesConfig.protocol.alternativeBlockPlacement != ProtocolConfig.AlternativePlaceType.NONE) { ++ throw new IllegalArgumentException("alternative-block-placement is enable, disable-distance-check-for-use-item always need true"); ++ } + } + } -+ } + -+ @GlobalConfig(name = "no-feather-falling-trample", category = "modify") -+ public static boolean noFeatherFallingTrample = false; ++ @GlobalConfig("no-feather-falling-trample") ++ public boolean noFeatherFallingTrample = false; + -+ @GlobalConfig(name = "shared-villager-discounts", category = "modify") -+ public static boolean sharedVillagerDiscounts = false; ++ @GlobalConfig("shared-villager-discounts") ++ public boolean sharedVillagerDiscounts = false; + -+ @GlobalConfig(name = "disable-check-out-of-order-command", category = "modify") -+ public static boolean disableCheckOutOfOrderCommand = false; ++ @GlobalConfig("disable-check-out-of-order-command") ++ public boolean disableCheckOutOfOrderCommand = false; + -+ @GlobalConfig(name = "despawn-enderman-with-block", category = "modify") -+ public static boolean despawnEndermanWithBlock = false; ++ @GlobalConfig("despawn-enderman-with-block") ++ public boolean despawnEndermanWithBlock = false; + -+ @GlobalConfig(name = "creative-no-clip", category = "modify", verify = CreativeNoClipVerify.class) -+ public static boolean creativeNoClip = false; ++ @GlobalConfig(value = "creative-no-clip", validator = CreativeNoClipValidator.class) ++ public boolean creativeNoClip = false; + -+ private static class CreativeNoClipVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ CarpetRules.register(CarpetRule.of("carpet", "creativeNoClip", value)); ++ private static class CreativeNoClipValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ CarpetRules.register(CarpetRule.of("carpet", "creativeNoClip", value)); ++ } + } -+ } + -+ @GlobalConfig(name = "shave-snow-layers", category = "modify") -+ public static boolean shaveSnowLayers = true; ++ @GlobalConfig("shave-snow-layers") ++ public boolean shaveSnowLayers = true; + -+ @GlobalConfig(name = "ignore-lc", category = "modify") -+ public static boolean ignoreLC = false; ++ @GlobalConfig("ignore-lc") ++ public boolean ignoreLC = false; + -+ @GlobalConfig(name = "disable-packet-limit", category = "modify") -+ public static boolean disablePacketLimit = false; ++ @GlobalConfig("disable-packet-limit") ++ public boolean disablePacketLimit = false; + -+ @GlobalConfig(name = "lava-riptide", category = "modify", verify = LavaRiptideVerify.class) -+ public static boolean lavaRiptide = false; ++ @GlobalConfig(value = "lava-riptide", validator = LavaRiptideValidator.class) ++ public boolean lavaRiptide = false; + -+ private static class LavaRiptideVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ LeavesFeatureSet.register(LeavesFeature.of("lava_riptide", value)); ++ private static class LavaRiptideValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ LeavesFeatureSet.register(LeavesFeature.of("lava_riptide", value)); ++ } + } -+ } + -+ @GlobalConfig(name = "no-block-update-command", category = "modify", verify = NoBlockUpdateVerify.class) -+ public static boolean noBlockUpdateCommand = false; ++ @GlobalConfig(value = "no-block-update-command", validator = NoBlockUpdateValidator.class) ++ public boolean noBlockUpdateCommand = false; + -+ @GlobalConfig(name = "no-tnt-place-update", category = "modify") -+ public static boolean noTNTPlaceUpdate = false; -+ -+ private static class NoBlockUpdateVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ if (value) { -+ registerCommand("blockupdate", new org.leavesmc.leaves.command.NoBlockUpdateCommand("blockupdate")); -+ } else { -+ unregisterCommand("blockupdate"); ++ private static class NoBlockUpdateValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ if (value) { ++ registerCommand("blockupdate", new org.leavesmc.leaves.command.NoBlockUpdateCommand("blockupdate")); ++ } else { ++ unregisterCommand("blockupdate"); ++ } + } + } -+ } + -+ @GlobalConfig(name = "raider-die-skip-self-raid-check", category = "modify") -+ public static boolean skipSelfRaidCheck = false; ++ @GlobalConfig("no-tnt-place-update") ++ public boolean noTNTPlaceUpdate = false; + -+ @GlobalConfig(name = "container-passthrough", category = "modify") -+ public static boolean containerPassthrough = false; ++ @GlobalConfig("raider-die-skip-self-raid-check") ++ public boolean skipSelfRaidCheck = false; + -+ @GlobalConfig(name = "avoid-anvil-too-expensive", category = "modify", verify = AnvilNotExpensiveVerify.class) -+ public static boolean avoidAnvilTooExpensive = false; ++ @GlobalConfig("container-passthrough") ++ public boolean containerPassthrough = false; + -+ private static class AnvilNotExpensiveVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ CarpetRules.register(CarpetRule.of("pca", "avoidAnvilTooExpensive", value)); ++ @GlobalConfig(value = "avoid-anvil-too-expensive", validator = AnvilNotExpensiveValidator.class) ++ public boolean avoidAnvilTooExpensive = false; ++ ++ private static class AnvilNotExpensiveValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ CarpetRules.register(CarpetRule.of("pca", "avoidAnvilTooExpensive", value)); ++ } + } -+ } + -+ @GlobalConfig(name = "bow-infinity-fix", category = "modify") -+ public static boolean bowInfinityFix = false; ++ @GlobalConfig("bow-infinity-fix") ++ public boolean bowInfinityFix = false; + -+ @GlobalConfig(name = "hopper-counter", category = "modify") -+ public static boolean hopperCounter = false; ++ @GlobalConfig("hopper-counter") ++ public boolean hopperCounter = false; + -+ @GlobalConfig(name = "spider-jockeys-drop-gapples", category = "modify", verify = JockeysDropGAppleVerify.class) -+ public static double spiderJockeysDropGapples = -1.0; ++ @GlobalConfig(value = "spider-jockeys-drop-gapples", validator = JockeysDropGAppleValidator.class) ++ public double spiderJockeysDropGapples = -1.0; + -+ private static class JockeysDropGAppleVerify extends ConfigVerifyImpl.DoubleConfigVerify { -+ @Override -+ public void check(Double old, Double value) throws IllegalArgumentException { -+ if (value > 1.0) { -+ throw new IllegalArgumentException("spider-jockeys-drop-gapples need <= 1.0f"); ++ private static class JockeysDropGAppleValidator extends DoubleConfigValidator { ++ @Override ++ public void verify(Double old, Double value) throws IllegalArgumentException { ++ if (value > 1.0) { ++ throw new IllegalArgumentException("spider-jockeys-drop-gapples need <= 1.0f"); ++ } + } + } -+ } + -+ @GlobalConfig(name = "renewable-deepslate", category = "modify") -+ public static boolean renewableDeepslate = false; ++ @GlobalConfig("renewable-deepslate") ++ public boolean renewableDeepslate = false; + -+ @GlobalConfig(name = "renewable-sponges", category = "modify") -+ public static boolean renewableSponges = false; ++ @GlobalConfig("renewable-sponges") ++ public boolean renewableSponges = false; + -+ @GlobalConfig(name = "renewable-coral", category = "modify", verify = RenewableCoralVerify.class) -+ public static RenewableCoralType renewableCoral = RenewableCoralType.FALSE; ++ @GlobalConfig(value = "renewable-coral", validator = RenewableCoralValidator.class) ++ public RenewableCoralType renewableCoral = RenewableCoralType.FALSE; + -+ public enum RenewableCoralType { -+ FALSE, TRUE, EXPANDED -+ } ++ public enum RenewableCoralType { ++ FALSE, TRUE, EXPANDED ++ } + -+ private static class RenewableCoralVerify extends ConfigVerifyImpl.EnumConfigVerify { -+ @Override -+ public void check(RenewableCoralType old, RenewableCoralType value) throws IllegalArgumentException { -+ CarpetRules.register(CarpetRule.of("carpet", "renewableCoral", value)); ++ private static class RenewableCoralValidator extends EnumConfigValidator { ++ @Override ++ public void verify(RenewableCoralType old, RenewableCoralType value) throws IllegalArgumentException { ++ CarpetRules.register(CarpetRule.of("carpet", "renewableCoral", value)); ++ } + } -+ } + -+ @GlobalConfig(name = "fast-resume", category = "modify") -+ public static boolean fastResume = false; ++ @GlobalConfig("fast-resume") ++ public boolean fastResume = false; + -+ @GlobalConfig(name = "force-peaceful-mode", category = "modify", verify = ForcePeacefulModeVerify.class) -+ public static int forcePeacefulMode = -1; ++ @GlobalConfig(value = "force-peaceful-mode", validator = ForcePeacefulModeValidator.class) ++ public int forcePeacefulMode = -1; + -+ private static class ForcePeacefulModeVerify extends ConfigVerifyImpl.IntConfigVerify { -+ @Override -+ public void check(Integer old, Integer value) throws IllegalArgumentException { -+ for (ServerLevel level : MinecraftServer.getServer().getAllLevels()) { -+ level.chunkSource.peacefulModeSwitchTick = value; ++ private static class ForcePeacefulModeValidator extends IntConfigValidator { ++ @Override ++ public void verify(Integer old, Integer value) throws IllegalArgumentException { ++ for (ServerLevel level : MinecraftServer.getServer().getAllLevels()) { ++ level.chunkSource.peacefulModeSwitchTick = value; ++ } + } + } -+ } -+ -+ @GlobalConfig(name = "disable-vault-blacklist", category = "modify") -+ public static boolean disableVaultBlacklist = false; + -+ @RemovedConfig(name = "tick-command", category = "modify") -+ @RemovedConfig(name = "player-can-edit-sign", category = "modify") -+ @RemovedConfig(name = "mending-compatibility-infinity", category = {"modify", "minecraft-old"}) -+ @RemovedConfig(name = "protection-stacking", category = {"modify", "minecraft-old"}) -+ public static boolean removedModify = false; ++ @GlobalConfig("disable-vault-blacklist") ++ public boolean disableVaultBlacklist = false; + -+ // Leaves end - modify -+ -+ // Leaves start - performance ++ @RemovedConfig(name = "tick-command", category = "modify") ++ @RemovedConfig(name = "player-can-edit-sign", category = "modify") ++ @RemovedConfig(name = "mending-compatibility-infinity", category = {"modify", "minecraft-old"}) ++ @RemovedConfig(name = "protection-stacking", category = {"modify", "minecraft-old"}) ++ @RemovedConfig(name = "disable-moved-wrongly-threshold", category = {"modify"}) ++ private final boolean removed = false; ++ } + -+ // Leaves start - performance - remove ++ public static PerformanceConfig performance = new PerformanceConfig(); + -+ @GlobalConfig(name = "tick-guard-lambda", category = {"performance", "remove"}) -+ public static boolean removeTickGuardLambda = true; ++ @GlobalConfigCategory("performance") ++ public static class PerformanceConfig { + -+ @GlobalConfig(name = "inventory-contains-iterators", category = {"performance", "remove"}) -+ public static boolean removeInventoryContainsIterators = true; ++ public PerformanceRemoveConfig remove = new PerformanceRemoveConfig(); + -+ @GlobalConfig(name = "range-check-streams-and-iterators", category = {"performance", "remove"}) -+ public static boolean removeRangeCheckStreams = true; ++ @GlobalConfigCategory("remove") ++ public static class PerformanceRemoveConfig { ++ @GlobalConfig("tick-guard-lambda") ++ public boolean tickGuardLambda = true; + -+ @GlobalConfig(name = "damage-lambda", category = {"performance", "remove"}) -+ public static boolean removeDamageLambda = true; ++ @GlobalConfig("inventory-contains-iterators") ++ public boolean inventoryContainsIterators = true; + -+ // Leaves end - performance - remove ++ @GlobalConfig("damage-lambda") ++ public boolean damageLambda = true; ++ } + -+ @GlobalConfig(name = "optimized-dragon-respawn", category = "performance") -+ public static boolean optimizedDragonRespawn = false; ++ @GlobalConfig("optimized-dragon-respawn") ++ public boolean optimizedDragonRespawn = false; + -+ @GlobalConfig(name = "dont-send-useless-entity-packets", category = "performance") -+ public static boolean dontSendUselessEntityPackets = true; ++ @GlobalConfig("dont-send-useless-entity-packets") ++ public boolean dontSendUselessEntityPackets = true; + -+ @GlobalConfig(name = "enable-suffocation-optimization", category = "performance") -+ public static boolean enableSuffocationOptimization = true; ++ @GlobalConfig("enable-suffocation-optimization") ++ public boolean enableSuffocationOptimization = true; + -+ @GlobalConfig(name = "check-spooky-season-once-an-hour", category = "performance") -+ public static boolean checkSpookySeasonOnceAnHour = true; ++ @GlobalConfig("check-spooky-season-once-an-hour") ++ public boolean checkSpookySeasonOnceAnHour = true; + -+ @GlobalConfig(name = "optimize-chunk-ticking", category = "performance", lock = true) -+ public static boolean optimizeChunkTicking = true; ++ @GlobalConfig("inactive-goal-selector-disable") ++ public boolean throttleInactiveGoalSelectorTick = false; + -+ @GlobalConfig(name = "entity-target-find-optimization", category = "performance") -+ public static boolean entityTargetFindingOptimization = true; ++ @GlobalConfig("reduce-entity-allocations") ++ public boolean reduceEntityAllocations = true; + -+ @GlobalConfig(name = "use-more-thread-unsafe-random", category = "performance") -+ public static boolean useMoreThreadUnsafeRandom = true; ++ @GlobalConfig("cache-climb-check") ++ public boolean cacheClimbCheck = true; + -+ @GlobalConfig(name = "inactive-goal-selector-disable", category = "performance") -+ public static boolean throttleInactiveGoalSelectorTick = false; ++ @GlobalConfig(value = "biome-temperatures-use-aging-cache", lock = true) ++ public boolean biomeTemperaturesUseAgingCache = true; + -+ @GlobalConfig(name = "reduce-entity-allocations", category = "performance") -+ public static boolean reduceEntityAllocations = true; ++ @GlobalConfig("reduce-chuck-load-and-lookup") ++ public boolean reduceChuckLoadAndLookup = true; + -+ @GlobalConfig(name = "cache-climb-check", category = "performance") -+ public static boolean cacheClimbCheck = true; ++ @GlobalConfig("cache-ignite-odds") ++ public boolean cacheIgniteOdds = true; + -+ @GlobalConfig(name = "biome-temperatures-use-aging-cache", category = "performance", lock = true) -+ public static boolean biomeTemperaturesUseAgingCache = true; ++ @GlobalConfig("faster-chunk-serialization") ++ public boolean fasterChunkSerialization = true; + -+ @GlobalConfig(name = "reduce-chuck-load-and-lookup", category = "performance") -+ public static boolean reduceChuckLoadAndLookup = true; ++ @GlobalConfig("cache-world-generator-sea-level") ++ public boolean cacheWorldGeneratorSeaLevel = true; + -+ @GlobalConfig(name = "improve-fluid-direction-caching", category = "performance", lock = true) -+ public static boolean improveFluidDirectionCaching = true; ++ @GlobalConfig("skip-secondary-POI-sensor-if-absent") ++ public boolean skipSecondaryPOISensorIfAbsent = true; + -+ @GlobalConfig(name = "cache-ignite-odds", category = "performance") -+ public static boolean cacheIgniteOdds = true; ++ @GlobalConfig("store-mob-counts-in-array") ++ public boolean storeMobCountsInArray = true; + -+ @GlobalConfig(name = "faster-chunk-serialization", category = "performance") -+ public static boolean fasterChunkSerialization = true; ++ @GlobalConfig("optimize-noise-generation") ++ public boolean optimizeNoiseGeneration = false; + -+ @GlobalConfig(name = "cache-world-generator-sea-level", category = "performance") -+ public static boolean cacheWorldGeneratorSeaLevel = true; ++ @GlobalConfig("optimize-sun-burn-tick") ++ public boolean optimizeSunBurnTick = true; + -+ @GlobalConfig(name = "skip-secondary-POI-sensor-if-absent", category = "performance") -+ public static boolean skipSecondaryPOISensorIfAbsent = true; ++ @GlobalConfig("optimized-CubePointRange") ++ public boolean optimizedCubePointRange = true; + -+ @GlobalConfig(name = "store-mob-counts-in-array", category = "performance") -+ public static boolean storeMobCountsInArray = true; ++ @GlobalConfig("check-frozen-ticks-before-landing-block") ++ public boolean checkFrozenTicksBeforeLandingBlock = true; + -+ @GlobalConfig(name = "cache-BlockStatePairKey-hash", category = "performance") -+ public static boolean cacheBlockStatePairKeyHash = true; ++ @GlobalConfig("skip-entity-move-if-movement-is-zero") ++ public boolean skipEntityMoveIfMovementIsZero = true; + -+ @GlobalConfig(name = "optimize-noise-generation", category = "performance") -+ public static boolean optimizeNoiseGeneration = false; ++ @GlobalConfig("skip-cloning-advancement-criteria") ++ public boolean skipCloningAdvancementCriteria = false; + -+ @GlobalConfig(name = "optimize-sun-burn-tick", category = "performance") -+ public static boolean optimizeSunBurnTick = true; ++ @GlobalConfig("skip-negligible-planar-movement-multiplication") ++ public boolean skipNegligiblePlanarMovementMultiplication = true; + -+ @GlobalConfig(name = "optimized-CubePointRange", category = "performance") -+ public static boolean optimizedCubePointRange = true; ++ @GlobalConfig("fix-villagers-dont-release-memory") ++ public boolean villagersDontReleaseMemoryFix = false; + -+ @GlobalConfig(name = "check-frozen-ticks-before-landing-block", category = "performance") -+ public static boolean checkFrozenTicksBeforeLandingBlock = true; ++ @RemovedConfig(name = "cache-ominous-banner-item", category = "performance") ++ @RemovedConfig(name = "use-optimized-collection", category = "performance") ++ @RemovedConfig(name = "async-pathfinding", category = "performance") ++ @RemovedConfig(name = "async-mob-spawning", category = "performance") ++ @RemovedConfig(name = "async-entity-tracker", category = "performance") ++ @RemovedConfig(name = "fix-paper-6045", category = {"performance", "fix"}) ++ @RemovedConfig(name = "fix-paper-9372", category = {"performance", "fix"}) ++ @RemovedConfig(name = "skip-clone-loot-parameters", category = "performance") ++ @RemovedConfig(name = "skip-poi-find-in-vehicle", category = "performance") ++ @RemovedConfig(name = "strip-raytracing-for-entity", category = "performance") ++ @RemovedConfig(name = "get-nearby-players-streams", category = {"performance", "remove"}) ++ @RemovedConfig(name = "optimize-world-generation-and-block-access", category = "performance") ++ @RemovedConfig(name = "cache-CubeVoxelShape-shape-array", category = "performance") ++ @RemovedConfig(name = "reduce-entity-fluid-lookup", category = "performance") ++ @RemovedConfig(name = "optimize-entity-coordinate-key", category = "performance") ++ @RemovedConfig(name = "entity-target-find-optimization", category = "performance") ++ @RemovedConfig(name = "use-more-thread-unsafe-random", category = "performance") ++ @RemovedConfig(name = "range-check-streams-and-iterators", category = {"performance", "remove"}) ++ @RemovedConfig(name = "improve-fluid-direction-caching", category = "performance") ++ @RemovedConfig(name = "cache-BlockStatePairKey-hash", category = "performance") ++ @RemovedConfig(name = "optimize-chunk-ticking", category = "performance") ++ private final boolean removedPerformance = true; ++ } + -+ @GlobalConfig(name = "skip-entity-move-if-movement-is-zero", category = "performance") -+ public static boolean skipEntityMoveIfMovementIsZero = true; ++ public static ProtocolConfig protocol = new ProtocolConfig(); + -+ @GlobalConfig(name = "skip-cloning-advancement-criteria", category = "performance") -+ public static boolean skipCloningAdvancementCriteria = false; ++ @GlobalConfigCategory("protocol") ++ public static class ProtocolConfig { + -+ @GlobalConfig(name = "skip-negligible-planar-movement-multiplication", category = "performance") -+ public static boolean skipNegligiblePlanarMovementMultiplication = true; ++ public BladerenConfig bladeren = new BladerenConfig(); + -+ @GlobalConfig(name = "fix-villagers-dont-release-memory", category = "performance") -+ public static boolean villagersDontReleaseMemoryFix = false; ++ @GlobalConfigCategory("bladeren") ++ public static class BladerenConfig { ++ @GlobalConfig("protocol") ++ public boolean enable = true; + -+ @RemovedConfig(name = "cache-ominous-banner-item", category = "performance") -+ @RemovedConfig(name = "use-optimized-collection", category = "performance") -+ @RemovedConfig(name = "async-pathfinding", category = "performance") -+ @RemovedConfig(name = "async-mob-spawning", category = "performance") -+ @RemovedConfig(name = "async-entity-tracker", category = "performance") -+ @RemovedConfig(name = "fix-paper-6045", category = {"performance", "fix"}) -+ @RemovedConfig(name = "fix-paper-9372", category = {"performance", "fix"}) -+ @RemovedConfig(name = "skip-clone-loot-parameters", category = "performance") -+ @RemovedConfig(name = "skip-poi-find-in-vehicle", category = "performance") -+ @RemovedConfig(name = "strip-raytracing-for-entity", category = "performance") -+ @RemovedConfig(name = "get-nearby-players-streams", category = {"performance", "remove"}) -+ @RemovedConfig(name = "optimize-world-generation-and-block-access", category = "performance") -+ @RemovedConfig(name = "cache-CubeVoxelShape-shape-array", category = "performance") -+ @RemovedConfig(name = "reduce-entity-fluid-lookup", category = "performance") -+ @RemovedConfig(name = "optimize-entity-coordinate-key", category = "performance") -+ public static boolean removedPerformance = true; ++ @GlobalConfig(value = "mspt-sync-protocol", validator = MSPTSyncValidator.class) ++ public boolean msptSyncProtocol = false; + -+ // Leaves end - performance ++ private static class MSPTSyncValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ LeavesFeatureSet.register(LeavesFeature.of("mspt_sync", value)); ++ } ++ } + -+ // Leaves start - protocol ++ @GlobalConfig(value = "mspt-sync-tick-interval", validator = MSPTSyncIntervalValidator.class) ++ public int msptSyncTickInterval = 20; + -+ // Leaves start - protocol - bladeren ++ private static class MSPTSyncIntervalValidator extends IntConfigValidator { ++ @Override ++ public void verify(Integer old, Integer value) throws IllegalArgumentException { ++ if (value <= 0) { ++ throw new IllegalArgumentException("mspt-sync-tick-interval need > 0"); ++ } ++ } ++ } ++ } + -+ @GlobalConfig(name = "protocol", category = {"protocol", "bladeren"}) -+ public static boolean bladerenLeavesProtocol = true; ++ public SyncmaticaConfig syncmatica = new SyncmaticaConfig(); + -+ @GlobalConfig(name = "mspt-sync-protocol", category = {"protocol", "bladeren"}, verify = MSPTSyncVerify.class) -+ public static boolean msptSyncProtocol = false; ++ @GlobalConfigCategory("syncmatica") ++ public static class SyncmaticaConfig { ++ @GlobalConfig(value = "enable", validator = SyncmaticaValidator.class) ++ public boolean enable = false; + -+ private static class MSPTSyncVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ LeavesFeatureSet.register(LeavesFeature.of("mspt_sync", value)); -+ } -+ } ++ public static class SyncmaticaValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ if (value) { ++ org.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol.init(); ++ } ++ } ++ } + -+ @GlobalConfig(name = "mspt-sync-tick-interval", category = {"protocol", "bladeren"}, verify = MSPTSyncIntervalVerify.class) -+ public static int msptSyncTickInterval = 20; ++ @GlobalConfig("quota") ++ public boolean useQuota = false; + -+ private static class MSPTSyncIntervalVerify extends ConfigVerifyImpl.IntConfigVerify { -+ @Override -+ public void check(Integer old, Integer value) throws IllegalArgumentException { -+ if (value <= 0) { -+ throw new IllegalArgumentException("mspt-sync-tick-interval need > 0"); -+ } ++ @GlobalConfig(value = "quota-limit", validator = IntConfigValidator.class) ++ public int quotaLimit = 40000000; + } -+ } + -+ // Leaves end - protocol - bladeren ++ public PCAConfig pca = new PCAConfig(); + -+ // Leaves start - protocol - syncmatica ++ @GlobalConfigCategory("pca") ++ public static class PCAConfig { ++ @RemovedConfig(name = "pca-sync-protocol", category = "protocol", transform = true) ++ @GlobalConfig(value = "pca-sync-protocol", validator = PcaValidator.class) ++ public boolean enable = false; + -+ @GlobalConfig(name = "enable", category = {"protocol", "syncmatica"}, verify = SyncmaticaVerify.class) -+ public static boolean syncmaticaProtocol = false; ++ public static class PcaValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ if (old != null && old != value) { ++ org.leavesmc.leaves.protocol.PcaSyncProtocol.onConfigModify(value); ++ } ++ } ++ } + -+ @GlobalConfig(name = "quota", category = {"protocol", "syncmatica"}) -+ public static boolean syncmaticaQuota = false; ++ @RemovedConfig(name = "pca-sync-player-entity", category = "protocol", convert = PcaPlayerEntityValidator.class, transform = true) ++ @GlobalConfig(value = "pca-sync-player-entity", validator = PcaPlayerEntityValidator.class) ++ public PcaPlayerEntityType syncPlayerEntity = PcaPlayerEntityType.OPS; + -+ @GlobalConfig(name = "quota-limit", category = {"protocol", "syncmatica"}, verify = ConfigVerifyImpl.IntConfigVerify.class) -+ public static int syncmaticaQuotaLimit = 40000000; ++ public enum PcaPlayerEntityType { ++ NOBODY, BOT, OPS, OPS_AND_SELF, EVERYONE ++ } + -+ public static class SyncmaticaVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ if (value) { -+ org.leavesmc.leaves.protocol.syncmatica.SyncmaticaProtocol.init(); ++ private static class PcaPlayerEntityValidator extends EnumConfigValidator { + } + } -+ } + -+ // Leaves end - protocol - syncmatica ++ public AppleSkinConfig appleskin = new AppleSkinConfig(); + -+ @RemovedConfig(name = "pca-sync-protocol", category = "protocol", transform = true) -+ @GlobalConfig(name = "pca-sync-protocol", category = {"protocol", "pca"}, verify = PcaVerify.class) -+ public static boolean pcaSyncProtocol = false; ++ @GlobalConfigCategory("appleskin") ++ public static class AppleSkinConfig { ++ @RemovedConfig(name = "appleskin-protocol", category = "protocol") ++ @GlobalConfig("protocol") ++ public boolean enable = false; + -+ public static class PcaVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ if (old != null && old != value) { -+ org.leavesmc.leaves.protocol.PcaSyncProtocol.onConfigModify(value); -+ } ++ @GlobalConfig("sync-tick-interval") ++ public int syncTickInterval = 20; + } -+ } + -+ @RemovedConfig(name = "pca-sync-player-entity", category = "protocol", convert = PcaPlayerEntityVerify.class, transform = true) -+ @GlobalConfig(name = "pca-sync-player-entity", category = {"protocol", "pca"}, verify = PcaPlayerEntityVerify.class) -+ public static PcaPlayerEntityType pcaSyncPlayerEntity = PcaPlayerEntityType.OPS; ++ public ServuxConfig servux = new ServuxConfig(); + -+ public enum PcaPlayerEntityType { -+ NOBODY, BOT, OPS, OPS_AND_SELF, EVERYONE -+ } ++ @GlobalConfigCategory("servux") ++ public static class ServuxConfig { ++ @RemovedConfig(name = "servux-protocol", category = "protocol", transform = true) ++ @GlobalConfig("structure-protocol") ++ public boolean structureProtocol = false; + -+ private static class PcaPlayerEntityVerify extends ConfigVerifyImpl.EnumConfigVerify { -+ } ++ @GlobalConfig("entity-protocol") ++ public boolean entityProtocol = false; ++ } + -+ @GlobalConfig(name = "bbor-protocol", category = "protocol") -+ public static boolean bborProtocol = false; ++ @GlobalConfig("bbor-protocol") ++ public boolean bborProtocol = false; + -+ @GlobalConfig(name = "jade-protocol", category = "protocol") -+ public static boolean jadeProtocol = false; ++ @GlobalConfig("jade-protocol") ++ public boolean jadeProtocol = false; + -+ @GlobalConfig(name = "alternative-block-placement", category = "protocol", verify = AlternativePlaceVerify.class) -+ public static AlternativePlaceType alternativeBlockPlacement = AlternativePlaceType.NONE; ++ @GlobalConfig(value = "alternative-block-placement", validator = AlternativePlaceValidator.class) ++ public AlternativePlaceType alternativeBlockPlacement = AlternativePlaceType.NONE; + -+ public enum AlternativePlaceType { -+ NONE, CARPET, CARPET_FIX, LITEMATICA -+ } ++ public enum AlternativePlaceType { ++ NONE, CARPET, CARPET_FIX, LITEMATICA ++ } + -+ private static class AlternativePlaceVerify extends ConfigVerifyImpl.EnumConfigVerify { -+ @Override -+ public void runAfterLoader(AlternativePlaceType value, boolean firstLoad) { -+ if (value != AlternativePlaceType.NONE) { -+ disableDistanceCheckForUseItem = true; ++ private static class AlternativePlaceValidator extends EnumConfigValidator { ++ @Override ++ public void runAfterLoader(AlternativePlaceType value, boolean firstLoad) { ++ if (value != AlternativePlaceType.NONE) { ++ LeavesConfig.modify.disableDistanceCheckForUseItem = true; ++ } + } + } -+ } + -+ @GlobalConfig(name = "appleskin-protocol", category = "protocol") -+ public static boolean appleskinProtocol = false; ++ @GlobalConfig("xaero-map-protocol") ++ public boolean xaeroMapProtocol = false; + -+ @GlobalConfig(name = "xaero-map-protocol", category = "protocol") -+ public static boolean xaeroMapProtocol = false; ++ @GlobalConfig(value = "xaero-map-server-id", validator = IntConfigValidator.class) ++ public int xaeroMapServerID = new Random().nextInt(); + -+ @GlobalConfig(name = "xaero-map-server-id", category = "protocol", verify = ConfigVerifyImpl.IntConfigVerify.class) -+ public static int xaeroMapServerID = new Random().nextInt(); ++ @GlobalConfig("leaves-carpet-support") ++ public boolean leavesCarpetSupport = false; ++ } + -+ @RemovedConfig(name = "servux-protocol", category = "protocol", transform = true) -+ @GlobalConfig(name = "structure-protocol", category = {"protocol", "servux"}) -+ public static boolean servuxStructureProtocol = false; ++ public static MiscConfig mics = new MiscConfig(); + -+ @GlobalConfig(name = "entity-protocol", category = {"protocol", "servux"}) -+ public static boolean servuxEntityProtocol = false; ++ @GlobalConfigCategory("misc") ++ public static class MiscConfig { + -+ @GlobalConfig(name = "leaves-carpet-support", category = "protocol") -+ public static boolean leavesCarpetSupport = false; ++ public AutoUpdateConfig autoUpdate = new AutoUpdateConfig(); + -+ // Leaves end - protocol ++ @GlobalConfigCategory("auto-update") ++ public static class AutoUpdateConfig { ++ @GlobalConfig(value = "enable", lock = true, validator = AutoUpdateValidator.class) ++ public boolean enable = false; + -+ // Leaves start - misc ++ private static class AutoUpdateValidator extends BooleanConfigValidator { ++ @Override ++ public void runAfterLoader(Boolean value, boolean firstLoad) { ++ if (firstLoad) { ++ org.leavesmc.leaves.util.LeavesUpdateHelper.init(); ++ if (value) { ++ LeavesLogger.LOGGER.warning("Auto-Update is not completely safe. Enabling it may cause data security problems!"); ++ } ++ } ++ } ++ } + -+ // Leaves start - misc - auto-update ++ @GlobalConfig(value = "download-source", lock = true, validator = DownloadSourceValidator.class) ++ public String source = "application"; + -+ @GlobalConfig(name = "enable", category = {"misc", "auto-update"}, lock = true, verify = AutoUpdateVerify.class) -+ public static boolean autoUpdate = false; ++ public static class DownloadSourceValidator extends StringConfigValidator { ++ private static final List suggestSourceList = List.of("application", "ghproxy", "cloud"); + -+ private static class AutoUpdateVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void runAfterLoader(Boolean value, boolean firstLoad) { -+ if (firstLoad) { -+ org.leavesmc.leaves.util.LeavesUpdateHelper.init(); -+ if (value) { -+ LeavesLogger.LOGGER.warning("Auto-Update is not completely safe. Enabling it may cause data security problems!"); ++ @Override ++ public List valueSuggest() { ++ return suggestSourceList; + } + } -+ } -+ } + -+ @GlobalConfig(name = "download-source", category = {"misc", "auto-update"}, lock = true, verify = DownloadSourceVerify.class) -+ public static String autoUpdateSource = "application"; ++ @GlobalConfig("allow-experimental") ++ public Boolean allowExperimental = false; + -+ public static class DownloadSourceVerify extends ConfigVerifyImpl.StringConfigVerify { -+ private static final List suggestSourceList = List.of("application", "ghproxy", "cloud"); -+ -+ @Override -+ public List valueSuggest() { -+ return suggestSourceList; ++ @GlobalConfig(value = "time", lock = true, validator = ListConfigValidator.STRING.class) ++ public List updateTime = List.of("14:00", "2:00"); + } -+ } -+ -+ @GlobalConfig(name = "allow-experimental", category = {"misc", "auto-update"}) -+ public static Boolean autoUpdateAllowExperimental = false; + -+ @GlobalConfig(name = "time", category = {"misc", "auto-update"}, lock = true, verify = ConfigVerifyImpl.ListConfigVerify.STRING.class) -+ public static List autoUpdateTime = List.of("14:00", "2:00"); ++ public ExtraYggdrasilConfig yggdrasil = new ExtraYggdrasilConfig(); + -+ // Leaves end - misc - auto-update ++ @GlobalConfigCategory("extra-yggdrasil-service") ++ public static class ExtraYggdrasilConfig { ++ @GlobalConfig(value = "enable", validator = ExtraYggdrasilValidator.class) ++ public boolean enable = false; + -+ // Leaves start - misc - extra-yggdrasil-service -+ -+ @GlobalConfig(name = "enable", category = {"misc", "extra-yggdrasil-service"}, verify = ExtraYggdrasilVerify.class) -+ public static boolean extraYggdrasilService = false; -+ -+ public static class ExtraYggdrasilVerify extends ConfigVerifyImpl.BooleanConfigVerify { -+ @Override -+ public void check(Boolean old, Boolean value) throws IllegalArgumentException { -+ if (value) { -+ LeavesLogger.LOGGER.warning("extra-yggdrasil-service is an unofficial support. Enabling it may cause data security problems!"); -+ GlobalConfiguration.get().unsupportedSettings.performUsernameValidation = true; // always check username ++ public static class ExtraYggdrasilValidator extends BooleanConfigValidator { ++ @Override ++ public void verify(Boolean old, Boolean value) throws IllegalArgumentException { ++ if (value) { ++ LeavesLogger.LOGGER.warning("extra-yggdrasil-service is an unofficial support. Enabling it may cause data security problems!"); ++ GlobalConfiguration.get().unsupportedSettings.performUsernameValidation = true; // always check username ++ } ++ } + } -+ } -+ } + -+ @GlobalConfig(name = "login-protect", category = {"misc", "extra-yggdrasil-service"}) -+ public static boolean extraYggdrasilLoginProtect = false; ++ @GlobalConfig("login-protect") ++ public boolean loginProtect = false; + -+ @GlobalConfig(name = "urls", category = {"misc", "extra-yggdrasil-service"}, lock = true, verify = ExtraYggdrasilUrlsVerify.class) -+ public static List extraYggdrasilServiceList = List.of("https://url.with.authlib-injector-yggdrasil"); ++ @GlobalConfig(value = "urls", lock = true, validator = ExtraYggdrasilUrlsValidator.class) ++ public List serviceList = List.of("https://url.with.authlib-injector-yggdrasil"); + -+ public static class ExtraYggdrasilUrlsVerify extends ConfigVerifyImpl.ListConfigVerify { -+ @Override -+ public void check(List old, List value) throws IllegalArgumentException { -+ org.leavesmc.leaves.profile.LeavesMinecraftSessionService.initExtraYggdrasilList(value); ++ public static class ExtraYggdrasilUrlsValidator extends ListConfigValidator.STRING { ++ @Override ++ public void verify(List old, List value) throws IllegalArgumentException { ++ org.leavesmc.leaves.profile.LeavesMinecraftSessionService.initExtraYggdrasilList(value); ++ } ++ } + } -+ } + -+ // Leaves end - misc - extra-yggdrasil-service ++ @GlobalConfig("disable-method-profiler") ++ public boolean disableMethodProfiler = true; + -+ @GlobalConfig(name = "disable-method-profiler", category = "misc") -+ public static boolean disableMethodProfiler = true; ++ @RemovedConfig(name = "no-chat-sign", category = {}, transform = true) ++ @GlobalConfig("no-chat-sign") ++ public boolean noChatSign = true; + -+ @RemovedConfig(name = "no-chat-sign", category = {}, transform = true) -+ @GlobalConfig(name = "no-chat-sign", category = "misc") -+ public static boolean noChatSign = true; ++ @GlobalConfig("dont-respond-ping-before-start-fully") ++ public boolean dontRespondPingBeforeStart = true; + -+ @GlobalConfig(name = "dont-respond-ping-before-start-fully", category = "misc") -+ public static boolean dontRespondPingBeforeStart = true; ++ @GlobalConfig(value = "server-lang", lock = true, validator = ServerLangValidator.class) ++ public String serverLang = "en_us"; + -+ @GlobalConfig(name = "server-lang", category = "misc", lock = true, verify = ServerLangVerify.class) -+ public static String serverLang = "en_us"; ++ private static class ServerLangValidator extends StringConfigValidator { ++ private static final List supportLang = List.of("en_us", "zh_cn"); + -+ private static class ServerLangVerify extends ConfigVerifyImpl.StringConfigVerify { -+ private static final List supportLang = List.of("en_us", "zh_cn"); ++ @Override ++ public void verify(String old, String value) throws IllegalArgumentException { ++ if (!supportLang.contains(value)) { ++ throw new IllegalArgumentException("lang " + value + " not supported"); ++ } ++ } + -+ @Override -+ public void check(String old, String value) throws IllegalArgumentException { -+ if (!supportLang.contains(value)) { -+ throw new IllegalArgumentException("lang " + value + " not supported"); ++ @Override ++ public List valueSuggest() { ++ return supportLang; + } + } -+ } + -+ @GlobalConfig(name = "server-mod-name", category = "misc", verify = ConfigVerifyImpl.StringConfigVerify.class) -+ public static String serverModName = "Leaves"; ++ @GlobalConfig(value = "server-mod-name", validator = StringConfigValidator.class) ++ public String serverModName = "Leaves"; + -+ @GlobalConfig(name = "bstats-privacy-mode", category = "misc") -+ public static boolean bstatsPrivacyMode = false; ++ @GlobalConfig("bstats-privacy-mode") ++ public boolean bstatsPrivacyMode = false; + -+ @GlobalConfig(name = "force-minecraft-command", category = "misc") -+ public static boolean forceMinecraftCommand = false; ++ @GlobalConfig("force-minecraft-command") ++ public boolean forceMinecraftCommand = false; + -+ @GlobalConfig(name = "leaves-packet-event", category = "misc") -+ public static boolean leavesPacketEvent = true; ++ @GlobalConfig("leaves-packet-event") ++ public boolean leavesPacketEvent = true; ++ } + -+ // Leaves end - misc ++ public static RegionConfig region = new RegionConfig(); + -+ // Leaves start - region ++ @GlobalConfigCategory("region") ++ public static class RegionConfig { + -+ @GlobalConfig(name = "format", category = "region", lock = true, verify = RegionFormatVerify.class) -+ public static org.leavesmc.leaves.region.RegionFileFormat regionFormat = org.leavesmc.leaves.region.RegionFileFormat.ANVIL; ++ @GlobalConfig(value = "format", lock = true, validator = RegionFormatValidator.class) ++ public org.leavesmc.leaves.region.RegionFileFormat format = org.leavesmc.leaves.region.RegionFileFormat.ANVIL; + -+ private static class RegionFormatVerify extends ConfigVerifyImpl.EnumConfigVerify { -+ } ++ private static class RegionFormatValidator extends EnumConfigValidator { ++ } + -+ @GlobalConfig(name = "flush-frequency", category = {"region", "linear"}, lock = true, verify = ConfigVerifyImpl.IntConfigVerify.class) -+ public static int linearFlushFrequency = 10; ++ public LinearConfig linear = new LinearConfig(); + -+ @GlobalConfig(name = "auto-convert-anvil-to-linear", category = {"region", "linear"}, lock = true) -+ public static boolean autoConvertAnvilToLinear = false; ++ @GlobalConfigCategory("linear") ++ public static class LinearConfig { + -+ @GlobalConfig(name = "flush-max-threads", category = {"region", "linear"}, lock = true, verify = ConfigVerifyImpl.IntConfigVerify.class) -+ public static int linearFlushThreads = 1; ++ @GlobalConfig(value = "flush-frequency", lock = true, validator = IntConfigValidator.class) ++ public int flushFrequency = 10; + -+ public static int getLinearFlushThreads() { -+ if (linearFlushThreads < 0) { -+ return Math.max(Runtime.getRuntime().availableProcessors() + linearFlushThreads, 1); -+ } else { -+ return Math.max(linearFlushThreads, 1); -+ } -+ } ++ @GlobalConfig(value = "auto-convert-anvil-to-linear", lock = true) ++ public boolean autoConvertAnvilToLinear = false; + -+ @GlobalConfig(name = "compression-level", category = {"region", "linear"}, lock = true, verify = LinearCompressVerify.class) -+ public static int linearCompressionLevel = 1; ++ @GlobalConfig(value = "flush-max-threads", lock = true, validator = IntConfigValidator.class) ++ public int flushThreads = 1; + -+ private static class LinearCompressVerify extends ConfigVerifyImpl.IntConfigVerify { -+ @Override -+ public void check(Integer old, Integer value) throws IllegalArgumentException { -+ if (value < 1 || value > 22) { -+ throw new IllegalArgumentException("linear.compression-level need between 1 and 22"); ++ public int getLinearFlushThreads() { ++ if (flushThreads < 0) { ++ return Math.max(Runtime.getRuntime().availableProcessors() + flushThreads, 1); ++ } else { ++ return Math.max(flushThreads, 1); ++ } + } -+ } -+ } + -+ @RemovedConfig(name = "crash-on-broken-symlink", category = {"region", "linear"}) -+ public static boolean linearCrashOnBrokenSymlink = true; ++ @GlobalConfig(value = "compression-level", lock = true, validator = LinearCompressValidator.class) ++ public int compressionLevel = 1; + -+ // Leaves end - region ++ private static class LinearCompressValidator extends IntConfigValidator { ++ @Override ++ public void verify(Integer old, Integer value) throws IllegalArgumentException { ++ if (value < 1 || value > 22) { ++ throw new IllegalArgumentException("linear.compression-level need between 1 and 22"); ++ } ++ } ++ } + -+ // Leaves start - fix ++ @RemovedConfig(name = "crash-on-broken-symlink", category = {"region", "linear"}) ++ private final boolean linearCrashOnBrokenSymlink = true; ++ } ++ } + -+ @GlobalConfig(name = "vanilla-hopper", category = "fix") -+ public static boolean vanillaHopper = false; ++ public static FixConfig fix = new FixConfig(); + -+ @RemovedConfig(name = "spigot-EndPlatform-destroy", category = "fix") -+ public static boolean spigotEndPlatformDestroy = false; ++ @GlobalConfigCategory("fix") ++ public static class FixConfig { ++ @GlobalConfig("vanilla-hopper") ++ public boolean vanillaHopper = false; + -+ // Leaves end - region ++ @RemovedConfig(name = "spigot-EndPlatform-destroy", category = "fix") ++ private final boolean spigotEndPlatformDestroy = false; ++ } +} diff --git a/src/main/java/org/leavesmc/leaves/command/CommandArgument.java b/src/main/java/org/leavesmc/leaves/command/CommandArgument.java new file mode 100644 @@ -1336,7 +1396,7 @@ index 0000000000000000000000000000000000000000..4b61fccc71d98a7b69bb7f88fb88ea0a +} diff --git a/src/main/java/org/leavesmc/leaves/command/subcommands/ConfigCommand.java b/src/main/java/org/leavesmc/leaves/command/subcommands/ConfigCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..78471bde136d982f19f23beb3b121e4b254d124b +index 0000000000000000000000000000000000000000..56ad63ae93e1322140d59efc234ba90f0d5c7ab8 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/command/subcommands/ConfigCommand.java @@ -0,0 +1,83 @@ @@ -1413,7 +1473,7 @@ index 0000000000000000000000000000000000000000..78471bde136d982f19f23beb3b121e4b + case 2 -> { + GlobalConfigManager.VerifiedConfig verifiedConfig = GlobalConfigManager.getVerifiedConfig(args[0]); + if (verifiedConfig != null) { -+ return LeavesCommandUtil.getListMatchingLast(sender, args, verifiedConfig.verify().valueSuggest()); ++ return LeavesCommandUtil.getListMatchingLast(sender, args, verifiedConfig.validator().valueSuggest()); + } else { + return Collections.singletonList(""); + } @@ -1423,18 +1483,19 @@ index 0000000000000000000000000000000000000000..78471bde136d982f19f23beb3b121e4b + return Collections.emptyList(); + } +} -diff --git a/src/main/java/org/leavesmc/leaves/config/ConfigConvert.java b/src/main/java/org/leavesmc/leaves/config/ConfigConvert.java +diff --git a/src/main/java/org/leavesmc/leaves/config/ConfigConverter.java b/src/main/java/org/leavesmc/leaves/config/ConfigConverter.java new file mode 100644 -index 0000000000000000000000000000000000000000..2ce05259acfeb2e28895502b72afd66938bf520b +index 0000000000000000000000000000000000000000..178f7e8636d135b084444b3b0c476631aac66dcc --- /dev/null -+++ b/src/main/java/org/leavesmc/leaves/config/ConfigConvert.java -@@ -0,0 +1,20 @@ ++++ b/src/main/java/org/leavesmc/leaves/config/ConfigConverter.java +@@ -0,0 +1,21 @@ +package org.leavesmc.leaves.config; + -+public interface ConfigConvert { ++public interface ConfigConverter { + + E convert(String value) throws IllegalArgumentException; + ++ @SuppressWarnings("unchecked") + default E loadConvert(Object value) throws IllegalArgumentException { + try { + return (E) value; @@ -1449,19 +1510,19 @@ index 0000000000000000000000000000000000000000..2ce05259acfeb2e28895502b72afd669 + + Class getFieldClass(); +} -diff --git a/src/main/java/org/leavesmc/leaves/config/ConfigVerify.java b/src/main/java/org/leavesmc/leaves/config/ConfigVerify.java +diff --git a/src/main/java/org/leavesmc/leaves/config/ConfigValidator.java b/src/main/java/org/leavesmc/leaves/config/ConfigValidator.java new file mode 100644 -index 0000000000000000000000000000000000000000..b77b9648829268d7fa591e059ddbc584a38ebd49 +index 0000000000000000000000000000000000000000..d343ae8d44a78e1d1536a2611b4bbbf9143c218e --- /dev/null -+++ b/src/main/java/org/leavesmc/leaves/config/ConfigVerify.java ++++ b/src/main/java/org/leavesmc/leaves/config/ConfigValidator.java @@ -0,0 +1,16 @@ +package org.leavesmc.leaves.config; + +import java.util.List; + -+public interface ConfigVerify extends ConfigConvert { ++public interface ConfigValidator extends ConfigConverter { + -+ default void check(E old, E value) throws IllegalArgumentException { ++ default void verify(E old, E value) throws IllegalArgumentException { + } + + default List valueSuggest() { @@ -1471,12 +1532,12 @@ index 0000000000000000000000000000000000000000..b77b9648829268d7fa591e059ddbc584 + default void runAfterLoader(E value, boolean firstLoad) { + } +} -diff --git a/src/main/java/org/leavesmc/leaves/config/ConfigVerifyImpl.java b/src/main/java/org/leavesmc/leaves/config/ConfigVerifyImpl.java +diff --git a/src/main/java/org/leavesmc/leaves/config/ConfigValidatorImpl.java b/src/main/java/org/leavesmc/leaves/config/ConfigValidatorImpl.java new file mode 100644 -index 0000000000000000000000000000000000000000..b0a71eaaeebb9887ee74f3a06fe46fc9ff41c7cb +index 0000000000000000000000000000000000000000..0e9cdc0fa9380ad07ad74a3933733fe4053b678b --- /dev/null -+++ b/src/main/java/org/leavesmc/leaves/config/ConfigVerifyImpl.java -@@ -0,0 +1,117 @@ ++++ b/src/main/java/org/leavesmc/leaves/config/ConfigValidatorImpl.java +@@ -0,0 +1,108 @@ +package org.leavesmc.leaves.config; + +import org.jetbrains.annotations.NotNull; @@ -1487,12 +1548,12 @@ index 0000000000000000000000000000000000000000..b0a71eaaeebb9887ee74f3a06fe46fc9 +import java.util.List; +import java.util.Locale; + -+public abstract class ConfigVerifyImpl implements ConfigVerify { ++public abstract class ConfigValidatorImpl implements ConfigValidator { + + private Class fieldClass; + + @SuppressWarnings("unchecked") -+ public ConfigVerifyImpl() { ++ public ConfigValidatorImpl() { + Type superClass = getClass().getGenericSuperclass(); + if (superClass instanceof ParameterizedType) { + Type[] actualTypeArguments = ((ParameterizedType) superClass).getActualTypeArguments(); @@ -1507,7 +1568,7 @@ index 0000000000000000000000000000000000000000..b0a71eaaeebb9887ee74f3a06fe46fc9 + return fieldClass; + } + -+ public static class BooleanConfigVerify extends ConfigVerifyImpl { ++ public static class BooleanConfigValidator extends ConfigValidatorImpl { + + @Override + public Boolean convert(String value) throws IllegalArgumentException { @@ -1520,29 +1581,29 @@ index 0000000000000000000000000000000000000000..b0a71eaaeebb9887ee74f3a06fe46fc9 + } + } + -+ public static class IntConfigVerify extends ConfigVerifyImpl { ++ public static class IntConfigValidator extends ConfigValidatorImpl { + @Override + public Integer convert(String value) throws IllegalArgumentException { + return Integer.parseInt(value); + } + } + -+ public static class StringConfigVerify extends ConfigVerifyImpl { ++ public static class StringConfigValidator extends ConfigValidatorImpl { + @Override + public String convert(String value) throws IllegalArgumentException { + return value; + } + } + -+ public static class DoubleConfigVerify extends ConfigVerifyImpl { ++ public static class DoubleConfigValidator extends ConfigValidatorImpl { + @Override + public Double convert(String value) throws IllegalArgumentException { + return Double.parseDouble(value); + } + } + -+ public abstract static class ListConfigVerify extends ConfigVerifyImpl> { -+ public static class STRING extends ListConfigVerify { ++ public abstract static class ListConfigValidator extends ConfigValidatorImpl> { ++ public static class STRING extends ListConfigValidator { + } + + @Override @@ -1551,18 +1612,14 @@ index 0000000000000000000000000000000000000000..b0a71eaaeebb9887ee74f3a06fe46fc9 + } + } + -+ public abstract static class EnumConfigVerify> extends ConfigVerifyImpl { ++ public abstract static class EnumConfigValidator> extends ConfigValidatorImpl { + -+ private final Class enumClass; + private final List enumValues; + -+ @SuppressWarnings({"unchecked", "unused"}) -+ public EnumConfigVerify() { -+ Type genericSuperclass = getClass().getGenericSuperclass(); -+ Type[] typeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments(); -+ this.enumClass = (Class) typeArguments[0]; ++ public EnumConfigValidator() { ++ super(); + this.enumValues = new ArrayList<>() {{ -+ for (E e : enumClass.getEnumConstants()) { ++ for (E e : getFieldClass().getEnumConstants()) { + add(e.name().toLowerCase(Locale.ROOT)); + } + }}; @@ -1570,7 +1627,7 @@ index 0000000000000000000000000000000000000000..b0a71eaaeebb9887ee74f3a06fe46fc9 + + @Override + public E convert(@NotNull String value) throws IllegalArgumentException { -+ return Enum.valueOf(enumClass, value.toUpperCase(Locale.ROOT)); ++ return Enum.valueOf(getFieldClass(), value.toUpperCase(Locale.ROOT)); + } + + @Override @@ -1587,19 +1644,14 @@ index 0000000000000000000000000000000000000000..b0a71eaaeebb9887ee74f3a06fe46fc9 + public List valueSuggest() { + return enumValues; + } -+ -+ @Override -+ public Class getFieldClass() { -+ return enumClass; -+ } + } +} diff --git a/src/main/java/org/leavesmc/leaves/config/GlobalConfig.java b/src/main/java/org/leavesmc/leaves/config/GlobalConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..d55ffed5026edfa1d37e310edbb74ac56b0d0c81 +index 0000000000000000000000000000000000000000..d6af8fd7552c5560f4397b9961dd5c39014e12ae --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/config/GlobalConfig.java -@@ -0,0 +1,19 @@ +@@ -0,0 +1,17 @@ +package org.leavesmc.leaves.config; + +import java.lang.annotation.ElementType; @@ -1611,60 +1663,64 @@ index 0000000000000000000000000000000000000000..d55ffed5026edfa1d37e310edbb74ac5 +@Retention(RetentionPolicy.RUNTIME) +public @interface GlobalConfig { + -+ String name(); -+ -+ String[] category(); ++ String value(); + + boolean lock() default false; + -+ Class> verify() default ConfigVerifyImpl.BooleanConfigVerify.class; ++ Class> validator() default ConfigValidatorImpl.BooleanConfigValidator.class; ++} +diff --git a/src/main/java/org/leavesmc/leaves/config/GlobalConfigCategory.java b/src/main/java/org/leavesmc/leaves/config/GlobalConfigCategory.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1e109a8b95f7dd25f68f7b3d2115c8cf3c43e58c +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/config/GlobalConfigCategory.java +@@ -0,0 +1,12 @@ ++package org.leavesmc.leaves.config; ++ ++import java.lang.annotation.ElementType; ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++import java.lang.annotation.Target; ++ ++@Target(ElementType.TYPE) ++@Retention(RetentionPolicy.RUNTIME) ++public @interface GlobalConfigCategory { ++ String value(); +} diff --git a/src/main/java/org/leavesmc/leaves/config/GlobalConfigCreator.java b/src/main/java/org/leavesmc/leaves/config/GlobalConfigCreator.java new file mode 100644 -index 0000000000000000000000000000000000000000..26304b8d8fcfbe68325b686fe37171e2851dbd81 +index 0000000000000000000000000000000000000000..baa8f15c5ef092f287004b8266b7f7cee1392260 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/config/GlobalConfigCreator.java -@@ -0,0 +1,56 @@ +@@ -0,0 +1,83 @@ +package org.leavesmc.leaves.config; + +import org.bukkit.configuration.file.YamlConfiguration; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.LeavesConfig; + +import java.io.File; +import java.io.IOException; ++import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Collections; + ++import static org.leavesmc.leaves.config.GlobalConfigManager.CONFIG_START; ++ +public class GlobalConfigCreator { + ++ private static YamlConfiguration config; ++ + public static void main(String[] args) { -+ YamlConfiguration config = new YamlConfiguration(); ++ config = new YamlConfiguration(); + config.options().setHeader(Collections.singletonList(LeavesConfig.CONFIG_HEADER)); + + config.set("config-version", LeavesConfig.CURRENT_CONFIG_VERSION); + -+ Class clazz = LeavesConfig.class; -+ -+ for (Field field : clazz.getDeclaredFields()) { -+ if (Modifier.isStatic(field.getModifiers())) { -+ field.setAccessible(true); -+ -+ GlobalConfig globalConfig = field.getAnnotation(GlobalConfig.class); -+ if (globalConfig != null) { -+ try { -+ GlobalConfigManager.VerifiedConfig verifiedConfig = GlobalConfigManager.VerifiedConfig.build(globalConfig, field); -+ -+ ConfigVerify verify = verifiedConfig.verify(); -+ boolean isEnumConfig = verify instanceof ConfigVerifyImpl.EnumConfigVerify; -+ -+ Object defValue = isEnumConfig ? field.get(null).toString() : field.get(null); -+ config.set(verifiedConfig.path(), defValue); -+ } catch (Exception e) { -+ e.printStackTrace(); -+ } -+ } -+ } ++ for (Field field : LeavesConfig.class.getDeclaredFields()) { ++ initField(field, null, CONFIG_START); + } + + config.set("settings.protocol.xaero-map-server-id", 0); @@ -1680,16 +1736,57 @@ index 0000000000000000000000000000000000000000..26304b8d8fcfbe68325b686fe37171e2 + e.printStackTrace(); + } + } ++ ++ private static void initCategory(@NotNull Field categoryField, @NotNull GlobalConfigCategory globalCategory, @Nullable Object upstreamField, @NotNull String upstreamPath) { ++ try { ++ Object category = categoryField.get(upstreamField); ++ String categoryPath = upstreamPath + globalCategory.value() + "."; ++ for (Field field : categoryField.getType().getDeclaredFields()) { ++ initField(field, category, categoryPath); ++ } ++ } catch (Exception e) { ++ e.printStackTrace(); ++ } ++ } ++ ++ private static void initField(@NotNull Field field, @Nullable Object upstreamField, @NotNull String upstreamPath) { ++ if (Modifier.isStatic(field.getModifiers())) { ++ field.setAccessible(true); ++ ++ GlobalConfig globalConfig = field.getAnnotation(GlobalConfig.class); ++ if (globalConfig != null) { ++ initConfig(field, globalConfig, upstreamField, upstreamPath); ++ return; ++ } ++ ++ GlobalConfigCategory globalCategory = field.getType().getAnnotation(GlobalConfigCategory.class); ++ if (globalCategory != null) { ++ initCategory(field, globalCategory, upstreamField, upstreamPath); ++ } ++ } ++ } ++ ++ ++ private static void initConfig(@NotNull Field field, GlobalConfig globalConfig, @Nullable Object upstreamField, @NotNull String upstreamPath) { ++ try { ++ GlobalConfigManager.VerifiedConfig verifiedConfig = GlobalConfigManager.VerifiedConfig.build(globalConfig, field, upstreamField, upstreamPath); ++ config.set(verifiedConfig.path(), verifiedConfig.validator().saveConvert(field.get(null))); ++ } catch (Exception e) { ++ e.printStackTrace(); ++ } ++ } +} diff --git a/src/main/java/org/leavesmc/leaves/config/GlobalConfigManager.java b/src/main/java/org/leavesmc/leaves/config/GlobalConfigManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..7eb14d1725bb250f8a5983bad1f4641dc51aa939 +index 0000000000000000000000000000000000000000..adc023d5b669d712ae7eae740f5ab43a7bd5731e --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/config/GlobalConfigManager.java -@@ -0,0 +1,204 @@ +@@ -0,0 +1,232 @@ +package org.leavesmc.leaves.config; + -+import org.bukkit.Bukkit; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; +import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.LeavesLogger; + @@ -1699,85 +1796,111 @@ index 0000000000000000000000000000000000000000..7eb14d1725bb250f8a5983bad1f4641d +import java.util.HashMap; +import java.util.Map; +import java.util.Set; -+import java.util.logging.Level; + +public class GlobalConfigManager { + ++ public final static String CONFIG_START = "settings."; ++ + private static boolean firstLoad = true; + private static final Map verifiedConfigs = new HashMap<>(); + + public static void init() { + verifiedConfigs.clear(); + -+ Class clazz = LeavesConfig.class; -+ for (Field field : clazz.getDeclaredFields()) { -+ if (Modifier.isStatic(field.getModifiers())) { -+ field.setAccessible(true); ++ for (Field field : LeavesConfig.class.getDeclaredFields()) { ++ initField(field, null, CONFIG_START); ++ } + -+ for (RemovedConfig removedConfig : field.getAnnotationsByType(RemovedConfig.class)) { -+ RemovedVerifiedConfig verifiedConfig = RemovedVerifiedConfig.build(removedConfig, field); -+ verifiedConfig.run(); -+ } ++ verifiedConfigs.forEach((path, config) -> config.validator.runAfterLoader(config.get(), firstLoad)); + -+ GlobalConfig globalConfig = field.getAnnotation(GlobalConfig.class); -+ if (globalConfig != null) { -+ try { -+ VerifiedConfig verifiedConfig = VerifiedConfig.build(globalConfig, field); ++ firstLoad = false; ++ LeavesConfig.save(); ++ } + -+ if (globalConfig.lock() && !firstLoad) { -+ verifiedConfigs.put(verifiedConfig.path.substring("settings.".length()), verifiedConfig); -+ continue; -+ } ++ private static void initCategory(@NotNull Field categoryField, @NotNull GlobalConfigCategory globalCategory, @Nullable Object upstreamField, @NotNull String upstreamPath) { ++ try { ++ Object category = categoryField.get(upstreamField); ++ String categoryPath = upstreamPath + globalCategory.value() + "."; ++ for (Field field : categoryField.getType().getDeclaredFields()) { ++ initField(field, category, categoryPath); ++ } ++ } catch (Exception e) { ++ LeavesLogger.LOGGER.severe("Failure to load leaves config" + upstreamPath, e); ++ } ++ } + -+ ConfigVerify verify = verifiedConfig.verify; ++ private static void initField(@NotNull Field field, @Nullable Object upstreamField, @NotNull String upstreamPath) { ++ if (upstreamField != null || Modifier.isStatic(field.getModifiers())) { ++ field.setAccessible(true); + -+ Object defValue = verify.saveConvert(field.get(null)); -+ LeavesConfig.config.addDefault(verifiedConfig.path, defValue); ++ for (RemovedConfig config : field.getAnnotationsByType(RemovedConfig.class)) { ++ RemovedVerifiedConfig.build(config, field, upstreamField).run(); ++ } + -+ try { -+ Object savedValue = LeavesConfig.config.get(verifiedConfig.path); -+ if (savedValue == null) { -+ throw new IllegalArgumentException("?"); -+ } ++ GlobalConfig globalConfig = field.getAnnotation(GlobalConfig.class); ++ if (globalConfig != null) { ++ initConfig(field, globalConfig, upstreamField, upstreamPath); ++ return; ++ } + -+ if (savedValue.getClass() != verify.getFieldClass()) { -+ savedValue = verify.loadConvert(savedValue); -+ } ++ GlobalConfigCategory globalCategory = field.getType().getAnnotation(GlobalConfigCategory.class); ++ if (globalCategory != null) { ++ initCategory(field, globalCategory, upstreamField, upstreamPath); ++ } ++ } ++ } + -+ verify.check(null, savedValue); ++ private static void initConfig(@NotNull Field field, GlobalConfig globalConfig, @Nullable Object upstreamField, @NotNull String upstreamPath) { ++ try { ++ VerifiedConfig verifiedConfig = VerifiedConfig.build(globalConfig, field, upstreamField, upstreamPath); + -+ field.set(null, savedValue); -+ } catch (IllegalArgumentException | ClassCastException e) { -+ LeavesConfig.config.set(verifiedConfig.path, defValue); -+ LeavesLogger.LOGGER.warning(e.getMessage() + ", reset to " + defValue); -+ } ++ if (globalConfig.lock() && !firstLoad) { ++ verifiedConfigs.put(verifiedConfig.path.substring(CONFIG_START.length()), verifiedConfig); ++ } + -+ verifiedConfigs.put(verifiedConfig.path.substring("settings.".length()), verifiedConfig); -+ } catch (Exception e) { -+ Bukkit.getLogger().log(Level.SEVERE, "Failure to load leaves config", e); -+ } ++ ConfigValidator validator = verifiedConfig.validator; ++ ++ Object defValue = validator.saveConvert(field.get(upstreamField)); ++ LeavesConfig.config.addDefault(verifiedConfig.path, defValue); ++ ++ try { ++ Object savedValue = LeavesConfig.config.get(verifiedConfig.path); ++ if (savedValue == null) { ++ throw new IllegalArgumentException("?"); + } -+ } -+ } + -+ verifiedConfigs.forEach((path, config) -> config.verify.runAfterLoader(config.get(), firstLoad)); ++ if (savedValue.getClass() != validator.getFieldClass()) { ++ savedValue = validator.loadConvert(savedValue); ++ } + -+ firstLoad = false; -+ LeavesConfig.save(); ++ validator.verify(null, savedValue); ++ ++ field.set(upstreamField, savedValue); ++ } catch (IllegalArgumentException | ClassCastException e) { ++ LeavesConfig.config.set(verifiedConfig.path, defValue); ++ LeavesLogger.LOGGER.warning(e.getMessage() + ", reset to " + defValue); ++ } ++ ++ verifiedConfigs.put(verifiedConfig.path.substring(CONFIG_START.length()), verifiedConfig); ++ } catch (Exception e) { ++ LeavesLogger.LOGGER.severe("Failure to load leaves config", e); ++ throw new RuntimeException(); ++ } + } + + public static VerifiedConfig getVerifiedConfig(String path) { + return verifiedConfigs.get(path); + } + -+ public static Set getVerifiedConfigPaths() { ++ @Contract(pure = true) ++ public static @NotNull Set getVerifiedConfigPaths() { + return verifiedConfigs.keySet(); + } + -+ public record RemovedVerifiedConfig(RemovedConfig config, ConfigConvert convert, Field field, String path) { ++ public record RemovedVerifiedConfig(ConfigConverter convert, boolean transform, Field field, Object upstreamField, String path) { + + public void run() { -+ if (config.transform()) { ++ if (transform) { + if (LeavesConfig.config.contains(path)) { + Object savedValue = LeavesConfig.config.get(path); + if (savedValue != null) { @@ -1785,7 +1908,7 @@ index 0000000000000000000000000000000000000000..7eb14d1725bb250f8a5983bad1f4641d + if (savedValue.getClass() != convert.getFieldClass()) { + savedValue = convert.loadConvert(savedValue); + } -+ field.set(null, savedValue); ++ field.set(upstreamField, savedValue); + } catch (IllegalAccessException | IllegalArgumentException e) { + LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e); + } @@ -1797,106 +1920,106 @@ index 0000000000000000000000000000000000000000..7eb14d1725bb250f8a5983bad1f4641d + LeavesConfig.config.set(path, null); + } + -+ @SuppressWarnings("all") -+ public static RemovedVerifiedConfig build(RemovedConfig config, Field field) { ++ @Contract("_, _, _ -> new") ++ public static @NotNull RemovedVerifiedConfig build(@NotNull RemovedConfig config, @NotNull Field field, @Nullable Object upstreamField) { + StringBuilder path = new StringBuilder("settings."); -+ for (int i = 0; i < config.category().length; i++) { -+ path.append(config.category()[i]).append("."); ++ for (String category : config.category()) { ++ path.append(category).append("."); + } + path.append(config.name()); + -+ ConfigConvert configConvert = null; ++ ConfigConverter converter = null; + try { -+ Constructor> constructor = config.convert().getDeclaredConstructor(); ++ Constructor> constructor = config.convert().getDeclaredConstructor(); + constructor.setAccessible(true); -+ configConvert = constructor.newInstance(); ++ converter = constructor.newInstance(); + } catch (Exception e) { + LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e); + } + -+ return new RemovedVerifiedConfig(config, configConvert, field, path.toString()); ++ return new RemovedVerifiedConfig(converter, config.transform(), field, upstreamField, path.toString()); + } + } + -+ public record VerifiedConfig(GlobalConfig config, ConfigVerify verify, Field field, String path) { ++ public record VerifiedConfig(ConfigValidator validator, boolean lock, Field field, Object upstreamField, String path) { + -+ public void set(String realValue) throws IllegalArgumentException { ++ public void set(String stringValue) throws IllegalArgumentException { + Object value; + try { -+ value = verify.convert(realValue); ++ value = validator.convert(stringValue); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("value parse error: " + e.getMessage()); + } + -+ verify.check(this.get(), value); ++ validator.verify(this.get(), value); + + try { -+ LeavesConfig.config.set(path, verify.saveConvert(value)); ++ LeavesConfig.config.set(path, validator.saveConvert(value)); + LeavesConfig.save(); -+ if (config.lock()) { ++ if (lock) { + throw new IllegalArgumentException("locked, will load after restart"); + } -+ field.set(null, value); ++ field.set(upstreamField, value); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e.getMessage()); + } + } + ++ public Object get() { ++ try { ++ return field.get(upstreamField); ++ } catch (IllegalAccessException e) { ++ LeavesLogger.LOGGER.severe("Failure to get " + path + " value", e); ++ return ""; ++ } ++ } ++ + public String getString() { + Object value = this.get(); + + Object savedValue = LeavesConfig.config.get(path); + try { + if (savedValue != null) { -+ if (verify.getFieldClass() != savedValue.getClass()) { -+ savedValue = verify.loadConvert(savedValue); ++ if (validator.getFieldClass() != savedValue.getClass()) { ++ savedValue = validator.loadConvert(savedValue); + } + + if (!savedValue.equals(value)) { + return value.toString() + "(" + savedValue + " after restart)"; + } + } -+ } catch (IllegalArgumentException ignore) { ++ } catch (IllegalArgumentException e) { ++ LeavesLogger.LOGGER.severe("Failure to get " + path + " value", e); + } + return value.toString(); + } + -+ public Object get() { -+ try { -+ return field.get(null); -+ } catch (IllegalAccessException e) { -+ LeavesLogger.LOGGER.log(Level.SEVERE, "Failure to get " + path + " value", e); -+ return ""; -+ } -+ } -+ -+ @SuppressWarnings("all") -+ public static VerifiedConfig build(GlobalConfig config, Field field) { -+ StringBuilder path = new StringBuilder("settings."); -+ for (int i = 0; i < config.category().length; i++) { -+ path.append(config.category()[i]).append("."); -+ } -+ path.append(config.name()); ++ @SuppressWarnings("unchecked") ++ @NotNull ++ @Contract("_, _, _, _ -> new") ++ public static VerifiedConfig build(@NotNull GlobalConfig config, @NotNull Field field, @Nullable Object upstreamField, @NotNull String upstreamPath) { ++ String path = upstreamPath + config.value(); + -+ ConfigVerify configVerify = null; ++ ConfigValidator validator; + try { -+ Constructor> constructor = config.verify().getDeclaredConstructor(); ++ Constructor> constructor = config.validator().getDeclaredConstructor(); + constructor.setAccessible(true); -+ configVerify = constructor.newInstance(); ++ validator = (ConfigValidator) constructor.newInstance(); + } catch (Exception e) { -+ LeavesLogger.LOGGER.warning("Failure to load leaves config" + path, e); ++ LeavesLogger.LOGGER.severe("Failure to load leaves config" + path, e); ++ throw new RuntimeException(); + } + -+ return new VerifiedConfig(config, configVerify, field, path.toString()); ++ return new VerifiedConfig(validator, config.lock(), field, upstreamField, path); + } + } +} diff --git a/src/main/java/org/leavesmc/leaves/config/RemovedConfig.java b/src/main/java/org/leavesmc/leaves/config/RemovedConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..a0f222d0fe7bbc09d3b894e121ad5b303c29375f +index 0000000000000000000000000000000000000000..a0364c2a5c4d56d30500233cd8294793309c7978 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/config/RemovedConfig.java -@@ -0,0 +1,21 @@ +@@ -0,0 +1,27 @@ +package org.leavesmc.leaves.config; + +import java.lang.annotation.ElementType; @@ -1907,7 +2030,7 @@ index 0000000000000000000000000000000000000000..a0f222d0fe7bbc09d3b894e121ad5b30 + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) -+@Repeatable(RemovedConfigs.class) ++@Repeatable(RemovedConfig.Array.class) +public @interface RemovedConfig { + + String name(); @@ -1916,23 +2039,11 @@ index 0000000000000000000000000000000000000000..a0f222d0fe7bbc09d3b894e121ad5b30 + + boolean transform() default false; + -+ Class> convert() default ConfigVerifyImpl.BooleanConfigVerify.class; -+} -diff --git a/src/main/java/org/leavesmc/leaves/config/RemovedConfigs.java b/src/main/java/org/leavesmc/leaves/config/RemovedConfigs.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b1ab6db328b562a8ab7d2091b47b81cee739adf1 ---- /dev/null -+++ b/src/main/java/org/leavesmc/leaves/config/RemovedConfigs.java -@@ -0,0 +1,12 @@ -+package org.leavesmc.leaves.config; -+ -+import java.lang.annotation.ElementType; -+import java.lang.annotation.Retention; -+import java.lang.annotation.RetentionPolicy; -+import java.lang.annotation.Target; ++ Class> convert() default ConfigValidatorImpl.BooleanConfigValidator.class; + -+@Target(ElementType.FIELD) -+@Retention(RetentionPolicy.RUNTIME) -+public @interface RemovedConfigs { -+ RemovedConfig[] value(); ++ @Target(ElementType.FIELD) ++ @Retention(RetentionPolicy.RUNTIME) ++ @interface Array { ++ RemovedConfig[] value(); ++ } +} diff --git a/patches/server/0007-Leaves-Protocol-Core.patch b/patches/server/0007-Leaves-Protocol-Core.patch index 7265c129..6cb323cc 100644 --- a/patches/server/0007-Leaves-Protocol-Core.patch +++ b/patches/server/0007-Leaves-Protocol-Core.patch @@ -47,12 +47,12 @@ index 1967c43ee3a12e63365cc40ee6565307e2fd73cf..6e376d0db5321d8e9b6e0b54617ffd17 assert isValidPath(path); diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 4464ce6ff4fd8eb9570205c7326c9a47b67d634d..7baa336edec37d8ca1d63f71b25d0daf035cdaf5 100644 +index ec5f7e652a05f35c2e6cbe31a63a980a2a476fb6..7518f8d633a6d348f9b86a12033eca3a9dad922c 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1806,6 +1806,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop map = MINECRAFT_REGISTER.get(protocol); + for (ProtocolHandler.MinecraftRegister register : map.keySet()) { -+ if (register.ignoreId() || register.channelId().equals(channel[1]) || -+ ArrayUtils.contains(register.channelIds(), channel[1])) { ++ if (register.ignoreId() || ArrayUtils.contains(register.channelId(), channel[1])) { + try { -+ map.get(register).invoke(null, player); ++ map.get(register).invoke(null, player, channel[1]); + } catch (InvocationTargetException | IllegalAccessException exception) { + LOGGER.warning("Failed to handle minecraft register, " + exception.getCause() + ": " + exception.getMessage()); + } @@ -620,10 +619,10 @@ index 0000000000000000000000000000000000000000..e5eb67c0bbdf4953ed0ccc3281f06eda +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java b/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java new file mode 100644 -index 0000000000000000000000000000000000000000..9d71f8e6af24301bedf60f5c87e0bb3c1697d5e3 +index 0000000000000000000000000000000000000000..202fb0717734aa8948ff8307420bf9aaf77d63ca --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/core/ProtocolHandler.java -@@ -0,0 +1,63 @@ +@@ -0,0 +1,55 @@ +package org.leavesmc.leaves.protocol.core; + +import java.lang.annotation.ElementType; @@ -636,13 +635,11 @@ index 0000000000000000000000000000000000000000..9d71f8e6af24301bedf60f5c87e0bb3c + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface Init { -+ + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface PayloadReceiver { -+ + Class> payload(); + + String[] payloadId() default ""; @@ -661,28 +658,22 @@ index 0000000000000000000000000000000000000000..9d71f8e6af24301bedf60f5c87e0bb3c + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface PlayerJoin { -+ + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface PlayerLeave { -+ + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface ReloadServer { -+ + } + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + public @interface MinecraftRegister { -+ -+ String channelId() default ""; -+ -+ String[] channelIds() default {}; ++ String[] channelId() default ""; + + boolean ignoreId() default false; + } diff --git a/patches/server/0008-Fix-trading-with-the-void.patch b/patches/server/0008-Fix-trading-with-the-void.patch index 6db257bc..84fc7a06 100644 --- a/patches/server/0008-Fix-trading-with-the-void.patch +++ b/patches/server/0008-Fix-trading-with-the-void.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix trading with the void diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 14e9140c9a18906c249e8cef39988ed7f81738f7..f30848556e677973c913ae481b268f51be90832a 100644 +index b4027f5cf90935a1fe3ab2c28b0bcbb55a7b541b..1d3f8b2c040b64e0f8548409a731d7f47d127f2c 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2565,11 +2565,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2753,11 +2753,7 @@ 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/0009-Make-snowball-and-egg-can-knockback-player.patch b/patches/server/0009-Make-snowball-and-egg-can-knockback-player.patch index d3d09765..a91d1c82 100644 --- a/patches/server/0009-Make-snowball-and-egg-can-knockback-player.patch +++ b/patches/server/0009-Make-snowball-and-egg-can-knockback-player.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Make snowball and egg can knockback player diff --git a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java -index 2b4d206c0d31ba38d7b2af654bd420e85145d441..f1070a44cd51b8d611f64e7e30691de372d9567f 100644 +index 70961e151666a0ecf5b791853f4581eaebbdcc8b..5d9834ce6a8f892339438a4fe262c9f5d52484fb 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/Snowball.java +++ b/src/main/java/net/minecraft/world/entity/projectile/Snowball.java @@ -61,6 +61,13 @@ public class Snowball extends ThrowableItemProjectile { @@ -14,7 +14,7 @@ index 2b4d206c0d31ba38d7b2af654bd420e85145d441..f1070a44cd51b8d611f64e7e30691de3 entity.hurt(this.damageSources().thrown(this, this.getOwner()), (float) i); + + // Leaves start - make snowball can knockback player -+ if (org.leavesmc.leaves.LeavesConfig.snowballAndEggCanKnockback && entity instanceof net.minecraft.server.level.ServerPlayer player) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.snowballAndEggCanKnockback && entity instanceof net.minecraft.server.level.ServerPlayer player) { + player.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); + player.knockback(0.4000000059604645D, this.getX() - player.getX(), this.getZ() - player.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE); + } @@ -23,15 +23,15 @@ index 2b4d206c0d31ba38d7b2af654bd420e85145d441..f1070a44cd51b8d611f64e7e30691de3 @Override 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 dbd60cc8c39f5d2d4c77e2de4f2567e7fa456cd2..2b8c8d0e813cd673f593dab49ecd4ee2d04dc6fa 100644 +index 155c2bbd35adacb7c3668fbe81a7c454e5102c8b..26696c09a2ce5c483dc2f723689ed985445663b8 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java -@@ -50,6 +50,12 @@ public class ThrownEgg extends ThrowableItemProjectile { +@@ -52,6 +52,12 @@ public class ThrownEgg extends ThrowableItemProjectile { protected void onHitEntity(EntityHitResult entityHitResult) { super.onHitEntity(entityHitResult); entityHitResult.getEntity().hurt(this.damageSources().thrown(this, this.getOwner()), 0.0F); + // Leaves start - make egg can knockback player -+ if (org.leavesmc.leaves.LeavesConfig.snowballAndEggCanKnockback && entityHitResult.getEntity() instanceof ServerPlayer player) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.snowballAndEggCanKnockback && entityHitResult.getEntity() instanceof ServerPlayer player) { + player.hurt(this.damageSources().thrown(this, this.getOwner()), 0.0000001F); + player.knockback(0.4000000059604645D, this.getX() - player.getX(), this.getZ() - player.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE); + } diff --git a/patches/server/0010-Fakeplayer-support.patch b/patches/server/0010-Fakeplayer-support.patch index ad25c942..b73b68b6 100644 --- a/patches/server/0010-Fakeplayer-support.patch +++ b/patches/server/0010-Fakeplayer-support.patch @@ -34,7 +34,7 @@ index 35772110e9318df46a2729dbc0b5879b290011b7..f26989a44cdda9baabf337d573436c6c Set> set = (Set) playerAdvancements.criterionData.get(this); // Paper - fix AdvancementDataPlayer leak if (set != null && !set.isEmpty()) { diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index 4a8356a714ed50d4a32bcf046a2e16491bef014b..b19298aeaa0dacfe1afb1e672bd30b0c069ec968 100644 +index e693a003ea8f022eef8b49e4332025b769333b30..49e03ba7c04381e263aaee5cda9ed6c042bf6c0e 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -104,7 +104,7 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -47,19 +47,19 @@ index 4a8356a714ed50d4a32bcf046a2e16491bef014b..b19298aeaa0dacfe1afb1e672bd30b0c private DisconnectionDetails disconnectionDetails; private boolean encrypted; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 7baa336edec37d8ca1d63f71b25d0daf035cdaf5..cb863f07d00e96b92e73dc312606110c259b4d5c 100644 +index 7518f8d633a6d348f9b86a12033eca3a9dad922c..f0d2c8bc40b36e6d638ad418963289ac2737f5a0 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -318,6 +318,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop pluginsBlockingSleep = new java.util.HashSet<>(); // Paper - API to allow/disallow tick sleeping + private org.leavesmc.leaves.bot.BotList botList; // Leaves - fakeplayer + public static S spin(Function serverFactory) { AtomicReference atomicreference = new AtomicReference(); Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> { // Paper - rewrite chunk system -@@ -745,6 +747,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> optional = PoiTypes.forState(oldBlock); -@@ -2497,6 +2505,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2685,6 +2693,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); @@ -192,7 +192,7 @@ index f30848556e677973c913ae481b268f51be90832a..82fe09e3ac6388611a168946f0c457f6 ServerLevel.this.updateSleepingPlayerList(); } -@@ -2574,6 +2587,11 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2762,6 +2775,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ServerLevel.this.getChunkSource().removeEntity(entity); if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.remove(entityplayer); @@ -205,10 +205,10 @@ index f30848556e677973c913ae481b268f51be90832a..82fe09e3ac6388611a168946f0c457f6 } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index c396580a9cfd86ff261bed439bb4662ae88010b5..c2263ef7fb67db7c01bac7aecf218ee8cb7369cb 100644 +index 5a8f396d47577f087abb415c972fd4f51e50faba..ebae6c704844755c75aa0c6f460603c5d909b5cf 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -212,7 +212,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -234,7 +234,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple private static final AttributeModifier CREATIVE_ENTITY_INTERACTION_RANGE_MODIFIER = new AttributeModifier(ResourceLocation.withDefaultNamespace("creative_mode_entity_range"), 2.0D, AttributeModifier.Operation.ADD_VALUE); public ServerGamePacketListenerImpl connection; public final MinecraftServer server; @@ -217,7 +217,7 @@ index c396580a9cfd86ff261bed439bb4662ae88010b5..c2263ef7fb67db7c01bac7aecf218ee8 private final PlayerAdvancements advancements; private final ServerStatsCounter stats; private float lastRecordedHealthAndAbsorption = Float.MIN_VALUE; -@@ -770,16 +770,20 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -998,16 +998,20 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple --this.invulnerableTime; } @@ -247,7 +247,7 @@ index c396580a9cfd86ff261bed439bb4662ae88010b5..c2263ef7fb67db7c01bac7aecf218ee8 Entity entity = this.getCamera(); -@@ -795,7 +799,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -1023,7 +1027,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple } } @@ -256,12 +256,12 @@ index c396580a9cfd86ff261bed439bb4662ae88010b5..c2263ef7fb67db7c01bac7aecf218ee8 if (this.levitationStartPos != null) { CriteriaTriggers.LEVITATION.trigger(this, this.levitationStartPos, this.tickCount - this.levitationStartTime); } -@@ -1416,6 +1420,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -1680,6 +1684,12 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple this.lastSentHealth = -1.0F; this.lastSentFood = -1; + // Leaves start - bot support -+ if (org.leavesmc.leaves.LeavesConfig.fakeplayerSupport) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable) { + this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(this, true)); // Leaves - render bot + } + // Leaves end - bot support @@ -270,10 +270,10 @@ index c396580a9cfd86ff261bed439bb4662ae88010b5..c2263ef7fb67db7c01bac7aecf218ee8 PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld()); this.level().getCraftServer().getPluginManager().callEvent(changeEvent); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 6bc129a8a71e8936d596fa2e585a259282d11622..ba5fd079be52e8d179029925777dad3db3de2433 100644 +index 9b1645cf1fa47b8d7592c7eda4a4497ad9d6bbf8..9b3fbc13779ded07c696e151772d834ff8d61a7d 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -123,6 +123,8 @@ import org.bukkit.event.player.PlayerRespawnEvent.RespawnReason; +@@ -124,6 +124,8 @@ import org.bukkit.event.player.PlayerRespawnEvent.RespawnReason; import org.bukkit.event.player.PlayerSpawnChangeEvent; // CraftBukkit end @@ -282,12 +282,12 @@ index 6bc129a8a71e8936d596fa2e585a259282d11622..ba5fd079be52e8d179029925777dad3d public abstract class PlayerList { public static final File USERBANLIST_FILE = new File("banned-players.json"); -@@ -351,6 +353,19 @@ public abstract class PlayerList { +@@ -355,6 +357,19 @@ public abstract class PlayerList { org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol + // Leaves start - bot support -+ if (org.leavesmc.leaves.LeavesConfig.fakeplayerSupport) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable) { + ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName()); + if (bot != null) { + this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false); @@ -302,12 +302,12 @@ index 6bc129a8a71e8936d596fa2e585a259282d11622..ba5fd079be52e8d179029925777dad3d final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure -@@ -941,6 +956,12 @@ public abstract class PlayerList { +@@ -907,6 +922,12 @@ public abstract class PlayerList { } // Paper end - Add PlayerPostRespawnEvent + // Leaves start - bot support -+ if (org.leavesmc.leaves.LeavesConfig.fakeplayerSupport) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable) { + this.server.getBotList().bots.forEach(bot -> bot.sendFakeDataIfNeed(entityplayer1, true)); // Leaves - render bot + } + // Leaves end - bot support @@ -315,7 +315,7 @@ index 6bc129a8a71e8936d596fa2e585a259282d11622..ba5fd079be52e8d179029925777dad3d // CraftBukkit end return entityplayer1; -@@ -1078,11 +1099,16 @@ public abstract class PlayerList { +@@ -1044,11 +1065,16 @@ public abstract class PlayerList { } public String[] getPlayerNamesArray() { @@ -333,7 +333,7 @@ index 6bc129a8a71e8936d596fa2e585a259282d11622..ba5fd079be52e8d179029925777dad3d return astring; } -@@ -1169,7 +1195,13 @@ public abstract class PlayerList { +@@ -1135,7 +1161,13 @@ public abstract class PlayerList { @Nullable public ServerPlayer getPlayerByName(String name) { @@ -348,7 +348,7 @@ index 6bc129a8a71e8936d596fa2e585a259282d11622..ba5fd079be52e8d179029925777dad3d } public void broadcast(@Nullable net.minecraft.world.entity.player.Player player, double x, double y, double z, double distance, ResourceKey worldKey, Packet packet) { -@@ -1509,7 +1541,13 @@ public abstract class PlayerList { +@@ -1476,7 +1508,13 @@ public abstract class PlayerList { @Nullable public ServerPlayer getPlayer(UUID uuid) { @@ -364,10 +364,10 @@ index 6bc129a8a71e8936d596fa2e585a259282d11622..ba5fd079be52e8d179029925777dad3d public boolean canBypassPlayerLimit(GameProfile profile) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index b5283b7a59c76e75ba9a822f315ba0d813df8cfb..35eafbfa719c9ac3e235df0728650e1ed1c23fcd 100644 +index 922996adcf2b85e55a934191e90a12c42f169b0f..7e61b008c9429f6ef60fcef4887bb50db4face91 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1457,7 +1457,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1522,7 +1522,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return offsetFactor; } @@ -377,7 +377,7 @@ index b5283b7a59c76e75ba9a822f315ba0d813df8cfb..35eafbfa719c9ac3e235df0728650e1e final boolean xZero = movement.x == 0.0; final boolean yZero = movement.y == 0.0; 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 09bcbc0ae36e4e69fee87a7e0c49acf496117a39..65b002f2ae062327f48df0e157aa35721478c5fd 100644 +index 61d412c4f1ebd55661cc3f0260468e3ac0efe0bb..c7bc8f493305cca9bac60c79e4e35cf5e369d355 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -183,7 +183,7 @@ public abstract class Player extends LivingEntity { @@ -389,7 +389,7 @@ index 09bcbc0ae36e4e69fee87a7e0c49acf496117a39..65b002f2ae062327f48df0e157aa3572 private final ItemCooldowns cooldowns; private Optional lastDeathLocation; @Nullable -@@ -337,6 +337,12 @@ public abstract class Player extends LivingEntity { +@@ -340,6 +340,12 @@ public abstract class Player extends LivingEntity { } @@ -402,7 +402,7 @@ index 09bcbc0ae36e4e69fee87a7e0c49acf496117a39..65b002f2ae062327f48df0e157aa3572 @Override protected float getMaxHeadRotationRelativeToBody() { return this.isBlocking() ? 15.0F : super.getMaxHeadRotationRelativeToBody(); -@@ -635,7 +641,7 @@ public abstract class Player extends LivingEntity { +@@ -661,7 +667,7 @@ public abstract class Player extends LivingEntity { } @@ -412,7 +412,7 @@ index 09bcbc0ae36e4e69fee87a7e0c49acf496117a39..65b002f2ae062327f48df0e157aa3572 } 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 1223c5d23d0ea6aed068bdf0f5725e2ad49fc82c..0e00f59a8962dd6356d483ef5be3209a3a410008 100644 +index 4daa69c6be6d48563e30343a7e40e4da9ec7e5ad..d5cb0d8ad7f7ed18ce38b39f245f5ec2c67042d5 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java @@ -63,7 +63,7 @@ public class FishingHook extends Projectile { @@ -425,10 +425,10 @@ index 1223c5d23d0ea6aed068bdf0f5725e2ad49fc82c..0e00f59a8962dd6356d483ef5be3209a public int timeUntilHooked; public float fishAngle; diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index dd4218e108f87f3305b76fbc8d88f488b447c609..9bb703f2af1f201772b5309a4d80b3fbe23a7201 100644 +index 4680f77a275d8d2b226018db89a571ac25998dd8..a21c658343ab6e1eb3a98ff10369b490bd7d52da 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -406,6 +406,8 @@ public abstract class AbstractContainerMenu { +@@ -443,6 +443,8 @@ public abstract class AbstractContainerMenu { ItemStack itemstack1; int l; @@ -437,7 +437,7 @@ index dd4218e108f87f3305b76fbc8d88f488b447c609..9bb703f2af1f201772b5309a4d80b3fb if (actionType == ClickType.QUICK_CRAFT) { int i1 = this.quickcraftStatus; -@@ -680,6 +682,22 @@ public abstract class AbstractContainerMenu { +@@ -733,6 +735,22 @@ public abstract class AbstractContainerMenu { } @@ -461,7 +461,7 @@ index dd4218e108f87f3305b76fbc8d88f488b447c609..9bb703f2af1f201772b5309a4d80b3fb FeatureFlagSet featureflagset = player.level().enabledFeatures(); 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 1b1b475ca27e799e251d6f8a8c9fe1a4fd8bae83..22f8e7d62df86a12c5b9ad709538d6ac564d3338 100644 +index 021221da5d0315f6e371380a705ac6b3f6ac18d3..9c13b31e3a0ce6542ef2b2dd2361b906fdb359b8 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java +++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java @@ -67,6 +67,11 @@ public class PhantomSpawner implements CustomSpawner { @@ -503,22 +503,22 @@ index b148cf247acdd36f856d0495cde4cc5ad32b5a2f..011d6c813781251c7f4041ad3a8396fb private static final Logger LOGGER = LogUtils.getLogger(); private final File playerDir; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -index c9ecec5da937bc5458f69736b68ff6ae50aa5ebc..decaea842c557adecb9d2d6e654376f0508721bd 100644 +index adc6741e0e017660fbd39a62b69be1e67e0e143f..9bc40b07b8eebded4f748fd053b45571df6286a5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java -@@ -428,6 +428,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor { +@@ -434,6 +434,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor { @SuppressWarnings("unchecked") public T addEntity(T entity) { Preconditions.checkArgument(!entity.isInWorld(), "Entity has already been added to a world"); + Preconditions.checkState(!(entity instanceof org.leavesmc.leaves.entity.CraftBot), "[Leaves] Fakeplayers do not support changing world, Please use leaves fakeplayer-api instead!"); net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) entity).getHandle(); if (nmsEntity.level() != this.getHandle().getLevel()) { - nmsEntity = nmsEntity.changeDimension(new DimensionTransition(this.getHandle().getLevel(), nmsEntity, DimensionTransition.DO_NOTHING)); + nmsEntity = nmsEntity.teleport(new TeleportTransition(this.getHandle().getLevel(), nmsEntity, TeleportTransition.DO_NOTHING)); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index e79af523a49aaa6558b690383cb29649e6ae40c8..61dd71c2d5efbcb5dd363e2ac16757011b454082 100644 +index 3435629606def598ca998fb41ef303677c4cbea4..26ef09c86315c1125167af044323dbd3dbcfc6f0 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 { +@@ -313,6 +313,7 @@ public final class CraftServer implements Server { private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes public final io.papermc.paper.SparksFly spark; // Paper - spark @@ -526,7 +526,7 @@ index e79af523a49aaa6558b690383cb29649e6ae40c8..61dd71c2d5efbcb5dd363e2ac1675701 // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); -@@ -478,6 +479,7 @@ public final class CraftServer implements Server { +@@ -492,6 +493,7 @@ public final class CraftServer implements Server { datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper this.spark = new io.papermc.paper.SparksFly(this); // Paper - spark org.leavesmc.leaves.protocol.core.LeavesProtocolManager.init(); // Leaves - protocol @@ -534,7 +534,7 @@ index e79af523a49aaa6558b690383cb29649e6ae40c8..61dd71c2d5efbcb5dd363e2ac1675701 } public boolean getCommandBlockOverride(String command) { -@@ -1465,7 +1467,7 @@ public final class CraftServer implements Server { +@@ -1479,7 +1481,7 @@ public final class CraftServer implements Server { return false; } @@ -543,10 +543,10 @@ index e79af523a49aaa6558b690383cb29649e6ae40c8..61dd71c2d5efbcb5dd363e2ac1675701 return false; } -@@ -3228,4 +3230,11 @@ public final class CraftServer implements Server { - return this.potionBrewer; +@@ -3281,4 +3283,11 @@ public final class CraftServer implements Server { + this.console.addPluginAllowingSleep(plugin.getName(), value); } - // Paper end + // Paper end - API to check if the server is sleeping + + // Leaves start - Bot API + @Override @@ -556,10 +556,10 @@ index e79af523a49aaa6558b690383cb29649e6ae40c8..61dd71c2d5efbcb5dd363e2ac1675701 + // Leaves end - Bot API } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index e76186d580a2d7f1a83af4600b0bdd435b67eba3..ce3d2a893729a95c6a74a373849dd42e04f7d68b 100644 +index 8f234b46c24a0ae08aa5f8190c5b27e1f62dfbab..df51d6d7909d407d8dcdbe1bfc5ca3a423005d5c 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -245,7 +245,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -241,7 +241,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public int getPlayerCount() { @@ -568,7 +568,7 @@ index e76186d580a2d7f1a83af4600b0bdd435b67eba3..ce3d2a893729a95c6a74a373849dd42e } @Override -@@ -1295,9 +1295,9 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1285,9 +1285,9 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public List getPlayers() { @@ -580,7 +580,7 @@ index e76186d580a2d7f1a83af4600b0bdd435b67eba3..ce3d2a893729a95c6a74a373849dd42e HumanEntity bukkitEntity = human.getBukkitEntity(); if ((bukkitEntity != null) && (bukkitEntity instanceof Player)) { -@@ -1982,7 +1982,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1960,7 +1960,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { public void playSound(final net.kyori.adventure.sound.Sound sound) { org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper final long seed = sound.seed().orElseGet(this.world.getRandom()::nextLong); @@ -589,7 +589,7 @@ index e76186d580a2d7f1a83af4600b0bdd435b67eba3..ce3d2a893729a95c6a74a373849dd42e player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player.getX(), player.getY(), player.getZ(), seed, null)); } } -@@ -1998,7 +1998,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -1988,7 +1988,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { org.spigotmc.AsyncCatcher.catchOp("play sound"); // Paper final long seed = sound.seed().orElseGet(this.getHandle().getRandom()::nextLong); if (emitter == net.kyori.adventure.sound.Sound.Emitter.self()) { @@ -598,7 +598,7 @@ index e76186d580a2d7f1a83af4600b0bdd435b67eba3..ce3d2a893729a95c6a74a373849dd42e player.connection.send(io.papermc.paper.adventure.PaperAdventure.asSoundPacket(sound, player, seed, null)); } } else if (emitter instanceof CraftEntity craftEntity) { -@@ -2219,7 +2219,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2212,7 +2212,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType()); } this.getHandle().sendParticles( @@ -608,10 +608,10 @@ index e76186d580a2d7f1a83af4600b0bdd435b67eba3..ce3d2a893729a95c6a74a373849dd42e CraftParticle.createParticleParam(particle, data), // Particle x, y, z, // Position diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 89c8713d2c2206d1b0d8c0a392c9d13b3e736f0c..48d3e8c718fb0d2926f6b2f26855bbbe115ccf7a 100644 +index ddabaed899c755925ad8618b78c33dacaf2126ac..dea387f418cd173980be2e6e24797b55f9f58409 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -94,6 +94,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -95,6 +95,8 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return new CraftHumanEntity(server, (net.minecraft.world.entity.player.Player) entity); } @@ -621,10 +621,10 @@ index 89c8713d2c2206d1b0d8c0a392c9d13b3e736f0c..48d3e8c718fb0d2926f6b2f26855bbbe if (entity instanceof EnderDragonPart complexPart) { if (complexPart.parentMob instanceof EnderDragon) { diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index 4632eb883e9f5efde520ee543bcad25827c0da2c..d710803137a325f34e0628405d5ddfd0bce16a95 100644 +index e37aaf77f94b97b736cc20ef070cefdff0400188..efc92e321bb78702388fb572197b7e442c463170 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -1027,7 +1027,10 @@ public class CraftEventFactory { +@@ -1025,7 +1025,10 @@ public class CraftEventFactory { event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel populateFields(victim, event); // Paper - make cancellable @@ -638,7 +638,7 @@ index 4632eb883e9f5efde520ee543bcad25827c0da2c..d710803137a325f34e0628405d5ddfd0 return event; diff --git a/src/main/java/org/leavesmc/leaves/bot/BotCommand.java b/src/main/java/org/leavesmc/leaves/bot/BotCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5fbc27a190 +index 0000000000000000000000000000000000000000..4bf25cb267a8d01c2d04a2a9e34b9fc6a433cade --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/BotCommand.java @@ -0,0 +1,544 @@ @@ -703,13 +703,13 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + if (args.length <= 1) { + list.add("create"); + list.add("remove"); -+ if (LeavesConfig.fakeplayerUseAction) { ++ if (LeavesConfig.modify.fakeplayer.canUseAction) { + list.add("action"); + } -+ if (LeavesConfig.fakeplayerModifyConfig) { ++ if (LeavesConfig.modify.fakeplayer.canModifyConfig) { + list.add("config"); + } -+ if (LeavesConfig.fakeplayerManualSaveAndLoad) { ++ if (LeavesConfig.modify.fakeplayer.canManualSaveAndLoad) { + list.add("save"); + list.add("load"); + } @@ -779,7 +779,7 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + + @Override + public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, String[] args) { -+ if (!testPermission(sender) || !LeavesConfig.fakeplayerSupport) return true; ++ if (!testPermission(sender) || !LeavesConfig.modify.fakeplayer.enable) return true; + + if (args.length == 0) { + sender.sendMessage(unknownMessage); @@ -851,12 +851,12 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + return false; + } + -+ if (org.leavesmc.leaves.LeavesConfig.unableFakeplayerNames.contains(name)) { ++ if (LeavesConfig.modify.fakeplayer.unableNames.contains(name)) { + sender.sendMessage(text("This name is not allowed", NamedTextColor.RED)); + return false; + } + -+ if (botList.bots.size() >= org.leavesmc.leaves.LeavesConfig.fakeplayerLimit) { ++ if (botList.bots.size() >= LeavesConfig.modify.fakeplayer.limit) { + sender.sendMessage(text("Fakeplayer limit is full", NamedTextColor.RED)); + return false; + } @@ -939,7 +939,7 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + } + + private void onAction(CommandSender sender, String @NotNull [] args) { -+ if (!LeavesConfig.fakeplayerUseAction) { ++ if (!LeavesConfig.modify.fakeplayer.canUseAction) { + return; + } + @@ -1051,7 +1051,7 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + private static final List acceptConfig = Configs.getConfigs().stream().map(config -> config.config.getName()).toList(); + + private void onConfig(CommandSender sender, String @NotNull [] args) { -+ if (!LeavesConfig.fakeplayerModifyConfig) { ++ if (!LeavesConfig.modify.fakeplayer.canModifyConfig) { + return; + } + @@ -1096,7 +1096,7 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + } + + private void onSave(CommandSender sender, String @NotNull [] args) { -+ if (!LeavesConfig.fakeplayerManualSaveAndLoad) { ++ if (!LeavesConfig.modify.fakeplayer.canManualSaveAndLoad) { + return; + } + @@ -1119,7 +1119,7 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + } + + private void onLoad(CommandSender sender, String @NotNull [] args) { -+ if (!LeavesConfig.fakeplayerManualSaveAndLoad) { ++ if (!LeavesConfig.modify.fakeplayer.canManualSaveAndLoad) { + return; + } + @@ -1153,7 +1153,7 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f + botMap.get(bukkitBot.getWorld()).add(bukkitBot.getName()); + } + -+ sender.sendMessage("Total number: (" + botList.bots.size() + "/" + org.leavesmc.leaves.LeavesConfig.fakeplayerLimit + ")"); ++ sender.sendMessage("Total number: (" + botList.bots.size() + "/" + LeavesConfig.modify.fakeplayer.limit + ")"); + for (World world : botMap.keySet()) { + sender.sendMessage(world.getName() + "(" + botMap.get(world).size() + "): " + formatPlayerNameList(botMap.get(world))); + } @@ -1188,7 +1188,7 @@ index 0000000000000000000000000000000000000000..527f01b206dcf0e677ac7ec8c27ebf5f +} diff --git a/src/main/java/org/leavesmc/leaves/bot/BotCreateState.java b/src/main/java/org/leavesmc/leaves/bot/BotCreateState.java new file mode 100644 -index 0000000000000000000000000000000000000000..ebb3aa94718382e8fac2a8fa617c796a9387709b +index 0000000000000000000000000000000000000000..bc09bb05fdccc7e6e51f441b0c23237145317e89 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/BotCreateState.java @@ -0,0 +1,120 @@ @@ -1242,7 +1242,7 @@ index 0000000000000000000000000000000000000000..ebb3aa94718382e8fac2a8fa617c796a + this.realName = realName; + this.location = location; + -+ this.name = LeavesConfig.fakeplayerPrefix + realName + LeavesConfig.fakeplayerSuffix; ++ this.name = LeavesConfig.modify.fakeplayer.prefix + realName + LeavesConfig.modify.fakeplayer.suffix; + this.skinName = this.realName; + this.skin = null; + this.createReason = BotCreateEvent.CreateReason.UNKNOWN; @@ -1638,10 +1638,10 @@ index 0000000000000000000000000000000000000000..4f5e6e5c1b9d8bd38c98e97fd31b3833 +} diff --git a/src/main/java/org/leavesmc/leaves/bot/BotList.java b/src/main/java/org/leavesmc/leaves/bot/BotList.java new file mode 100644 -index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256391085c0 +index 0000000000000000000000000000000000000000..3881aa5c5bd18a8859715ad31624dbd5e92e5721 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/BotList.java -@@ -0,0 +1,340 @@ +@@ -0,0 +1,297 @@ +package org.leavesmc.leaves.bot; + +import com.google.common.collect.Maps; @@ -1659,7 +1659,6 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.Level; +import org.bukkit.Bukkit; +import org.bukkit.Location; @@ -1675,7 +1674,6 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 +import org.leavesmc.leaves.event.bot.BotSpawnLocationEvent; +import org.slf4j.Logger; + -+import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; @@ -1762,7 +1760,10 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + } + + public ServerBot placeNewBot(ServerBot bot, ServerLevel world, Location location, @Nullable CompoundTag nbt) { ++ Optional optional = Optional.ofNullable(nbt); ++ + bot.isRealPlayer = true; ++ bot.loginTime = System.currentTimeMillis(); + bot.connection = new ServerBotPacketListenerImpl(this.server, bot); + bot.setServerLevel(world); + @@ -1771,18 +1772,21 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + location = event.getSpawnLocation(); + + bot.spawnIn(world); -+ bot.gameMode.setLevel((ServerLevel) bot.level()); ++ bot.gameMode.setLevel(bot.serverLevel()); + + bot.setPosRaw(location.getX(), location.getY(), location.getZ()); + bot.setRot(location.getYaw(), location.getPitch()); + ++ bot.connection.teleport(bot.getX(), bot.getY(), bot.getZ(), bot.getYRot(), bot.getXRot()); ++ + this.bots.add(bot); + this.botsByName.put(bot.getScoreboardName().toLowerCase(Locale.ROOT), bot); + this.botsByUUID.put(bot.getUUID(), bot); + + bot.supressTrackerForLogin = true; + world.addNewPlayer(bot); -+ this.mountSavedVehicle(bot, world, nbt); ++ bot.loadAndSpawnEnderpearls(optional); ++ bot.loadAndSpawnParentVehicle(optional); + + BotJoinEvent event1 = new BotJoinEvent(bot.getBukkitEntity(), PaperAdventure.asAdventure(Component.translatable("multiplayer.player.joined", bot.getDisplayName())).style(Style.style(NamedTextColor.YELLOW))); + this.server.server.getPluginManager().callEvent(event1); @@ -1794,59 +1798,12 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + + bot.renderAll(); + bot.supressTrackerForLogin = false; ++ + bot.serverLevel().getChunkSource().chunkMap.addEntity(bot); + BotList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", bot.getName().getString(), "Local", bot.getId(), bot.serverLevel().serverLevelData.getLevelName(), bot.getX(), bot.getY(), bot.getZ()); + return bot; + } + -+ private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, @Nullable CompoundTag nbt) { -+ Optional optional = Optional.ofNullable(nbt); -+ if (optional.isPresent() && optional.get().contains("RootVehicle", 10)) { -+ CompoundTag nbttagcompound = optional.get().getCompound("RootVehicle"); -+ Entity entity = EntityType.loadEntityRecursive(nbttagcompound.getCompound("Entity"), worldserver1, (entity1) -> { -+ return !worldserver1.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; -+ }); -+ -+ if (entity != null) { -+ UUID uuid; -+ -+ if (nbttagcompound.hasUUID("Attach")) { -+ uuid = nbttagcompound.getUUID("Attach"); -+ } else { -+ uuid = null; -+ } -+ -+ Iterator iterator; -+ Entity entity1; -+ -+ if (entity.getUUID().equals(uuid)) { -+ player.startRiding(entity, true); -+ } else { -+ iterator = entity.getIndirectPassengers().iterator(); -+ -+ while (iterator.hasNext()) { -+ entity1 = iterator.next(); -+ if (entity1.getUUID().equals(uuid)) { -+ player.startRiding(entity1, true); -+ break; -+ } -+ } -+ } -+ -+ if (!player.isPassenger()) { -+ BotList.LOGGER.warn("Couldn't reattach entity to fakeplayer"); -+ entity.discard(); -+ iterator = entity.getIndirectPassengers().iterator(); -+ -+ while (iterator.hasNext()) { -+ entity1 = iterator.next(); -+ entity1.discard(); -+ } -+ } -+ } -+ } -+ } -+ + public boolean removeBot(@NotNull ServerBot bot, @NotNull BotRemoveEvent.RemoveReason reason, @Nullable CommandSender remover, boolean saved) { + return this.removeBot(bot, reason, remover, saved, this.dataStorage); + } @@ -1917,13 +1874,13 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + + public void removeAll() { + for (ServerBot bot : this.bots) { -+ bot.resume = LeavesConfig.fakeplayerResident; -+ this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, LeavesConfig.fakeplayerResident); ++ bot.resume = LeavesConfig.modify.fakeplayer.canResident; ++ this.removeBot(bot, BotRemoveEvent.RemoveReason.INTERNAL, null, LeavesConfig.modify.fakeplayer.canResident); + } + } + + public void loadResume() { -+ if (LeavesConfig.fakeplayerSupport && LeavesConfig.fakeplayerResident) { ++ if (LeavesConfig.modify.fakeplayer.enable && LeavesConfig.modify.fakeplayer.canResident) { + CompoundTag savedBotList = this.getSavedBotList().copy(); + for (String realName : savedBotList.getAllKeys()) { + CompoundTag nbt = savedBotList.getCompound(realName); @@ -1961,11 +1918,11 @@ index 0000000000000000000000000000000000000000..bb33cad06036f188bd9228556fff6256 + return false; + } + -+ if (LeavesConfig.unableFakeplayerNames.contains(name)) { ++ if (LeavesConfig.modify.fakeplayer.unableNames.contains(name)) { + return false; + } + -+ return this.bots.size() < LeavesConfig.fakeplayerLimit; ++ return this.bots.size() < LeavesConfig.modify.fakeplayer.limit; + } + + public static class CustomGameProfile extends GameProfile { @@ -2124,7 +2081,7 @@ index 0000000000000000000000000000000000000000..7ebe4d6c71e90be92387a585ea581c6b +} diff --git a/src/main/java/org/leavesmc/leaves/bot/MojangAPI.java b/src/main/java/org/leavesmc/leaves/bot/MojangAPI.java new file mode 100644 -index 0000000000000000000000000000000000000000..517e3321b866abe9d17a6fe9e919528b50bb130a +index 0000000000000000000000000000000000000000..4162df8802b1af73d9a0a76f846ab9ad953a1921 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/MojangAPI.java @@ -0,0 +1,39 @@ @@ -2145,7 +2102,7 @@ index 0000000000000000000000000000000000000000..517e3321b866abe9d17a6fe9e919528b + private static final Map CACHE = new HashMap<>(); + + public static String[] getSkin(String name) { -+ if (LeavesConfig.fakeplayerCacheSkin && CACHE.containsKey(name)) { ++ if (LeavesConfig.modify.fakeplayer.useSkinCache && CACHE.containsKey(name)) { + return CACHE.get(name); + } + @@ -2169,10 +2126,10 @@ index 0000000000000000000000000000000000000000..517e3321b866abe9d17a6fe9e919528b +} diff --git a/src/main/java/org/leavesmc/leaves/bot/ServerBot.java b/src/main/java/org/leavesmc/leaves/bot/ServerBot.java new file mode 100644 -index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a79a459dee +index 0000000000000000000000000000000000000000..f83b787a6827bdcf3927dbf2a0a0fa6e998959ac --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/ServerBot.java -@@ -0,0 +1,548 @@ +@@ -0,0 +1,556 @@ +package org.leavesmc.leaves.bot; + +import com.google.common.collect.ImmutableMap; @@ -2204,6 +2161,7 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EquipmentSlot; ++import net.minecraft.world.entity.PositionMoveRotation; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; @@ -2212,7 +2170,7 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 +import net.minecraft.world.level.GameRules; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; -+import net.minecraft.world.level.portal.DimensionTransition; ++import net.minecraft.world.level.portal.TeleportTransition; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.Vec3; +import org.bukkit.Bukkit; @@ -2282,7 +2240,7 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + this.tracingRange = world.spigotConfig.playerTrackingRange * world.spigotConfig.playerTrackingRange; + + this.notSleepTicks = 0; -+ this.fauxSleeping = LeavesConfig.fakeplayerSkipSleep; ++ this.fauxSleeping = LeavesConfig.modify.fakeplayer.canSkipSleep; + } + + public void sendPlayerInfo(ServerPlayer player) { @@ -2330,7 +2288,7 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + + @Override + public void die(@NotNull DamageSource damageSource) { -+ boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); ++ boolean flag = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); + Component defaultMessage = this.getCombatTracker().getDeathMessage(); + + BotDeathEvent event = new BotDeathEvent(this.getBukkitEntity(), PaperAdventure.asAdventure(defaultMessage), flag); @@ -2357,10 +2315,23 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + this.sendPacket(new ClientboundPlayerInfoRemovePacket(List.of(this.getUUID()))); + } + -+ @Nullable + @Override -+ public Entity changeDimension(@NotNull DimensionTransition teleportTarget) { -+ return this; // disable dimension change ++ public @Nullable ServerBot teleport(@NotNull TeleportTransition teleportTarget) { ++ if (this.isSleeping() || this.isRemoved()) { ++ return null; ++ } ++ if (teleportTarget.newLevel().dimension() != this.serverLevel().dimension()) { ++ return null; ++ } else { ++ if (!teleportTarget.asPassenger()) { ++ this.stopRiding(); ++ } ++ ++ this.connection.internalTeleport(PositionMoveRotation.of(teleportTarget), teleportTarget.relatives()); ++ this.connection.resetPosition(); ++ teleportTarget.postTeleportTransition().onTransition(this); ++ return this; ++ } + } + + @Override @@ -2378,10 +2349,10 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + notSleepTicks++; + } + -+ if (LeavesConfig.fakeplayerRegenAmount > 0.0 && server.getTickCount() % 20 == 0) { ++ if (LeavesConfig.modify.fakeplayer.regenAmount > 0.0 && server.getTickCount() % 20 == 0) { + float health = getHealth(); + float maxHealth = getMaxHealth(); -+ float regenAmount = (float) (LeavesConfig.fakeplayerRegenAmount * 20); ++ float regenAmount = (float) (LeavesConfig.modify.fakeplayer.regenAmount * 20); + float amount; + + if (health < maxHealth - regenAmount) { @@ -2414,13 +2385,12 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + + @Override + public @NotNull InteractionResult interact(@NotNull Player player, @NotNull InteractionHand hand) { -+ if (LeavesConfig.openFakeplayerInventory) { ++ if (LeavesConfig.modify.fakeplayer.canOpenInventory) { + if (player instanceof ServerPlayer player1 && player.getMainHandItem().isEmpty()) { + BotInventoryOpenEvent event = new BotInventoryOpenEvent(this.getBukkitEntity(), player1.getBukkitEntity()); + this.server.server.getPluginManager().callEvent(event); + if (!event.isCancelled()) { -+ Component menuName = this.getDisplayName() != null ? this.getDisplayName() : Component.literal(this.createState.name()); -+ player.openMenu(new SimpleMenuProvider((i, inventory, p) -> ChestMenu.sixRows(i, inventory, this.container), menuName)); ++ player.openMenu(new SimpleMenuProvider((i, inventory, p) -> ChestMenu.sixRows(i, inventory, this.container), this.getDisplayName())); + return InteractionResult.SUCCESS; + } + } @@ -2501,7 +2471,7 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + this.addDeltaMovement(knockback); + this.knockback = Vec3.ZERO; + -+ this.server.tell(this.server.wrapRunnable(this::runAction)); ++ this.server.scheduleOnMain(this::runAction); + + this.livingEntityTick(); + @@ -2537,11 +2507,6 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + } + + @Override -+ public void setRot(float yaw, float pitch) { -+ this.getBukkitEntity().setRotation(yaw, pitch); -+ } -+ -+ @Override + public void attack(@NotNull Entity target) { + super.attack(target); + this.swing(InteractionHand.MAIN_HAND); @@ -2677,14 +2642,14 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 + } + + private void runAction() { -+ if (LeavesConfig.fakeplayerUseAction) { ++ if (LeavesConfig.modify.fakeplayer.canUseAction) { + this.actions.forEach(action -> action.tryTick(this)); + this.actions.removeIf(BotAction::isCancelled); + } + } + + public boolean addBotAction(BotAction action, CommandSender sender) { -+ if (!LeavesConfig.fakeplayerUseAction) { ++ if (!LeavesConfig.modify.fakeplayer.canUseAction) { + return false; + } + @@ -2723,10 +2688,10 @@ index 0000000000000000000000000000000000000000..1a50c4efbec7ff4000e23a477c2f60a7 +} diff --git a/src/main/java/org/leavesmc/leaves/bot/ServerBotGameMode.java b/src/main/java/org/leavesmc/leaves/bot/ServerBotGameMode.java new file mode 100644 -index 0000000000000000000000000000000000000000..bc1e29f6080c4783940848456620be8c06c32cce +index 0000000000000000000000000000000000000000..87ea98ab920a604bdd51281e0656c65160d30118 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/ServerBotGameMode.java -@@ -0,0 +1,138 @@ +@@ -0,0 +1,137 @@ +package org.leavesmc.leaves.bot; + +import net.kyori.adventure.text.Component; @@ -2736,7 +2701,6 @@ index 0000000000000000000000000000000000000000..bc1e29f6080c4783940848456620be8c +import net.minecraft.server.level.ServerPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; -+import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.GameType; @@ -2826,7 +2790,7 @@ index 0000000000000000000000000000000000000000..bc1e29f6080c4783940848456620be8c + return InteractionResult.FAIL; + } + -+ if (player.getCooldowns().isOnCooldown(stack.getItem())) { ++ if (player.getCooldowns().isOnCooldown(stack)) { + return InteractionResult.PASS; + } + @@ -2840,13 +2804,13 @@ index 0000000000000000000000000000000000000000..bc1e29f6080c4783940848456620be8c + boolean flag1 = player.isSecondaryUseActive() && flag; + + if (!flag1) { -+ ItemInteractionResult iteminteractionresult = iblockdata.useItemOn(player.getItemInHand(hand), world, player, hand, hitResult); ++ InteractionResult iteminteractionresult = iblockdata.useItemOn(player.getItemInHand(hand), world, player, hand, hitResult); + + if (iteminteractionresult.consumesAction()) { -+ return iteminteractionresult.result(); ++ return iteminteractionresult; + } + -+ if (iteminteractionresult == ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION && hand == InteractionHand.MAIN_HAND) { ++ if (iteminteractionresult == InteractionResult.PASS && hand == InteractionHand.MAIN_HAND) { + enuminteractionresult = iblockdata.useWithoutItem(world, player, hitResult); + if (enuminteractionresult.consumesAction()) { + return enuminteractionresult; @@ -3349,7 +3313,7 @@ index 0000000000000000000000000000000000000000..be55a3085a53542c08e7f0209883a4f3 +} diff --git a/src/main/java/org/leavesmc/leaves/bot/agent/actions/AttackAction.java b/src/main/java/org/leavesmc/leaves/bot/agent/actions/AttackAction.java new file mode 100644 -index 0000000000000000000000000000000000000000..03e9baf9b7c2da0fd1d7d9b0058b70daddedeeaa +index 0000000000000000000000000000000000000000..6c66ef29e702a49d1b8569aa0942e22e40843343 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/agent/actions/AttackAction.java @@ -0,0 +1,22 @@ @@ -3367,7 +3331,7 @@ index 0000000000000000000000000000000000000000..03e9baf9b7c2da0fd1d7d9b0058b70da + + @Override + public boolean doTick(@NotNull ServerBot bot) { -+ Entity entity = bot.getTargetEntity(3, Entity::isAttackable); ++ Entity entity = bot.getTargetEntity(3, target -> target.isAttackable() && !target.skipAttackInteraction(bot)); + if (entity != null) { + bot.attack(entity); + return true; @@ -4208,7 +4172,7 @@ index 0000000000000000000000000000000000000000..f8334858a7a0572d1c3dcf5f04696fbb +} diff --git a/src/main/java/org/leavesmc/leaves/bot/agent/configs/AlwaysSendDataConfig.java b/src/main/java/org/leavesmc/leaves/bot/agent/configs/AlwaysSendDataConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..9a584603edbbe4ccd8a88c90ef3e9125480635f1 +index 0000000000000000000000000000000000000000..31f68872652b3ac217d3b4f56e3bdd778314c27a --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/agent/configs/AlwaysSendDataConfig.java @@ -0,0 +1,45 @@ @@ -4231,7 +4195,7 @@ index 0000000000000000000000000000000000000000..9a584603edbbe4ccd8a88c90ef3e9125 + + public AlwaysSendDataConfig() { + super("always_send_data", CommandArgument.of(CommandArgumentType.BOOLEAN).setTabComplete(0, List.of("ture", "false")), AlwaysSendDataConfig::new); -+ this.value = LeavesConfig.alwaysSendFakeplayerData; ++ this.value = LeavesConfig.modify.fakeplayer.canSendDataAlways; + } + + @Override @@ -4360,7 +4324,7 @@ index 0000000000000000000000000000000000000000..0d934910cff745ea9a53d651e2007963 +} diff --git a/src/main/java/org/leavesmc/leaves/bot/agent/configs/SpawnPhantomConfig.java b/src/main/java/org/leavesmc/leaves/bot/agent/configs/SpawnPhantomConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..a3f978318a67c3c5e147a50eb2b6c01c3f549dc2 +index 0000000000000000000000000000000000000000..983b358a5cc03f07d36a3924d55275294b9a727e --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bot/agent/configs/SpawnPhantomConfig.java @@ -0,0 +1,51 @@ @@ -4382,7 +4346,7 @@ index 0000000000000000000000000000000000000000..a3f978318a67c3c5e147a50eb2b6c01c + + public SpawnPhantomConfig() { + super("spawn_phantom", CommandArgument.of(CommandArgumentType.BOOLEAN).setTabComplete(0, List.of("ture", "false")), SpawnPhantomConfig::new); -+ this.value = LeavesConfig.fakeplayerSpawnPhantom; ++ this.value = LeavesConfig.modify.fakeplayer.canSpawnPhantom; + } + + @Override @@ -4429,22 +4393,16 @@ index f50c3871e3ab435abc6de5bfb67b85b09d235733..d110bf39788503ec662d6f0c737ce9aa import org.checkerframework.checker.nullness.qual.NonNull; diff --git a/src/main/java/org/leavesmc/leaves/entity/CraftBot.java b/src/main/java/org/leavesmc/leaves/entity/CraftBot.java new file mode 100644 -index 0000000000000000000000000000000000000000..b33a3ca0e2b6a06668252048ce064dd294c28bee +index 0000000000000000000000000000000000000000..aaa5f8a3a70cac4483003c4a4a7ac2db72791ef9 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/entity/CraftBot.java -@@ -0,0 +1,102 @@ +@@ -0,0 +1,94 @@ +package org.leavesmc.leaves.entity; + +import com.google.common.base.Preconditions; -+import io.papermc.paper.entity.TeleportFlag; -+import net.minecraft.world.level.portal.DimensionTransition; -+import net.minecraft.world.phys.Vec3; -+import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.CraftServer; -+import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; -+import org.bukkit.craftbukkit.util.CraftLocation; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; @@ -4456,7 +4414,6 @@ index 0000000000000000000000000000000000000000..b33a3ca0e2b6a06668252048ce064dd2 +import org.leavesmc.leaves.event.bot.BotActionStopEvent; +import org.leavesmc.leaves.event.bot.BotRemoveEvent; + -+import java.util.Set; +import java.util.UUID; + +public class CraftBot extends CraftPlayer implements Bot { @@ -4515,7 +4472,6 @@ index 0000000000000000000000000000000000000000..b33a3ca0e2b6a06668252048ce064dd2 + + @Override + public boolean teleport(Location location, PlayerTeleportEvent.TeleportCause cause, io.papermc.paper.entity.TeleportFlag... flags) { -+ // Paper end + Preconditions.checkArgument(location != null, "location cannot be null"); + Preconditions.checkState(location.getWorld().equals(this.getWorld()), "[Leaves] Fakeplayers do not support changing world, Please use leaves fakeplayer-api instead!"); + return super.teleport(location, cause, flags); diff --git a/patches/server/0011-Make-shears-in-dispenser-can-unlimited-use.patch b/patches/server/0011-Make-shears-in-dispenser-can-unlimited-use.patch index 61b74433..e1ccecd8 100644 --- a/patches/server/0011-Make-shears-in-dispenser-can-unlimited-use.patch +++ b/patches/server/0011-Make-shears-in-dispenser-can-unlimited-use.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Make shears in dispenser can unlimited use diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java -index 44b79a7c2f8b95a484d1999fa2167ce588f7985b..67c1aaf2fce72da77e74748d3a8855f0e2b02efb 100644 +index 65ed3d77a51b8299517e0c165403b0c5ac413475..4708560d4c749f3c1039beaa2779c0036fb3d42e 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java @@ -64,7 +64,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING)); - this.setSuccess(ShearsDispenseItemBehavior.tryShearBeehive(worldserver, blockposition) || ShearsDispenseItemBehavior.tryShearLivingEntity(worldserver, blockposition, bukkitBlock, craftItem)); // CraftBukkit + this.setSuccess(ShearsDispenseItemBehavior.tryShearBeehive(worldserver, blockposition) || ShearsDispenseItemBehavior.tryShearLivingEntity(worldserver, blockposition, stack, bukkitBlock, craftItem)); // CraftBukkit - if (this.isSuccess()) { -+ if (this.isSuccess() && !org.leavesmc.leaves.LeavesConfig.shearsInDispenserCanZeroAmount) { // Leaves - Make shears in dispenser can unlimited use ++ if (this.isSuccess() && !org.leavesmc.leaves.LeavesConfig.modify.oldMC.shearsInDispenserCanZeroAmount) { // Leaves - Make shears in dispenser can unlimited use stack.hurtAndBreak(1, worldserver, (ServerPlayer) null, (item) -> { }); } diff --git a/patches/server/0012-Redstone-Shears-Wrench.patch b/patches/server/0012-Redstone-Shears-Wrench.patch index 4c13669e..12845b3b 100644 --- a/patches/server/0012-Redstone-Shears-Wrench.patch +++ b/patches/server/0012-Redstone-Shears-Wrench.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Redstone Shears Wrench diff --git a/src/main/java/net/minecraft/world/item/ShearsItem.java b/src/main/java/net/minecraft/world/item/ShearsItem.java -index cb809796372a4658aa617404f9fddffff9b45cb7..6ec6f786fda5a6d3f28e4e3d29a9754edb0356d0 100644 +index 374d51da03ce47ff744b64b8cfe98ad6d72ebdb4..5ae43ecff45239086ab8aad3b5c2e0774b999544 100644 --- a/src/main/java/net/minecraft/world/item/ShearsItem.java +++ b/src/main/java/net/minecraft/world/item/ShearsItem.java -@@ -19,6 +19,23 @@ import net.minecraft.world.level.block.GrowingPlantHeadBlock; +@@ -23,6 +23,23 @@ import net.minecraft.world.level.block.GrowingPlantHeadBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.gameevent.GameEvent; @@ -32,13 +32,13 @@ index cb809796372a4658aa617404f9fddffff9b45cb7..6ec6f786fda5a6d3f28e4e3d29a9754e public class ShearsItem extends Item { public ShearsItem(Item.Properties settings) { super(settings); -@@ -77,6 +94,67 @@ public class ShearsItem extends Item { - return InteractionResult.sidedSuccess(level.isClientSide); +@@ -82,6 +99,67 @@ public class ShearsItem extends Item { + return InteractionResult.SUCCESS; } + // Leaves start - shears wrench + Block block = blockState.getBlock(); -+ if (org.leavesmc.leaves.LeavesConfig.redstoneShearsWrench && block instanceof ObserverBlock || block instanceof DispenserBlock || ++ if (org.leavesmc.leaves.LeavesConfig.modify.redstoneShearsWrench && block instanceof ObserverBlock || block instanceof DispenserBlock || + block instanceof PistonBaseBlock || block instanceof HopperBlock || block instanceof RepeaterBlock || block instanceof ComparatorBlock || + block instanceof CrafterBlock || block instanceof LeverBlock || block instanceof CocoaBlock) { + StateDefinition blockstatelist = block.getStateDefinition(); diff --git a/patches/server/0013-Add-isShrink-to-EntityResurrectEvent.patch b/patches/server/0013-Add-isShrink-to-EntityResurrectEvent.patch index 70581d77..c563343f 100644 --- a/patches/server/0013-Add-isShrink-to-EntityResurrectEvent.patch +++ b/patches/server/0013-Add-isShrink-to-EntityResurrectEvent.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add isShrink to EntityResurrectEvent diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a0f6d383b430c8e320f041fe2221943830b021eb..98df8261434739e3648b4b1e473606921c9a27c6 100644 +index f36a075dbee2b96d01899e02460b1d8443e91749..d487bf7c9d425e5bc82c7efd7b901752ef915f16 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -1662,12 +1662,12 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -1703,12 +1703,12 @@ public abstract class LivingEntity extends Entity implements Attackable { } org.bukkit.inventory.EquipmentSlot handSlot = (hand != null) ? org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand) : null; @@ -22,8 +22,8 @@ index a0f6d383b430c8e320f041fe2221943830b021eb..98df8261434739e3648b4b1e47360692 + if (!itemstack1.isEmpty() && itemstack != null && event.isShrink()) { // Paper - only reduce item if actual totem was found // Leaves - can dont shrink itemstack1.shrink(1); } - if (itemstack != null && this instanceof ServerPlayer) { -@@ -4666,3 +4666,4 @@ public abstract class LivingEntity extends Entity implements Attackable { + // Paper start - fix NPE when pre-cancelled EntityResurrectEvent is uncancelled +@@ -4804,3 +4804,4 @@ public abstract class LivingEntity extends Entity implements Attackable { } } diff --git a/patches/server/0014-Budding-Amethyst-can-push-by-piston.patch b/patches/server/0014-Budding-Amethyst-can-push-by-piston.patch index fae4770d..9d368d03 100644 --- a/patches/server/0014-Budding-Amethyst-can-push-by-piston.patch +++ b/patches/server/0014-Budding-Amethyst-can-push-by-piston.patch @@ -5,43 +5,45 @@ Subject: [PATCH] Budding Amethyst can push by piston 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 ae86e1edde015e2ff6cd10c31e0a6065708241af..7130209f48c488e2d184f31335f0511735963c55 100644 +index b6d6c2cb9b227a17fb4ce42bc75f92206fbea043..b3a3388ef62b0622906b2470056cb41f0deb0391 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -588,6 +588,12 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -583,6 +583,13 @@ public class Block extends BlockBehaviour implements ItemLike { } // Spigot end + // Leaves start - reset push reaction ++ @org.jetbrains.annotations.Nullable + public net.minecraft.world.level.material.PushReaction getResetPushReaction() { + return null; + } + // Leaves end - reset push reaction + - public static final class BlockStatePairKey { + private static record ShapePairKey(VoxelShape first, VoxelShape second) { - private final BlockState first; + public boolean equals(Object object) { diff --git a/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java b/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java -index 8920855b07a31715327b8102c7faafc9f916825d..32d926a1b952b8069c5bf48c88e3c108b08b4ab1 100644 +index 8920855b07a31715327b8102c7faafc9f916825d..e6cc94e9c1b2388b8e42821e6bfaa2e22d44f9d3 100644 --- a/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BuddingAmethystBlock.java -@@ -60,4 +60,11 @@ public class BuddingAmethystBlock extends AmethystBlock { +@@ -60,4 +60,12 @@ public class BuddingAmethystBlock extends AmethystBlock { public static boolean canClusterGrowAtState(BlockState state) { return state.isAir() || state.is(Blocks.WATER) && state.getFluidState().getAmount() == 8; } + + // Leaves start - budding amethyst can push by piston ++ @org.jetbrains.annotations.Nullable + @Override + public net.minecraft.world.level.material.PushReaction getResetPushReaction() { -+ return org.leavesmc.leaves.LeavesConfig.buddingAmethystCanPushByPiston ? net.minecraft.world.level.material.PushReaction.PUSH_ONLY : null; ++ return org.leavesmc.leaves.LeavesConfig.modify.buddingAmethystCanPushByPiston ? net.minecraft.world.level.material.PushReaction.PUSH_ONLY : null; + } + // Leaves end - budding amethyst can push by piston } 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..e9b4e88caeb57cc67bfd027bb15585eff9a13e04 100644 +index 99fd67a78539133adf78d65e2c520ff3dd260301..4c1ec8de5aa2edde1dbcff350a65b7fc4a4b5e74 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 -@@ -1099,7 +1099,7 @@ public abstract class BlockBehaviour implements FeatureElement { +@@ -1159,7 +1159,7 @@ public abstract class BlockBehaviour implements FeatureElement { } public PushReaction getPistonPushReaction() { @@ -49,4 +51,4 @@ index d0109633e8bdf109cfc9178963d7b6cf92f8b189..e9b4e88caeb57cc67bfd027bb15585ef + return !this.isDestroyable() ? PushReaction.BLOCK : this.getBlock().getResetPushReaction() == null ? this.pushReaction : this.getBlock().getResetPushReaction(); // Paper - Protect Bedrock and End Portal/Frames from being destroyed // Leaves - can reset } - public boolean isSolidRender(BlockGetter world, BlockPos pos) { + public boolean isSolidRender() { diff --git a/patches/server/0015-Spectator-dont-get-Advancement.patch b/patches/server/0015-Spectator-dont-get-Advancement.patch index 9386bd77..59b916e7 100644 --- a/patches/server/0015-Spectator-dont-get-Advancement.patch +++ b/patches/server/0015-Spectator-dont-get-Advancement.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Spectator dont get Advancement diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java -index b5f18a0115b629930de84a9d086505adaa6087dd..ece0aa3bf18e864a261d4d4edf0a98a40e7f6bb3 100644 +index b9ed92cd8a12f648eeaa02427d95d75468534420..7f8eaf4590a29b147aa8c05cec919fd7744e74ba 100644 --- a/src/main/java/net/minecraft/server/PlayerAdvancements.java +++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java @@ -221,6 +221,11 @@ public class PlayerAdvancements { @@ -13,7 +13,7 @@ index b5f18a0115b629930de84a9d086505adaa6087dd..ece0aa3bf18e864a261d4d4edf0a98a4 public boolean award(AdvancementHolder advancement, String criterionName) { + // Leaves start - spectator don't get advancement -+ if (org.leavesmc.leaves.LeavesConfig.spectatorDontGetAdvancement && player.gameMode.getGameModeForPlayer() == net.minecraft.world.level.GameType.SPECTATOR) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.spectatorDontGetAdvancement && player.gameMode.getGameModeForPlayer() == net.minecraft.world.level.GameType.SPECTATOR) { + return false; + } + // Leaves end - spectator don't get advancement diff --git a/patches/server/0016-Stick-can-change-ArmorStand-arm-status.patch b/patches/server/0016-Stick-can-change-ArmorStand-arm-status.patch index cc65c63d..817ed945 100644 --- a/patches/server/0016-Stick-can-change-ArmorStand-arm-status.patch +++ b/patches/server/0016-Stick-can-change-ArmorStand-arm-status.patch @@ -5,16 +5,16 @@ Subject: [PATCH] Stick can change ArmorStand arm status 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..df29a54063ee957c2b88a12ef228c7d8541a2f2c 100644 +index 70b8023c3badc745f342d5b0ab54699e3923826a..49e8a9d5df9b20bced385019f5e7fb622536213a 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -392,6 +392,12 @@ public class ArmorStand extends LivingEntity { - return InteractionResult.SUCCESS; +@@ -397,6 +397,12 @@ public class ArmorStand extends LivingEntity { + return InteractionResult.SUCCESS_SERVER; } } else { + // Leaves start - stick can change ArmorStand arm status -+ if (org.leavesmc.leaves.LeavesConfig.stickChangeArmorStandArmStatus && itemstack.is(Items.STICK) && player.isShiftKeyDown()) { -+ setShowArms(!isShowArms()); ++ if (org.leavesmc.leaves.LeavesConfig.modify.stickChangeArmorStandArmStatus && itemstack.is(Items.STICK) && player.isShiftKeyDown()) { ++ setShowArms(!showArms()); + } + // Leaves end - stick can change ArmorStand arm status + diff --git a/patches/server/0017-Configurable-MC-59471.patch b/patches/server/0017-Configurable-MC-59471.patch new file mode 100644 index 00000000..2841fe07 --- /dev/null +++ b/patches/server/0017-Configurable-MC-59471.patch @@ -0,0 +1,42 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Sat, 30 Jul 2022 01:11:30 +0800 +Subject: [PATCH] Configurable MC-59471 + + +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 c2589f42c467ca672417c24076313da51bb2dcbb..99caf34456385565d8a985409690c656ab3d3c3d 100644 +--- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java +@@ -191,7 +191,7 @@ public class TripWireHookBlock extends Block { + + TripWireHookBlock.emitState(world, pos, flag4, flag5, flag2, flag3); + if (!flag) { +- if (world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update ++ // if (world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update // Leaves - vanilla lol + world.setBlock(pos, (BlockState) iblockdata3.setValue(TripWireHookBlock.FACING, enumdirection), 3); + if (flag1) { + TripWireHookBlock.notifyNeighbors(block, world, pos, enumdirection); +@@ -204,11 +204,18 @@ public class TripWireHookBlock extends Block { + BlockState iblockdata4 = aiblockdata[l]; + + if (iblockdata4 != null) { +- BlockState iblockdata5 = world.getBlockState(blockposition2); +- +- if (iblockdata5.is(Blocks.TRIPWIRE) || iblockdata5.is(Blocks.TRIPWIRE_HOOK)) { +- world.setBlock(blockposition2, (BlockState) iblockdata4.trySetValue(TripWireHookBlock.ATTACHED, flag4), 3); ++ // Leaves start - MC-59471 ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.stringTripwireHookDuplicate) { ++ world.setBlock(blockposition2, iblockdata4.trySetValue(TripWireHookBlock.ATTACHED, flag4), 3); ++ world.getBlockState(blockposition2); ++ } else { ++ BlockState iblockdata5 = world.getBlockState(blockposition2); ++ ++ if (iblockdata5.is(Blocks.TRIPWIRE) || iblockdata5.is(Blocks.TRIPWIRE_HOOK)) { ++ world.setBlock(blockposition2, (BlockState) iblockdata4.trySetValue(TripWireHookBlock.ATTACHED, flag4), 3); ++ } + } ++ // Leaves end - MC-59471 + } + } + } diff --git a/patches/server/0017-Fix-tripwire-update.patch b/patches/server/0017-Fix-tripwire-update.patch deleted file mode 100644 index 7e6fac4d..00000000 --- a/patches/server/0017-Fix-tripwire-update.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Sat, 30 Jul 2022 01:11:30 +0800 -Subject: [PATCH] Fix tripwire 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 76aca266d3f3222502ff4c196228f08fcd88c5f8..6b921c459e24c509b3962837b4c966d012940c08 100644 ---- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java -@@ -189,7 +189,7 @@ public class TripWireHookBlock extends Block { - - TripWireHookBlock.emitState(world, pos, flag4, flag5, flag2, flag3); - if (!flag) { -- if (world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update -+ // if (world.getBlockState(pos).getBlock() == Blocks.TRIPWIRE_HOOK) // Paper - Validate tripwire hook placement before update // Leaves - vanilla lol - world.setBlock(pos, (BlockState) iblockdata3.setValue(TripWireHookBlock.FACING, enumdirection), 3); - if (flag1) { - TripWireHookBlock.notifyNeighbors(block, world, pos, enumdirection); -@@ -202,8 +202,9 @@ 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()) { -+ ; - } - } - } diff --git a/patches/server/0018-No-chat-sign.patch b/patches/server/0018-No-chat-sign.patch index 495b4460..d4c9ffa0 100644 --- a/patches/server/0018-No-chat-sign.patch +++ b/patches/server/0018-No-chat-sign.patch @@ -5,7 +5,7 @@ Subject: [PATCH] No chat sign diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java -index 14e412ebf75b0e06ab53a1c8f9dd1be6ad1e2680..8fe9a0bf5a6c27d8a505afc2f51b3dccc905423b 100644 +index 14e412ebf75b0e06ab53a1c8f9dd1be6ad1e2680..73d239536b373e292ee2883edac0049541b59ba0 100644 --- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java +++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java @@ -317,7 +317,7 @@ public final class ChatProcessor { @@ -13,12 +13,12 @@ index 14e412ebf75b0e06ab53a1c8f9dd1be6ad1e2680..8fe9a0bf5a6c27d8a505afc2f51b3dcc private void sendToServer(final ChatType.Bound chatType, final @Nullable Function msgFunction) { final PlayerChatMessage toConsoleMessage = msgFunction == null ? ChatProcessor.this.message : ChatProcessor.this.message.withUnsignedContent(msgFunction.apply(ChatProcessor.this.server.console)); - ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) ? null : "Not Secure"); -+ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) || org.leavesmc.leaves.LeavesConfig.noChatSign ? null : "Not Secure"); // Leaves - No Not Secure ++ ChatProcessor.this.server.logChatMessage(toConsoleMessage.decoratedContent(), chatType, ChatProcessor.this.server.getPlayerList().verifyChatTrusted(toConsoleMessage) || org.leavesmc.leaves.LeavesConfig.mics.noChatSign ? null : "Not Secure"); // Leaves - No Not Secure } } diff --git a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java -index 479e6e2aa88a22ef7f8fccb06add6806f5b71d9d..e6a6d09a64414ae6932e9bac338ce36043bd4b26 100644 +index 479e6e2aa88a22ef7f8fccb06add6806f5b71d9d..5a103b7c4d2566d93b18a2e8db32a3444ba44e36 100644 --- a/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java +++ b/src/main/java/net/minecraft/commands/arguments/ArgumentSignatures.java @@ -13,10 +13,17 @@ public record ArgumentSignatures(List entries) { @@ -33,7 +33,7 @@ index 479e6e2aa88a22ef7f8fccb06add6806f5b71d9d..e6a6d09a64414ae6932e9bac338ce360 + private static List readSign(FriendlyByteBuf buf) { + var entries = buf.readCollection(FriendlyByteBuf.limitValue(ArrayList::new, 8), Entry::new); -+ return org.leavesmc.leaves.LeavesConfig.noChatSign ? List.of() : entries; ++ return org.leavesmc.leaves.LeavesConfig.mics.noChatSign ? List.of() : entries; + } + // Leaves end - no chat sign + @@ -41,7 +41,7 @@ index 479e6e2aa88a22ef7f8fccb06add6806f5b71d9d..e6a6d09a64414ae6932e9bac338ce360 buf.writeCollection(this.entries, (buf2, entry) -> entry.write(buf2)); } diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java -index 0cd6a50837efce87ca052a0e1e24db2b75761196..8212aaf92f028ea560b357771cdf5810d84aed43 100644 +index a523a83aec3a6ecbec4d60a187edc0c0167d15b4..e4ac9fac52cec522d679a1ffe8b3263a204f5d7f 100644 --- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java +++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java @@ -129,6 +129,16 @@ public class FriendlyByteBuf extends ByteBuf { @@ -51,7 +51,7 @@ index 0cd6a50837efce87ca052a0e1e24db2b75761196..8212aaf92f028ea560b357771cdf5810 + // Leaves start - no chat sign + if (codec == net.minecraft.network.protocol.status.ServerStatus.CODEC) { + JsonElement element = dataresult.getOrThrow(string -> new EncoderException("Failed to encode: " + string + " " + value)); -+ element.getAsJsonObject().addProperty("preventsChatReports", org.leavesmc.leaves.LeavesConfig.noChatSign); ++ element.getAsJsonObject().addProperty("preventsChatReports", org.leavesmc.leaves.LeavesConfig.mics.noChatSign); + + this.writeUtf(GSON.toJson(element)); + return; @@ -62,7 +62,7 @@ index 0cd6a50837efce87ca052a0e1e24db2b75761196..8212aaf92f028ea560b357771cdf5810 return new EncoderException("Failed to encode: " + s + " " + String.valueOf(value)); })), maxLength); // Paper - Adventure; add max length parameter diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java -index 07df3299f1d1aa5506e1f6f146347d53e0278d9c..fb441424c03d547cdf4dcfcde5e60d8e4d6a4f59 100644 +index 07df3299f1d1aa5506e1f6f146347d53e0278d9c..342f23250f22771d8b395cece087d277fd99eaae 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java @@ -15,8 +15,9 @@ public record ServerboundChatPacket(String message, Instant timeStamp, long salt @@ -83,7 +83,7 @@ index 07df3299f1d1aa5506e1f6f146347d53e0278d9c..fb441424c03d547cdf4dcfcde5e60d8e + private static MessageSignature readSign(FriendlyByteBuf buf) { + byte[] bs = new byte[256]; + buf.readBytes(bs); -+ return org.leavesmc.leaves.LeavesConfig.noChatSign ? null : new MessageSignature(bs); ++ return org.leavesmc.leaves.LeavesConfig.mics.noChatSign ? null : new MessageSignature(bs); + } + // Leaves end - no chat sign + @@ -91,7 +91,7 @@ index 07df3299f1d1aa5506e1f6f146347d53e0278d9c..fb441424c03d547cdf4dcfcde5e60d8e public PacketType type() { return GamePacketTypes.SERVERBOUND_CHAT; diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java -index 5705cb920084b775cce4b361683b32c6b6e003ed..cbff868303d751d09b68f431c78bb13b4734f48f 100644 +index 5705cb920084b775cce4b361683b32c6b6e003ed..eb0caad2613e8fdd7dbcc2a295cc9201a225f3f2 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatSessionUpdatePacket.java @@ -26,6 +26,11 @@ public record ServerboundChatSessionUpdatePacket(RemoteChatSession.Data chatSess @@ -99,7 +99,7 @@ index 5705cb920084b775cce4b361683b32c6b6e003ed..cbff868303d751d09b68f431c78bb13b @Override public void handle(ServerGamePacketListener listener) { + // Leaves start - no chat report -+ if (org.leavesmc.leaves.LeavesConfig.noChatSign) { ++ if (org.leavesmc.leaves.LeavesConfig.mics.noChatSign) { + return; + } + // Leaves end - no chat report @@ -107,28 +107,28 @@ index 5705cb920084b775cce4b361683b32c6b6e003ed..cbff868303d751d09b68f431c78bb13b } } diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 4ac40259f31f3deef6b5fe4456576bbd44cc2569..e45acea31d61462c877c902b238209f14f2c8ad1 100644 +index 9b1e6effb8bf852957dba92a54688932ddb0d565..679a40aeedc7e259401a6c244ed54136d6c75a40 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -669,7 +669,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -650,7 +650,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface // Paper start - Add setting for proxy online mode status return dedicatedserverproperties.enforceSecureProfile && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() - && this.services.canValidateProfileKeys(); -+ && this.services.canValidateProfileKeys() && !org.leavesmc.leaves.LeavesConfig.noChatSign; // Leaves - no chat sign ++ && this.services.canValidateProfileKeys() && !org.leavesmc.leaves.LeavesConfig.mics.noChatSign; // Leaves - no chat sign // Paper end - Add setting for proxy online mode status } diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 7adef76ecc246b131cee35cf00c3c05bd75d5504..7bc847d7475de6cca22e587fdb9999563bbce14d 100644 +index 8344c7f953fc465ee9f43e1f81e2eb062fd3c432..93404b7e1aaf74d6acc7031116dc8f63fc70f964 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -297,10 +297,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -304,10 +304,24 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack } public void send(Packet packet) { + // Leaves start - rebuild ClientboundPlayerChatPacket -+ if (org.leavesmc.leaves.LeavesConfig.noChatSign) { ++ if (org.leavesmc.leaves.LeavesConfig.mics.noChatSign) { + if (this instanceof ServerGamePacketListenerImpl && packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat) { + packet = new net.minecraft.network.protocol.game.ClientboundSystemChatPacket(chat.chatType().decorate(chat.unsignedContent() != null ? chat.unsignedContent() : Component.literal(chat.body().content())), false); + } @@ -139,7 +139,7 @@ index 7adef76ecc246b131cee35cf00c3c05bd75d5504..7bc847d7475de6cca22e587fdb999956 public void send(Packet packet, @Nullable PacketSendListener callbacks) { + // Leaves start - no ClientboundPlayerChatHeaderPacket and rebuild ClientboundPlayerChatPacket -+ if (org.leavesmc.leaves.LeavesConfig.noChatSign) { ++ if (org.leavesmc.leaves.LeavesConfig.mics.noChatSign) { + if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerChatPacket chat && callbacks != null) { + callbacks = null; + } @@ -149,15 +149,15 @@ index 7adef76ecc246b131cee35cf00c3c05bd75d5504..7bc847d7475de6cca22e587fdb999956 if (packet == null || this.processedDisconnect) { // Spigot return; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 31a55145bf2ed0e5a23fd07d1c14e93572d5ef5a..5221ab490fcbc11434c1209f654e5731fa15487e 100644 +index 9b3fbc13779ded07c696e151772d834ff8d61a7d..b83b903381ca6c426d2f26f9459e769083eb5876 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1456,7 +1456,7 @@ public abstract class PlayerList { +@@ -1423,7 +1423,7 @@ public abstract class PlayerList { } public boolean verifyChatTrusted(PlayerChatMessage message) { // Paper - private -> public - return message.hasSignature() && !message.hasExpiredServer(Instant.now()); -+ return org.leavesmc.leaves.LeavesConfig.noChatSign || (message.hasSignature() && !message.hasExpiredServer(Instant.now())); // Leaves - No Not Secure ++ return org.leavesmc.leaves.LeavesConfig.mics.noChatSign || (message.hasSignature() && !message.hasExpiredServer(Instant.now())); // Leaves - No Not Secure } // CraftBukkit start diff --git a/patches/server/0019-Dont-send-useless-entity-packets.patch b/patches/server/0019-Dont-send-useless-entity-packets.patch index 6aae31a3..20873c6b 100644 --- a/patches/server/0019-Dont-send-useless-entity-packets.patch +++ b/patches/server/0019-Dont-send-useless-entity-packets.patch @@ -6,22 +6,22 @@ Subject: [PATCH] Dont send useless entity packets This patch is Powered by Purpur(https://github.com/PurpurMC/Purpur) diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 8ea2f24695f5dad55e21f238b69442513e7a90c6..0846e11c82295ccf93683f877962ec7804dad677 100644 +index 90eb4927fa51ce3df86aa7b6c71f49150a03e337..1e1e5ade09d368f0fdc6533f26281bd7d6d31751 100644 --- a/src/main/java/net/minecraft/server/level/ServerEntity.java +++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -212,6 +212,11 @@ public class ServerEntity { - packet1 = new ClientboundTeleportEntityPacket(this.entity); - flag4 = true; - flag5 = true; -+ // Leaves start - dont send useless entity packets -+ if (org.leavesmc.leaves.LeavesConfig.dontSendUselessEntityPackets && isUselessPacket(packet1)) { -+ packet1 = null; -+ } -+ // Leaves end - dont send useless entity packets - } +@@ -226,6 +226,11 @@ public class ServerEntity { + packet1 = ClientboundEntityPositionSyncPacket.of(this.entity); + flag3 = true; + flag4 = true; ++ // Leaves start - dont send useless entity packets ++ if (org.leavesmc.leaves.LeavesConfig.performance.dontSendUselessEntityPackets && isUselessPacket(packet1)) { ++ packet1 = null; ++ } ++ // Leaves end - dont send useless entity packets + } - if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) { -@@ -294,6 +299,21 @@ public class ServerEntity { + if ((this.trackDelta || this.entity.hasImpulse || this.entity instanceof LivingEntity && ((LivingEntity) this.entity).isFallFlying()) && this.tickCount > 0) { +@@ -332,6 +337,21 @@ public class ServerEntity { }); } diff --git a/patches/server/0020-Optimize-suffocation.patch b/patches/server/0020-Optimize-suffocation.patch index 2f3fec80..afe1f83d 100644 --- a/patches/server/0020-Optimize-suffocation.patch +++ b/patches/server/0020-Optimize-suffocation.patch @@ -6,19 +6,19 @@ Subject: [PATCH] Optimize suffocation This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 15386ed5c4304f85ff3edd9bbf95db9144c28523..0556500fde799583a65a82d00a6b2c65a1757d5e 100644 +index 7610b2961d59af006440476f7c91038b9b1c5432..8c34c7f74779774e8627c2eb9d5230ed1980df36 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -448,7 +448,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - boolean flag = this instanceof net.minecraft.world.entity.player.Player; +@@ -467,7 +467,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - if (!this.level().isClientSide) { + if (world1 instanceof ServerLevel) { + worldserver1 = (ServerLevel) world1; - if (this.isInWall()) { -+ if ((!org.leavesmc.leaves.LeavesConfig.enableSuffocationOptimization || this instanceof WitherBoss || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F))) && this.isInWall()) { // Leaves - optimize suffocation - this.hurt(this.damageSources().inWall(), 1.0F); ++ if ((!org.leavesmc.leaves.LeavesConfig.performance.enableSuffocationOptimization || this instanceof WitherBoss || (tickCount % 10 == 0 && couldPossiblyBeHurt(1.0F))) && this.isInWall()) { // Leaves - optimize suffocation + this.hurtServer(worldserver1, this.damageSources().inWall(), 1.0F); } else if (flag && !this.level().getWorldBorder().isWithinBounds(this.getBoundingBox())) { - double d0 = this.level().getWorldBorder().getDistanceToBorder(this) + this.level().getWorldBorder().getDamageSafeZone(); -@@ -1408,6 +1408,15 @@ public abstract class LivingEntity extends Entity implements Attackable { + double d1 = this.level().getWorldBorder().getDistanceToBorder(this) + this.level().getWorldBorder().getDamageSafeZone(); +@@ -1437,6 +1437,15 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.getHealth() <= 0.0F; } @@ -32,5 +32,5 @@ index 15386ed5c4304f85ff3edd9bbf95db9144c28523..0556500fde799583a65a82d00a6b2c65 + // Leaves end - optimize suffocation + @Override - public boolean hurt(DamageSource source, float amount) { - if (this.isInvulnerableTo(source)) { + public boolean hurtServer(ServerLevel world, DamageSource source, float amount) { + if (this.isInvulnerableTo(world, source)) { diff --git a/patches/server/0021-Only-check-for-spooky-season-once-an-hour.patch b/patches/server/0021-Only-check-for-spooky-season-once-an-hour.patch index d52e630c..6cd6a8eb 100644 --- a/patches/server/0021-Only-check-for-spooky-season-once-an-hour.patch +++ b/patches/server/0021-Only-check-for-spooky-season-once-an-hour.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Only check for spooky season once an hour This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) 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 dc27ddf5131e7398a5390a5187261d4c7fb6ccaa..601072324b54d062bd4cceb821ae187d904ad49b 100644 +index 60c2868f255d372226e0c1389caaa5477bbef41e..d432e00ec084d1c7a23f10be6c457681ae66db37 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/Bat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/Bat.java -@@ -239,13 +239,30 @@ public class Bat extends AmbientCreature { +@@ -242,13 +242,30 @@ public class Bat extends AmbientCreature { } } @@ -21,7 +21,7 @@ index dc27ddf5131e7398a5390a5187261d4c7fb6ccaa..601072324b54d062bd4cceb821ae187d - LocalDate localdate = LocalDate.now(); - int i = localdate.get(ChronoField.DAY_OF_MONTH); - int j = localdate.get(ChronoField.MONTH_OF_YEAR); -+ if (org.leavesmc.leaves.LeavesConfig.checkSpookySeasonOnceAnHour) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.checkSpookySeasonOnceAnHour) { + if (net.minecraft.server.MinecraftServer.currentTick - lastSpookyCheck > ONE_HOUR) { + LocalDate localdate = LocalDate.now(); + int i = localdate.get(ChronoField.DAY_OF_MONTH); diff --git a/patches/server/0022-Config-to-disable-method-profiler.patch b/patches/server/0022-Config-to-disable-method-profiler.patch new file mode 100644 index 00000000..9700fefd --- /dev/null +++ b/patches/server/0022-Config-to-disable-method-profiler.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Mon, 15 Aug 2022 10:18:36 +0800 +Subject: [PATCH] Config to disable method profiler + +This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) + +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index f0d2c8bc40b36e6d638ad418963289ac2737f5a0..feaf9b26c12f4da94aedfdab7362c8d94c7a72eb 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1321,7 +1321,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop -Date: Mon, 15 Aug 2022 10:18:36 +0800 -Subject: [PATCH] Config to disable method profiler - -This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) - -diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index cb863f07d00e96b92e73dc312606110c259b4d5c..4c8cf72e44e991920ed6a6110d811530c77adbbe 100644 ---- a/src/main/java/net/minecraft/server/MinecraftServer.java -+++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -2557,6 +2557,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop attribute) { - return this.attributes.computeIfAbsent(attribute, attributex -> this.supplier.createInstance(this::onAttributeModified, attributex)); + // Leaves start - cache lambda, as for some reason java allocates it anyways -+ if (org.leavesmc.leaves.LeavesConfig.reduceEntityAllocations) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.reduceEntityAllocations) { + return this.attributes.computeIfAbsent(attribute, this.createInstance); + } else { + return this.attributes.computeIfAbsent(attribute, attributex -> this.supplier.createInstance(this::onAttributeModified, attributex)); diff --git a/patches/server/0026-Remove-lambda-from-ticking-guard.patch b/patches/server/0025-Remove-lambda-from-ticking-guard.patch similarity index 90% rename from patches/server/0026-Remove-lambda-from-ticking-guard.patch rename to patches/server/0025-Remove-lambda-from-ticking-guard.patch index 726abe73..0d04eecc 100644 --- a/patches/server/0026-Remove-lambda-from-ticking-guard.patch +++ b/patches/server/0025-Remove-lambda-from-ticking-guard.patch @@ -6,16 +6,16 @@ Subject: [PATCH] Remove lambda from ticking guard This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 49e7d9bc75e029a8800f7369681e43efd14cd322..5a97f8a853664a3ced63215a386286873a6c7a95 100644 +index 1b1350485ba333e9bda048b01273de9744ce16a9..1b2ba3ff09b27ea74afc96735e48a474cf6ebddd 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -725,7 +725,23 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -811,7 +811,23 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } gameprofilerfiller.push("tick"); - this.guardEntityTick(this::tickNonPassenger, entity); + // Leaves start - copied from this.guardEntityTick -+ if (org.leavesmc.leaves.LeavesConfig.removeTickGuardLambda) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.remove.tickGuardLambda) { + try { + this.tickNonPassenger(entity); // Leaves - changed + } catch (Throwable throwable) { diff --git a/patches/server/0027-Remove-iterators-from-inventory-contains.patch b/patches/server/0026-Remove-iterators-from-inventory-contains.patch similarity index 89% rename from patches/server/0027-Remove-iterators-from-inventory-contains.patch rename to patches/server/0026-Remove-iterators-from-inventory-contains.patch index 960d5fbf..002b1f2a 100644 --- a/patches/server/0027-Remove-iterators-from-inventory-contains.patch +++ b/patches/server/0026-Remove-iterators-from-inventory-contains.patch @@ -6,16 +6,16 @@ Subject: [PATCH] Remove iterators from inventory contains This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) 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 6e66141dca61f777b354854b5d0bac2570b8bf3b..eb11482f48c9f330b7fa62a278fd6f07d3a642e1 100644 +index 0e214d502998e9eb959952b257844529992df0df..9506c4cf1c757219f9f01c06cf61ad3e40ee0979 100644 --- a/src/main/java/net/minecraft/world/entity/player/Inventory.java +++ b/src/main/java/net/minecraft/world/entity/player/Inventory.java -@@ -643,17 +643,31 @@ public class Inventory implements Container, Nameable { +@@ -649,17 +649,31 @@ public class Inventory implements Container, Nameable { } public boolean contains(ItemStack stack) { - Iterator iterator = this.compartments.iterator(); + // Leaves start - don't allocate iterators -+ if (org.leavesmc.leaves.LeavesConfig.removeInventoryContainsIterators) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.remove.inventoryContainsIterators) { + for (int i = 0; i < this.compartments.size(); i++) { + List list = this.compartments.get(i); + for (int j = 0; j < list.size(); j++) { @@ -49,12 +49,12 @@ index 6e66141dca61f777b354854b5d0bac2570b8bf3b..eb11482f48c9f330b7fa62a278fd6f07 } } } -@@ -662,17 +676,30 @@ public class Inventory implements Container, Nameable { +@@ -668,17 +682,30 @@ public class Inventory implements Container, Nameable { } public boolean contains(TagKey tag) { - Iterator iterator = this.compartments.iterator(); -+ if (org.leavesmc.leaves.LeavesConfig.removeInventoryContainsIterators) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.remove.inventoryContainsIterators) { + for (int i = 0; i < this.compartments.size(); i++) { + List list = this.compartments.get(i); + for (int j = 0; j < list.size(); j++) { @@ -88,12 +88,12 @@ index 6e66141dca61f777b354854b5d0bac2570b8bf3b..eb11482f48c9f330b7fa62a278fd6f07 } } } -@@ -681,21 +708,34 @@ public class Inventory implements Container, Nameable { +@@ -687,21 +714,34 @@ public class Inventory implements Container, Nameable { } public boolean contains(Predicate predicate) { - Iterator iterator = this.compartments.iterator(); -+ if (org.leavesmc.leaves.LeavesConfig.removeInventoryContainsIterators) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.remove.inventoryContainsIterators) { + for (int i = 0; i < this.compartments.size(); i++) { + List list = this.compartments.get(i); + for (int j = 0; j < list.size(); j++) { diff --git a/patches/server/0029-Cache-climbing-check-for-activation.patch b/patches/server/0027-Cache-climbing-check-for-activation.patch similarity index 85% rename from patches/server/0029-Cache-climbing-check-for-activation.patch rename to patches/server/0027-Cache-climbing-check-for-activation.patch index 5bcfed4b..35614163 100644 --- a/patches/server/0029-Cache-climbing-check-for-activation.patch +++ b/patches/server/0027-Cache-climbing-check-for-activation.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Cache climbing check for activation This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 0556500fde799583a65a82d00a6b2c65a1757d5e..408700b2236b4e04baebe23b47e72722006e3e23 100644 +index d5614e702137b52700873a8301d9ec3c87f47040..44180a5fddaafec623875676ab54cbd62b1268a8 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -2073,6 +2073,22 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -2129,6 +2129,22 @@ public abstract class LivingEntity extends Entity implements Attackable { return this.lastClimbablePos; } @@ -18,7 +18,7 @@ index 0556500fde799583a65a82d00a6b2c65a1757d5e..408700b2236b4e04baebe23b47e72722 + private BlockPos lastClimbingPosition = null; + + public boolean onClimableCached() { -+ if (!org.leavesmc.leaves.LeavesConfig.cacheClimbCheck) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.cacheClimbCheck) { + return this.onClimbable(); + } + if (!this.blockPosition().equals(this.lastClimbingPosition)) { @@ -33,7 +33,7 @@ index 0556500fde799583a65a82d00a6b2c65a1757d5e..408700b2236b4e04baebe23b47e72722 if (this.isSpectator()) { return false; diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java -index 621bda8248e35f5a5730f89a4bcfbe6615ed969c..47c30ebb3ea6fab0a0d51211905217a1d2a0c770 100644 +index 1d438ef44cbe4d1eedfba36d8fe5d2ad53464921..4f6f42fb965d76c8360eb7c67936d2c3d104a700 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -295,7 +295,7 @@ public class ActivationRange diff --git a/patches/server/0031-Reduce-chunk-loading-lookups.patch b/patches/server/0028-Reduce-chunk-loading-lookups.patch similarity index 77% rename from patches/server/0031-Reduce-chunk-loading-lookups.patch rename to patches/server/0028-Reduce-chunk-loading-lookups.patch index 81d2d1e0..b2bb3b40 100644 --- a/patches/server/0031-Reduce-chunk-loading-lookups.patch +++ b/patches/server/0028-Reduce-chunk-loading-lookups.patch @@ -6,30 +6,30 @@ Subject: [PATCH] Reduce chunk loading & lookups This patch is Powered by Pufferfish(https://github.com/pufferfish-gg/Pufferfish) 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 828c51477cd8f35d591367b30bf4feef6a250292..17a71bb3b65cc1030b70c931b1dc998d06713231 100644 +index 48dcd2bc12ce1d08cc5195bff5460dc0dd9902d3..2b8e1a8e233071821411eb1f95c705efb4a6e816 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -320,11 +320,28 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -307,11 +307,28 @@ public class EnderMan extends Monster implements NeutralMob { private boolean teleport(double x, double y, double z) { BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(x, y, z); -- while (blockposition_mutableblockposition.getY() > this.level().getMinBuildHeight() && !this.level().getBlockState(blockposition_mutableblockposition).blocksMotion()) { +- while (blockposition_mutableblockposition.getY() > this.level().getMinY() && !this.level().getBlockState(blockposition_mutableblockposition).blocksMotion()) { - blockposition_mutableblockposition.move(Direction.DOWN); + // Leaves start - single chunk lookup + BlockState iblockdata; -+ if (org.leavesmc.leaves.LeavesConfig.reduceChuckLoadAndLookup) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.reduceChuckLoadAndLookup) { + net.minecraft.world.level.chunk.LevelChunk chunk = this.level().getChunkIfLoaded(blockposition_mutableblockposition); + if (chunk == null) { + return false; + } + -+ while (blockposition_mutableblockposition.getY() > this.level().getMinBuildHeight() && !chunk.getBlockState(blockposition_mutableblockposition).blocksMotion()) { ++ while (blockposition_mutableblockposition.getY() > this.level().getMinY() && !chunk.getBlockState(blockposition_mutableblockposition).blocksMotion()) { + blockposition_mutableblockposition.move(Direction.DOWN); + } + + iblockdata = chunk.getBlockState(blockposition_mutableblockposition); + } else { -+ while (blockposition_mutableblockposition.getY() > this.level().getMinBuildHeight() && !this.level().getBlockState(blockposition_mutableblockposition).blocksMotion()) { ++ while (blockposition_mutableblockposition.getY() > this.level().getMinY() && !this.level().getBlockState(blockposition_mutableblockposition).blocksMotion()) { + blockposition_mutableblockposition.move(Direction.DOWN); + } + diff --git a/patches/server/0032-InstantBlockUpdater-Reintroduced.patch b/patches/server/0029-InstantBlockUpdater-Reintroduced.patch similarity index 82% rename from patches/server/0032-InstantBlockUpdater-Reintroduced.patch rename to patches/server/0029-InstantBlockUpdater-Reintroduced.patch index b37b4576..5eeceab9 100644 --- a/patches/server/0032-InstantBlockUpdater-Reintroduced.patch +++ b/patches/server/0029-InstantBlockUpdater-Reintroduced.patch @@ -6,16 +6,16 @@ Subject: [PATCH] InstantBlockUpdater Reintroduced This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition) diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index e935903d918f12e5e1617ebf2d74399b9cd4f79c..1f6e6bba0f6d16091f4c6a5fdb4bac4579ba525f 100644 +index 022de445bbbb869c38be4972c98dcf1c665539ec..1187453b7d961a0605af636cb6b5ed0c1f6b4be3 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -723,7 +723,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -878,7 +878,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl this.thread = Thread.currentThread(); this.biomeManager = new BiomeManager(this, i); this.isDebug = flag1; - this.neighborUpdater = new CollectingNeighborUpdater(this, j); + // Leaves start - instantBlockUpdaterReintroduced -+ if (org.leavesmc.leaves.LeavesConfig.instantBlockUpdaterReintroduced) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.updater.instantBlockUpdaterReintroduced) { + this.neighborUpdater = new net.minecraft.world.level.redstone.InstantNeighborUpdater(this); + } else { + this.neighborUpdater = new CollectingNeighborUpdater(this, j); diff --git a/patches/server/0033-Random-flatten-triangular-distribution.patch b/patches/server/0030-Random-flatten-triangular-distribution.patch similarity index 82% rename from patches/server/0033-Random-flatten-triangular-distribution.patch rename to patches/server/0030-Random-flatten-triangular-distribution.patch index e6d51c9b..420ad4de 100644 --- a/patches/server/0033-Random-flatten-triangular-distribution.patch +++ b/patches/server/0030-Random-flatten-triangular-distribution.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Random flatten triangular distribution This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition) diff --git a/src/main/java/net/minecraft/util/RandomSource.java b/src/main/java/net/minecraft/util/RandomSource.java -index 9c6f5b55b1f1376fa75e216cd366ee47c79fafc4..50dc6530e6191f2a00025d4610e335041bc858a4 100644 +index 252aef3ffe0fecd47ebea1ed7df48e14fa873eb9..bbfe68a7e860fff5c43feb2dc02c3c664a29bd09 100644 --- a/src/main/java/net/minecraft/util/RandomSource.java +++ b/src/main/java/net/minecraft/util/RandomSource.java @@ -53,7 +53,14 @@ public interface RandomSource { @@ -15,7 +15,7 @@ index 9c6f5b55b1f1376fa75e216cd366ee47c79fafc4..50dc6530e6191f2a00025d4610e33504 default double triangle(double mode, double deviation) { - return mode + deviation * (this.nextDouble() - this.nextDouble()); + // Leaves start - flattenTriangularDistribution -+ if (org.leavesmc.leaves.LeavesConfig.flattenTriangularDistribution) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.flattenTriangularDistribution) { + this.nextDouble(); + return mode + deviation * (-1 + this.nextDouble() * 2); + } else { @@ -24,4 +24,4 @@ index 9c6f5b55b1f1376fa75e216cd366ee47c79fafc4..50dc6530e6191f2a00025d4610e33504 + // Leaves end - flattenTriangularDistribution } - default void consumeCount(int count) { + default float triangle(float mode, float deviation) { diff --git a/patches/server/0034-BBOR-Protocol.patch b/patches/server/0031-BBOR-Protocol.patch similarity index 91% rename from patches/server/0034-BBOR-Protocol.patch rename to patches/server/0031-BBOR-Protocol.patch index e446fec3..1e6b5974 100644 --- a/patches/server/0034-BBOR-Protocol.patch +++ b/patches/server/0031-BBOR-Protocol.patch @@ -5,10 +5,10 @@ Subject: [PATCH] BBOR Protocol diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 5221ab490fcbc11434c1209f654e5731fa15487e..7ba6579cfe925ef40940cce29ebc0abb6458f13d 100644 +index b83b903381ca6c426d2f26f9459e769083eb5876..7a741442ee2373f1a400214047bbf5844efecce6 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1596,6 +1596,7 @@ public abstract class PlayerList { +@@ -1566,6 +1566,7 @@ public abstract class PlayerList { entityplayer.getRecipeBook().sendInitialRecipeBook(entityplayer); } @@ -17,10 +17,10 @@ index 5221ab490fcbc11434c1209f654e5731fa15487e..7ba6579cfe925ef40940cce29ebc0abb public boolean isAllowCommandsForAllPlayers() { 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 c0ce5d4c3189337b06476c16558e12d3f8127797..382ca565fe1a680ab49b14ac90e4ec3bd903450d 100644 +index 4640baec5bed6c2d53cc0f8ca1d273cc115abe9b..2fea5a46bba27578366c36f594472c3e38395bee 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -784,6 +784,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -813,6 +813,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p public void setLoaded(boolean loadedToWorld) { this.loaded = loadedToWorld; @@ -34,7 +34,7 @@ index c0ce5d4c3189337b06476c16558e12d3f8127797..382ca565fe1a680ab49b14ac90e4ec3b public Level getLevel() { diff --git a/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85d6d145fd +index 0000000000000000000000000000000000000000..c4ba09a998966fd8563f592920774cba2ea61c31 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/BBORProtocol.java @@ -0,0 +1,227 @@ @@ -90,7 +90,7 @@ index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85 + + @ProtocolHandler.Ticker + public static void tick() { -+ if (LeavesConfig.bborProtocol) { ++ if (LeavesConfig.protocol.bborProtocol) { + for (var playerEntry : players.entrySet()) { + sendBoundingToPlayer(playerEntry.getKey(), playerEntry.getValue()); + } @@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85 + + @ProtocolHandler.ReloadServer + public static void onServerReload() { -+ if (LeavesConfig.bborProtocol) { ++ if (LeavesConfig.protocol.bborProtocol) { + initAllPlayer(); + } else { + loggedOutAllPlayer(); @@ -108,7 +108,7 @@ index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85 + + @ProtocolHandler.PlayerJoin + public static void onPlayerLoggedIn(@NotNull ServerPlayer player) { -+ if (LeavesConfig.bborProtocol) { ++ if (LeavesConfig.protocol.bborProtocol) { + ServerLevel overworld = MinecraftServer.getServer().overworld(); + ProtocolUtils.sendPayloadPacket(player, INITIALIZE_CLIENT, buf -> { + buf.writeLong(overworld.getSeed()); @@ -121,7 +121,7 @@ index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85 + + @ProtocolHandler.PlayerLeave + public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { -+ if (LeavesConfig.bborProtocol) { ++ if (LeavesConfig.protocol.bborProtocol) { + players.remove(player.getId()); + playerBoundingBoxesCache.remove(player.getId()); + } @@ -129,22 +129,22 @@ index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85 + + @ProtocolHandler.PayloadReceiver(payload = EmptyPayload.class, payloadId = "subscribe") + public static void onPlayerSubscribed(@NotNull ServerPlayer player, EmptyPayload payload) { -+ if (LeavesConfig.bborProtocol) { ++ if (LeavesConfig.protocol.bborProtocol) { + players.put(player.getId(), player); + sendBoundingToPlayer(player.getId(), player); + } + } + + public static void onDataPackReload() { -+ if (LeavesConfig.bborProtocol) { ++ if (LeavesConfig.protocol.bborProtocol) { + players.values().forEach(BBORProtocol::sendStructureList); + } + } + + public static void onChunkLoaded(@NotNull LevelChunk chunk) { -+ if (LeavesConfig.bborProtocol) { ++ if (LeavesConfig.protocol.bborProtocol) { + Map structures = new HashMap<>(); -+ final Registry structureFeatureRegistry = chunk.getLevel().registryAccess().registryOrThrow(Registries.STRUCTURE); ++ final Registry structureFeatureRegistry = chunk.getLevel().registryAccess().lookupOrThrow(Registries.STRUCTURE); + for (var es : chunk.getAllStarts().entrySet()) { + final var optional = structureFeatureRegistry.getResourceKey(es.getKey()); + optional.ifPresent(key -> structures.put(key.location().toString(), es.getValue())); @@ -184,8 +184,8 @@ index 0000000000000000000000000000000000000000..16ef00dde5a1c502449378829b1b6b85 + return new BBoundingBox(type, min, max); + } + -+ private static void sendStructureList(ServerPlayer player) { -+ final Registry structureRegistry = player.server.registryAccess().registryOrThrow(Registries.STRUCTURE); ++ private static void sendStructureList(@NotNull ServerPlayer player) { ++ final Registry structureRegistry = player.server.registryAccess().lookupOrThrow(Registries.STRUCTURE); + final Set structureIds = structureRegistry.entrySet().stream() + .map(e -> e.getKey().location().toString()).collect(Collectors.toSet()); + ProtocolUtils.sendPayloadPacket(player, STRUCTURE_LIST_SYNC, buf -> { diff --git a/patches/server/0035-PCA-sync-protocol.patch b/patches/server/0032-PCA-sync-protocol.patch similarity index 90% rename from patches/server/0035-PCA-sync-protocol.patch rename to patches/server/0032-PCA-sync-protocol.patch index fdf33077..192f5d21 100644 --- a/patches/server/0035-PCA-sync-protocol.patch +++ b/patches/server/0032-PCA-sync-protocol.patch @@ -6,15 +6,15 @@ Subject: [PATCH] PCA sync protocol This patch is Powered by plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) 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 1f5ed236fb7c0c1b0181675747d25d233f534284..08559ff5409d362bc674f63d6e46ced6c0474601 100644 +index 8aed30cdbbfdd42c20dcd4c8773c8a0ee21a980d..b2c83534446f95503b9fd8bd09be90575622c395 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 -@@ -436,6 +436,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -449,6 +449,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, @Override public void containerChanged(Container sender) { + // Leaves start - pca -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this); + } + // Leaves end - pca @@ -22,7 +22,7 @@ index 1f5ed236fb7c0c1b0181675747d25d233f534284..08559ff5409d362bc674f63d6e46ced6 this.syncSaddleToClients(); 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 d28ebcae036168dd65a5f3236d12ee416308c23f..ebdb1546fb057bf4881d53538f8e44c14fe88b74 100644 +index 5f656fc726a1dc5f42657095a2f2b7cf85b92d7c..6c0cece094d36ddb2ae8d67d3c847a2c8faa3da8 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -69,6 +69,15 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @@ -32,7 +32,7 @@ index d28ebcae036168dd65a5f3236d12ee416308c23f..ebdb1546fb057bf4881d53538f8e44c1 + // Leaves start - pca + if (!this.level().isClientSide()) { + this.inventory.addListener(inventory -> { -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this); + } + }); @@ -42,17 +42,17 @@ index d28ebcae036168dd65a5f3236d12ee416308c23f..ebdb1546fb057bf4881d53538f8e44c1 @Override 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 9549eee0d92f322bd5232abd7e695213660c2e22..6044de3b76e236e22d4d00f80dae0380ba82d354 100644 +index d528e8e4aea266c495377365f01e314001eb1970..2472eb9f8f0b6872f7b98cb2da511c6a2527b8fc 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -@@ -126,7 +126,13 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme +@@ -122,7 +122,13 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme } @Override - public void setChanged() {} + public void setChanged() { + // Leaves start - pca -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this); + } + // Leaves end - pca @@ -61,18 +61,18 @@ index 9549eee0d92f322bd5232abd7e695213660c2e22..6044de3b76e236e22d4d00f80dae0380 @Override public boolean stillValid(Player player) { 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 730aca233f6e7564d4cb85b5b628d23c4f01d2f4..9ad4600ebee09d81b1785103ad17de47cf1f2ede 100644 +index 15e0861486a2bda3e2f4049b1b5a299c870acd31..82e93a63ea64adbf648ea7b8a844a376bbe63597 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 -@@ -558,6 +558,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit - +@@ -440,6 +440,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit + } } + // Leaves start - pca + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -82,7 +82,7 @@ index 730aca233f6e7564d4cb85b5b628d23c4f01d2f4..9ad4600ebee09d81b1785103ad17de47 public boolean canPlaceItem(int slot, ItemStack stack) { if (slot == 2) { diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java -index 6186e55014bbb9d5bedaa0e9d196879c55339d42..956c39ab508c2d8a7b9156aa53d655624db91f3d 100644 +index 618552afbdacc919c33b30a6bf4834fb71ab3d5b..c14e7805e849e56912d50b61d5f2f3d802ac9bde 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java @@ -132,6 +132,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity { @@ -93,7 +93,7 @@ index 6186e55014bbb9d5bedaa0e9d196879c55339d42..956c39ab508c2d8a7b9156aa53d65562 + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -103,27 +103,27 @@ index 6186e55014bbb9d5bedaa0e9d196879c55339d42..956c39ab508c2d8a7b9156aa53d65562 protected Component getDefaultName() { return Component.translatable("container.barrel"); 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 f933fa419a4b55b0096ff42caf1b071d027b8e7e..c8891f72d3353faf4afe5b49e1759ee0fe475cc3 100644 +index 83ad45aed0894e90825d22e078632352c3a06816..58319df10af098db7cb74f08651880dab64ae4e1 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 -@@ -143,6 +143,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -144,6 +144,11 @@ public class BeehiveBlockEntity extends BlockEntity { super.setChanged(); } + // Leaves start - pca -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + // Leaves end - pca return list; } -@@ -197,6 +202,12 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -198,6 +203,12 @@ public class BeehiveBlockEntity extends BlockEntity { this.level.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, this.getBlockState())); } + // Leaves start - pca -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + // Leaves end - pca @@ -131,24 +131,24 @@ index f933fa419a4b55b0096ff42caf1b071d027b8e7e..c8891f72d3353faf4afe5b49e1759ee0 entity.discard(EntityRemoveEvent.Cause.ENTER_BLOCK); // CraftBukkit - add Bukkit remove cause super.setChanged(); } -@@ -312,6 +323,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -313,6 +324,11 @@ public class BeehiveBlockEntity extends BlockEntity { if (BeehiveBlockEntity.releaseOccupant(world, pos, state, tileentitybeehive_hivebee.toOccupant(), (List) null, tileentitybeehive_releasestatus, flowerPos)) { flag = true; iterator.remove(); + // Leaves start - pca -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(Objects.requireNonNull(world.getBlockEntity(pos))); + } + // Leaves end - pca // CraftBukkit start } else { tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.occupant.minTicksInHive / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - Fix bees aging inside hives; use exitTickCounter to keep actual bee life -@@ -357,6 +373,11 @@ public class BeehiveBlockEntity extends BlockEntity { +@@ -358,6 +374,11 @@ public class BeehiveBlockEntity extends BlockEntity { this.maxBees = nbt.getInt("Bukkit.MaxEntities"); } // CraftBukkit end + // Leaves start - pca -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + // Leaves end - pca @@ -156,10 +156,10 @@ index f933fa419a4b55b0096ff42caf1b071d027b8e7e..c8891f72d3353faf4afe5b49e1759ee0 @Override 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 0a93bacd62249bae1800ff306b8a7c765b0e5a8b..9561d804ef47d11a492531f8e8a419f905b48c17 100644 +index 02fc9ce21c7d367055da350d21be4870d4242f3a..974a7fbec9ec347ea16a07d7c857a27e3b25f76d 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 -@@ -344,6 +344,16 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements +@@ -345,6 +345,16 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements return this.canPlaceItem(slot, stack); } @@ -167,7 +167,7 @@ index 0a93bacd62249bae1800ff306b8a7c765b0e5a8b..9561d804ef47d11a492531f8e8a419f9 + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -177,7 +177,7 @@ index 0a93bacd62249bae1800ff306b8a7c765b0e5a8b..9561d804ef47d11a492531f8e8a419f9 public boolean canTakeItemThroughFace(int slot, ItemStack stack, Direction dir) { return slot == 3 ? stack.is(Items.GLASS_BOTTLE) : true; 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 b88aa184cd06a0485146f58a5b61a56a50911209..4d4485f1007341a5303374b3facd033c87b887b3 100644 +index 8847617f6a23e6d2fe9bf7444a2072dc53f741b8..ef91101fb9e44b5db58272e4c2fdada1fa9e1686 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 @@ -191,6 +191,16 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement @@ -188,7 +188,7 @@ index b88aa184cd06a0485146f58a5b61a56a50911209..4d4485f1007341a5303374b3facd033c + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -198,7 +198,7 @@ index b88aa184cd06a0485146f58a5b61a56a50911209..4d4485f1007341a5303374b3facd033c public float getOpenNess(float tickDelta) { return this.chestLidController.getOpenness(tickDelta); diff --git a/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java -index 7ea490a61321830c41dfa1bbd5480217dc62f478..d037adbe784d1b9e620d3c0798bc8b86061c5701 100644 +index 9db5826420d693628ad74614f4cee79e1ebd88d9..0e14b15b262f1ca5e12e31d2f18bc90bb94baf79 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java @@ -24,6 +24,16 @@ public class ComparatorBlockEntity extends BlockEntity { @@ -209,7 +209,7 @@ index 7ea490a61321830c41dfa1bbd5480217dc62f478..d037adbe784d1b9e620d3c0798bc8b86 + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -219,7 +219,7 @@ index 7ea490a61321830c41dfa1bbd5480217dc62f478..d037adbe784d1b9e620d3c0798bc8b86 return this.output; } diff --git a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java -index 431fb6a658c6aac43b6f9dbd1f578b83f261a4e3..138c045dc694c596083bc2f23831ca22e9484297 100644 +index c7f1937b0f171eee967388ab4699703dcdcfbd2b..c3d41360b2c5dab04f519459bd855045e8bec7c1 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java @@ -109,6 +109,16 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity { @@ -230,7 +230,7 @@ index 431fb6a658c6aac43b6f9dbd1f578b83f261a4e3..138c045dc694c596083bc2f23831ca22 + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -240,7 +240,7 @@ index 431fb6a658c6aac43b6f9dbd1f578b83f261a4e3..138c045dc694c596083bc2f23831ca22 protected Component getDefaultName() { return Component.translatable("container.dispenser"); 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 cab403efd471bb61835224eea4e99570d34dcaaa..f7a6296773defc95215bdf36d8ea105cf9590a9e 100644 +index 5ebbdb94d9b91c442ff60eb6872f740ebd790fa0..02bda85189fd57bd3f6d18cfd573553b2e607300 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 @@ -134,6 +134,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -251,7 +251,7 @@ index cab403efd471bb61835224eea4e99570d34dcaaa..f7a6296773defc95215bdf36d8ea105c + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -265,7 +265,7 @@ index cab403efd471bb61835224eea4e99570d34dcaaa..f7a6296773defc95215bdf36d8ea105c blockEntity.setCooldown(world.spigotConfig.hopperTransfer); // Spigot setChanged(world, pos, state); + // Leaves start - pca -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(blockEntity); + } + // Leaves end - pca @@ -273,7 +273,7 @@ index cab403efd471bb61835224eea4e99570d34dcaaa..f7a6296773defc95215bdf36d8ea105c } } diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -index 0d68db20f5fbe5e834f12c1e8fd429099a44e4b6..5b62860cd64b5e6dc02dadb4651824ac04b00024 100644 +index 6291ebf3426bddb0e6d13159ce20936b6e9ba6bd..3784e4c14bb59073f941b966f616ddac3f80a497 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java @@ -270,6 +270,16 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl @@ -284,7 +284,7 @@ index 0d68db20f5fbe5e834f12c1e8fd429099a44e4b6..5b62860cd64b5e6dc02dadb4651824ac + @Override + public void setChanged() { + super.setChanged(); -+ if (org.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) { ++ if (org.leavesmc.leaves.LeavesConfig.protocol.pca.enable) { + org.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this); + } + } @@ -295,7 +295,7 @@ index 0d68db20f5fbe5e834f12c1e8fd429099a44e4b6..5b62860cd64b5e6dc02dadb4651824ac return ShulkerBoxBlockEntity.SLOTS; diff --git a/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..7126ec4b6e0a1bfa16d97fd21d7ae8955a66565c +index 0000000000000000000000000000000000000000..a38318506aeb1632ba7903671bcfad1e871c8fc7 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/PcaSyncProtocol.java @@ -0,0 +1,432 @@ @@ -363,14 +363,14 @@ index 0000000000000000000000000000000000000000..7126ec4b6e0a1bfa16d97fd21d7ae895 + + @ProtocolHandler.PlayerJoin + private static void onJoin(ServerPlayer player) { -+ if (LeavesConfig.pcaSyncProtocol) { ++ if (LeavesConfig.protocol.pca.enable) { + enablePcaSyncProtocol(player); + } + } + + @ProtocolHandler.PayloadReceiver(payload = EmptyPayload.class, payloadId = "cancel_sync_block_entity") + private static void cancelSyncBlockEntityHandler(ServerPlayer player, EmptyPayload payload) { -+ if (!LeavesConfig.pcaSyncProtocol) { ++ if (!LeavesConfig.protocol.pca.enable) { + return; + } + PcaSyncProtocol.clearPlayerWatchBlock(player); @@ -378,7 +378,7 @@ index 0000000000000000000000000000000000000000..7126ec4b6e0a1bfa16d97fd21d7ae895 + + @ProtocolHandler.PayloadReceiver(payload = EmptyPayload.class, payloadId = "cancel_sync_entity") + private static void cancelSyncEntityHandler(ServerPlayer player, EmptyPayload payload) { -+ if (!LeavesConfig.pcaSyncProtocol) { ++ if (!LeavesConfig.protocol.pca.enable) { + return; + } + PcaSyncProtocol.clearPlayerWatchEntity(player); @@ -386,7 +386,7 @@ index 0000000000000000000000000000000000000000..7126ec4b6e0a1bfa16d97fd21d7ae895 + + @ProtocolHandler.PayloadReceiver(payload = SyncBlockEntityPayload.class, payloadId = "sync_block_entity") + private static void syncBlockEntityHandler(ServerPlayer player, SyncBlockEntityPayload payload) { -+ if (!LeavesConfig.pcaSyncProtocol) { ++ if (!LeavesConfig.protocol.pca.enable) { + return; + } + @@ -430,7 +430,7 @@ index 0000000000000000000000000000000000000000..7126ec4b6e0a1bfa16d97fd21d7ae895 + + @ProtocolHandler.PayloadReceiver(payload = SyncEntityPayload.class, payloadId = "sync_entity") + private static void syncEntityHandler(ServerPlayer player, SyncEntityPayload payload) { -+ if (!LeavesConfig.pcaSyncProtocol) { ++ if (!LeavesConfig.protocol.pca.enable) { + return; + } + @@ -445,7 +445,7 @@ index 0000000000000000000000000000000000000000..7126ec4b6e0a1bfa16d97fd21d7ae895 + clearPlayerWatchData(player); + + if (entity instanceof Player) { -+ switch (LeavesConfig.pcaSyncPlayerEntity) { ++ switch (LeavesConfig.protocol.pca.syncPlayerEntity) { + case NOBODY -> { + return; + } diff --git a/patches/server/0036-Jade-Protocol.patch b/patches/server/0033-Jade-Protocol.patch similarity index 98% rename from patches/server/0036-Jade-Protocol.patch rename to patches/server/0033-Jade-Protocol.patch index 4ea85964..dad10a3b 100644 --- a/patches/server/0036-Jade-Protocol.patch +++ b/patches/server/0033-Jade-Protocol.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Jade Protocol This patch is Powered by Jade(https://github.com/Snownee/Jade) 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 729fd2d52dd48e25ee7a077a3ffafc80ecef7c9f..28d6b1d49045c125214c40895efd484e4ae20c2b 100644 +index c1ef714096159608752d744b98f615cd45fe459a..142bc508f5b816407d219944b9354db649a10ce0 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 @@ -63,7 +63,7 @@ public class Armadillo extends Animal { @@ -19,10 +19,10 @@ index 729fd2d52dd48e25ee7a077a3ffafc80ecef7c9f..28d6b1d49045c125214c40895efd484e public Armadillo(EntityType type, Level world) { 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 43046f4a0cff620834ac4647efdcde227185b2ff..a08cd692e332a6caed33cd3db2373e847621ad6a 100644 +index 48ac8c3f6e00c3c2dc67b6c994be7c0ac6dfcf81..ac306874dc94ec59427b353beec273f9f7d54432 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 -@@ -256,7 +256,7 @@ public class Tadpole extends AbstractFish { +@@ -246,7 +246,7 @@ public class Tadpole extends AbstractFish { } @@ -32,10 +32,10 @@ index 43046f4a0cff620834ac4647efdcde227185b2ff..a08cd692e332a6caed33cd3db2373e84 } 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 6684ded7135f943f8cea954b417f596369215357..0621c6c026678cb4ac3626342d73290c0f2803d9 100644 +index a49f83784f85f5420091692aae588ef067aa5fcd..137f777d324d0a0addc2e43913e196bc9f09e004 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 -@@ -72,7 +72,7 @@ public class TrialSpawnerData { +@@ -73,7 +73,7 @@ public class TrialSpawnerData { }); public final Set detectedPlayers; public final Set currentMobs; @@ -58,12 +58,12 @@ index 38078c44b35e917d1d243a5f8599aa858d8611de..13dbadfb50278b79b33d9dce10413c93 private final Predicate compositeCondition; private final List functions; 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 edaf7f1692ae059581f3abc24bb228874e6d114b..f09cfc472d4dbdc8cb0b6a45ef240b25a865ffba 100644 +index c2bded5094097f5615a2ddb0718942486ede93b5..78fd2b33174a0c8b1dec99009bc2c8d41f6cbfe0 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 @@ -58,7 +58,7 @@ public class LootTable { public static final Codec> CODEC = RegistryFileCodec.create(Registries.LOOT_TABLE, LootTable.DIRECT_CODEC); - private final LootContextParamSet paramSet; + private final ContextKeySet paramSet; private final Optional randomSequence; - private final List pools; + public final List pools; // Leaves - private -> public @@ -97,7 +97,7 @@ index 1d2f2bb352abf6772cd20293575fc79e8e64ce3b..b157dfaf1efffebd3f2ae8cb8fcf0972 protected LootPoolEntryContainer(List conditions) { diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java -index 71989359192c8f30a1a8d343a2c6cb5b92330491..ec273bd4d0e61f54532df599f00695e8b9d44800 100644 +index 61d47a1e86a26bdee49d0ae931aeb92417ab02c2..1116f194b457ef736bf9e836c190817610008ef6 100644 --- a/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java +++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/NestedLootTable.java @@ -25,7 +25,7 @@ public class NestedLootTable extends LootPoolSingletonContainer { @@ -124,10 +124,10 @@ index 30d0133a42ce990352f5c492fcf9beb105364848..1ab2eab686b3a89d406f127a6036c0e2 protected CompositeLootItemCondition(List terms, Predicate predicate) { diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..438dfee78f7114e7c8d3d57c5dcc90e1fcc75a4c +index 0000000000000000000000000000000000000000..ccce630f67cd6329033d65156231e749eaf0c448 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/JadeProtocol.java -@@ -0,0 +1,311 @@ +@@ -0,0 +1,312 @@ +package org.leavesmc.leaves.protocol.jade; + +import com.google.common.base.Suppliers; @@ -290,8 +290,9 @@ index 0000000000000000000000000000000000000000..438dfee78f7114e7c8d3d57c5dcc90e1 + + try { + shearableBlocks = Collections.unmodifiableList(LootTableMineableCollector.execute( -+ MinecraftServer.getServer().reloadableRegistries().get().registryOrThrow(Registries.LOOT_TABLE), -+ Items.SHEARS.getDefaultInstance())); ++ MinecraftServer.getServer().reloadableRegistries().lookup().lookupOrThrow(Registries.LOOT_TABLE), ++ Items.SHEARS.getDefaultInstance() ++ )); + } catch (Throwable ignore) { + shearableBlocks = List.of(); + LeavesLogger.LOGGER.severe("Failed to collect shearable blocks"); @@ -300,7 +301,7 @@ index 0000000000000000000000000000000000000000..438dfee78f7114e7c8d3d57c5dcc90e1 + + @ProtocolHandler.PlayerJoin + public static void onPlayerJoin(ServerPlayer player) { -+ if (!LeavesConfig.jadeProtocol) { ++ if (!LeavesConfig.protocol.jadeProtocol) { + return; + } + @@ -309,7 +310,7 @@ index 0000000000000000000000000000000000000000..438dfee78f7114e7c8d3d57c5dcc90e1 + + @ProtocolHandler.PayloadReceiver(payload = RequestEntityPayload.class, payloadId = "request_entity") + public static void requestEntityData(ServerPlayer player, RequestEntityPayload payload) { -+ if (!LeavesConfig.jadeProtocol) { ++ if (!LeavesConfig.protocol.jadeProtocol) { + return; + } + @@ -361,7 +362,7 @@ index 0000000000000000000000000000000000000000..438dfee78f7114e7c8d3d57c5dcc90e1 + + @ProtocolHandler.PayloadReceiver(payload = RequestBlockPayload.class, payloadId = "request_block") + public static void requestBlockData(ServerPlayer player, RequestBlockPayload payload) { -+ if (!LeavesConfig.jadeProtocol) { ++ if (!LeavesConfig.protocol.jadeProtocol) { + return; + } + @@ -424,7 +425,7 @@ index 0000000000000000000000000000000000000000..438dfee78f7114e7c8d3d57c5dcc90e1 + + @ProtocolHandler.ReloadServer + public static void onServerReload() { -+ if (LeavesConfig.jadeProtocol) { ++ if (LeavesConfig.protocol.jadeProtocol) { + enableAllPlayer(); + } + } @@ -1231,7 +1232,7 @@ index 0000000000000000000000000000000000000000..6e32eed15f028020223e2500849b4db3 \ No newline at end of file diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java new file mode 100644 -index 0000000000000000000000000000000000000000..797558f3804a1a8143eafafd5dc46cc72ea19a42 +index 0000000000000000000000000000000000000000..3efa3ceb9654bc53adb61ded96c0ad08eb9b083d --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/provider/ItemStorageExtensionProvider.java @@ -0,0 +1,138 @@ @@ -1285,7 +1286,7 @@ index 0000000000000000000000000000000000000000..797558f3804a1a8143eafafd5dc46cc7 + case RandomizableContainer te when te.getLootTable() != null -> { + return List.of(); + } -+ case ContainerEntity containerEntity when containerEntity.getLootTable() != null -> { ++ case ContainerEntity containerEntity when containerEntity.getContainerLootTable() != null -> { + return List.of(); + } + default -> { @@ -3097,15 +3098,16 @@ index 0000000000000000000000000000000000000000..a046ae4e542efcadd0001b7225440c30 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/jade/util/LootTableMineableCollector.java b/src/main/java/org/leavesmc/leaves/protocol/jade/util/LootTableMineableCollector.java new file mode 100644 -index 0000000000000000000000000000000000000000..63f4d0a31232525db3620095fc662f0225c5f306 +index 0000000000000000000000000000000000000000..81575cfa4c5a6f1a1aadbf9ea7743cd1d053f925 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/jade/util/LootTableMineableCollector.java -@@ -0,0 +1,105 @@ +@@ -0,0 +1,109 @@ +package org.leavesmc.leaves.protocol.jade.util; + +import com.google.common.collect.Lists; +import net.minecraft.advancements.critereon.ItemPredicate; -+import net.minecraft.core.Registry; ++import net.minecraft.core.Holder; ++import net.minecraft.core.HolderGetter; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; @@ -3121,19 +3123,20 @@ index 0000000000000000000000000000000000000000..63f4d0a31232525db3620095fc662f02 +import org.leavesmc.leaves.protocol.jade.tool.ShearsToolHandler; + +import java.util.List; ++import java.util.Optional; +import java.util.function.Function; + +public class LootTableMineableCollector { + -+ private final Registry lootRegistry; ++ private final HolderGetter lootRegistry; + private final ItemStack toolItem; + -+ public LootTableMineableCollector(Registry lootRegistry, ItemStack toolItem) { ++ public LootTableMineableCollector(HolderGetter lootRegistry, ItemStack toolItem) { + this.lootRegistry = lootRegistry; + this.toolItem = toolItem; + } + -+ public static @NotNull List execute(Registry lootRegistry, ItemStack toolItem) { ++ public static @NotNull List execute(HolderGetter lootRegistry, ItemStack toolItem) { + LootTableMineableCollector collector = new LootTableMineableCollector(lootRegistry, toolItem); + List list = Lists.newArrayList(); + for (Block block : BuiltInRegistries.BLOCK) { @@ -3141,9 +3144,11 @@ index 0000000000000000000000000000000000000000..63f4d0a31232525db3620095fc662f02 + continue; + } + -+ LootTable lootTable = lootRegistry.get(block.getLootTable()); -+ if (collector.doLootTable(lootTable)) { -+ list.add(block); ++ if (block.getLootTable().isPresent()) { ++ LootTable lootTable = lootRegistry.get(block.getLootTable().get()).map(Holder::value).orElse(null); ++ if (collector.doLootTable(lootTable)) { ++ list.add(block); ++ } + } + } + return list; @@ -3179,7 +3184,7 @@ index 0000000000000000000000000000000000000000..63f4d0a31232525db3620095fc662f02 + } + } + } else if (entry instanceof NestedLootTable nestedLootTable) { -+ LootTable lootTable = nestedLootTable.contents.map(lootRegistry::get, Function.identity()); ++ LootTable lootTable = nestedLootTable.contents.map($ -> lootRegistry.get($).map(Holder::value).orElse(null), Function.identity()); + return doLootTable(lootTable); + } else { + return isCorrectConditions(entry.conditions, toolItem); @@ -3193,8 +3198,8 @@ index 0000000000000000000000000000000000000000..63f4d0a31232525db3620095fc662f02 + } + + LootItemCondition condition = conditions.getFirst(); -+ if (condition instanceof MatchTool matchTool) { -+ ItemPredicate itemPredicate = matchTool.predicate().orElse(null); ++ if (condition instanceof MatchTool(Optional predicate)) { ++ ItemPredicate itemPredicate = predicate.orElse(null); + return itemPredicate != null && itemPredicate.test(toolItem); + } else if (condition instanceof AnyOfCondition anyOfCondition) { + for (LootItemCondition child : anyOfCondition.terms) { diff --git a/patches/server/0037-Alternative-block-placement-Protocol.patch b/patches/server/0034-Alternative-block-placement-Protocol.patch similarity index 90% rename from patches/server/0037-Alternative-block-placement-Protocol.patch rename to patches/server/0034-Alternative-block-placement-Protocol.patch index 32bff813..f37dba8e 100644 --- a/patches/server/0037-Alternative-block-placement-Protocol.patch +++ b/patches/server/0034-Alternative-block-placement-Protocol.patch @@ -9,15 +9,15 @@ MasaGadget(https://github.com/plusls/MasaGadget) litematica(https://github.com/maruohon/litematica) diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 96fb69ec6db2e7c8c728435f0c537b076259b2fb..29f38a0a87cb7e27ac18c09dd59e774cfd874592 100644 +index c816c935ecc74a811ffdffbe6ded73c06e92324a..dba8ee20f9fed3adf26885471897ade154ec1d4d 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -163,6 +163,27 @@ public class BlockItem extends Item { +@@ -157,6 +157,27 @@ public class BlockItem extends Item { @Nullable protected BlockState getPlacementState(BlockPlaceContext context) { BlockState iblockdata = this.getBlock().getStateForPlacement(context); + // Leaves start - alternativeBlockPlacement -+ switch (org.leavesmc.leaves.LeavesConfig.alternativeBlockPlacement) { ++ switch (org.leavesmc.leaves.LeavesConfig.protocol.alternativeBlockPlacement) { + case CARPET -> { + BlockState tryState = org.leavesmc.leaves.protocol.CarpetAlternativeBlockPlacement.alternativeBlockPlacement(getBlock(), context); + if (tryState != null) { @@ -41,7 +41,7 @@ index 96fb69ec6db2e7c8c728435f0c537b076259b2fb..29f38a0a87cb7e27ac18c09dd59e774c return iblockdata != null && this.canPlace(context, iblockdata) ? iblockdata : null; } diff --git a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java -index f8f909ebdad5e96379e8bd8c610164ef0697368e..0b761f3ae15ad4a3b8152f497a60403212109534 100644 +index 1451b25cedb7a8f01c046c8e1f8c6853aca42283..4390adf843b395db688017eb9034b56a40971473 100644 --- a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java +++ b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java @@ -34,7 +34,7 @@ public class StandingAndWallBlockItem extends BlockItem { @@ -63,10 +63,10 @@ index f8f909ebdad5e96379e8bd8c610164ef0697368e..0b761f3ae15ad4a3b8152f497a604032 if (iblockdata2 != null && this.canPlace(world, iblockdata2, blockposition)) { iblockdata1 = iblockdata2; 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 7130209f48c488e2d184f31335f0511735963c55..0c31c53b1512f0c47a525eff04c1b783cb782fd3 100644 +index b3a3388ef62b0622906b2470056cb41f0deb0391..1c9b9f27179f2bd3f24709a763ff264e97cb1dca 100644 --- a/src/main/java/net/minecraft/world/level/block/Block.java +++ b/src/main/java/net/minecraft/world/level/block/Block.java -@@ -411,6 +411,33 @@ public class Block extends BlockBehaviour implements ItemLike { +@@ -414,6 +414,33 @@ public class Block extends BlockBehaviour implements ItemLike { public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) {} @@ -74,7 +74,7 @@ index 7130209f48c488e2d184f31335f0511735963c55..0c31c53b1512f0c47a525eff04c1b783 + @Nullable + public BlockState getRealStateForPlacement(BlockPlaceContext ctx) { + BlockState vanillaState = getStateForPlacement(ctx); -+ switch (org.leavesmc.leaves.LeavesConfig.alternativeBlockPlacement) { ++ switch (org.leavesmc.leaves.LeavesConfig.protocol.alternativeBlockPlacement) { + case CARPET -> { + BlockState tryState = org.leavesmc.leaves.protocol.CarpetAlternativeBlockPlacement.alternativeBlockPlacement(this, ctx); + if (tryState != null) { @@ -102,10 +102,10 @@ index 7130209f48c488e2d184f31335f0511735963c55..0c31c53b1512f0c47a525eff04c1b783 return this.defaultBlockState(); diff --git a/src/main/java/org/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java b/src/main/java/org/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java new file mode 100644 -index 0000000000000000000000000000000000000000..03978356d2716296f8c5e4173d10862db57a3193 +index 0000000000000000000000000000000000000000..e5c5bee2518ff2843270979d36d264f17a5cf0a6 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/CarpetAlternativeBlockPlacement.java -@@ -0,0 +1,162 @@ +@@ -0,0 +1,167 @@ +package org.leavesmc.leaves.protocol; + +import net.minecraft.core.BlockPos; @@ -128,7 +128,7 @@ index 0000000000000000000000000000000000000000..03978356d2716296f8c5e4173d10862d +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.ComparatorMode; -+import net.minecraft.world.level.block.state.properties.DirectionProperty; ++import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.Half; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.block.state.properties.SlabType; @@ -152,7 +152,7 @@ index 0000000000000000000000000000000000000000..03978356d2716296f8c5e4173d10862d + return null; + } + -+ DirectionProperty directionProp = getFirstDirectionProperty(state); ++ EnumProperty directionProp = getFirstDirectionProperty(state); + int protocolValue = ((int) relativeHitX - 2) / 2; + + if (directionProp != null) { @@ -209,7 +209,8 @@ index 0000000000000000000000000000000000000000..03978356d2716296f8c5e4173d10862d + return state; + } + -+ public static BlockState alternativeBlockPlacementFix(Block block, BlockPlaceContext context) { ++ @Nullable ++ public static BlockState alternativeBlockPlacementFix(Block block, @NotNull BlockPlaceContext context) { + Direction facing; + Vec3 vec3d = context.getClickLocation(); + BlockPos pos = context.getClickedPos(); @@ -258,22 +259,26 @@ index 0000000000000000000000000000000000000000..03978356d2716296f8c5e4173d10862d + return null; + } + ++ @SuppressWarnings("unchecked") + @Nullable -+ public static DirectionProperty getFirstDirectionProperty(@NotNull BlockState state) { ++ public static EnumProperty getFirstDirectionProperty(@NotNull BlockState state) { + for (Property prop : state.getProperties()) { -+ if (prop instanceof DirectionProperty) { -+ return (DirectionProperty) prop; ++ if (prop instanceof EnumProperty enumProperty) { ++ if (enumProperty.getValueClass().equals(Direction.class)) { ++ return (EnumProperty) enumProperty; ++ } + } + } ++ + return null; + } +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a4688f9eb +index 0000000000000000000000000000000000000000..eceb1b8322fa50809990636e6caed491828e2fd6 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/LitematicaEasyPlaceProtocol.java -@@ -0,0 +1,209 @@ +@@ -0,0 +1,214 @@ +package org.leavesmc.leaves.protocol; + +import com.google.common.collect.ImmutableSet; @@ -287,10 +292,11 @@ index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a +import net.minecraft.world.level.block.BedBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; -+import net.minecraft.world.level.block.state.properties.DirectionProperty; ++import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.Property; +import net.minecraft.world.level.block.state.properties.SlabType; +import net.minecraft.world.phys.Vec3; ++import org.jetbrains.annotations.NotNull; +import org.leavesmc.leaves.LeavesLogger; + +import javax.annotation.Nullable; @@ -311,6 +317,8 @@ index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a + BlockStateProperties.CHEST_TYPE, + BlockStateProperties.MODE_COMPARATOR, + BlockStateProperties.DOOR_HINGE, ++ BlockStateProperties.FACING_HOPPER, ++ BlockStateProperties.HORIZONTAL_FACING, + BlockStateProperties.ORIENTATION, + BlockStateProperties.RAIL_SHAPE, + BlockStateProperties.RAIL_SHAPE_STRAIGHT, @@ -326,14 +334,15 @@ index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a + return applyPlacementProtocolV3(state, UseContext.from(context, context.getHand())); + } + -+ private static > BlockState applyPlacementProtocolV3(BlockState state, UseContext context) { ++ @Nullable ++ private static > BlockState applyPlacementProtocolV3(BlockState state, @NotNull UseContext context) { + int protocolValue = (int) (context.getHitVec().x - (double) context.getPos().getX()) - 2; + BlockState oldState = state; + if (protocolValue < 0) { + return oldState; + } + -+ @Nullable DirectionProperty property = CarpetAlternativeBlockPlacement.getFirstDirectionProperty(state); ++ EnumProperty property = CarpetAlternativeBlockPlacement.getFirstDirectionProperty(state); + + if (property != null && property != BlockStateProperties.VERTICAL_DIRECTION) { + state = applyDirectionProperty(state, context, property, protocolValue); @@ -358,7 +367,7 @@ index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a + + try { + for (Property p : propList) { -+ if (!(p instanceof DirectionProperty) && WHITELISTED_PROPERTIES.contains(p)) { ++ if (((p instanceof EnumProperty ep) && !ep.getValueClass().equals(Direction.class)) && WHITELISTED_PROPERTIES.contains(p)) { + @SuppressWarnings("unchecked") + Property prop = (Property) p; + List list = new ArrayList<>(prop.getPossibleValues()); @@ -386,7 +395,7 @@ index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a + } + } + } catch (Exception e) { -+ LeavesLogger.LOGGER.warning("Exception trying to apply placement protocol value"); ++ LeavesLogger.LOGGER.warning("Exception trying to apply placement protocol value", e); + } + + if (state.canSurvive(context.getWorld(), context.getPos())) { @@ -396,7 +405,7 @@ index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a + } + } + -+ private static BlockState applyDirectionProperty(BlockState state, UseContext context, DirectionProperty property, int protocolValue) { ++ private static BlockState applyDirectionProperty(BlockState state, UseContext context, EnumProperty property, int protocolValue) { + Direction facingOrig = state.getValue(property); + Direction facing = facingOrig; + int decodedFacingIndex = (protocolValue & 0xF) >> 1; @@ -448,7 +457,8 @@ index 0000000000000000000000000000000000000000..92f90ebf04f00341360e9e0ba1da5e0a + this.itemPlacementContext = itemPlacementContext; + } + -+ public static UseContext from(BlockPlaceContext ctx, InteractionHand hand) { ++ @NotNull ++ public static UseContext from(@NotNull BlockPlaceContext ctx, InteractionHand hand) { + Vec3 pos = ctx.getClickLocation(); + return new UseContext(ctx.getLevel(), ctx.getClickedPos(), ctx.getClickedFace(), new Vec3(pos.x, pos.y, pos.z), ctx.getPlayer(), hand, ctx); + } diff --git a/patches/server/0038-Player-operation-limiter.patch b/patches/server/0035-Player-operation-limiter.patch similarity index 87% rename from patches/server/0038-Player-operation-limiter.patch rename to patches/server/0035-Player-operation-limiter.patch index 440e1e99..8471c8ef 100644 --- a/patches/server/0038-Player-operation-limiter.patch +++ b/patches/server/0035-Player-operation-limiter.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Player operation limiter This patch is Powered by plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index c2263ef7fb67db7c01bac7aecf218ee8cb7369cb..b4ddddc0bf56ef1993d5db5727287cbeb19e6e53 100644 +index ebae6c704844755c75aa0c6f460603c5d909b5cf..d02f0123a830c77056e978bbef8d454d110d0589 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -302,6 +302,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -329,6 +329,10 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent 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 @@ -20,7 +20,7 @@ index c2263ef7fb67db7c01bac7aecf218ee8cb7369cb..b4ddddc0bf56ef1993d5db5727287cbe // Paper start - rewrite chunk system private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; -@@ -763,6 +767,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -991,6 +995,7 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple this.joining = false; } // CraftBukkit end @@ -28,7 +28,7 @@ index c2263ef7fb67db7c01bac7aecf218ee8cb7369cb..b4ddddc0bf56ef1993d5db5727287cbe this.gameMode.tick(); this.wardenSpawnTracker.tick(); --this.spawnInvulnerableTime; -@@ -2955,5 +2960,32 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -3314,5 +3319,32 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple public CraftPlayer getBukkitEntity() { return (CraftPlayer) super.getBukkitEntity(); } @@ -62,15 +62,15 @@ index c2263ef7fb67db7c01bac7aecf218ee8cb7369cb..b4ddddc0bf56ef1993d5db5727287cbe // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -index ee9e4521079137d7b72194e8789810e7a89b8e75..171c2c2fe69e48a3b73348ee73e47417b80dec23 100644 +index a96f859a5d0c6ec692d4627a69f3c9ee49199dbc..31ff81ca6a89fc3ce59c4b53a6a547eb4f2e812a 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java -@@ -339,6 +339,19 @@ public class ServerPlayerGameMode { +@@ -337,6 +337,19 @@ public class ServerPlayerGameMode { } public void destroyAndAck(BlockPos pos, int sequence, String reason) { + // Leaves start - player operation limiter -+ if (org.leavesmc.leaves.LeavesConfig.playerOperationLimiter) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.playerOperationLimiter) { + if (reason.equals("insta mine")) { + player.addInstaBreakCountPerTick(); + if (!player.allowOperation()) { @@ -86,15 +86,15 @@ index ee9e4521079137d7b72194e8789810e7a89b8e75..171c2c2fe69e48a3b73348ee73e47417 this.debugLogging(pos, true, sequence, reason); } else { diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 29f38a0a87cb7e27ac18c09dd59e774cfd874592..2759a9eeef85b323b7e1ea78090f4f9d637c938a 100644 +index dba8ee20f9fed3adf26885471897ade154ec1d4d..77309808abd4ab476e815d60015ad828102a1f6b 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -80,6 +80,20 @@ public class BlockItem extends Item { +@@ -74,6 +74,20 @@ public class BlockItem extends Item { final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper - Reset placed block on exception // CraftBukkit end + // Leaves start - player operation limiter -+ if (org.leavesmc.leaves.LeavesConfig.playerOperationLimiter && !context.getLevel().isClientSide()) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.playerOperationLimiter && !context.getLevel().isClientSide()) { + ServerPlayer player = (ServerPlayer) context.getPlayer(); + if (player != null && iblockdata != null) { + player.addPlaceBlockCountPerTick(); diff --git a/patches/server/0039-Renewable-Elytra.patch b/patches/server/0036-Renewable-Elytra.patch similarity index 67% rename from patches/server/0039-Renewable-Elytra.patch rename to patches/server/0036-Renewable-Elytra.patch index d340ed4a..440ba374 100644 --- a/patches/server/0039-Renewable-Elytra.patch +++ b/patches/server/0036-Renewable-Elytra.patch @@ -6,22 +6,22 @@ Subject: [PATCH] Renewable Elytra This patch is Powered by Carpet-TIS-Addition(https://github.com/plusls/Carpet-TIS-Addition) 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 c277dac448a64809e93dd7a447ee3dc2a86c860e..5641da81d6f00e153d847b9284251084d545e726 100644 +index 150fd890ac65097b5434fd88e8d2b24a89dca79a..e47de71f7c120cf7f1a7cdb5e49b1d89163e5722 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java @@ -233,6 +233,20 @@ public class Phantom extends FlyingMob implements Enemy { - return entitysize.scale(1.0F + 0.15F * (float) i); + return predicate.test(world, this, target); } + // Leaves start - renewable elytra + @Override -+ protected void dropFromLootTable(DamageSource source, boolean causedByPlayer) { -+ super.dropFromLootTable(source, causedByPlayer); -+ if (org.leavesmc.leaves.LeavesConfig.renewableElytra > 0.0D) { -+ if (source.getEntity() instanceof Shulker && this.random.nextDouble() < org.leavesmc.leaves.LeavesConfig.renewableElytra) { ++ protected void dropFromLootTable(ServerLevel level, DamageSource source, boolean causedByPlayer) { ++ super.dropFromLootTable(level, source, causedByPlayer); ++ if (org.leavesmc.leaves.LeavesConfig.modify.renewableElytra > 0.0D) { ++ if (source.getEntity() instanceof Shulker && this.random.nextDouble() < org.leavesmc.leaves.LeavesConfig.modify.renewableElytra) { + net.minecraft.world.item.ItemStack item = new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ELYTRA); + item.setDamageValue(432); -+ this.spawnAtLocation(item); ++ this.spawnAtLocation(level, item); + } + } + } diff --git a/patches/server/0040-Stackable-ShulkerBoxes.patch b/patches/server/0037-Stackable-ShulkerBoxes.patch similarity index 85% rename from patches/server/0040-Stackable-ShulkerBoxes.patch rename to patches/server/0037-Stackable-ShulkerBoxes.patch index 75e7f0a8..135ecf70 100644 --- a/patches/server/0040-Stackable-ShulkerBoxes.patch +++ b/patches/server/0037-Stackable-ShulkerBoxes.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Stackable ShulkerBoxes This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet) and plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition) 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 8cca2ac616a2c80268c96b9f95e33f834a0fc8fd..bcca3fa530fd52238bc9444244b1f26a567f6fc4 100644 +index 8d5939e03a065197af125d95a10134abbccd07ec..f6b703a7c46da64b7d789dc85b0973e894ced6de 100644 --- a/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java +++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundContainerSetContentPacket.java @@ -23,7 +23,7 @@ public class ClientboundContainerSetContentPacket implements Packet= 1 && packet.slotNum() <= 45; @@ -62,7 +62,7 @@ index 5db5ba026462ca642dcee718af732f80fadabef5..bca47bc78a444011b7e549aba949fea7 boolean stillValid(Player player); diff --git a/src/main/java/net/minecraft/world/SimpleContainer.java b/src/main/java/net/minecraft/world/SimpleContainer.java -index d04bf7d06855022c973073fb84c5d3d65f2553e1..9bedd76330e71ca7f3feecf0b90ec960c35d1a6f 100644 +index 7ed52b887c4d766c23220a8809914d5d80f12ea4..8f8ae3f27be586de1413013db3ffca254f93f4eb 100644 --- a/src/main/java/net/minecraft/world/SimpleContainer.java +++ b/src/main/java/net/minecraft/world/SimpleContainer.java @@ -222,7 +222,7 @@ public class SimpleContainer implements Container, StackedContentsCompatible { @@ -84,31 +84,32 @@ index d04bf7d06855022c973073fb84c5d3d65f2553e1..9bedd76330e71ca7f3feecf0b90ec960 if (j > 0) { 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 4423973d4d9a2c3879d98d1d4c8b8c117c677ac5..4259852e2387c87cb692e44b2d1a3f5d1cfcd616 100644 +index 0f086af57a5ff08c264dcbf89a8c3931ec73a609..8f2ca7211d4ebf494beae85caea5876fad4723eb 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -22,10 +22,12 @@ import net.minecraft.world.entity.EntityType; +@@ -12,11 +12,13 @@ import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.SlotAccess; import net.minecraft.world.entity.TraceableEntity; +import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; - import net.minecraft.world.item.Items; + import net.minecraft.world.level.Explosion; + import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.ShulkerBoxBlock; import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.portal.DimensionTransition; + import net.minecraft.world.level.portal.TeleportTransition; import net.minecraft.world.phys.Vec3; -@@ -36,6 +38,7 @@ import net.minecraft.sounds.SoundSource; - import net.minecraft.stats.Stats; +@@ -36,6 +38,7 @@ import net.minecraft.tags.ItemTags; + import net.minecraft.util.Mth; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.entity.Player; +import org.bukkit.block.ShulkerBox; import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityRemoveEvent; import org.bukkit.event.player.PlayerPickupItemEvent; -@@ -314,10 +317,49 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -317,10 +320,49 @@ public class ItemEntity extends Entity implements TraceableEntity { private boolean isMergable() { ItemStack itemstack = this.getItem(); @@ -119,7 +120,7 @@ index 4423973d4d9a2c3879d98d1d4c8b8c117c677ac5..4259852e2387c87cb692e44b2d1a3f5d + // Leaves end - stackable shulker boxes + private boolean tryStackShulkerBoxes(ItemEntity other) { + ItemStack selfStack = this.getItem(); -+ if (org.leavesmc.leaves.LeavesConfig.shulkerBoxStackSize == 1 || !(selfStack.getItem() instanceof BlockItem bi) || !(bi.getBlock() instanceof ShulkerBoxBlock)) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize == 1 || !(selfStack.getItem() instanceof BlockItem bi) || !(bi.getBlock() instanceof ShulkerBoxBlock)) { + return false; + } + @@ -128,8 +129,8 @@ index 4423973d4d9a2c3879d98d1d4c8b8c117c677ac5..4259852e2387c87cb692e44b2d1a3f5d + && org.leavesmc.leaves.util.ShulkerBoxUtils.shulkerBoxNoItem(selfStack) + && org.leavesmc.leaves.util.ShulkerBoxUtils.shulkerBoxNoItem(otherStack) + && Objects.equals(selfStack.getComponents(), otherStack.getComponents()) // empty block entity tags are cleaned up when spawning -+ && selfStack.getCount() != org.leavesmc.leaves.LeavesConfig.shulkerBoxStackSize) { -+ int amount = Math.min(otherStack.getCount(), org.leavesmc.leaves.LeavesConfig.shulkerBoxStackSize - selfStack.getCount()); ++ && selfStack.getCount() != org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize) { ++ int amount = Math.min(otherStack.getCount(), org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize - selfStack.getCount()); + + selfStack.grow(amount); + this.setItem(selfStack); @@ -160,10 +161,10 @@ index 4423973d4d9a2c3879d98d1d4c8b8c117c677ac5..4259852e2387c87cb692e44b2d1a3f5d ItemStack itemstack1 = other.getItem(); 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 eb11482f48c9f330b7fa62a278fd6f07d3a642e1..62b4aeabbde9561cd7e78fe14b751bd377ba129a 100644 +index d2bd4c5b2a7a9689680f4b021368f25356c58ac7..c07dae6cf6cd60a1f100415977dd9fe2ce639d72 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) { @@ -172,7 +173,7 @@ index eb11482f48c9f330b7fa62a278fd6f07d3a642e1..62b4aeabbde9561cd7e78fe14b751bd3 } // CraftBukkit start - Watch method above! :D -@@ -122,13 +122,13 @@ public class Inventory implements Container, Nameable { +@@ -121,13 +121,13 @@ public class Inventory implements Container, Nameable { if (itemstack1.isEmpty()) return itemstack.getCount(); if (this.hasRemainingSpaceForItem(itemstack1, itemstack)) { @@ -188,7 +189,7 @@ index eb11482f48c9f330b7fa62a278fd6f07d3a642e1..62b4aeabbde9561cd7e78fe14b751bd3 } if (remains <= 0) return itemstack.getCount(); -@@ -279,7 +279,9 @@ public class Inventory implements Container, Nameable { +@@ -273,7 +273,9 @@ public class Inventory implements Container, Nameable { this.setItem(slot, itemstack1); } @@ -199,20 +200,20 @@ index eb11482f48c9f330b7fa62a278fd6f07d3a642e1..62b4aeabbde9561cd7e78fe14b751bd3 int l = Math.min(j, k); if (l == 0) { -@@ -394,7 +396,7 @@ public class Inventory implements Container, Nameable { +@@ -388,7 +390,7 @@ public class Inventory implements Container, Nameable { } if (i != -1) { - int j = stack.getMaxStackSize() - this.getItem(i).getCount(); + int j = org.leavesmc.leaves.util.ShulkerBoxUtils.getItemStackMaxCount(stack) - this.getItem(i).getCount(); // Leaves - stackable shulker boxes - if (this.add(i, stack.split(j)) && notifiesClient && this.player instanceof ServerPlayer) { - ((ServerPlayer) this.player).connection.send(new ClientboundContainerSetSlotPacket(-2, 0, i, this.getItem(i))); + if (!this.add(i, stack.split(j)) || !notifiesClient) { + continue; 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 9fdeaaa67a39b7b4bd2ac8f58dd38b87c6540e3e..a0cb30bb04742a8ae4a9c4c8e17707e4530b40ed 100644 +index 45f6191cc8e2ecdacbc2df0ddb5ea7cc6a546812..02cfa01c85089c3aeee5288bff56cb4fa842dab6 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java -@@ -166,7 +166,7 @@ public interface ContainerEntity extends Container, MenuProvider { +@@ -165,7 +165,7 @@ public interface ContainerEntity extends Container, MenuProvider { default void setChestVehicleItem(int slot, ItemStack stack) { this.unpackChestVehicleLootTable(null); this.getItemStacks().set(slot, stack); @@ -222,10 +223,10 @@ index 9fdeaaa67a39b7b4bd2ac8f58dd38b87c6540e3e..a0cb30bb04742a8ae4a9c4c8e17707e4 default SlotAccess getChestVehicleSlot(int slot) { diff --git a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -index 9bb703f2af1f201772b5309a4d80b3fbe23a7201..ac9f80727e973b5303e4494310fbcb78203d9102 100644 +index a21c658343ab6e1eb3a98ff10369b490bd7d52da..8d9bcffdfe722dbe0fb4503cc2c2ead47d338acb 100644 --- a/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AbstractContainerMenu.java -@@ -456,7 +456,7 @@ public abstract class AbstractContainerMenu { +@@ -493,7 +493,7 @@ public abstract class AbstractContainerMenu { if (slot1 != null && AbstractContainerMenu.canItemQuickReplace(slot1, itemstack2, true) && slot1.mayPlace(itemstack2) && (this.quickcraftType == 2 || itemstack2.getCount() >= this.quickcraftSlots.size()) && this.canDragTo(slot1)) { int j1 = slot1.hasItem() ? slot1.getItem().getCount() : 0; @@ -234,7 +235,7 @@ index 9bb703f2af1f201772b5309a4d80b3fbe23a7201..ac9f80727e973b5303e4494310fbcb78 int l1 = Math.min(AbstractContainerMenu.getQuickCraftPlaceCount(this.quickcraftSlots, this.quickcraftType, itemstack1) + j1, k1); l -= l1 - j1; -@@ -575,7 +575,7 @@ public abstract class AbstractContainerMenu { +@@ -612,7 +612,7 @@ public abstract class AbstractContainerMenu { slot.setByPlayer(itemstack3); } } else if (ItemStack.isSameItemSameComponents(itemstack, itemstack3)) { @@ -243,7 +244,7 @@ index 9bb703f2af1f201772b5309a4d80b3fbe23a7201..ac9f80727e973b5303e4494310fbcb78 optional1.ifPresent((itemstack4) -> { itemstack3.grow(itemstack4.getCount()); -@@ -645,7 +645,7 @@ public abstract class AbstractContainerMenu { +@@ -682,7 +682,7 @@ public abstract class AbstractContainerMenu { slot2 = (Slot) this.slots.get(slotIndex); if (slot2.hasItem()) { itemstack1 = slot2.getItem(); @@ -252,7 +253,7 @@ index 9bb703f2af1f201772b5309a4d80b3fbe23a7201..ac9f80727e973b5303e4494310fbcb78 } } else if (actionType == ClickType.THROW && this.getCarried().isEmpty() && slotIndex >= 0) { slot2 = (Slot) this.slots.get(slotIndex); -@@ -660,13 +660,13 @@ public abstract class AbstractContainerMenu { +@@ -713,13 +713,13 @@ public abstract class AbstractContainerMenu { j2 = button == 0 ? 1 : -1; for (i2 = 0; i2 < 2; ++i2) { @@ -268,7 +269,7 @@ index 9bb703f2af1f201772b5309a4d80b3fbe23a7201..ac9f80727e973b5303e4494310fbcb78 ItemStack itemstack6 = slot3.safeTake(itemstack5.getCount(), itemstack1.getMaxStackSize() - itemstack1.getCount(), player); itemstack1.grow(itemstack6.getCount()); -@@ -805,7 +805,7 @@ public abstract class AbstractContainerMenu { +@@ -868,7 +868,7 @@ public abstract class AbstractContainerMenu { ItemStack itemstack1; int l; @@ -277,7 +278,7 @@ index 9bb703f2af1f201772b5309a4d80b3fbe23a7201..ac9f80727e973b5303e4494310fbcb78 while (!stack.isEmpty()) { if (fromLast) { if (k < startIndex) { -@@ -824,6 +824,7 @@ public abstract class AbstractContainerMenu { +@@ -887,6 +887,7 @@ public abstract class AbstractContainerMenu { // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent if (!itemstack1.isEmpty() && ItemStack.isSameItemSameComponents(stack, itemstack1)) { l = itemstack1.getCount() + stack.getCount(); @@ -285,7 +286,7 @@ index 9bb703f2af1f201772b5309a4d80b3fbe23a7201..ac9f80727e973b5303e4494310fbcb78 int i1 = slot.getMaxStackSize(itemstack1); if (l <= i1) { -@@ -875,6 +876,7 @@ public abstract class AbstractContainerMenu { +@@ -938,6 +939,7 @@ public abstract class AbstractContainerMenu { } // Paper end - Add PlayerTradeEvent and PlayerPurchaseEvent if (itemstack1.isEmpty() && slot.mayPlace(stack)) { @@ -307,7 +308,7 @@ index 9140fab07aab32065f7a3b5d13dd17d61dc6d646..210b88b5d87fad641188cf5907c54824 this.updateSellItem(); } diff --git a/src/main/java/net/minecraft/world/inventory/Slot.java b/src/main/java/net/minecraft/world/inventory/Slot.java -index c39c773112fb8b534b926f2f2b47fe6fbb69fcb2..ae9338b8a5598e7a257b469adae72858fed95c39 100644 +index 0bdbd192f9eb2d6d529dc5b2baee9b4f20885b9c..7851247575321784aa13b707a7d6b945b4f24587 100644 --- a/src/main/java/net/minecraft/world/inventory/Slot.java +++ b/src/main/java/net/minecraft/world/inventory/Slot.java @@ -76,7 +76,7 @@ public class Slot { @@ -320,10 +321,10 @@ index c39c773112fb8b534b926f2f2b47fe6fbb69fcb2..ae9338b8a5598e7a257b469adae72858 @Nullable diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 522b817f23f08eb720fe9d05eec7f548d2761603..a0879f03e8f1477d2c45bd4754f4d9171774a8a1 100644 +index 33e7d2884195677c4d6340d8b84c1dd85c636ec1..f38487562422ebaf59a679f493f956b90cc18ff1 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -225,7 +225,7 @@ public final class ItemStack implements DataComponentHolder { +@@ -224,7 +224,7 @@ public final class ItemStack implements DataComponentHolder { @Deprecated @Nullable private Item item; @@ -333,25 +334,25 @@ index 522b817f23f08eb720fe9d05eec7f548d2761603..a0879f03e8f1477d2c45bd4754f4d917 private Entity entityRepresentation; 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 4fdef6d7bcea0cf6b7d90324398af597660c80e3..b84d03bc51d081775207abd9ce1f4da80c0588eb 100644 +index e00ab1ed8088a1970249313ed63e09070fc6192d..89cfabda335d27d3657299c69837e29057617052 100644 --- a/src/main/java/net/minecraft/world/level/block/AbstractCauldronBlock.java +++ b/src/main/java/net/minecraft/world/level/block/AbstractCauldronBlock.java -@@ -58,9 +58,27 @@ public abstract class AbstractCauldronBlock extends Block { - ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit - ) { +@@ -56,9 +56,27 @@ 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, hit.getDirection()); // Paper - pass hit direction + return wrapInteractor(cauldronInteraction, state, world, pos, player, hand, stack, hit.getDirection()); // Paper - pass hit direction // Leaves - stackable shulker boxes } + // Leaves start - stackable shulker boxes -+ private ItemInteractionResult wrapInteractor(CauldronInteraction cauldronBehavior, BlockState blockState, Level world, BlockPos blockPos, Player playerEntity, InteractionHand hand, ItemStack itemStack, net.minecraft.core.Direction hitDirection) { ++ private InteractionResult wrapInteractor(CauldronInteraction cauldronBehavior, BlockState blockState, Level world, BlockPos blockPos, Player playerEntity, InteractionHand hand, ItemStack itemStack, net.minecraft.core.Direction hitDirection) { + int count = -1; -+ if (org.leavesmc.leaves.LeavesConfig.shulkerBoxStackSize > 1 && itemStack.getItem() instanceof net.minecraft.world.item.BlockItem bi && ++ if (org.leavesmc.leaves.LeavesConfig.modify.shulkerBoxStackSize > 1 && itemStack.getItem() instanceof net.minecraft.world.item.BlockItem bi && + bi.getBlock() instanceof ShulkerBoxBlock) { + count = itemStack.getCount(); + } -+ ItemInteractionResult result = cauldronBehavior.interact(blockState, world, blockPos, playerEntity, hand, itemStack, hitDirection); ++ InteractionResult result = cauldronBehavior.interact(blockState, world, blockPos, playerEntity, hand, itemStack, hitDirection); + if (count > 0 && result.consumesAction()) { + ItemStack current = playerEntity.getItemInHand(hand); + if (current.getItem() instanceof net.minecraft.world.item.BlockItem bi && bi.getBlock() instanceof ShulkerBoxBlock) { @@ -366,20 +367,20 @@ index 4fdef6d7bcea0cf6b7d90324398af597660c80e3..b84d03bc51d081775207abd9ce1f4da8 protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return SHAPE; 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 9ad4600ebee09d81b1785103ad17de47cf1f2ede..7092a4d4a583f4e01cc02bca17f3bd1bd32677a0 100644 +index 82e93a63ea64adbf648ea7b8a844a376bbe63597..46bdb85f18077c77c445ce0bc3cfe32468c75306 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 -@@ -549,7 +549,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -426,7 +426,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit boolean flag = !stack.isEmpty() && ItemStack.isSameItemSameComponents(itemstack1, stack); this.items.set(slot, stack); - stack.limitSize(this.getMaxStackSize(stack)); + stack.limitSize(this.getMaxStackLeaves(stack)); // Leaves - stackable shulker boxes if (slot == 0 && !flag) { - this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this.recipeType, this, this.cookSpeedMultiplier); // Paper - cook speed multiplier API - this.cookingProgress = 0; + Level world = this.level; + 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 2ddf349fde5b310ec3f74baee1f3d33e09d5286c..76d85d7a34888731c083d33be906205576fed840 100644 +index 1f29b2419914ca9257db6553f01b7e7ec49bfc18..9d9a7c972119b224089f062d9c64c689e3d47bcc 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 @@ -158,7 +158,7 @@ public abstract class BaseContainerBlockEntity extends BlockEntity implements Co @@ -392,7 +393,7 @@ index 2ddf349fde5b310ec3f74baee1f3d33e09d5286c..76d85d7a34888731c083d33be9062055 } 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 f7a6296773defc95215bdf36d8ea105cf9590a9e..5f394cda052271b6ecfafc325733e5ae0524822f 100644 +index 02bda85189fd57bd3f6d18cfd573553b2e607300..ad5a971a4de217aa93601db8364f2cad1aab4c38 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 @@ -125,7 +125,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -418,7 +419,7 @@ index f7a6296773defc95215bdf36d8ea105cf9590a9e..5f394cda052271b6ecfafc325733e5ae ignoreTileUpdates = true; // Paper - Perf: Optimize Hoppers diff --git a/src/main/java/org/leavesmc/leaves/util/ShulkerBoxUtils.java b/src/main/java/org/leavesmc/leaves/util/ShulkerBoxUtils.java new file mode 100644 -index 0000000000000000000000000000000000000000..64344eb9310690dd31e7fadcfb29ed8dda559716 +index 0000000000000000000000000000000000000000..07ed58fba9f8eb0f66c5aa6bd216fc02bbc5a5b3 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/ShulkerBoxUtils.java @@ -0,0 +1,39 @@ @@ -440,9 +441,9 @@ index 0000000000000000000000000000000000000000..64344eb9310690dd31e7fadcfb29ed8d + } + + public static int getItemStackMaxCount(ItemStack stack) { -+ if (LeavesConfig.shulkerBoxStackSize > 1 && stack.getItem() instanceof BlockItem bi && ++ if (LeavesConfig.modify.shulkerBoxStackSize > 1 && stack.getItem() instanceof BlockItem bi && + bi.getBlock() instanceof ShulkerBoxBlock && shulkerBoxNoItem(stack)) { -+ return LeavesConfig.shulkerBoxStackSize; ++ return LeavesConfig.modify.shulkerBoxStackSize; + } + return stack.getMaxStackSize(); + } diff --git a/patches/server/0042-MC-Technical-Survival-Mode.patch b/patches/server/0038-MC-Technical-Survival-Mode.patch similarity index 56% rename from patches/server/0042-MC-Technical-Survival-Mode.patch rename to patches/server/0038-MC-Technical-Survival-Mode.patch index 2358239e..dc13c7e9 100644 --- a/patches/server/0042-MC-Technical-Survival-Mode.patch +++ b/patches/server/0038-MC-Technical-Survival-Mode.patch @@ -6,10 +6,10 @@ Subject: [PATCH] MC Technical Survival Mode Will automatically overwrite some configuration after startup diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -index 1029b6de6f36b08bf634b4056ef5701383f6f258..64bb056d409c19eca724caa8512e6a597623170e 100644 +index c5644d8d64f12073e39bc6ed79c8714f4560ff89..e2e5fdf539f69629d13e50ab08b3fc38474e3384 100644 --- a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java +++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -@@ -318,6 +318,7 @@ public class PaperConfigurations extends Configurations 0 && ++this.level().spigotConfig.currentPrimedTnt > this.level().spigotConfig.maxTntTicksPerTick) { return; } // Spigot -+ if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > (org.leavesmc.leaves.LeavesConfig.mcTechnicalMode ? 2000 : this.level().spigotConfig.maxTntTicksPerTick)) { return; } // Spigot // Leaves - mc technical survival mode ++ if (this.level().spigotConfig.maxTntTicksPerTick > 0 && ++this.level().spigotConfig.currentPrimedTnt > (org.leavesmc.leaves.LeavesConfig.modify.mcTechnicalMode ? 2000 : this.level().spigotConfig.maxTntTicksPerTick)) { return; } // Spigot // Leaves - mc technical survival mode this.handlePortal(); this.applyGravity(); this.move(MoverType.SELF, this.getDeltaMovement()); -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 10ade433c083851d9ea4797c6ec618db122229f9..dff461c78e3a613391601b4a948fe49e62332439 100644 ---- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java -@@ -126,7 +126,7 @@ public abstract class Projectile extends Entity implements TraceableEntity { - if (nbt.hasUUID("Owner")) { - this.ownerUUID = nbt.getUUID("Owner"); - this.cachedOwner = null; -- 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 && !org.leavesmc.leaves.LeavesConfig.mcTechnicalMode) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit // Leaves - mc technical mode - } - - this.leftOwner = nbt.getBoolean("LeftOwner"); diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 8205d34ed80781b2aab1fb2ef59986b9370f0198..c5b26fdb173a59280e790a5d5a687e0c0114bb74 100644 +index c1b76a1ebc1eea7ab70cf61d8175a31794dd122a..f817fd922ffcf857e8a5fc803b10421f640a8cd1 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -90,7 +90,7 @@ public final class NaturalSpawner { +@@ -94,7 +94,7 @@ public final class NaturalSpawner { if (enumcreaturetype != MobCategory.MISC) { // Paper start - Only count natural spawns - if (!entity.level().paperConfig().entities.spawning.countAllMobsForSpawning && -+ if (!org.leavesmc.leaves.LeavesConfig.mcTechnicalMode && !entity.level().paperConfig().entities.spawning.countAllMobsForSpawning && // Leaves - mc technical survival mode ++ if (!org.leavesmc.leaves.LeavesConfig.modify.mcTechnicalMode && !entity.level().paperConfig().entities.spawning.countAllMobsForSpawning && // Leaves - mc technical survival mode !(entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL || entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) { continue; 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 5f394cda052271b6ecfafc325733e5ae0524822f..cee74a6c47cd56a17a8faf68405fee09d6fd4655 100644 +index ad5a971a4de217aa93601db8364f2cad1aab4c38..7280d2216dcbe09278a2447eb994c4bd2aa98576 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 @@ -295,7 +295,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -104,7 +78,7 @@ index 5f394cda052271b6ecfafc325733e5ae0524822f..cee74a6c47cd56a17a8faf68405fee09 } } - if (foundItem && level.paperConfig().hopper.cooldownWhenFull) { // Inventory was full - cooldown -+ if (foundItem && level.paperConfig().hopper.cooldownWhenFull && !org.leavesmc.leaves.LeavesConfig.mcTechnicalMode) { // Inventory was full - cooldown // Leaves ++ if (foundItem && level.paperConfig().hopper.cooldownWhenFull && !org.leavesmc.leaves.LeavesConfig.modify.mcTechnicalMode) { // Inventory was full - cooldown // Leaves hopper.setCooldown(level.spigotConfig.hopperTransfer); } return false; @@ -113,13 +87,13 @@ index 5f394cda052271b6ecfafc325733e5ae0524822f..cee74a6c47cd56a17a8faf68405fee09 origItemStack.setCount(originalItemCount); - if (level.paperConfig().hopper.cooldownWhenFull) { -+ if (level.paperConfig().hopper.cooldownWhenFull && !org.leavesmc.leaves.LeavesConfig.mcTechnicalMode) { // Leaves ++ if (level.paperConfig().hopper.cooldownWhenFull && !org.leavesmc.leaves.LeavesConfig.modify.mcTechnicalMode) { // Leaves cooldownHopper(hopper); } diff --git a/src/main/java/org/leavesmc/leaves/util/McTechnicalModeHelper.java b/src/main/java/org/leavesmc/leaves/util/McTechnicalModeHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..2fdcb75a1fb85ab2fc6759050b2e7ffa601dcfa0 +index 0000000000000000000000000000000000000000..0d8e5bf5f37357f2ed619e5574a8ce01589fe63e --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/McTechnicalModeHelper.java @@ -0,0 +1,27 @@ @@ -133,7 +107,7 @@ index 0000000000000000000000000000000000000000..2fdcb75a1fb85ab2fc6759050b2e7ffa +public class McTechnicalModeHelper { + + public static void doMcTechnicalModeIf() { -+ if (LeavesConfig.mcTechnicalMode) { ++ if (LeavesConfig.modify.mcTechnicalMode) { + doMcTechnicalMode(); + } + } diff --git a/patches/server/0043-Return-nether-portal-fix.patch b/patches/server/0039-Return-nether-portal-fix.patch similarity index 89% rename from patches/server/0043-Return-nether-portal-fix.patch rename to patches/server/0039-Return-nether-portal-fix.patch index f5468e24..7d123197 100644 --- a/patches/server/0043-Return-nether-portal-fix.patch +++ b/patches/server/0039-Return-nether-portal-fix.patch @@ -6,15 +6,15 @@ Subject: [PATCH] Return nether portal fix This patch is powered by NetherPortalFix(https://github.com/TwelveIterationMods/NetherPortalFix) diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java -index b70ee2d80756e90c495c578ceb1c9235c6861a6e..5a044eb18e598e8c9f860e899631633342d39350 100644 +index b0c1cc7196dae695b73eb766c5acbffeffd306b3..f80911edce05c7440ead01a2332452e20ed734c1 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java -@@ -1435,6 +1435,21 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -1699,6 +1699,21 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.getBukkitEntity(), worldserver1.getWorld()); this.level().getCraftServer().getPluginManager().callEvent(changeEvent); // CraftBukkit end + // Leaves start - nether portal fix -+ if (org.leavesmc.leaves.LeavesConfig.netherPortalFix) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.netherPortalFix) { + final ResourceKey fromDim = worldserver1.dimension(); + final ResourceKey toDim = level().dimension(); + final ResourceKey OVERWORLD = Level.OVERWORLD; @@ -32,15 +32,15 @@ index b70ee2d80756e90c495c578ceb1c9235c6861a6e..5a044eb18e598e8c9f860e8996316333 if (this.isBlocking()) { this.stopUsingItem(); diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 2fc4d42619611a2724aff9bc114c9118212ad974..8bcb3ceab7089224d93b73ab5dbafb0b77c4c317 100644 +index 7a741442ee2373f1a400214047bbf5844efecce6..eb43b1fcda50326f086999a6e134c9807b837045 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -943,6 +943,24 @@ public abstract class PlayerList { +@@ -909,6 +909,24 @@ public abstract class PlayerList { if (fromWorld != worldserver) { PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(entityplayer.getBukkitEntity(), fromWorld.getWorld()); this.server.server.getPluginManager().callEvent(event); + // Leaves start - nether portal fix -+ if (org.leavesmc.leaves.LeavesConfig.netherPortalFix) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.netherPortalFix) { + final ResourceKey fromDim = entityplayer.level().dimension(); + final ResourceKey toDim = entityplayer1.level().dimension(); + final ResourceKey OVERWORLD = Level.OVERWORLD; @@ -61,10 +61,10 @@ index 2fc4d42619611a2724aff9bc114c9118212ad974..8bcb3ceab7089224d93b73ab5dbafb0b // Save player file again if they were disconnected diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index d06f3080bf24b37a79519562825aba582a3f881a..ec5ac957bd463496a1d82e22db10be7d1b2de2dd 100644 +index 3002879d96916ce24400159792b48e5f9b8e2e3e..bc0eeb8274a7248dca7f01ddd89c9a7e481da75b 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -260,7 +260,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -272,7 +272,7 @@ public abstract class LivingEntity extends Entity implements Attackable { protected ItemStack useItem; public int useItemRemaining; protected int fallFlyTicks; @@ -74,17 +74,17 @@ index d06f3080bf24b37a79519562825aba582a3f881a..ec5ac957bd463496a1d82e22db10be7d @Nullable private DamageSource lastDamageSource; 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 0fdbcab175b51a8b77646e0e4a267d987b133a35..d61354349c3d0eea71b0a8ef8013ad418a639686 100644 +index 2b31bf586c1c0bd393d2aa8d0b6635dd9f22f21c..0a9ce12e958ac25a4d789254e1fec9ec2c2a33ca 100644 --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -172,7 +172,18 @@ public class NetherPortalBlock extends Block implements Portal { +@@ -180,7 +180,18 @@ public class NetherPortalBlock extends Block implements Portal { @Nullable - private DimensionTransition getExitPortal(ServerLevel worldserver, Entity entity, BlockPos blockposition, BlockPos blockposition1, boolean flag, WorldBorder worldborder, int searchRadius, boolean canCreatePortal, int createRadius) { + private TeleportTransition getExitPortal(ServerLevel worldserver, Entity entity, BlockPos blockposition, BlockPos blockposition1, boolean flag, WorldBorder worldborder, int searchRadius, boolean canCreatePortal, int createRadius) { - Optional optional = worldserver.getPortalForcer().findClosestPortalPosition(blockposition1, worldborder, searchRadius); + // Leaves start - fix return portal + Optional optional = Optional.empty(); -+ if (org.leavesmc.leaves.LeavesConfig.netherPortalFix && entity instanceof net.minecraft.server.level.ServerPlayer player) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.netherPortalFix && entity instanceof net.minecraft.server.level.ServerPlayer player) { + org.leavesmc.leaves.util.ReturnPortalManager.ReturnPortal portal = org.leavesmc.leaves.util.ReturnPortalManager.findReturnPortal(player, entity.level().dimension(), entity.blockPosition()); + if (portal != null && worldserver.getBlockState(portal.pos()).is(Blocks.NETHER_PORTAL)) { + optional = Optional.of(portal.pos()); @@ -95,7 +95,7 @@ index 0fdbcab175b51a8b77646e0e4a267d987b133a35..d61354349c3d0eea71b0a8ef8013ad41 + } + // Leaves end - fix return portal BlockUtil.FoundRectangle blockutil_rectangle; - DimensionTransition.PostDimensionTransition dimensiontransition_a; + TeleportTransition.PostTeleportTransition teleporttransition_a; diff --git a/src/main/java/org/leavesmc/leaves/util/ReturnPortalManager.java b/src/main/java/org/leavesmc/leaves/util/ReturnPortalManager.java new file mode 100644 diff --git a/patches/server/0040-Appleskin-Protocol.patch b/patches/server/0040-Appleskin-Protocol.patch new file mode 100644 index 00000000..b9f002ec --- /dev/null +++ b/patches/server/0040-Appleskin-Protocol.patch @@ -0,0 +1,139 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Wed, 25 Jan 2023 11:03:53 +0800 +Subject: [PATCH] Appleskin Protocol + + +diff --git a/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java +new file mode 100644 +index 0000000000000000000000000000000000000000..dd8afa5a47e62829788c4d49d18e4436daa242dd +--- /dev/null ++++ b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java +@@ -0,0 +1,127 @@ ++package org.leavesmc.leaves.protocol; ++ ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.level.ServerPlayer; ++import net.minecraft.world.food.FoodData; ++import net.minecraft.world.level.GameRules; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++import org.leavesmc.leaves.LeavesConfig; ++import org.leavesmc.leaves.protocol.core.LeavesProtocol; ++import org.leavesmc.leaves.protocol.core.ProtocolHandler; ++import org.leavesmc.leaves.protocol.core.ProtocolUtils; ++ ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++import java.util.Set; ++ ++@LeavesProtocol(namespace = "appleskin") ++public class AppleSkinProtocol { ++ ++ public static final String PROTOCOL_ID = "appleskin"; ++ ++ private static final ResourceLocation SATURATION_KEY = id("saturation"); ++ private static final ResourceLocation EXHAUSTION_KEY = id("exhaustion"); ++ private static final ResourceLocation NATURAL_REGENERATION_KEY = id("natural_regeneration"); ++ ++ private static final float MINIMUM_EXHAUSTION_CHANGE_THRESHOLD = 0.01F; ++ ++ private static final Map previousSaturationLevels = new HashMap<>(); ++ private static final Map previousExhaustionLevels = new HashMap<>(); ++ private static final Map previousNaturalRegeneration = new HashMap<>(); ++ ++ private static final Map> subscribedChannels = new HashMap<>(); ++ ++ @Contract("_ -> new") ++ public static @NotNull ResourceLocation id(String path) { ++ return new ResourceLocation(PROTOCOL_ID, path); ++ } ++ ++ @ProtocolHandler.PlayerJoin ++ public static void onPlayerLoggedIn(@NotNull ServerPlayer player) { ++ if (LeavesConfig.protocol.appleskin.enable) { ++ resetPlayerData(player); ++ } ++ } ++ ++ @ProtocolHandler.PlayerLeave ++ public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { ++ if (LeavesConfig.protocol.appleskin.enable) { ++ subscribedChannels.remove(player); ++ resetPlayerData(player); ++ } ++ } ++ ++ @ProtocolHandler.MinecraftRegister(ignoreId = true) ++ public static void onPlayerSubscribed(@NotNull ServerPlayer player, String channel) { ++ if (LeavesConfig.protocol.appleskin.enable) { ++ subscribedChannels.computeIfAbsent(player, k -> new HashSet<>()).add(channel); ++ } ++ } ++ ++ @ProtocolHandler.Ticker ++ public static void tick() { ++ if (LeavesConfig.protocol.appleskin.enable) { ++ if (MinecraftServer.getServer().getTickCount() % LeavesConfig.protocol.appleskin.syncTickInterval != 0) { ++ return; ++ } ++ ++ for (Map.Entry> entry : subscribedChannels.entrySet()) { ++ ServerPlayer player = entry.getKey(); ++ FoodData data = player.getFoodData(); ++ ++ for (String channel : entry.getValue()) { ++ switch (channel) { ++ case "saturation" -> { ++ float saturation = data.getSaturationLevel(); ++ Float previousSaturation = previousSaturationLevels.get(player); ++ if (previousSaturation == null || saturation != previousSaturation) { ++ ProtocolUtils.sendPayloadPacket(player, SATURATION_KEY, buf -> buf.writeFloat(saturation)); ++ previousSaturationLevels.put(player, saturation); ++ } ++ } ++ ++ case "exhaustion" -> { ++ float exhaustion = data.exhaustionLevel; ++ Float previousExhaustion = previousExhaustionLevels.get(player); ++ if (previousExhaustion == null || Math.abs(exhaustion - previousExhaustion) >= MINIMUM_EXHAUSTION_CHANGE_THRESHOLD) { ++ ProtocolUtils.sendPayloadPacket(player, EXHAUSTION_KEY, buf -> buf.writeFloat(exhaustion)); ++ previousExhaustionLevels.put(player, exhaustion); ++ } ++ } ++ ++ case "natural_regeneration" -> { ++ boolean regeneration = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION); ++ Boolean previousRegeneration = previousNaturalRegeneration.get(player); ++ if (previousRegeneration == null || regeneration != previousRegeneration) { ++ ProtocolUtils.sendPayloadPacket(player, NATURAL_REGENERATION_KEY, buf -> buf.writeBoolean(regeneration)); ++ previousNaturalRegeneration.put(player, regeneration); ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ @ProtocolHandler.ReloadServer ++ public static void onServerReload() { ++ if (!LeavesConfig.protocol.appleskin.enable) { ++ disableAllPlayer(); ++ } ++ } ++ ++ public static void disableAllPlayer() { ++ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) { ++ onPlayerLoggedOut(player); ++ } ++ } ++ ++ private static void resetPlayerData(@NotNull ServerPlayer player) { ++ previousExhaustionLevels.remove(player); ++ previousSaturationLevels.remove(player); ++ previousNaturalRegeneration.remove(player); ++ } ++} diff --git a/patches/server/0045-Xaero-Map-Protocol.patch b/patches/server/0041-Xaero-Map-Protocol.patch similarity index 86% rename from patches/server/0045-Xaero-Map-Protocol.patch rename to patches/server/0041-Xaero-Map-Protocol.patch index adebd201..64559bec 100644 --- a/patches/server/0045-Xaero-Map-Protocol.patch +++ b/patches/server/0041-Xaero-Map-Protocol.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Xaero Map Protocol diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 69323d0889a0c9cd243441c42c8f454457421cfe..e62a27431bb2872bdf7dcc34366249dbfe8add17 100644 +index eb43b1fcda50326f086999a6e134c9807b837045..7a80d3e7d46a9c2a729ca50e2bd265fe5711a23f 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -1289,6 +1289,7 @@ public abstract class PlayerList { +@@ -1256,6 +1256,7 @@ public abstract class PlayerList { player.connection.send(new ClientboundInitializeBorderPacket(worldborder)); player.connection.send(new ClientboundSetTimePacket(world.getGameTime(), world.getDayTime(), world.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); player.connection.send(new ClientboundSetDefaultSpawnPositionPacket(world.getSharedSpawnPos(), world.getSharedSpawnAngle())); @@ -18,7 +18,7 @@ index 69323d0889a0c9cd243441c42c8f454457421cfe..e62a27431bb2872bdf7dcc34366249db // entityplayer.connection.send(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.START_RAINING, 0.0F)); diff --git a/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..14e66b8eb6f2d768e03439df7f4dedc9ba8624dd +index 0000000000000000000000000000000000000000..a94b5174282e0cb520c99a93cae7d3f439cd9cc8 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/XaeroMapProtocol.java @@ -0,0 +1,42 @@ @@ -52,14 +52,14 @@ index 0000000000000000000000000000000000000000..14e66b8eb6f2d768e03439df7f4dedc9 + } + + public static void onSendWorldInfo(@NotNull ServerPlayer player) { -+ if (LeavesConfig.xaeroMapProtocol) { ++ if (LeavesConfig.protocol.xaeroMapProtocol) { + ProtocolUtils.sendPayloadPacket(player, MINIMAP_KEY, buf -> { + buf.writeByte(0); -+ buf.writeInt(LeavesConfig.xaeroMapServerID); ++ buf.writeInt(LeavesConfig.protocol.xaeroMapServerID); + }); + ProtocolUtils.sendPayloadPacket(player, WORLDMAP_KEY, buf -> { + buf.writeByte(0); -+ buf.writeInt(LeavesConfig.xaeroMapServerID); ++ buf.writeInt(LeavesConfig.protocol.xaeroMapServerID); + }); + } + } diff --git a/patches/server/0046-Leaves-Extra-Yggdrasil-Service.patch b/patches/server/0042-Leaves-Extra-Yggdrasil-Service.patch similarity index 93% rename from patches/server/0046-Leaves-Extra-Yggdrasil-Service.patch rename to patches/server/0042-Leaves-Extra-Yggdrasil-Service.patch index f83ed2b7..81a44028 100644 --- a/patches/server/0046-Leaves-Extra-Yggdrasil-Service.patch +++ b/patches/server/0042-Leaves-Extra-Yggdrasil-Service.patch @@ -18,7 +18,7 @@ index 48e774677edf17d4a99ae9ed23d1b371dab41abb..21409ff86db65c00d92bff9eae8bdeb3 public PaperAuthenticationService(Proxy proxy) { super(proxy); diff --git a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java -index bfc1e27c37689c1fbb927404a7176780a439a057..bc8ab50ef1390a2c51110a89dc43db58215396a9 100644 +index 8c3151c25c172b846f0d028b5100718ada2d09d7..d59d05f8894481fb5ebe1aeb8ee7a162b3dc6f1c 100644 --- a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java +++ b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java @@ -46,7 +46,7 @@ import java.util.stream.Collectors; @@ -31,7 +31,7 @@ index bfc1e27c37689c1fbb927404a7176780a439a057..bc8ab50ef1390a2c51110a89dc43db58 private final String baseUrl; private final URL joinUrl; diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java -index 581bd217304e0f9e0b2113c335694805dfb4e2a1..be579118fe33215016b25b144b405d10c7a36fbf 100644 +index 90ca25c4aaf92a5639839a7cdaee2ffcdb75efa7..f0c265a171590bafaed7c87c4f2e64e8e631ea41 100644 --- a/src/main/java/net/minecraft/server/Main.java +++ b/src/main/java/net/minecraft/server/Main.java @@ -191,7 +191,7 @@ public class Main { @@ -44,10 +44,10 @@ index 581bd217304e0f9e0b2113c335694805dfb4e2a1..be579118fe33215016b25b144b405d10 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 0f07ee9d947235fc91f7d450d746f056a9b9e13a..375f4c7fc502902df9defd37409c4b54e643acfe 100644 +index ee43310ce1cd051e45486c4587c5e2aa1d000338..afe3cda698c415079d9f038b452cf594579b4eaf 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -265,7 +265,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop arguments = new HashMap<>(); + arguments.put("username", profileName); + arguments.put("serverId", serverId); @@ -152,7 +152,7 @@ index 0000000000000000000000000000000000000000..b15ee80ac1aea751594cd3321928f26d + } + + GameProfile cache = null; -+ if (LeavesConfig.extraYggdrasilLoginProtect) { ++ if (LeavesConfig.mics.yggdrasil.loginProtect) { + cache = MinecraftServer.getServer().services.profileCache().getProfileIfCached(profileName); + } + @@ -161,7 +161,7 @@ index 0000000000000000000000000000000000000000..b15ee80ac1aea751594cd3321928f26d + try { + final HasJoinedMinecraftServerResponse response = client.get(url, HasJoinedMinecraftServerResponse.class); + if (response != null && response.id() != null) { -+ if (LeavesConfig.extraYggdrasilLoginProtect && cache != null) { ++ if (LeavesConfig.mics.yggdrasil.loginProtect && cache != null) { + if (response.id() != cache.getId()) { + continue; + } diff --git a/patches/server/0047-Use-vanilla-random-config.patch b/patches/server/0043-Use-vanilla-random-config.patch similarity index 70% rename from patches/server/0047-Use-vanilla-random-config.patch rename to patches/server/0043-Use-vanilla-random-config.patch index 77f3ad5f..1fa90581 100644 --- a/patches/server/0047-Use-vanilla-random-config.patch +++ b/patches/server/0043-Use-vanilla-random-config.patch @@ -5,46 +5,46 @@ Subject: [PATCH] Use vanilla random config diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 1beefbd05c13181214e188f50e88fb67f6712a45..012c638335ac54ffe1f780d2cd1e3a50243e33e9 100644 +index 7e61b008c9429f6ef60fcef4887bb50db4face91..b7d5a1f56067c6fec74d653b0da48e9610def283 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -558,7 +558,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -578,7 +578,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.bb = Entity.INITIAL_AABB; this.stuckSpeedMultiplier = Vec3.ZERO; this.nextStep = 1.0F; - this.random = SHARED_RANDOM; // Paper - Share random for entities to make them more random -+ this.random = org.leavesmc.leaves.LeavesConfig.useVanillaRandom ? RandomSource.create() : SHARED_RANDOM; // Paper - Share random for entities to make them more random // Leaves - vanilla plz ++ this.random = org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? RandomSource.create() : SHARED_RANDOM; // Paper - Share random for entities to make them more random // Leaves - vanilla plz this.remainingFireTicks = -this.getFireImmuneTicks(); this.fluidHeight = new Object2DoubleArrayMap(2); this.fluidOnEyes = new HashSet(); 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 1b3978f4ea7e8491e0c0cb6de23c141f44fab414..024ca6a445e5a29fdf5636ff1b4770d4c62f8615 100644 +index 42276acfeadec6e7aa9a91d3f446f4fedb04829d..c2f178d74e61c6d169ccea15ce8d3d0568dbcbe8 100644 --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java -@@ -1029,7 +1029,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -1088,7 +1088,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { BeeGoToHiveGoal() { super(); - this.travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues -+ this.travellingTicks = org.leavesmc.leaves.LeavesConfig.useVanillaRandom ? Bee.this.level().random.nextInt(10) : Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues // Leaves - why no vanilla ++ this.travellingTicks = org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? Bee.this.level().random.nextInt(10) : Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues // Leaves - why no vanilla this.blacklistedTargets = Lists.newArrayList(); this.setFlags(EnumSet.of(Goal.Flag.MOVE)); } 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 42f4e544fe7fbc342f15eacb5e38d40849e3c419..0bd9ee3d0b546564a069f4aaf7a33e35bfa13ad8 100644 +index f9fdc600dc680c55219fcbf9bc8f151a733a093c..ff9e8f501a537d005aba63737303177ca6882760 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); - //this.random.setSeed((long)this.getId()); // Paper - Share random for entities to make them more random -+ if (org.leavesmc.leaves.LeavesConfig.useVanillaRandom) this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random // Leaves - vanilla plz ++ if (org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom) this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random // Leaves - vanilla plz this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F; } 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 929a9bee808e8216dacb74dc58dbeee612126afe..9205d565f375a8177c6bc0c19e1f594d1d8cd0ed 100644 +index 8f2ca7211d4ebf494beae85caea5876fad4723eb..9e8a40f51337822ac55b5020778076c7466f5ef3 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java @@ -79,7 +79,13 @@ public class ItemEntity extends Entity implements TraceableEntity { @@ -53,7 +53,7 @@ index 929a9bee808e8216dacb74dc58dbeee612126afe..9205d565f375a8177c6bc0c19e1f594d this.setPos(x, y, z); - this.setDeltaMovement(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D); + // Leaves start - vanilla yes, paper no -+ if (org.leavesmc.leaves.LeavesConfig.useVanillaRandom) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom) { + this.setDeltaMovement(world.random.nextDouble() * 0.2D - 0.1D, 0.2D, world.random.nextDouble() * 0.2D - 0.1D); + } else { + this.setDeltaMovement(this.random.nextDouble() * 0.2D - 0.1D, 0.2D, this.random.nextDouble() * 0.2D - 0.1D); @@ -63,15 +63,15 @@ index 929a9bee808e8216dacb74dc58dbeee612126afe..9205d565f375a8177c6bc0c19e1f594d // Paper end - Don't use level random in entity constructors } 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 8d494b549abb452bb554220060cc9c5beec5edf6..ac05fe9a17f67a4cb12cdb9c381896d7bb0b3f6a 100644 +index 34b9384c0f852d28dc8b834a40785ede74b33cfd..aa4179781fc67e7e4194cfac795aa2a84abe616b 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); - double d3 = this.random.nextDouble() * 6.2831854820251465D; // Paper - Don't use level random in entity constructors -+ double d3 = (org.leavesmc.leaves.LeavesConfig.useVanillaRandom ? world.random.nextDouble() : this.random.nextDouble()) * 6.2831854820251465D; // Paper - Don't use level random in entity constructors // Leaves - why? ++ double d3 = (org.leavesmc.leaves.LeavesConfig.modify.useVanillaRandom ? world.random.nextDouble() : this.random.nextDouble()) * 6.2831854820251465D; // Paper - Don't use level random in entity constructors // Leaves - why? this.setDeltaMovement(-Math.sin(d3) * 0.02D, 0.20000000298023224D, -Math.cos(d3) * 0.02D); this.setFuse(80); diff --git a/patches/server/0044-Appleskin-Protocol.patch b/patches/server/0044-Appleskin-Protocol.patch deleted file mode 100644 index 687a20f4..00000000 --- a/patches/server/0044-Appleskin-Protocol.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Wed, 25 Jan 2023 11:03:53 +0800 -Subject: [PATCH] Appleskin Protocol - - -diff --git a/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java -new file mode 100644 -index 0000000000000000000000000000000000000000..6662ecf8a9342db2e0ded507d7420319388f9974 ---- /dev/null -+++ b/src/main/java/org/leavesmc/leaves/protocol/AppleSkinProtocol.java -@@ -0,0 +1,106 @@ -+package org.leavesmc.leaves.protocol; -+ -+import net.minecraft.resources.ResourceLocation; -+import net.minecraft.server.MinecraftServer; -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.food.FoodData; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; -+import org.leavesmc.leaves.LeavesConfig; -+import org.leavesmc.leaves.protocol.core.LeavesProtocol; -+import org.leavesmc.leaves.protocol.core.ProtocolHandler; -+import org.leavesmc.leaves.protocol.core.ProtocolUtils; -+ -+import java.util.HashMap; -+import java.util.HashSet; -+import java.util.Map; -+import java.util.Set; -+import java.util.UUID; -+ -+@LeavesProtocol(namespace = "appleskin") -+public class AppleSkinProtocol { -+ -+ public static final String PROTOCOL_ID = "appleskin"; -+ -+ private static final ResourceLocation SATURATION_KEY = id("saturation_sync"); -+ private static final ResourceLocation EXHAUSTION_KEY = id("exhaustion_sync"); -+ -+ private static final Map previousSaturationLevels = new HashMap<>(); -+ private static final Map previousExhaustionLevels = new HashMap<>(); -+ -+ private static final float MINIMUM_EXHAUSTION_CHANGE_THRESHOLD = 0.01F; -+ -+ private static final Set players = new HashSet<>(); -+ -+ @Contract("_ -> new") -+ public static @NotNull ResourceLocation id(String path) { -+ return new ResourceLocation(PROTOCOL_ID, path); -+ } -+ -+ @ProtocolHandler.PlayerJoin -+ public static void onPlayerLoggedIn(@NotNull ServerPlayer player) { -+ if (LeavesConfig.appleskinProtocol) { -+ resetPlayerData(player); -+ } -+ } -+ -+ @ProtocolHandler.PlayerLeave -+ public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { -+ if (LeavesConfig.appleskinProtocol) { -+ players.remove(player); -+ resetPlayerData(player); -+ } -+ } -+ -+ @ProtocolHandler.MinecraftRegister(ignoreId = true) -+ public static void onPlayerSubscribed(@NotNull ServerPlayer player) { -+ if (LeavesConfig.appleskinProtocol) { -+ players.add(player); -+ } -+ } -+ -+ @ProtocolHandler.Ticker -+ public static void tick() { -+ if (LeavesConfig.appleskinProtocol) { -+ for (ServerPlayer player : players) { -+ FoodData data = player.getFoodData(); -+ -+ float saturation = data.getSaturationLevel(); -+ Float previousSaturation = previousSaturationLevels.get(player.getUUID()); -+ if (previousSaturation == null || saturation != previousSaturation) { -+ ProtocolUtils.sendPayloadPacket(player, SATURATION_KEY, buf -> { -+ buf.writeFloat(saturation); -+ }); -+ previousSaturationLevels.put(player.getUUID(), saturation); -+ } -+ -+ float exhaustion = data.getExhaustionLevel(); -+ Float previousExhaustion = previousExhaustionLevels.get(player.getUUID()); -+ if (previousExhaustion == null || Math.abs(exhaustion - previousExhaustion) >= MINIMUM_EXHAUSTION_CHANGE_THRESHOLD) { -+ ProtocolUtils.sendPayloadPacket(player, EXHAUSTION_KEY, buf -> { -+ buf.writeFloat(exhaustion); -+ }); -+ previousExhaustionLevels.put(player.getUUID(), exhaustion); -+ } -+ } -+ } -+ } -+ -+ @ProtocolHandler.ReloadServer -+ public static void onServerReload() { -+ if (!LeavesConfig.appleskinProtocol) { -+ disableAllPlayer(); -+ } -+ } -+ -+ public static void disableAllPlayer() { -+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) { -+ onPlayerLoggedOut(player); -+ } -+ } -+ -+ private static void resetPlayerData(@NotNull ServerPlayer player) { -+ previousExhaustionLevels.remove(player.getUUID()); -+ previousSaturationLevels.remove(player.getUUID()); -+ } -+} diff --git a/patches/server/0048-Fix-update-suppression-crash.patch b/patches/server/0044-Fix-update-suppression-crash.patch similarity index 77% rename from patches/server/0048-Fix-update-suppression-crash.patch rename to patches/server/0044-Fix-update-suppression-crash.patch index 9f4501c0..8ef5ba51 100644 --- a/patches/server/0048-Fix-update-suppression-crash.patch +++ b/patches/server/0044-Fix-update-suppression-crash.patch @@ -20,11 +20,11 @@ index 1f7f68aad97ee73763c042837f239bdc7167db55..1e8025ecb14acc7c24917793c97f5435 if (exception instanceof ReportedException) { ReportedException reportedexception = (ReportedException) exception; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index bf1bb8fa681360c3b634bcd6d8979cc2c5137957..236ad5ac3f4665ff940c6505ca1d01c6ace7f316 100644 +index 10108b66622128c90be01d5fa83c8dca6647c354..0badf81ac6c141b8736758eef1e93af9baf66d33 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1787,7 +1787,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop map = pistonCache.get(level); + + boolean flag = map != null && map.get(bedrock) != null; @@ -164,7 +164,7 @@ index 0000000000000000000000000000000000000000..1c5992f1480a25dbd5967218be2a3a21 + } + + public static void onScoreboardAdd(@NotNull Objective objective) { -+ if (LeavesConfig.bedrockBreakList) { ++ if (LeavesConfig.modify.bedrockBreakList) { + if (objective.getCriteria() == ObjectiveCriteria.DUMMY) { + String name = objective.getName(); + @@ -182,7 +182,7 @@ index 0000000000000000000000000000000000000000..1c5992f1480a25dbd5967218be2a3a21 + } + + public static void onScoreboardRemove(@NotNull Objective objective) { -+ if (LeavesConfig.bedrockBreakList) { ++ if (LeavesConfig.modify.bedrockBreakList) { + if (objective.getCriteria() == ObjectiveCriteria.DUMMY) { + String name = objective.getName(); + diff --git a/patches/server/0050-Fix-trapdoor-feature.patch b/patches/server/0046-Fix-trapdoor-feature.patch similarity index 86% rename from patches/server/0050-Fix-trapdoor-feature.patch rename to patches/server/0046-Fix-trapdoor-feature.patch index e1de062e..82882bca 100644 --- a/patches/server/0050-Fix-trapdoor-feature.patch +++ b/patches/server/0046-Fix-trapdoor-feature.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix trapdoor feature 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 336fcf4af0ffb416b5595a9e65172f36cc36aaa3..b6c8c4af91f9ca2288e97b9402ec88d56385e75d 100644 +index 872e52e13293a99d45f93d90d8fa7f6aa99d1f3a..2b57a82eeb98fffc47f37d073f7934e26a1a6221 100644 --- a/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TrapDoorBlock.java -@@ -153,6 +153,8 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW +@@ -157,6 +157,8 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW flag1 = eventRedstone.getNewCurrent() > 0; } // CraftBukkit end @@ -17,7 +17,7 @@ index 336fcf4af0ffb416b5595a9e65172f36cc36aaa3..b6c8c4af91f9ca2288e97b9402ec88d5 // Paper start - break redstone on trapdoors early boolean open = (Boolean) state.getValue(TrapDoorBlock.OPEN) != flag1; // note: this must run before any state for this block/its neighborus are written to the world -@@ -173,6 +175,9 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW +@@ -177,6 +179,9 @@ public class TrapDoorBlock extends HorizontalDirectionalBlock implements SimpleW } if (open) { // Paper end - break redstone on trapdoors early diff --git a/patches/server/0051-Disable-distance-check-for-UseItemOnPacket.patch b/patches/server/0047-Disable-distance-check-for-UseItemOnPacket.patch similarity index 73% rename from patches/server/0051-Disable-distance-check-for-UseItemOnPacket.patch rename to patches/server/0047-Disable-distance-check-for-UseItemOnPacket.patch index 973074b2..81acf322 100644 --- a/patches/server/0051-Disable-distance-check-for-UseItemOnPacket.patch +++ b/patches/server/0047-Disable-distance-check-for-UseItemOnPacket.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Disable distance check for UseItemOnPacket diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index af8a2b3b37aba58cb402040e178c46f53aa3e93d..faa8309eb3eed72cdd459a22f69046d06c0060ba 100644 +index 43cfe5e00285bf88d0724d27e55d28c2f825f741..c88cb9c1c7f588b2617a71ecd6acbcf98ade5687 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -1931,7 +1931,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -1945,7 +1945,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Vec3 vec3d1 = vec3d.subtract(Vec3.atCenterOf(blockposition)); double d0 = 1.0000001D; - if (Math.abs(vec3d1.x()) < 1.0000001D && Math.abs(vec3d1.y()) < 1.0000001D && Math.abs(vec3d1.z()) < 1.0000001D) { -+ if (org.leavesmc.leaves.LeavesConfig.disableDistanceCheckForUseItem || (Math.abs(vec3d1.x()) < 1.0000001D && Math.abs(vec3d1.y()) < 1.0000001D && Math.abs(vec3d1.z()) < 1.0000001D)) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.disableDistanceCheckForUseItem || (Math.abs(vec3d1.x()) < 1.0000001D && Math.abs(vec3d1.y()) < 1.0000001D && Math.abs(vec3d1.z()) < 1.0000001D)) { Direction enumdirection = movingobjectpositionblock.getDirection(); this.player.resetLastActionTime(); diff --git a/patches/server/0048-No-feather-falling-trample.patch b/patches/server/0048-No-feather-falling-trample.patch new file mode 100644 index 00000000..48708e8c --- /dev/null +++ b/patches/server/0048-No-feather-falling-trample.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Thu, 25 May 2023 16:37:06 +0800 +Subject: [PATCH] No feather falling trample + + +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 c3dba0c2c94f3804338f86621dc42405e380a6b3..b3de7e10a5514100712998519a7e9303b347d6a8 100644 +--- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java +@@ -113,6 +113,13 @@ public class FarmBlock extends Block { + super.fallOn(world, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. + if (world instanceof ServerLevel worldserver) { + if (world.random.nextFloat() < fallDistance - 0.5F && entity instanceof LivingEntity && (entity instanceof Player || worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { ++ // Leaves start - noFeatherFallingTrample ++ if (org.leavesmc.leaves.LeavesConfig.modify.noFeatherFallingTrample) { ++ if (net.minecraft.world.item.enchantment.EnchantmentHelper.getEnchantmentLevel(world.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getOrThrow(net.minecraft.world.item.enchantment.Enchantments.FEATHER_FALLING), (LivingEntity) entity) > 0) { ++ return; ++ } ++ } ++ // Leaves end - noFeatherFallingTrample + // CraftBukkit start - Interact soil + org.bukkit.event.Cancellable cancellable; + if (entity instanceof Player) { diff --git a/patches/server/0053-Syncmatica-Protocol.patch b/patches/server/0049-Syncmatica-Protocol.patch similarity index 99% rename from patches/server/0053-Syncmatica-Protocol.patch rename to patches/server/0049-Syncmatica-Protocol.patch index b1518606..fd2b3d24 100644 --- a/patches/server/0053-Syncmatica-Protocol.patch +++ b/patches/server/0049-Syncmatica-Protocol.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Syncmatica Protocol This patch is Powered by Syncmatica(https://github.com/End-Tech/syncmatica) diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 1e71c352529afaa73cef3b9ea08098d9a86f6589..f893f841509017d61b496e712c12b578d4d69345 100644 +index c88cb9c1c7f588b2617a71ecd6acbcf98ade5687..58b260c37393eebc9fe838ab801287573c04cfde 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -314,6 +314,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -324,6 +324,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl Objects.requireNonNull(server); this.signedMessageDecoder = SignedMessageChain.Decoder.unsigned(uuid, server::enforceSecureProfile); this.chatMessageChain = new FutureChain(server.chatExecutor); // CraftBukkit - async chat @@ -17,7 +17,7 @@ index 1e71c352529afaa73cef3b9ea08098d9a86f6589..f893f841509017d61b496e712c12b578 } // CraftBukkit start - add fields and methods -@@ -332,6 +333,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -342,6 +343,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl private boolean justTeleported = false; // CraftBukkit end @@ -28,7 +28,7 @@ index 1e71c352529afaa73cef3b9ea08098d9a86f6589..f893f841509017d61b496e712c12b578 if (this.ackBlockChangesUpTo > -1) { diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java new file mode 100644 -index 0000000000000000000000000000000000000000..c452bb80f8a51a11b9d4eca53fc6d977b35ae2ef +index 0000000000000000000000000000000000000000..365b07d8d9741d07bf4505d121394dd053825c76 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/CommunicationManager.java @@ -0,0 +1,396 @@ @@ -100,7 +100,7 @@ index 0000000000000000000000000000000000000000..c452bb80f8a51a11b9d4eca53fc6d977 + + @ProtocolHandler.PlayerJoin + public static void onPlayerJoin(ServerPlayer player) { -+ if (!LeavesConfig.syncmaticaProtocol) { ++ if (!LeavesConfig.protocol.syncmatica.enable) { + return; + } + final ExchangeTarget newPlayer = player.connection.exchangeTarget; @@ -113,7 +113,7 @@ index 0000000000000000000000000000000000000000..c452bb80f8a51a11b9d4eca53fc6d977 + + @ProtocolHandler.PlayerLeave + public static void onPlayerLeave(ServerPlayer player) { -+ if (!LeavesConfig.syncmaticaProtocol) { ++ if (!LeavesConfig.protocol.syncmatica.enable) { + return; + } + final ExchangeTarget oldPlayer = player.connection.exchangeTarget; @@ -130,7 +130,7 @@ index 0000000000000000000000000000000000000000..c452bb80f8a51a11b9d4eca53fc6d977 + + @ProtocolHandler.PayloadReceiver(payload = SyncmaticaPayload.class, payloadId = "main") + public static void onPacketGet(ServerPlayer player, SyncmaticaPayload payload) { -+ if (!LeavesConfig.syncmaticaProtocol) { ++ if (!LeavesConfig.protocol.syncmatica.enable) { + return; + } + onPacket(player.connection.exchangeTarget, payload.packetType(), payload.data()); @@ -1335,7 +1335,7 @@ index 0000000000000000000000000000000000000000..d7a3c85df0f5950f3f0c69c33fa5d809 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..0d93792de3a12a450f5da1705cff95274360a9c4 +index 0000000000000000000000000000000000000000..055da1928daddedaa72e8d805193f81e4aaafdea --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/syncmatica/SyncmaticaProtocol.java @@ -0,0 +1,127 @@ @@ -1438,7 +1438,7 @@ index 0000000000000000000000000000000000000000..0d93792de3a12a450f5da1705cff9527 + } + + public static boolean isOverQuota(int sent) { -+ return LeavesConfig.syncmaticaQuota && sent > LeavesConfig.syncmaticaQuotaLimit; ++ return LeavesConfig.protocol.syncmatica.useQuota && sent > LeavesConfig.protocol.syncmatica.quotaLimit; + } + + public static void backupAndReplace(final Path backup, final Path current, final Path incoming) { diff --git a/patches/server/0054-Shared-villager-discounts.patch b/patches/server/0050-Shared-villager-discounts.patch similarity index 86% rename from patches/server/0054-Shared-villager-discounts.patch rename to patches/server/0050-Shared-villager-discounts.patch index 49a4445a..7a058f64 100644 --- a/patches/server/0054-Shared-villager-discounts.patch +++ b/patches/server/0050-Shared-villager-discounts.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Shared villager discounts diff --git a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java -index c7f012674361a323c1efeca4660cd3f46d308ee1..cea09319941f39dbb958ea7ee78c52c7f34fad9e 100644 +index c7f012674361a323c1efeca4660cd3f46d308ee1..c211b62fd753adad649c084fe791918c8c620c04 100644 --- a/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java +++ b/src/main/java/net/minecraft/world/entity/ai/gossip/GossipContainer.java @@ -115,6 +115,16 @@ public class GossipContainer { @@ -13,7 +13,7 @@ index c7f012674361a323c1efeca4660cd3f46d308ee1..cea09319941f39dbb958ea7ee78c52c7 public int getReputation(UUID target, Predicate gossipTypeFilter) { GossipContainer.EntityGossips entityGossips = this.gossips.get(target); + // Leaves start - sharedVillagerDiscounts -+ if (org.leavesmc.leaves.LeavesConfig.sharedVillagerDiscounts && gossipTypeFilter.test(GossipType.MAJOR_POSITIVE)) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.sharedVillagerDiscounts && gossipTypeFilter.test(GossipType.MAJOR_POSITIVE)) { + int otherRep = 0; + if (entityGossips != null) { + otherRep = entityGossips.weightedValue(v -> gossipTypeFilter.test(v) && !v.equals(GossipType.MAJOR_POSITIVE)); diff --git a/patches/server/0051-Redstone-wire-dont-connect-if-on-trapdoor.patch b/patches/server/0051-Redstone-wire-dont-connect-if-on-trapdoor.patch new file mode 100644 index 00000000..24f7d0fc --- /dev/null +++ b/patches/server/0051-Redstone-wire-dont-connect-if-on-trapdoor.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Wed, 14 Jun 2023 12:07:07 +0800 +Subject: [PATCH] Redstone wire dont connect if on trapdoor + + +diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java +index 09b8f5335cb7651d90f4d1ca61b2ec5aa324e443..22b4abfdda9df1003dc57696d0b7524db442de88 100644 +--- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java +@@ -204,7 +204,7 @@ public class RedStoneWireBlock extends Block { + RandomSource random + ) { + if (direction == Direction.DOWN) { +- return !this.canSurviveOn(world, neighborPos, neighborState) ? Blocks.AIR.defaultBlockState() : state; ++ return org.leavesmc.leaves.LeavesConfig.modify.oldMC.updater.redstoneDontCantOnTrapDoor ? state : !this.canSurviveOn(world, neighborPos, neighborState) ? Blocks.AIR.defaultBlockState() : state; // Leaves - behavior to 1.19 + } else if (direction == Direction.UP) { + return this.getConnectionState(world, state, pos); + } else { +@@ -263,7 +263,7 @@ public class RedStoneWireBlock extends Block { + BlockPos blockPos = pos.relative(direction); + BlockState blockState = world.getBlockState(blockPos); + if (bl) { +- boolean bl2 = blockState.getBlock() instanceof TrapDoorBlock || this.canSurviveOn(world, blockPos, blockState); ++ boolean bl2 = (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.updater.redstoneDontCantOnTrapDoor && blockState.getBlock() instanceof TrapDoorBlock) || this.canSurviveOn(world, blockPos, blockState); // Leaves - behavior to 1.19 + if (bl2 && shouldConnectTo(world.getBlockState(blockPos.above()))) { + if (blockState.isFaceSturdy(world, blockPos, direction.getOpposite())) { + return RedstoneSide.UP; diff --git a/patches/server/0056-Disable-check-out-of-order-command.patch b/patches/server/0052-Disable-check-out-of-order-command.patch similarity index 83% rename from patches/server/0056-Disable-check-out-of-order-command.patch rename to patches/server/0052-Disable-check-out-of-order-command.patch index 8c25354a..2290d0be 100644 --- a/patches/server/0056-Disable-check-out-of-order-command.patch +++ b/patches/server/0052-Disable-check-out-of-order-command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Disable check out-of-order command diff --git a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java -index 300929a406905f5ff1ede664d5b99fb0938d4d2e..82d7c376a0a71075f7a013518e284bfe3789f329 100644 +index 300929a406905f5ff1ede664d5b99fb0938d4d2e..48ffdcc799999f1d5f76e0bf124efc44c1aec3f8 100644 --- a/src/main/java/net/minecraft/network/chat/SignedMessageChain.java +++ b/src/main/java/net/minecraft/network/chat/SignedMessageChain.java @@ -45,7 +45,7 @@ public class SignedMessageChain { @@ -13,7 +13,7 @@ index 300929a406905f5ff1ede664d5b99fb0938d4d2e..82d7c376a0a71075f7a013518e284bfe if (signedMessageLink == null) { throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.CHAIN_BROKEN); - } else if (body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { -+ } else if (!org.leavesmc.leaves.LeavesConfig.disableCheckOutOfOrderCommand && body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { // Leaves - disable check to support Velocity ++ } else if (!org.leavesmc.leaves.LeavesConfig.modify.disableCheckOutOfOrderCommand && body.timeStamp().isBefore(SignedMessageChain.this.lastTimeStamp)) { // Leaves - disable check to support Velocity this.setChainBroken(); throw new SignedMessageChain.DecodeException(SignedMessageChain.DecodeException.OUT_OF_ORDER_CHAT, org.bukkit.event.player.PlayerKickEvent.Cause.OUT_OF_ORDER_CHAT); // Paper - kick event causes } else { diff --git a/patches/server/0052-No-feather-falling-trample.patch b/patches/server/0052-No-feather-falling-trample.patch deleted file mode 100644 index 43d00b55..00000000 --- a/patches/server/0052-No-feather-falling-trample.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Thu, 25 May 2023 16:37:06 +0800 -Subject: [PATCH] No feather falling trample - - -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 d59e33e7326489c6d55d316d0130f22235f4c63c..e48b1b7dbfb5d6914420bce0565108c34342922b 100644 ---- a/src/main/java/net/minecraft/world/level/block/FarmBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/FarmBlock.java -@@ -112,6 +112,13 @@ public class FarmBlock extends Block { - public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { - super.fallOn(world, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. - if (!world.isClientSide && world.random.nextFloat() < fallDistance - 0.5F && entity instanceof LivingEntity && (entity instanceof Player || world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { -+ // Leaves start - noFeatherFallingTrample -+ if (org.leavesmc.leaves.LeavesConfig.noFeatherFallingTrample) { -+ if (net.minecraft.world.item.enchantment.EnchantmentHelper.getEnchantmentLevel(world.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getHolder(net.minecraft.world.item.enchantment.Enchantments.FEATHER_FALLING).get(), (LivingEntity) entity) > 0) { -+ return; -+ } -+ } -+ // Leaves end - noFeatherFallingTrample - // CraftBukkit start - Interact soil - org.bukkit.event.Cancellable cancellable; - if (entity instanceof Player) { diff --git a/patches/server/0057-Despawn-enderman-with-block.patch b/patches/server/0053-Despawn-enderman-with-block.patch similarity index 73% rename from patches/server/0057-Despawn-enderman-with-block.patch rename to patches/server/0053-Despawn-enderman-with-block.patch index 2f87917a..41a99ec0 100644 --- a/patches/server/0057-Despawn-enderman-with-block.patch +++ b/patches/server/0053-Despawn-enderman-with-block.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Despawn enderman with block 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 17a71bb3b65cc1030b70c931b1dc998d06713231..2a26fb795ca8d71f02d7d991dd28c34118266f02 100644 +index 2b8e1a8e233071821411eb1f95c705efb4a6e816..e7a004ab26bd73a264bc7c911f99107c57661367 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java +++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java -@@ -471,7 +471,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -458,7 +458,7 @@ public class EnderMan extends Monster implements NeutralMob { @Override public boolean requiresCustomPersistence() { - return super.requiresCustomPersistence() || this.getCarriedBlock() != null; -+ return super.requiresCustomPersistence() || (!org.leavesmc.leaves.LeavesConfig.despawnEndermanWithBlock && this.getCarriedBlock() != null); // Leaves - despawn enderman with block ++ return super.requiresCustomPersistence() || (!org.leavesmc.leaves.LeavesConfig.modify.despawnEndermanWithBlock && this.getCarriedBlock() != null); // Leaves - despawn enderman with block } private static class EndermanFreezeWhenLookedAt extends Goal { diff --git a/patches/server/0058-Leaves-carpet-support.patch b/patches/server/0054-Leaves-carpet-support.patch similarity index 95% rename from patches/server/0058-Leaves-carpet-support.patch rename to patches/server/0054-Leaves-carpet-support.patch index da35798c..0a5140e1 100644 --- a/patches/server/0058-Leaves-carpet-support.patch +++ b/patches/server/0054-Leaves-carpet-support.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Leaves carpet support diff --git a/src/main/java/org/leavesmc/leaves/protocol/CarpetServerProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/CarpetServerProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..3b6801435790fd892ece3ba7d89499eec29626ff +index 0000000000000000000000000000000000000000..b68179532ceace257968b8fd7776608ab0bb798d --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/CarpetServerProtocol.java @@ -0,0 +1,120 @@ @@ -47,7 +47,7 @@ index 0000000000000000000000000000000000000000..3b6801435790fd892ece3ba7d89499ee + + @ProtocolHandler.PlayerJoin + public static void onPlayerJoin(ServerPlayer player) { -+ if (LeavesConfig.leavesCarpetSupport) { ++ if (LeavesConfig.protocol.leavesCarpetSupport) { + CompoundTag data = new CompoundTag(); + data.putString(HI, VERSION); + ProtocolUtils.sendPayloadPacket(player, new CarpetPayload(data)); @@ -56,7 +56,7 @@ index 0000000000000000000000000000000000000000..3b6801435790fd892ece3ba7d89499ee + + @ProtocolHandler.PayloadReceiver(payload = CarpetPayload.class, payloadId = "hello") + private static void handleHello(@NotNull ServerPlayer player, @NotNull CarpetServerProtocol.CarpetPayload payload) { -+ if (LeavesConfig.leavesCarpetSupport) { ++ if (LeavesConfig.protocol.leavesCarpetSupport) { + if (payload.nbt.contains(HELLO)) { + LeavesLogger.LOGGER.info("Player " + player.getScoreboardName() + " joined with carpet " + payload.nbt.getString(HELLO)); + CompoundTag data = new CompoundTag(); diff --git a/patches/server/0059-Creative-fly-no-clip.patch b/patches/server/0055-Creative-fly-no-clip.patch similarity index 86% rename from patches/server/0059-Creative-fly-no-clip.patch rename to patches/server/0055-Creative-fly-no-clip.patch index 14190be3..66b30f62 100644 --- a/patches/server/0059-Creative-fly-no-clip.patch +++ b/patches/server/0055-Creative-fly-no-clip.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Creative fly no clip 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 65b002f2ae062327f48df0e157aa35721478c5fd..a570e9ef4b2b767af3ebb2b33230eb7877553a85 100644 +index c7bc8f493305cca9bac60c79e4e35cf5e369d355..e4bb0b2eb8512f75042dab77bb79b4f51742ab4e 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -252,8 +252,8 @@ public abstract class Player extends LivingEntity { @@ -19,7 +19,7 @@ index 65b002f2ae062327f48df0e157aa35721478c5fd..a570e9ef4b2b767af3ebb2b33230eb78 this.setOnGround(false); } -@@ -442,7 +442,7 @@ public abstract class Player extends LivingEntity { +@@ -476,7 +476,7 @@ public abstract class Player extends LivingEntity { Pose entitypose1; @@ -28,7 +28,7 @@ index 65b002f2ae062327f48df0e157aa35721478c5fd..a570e9ef4b2b767af3ebb2b33230eb78 if (this.canPlayerFitWithinBlocksAndEntitiesWhen(Pose.CROUCHING)) { entitypose1 = Pose.CROUCHING; } else { -@@ -588,7 +588,7 @@ public abstract class Player extends LivingEntity { +@@ -612,7 +612,7 @@ public abstract class Player extends LivingEntity { } this.bob += (f - this.bob) * 0.4F; @@ -37,13 +37,13 @@ index 65b002f2ae062327f48df0e157aa35721478c5fd..a570e9ef4b2b767af3ebb2b33230eb78 AABB axisalignedbb; if (this.isPassenger() && !this.getVehicle().isRemoved()) { -@@ -2119,6 +2119,21 @@ public abstract class Player extends LivingEntity { +@@ -2058,6 +2058,21 @@ public abstract class Player extends LivingEntity { @Override public abstract boolean isSpectator(); + // Leaves start - creative no clip + public boolean isCreativeFlyOrSpectator() { -+ return isSpectator() || (org.leavesmc.leaves.LeavesConfig.creativeNoClip && isCreative() && getAbilities().flying); ++ return isSpectator() || (org.leavesmc.leaves.LeavesConfig.modify.creativeNoClip && isCreative() && getAbilities().flying); + } + + public boolean canSpectatingPlace(Level world, BlockState state, BlockPos pos, net.minecraft.world.phys.shapes.CollisionContext context) { @@ -60,20 +60,20 @@ index 65b002f2ae062327f48df0e157aa35721478c5fd..a570e9ef4b2b767af3ebb2b33230eb78 public boolean canBeHitByProjectile() { return !this.isSpectator() && super.canBeHitByProjectile(); diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java -index 2759a9eeef85b323b7e1ea78090f4f9d637c938a..4b044d76e803027bfc2df7dab9878eca01e62f5a 100644 +index 77309808abd4ab476e815d60015ad828102a1f6b..b101113c67bee1fb1732c49a32a813736f4c7c18 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java -@@ -223,7 +223,7 @@ public class BlockItem extends Item { +@@ -217,7 +217,7 @@ public class BlockItem extends Item { CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of(entityhuman); // CraftBukkit start - store default return Level world = context.getLevel(); // Paper - Cancel hit for vanished players - boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper - Cancel hit for vanished players -+ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && (org.leavesmc.leaves.LeavesConfig.creativeNoClip && context.getPlayer() != null ? context.getPlayer().canSpectatingPlace(world, state, context.getClickedPos(), voxelshapecollision) : world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true)); // Paper - Cancel hit for vanished players // Leaves - creative no clip ++ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && (org.leavesmc.leaves.LeavesConfig.modify.creativeNoClip && context.getPlayer() != null ? context.getPlayer().canSpectatingPlace(world, state, context.getClickedPos(), voxelshapecollision) : world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true)); // Paper - Cancel hit for vanished players // Leaves - creative no clip org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null; BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent diff --git a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java -index 0b761f3ae15ad4a3b8152f497a60403212109534..fdb2bb8a5e6c5d69692804adb086a2d476d558cd 100644 +index 4390adf843b395db688017eb9034b56a40971473..5527ebdffb09d2d75275c73481f2f2af702222f6 100644 --- a/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java +++ b/src/main/java/net/minecraft/world/item/StandingAndWallBlockItem.java @@ -56,7 +56,7 @@ public class StandingAndWallBlockItem extends BlockItem { @@ -86,7 +86,7 @@ index 0b761f3ae15ad4a3b8152f497a60403212109534..fdb2bb8a5e6c5d69692804adb086a2d4 BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(world, blockposition), player, CraftBlockData.fromData(iblockdata1), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java -index 5b62860cd64b5e6dc02dadb4651824ac04b00024..6c23de5ebcfaf378b1ab97689e50add07d37ff03 100644 +index 3784e4c14bb59073f941b966f616ddac3f80a497..afd84141d1d6dcdba307cfd9663657c09c0728bd 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java +++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java @@ -163,7 +163,7 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl @@ -99,10 +99,10 @@ index 5b62860cd64b5e6dc02dadb4651824ac04b00024..6c23de5ebcfaf378b1ab97689e50add0 } } 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 b35f476e26a020cf75e53a5eb488717d996a6935..73651a8ae9341807ec96300914d49329fb8a4e90 100644 +index e1c9a961064887070b29207efd7af47884f8dc29..13f0a27f493754e707e8008ebed5ca14c68e31fc 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 -@@ -147,7 +147,7 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -148,7 +148,7 @@ public class PistonMovingBlockEntity extends BlockEntity { h = (double)direction.getStepZ(); } @@ -111,7 +111,7 @@ index b35f476e26a020cf75e53a5eb488717d996a6935..73651a8ae9341807ec96300914d49329 // Paper - EAR items stuck in in slime pushed by a piston entity.activatedTick = Math.max(entity.activatedTick, net.minecraft.server.MinecraftServer.currentTick + 10); entity.activatedImmunityTick = Math.max(entity.activatedImmunityTick, net.minecraft.server.MinecraftServer.currentTick + 10); -@@ -183,6 +183,7 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -184,6 +184,7 @@ public class PistonMovingBlockEntity extends BlockEntity { } private static void moveEntityByPiston(Direction direction, Entity entity, double distance, Direction movementDirection) { diff --git a/patches/server/0055-Redstone-wire-dont-connect-if-on-trapdoor.patch b/patches/server/0055-Redstone-wire-dont-connect-if-on-trapdoor.patch deleted file mode 100644 index 9a3a0d9b..00000000 --- a/patches/server/0055-Redstone-wire-dont-connect-if-on-trapdoor.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Wed, 14 Jun 2023 12:07:07 +0800 -Subject: [PATCH] Redstone wire dont connect if on trapdoor - - -diff --git a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java -index c131734cad123a35456d18f8a161f77a4ac9ac99..067aaa8cea1534f8b87159ad161917e81a258dac 100644 ---- a/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/RedStoneWireBlock.java -@@ -173,7 +173,7 @@ public class RedStoneWireBlock extends Block { - @Override - protected BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) { - if (direction == Direction.DOWN) { -- return !this.canSurviveOn(world, neighborPos, neighborState) ? Blocks.AIR.defaultBlockState() : state; -+ return org.leavesmc.leaves.LeavesConfig.redstoneDontCantOnTrapDoor ? state : !this.canSurviveOn(world, neighborPos, neighborState) ? Blocks.AIR.defaultBlockState() : state; // Leaves - behavior to 1.19 - } else if (direction == Direction.UP) { - return this.getConnectionState(world, state, pos); - } else { -@@ -232,7 +232,7 @@ public class RedStoneWireBlock extends Block { - BlockState iblockdata = world.getBlockState(blockposition1); - - if (flag) { -- boolean flag1 = iblockdata.getBlock() instanceof TrapDoorBlock || this.canSurviveOn(world, blockposition1, iblockdata); -+ boolean flag1 = (!org.leavesmc.leaves.LeavesConfig.redstoneDontCantOnTrapDoor && iblockdata.getBlock() instanceof TrapDoorBlock) || this.canSurviveOn(world, blockposition1, iblockdata); // Leaves - behavior to 1.19 - - if (flag1 && RedStoneWireBlock.shouldConnectTo(world.getBlockState(blockposition1.above()))) { - if (iblockdata.isFaceSturdy(world, blockposition1, direction.getOpposite())) { diff --git a/patches/server/0060-Optimized-dragon-respawn.patch b/patches/server/0056-Optimized-dragon-respawn.patch similarity index 96% rename from patches/server/0060-Optimized-dragon-respawn.patch rename to patches/server/0056-Optimized-dragon-respawn.patch index f3de77fc..5a2cb728 100644 --- a/patches/server/0060-Optimized-dragon-respawn.patch +++ b/patches/server/0056-Optimized-dragon-respawn.patch @@ -18,10 +18,10 @@ index ee99519ebd46b1db3e76e7eb86e5cc121c867dc4..63f6f1328c4e39cc1f35480166ae5e22 for (int j = 0; j < this.height; j++) { for (int k = 0; k < this.depth; k++) { 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 84300f2f7b7be4f5281edd8e263646dbcbb3ba07..6f867139ef83ca6d1fc26f98c4d9e4b7ce689580 100644 +index b331c93c82c27f9456fec208a0c008c5bedfa8c4..e944a730503a9c50bcde819515a1d7e7f1ec59fd 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 -@@ -291,8 +291,67 @@ public class EndDragonFight { +@@ -292,8 +292,67 @@ public class EndDragonFight { return false; } @@ -32,7 +32,7 @@ index 84300f2f7b7be4f5281edd8e263646dbcbb3ba07..6f867139ef83ca6d1fc26f98c4d9e4b7 + @Nullable public BlockPattern.BlockPatternMatch findExitPortal() { -+ if (org.leavesmc.leaves.LeavesConfig.optimizedDragonRespawn) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.optimizedDragonRespawn) { + int i, j; + for (i = cachePortalChunkIteratorX; i <= 8; ++i) { + for (j = cachePortalChunkIteratorZ; j <= 8; ++j) { @@ -89,7 +89,7 @@ index 84300f2f7b7be4f5281edd8e263646dbcbb3ba07..6f867139ef83ca6d1fc26f98c4d9e4b7 ChunkPos chunkcoordintpair = new ChunkPos(this.origin); int i; -@@ -621,6 +680,11 @@ public class EndDragonFight { +@@ -624,6 +683,11 @@ public class EndDragonFight { } public boolean respawnDragon(List list) { // CraftBukkit - return boolean diff --git a/patches/server/0061-Shave-snow-layers.patch b/patches/server/0057-Shave-snow-layers.patch similarity index 88% rename from patches/server/0061-Shave-snow-layers.patch rename to patches/server/0057-Shave-snow-layers.patch index 08abe683..3cba8c18 100644 --- a/patches/server/0061-Shave-snow-layers.patch +++ b/patches/server/0057-Shave-snow-layers.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Shave snow layers diff --git a/src/main/java/net/minecraft/world/item/ShovelItem.java b/src/main/java/net/minecraft/world/item/ShovelItem.java -index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..97c3a9281ef10c88947febf152a005b0cd05cc64 100644 +index 55c18f182166f4905d623d6f5e909eefd5ed2483..80de1b720abc98d8abdda4d6ef356e7cc3dda631 100644 --- a/src/main/java/net/minecraft/world/item/ShovelItem.java +++ b/src/main/java/net/minecraft/world/item/ShovelItem.java @@ -44,6 +44,26 @@ public class ShovelItem extends DiggerItem { @@ -13,10 +13,10 @@ index 24f6a158e4759aac3be8da4cf5e0d40bd295355b..97c3a9281ef10c88947febf152a005b0 } else { Player player = context.getPlayer(); + // Leaves start - shaveSnowLayers -+ if (org.leavesmc.leaves.LeavesConfig.shaveSnowLayers && blockState.is(Blocks.SNOW)) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.shaveSnowLayers && blockState.is(Blocks.SNOW)) { + int layers = blockState.getValue(net.minecraft.world.level.block.SnowLayerBlock.LAYERS); + ItemStack tool = context.getItemInHand(); -+ boolean hasSilkTouch = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(level.registryAccess().registryOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getHolder(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH).get(), tool) > 0; ++ boolean hasSilkTouch = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(level.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.ENCHANTMENT).getOrThrow(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH), tool) > 0; + BlockState shavedBlockState = layers > 1 ? blockState.setValue(net.minecraft.world.level.block.SnowLayerBlock.LAYERS, layers - 1) : Blocks.AIR.defaultBlockState(); + + level.setBlock(blockPos, shavedBlockState, Block.UPDATE_ALL_IMMEDIATE); diff --git a/patches/server/0063-Elytra-aeronautics-no-chunk-load.patch b/patches/server/0058-Elytra-aeronautics-no-chunk-load.patch similarity index 75% rename from patches/server/0063-Elytra-aeronautics-no-chunk-load.patch rename to patches/server/0058-Elytra-aeronautics-no-chunk-load.patch index fd50851e..d238311d 100644 --- a/patches/server/0063-Elytra-aeronautics-no-chunk-load.patch +++ b/patches/server/0058-Elytra-aeronautics-no-chunk-load.patch @@ -5,20 +5,20 @@ Subject: [PATCH] Elytra aeronautics no chunk load diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java -index e0650881a3f90532fc446607cf5ae34da4a2a1dc..07d75d8d518456387393ecf371bc1947e1ea4bb5 100644 +index 9a226396b4c38768574d5785744f22e61d6913f3..9a5488df906a0a3dd07f94942750fe9b646a96d9 100644 --- a/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java -@@ -749,7 +749,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -791,7 +791,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } private boolean skipPlayer(ServerPlayer player) { - return player.isSpectator() && !this.level.getGameRules().getBoolean(GameRules.RULE_SPECTATORSGENERATECHUNKS); + return (player.isSpectator() && !this.level.getGameRules().getBoolean(GameRules.RULE_SPECTATORSGENERATECHUNKS)) -+ || (org.leavesmc.leaves.LeavesConfig.elytraAeronauticsNoChunk && player.elytraAeronauticsNoChunk); // Leaves - Elytra aeronautics ++ || (org.leavesmc.leaves.LeavesConfig.modify.elytraAeronautics.noChunk && player.elytraAeronauticsNoChunk); // Leaves - Elytra aeronautics } void updatePlayerStatus(ServerPlayer player, boolean added) { -@@ -787,6 +788,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider +@@ -829,6 +830,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider } public void move(ServerPlayer player) { @@ -27,10 +27,10 @@ index e0650881a3f90532fc446607cf5ae34da4a2a1dc..07d75d8d518456387393ecf371bc1947 SectionPos sectionposition = player.getLastSectionPos(); diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 88e15a2a90485e461df242a1071ecb5b567c46aa..1e4364e4dbc35064fe06a92b7c2c3baae07b0326 100644 +index c5427e40ff55f90aca61866837311d30a74f0f08..4c3a4d6021fe3d02a5c8283eb86293a64b762da5 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -559,7 +559,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -564,7 +564,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl speed *= 2f; // TODO: Get the speed of the vehicle instead of the player // Paper start - Prevent moving into unloaded chunks @@ -40,25 +40,25 @@ index 88e15a2a90485e461df242a1071ecb5b567c46aa..1e4364e4dbc35064fe06a92b7c2c3baa !worldserver.areChunksLoadedForMove(entity.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(entity.position()))) )) { diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 6d97b1be9192d237e5ed2cef94ec9bd72881e156..c7e3772a031c997d43120c3ec95b30093b3ea7eb 100644 +index b7d5a1f56067c6fec74d653b0da48e9610def283..13956aa8210d0234176a9d7450afdf42a2311f11 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -1138,7 +1138,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1186,7 +1186,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return; } } - + // Leaves start - elytra aeronautics -+ if (org.leavesmc.leaves.LeavesConfig.elytraAeronauticsNoChunk && this instanceof Player player) { -+ if (movementType == MoverType.PLAYER && player.isFallFlying()) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.elytraAeronautics.noChunk && this instanceof Player player) { ++ if (type == MoverType.PLAYER && player.isFallFlying()) { + org.leavesmc.leaves.util.ElytraAeronauticsHelper.flightBehaviour(player, movement); + } + } + // Leaves end - elytra aeronautics - this.level().getProfiler().push("move"); - if (this.stuckSpeedMultiplier.lengthSqr() > 1.0E-7D) { - movement = movement.multiply(this.stuckSpeedMultiplier); -@@ -2098,6 +2104,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("move"); +@@ -2184,6 +2190,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.yo = y; this.zo = d4; this.setPos(d3, y, d4); @@ -67,7 +67,7 @@ index 6d97b1be9192d237e5ed2cef94ec9bd72881e156..c7e3772a031c997d43120c3ec95b3009 } 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 a570e9ef4b2b767af3ebb2b33230eb7877553a85..b737848442843b4d7decc140f51f77ed6f7c5f4b 100644 +index e4bb0b2eb8512f75042dab77bb79b4f51742ab4e..b36d67774cf34cf95bcfbaa2fc8cb4f56b1e7557 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -197,6 +197,7 @@ public abstract class Player extends LivingEntity { @@ -80,7 +80,7 @@ index a570e9ef4b2b767af3ebb2b33230eb7877553a85..b737848442843b4d7decc140f51f77ed public boolean fauxSleeping; diff --git a/src/main/java/org/leavesmc/leaves/util/ElytraAeronauticsHelper.java b/src/main/java/org/leavesmc/leaves/util/ElytraAeronauticsHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..0a9cde390476a728dd43f017e3eac3c923709b72 +index 0000000000000000000000000000000000000000..96282f07cbb4609741e66b53ec639de0cc33f6b6 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/ElytraAeronauticsHelper.java @@ -0,0 +1,40 @@ @@ -98,14 +98,14 @@ index 0000000000000000000000000000000000000000..0a9cde390476a728dd43f017e3eac3c9 +public class ElytraAeronauticsHelper { + + public static void flightBehaviour(Player player, Vec3 velocity) { -+ if (LeavesConfig.elytraAeronauticsNoChunk) { -+ if ((LeavesConfig.elytraAeronauticsNoChunkSpeed <= 0.0D || velocity.horizontalDistanceSqr() >= LeavesConfig.elytraAeronauticsNoChunkSpeed) -+ && (LeavesConfig.elytraAeronauticsNoChunkHeight <= 0.0D || player.getY() >= LeavesConfig.elytraAeronauticsNoChunkHeight)) { ++ if (LeavesConfig.modify.elytraAeronautics.noChunk) { ++ if ((LeavesConfig.modify.elytraAeronautics.noChunkSpeed <= 0.0D || velocity.horizontalDistanceSqr() >= LeavesConfig.modify.elytraAeronautics.noChunkSpeed) ++ && (LeavesConfig.modify.elytraAeronautics.noChunkHeight <= 0.0D || player.getY() >= LeavesConfig.modify.elytraAeronautics.noChunkHeight)) { + if (!player.elytraAeronauticsNoChunk) { + player.elytraAeronauticsNoChunk = true; + ServerPlayer serverPlayer = (ServerPlayer) player; -+ if (LeavesConfig.elytraAeronauticsNoChunkMes) { -+ serverPlayer.sendSystemMessage(Component.literal(LeavesConfig.elytraAeronauticsNoChunkStartMes), true); ++ if (LeavesConfig.modify.elytraAeronautics.noChunkMes) { ++ serverPlayer.sendSystemMessage(Component.literal(LeavesConfig.modify.elytraAeronautics.noChunkStartMes), true); + } + ChunkSystem.removePlayerFromDistanceMaps((ServerLevel) serverPlayer.level(), serverPlayer); + ((ServerLevel) serverPlayer.level()).chunkSource.chunkMap.getDistanceManager().removePlayer(serverPlayer.getLastSectionPos(), serverPlayer); @@ -114,8 +114,8 @@ index 0000000000000000000000000000000000000000..0a9cde390476a728dd43f017e3eac3c9 + if (player.elytraAeronauticsNoChunk) { + player.elytraAeronauticsNoChunk = false; + ServerPlayer serverPlayer = (ServerPlayer) player; -+ if (LeavesConfig.elytraAeronauticsNoChunkMes) { -+ serverPlayer.sendSystemMessage(Component.literal(LeavesConfig.elytraAeronauticsNoChunkEndMes), true); ++ if (LeavesConfig.modify.elytraAeronautics.noChunkMes) { ++ serverPlayer.sendSystemMessage(Component.literal(LeavesConfig.modify.elytraAeronautics.noChunkEndMes), true); + } + ChunkSystem.addPlayerToDistanceMaps((ServerLevel) serverPlayer.level(), serverPlayer); + ((ServerLevel) serverPlayer.level()).chunkSource.chunkMap.getDistanceManager().addPlayer(SectionPos.of(serverPlayer), serverPlayer); diff --git a/patches/server/0064-Cache-ignite-odds.patch b/patches/server/0059-Cache-ignite-odds.patch similarity index 94% rename from patches/server/0064-Cache-ignite-odds.patch rename to patches/server/0059-Cache-ignite-odds.patch index 9240607f..cb3135fc 100644 --- a/patches/server/0064-Cache-ignite-odds.patch +++ b/patches/server/0059-Cache-ignite-odds.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Cache ignite odds 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 0a77a470d78f68e8397f29f298e7f52fbd7ba9a2..3f82dd92c41519bd21b481f2303f03a12bb8f973 100644 +index 0e5a47ab235d99e6cb1468905f791c2c59ac0082..f2b5ae54fbe5a98bf464d85a7dafcef6d6cacd42 100644 --- a/src/main/java/net/minecraft/world/level/block/FireBlock.java +++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java @@ -220,6 +220,7 @@ public class FireBlock extends BaseFireBlock { @@ -21,7 +21,7 @@ index 0a77a470d78f68e8397f29f298e7f52fbd7ba9a2..3f82dd92c41519bd21b481f2303f03a1 blockposition_mutableblockposition.setWithOffset(pos, l, j1, i1); - int l1 = this.getIgniteOdds(world, blockposition_mutableblockposition); -+ int l1 = this.getIgniteOdds(world, blockposition_mutableblockposition, org.leavesmc.leaves.LeavesConfig.cacheIgniteOdds ? blockPositionIgniteCache : null); // Leaves - cache ignite odds ++ int l1 = this.getIgniteOdds(world, blockposition_mutableblockposition, org.leavesmc.leaves.LeavesConfig.performance.cacheIgniteOdds ? blockPositionIgniteCache : null); // Leaves - cache ignite odds if (l1 > 0) { int i2 = (l1 + 40 + world.getDifficulty().getId() * 7) / (i + 30); diff --git a/patches/server/0060-Lava-riptide.patch b/patches/server/0060-Lava-riptide.patch new file mode 100644 index 00000000..9d3e4b54 --- /dev/null +++ b/patches/server/0060-Lava-riptide.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Fri, 7 Jul 2023 16:53:32 +0800 +Subject: [PATCH] Lava riptide + + +diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java +index 8b9a93ef71164cce8a616735b71d96d37e83b1a8..98b10cca7e583da08f43e312d387e37a95fa7686 100644 +--- a/src/main/java/net/minecraft/world/item/TridentItem.java ++++ b/src/main/java/net/minecraft/world/item/TridentItem.java +@@ -75,7 +75,7 @@ public class TridentItem extends Item implements ProjectileItem { + } else { + float f = EnchantmentHelper.getTridentSpinAttackStrength(stack, entityhuman); + +- if (f > 0.0F && !entityhuman.isInWaterOrRain()) { ++ if (f > 0.0F && !entityhuman.isInWaterOrRain() || (org.leavesmc.leaves.LeavesConfig.modify.lavaRiptide && entityhuman.isInLava())) { // Leaves - lava riptide + return false; + } else if (stack.nextDamageWillBreak()) { + return false; +@@ -158,7 +158,7 @@ public class TridentItem extends Item implements ProjectileItem { + + if (itemstack.nextDamageWillBreak()) { + return InteractionResult.FAIL; +- } else if (EnchantmentHelper.getTridentSpinAttackStrength(itemstack, user) > 0.0F && !user.isInWaterOrRain()) { ++ } else if (EnchantmentHelper.getTridentSpinAttackStrength(itemstack, user) > 0.0F && !user.isInWaterOrRain() && !(org.leavesmc.leaves.LeavesConfig.modify.lavaRiptide && user.isInLava())) { // Leaves - lava riptide + return InteractionResult.FAIL; + } else { + user.startUsingItem(hand); diff --git a/patches/server/0066-No-block-update-command.patch b/patches/server/0061-No-block-update-command.patch similarity index 73% rename from patches/server/0066-No-block-update-command.patch rename to patches/server/0061-No-block-update-command.patch index 098d3a9d..dad85ae5 100644 --- a/patches/server/0066-No-block-update-command.patch +++ b/patches/server/0061-No-block-update-command.patch @@ -5,10 +5,10 @@ Subject: [PATCH] No block update command diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index e8fa04e83aa80d8284aa58bf3899f5c81e4a2ef6..f494ea2671f219ce02c53ad725cc41646558a4c4 100644 +index 1b2ba3ff09b27ea74afc96735e48a474cf6ebddd..e52c490540319db13a2b23f839f7fd88aeadda64 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2300,6 +2300,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2453,6 +2453,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void blockUpdated(BlockPos pos, Block block) { @@ -17,23 +17,23 @@ index e8fa04e83aa80d8284aa58bf3899f5c81e4a2ef6..f494ea2671f219ce02c53ad725cc4164 // CraftBukkit start if (this.populating) { diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java -index 2a2b9631a16c16f41261b7e042acd14d600df230..952be4dde6518e1459b1a4262b6c5aa13b17ace5 100644 +index f38487562422ebaf59a679f493f956b90cc18ff1..b6b3189f15c9e56f104a788716bb134b352cc83c 100644 --- a/src/main/java/net/minecraft/world/item/ItemStack.java +++ b/src/main/java/net/minecraft/world/item/ItemStack.java -@@ -527,7 +527,7 @@ public final class ItemStack implements DataComponentHolder { - net.minecraft.world.level.block.state.BlockState block = world.getBlockState(newblockposition); +@@ -533,7 +533,7 @@ public final class ItemStack implements DataComponentHolder { + net.minecraft.world.level.block.state.BlockState block = world.getBlockState(newblockposition); - if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically -- block.onPlace(world, newblockposition, oldBlock, true, context); -+ if (!org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) block.onPlace(world, newblockposition, oldBlock, true, context); // Leaves - no block update - } + if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically +- block.onPlace(world, newblockposition, oldBlock, true, context); ++ if (!org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) block.onPlace(world, newblockposition, oldBlock, true, context); // Leaves - no block update + } - world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point + world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point 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 382ca565fe1a680ab49b14ac90e4ec3bd903450d..ce5964c1a53b362bcc5fb735684b78c96609cb86 100644 +index 2fea5a46bba27578366c36f594472c3e38395bee..80c71d08ea7588ba95416296531c5629097d9257 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java -@@ -403,7 +403,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p +@@ -427,7 +427,7 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p } else { // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. if (!this.level.isClientSide && doPlace && (!this.level.captureBlockStates || block instanceof net.minecraft.world.level.block.BaseEntityBlock)) { @@ -43,22 +43,22 @@ index 382ca565fe1a680ab49b14ac90e4ec3bd903450d..ce5964c1a53b362bcc5fb735684b78c9 if (iblockdata.hasBlockEntity()) { 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 1687ab4965433459219bb5d8aaf5ec8e5baeb605..36d49bd355b9c061b1663bcac7c9f590173f34df 100644 +index f4fbcbb8ff6d2677af1a02a0801a323c06dce9b1..dd9e7b030b64b10d61481e744fe3e53ff80087f8 100644 --- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java +++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java -@@ -506,6 +506,7 @@ public abstract class FlowingFluid extends Fluid { +@@ -516,6 +516,7 @@ public abstract class FlowingFluid extends Fluid { @Override - public void tick(Level world, BlockPos pos, FluidState state) { + public void tick(ServerLevel world, BlockPos pos, BlockState blockState, FluidState fluidState) { + if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update - if (!state.isSource()) { + if (!fluidState.isSource()) { FluidState fluid1 = this.getNewLiquid(world, pos, world.getBlockState(pos)); - int i = this.getSpreadDelay(world, pos, state, fluid1); + int i = this.getSpreadDelay(world, pos, fluidState, fluid1); 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 106af2b2c7ff72c7549975aef75cdcff8d9a7d97..ef9f2552367dfa8b708f18d66a4526fea8c24807 100644 +index 3a95e3236eafd14baed035e53503b58c2e21b68a..717d9042a9a67aea771b0b544776a9956eb52eab 100644 --- a/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java +++ b/src/main/java/net/minecraft/world/level/redstone/CollectingNeighborUpdater.java -@@ -48,6 +48,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater { +@@ -49,6 +49,7 @@ public class CollectingNeighborUpdater implements NeighborUpdater { } private void addAndRun(BlockPos pos, CollectingNeighborUpdater.NeighborUpdates entry) { @@ -67,33 +67,33 @@ index 106af2b2c7ff72c7549975aef75cdcff8d9a7d97..ef9f2552367dfa8b708f18d66a4526fe boolean bl2 = this.maxChainedNeighborUpdates >= 0 && this.count >= this.maxChainedNeighborUpdates; this.count++; diff --git a/src/main/java/net/minecraft/world/level/redstone/InstantNeighborUpdater.java b/src/main/java/net/minecraft/world/level/redstone/InstantNeighborUpdater.java -index 2708251ebc1995e71fb0e5dca9e158a3005f8a8a..2c39d07e5612b3d435fb782d7861448c470950b4 100644 +index e1c3dbd74a009ca8adc6269fd22f9547ee03f347..efb9cc019e804aa4f88d77cbee6d05cb9f65de29 100644 --- a/src/main/java/net/minecraft/world/level/redstone/InstantNeighborUpdater.java +++ b/src/main/java/net/minecraft/world/level/redstone/InstantNeighborUpdater.java -@@ -15,17 +15,20 @@ public class InstantNeighborUpdater implements NeighborUpdater { +@@ -16,17 +16,20 @@ public class InstantNeighborUpdater implements NeighborUpdater { @Override public void shapeUpdate(Direction direction, BlockState neighborState, BlockPos pos, BlockPos neighborPos, int flags, int maxUpdateDepth) { + if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update - NeighborUpdater.executeShapeUpdate(this.level, direction, neighborState, pos, neighborPos, flags, maxUpdateDepth - 1); + NeighborUpdater.executeShapeUpdate(this.level, direction, pos, neighborPos, neighborState, flags, maxUpdateDepth - 1); } @Override - public void neighborChanged(BlockPos pos, Block sourceBlock, BlockPos sourcePos) { + public void neighborChanged(BlockPos pos, Block sourceBlock, @Nullable Orientation orientation) { + if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update BlockState blockState = this.level.getBlockState(pos); - this.neighborChanged(blockState, pos, sourceBlock, sourcePos, false); + this.neighborChanged(blockState, pos, sourceBlock, orientation, false); } @Override - public void neighborChanged(BlockState state, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) { + public void neighborChanged(BlockState state, BlockPos pos, Block sourceBlock, @Nullable Orientation orientation, boolean notify) { + if (org.leavesmc.leaves.command.NoBlockUpdateCommand.isNoBlockUpdate()) return; // Leaves - no block update - NeighborUpdater.executeUpdate(this.level, state, pos, sourceBlock, sourcePos, notify); + NeighborUpdater.executeUpdate(this.level, state, pos, sourceBlock, orientation, notify); } } diff --git a/src/main/java/org/leavesmc/leaves/command/NoBlockUpdateCommand.java b/src/main/java/org/leavesmc/leaves/command/NoBlockUpdateCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..f60f3409aeb72f8f0195e667ccb139a7f81729b6 +index 0000000000000000000000000000000000000000..8f25ce0145341d363bb42183a9e64622159663ff --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/command/NoBlockUpdateCommand.java @@ -0,0 +1,52 @@ @@ -146,6 +146,6 @@ index 0000000000000000000000000000000000000000..f60f3409aeb72f8f0195e667ccb139a7 + } + + public static boolean isNoBlockUpdate() { -+ return LeavesConfig.noBlockUpdateCommand && noBlockUpdate; ++ return LeavesConfig.modify.noBlockUpdateCommand && noBlockUpdate; + } +} diff --git a/patches/server/0067-Raider-die-skip-self-raid-check.patch b/patches/server/0062-Raider-die-skip-self-raid-check.patch similarity index 69% rename from patches/server/0067-Raider-die-skip-self-raid-check.patch rename to patches/server/0062-Raider-die-skip-self-raid-check.patch index 4d1e047f..986edc9e 100644 --- a/patches/server/0067-Raider-die-skip-self-raid-check.patch +++ b/patches/server/0062-Raider-die-skip-self-raid-check.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Raider die skip self raid check 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 bbf21ea433f9e3963aac0ede597ed8d3c8e50ed8..6e68f8fa8280a106b1a262d86aa130e89d4f5cce 100644 +index ab132041982df2a701e4baea8195873f31b4a5fb..9b911254b24bc77930c518a9c61916983ba72e3c 100644 --- a/src/main/java/net/minecraft/world/entity/raid/Raider.java +++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java -@@ -121,7 +121,7 @@ public abstract class Raider extends PatrollingMonster { +@@ -124,7 +124,7 @@ public abstract class Raider extends PatrollingMonster { Raid raid = this.getCurrentRaid(); if (raid != null) { - if (this.isPatrolLeader()) { -+ if (!org.leavesmc.leaves.LeavesConfig.skipSelfRaidCheck && this.isPatrolLeader()) { // Leaves - skip self raid check ++ if (!org.leavesmc.leaves.LeavesConfig.modify.skipSelfRaidCheck && this.isPatrolLeader()) { // Leaves - skip self raid check raid.removeLeader(this.getWave()); } diff --git a/patches/server/0068-Container-open-passthrough.patch b/patches/server/0063-Container-open-passthrough.patch similarity index 78% rename from patches/server/0068-Container-open-passthrough.patch rename to patches/server/0063-Container-open-passthrough.patch index 7bb8125a..a84e8fe0 100644 --- a/patches/server/0068-Container-open-passthrough.patch +++ b/patches/server/0063-Container-open-passthrough.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Container open passthrough 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 73874cd18a5b335e895ea0b2fefbd521209afe08..0f560a03676571e1ebf3811a7caa4faba0e7ef95 100644 +index b212fe323f048dab40c0ccbb9327c9fc73b9e03a..ccfa890b1c83fe9492cb4f5863911008536b46f0 100644 --- a/src/main/java/net/minecraft/world/level/block/SignBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SignBlock.java -@@ -110,6 +110,18 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo +@@ -111,6 +111,18 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo } else { - return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } + // Leaves start - signContainerPassthrough -+ } else if (org.leavesmc.leaves.LeavesConfig.containerPassthrough) { ++ } else if (org.leavesmc.leaves.LeavesConfig.modify.containerPassthrough) { + BlockPos pos1 = pos.relative(hit.getDirection().getOpposite()); + if (this instanceof WallSignBlock || this instanceof WallHangingSignBlock) { + pos1 = pos.relative(state.getValue(HorizontalDirectionalBlock.FACING).getOpposite()); @@ -22,17 +22,17 @@ index 73874cd18a5b335e895ea0b2fefbd521209afe08..0f560a03676571e1ebf3811a7caa4fab + BlockState state1 = world.getBlockState(pos1); + return state1.useItemOn(stack, world, player, hand, hit.withPosition(pos1)); + } -+ return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; ++ return InteractionResult.PASS; + // Leaves end - signContainerPassthrough } else { - return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + return InteractionResult.TRY_WITH_EMPTY_HAND; } -@@ -138,6 +150,25 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo - return InteractionResult.SUCCESS; +@@ -139,6 +151,25 @@ public abstract class SignBlock extends BaseEntityBlock implements SimpleWaterlo + return InteractionResult.SUCCESS_SERVER; } else if (flag1) { - return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS_SERVER; + // Leaves start - signContainerPassthrough -+ } else if (org.leavesmc.leaves.LeavesConfig.containerPassthrough) { ++ } else if (org.leavesmc.leaves.LeavesConfig.modify.containerPassthrough) { + if (player.isShiftKeyDown()) { + if (!this.otherPlayerIsEditingSign(player, tileentitysign) && player.mayBuild() && this.hasEditableText(player, tileentitysign, flag1)) { + this.openTextEdit(player, tileentitysign, flag1); @@ -52,4 +52,4 @@ index 73874cd18a5b335e895ea0b2fefbd521209afe08..0f560a03676571e1ebf3811a7caa4fab + // Leaves end - signContainerPassthrough } else if (!this.otherPlayerIsEditingSign(player, tileentitysign) && player.mayBuild() && this.hasEditableText(player, tileentitysign, flag)) { this.openTextEdit(player, tileentitysign, flag, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent - return InteractionResult.SUCCESS; + return InteractionResult.SUCCESS_SERVER; diff --git a/patches/server/0069-SIMD-support.patch b/patches/server/0064-SIMD-support.patch similarity index 79% rename from patches/server/0069-SIMD-support.patch rename to patches/server/0064-SIMD-support.patch index 4886c231..d8227b35 100644 --- a/patches/server/0069-SIMD-support.patch +++ b/patches/server/0064-SIMD-support.patch @@ -5,10 +5,10 @@ Subject: [PATCH] SIMD support diff --git a/build.gradle.kts b/build.gradle.kts -index d3bc2ed92763b701d91a8c705818e7f4e12e45f0..51bf5df7bca5b32e171e452d62f6843a7a10fee1 100644 +index b8132401ddaedf13bc9ddc74524166d0e0dcf419..0add94373b7b38f271893b1c44a448051b845e8b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -78,6 +78,7 @@ tasks.withType { +@@ -92,6 +92,7 @@ tasks.withType { compilerArgs.add("-Xlint:-module") compilerArgs.add("-Xlint:-removal") compilerArgs.add("-Xlint:-dep-ann") @@ -16,7 +16,7 @@ index d3bc2ed92763b701d91a8c705818e7f4e12e45f0..51bf5df7bca5b32e171e452d62f6843a } // Leaves end - hide irrelevant compilation warnings -@@ -191,6 +192,8 @@ fun TaskContainer.registerRunTask( +@@ -210,6 +211,8 @@ fun TaskContainer.registerRunTask( minHeapSize = "${memoryGb}G" maxHeapSize = "${memoryGb}G" diff --git a/patches/server/0070-Dont-respond-ping-before-start-fully.patch b/patches/server/0065-Dont-respond-ping-before-start-fully.patch similarity index 83% rename from patches/server/0070-Dont-respond-ping-before-start-fully.patch rename to patches/server/0065-Dont-respond-ping-before-start-fully.patch index 70b0d692..f5ba8181 100644 --- a/patches/server/0070-Dont-respond-ping-before-start-fully.patch +++ b/patches/server/0065-Dont-respond-ping-before-start-fully.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Dont respond ping before start fully This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java -index 532f09089b8d6798999cf3f83e852df7479e450e..85f8acea5923494d3a079387ddceae38419d9847 100644 +index 532f09089b8d6798999cf3f83e852df7479e450e..e4751b27607f33b25623e2c593840323c4f0242c 100644 --- a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java @@ -154,6 +154,12 @@ public class ServerStatusPacketListenerImpl implements ServerStatusPacketListene @@ -15,7 +15,7 @@ index 532f09089b8d6798999cf3f83e852df7479e450e..85f8acea5923494d3a079387ddceae38 */ + // Leaves start - dont respond it before start full + var status = MinecraftServer.getServer().getStatus(); -+ if (org.leavesmc.leaves.LeavesConfig.dontRespondPingBeforeStart && (status == null || status.version() == null || status.version().isEmpty())) { ++ if (org.leavesmc.leaves.LeavesConfig.mics.dontRespondPingBeforeStart && (status == null || status.version() == null || status.version().isEmpty())) { + return; + } + // Leaves end - dont respond it before start full diff --git a/patches/server/0065-Lava-riptide.patch b/patches/server/0065-Lava-riptide.patch deleted file mode 100644 index 284a3923..00000000 --- a/patches/server/0065-Lava-riptide.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Fri, 7 Jul 2023 16:53:32 +0800 -Subject: [PATCH] Lava riptide - - -diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java -index f1b2d388a1a40a1d909a2e726f32d6c15e1eb0eb..da3887eec5b1e2b8151d71ddb759d083993d54bb 100644 ---- a/src/main/java/net/minecraft/world/item/TridentItem.java -+++ b/src/main/java/net/minecraft/world/item/TridentItem.java -@@ -72,7 +72,7 @@ public class TridentItem extends Item implements ProjectileItem { - if (j >= 10) { - float f = EnchantmentHelper.getTridentSpinAttackStrength(stack, entityhuman); - -- if (f <= 0.0F || entityhuman.isInWaterOrRain()) { -+ if (f <= 0.0F || entityhuman.isInWaterOrRain() || (org.leavesmc.leaves.LeavesConfig.lavaRiptide && entityhuman.isInLava())) { // Leaves - lava riptide - if (!TridentItem.isTooDamagedToUse(stack)) { - Holder holder = (Holder) EnchantmentHelper.pickHighestLevel(stack, EnchantmentEffectComponents.TRIDENT_SOUND).orElse(SoundEvents.TRIDENT_THROW); - -@@ -150,7 +150,7 @@ public class TridentItem extends Item implements ProjectileItem { - - if (TridentItem.isTooDamagedToUse(itemstack)) { - return InteractionResultHolder.fail(itemstack); -- } else if (EnchantmentHelper.getTridentSpinAttackStrength(itemstack, user) > 0.0F && !user.isInWaterOrRain()) { -+ } else if (EnchantmentHelper.getTridentSpinAttackStrength(itemstack, user) > 0.0F && !user.isInWaterOrRain() && !(org.leavesmc.leaves.LeavesConfig.lavaRiptide && user.isInLava())) { // Leaves - lava riptide - return InteractionResultHolder.fail(itemstack); - } else { - user.startUsingItem(hand); diff --git a/patches/server/0071-Faster-chunk-serialization.patch b/patches/server/0066-Faster-chunk-serialization.patch similarity index 94% rename from patches/server/0071-Faster-chunk-serialization.patch rename to patches/server/0066-Faster-chunk-serialization.patch index 8c3d76f5..a7989861 100644 --- a/patches/server/0071-Faster-chunk-serialization.patch +++ b/patches/server/0066-Faster-chunk-serialization.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Faster chunk serialization This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java -index 19661e106612b8e4e152085fb398db7bd06acc23..b0eebd6f35bcf5dac99b9efe13ae6b2c03fce4a1 100644 +index e4e153cb8899e70273aa150b8ea26907cf68b15c..cf5adffc17da35067c75e6432eae038762bd36f1 100644 --- a/src/main/java/net/minecraft/util/BitStorage.java +++ b/src/main/java/net/minecraft/util/BitStorage.java @@ -1,5 +1,7 @@ @@ -27,7 +27,7 @@ index 19661e106612b8e4e152085fb398db7bd06acc23..b0eebd6f35bcf5dac99b9efe13ae6b2c // provide default impl in case mods implement this... @Override diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java -index 8acf2f2491a8d9d13392c5e89b2bd5c9918285e1..eccef53172ed8cd7d7903c7e128908e2cb87fd08 100644 +index d99ec470b4653beab630999a5b2c1a6428b20c38..404d1cc8467505cf1ca81c3d845b880033e03dbf 100644 --- a/src/main/java/net/minecraft/util/SimpleBitStorage.java +++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java @@ -3,6 +3,7 @@ package net.minecraft.util; @@ -38,7 +38,7 @@ index 8acf2f2491a8d9d13392c5e89b2bd5c9918285e1..eccef53172ed8cd7d7903c7e128908e2 public class SimpleBitStorage implements BitStorage { private static final int[] MAGIC = new int[]{ -@@ -401,4 +402,44 @@ public class SimpleBitStorage implements BitStorage { +@@ -472,4 +473,44 @@ public class SimpleBitStorage implements BitStorage { super(message); } } @@ -84,7 +84,7 @@ index 8acf2f2491a8d9d13392c5e89b2bd5c9918285e1..eccef53172ed8cd7d7903c7e128908e2 + // Leaves end - faster chunk serialization } diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java -index 15c5164d0ef41a978c16ee317fa73e97f2480207..93d1416cf2eaeb10e24c69a28a1d9e576ca7dbdc 100644 +index 1f9c436a632e4f110be61cf76fcfc3b7eb80334e..87393a181c64af6a02ebddfccae674c4fbcb3903 100644 --- a/src/main/java/net/minecraft/util/ZeroBitStorage.java +++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java @@ -3,6 +3,7 @@ package net.minecraft.util; @@ -103,7 +103,7 @@ index 15c5164d0ef41a978c16ee317fa73e97f2480207..93d1416cf2eaeb10e24c69a28a1d9e57 + // 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() { diff --git a/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java b/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java index acae3eb30e0689048937f479dc3070f0688abdad..029b62acf1d9f8479ab64a55c12f00ba467249e3 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PaletteResize.java @@ -116,7 +116,7 @@ index acae3eb30e0689048937f479dc3070f0688abdad..029b62acf1d9f8479ab64a55c12f00ba int onResize(int newBits, T object); } 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..fd8dc6395f6a307971f781c40768845b6e10e22e 100644 +index 8b84bf2272556ac3321cbf16361d7f48a1cc6873..404cb8e85c1983346c9e4de5b5d5a0c040915eff 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -23,8 +23,25 @@ import net.minecraft.util.Mth; @@ -145,7 +145,7 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..fd8dc6395f6a307971f781c40768845b private static final int MIN_PALETTE_BITS = 0; private final PaletteResize dummyPaletteResize = (newSize, added) -> 0; public final IdMap registry; -@@ -304,28 +321,78 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -348,28 +365,78 @@ public class PalettedContainer implements PaletteResize, PalettedContainer public synchronized PalettedContainerRO.PackedData pack(IdMap idList, PalettedContainer.Strategy paletteProvider) { // Paper - synchronize this.acquire(); @@ -164,7 +164,7 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..fd8dc6395f6a307971f781c40768845b - } else { - optional = Optional.empty(); + // Leaves start - faster chunk serialization -+ if (!org.leavesmc.leaves.LeavesConfig.fasterChunkSerialization) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.fasterChunkSerialization) { + PalettedContainerRO.PackedData var12; + try { + HashMapPalette hashMapPalette = new HashMapPalette<>(idList, this.data.storage.getBits(), this.dummyPaletteResize); @@ -243,14 +243,14 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..fd8dc6395f6a307971f781c40768845b } private static void swapPalette(int[] is, IntUnaryOperator applier) { -@@ -364,13 +431,47 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -409,13 +476,47 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @Override public void count(PalettedContainer.CountConsumer counter) { - if (this.data.palette.getSize() == 1) { - counter.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); + // Leaves start - faster chunk serialization -+ if (!org.leavesmc.leaves.LeavesConfig.fasterChunkSerialization) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.fasterChunkSerialization) { + if (this.data.palette.getSize() == 1) { + counter.accept(this.data.palette.valueFor(0), this.data.storage.getSize()); + } else { @@ -298,7 +298,7 @@ index 13d3c877b006a4975e7370713e3919c661e7890f..fd8dc6395f6a307971f781c40768845b static record Configuration(Palette.Factory factory, int bits) { diff --git a/src/main/java/org/leavesmc/leaves/lithium/common/world/chunk/LithiumHashPalette.java b/src/main/java/org/leavesmc/leaves/lithium/common/world/chunk/LithiumHashPalette.java new file mode 100644 -index 0000000000000000000000000000000000000000..3a110e892dafa965274597018265fc5b9d9a9640 +index 0000000000000000000000000000000000000000..da32fdd8bbb9a966bd17c7457d94bb676f28c60d --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/lithium/common/world/chunk/LithiumHashPalette.java @@ -0,0 +1,197 @@ @@ -474,8 +474,8 @@ index 0000000000000000000000000000000000000000..3a110e892dafa965274597018265fc5b + + @NotNull + @Override -+ public Palette copy() { -+ return new LithiumHashPalette<>(this.idList, this.resizeHandler, this.indexBits, this.entries.clone(), new Reference2IntOpenHashMap<>(this.table), this.size); ++ public Palette copy(@NotNull PaletteResize resizeListener) { ++ return new LithiumHashPalette<>(this.idList, resizeHandler, this.indexBits, this.entries.clone(), new Reference2IntOpenHashMap<>(this.table), this.size); + } + + private void clear() { diff --git a/patches/server/0072-Cache-world-generator-sea-level.patch b/patches/server/0067-Cache-world-generator-sea-level.patch similarity index 92% rename from patches/server/0072-Cache-world-generator-sea-level.patch rename to patches/server/0067-Cache-world-generator-sea-level.patch index 96ae4546..65de710d 100644 --- a/patches/server/0072-Cache-world-generator-sea-level.patch +++ b/patches/server/0067-Cache-world-generator-sea-level.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Cache world generator sea level This patch is Powered by Gale(https://github.com/GaleMC/Gale) 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 68be0d51aa64b5d917fb53dbbbdf8966d4f4abd8..4adac668fb3d02ed43a89da446a71503d0380c73 100644 +index 3f39d6c786d9dfdd9ad591e08ff05fcbb41a1df6..be411653a89e4c3585db95509e3a93d140a05fba 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java +++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java @@ -61,12 +61,17 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator { @@ -34,7 +34,7 @@ index 68be0d51aa64b5d917fb53dbbbdf8966d4f4abd8..4adac668fb3d02ed43a89da446a71503 public int getSeaLevel() { - return ((NoiseGeneratorSettings) this.settings.value()).seaLevel(); + // Leaves start - cache world generator sea level -+ if (!org.leavesmc.leaves.LeavesConfig.cacheWorldGeneratorSeaLevel) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.cacheWorldGeneratorSeaLevel) { + return ((NoiseGeneratorSettings) this.settings.value()).seaLevel(); + } else { + return cachedSeaLevel; diff --git a/patches/server/0073-Bladeren-Protocol.patch b/patches/server/0068-Bladeren-Protocol.patch similarity index 95% rename from patches/server/0073-Bladeren-Protocol.patch rename to patches/server/0068-Bladeren-Protocol.patch index 35d88956..f3da2991 100644 --- a/patches/server/0073-Bladeren-Protocol.patch +++ b/patches/server/0068-Bladeren-Protocol.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Bladeren Protocol diff --git a/src/main/java/org/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..318a1a42c43688cc2711c3b902e7302e26c9a83e +index 0000000000000000000000000000000000000000..6aeab5b37f142fd84c9e290f08078180d7e327b2 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/bladeren/BladerenProtocol.java @@ -0,0 +1,150 @@ @@ -47,7 +47,7 @@ index 0000000000000000000000000000000000000000..318a1a42c43688cc2711c3b902e7302e + + @ProtocolHandler.PayloadReceiver(payload = BladerenHelloPayload.class, payloadId = "hello") + private static void handleHello(@NotNull ServerPlayer player, @NotNull BladerenHelloPayload payload) { -+ if (LeavesConfig.bladerenLeavesProtocol) { ++ if (LeavesConfig.protocol.bladeren.enable) { + String clientVersion = payload.version; + CompoundTag tag = payload.nbt; + @@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..318a1a42c43688cc2711c3b902e7302e + + @ProtocolHandler.PayloadReceiver(payload = BladerenFeatureModifyPayload.class, payloadId = "feature_modify") + private static void handleModify(@NotNull ServerPlayer player, @NotNull BladerenFeatureModifyPayload payload) { -+ if (LeavesConfig.bladerenLeavesProtocol) { ++ if (LeavesConfig.protocol.bladeren.enable) { + String name = payload.name; + CompoundTag tag = payload.nbt; + @@ -78,7 +78,7 @@ index 0000000000000000000000000000000000000000..318a1a42c43688cc2711c3b902e7302e + + @ProtocolHandler.PlayerJoin + public static void onPlayerJoin(@NotNull ServerPlayer player) { -+ if (LeavesConfig.bladerenLeavesProtocol) { ++ if (LeavesConfig.protocol.bladeren.enable) { + CompoundTag tag = new CompoundTag(); + LeavesFeatureSet.writeNBT(tag); + ProtocolUtils.sendPayloadPacket(player, new BladerenHelloPayload(PROTOCOL_VERSION, tag)); diff --git a/patches/server/0074-Skip-secondary-POI-sensor-if-absent.patch b/patches/server/0069-Skip-secondary-POI-sensor-if-absent.patch similarity index 87% rename from patches/server/0074-Skip-secondary-POI-sensor-if-absent.patch rename to patches/server/0069-Skip-secondary-POI-sensor-if-absent.patch index 672f74e9..18645f3f 100644 --- a/patches/server/0074-Skip-secondary-POI-sensor-if-absent.patch +++ b/patches/server/0069-Skip-secondary-POI-sensor-if-absent.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Skip secondary POI sensor if absent This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java -index a0e0692d17760f440fe81d52887284c787e562db..4b9470eb94ca1d90161cfbd3de06ec5f56adbb7b 100644 +index a0e0692d17760f440fe81d52887284c787e562db..c6f5f7f7c0821b707d9cfe239ccab748e6b8b9cb 100644 --- a/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/SecondaryPoiSensor.java @@ -22,6 +22,15 @@ public class SecondaryPoiSensor extends Sensor { @@ -14,7 +14,7 @@ index a0e0692d17760f440fe81d52887284c787e562db..4b9470eb94ca1d90161cfbd3de06ec5f @Override protected void doTick(ServerLevel world, Villager entity) { + // Leaves start - skip secondary POI sensor if absent -+ if (org.leavesmc.leaves.LeavesConfig.skipSecondaryPOISensorIfAbsent) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.skipSecondaryPOISensorIfAbsent) { + var secondaryPoi = entity.getVillagerData().getProfession().secondaryPoi(); + if (secondaryPoi.isEmpty()) { + entity.getBrain().eraseMemory(MemoryModuleType.SECONDARY_JOB_SITE); diff --git a/patches/server/0075-Bladeren-mspt-sync-protocol.patch b/patches/server/0070-Bladeren-mspt-sync-protocol.patch similarity index 88% rename from patches/server/0075-Bladeren-mspt-sync-protocol.patch rename to patches/server/0070-Bladeren-mspt-sync-protocol.patch index 8e8342dd..90c97f05 100644 --- a/patches/server/0075-Bladeren-mspt-sync-protocol.patch +++ b/patches/server/0070-Bladeren-mspt-sync-protocol.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Bladeren mspt sync protocol diff --git a/src/main/java/org/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..8bbcb87cf327ac3b85b8134231a23cb6092c5afb +index 0000000000000000000000000000000000000000..6e4ea71f6d1a6e784248ce2eacd270e2d410da66 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/bladeren/MsptSyncProtocol.java @@ -0,0 +1,77 @@ @@ -54,20 +54,20 @@ index 0000000000000000000000000000000000000000..8bbcb87cf327ac3b85b8134231a23cb6 + + @ProtocolHandler.PlayerLeave + public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { -+ if (LeavesConfig.msptSyncProtocol) { ++ if (LeavesConfig.protocol.bladeren.msptSyncProtocol) { + players.remove(player); + } + } + + @ProtocolHandler.Ticker + public static void tick() { -+ if (LeavesConfig.msptSyncProtocol) { ++ if (LeavesConfig.protocol.bladeren.msptSyncProtocol) { + if (players.isEmpty()) { + return; + } + + MinecraftServer server = MinecraftServer.getServer(); -+ if (server.getTickCount() % LeavesConfig.msptSyncTickInterval == 0) { ++ if (server.getTickCount() % LeavesConfig.protocol.bladeren.msptSyncTickInterval == 0) { + OptionalDouble msptArr = Arrays.stream(server.getTickTimesNanos()).average(); + if (msptArr.isPresent()) { + double mspt = msptArr.getAsDouble() * 1.0E-6D; @@ -82,7 +82,7 @@ index 0000000000000000000000000000000000000000..8bbcb87cf327ac3b85b8134231a23cb6 + } + + public static void onPlayerSubmit(@NotNull ServerPlayer player) { -+ if (LeavesConfig.msptSyncProtocol) { ++ if (LeavesConfig.protocol.bladeren.msptSyncProtocol) { + players.add(player); + } + } diff --git a/patches/server/0076-Store-mob-counts-in-an-array.patch b/patches/server/0071-Store-mob-counts-in-an-array.patch similarity index 87% rename from patches/server/0076-Store-mob-counts-in-an-array.patch rename to patches/server/0071-Store-mob-counts-in-an-array.patch index 8dbb7568..932876f6 100644 --- a/patches/server/0076-Store-mob-counts-in-an-array.patch +++ b/patches/server/0071-Store-mob-counts-in-an-array.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Store mob counts in an array This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java b/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java -index 2039b16e5e9bc0797b3f31081d221bb8b34a4dc7..ed3ef016bf22772f30c9f02d574405948e68d2af 100644 +index 2039b16e5e9bc0797b3f31081d221bb8b34a4dc7..973331b29f2fd672c18c2dea858f473009d59637 100644 --- a/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java +++ b/src/main/java/net/minecraft/world/level/LocalMobCapCalculator.java @@ -43,13 +43,26 @@ public class LocalMobCapCalculator { @@ -18,7 +18,7 @@ index 2039b16e5e9bc0797b3f31081d221bb8b34a4dc7..ed3ef016bf22772f30c9f02d57440594 public void add(MobCategory spawnGroup) { - this.counts.computeInt(spawnGroup, (group, density) -> density == null ? 1 : density + 1); + // Leaves start - store mob counts in an array -+ if (!org.leavesmc.leaves.LeavesConfig.storeMobCountsInArray) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.storeMobCountsInArray) { + this.counts.computeInt(spawnGroup, (group, density) -> density == null ? 1 : density + 1); + } else { + this.arrCounts[spawnGroup.ordinal()]++; @@ -29,7 +29,7 @@ index 2039b16e5e9bc0797b3f31081d221bb8b34a4dc7..ed3ef016bf22772f30c9f02d57440594 public boolean canSpawn(MobCategory spawnGroup) { - return this.counts.getOrDefault(spawnGroup, 0) < spawnGroup.getMaxInstancesPerChunk(); + // Leaves start - store mob counts in an array -+ if (!org.leavesmc.leaves.LeavesConfig.storeMobCountsInArray) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.storeMobCountsInArray) { + return this.counts.getOrDefault(spawnGroup, 0) < spawnGroup.getMaxInstancesPerChunk(); + } else { + return this.arrCounts[spawnGroup.ordinal()] < spawnGroup.getMaxInstancesPerChunk(); diff --git a/patches/server/0078-Optimize-noise-generation.patch b/patches/server/0072-Optimize-noise-generation.patch similarity index 94% rename from patches/server/0078-Optimize-noise-generation.patch rename to patches/server/0072-Optimize-noise-generation.patch index 645abca5..9304759b 100644 --- a/patches/server/0078-Optimize-noise-generation.patch +++ b/patches/server/0072-Optimize-noise-generation.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimize noise generation This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java -index 9a97e5cd23d839183ac4d243d28df92af3119fe7..6eeb8ff51a3fa519f43f17a3ced2b2080f264d7a 100644 +index 9a97e5cd23d839183ac4d243d28df92af3119fe7..344a0873334d2626a7c745c4dd2547f54c581806 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java +++ b/src/main/java/net/minecraft/world/level/levelgen/synth/ImprovedNoise.java @@ -11,6 +11,27 @@ public final class ImprovedNoise { @@ -48,7 +48,7 @@ index 9a97e5cd23d839183ac4d243d28df92af3119fe7..6eeb8ff51a3fa519f43f17a3ced2b208 + double g; + double h; + double l; -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeNoiseGeneration) { + g = d - (double)i; + h = e - (double)j; + l = f - (double)k; @@ -67,7 +67,7 @@ index 9a97e5cd23d839183ac4d243d28df92af3119fe7..6eeb8ff51a3fa519f43f17a3ced2b208 - o = (double)Mth.floor(m / yScale + 1.0E-7F) * yScale; + // Leaves start - optimize noise generation -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeNoiseGeneration) { + o = (double)Mth.floor(m / yScale + 1.0E-7F) * yScale; + } else { + o = Math.floor(m / yScale + (double)1.0E-7F) * yScale; @@ -79,7 +79,7 @@ index 9a97e5cd23d839183ac4d243d28df92af3119fe7..6eeb8ff51a3fa519f43f17a3ced2b208 - return this.sampleAndLerp(i, j, k, g, h - o, l, h); + // Leaves start - optimize noise generation -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeNoiseGeneration) { + return this.sampleAndLerp(i, j, k, g, h - o, l, h); + } else { + return this.sampleAndLerp((int) i, (int) j, (int) k, g, h - o, l, h); @@ -97,7 +97,7 @@ index 9a97e5cd23d839183ac4d243d28df92af3119fe7..6eeb8ff51a3fa519f43f17a3ced2b208 - double l = f - (double)k; - return this.sampleWithDerivative(i, j, k, g, h, l, ds); + // Leaves start - optimize noise generation -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeNoiseGeneration) { + double g = d - (double)i; + double h = e - (double)j; + double l = f - (double)k; @@ -135,7 +135,7 @@ index 9a97e5cd23d839183ac4d243d28df92af3119fe7..6eeb8ff51a3fa519f43f17a3ced2b208 - double t = Mth.smoothstep(localZ); - return Mth.lerp3(r, s, t, d, e, f, g, h, o, p, q); + // Leaves start - optimize noise generation -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeNoiseGeneration) { + int i = this.p(sectionX); + int j = this.p(sectionX + 1); + int k = this.p(i + sectionY); @@ -222,7 +222,7 @@ index 9a97e5cd23d839183ac4d243d28df92af3119fe7..6eeb8ff51a3fa519f43f17a3ced2b208 private double sampleWithDerivative(int sectionX, int sectionY, int sectionZ, double localX, double localY, double localZ, double[] ds) { diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java -index 35820670837376bcad8891241724d5b946fbd31f..cd52ee8c8ad0a3f0befc8d9d98e5afc75a802d15 100644 +index 35820670837376bcad8891241724d5b946fbd31f..317a3cc6d01309513a1177a19b6c9380d5792fc5 100644 --- a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java +++ b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java @@ -26,6 +26,10 @@ public class PerlinNoise { @@ -253,7 +253,7 @@ index 35820670837376bcad8891241724d5b946fbd31f..cd52ee8c8ad0a3f0befc8d9d98e5afc7 public double getValue(double x, double y, double z) { - return this.getValue(x, y, z, 0.0, 0.0, false); + // Leaves start - optimize noise generation -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeNoiseGeneration) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeNoiseGeneration) { + return this.getValue(x, y, z, 0.0, 0.0, false); + } else { + double d = 0.0; diff --git a/patches/server/0079-Disable-packet-limit.patch b/patches/server/0073-Disable-packet-limit.patch similarity index 68% rename from patches/server/0079-Disable-packet-limit.patch rename to patches/server/0073-Disable-packet-limit.patch index 98d3ffca..bb590b10 100644 --- a/patches/server/0079-Disable-packet-limit.patch +++ b/patches/server/0073-Disable-packet-limit.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Disable packet limit diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 53913dfa4d9b73862179dcdef080c7e3adfe3b0f..0d41f7561f11d11a69399c191881afa2abadd9ff 100644 +index 17e23ca4dd2bbfba49ea00aa2b719a95feb931be..d4e2e93689e831e56e7500d6d14f1704e0c66874 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -@@ -283,7 +283,7 @@ public class GlobalConfiguration extends ConfigurationPart { +@@ -275,7 +275,7 @@ public class GlobalConfiguration extends ConfigurationPart { } public boolean isEnabled() { - return this.interval > 0.0 && this.maxPacketRate > 0.0; -+ return !org.leavesmc.leaves.LeavesConfig.disablePacketLimit && (this.interval > 0.0 && this.maxPacketRate > 0.0); // Leaves - disable packet limit ++ return !org.leavesmc.leaves.LeavesConfig.modify.disablePacketLimit && (this.interval > 0.0 && this.maxPacketRate > 0.0); // Leaves - disable packet limit } public enum ViolateAction { diff --git a/patches/server/0080-Reduce-array-allocations.patch b/patches/server/0074-Reduce-array-allocations.patch similarity index 67% rename from patches/server/0080-Reduce-array-allocations.patch rename to patches/server/0074-Reduce-array-allocations.patch index f61e215c..7bedb78a 100644 --- a/patches/server/0080-Reduce-array-allocations.patch +++ b/patches/server/0074-Reduce-array-allocations.patch @@ -5,65 +5,19 @@ Subject: [PATCH] Reduce array allocations This patch is Powered by Gale(https://github.com/GaleMC/Gale) -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..a8e93e61beb51cc061b489ed4ad70e8fe6dfb8b9 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/EntityList.java -@@ -5,6 +5,7 @@ import net.minecraft.world.entity.Entity; - import java.util.Arrays; - import java.util.Iterator; - import java.util.NoSuchElementException; -+import org.leavesmc.leaves.util.ArrayConstants; - - // list with O(1) remove & contains - -@@ -18,9 +19,7 @@ public final class EntityList implements Iterable { - this.entityToIndex.defaultReturnValue(Integer.MIN_VALUE); - } - -- protected static final Entity[] EMPTY_LIST = new Entity[0]; -- -- protected Entity[] entities = EMPTY_LIST; -+ protected Entity[] entities = ArrayConstants.emptyEntityArray; // Leaves - reduce array allocations - protected int count; - - public int size() { -diff --git a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -index fcfbca333234c09f7c056bbfcd9ac8860b20a8db..18503ef068924d4be4d40390af8db70d26fd9c7d 100644 ---- a/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -+++ b/src/main/java/ca/spottedleaf/moonrise/common/list/IBlockDataList.java -@@ -6,6 +6,7 @@ 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; -+import org.leavesmc.leaves.util.ArrayConstants; - - public final class IBlockDataList { - -@@ -17,9 +18,7 @@ public final class IBlockDataList { - this.map.defaultReturnValue(Long.MAX_VALUE); - } - -- private static final long[] EMPTY_LIST = new long[0]; -- -- private long[] byIndex = EMPTY_LIST; -+ private long[] byIndex = ArrayConstants.emptyLongArray; // Leaves - reduce array allocations - private int size; - - public static int getLocationKey(final int x, final int y, final int z) { 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..56ca2488154bd5f064c0a97bf778dc07da4a0662 100644 +index b3c993a790fc3fab6a408c731deb297f74c959ce..f85775a40eb72f207ac8b8f8169b20b584b19737 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 -@@ -27,6 +27,7 @@ import java.util.Iterator; +@@ -29,6 +29,7 @@ import java.util.Arrays; + import java.util.Iterator; import java.util.List; import java.util.function.Predicate; - import org.bukkit.event.entity.EntityRemoveEvent; +import org.leavesmc.leaves.util.ArrayConstants; public final class ChunkEntitySlices { -@@ -408,7 +409,7 @@ public final class ChunkEntitySlices { +@@ -387,7 +388,7 @@ public final class ChunkEntitySlices { private static final class BasicEntityList { @@ -72,7 +26,7 @@ index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..56ca2488154bd5f064c0a97bf778dc07 private static final int DEFAULT_CAPACITY = 4; private E[] storage; -@@ -419,7 +420,7 @@ public final class ChunkEntitySlices { +@@ -398,7 +399,7 @@ public final class ChunkEntitySlices { } public BasicEntityList(final int cap) { @@ -81,7 +35,7 @@ index 5c7f2471a0b15ac2e714527296ad2aa7291999eb..56ca2488154bd5f064c0a97bf778dc07 } public boolean isEmpty() { -@@ -431,7 +432,7 @@ public final class ChunkEntitySlices { +@@ -410,7 +411,7 @@ public final class ChunkEntitySlices { } private void resize() { @@ -193,7 +147,7 @@ index ff13d67151c50ea11a45117e524c7524e2b1a202..8c3ee4c9aa22bcc46f2dc3a5bc35bdde @Override diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java -index b19298aeaa0dacfe1afb1e672bd30b0c069ec968..8b6304160a6a3ca4c30f1ab75802a9d318d7d7c6 100644 +index 49e03ba7c04381e263aaee5cda9ed6c042bf6c0e..42e7da8be33fc4f85bf2d57b6f895762772a547c 100644 --- a/src/main/java/net/minecraft/network/Connection.java +++ b/src/main/java/net/minecraft/network/Connection.java @@ -66,6 +66,7 @@ import org.apache.commons.lang3.Validate; @@ -204,36 +158,23 @@ index b19298aeaa0dacfe1afb1e672bd30b0c069ec968..8b6304160a6a3ca4c30f1ab75802a9d3 public class Connection extends SimpleChannelInboundHandler> { -diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java -index 0846e11c82295ccf93683f877962ec7804dad677..b747b3858befe48996ea707cf126f6f8496258fd 100644 ---- a/src/main/java/net/minecraft/server/level/ServerEntity.java -+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java -@@ -369,7 +369,7 @@ public class ServerEntity { - - if (this.entity instanceof LivingEntity) { - List> list = Lists.newArrayList(); -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index f494ea2671f219ce02c53ad725cc41646558a4c4..fc7ce6a031c50d270a979ec57e05cec0de7426c2 100644 +index e52c490540319db13a2b23f839f7fd88aeadda64..a88ca4aaaca3c9e6370bba7e6fbdb0f57c6065f7 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -181,6 +181,7 @@ import org.bukkit.event.server.MapInitializeEvent; +@@ -184,6 +184,7 @@ import org.bukkit.event.server.MapInitializeEvent; import org.bukkit.event.weather.LightningStrikeEvent; import org.bukkit.event.world.TimeSkipEvent; // CraftBukkit end +import org.leavesmc.leaves.util.ArrayConstants; - 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, 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 diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index bc3b8de51def54996cfe8e7a612f382df0b060e1..17b5d93e4d822d0b815594c18884f5349abbef19 100644 +index 4c3a4d6021fe3d02a5c8283eb86293a64b762da5..2bd29d075eafd72a146406836a933841a23cde76 100644 --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -249,6 +249,7 @@ import org.bukkit.inventory.EquipmentSlot; +@@ -260,6 +260,7 @@ import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.SmithingInventory; // CraftBukkit end @@ -241,7 +182,7 @@ index bc3b8de51def54996cfe8e7a612f382df0b060e1..17b5d93e4d822d0b815594c18884f534 public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements ServerGamePacketListener, ServerPlayerConnection, TickablePacketListener { -@@ -806,7 +807,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -818,7 +819,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl // Paper start final int index; if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64)) { @@ -251,7 +192,7 @@ index bc3b8de51def54996cfe8e7a612f382df0b060e1..17b5d93e4d822d0b815594c18884f534 } // Paper end diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java -index 40638b439966619e9c70a18a32abd95b2178fe9f..153e918f1059bb09ad074eb06bbdbbdc6f673b05 100644 +index 033755682c61c889723c3669b5cff4de147f637e..f4261a204577f349354b5ebca2d2070203597d63 100644 --- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java @@ -51,6 +51,7 @@ import org.bukkit.craftbukkit.entity.CraftPlayer; @@ -287,10 +228,10 @@ index 40638b439966619e9c70a18a32abd95b2178fe9f..153e918f1059bb09ad074eb06bbdbbdc final String s; diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index e62a27431bb2872bdf7dcc34366249dbfe8add17..3322ee4e6720c8b06e6d6684cbac95c2d14babb1 100644 +index 7a80d3e7d46a9c2a729ca50e2bd265fe5711a23f..aa864ac20bb3d0ddef8376768bf5921e81eb9597 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -950,13 +950,9 @@ public abstract class PlayerList { +@@ -916,13 +916,9 @@ public abstract class PlayerList { final ResourceKey OVERWORLD = Level.OVERWORLD; final ResourceKey THE_NETHER = Level.NETHER; if (!((fromDim != OVERWORLD || toDim != THE_NETHER) && (fromDim != THE_NETHER || toDim != OVERWORLD))) { @@ -329,7 +270,7 @@ index c038da20b76c0b7b1c18471b20be01e849d29f3a..603007a376dc76c46d34f265283dda69 public boolean isEmpty() { diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java -index 93d1416cf2eaeb10e24c69a28a1d9e576ca7dbdc..72d908b88bd21a777a26ed3a510c422912bf9e56 100644 +index 87393a181c64af6a02ebddfccae674c4fbcb3903..09a402e95cdb8c75881fbeff66ca853709b62a33 100644 --- a/src/main/java/net/minecraft/util/ZeroBitStorage.java +++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java @@ -4,9 +4,10 @@ import java.util.Arrays; @@ -344,100 +285,48 @@ index 93d1416cf2eaeb10e24c69a28a1d9e576ca7dbdc..72d908b88bd21a777a26ed3a510c4229 private final int size; public ZeroBitStorage(int size) { -diff --git a/src/main/java/net/minecraft/world/entity/EquipmentSlot.java b/src/main/java/net/minecraft/world/entity/EquipmentSlot.java -index 2fa2a4eef21e786f738f36616c3160defa95bce8..36c98f611f043ebadffd1b110ba3002b29731a52 100644 ---- a/src/main/java/net/minecraft/world/entity/EquipmentSlot.java -+++ b/src/main/java/net/minecraft/world/entity/EquipmentSlot.java -@@ -19,6 +19,7 @@ public enum EquipmentSlot implements StringRepresentable { - private final int countLimit; - private final int filterFlag; - private final String name; -+ public static final EquipmentSlot[] VALUES = EquipmentSlot.values(); // Leaves - reduce array allocations - - private EquipmentSlot(final EquipmentSlot.Type type, final int entityId, final int maxCount, final int armorStandId, final String name) { - this.type = type; diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index 567ceb290d91ce6291202e03496d455503ba59c5..28b6689421b311c5aa975c1f9e3deca9ce76d688 100644 +index d50f928b70eb0b77088e77b76788c6d878b722ee..16cec435f86390ef57388ae83825dec397777b1c 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3280,7 +3280,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - @Nullable - private Map collectEquipmentChanges() { - Map map = null; -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { -diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 32a039bc4a99cb9b5db5c3a0e596f1b67a3c8738..69d37babce0b8d38d24abe9664bc0a8be8982820 100644 ---- a/src/main/java/net/minecraft/world/entity/Mob.java -+++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1154,7 +1154,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - @Override - protected void dropCustomDeathLoot(ServerLevel world, DamageSource source, boolean causedByPlayer) { - super.dropCustomDeathLoot(world, source, causedByPlayer); -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { -@@ -1284,7 +1284,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -3439,7 +3439,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + throw new MatchException((String) null, (Throwable) null); } - boolean flag = true; -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int j = aenumitemslot.length; - - for (int k = 0; k < j; ++k) { -@@ -1369,7 +1369,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - - protected void populateDefaultEquipmentEnchantments(ServerLevelAccessor world, RandomSource random, DifficultyInstance localDifficulty) { - this.enchantSpawnedWeapon(world, random, localDifficulty); -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { -@@ -1574,7 +1574,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - t0.setInvulnerable(this.isInvulnerable()); - if (flag) { - t0.setCanPickUpLoot(this.canPickUpLoot()); -- EquipmentSlot[] aenumitemslot = EquipmentSlot.values(); -+ EquipmentSlot[] aenumitemslot = EquipmentSlot.VALUES; // Leaves - reduce array allocations - int i = aenumitemslot.length; - - for (int j = 0; j < i; ++j) { +- ItemStack itemstack2 = itemstack1; final ItemStack oldEquipment = itemstack2; // Paper - PlayerArmorChangeEvent - obfhelper ++ ItemStack itemstack2 = itemstack1; final ItemStack oldEquipment = itemstack2; // Paper - PlayerArmorChangeEvent - obfhelper + + itemstack = this.getItemBySlot(enumitemslot); final ItemStack newEquipment = itemstack;// Paper - PlayerArmorChangeEvent - obfhelper + if (this.equipmentHasChanged(itemstack2, itemstack)) { 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 1bf54b0142fe41b29b21c8b97d3f52bb24a36a92..f19ace4f9027260ded3ee37c1bda91c56d2a086c 100644 +index 980fea65899ef5f37808506b822fd3de5830d2c7..11a89f7ce8096b375e6fb4786ecca53675943026 100644 --- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java +++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java -@@ -16,6 +16,7 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe; +@@ -23,6 +23,7 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe; import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; import org.bukkit.inventory.RecipeChoice; // CraftBukkit end +import org.leavesmc.leaves.util.ArrayConstants; - public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookExactChoiceRecipe implements CraftingRecipe { // Paper - improve exact recipe choices + public class ShapedRecipe implements CraftingRecipe { diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 9a6a2acec1bf11282d1451f5d5178e41fab91b39..5452a15b8a082337c9e53a004e93d8058f6a0474 100644 +index 83cfa4fb4fd85bda767de6f3c5e440a0a5229b59..bb5a19253fdb46fabb0da2faa2a7d608fa79e279 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -102,6 +102,7 @@ import org.bukkit.craftbukkit.util.CraftSpawnCategory; +@@ -104,6 +104,7 @@ import org.bukkit.craftbukkit.util.CraftSpawnCategory; import org.bukkit.entity.SpawnCategory; import org.bukkit.event.block.BlockPhysicsEvent; // CraftBukkit end +import org.leavesmc.leaves.util.ArrayConstants; - 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 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 d3d12f9114173f4971f95d7ef895a4374705bd3f..d9e28a241f7fc9c6828dc3b169f56bad08db5b04 100644 +index db837b250fc35af5b528bf973b3b07f63e79bc46..4c55f5c1abbbe7ea55ee60e65a11b0d274fa746e 100644 --- a/src/main/java/net/minecraft/world/level/block/ComposterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ComposterBlock.java -@@ -46,6 +46,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; +@@ -45,6 +45,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder; import org.bukkit.craftbukkit.util.DummyGeneratorAccess; // CraftBukkit end @@ -445,7 +334,7 @@ index d3d12f9114173f4971f95d7ef895a4374705bd3f..d9e28a241f7fc9c6828dc3b169f56bad public class ComposterBlock extends Block implements WorldlyContainerHolder { -@@ -430,7 +431,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -434,7 +435,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { @@ -454,7 +343,7 @@ index d3d12f9114173f4971f95d7ef895a4374705bd3f..d9e28a241f7fc9c6828dc3b169f56bad } @Override -@@ -479,7 +480,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -483,7 +484,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { @@ -463,7 +352,7 @@ index d3d12f9114173f4971f95d7ef895a4374705bd3f..d9e28a241f7fc9c6828dc3b169f56bad } @Override -@@ -521,7 +522,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { +@@ -525,7 +526,7 @@ public class ComposterBlock extends Block implements WorldlyContainerHolder { @Override public int[] getSlotsForFace(Direction side) { @@ -473,10 +362,10 @@ index d3d12f9114173f4971f95d7ef895a4374705bd3f..d9e28a241f7fc9c6828dc3b169f56bad @Override 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 7092a4d4a583f4e01cc02bca17f3bd1bd32677a0..32622ebdd9c5949ad995875d29e121a49e98b698 100644 +index 46bdb85f18077c77c445ce0bc3cfe32468c75306..8a17b6a2e8fcd5d0bc071e94a123a0da264ffe60 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 -@@ -60,6 +60,7 @@ import org.bukkit.event.inventory.FurnaceSmeltEvent; +@@ -54,6 +54,7 @@ import org.bukkit.event.inventory.FurnaceSmeltEvent; import org.bukkit.event.inventory.FurnaceStartSmeltEvent; import org.bukkit.inventory.CookingRecipe; // CraftBukkit end @@ -484,7 +373,7 @@ index 7092a4d4a583f4e01cc02bca17f3bd1bd32677a0..32622ebdd9c5949ad995875d29e121a4 public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntity implements WorldlyContainer, RecipeCraftingHolder, StackedContentsCompatible { -@@ -67,7 +68,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit +@@ -61,7 +62,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit protected static final int SLOT_FUEL = 1; protected static final int SLOT_RESULT = 2; public static final int DATA_LIT_TIME = 0; @@ -493,23 +382,6 @@ index 7092a4d4a583f4e01cc02bca17f3bd1bd32677a0..32622ebdd9c5949ad995875d29e121a4 private static final int[] SLOTS_FOR_DOWN = new int[]{2, 1}; private static final int[] SLOTS_FOR_SIDES = new int[]{1}; public static final int DATA_LIT_DURATION = 1; -diff --git a/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java b/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java -index ae86c45c1d49c7646c721991910592091e7333f8..f3dce7156d518193fe27a69f5792800b72742632 100644 ---- a/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java -+++ b/src/main/java/org/bukkit/craftbukkit/CraftEquipmentSlot.java -@@ -7,8 +7,10 @@ import org.bukkit.inventory.EquipmentSlot; - - public class CraftEquipmentSlot { - -- private static final net.minecraft.world.entity.EquipmentSlot[] slots = new net.minecraft.world.entity.EquipmentSlot[EquipmentSlot.values().length]; -- private static final EquipmentSlot[] enums = new EquipmentSlot[net.minecraft.world.entity.EquipmentSlot.values().length]; -+ // Leaves start - reduce array allocations -+ private static final net.minecraft.world.entity.EquipmentSlot[] slots = net.minecraft.world.entity.EquipmentSlot.VALUES; -+ private static final EquipmentSlot[] enums = new EquipmentSlot[net.minecraft.world.entity.EquipmentSlot.VALUES.length]; -+ // Leaves end - reduce array allocations - - static { - set(EquipmentSlot.HAND, net.minecraft.world.entity.EquipmentSlot.MAINHAND); diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java index fdcc414f4fa246082ad0732133c870d915ae3084..556247696cde0d31cbb70907648d2970acf81153 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java diff --git a/patches/server/0081-Optimize-sun-burn-tick.patch b/patches/server/0075-Optimize-sun-burn-tick.patch similarity index 89% rename from patches/server/0081-Optimize-sun-burn-tick.patch rename to patches/server/0075-Optimize-sun-burn-tick.patch index fdfc88b3..d1819053 100644 --- a/patches/server/0081-Optimize-sun-burn-tick.patch +++ b/patches/server/0075-Optimize-sun-burn-tick.patch @@ -6,16 +6,16 @@ Subject: [PATCH] Optimize sun burn tick This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index c7e3772a031c997d43120c3ec95b30093b3ea7eb..8c6f9911c3ec32909a0830dc5eee6442ff42d41c 100644 +index 13956aa8210d0234176a9d7450afdf42a2311f11..6a19f5725387b7178720ba209ebc2a5c46241bf5 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -2080,8 +2080,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2166,8 +2166,22 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess /** @deprecated */ @Deprecated public float getLightLevelDependentMagicValue() { - return this.level().hasChunkAt(this.getBlockX(), this.getBlockZ()) ? this.level().getLightLevelDependentMagicValue(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())) : 0.0F; + // Leaves start - optimize sun burn tick -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeSunBurnTick) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeSunBurnTick) { + return this.level().hasChunkAt(this.getBlockX(), this.getBlockZ()) ? this.level().getLightLevelDependentMagicValue(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())) : 0.0F; + } else { + return this.getLightLevelDependentMagicValue(BlockPos.containing(this.getX(), this.getEyeY(), this.getZ())); @@ -34,10 +34,10 @@ index c7e3772a031c997d43120c3ec95b30093b3ea7eb..8c6f9911c3ec32909a0830dc5eee6442 public void absMoveTo(double x, double y, double z, float yaw, float pitch) { this.absMoveTo(x, y, z); diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java -index 69d37babce0b8d38d24abe9664bc0a8be8982820..cff93b927757cbf39d2a574b4f79ccc19280a62e 100644 +index c80976958ad8f51aadf0dab5d49a3e11c77010d4..b3775c9c5986f460b0b65ce49a5e2ff064349394 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java -@@ -1754,15 +1754,41 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1742,15 +1742,41 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab protected void playAttackSound() {} @@ -52,7 +52,7 @@ index 69d37babce0b8d38d24abe9664bc0a8be8982820..cff93b927757cbf39d2a574b4f79ccc1 - BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); - boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; + // Leaves start - optimize sun burn tick -+ if (!org.leavesmc.leaves.LeavesConfig.optimizeSunBurnTick) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizeSunBurnTick) { + float f = this.getLightLevelDependentMagicValue(); + BlockPos blockposition = BlockPos.containing(this.getX(), this.getEyeY(), this.getZ()); + boolean flag = this.isInWaterRainOrBubble() || this.isInPowderSnow || this.wasInPowderSnow; diff --git a/patches/server/0082-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch b/patches/server/0076-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch similarity index 92% rename from patches/server/0082-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch rename to patches/server/0076-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch index f0f4b962..f24df5e3 100644 --- a/patches/server/0082-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch +++ b/patches/server/0076-Reduce-lambda-and-Optional-allocation-in-EntityBased.patch @@ -7,7 +7,7 @@ Subject: [PATCH] Reduce lambda and Optional allocation in This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java b/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java -index 3527f1621ef9b4f3f8d8bbb93379f13ff141c3be..523bd9cb8121d419a763b59a64f50cbeae88aeb4 100644 +index 3527f1621ef9b4f3f8d8bbb93379f13ff141c3be..f6e51bce07849553c907c81ad141105f36f393cb 100644 --- a/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java +++ b/src/main/java/net/minecraft/world/level/EntityBasedExplosionDamageCalculator.java @@ -15,8 +15,20 @@ public class EntityBasedExplosionDamageCalculator extends ExplosionDamageCalcula @@ -16,7 +16,7 @@ index 3527f1621ef9b4f3f8d8bbb93379f13ff141c3be..523bd9cb8121d419a763b59a64f50cbe public Optional getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState) { - return super.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState) - .map(max -> this.source.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState, max)); -+ if (!org.leavesmc.leaves.LeavesConfig.removeDamageLambda) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.remove.damageLambda) { + return super.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState) + .map(max -> this.source.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState, max)); + } else { diff --git a/patches/server/0083-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch b/patches/server/0077-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch similarity index 100% rename from patches/server/0083-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch rename to patches/server/0077-Avoid-Class-isAssignableFrom-call-in-ClassInstanceMu.patch diff --git a/patches/server/0084-Optimized-CubePointRange.patch b/patches/server/0078-Optimized-CubePointRange.patch similarity index 83% rename from patches/server/0084-Optimized-CubePointRange.patch rename to patches/server/0078-Optimized-CubePointRange.patch index d05acc81..ea0a5d5b 100644 --- a/patches/server/0084-Optimized-CubePointRange.patch +++ b/patches/server/0078-Optimized-CubePointRange.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Optimized CubePointRange This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java -index ad02cdb00360165f6405eb3044bd8320f01a7ef1..99ddf5419833244338d349a32e576d21198cef54 100644 +index ad02cdb00360165f6405eb3044bd8320f01a7ef1..d628e696c3ddd10cc2a347a8dd720d9379cf894c 100644 --- a/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java +++ b/src/main/java/net/minecraft/world/phys/shapes/CubePointRange.java @@ -3,21 +3,31 @@ package net.minecraft.world.phys.shapes; @@ -30,7 +30,7 @@ index ad02cdb00360165f6405eb3044bd8320f01a7ef1..99ddf5419833244338d349a32e576d21 public double getDouble(int i) { - return (double)i / (double)this.parts; + // Leaves start - replace division by multiplication in CubePointRange -+ if (!org.leavesmc.leaves.LeavesConfig.optimizedCubePointRange) { ++ if (!org.leavesmc.leaves.LeavesConfig.performance.optimizedCubePointRange) { + return (double)i / (double)this.parts; + } else { + return i * this.scale; @@ -40,6 +40,6 @@ index ad02cdb00360165f6405eb3044bd8320f01a7ef1..99ddf5419833244338d349a32e576d21 public int size() { - return this.parts + 1; -+ return !org.leavesmc.leaves.LeavesConfig.optimizedCubePointRange ? this.parts + 1 : size; // Leaves - replace parts by size in CubePointRange ++ return !org.leavesmc.leaves.LeavesConfig.performance.optimizedCubePointRange ? this.parts + 1 : size; // Leaves - replace parts by size in CubePointRange } } diff --git a/patches/server/0085-Check-frozen-ticks-before-landing-block.patch b/patches/server/0079-Check-frozen-ticks-before-landing-block.patch similarity index 63% rename from patches/server/0085-Check-frozen-ticks-before-landing-block.patch rename to patches/server/0079-Check-frozen-ticks-before-landing-block.patch index 830a1c94..00a0edeb 100644 --- a/patches/server/0085-Check-frozen-ticks-before-landing-block.patch +++ b/patches/server/0079-Check-frozen-ticks-before-landing-block.patch @@ -6,20 +6,20 @@ Subject: [PATCH] Check frozen ticks before landing block This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index af8f8161b940afb1b77dee7cc2711e42738a6bed..c578497c824021e571b21b1b938705e7f585632c 100644 +index 74e86f0e0fb237711c6741a1e3909e4f47dc200e..55cce94ebee920a64fdd80248fe10c231c8023d0 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -564,11 +564,11 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -581,11 +581,11 @@ public abstract class LivingEntity extends Entity implements Attackable { } protected void tryAddFrost() { - if (!this.getBlockStateOnLegacy().isAir()) { -+ if (org.leavesmc.leaves.LeavesConfig.checkFrozenTicksBeforeLandingBlock || !this.getBlockStateOnLegacy().isAir()) { // Leaves - check frozen ticks before landing block ++ if (org.leavesmc.leaves.LeavesConfig.performance.checkFrozenTicksBeforeLandingBlock || !this.getBlockStateOnLegacy().isAir()) { // Leaves - check frozen ticks before landing block int i = this.getTicksFrozen(); if (i > 0) { - AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED); -+ AttributeInstance attributemodifiable = !org.leavesmc.leaves.LeavesConfig.checkFrozenTicksBeforeLandingBlock || !this.getBlockStateOnLegacy().isAir() ? this.getAttribute(Attributes.MOVEMENT_SPEED) : null; // Leaves - check frozen ticks before landing block ++ AttributeInstance attributemodifiable = !org.leavesmc.leaves.LeavesConfig.performance.checkFrozenTicksBeforeLandingBlock || !this.getBlockStateOnLegacy().isAir() ? this.getAttribute(Attributes.MOVEMENT_SPEED) : null; // Leaves - check frozen ticks before landing block if (attributemodifiable == null) { return; diff --git a/patches/server/0086-Skip-entity-move-if-movement-is-zero.patch b/patches/server/0080-Skip-entity-move-if-movement-is-zero.patch similarity index 80% rename from patches/server/0086-Skip-entity-move-if-movement-is-zero.patch rename to patches/server/0080-Skip-entity-move-if-movement-is-zero.patch index e6ab6b4a..bc5b009e 100644 --- a/patches/server/0086-Skip-entity-move-if-movement-is-zero.patch +++ b/patches/server/0080-Skip-entity-move-if-movement-is-zero.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Skip entity move if movement is zero This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 8c6f9911c3ec32909a0830dc5eee6442ff42d41c..5f4dd9b08638d8a28dfdce2cc5a320099b72055b 100644 +index 6a19f5725387b7178720ba209ebc2a5c46241bf5..bab140f5489ab13bb67a3372cb1429e5ead1d93d 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -323,6 +323,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -282,6 +282,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public float yRotO; public float xRotO; private AABB bb; @@ -17,12 +17,12 @@ index 8c6f9911c3ec32909a0830dc5eee6442ff42d41c..5f4dd9b08638d8a28dfdce2cc5a32009 public boolean onGround; public boolean horizontalCollision; public boolean verticalCollision; -@@ -1115,6 +1116,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1163,6 +1164,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper end - detailed watchdog information - public void move(MoverType movementType, Vec3 movement) { + public void move(MoverType type, Vec3 movement) { + // Leaves start - skip entity move if movement is zero -+ if (org.leavesmc.leaves.LeavesConfig.skipEntityMoveIfMovementIsZero) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.skipEntityMoveIfMovementIsZero) { + if (!this.boundingBoxChanged && movement.equals(Vec3.ZERO)) { + return; + } @@ -31,7 +31,7 @@ index 8c6f9911c3ec32909a0830dc5eee6442ff42d41c..5f4dd9b08638d8a28dfdce2cc5a32009 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"); -@@ -4166,6 +4174,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4421,6 +4429,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public final void setBoundingBox(AABB boundingBox) { diff --git a/patches/server/0087-Skip-cloning-advancement-criteria.patch b/patches/server/0081-Skip-cloning-advancement-criteria.patch similarity index 76% rename from patches/server/0087-Skip-cloning-advancement-criteria.patch rename to patches/server/0081-Skip-cloning-advancement-criteria.patch index 532c4560..90e6ffc5 100644 --- a/patches/server/0087-Skip-cloning-advancement-criteria.patch +++ b/patches/server/0081-Skip-cloning-advancement-criteria.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Skip cloning advancement criteria This patch is Powered by Gale(https://github.com/GaleMC/Gale) diff --git a/src/main/java/net/minecraft/advancements/Advancement.java b/src/main/java/net/minecraft/advancements/Advancement.java -index fb4b7652c386fa10783d71899615723a958ffd56..eb987b0cb6d2018e648c1488aa2059be18369bd4 100644 +index fb4b7652c386fa10783d71899615723a958ffd56..dad1164397b112c687bcc13bd44e546e58d9d970 100644 --- a/src/main/java/net/minecraft/advancements/Advancement.java +++ b/src/main/java/net/minecraft/advancements/Advancement.java @@ -60,7 +60,7 @@ public record Advancement( @@ -14,7 +14,7 @@ index fb4b7652c386fa10783d71899615723a958ffd56..eb987b0cb6d2018e648c1488aa2059be boolean sendsTelemetryEvent ) { - this(parent, display, rewards, Map.copyOf(criteria), requirements, sendsTelemetryEvent, display.map(Advancement::decorateName)); -+ this(parent, display, rewards, !org.leavesmc.leaves.LeavesConfig.skipCloningAdvancementCriteria ? Map.copyOf(criteria) : criteria, requirements, sendsTelemetryEvent, display.map(Advancement::decorateName)); // Leaves - skip cloning advancement criteria ++ this(parent, display, rewards, !org.leavesmc.leaves.LeavesConfig.performance.skipCloningAdvancementCriteria ? Map.copyOf(criteria) : criteria, requirements, sendsTelemetryEvent, display.map(Advancement::decorateName)); // Leaves - skip cloning advancement criteria } private static DataResult validate(Advancement advancement) { diff --git a/patches/server/0082-Fix-villagers-dont-release-memory.patch b/patches/server/0082-Fix-villagers-dont-release-memory.patch new file mode 100644 index 00000000..2b5e309c --- /dev/null +++ b/patches/server/0082-Fix-villagers-dont-release-memory.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Sat, 22 Jul 2023 12:00:59 +0800 +Subject: [PATCH] Fix villagers dont release memory + + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index bab140f5489ab13bb67a3372cb1429e5ead1d93d..c317035db4f7456988dd02b72729ec6ad7703a7c 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -4021,7 +4021,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return this; + } + +- private Entity teleportCrossDimension(ServerLevel world, TeleportTransition teleportTarget) { ++ protected Entity teleportCrossDimension(ServerLevel world, TeleportTransition teleportTarget) { // Leaves - private -> protected + List list = this.getPassengers(); + List list1 = new ArrayList(list.size()); + +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 b7a34f1c4d7b5ef3f7a843d152e33c839dcdedd5..8d3959e86ef1357e49aac6ef3c8285c770f2856a 100644 +--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java ++++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java +@@ -1045,4 +1045,19 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + return worldTime - olong < 24000L; + }).isPresent(); + } ++ ++ // Leaves start - fixes a memory leak when villagers get moved to another world ++ @Override ++ public Entity teleportCrossDimension(ServerLevel world, net.minecraft.world.level.portal.TeleportTransition transition) { ++ if (org.leavesmc.leaves.LeavesConfig.performance.villagersDontReleaseMemoryFix) { ++ this.releaseAllPois(); ++ this.getBrain().eraseMemory(MemoryModuleType.HOME); ++ this.getBrain().eraseMemory(MemoryModuleType.JOB_SITE); ++ this.getBrain().eraseMemory(MemoryModuleType.POTENTIAL_JOB_SITE); ++ this.getBrain().eraseMemory(MemoryModuleType.MEETING_POINT); ++ this.refreshBrain(transition.newLevel()); ++ } ++ return super.teleportCrossDimension(world, transition); ++ } ++ // Leaves end - fixes a memory leak when villagers get moved to another world + } diff --git a/patches/server/0090-Avoid-anvil-too-expensive.patch b/patches/server/0083-Avoid-anvil-too-expensive.patch similarity index 63% rename from patches/server/0090-Avoid-anvil-too-expensive.patch rename to patches/server/0083-Avoid-anvil-too-expensive.patch index 69f7cd1b..78ab8064 100644 --- a/patches/server/0090-Avoid-anvil-too-expensive.patch +++ b/patches/server/0083-Avoid-anvil-too-expensive.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Avoid anvil too expensive diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -index 362278407679f245ebcea778f2199b357339e1fe..6f5a9ce4bf378f414887b93cb38a4d9b70e7b91f 100644 +index 286ae002e1711ad9e800b7f2091988d66cd572a7..d27f1b159984032f7cbbd8ed59ea7ab34bdfc79d 100644 --- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java +++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java -@@ -281,7 +281,7 @@ public class AnvilMenu extends ItemCombinerMenu { - this.cost.set(this.maximumRepairCost - 1); // CraftBukkit +@@ -287,7 +287,7 @@ public class AnvilMenu extends ItemCombinerMenu { + this.onlyRenaming = true; } - if (this.cost.get() >= this.maximumRepairCost && !this.player.getAbilities().instabuild) { // CraftBukkit -+ if (this.cost.get() >= this.maximumRepairCost && (!org.leavesmc.leaves.LeavesConfig.avoidAnvilTooExpensive || this.cost.get() == DEFAULT_DENIED_COST) && !this.player.getAbilities().instabuild) { // CraftBukkit // Leaves - avoid anvil too expensive ++ if (this.cost.get() >= this.maximumRepairCost && (!org.leavesmc.leaves.LeavesConfig.modify.avoidAnvilTooExpensive || this.cost.get() == DEFAULT_DENIED_COST) && !this.player.getAbilities().instabuild) { // CraftBukkit // Leaves - avoid anvil too expensive itemstack1 = ItemStack.EMPTY; } diff --git a/patches/server/0091-Bow-infinity-fix.patch b/patches/server/0084-Bow-infinity-fix.patch similarity index 64% rename from patches/server/0091-Bow-infinity-fix.patch rename to patches/server/0084-Bow-infinity-fix.patch index 4683509c..11c29b17 100644 --- a/patches/server/0091-Bow-infinity-fix.patch +++ b/patches/server/0084-Bow-infinity-fix.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Bow infinity fix 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 b737848442843b4d7decc140f51f77ed6f7c5f4b..015104dfdfe9673a928f20f2946571a543a16772 100644 +index b36d67774cf34cf95bcfbaa2fc8cb4f56b1e7557..fe9500f96709b9e15f63218de1b8a3f87007087c 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java -@@ -2348,7 +2348,7 @@ public abstract class Player extends LivingEntity { +@@ -2288,7 +2288,7 @@ public abstract class Player extends LivingEntity { } } - return this.abilities.instabuild ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; -+ return this.abilities.instabuild || (org.leavesmc.leaves.LeavesConfig.bowInfinityFix && net.minecraft.world.item.enchantment.EnchantmentHelper.processAmmoUse((ServerLevel) this.level(), stack, new ItemStack(Items.ARROW), 1) <= 0) ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; ++ return this.abilities.instabuild || (org.leavesmc.leaves.LeavesConfig.modify.bowInfinityFix && net.minecraft.world.item.enchantment.EnchantmentHelper.processAmmoUse((ServerLevel) this.level(), stack, new ItemStack(Items.ARROW), 1) <= 0) ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; } } } diff --git a/patches/server/0092-Zero-tick-plants.patch b/patches/server/0085-Zero-tick-plants.patch similarity index 79% rename from patches/server/0092-Zero-tick-plants.patch rename to patches/server/0085-Zero-tick-plants.patch index 82e12831..81510761 100644 --- a/patches/server/0092-Zero-tick-plants.patch +++ b/patches/server/0085-Zero-tick-plants.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Zero tick plants 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 e2951dd077441fe9cda461a2d3ef0c0671308316..a53d00991a02edf7e68faa1632d17f10136ccaf2 100644 +index 5e88bd02f5c53124f1aeec3eae727a1f83cc8238..6243ca580b976375084732e468adf83ff2f9cd1c 100644 --- a/src/main/java/net/minecraft/world/level/block/BambooStalkBlock.java +++ b/src/main/java/net/minecraft/world/level/block/BambooStalkBlock.java @@ -122,8 +122,11 @@ public class BambooStalkBlock extends Block implements BonemealableBlock { @@ -13,7 +13,7 @@ index e2951dd077441fe9cda461a2d3ef0c0671308316..a53d00991a02edf7e68faa1632d17f10 if (!state.canSurvive(world, pos)) { world.destroyBlock(pos, true); + // Leaves start - zero tick plants -+ } else if (org.leavesmc.leaves.LeavesConfig.zeroTickPlants) { ++ } else if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.zeroTickPlants) { + this.randomTick(state, world, pos, random); + // Leaves end - zero tick plants } @@ -22,15 +22,15 @@ index e2951dd077441fe9cda461a2d3ef0c0671308316..a53d00991a02edf7e68faa1632d17f10 @Override 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 ff4dda48116a2969704b355ff96407ba869b466e..8e544483b7556c9c54a8f5e9f691d4079e79db3c 100644 +index c045b1cccf0047dbef8c04d5a28d31d53389054f..5154d910639b431a9b9be6dc009b0be66280e5e3 100644 --- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java -@@ -46,8 +46,11 @@ public class CactusBlock extends Block { +@@ -47,8 +47,11 @@ public class CactusBlock extends Block { protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { if (!state.canSurvive(world, pos)) { world.destroyBlock(pos, true); + // Leaves start - zero tick plants -+ } else if (org.leavesmc.leaves.LeavesConfig.zeroTickPlants) { ++ } else if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.zeroTickPlants) { + this.randomTick(state, world, pos, random); + // Leaves end - zero tick plants } @@ -39,15 +39,15 @@ index ff4dda48116a2969704b355ff96407ba869b466e..8e544483b7556c9c54a8f5e9f691d407 @Override 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 6709cb6b657a8612781c2fe4dd76ee38f329c5ba..43978e5aee045577d3fb1e51a2b225c91f3d6c20 100644 +index 6d0d13e70a82c4db7848e1007f5b6d670dd5acad..2325219113f47424425a7896e8ccdca0e754ab4e 100644 --- a/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChorusFlowerBlock.java -@@ -51,8 +51,11 @@ public class ChorusFlowerBlock extends Block { +@@ -52,8 +52,11 @@ public class ChorusFlowerBlock extends Block { protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { if (!state.canSurvive(world, pos)) { world.destroyBlock(pos, true); + // Leaves start - zero tick plants -+ } else if (org.leavesmc.leaves.LeavesConfig.zeroTickPlants) { ++ } else if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.zeroTickPlants) { + this.randomTick(state, world, pos, random); + // Leaves end - zero tick plants } @@ -56,7 +56,7 @@ index 6709cb6b657a8612781c2fe4dd76ee38f329c5ba..43978e5aee045577d3fb1e51a2b225c9 @Override 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 cf05da1c86e3018db11dc079bf50317b6639e5cc..9c3599e5193bae23cca6f492be5e70fe1276e807 100644 +index 9b424d7661fedf8ee1eb9f3167c62e563f04d4d1..f385600aae4075a7776ef1517cbc0dcfe39b5718 100644 --- a/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java +++ b/src/main/java/net/minecraft/world/level/block/GrowingPlantHeadBlock.java @@ -142,4 +142,15 @@ public abstract class GrowingPlantHeadBlock extends GrowingPlantBlock implements @@ -69,14 +69,14 @@ index cf05da1c86e3018db11dc079bf50317b6639e5cc..9c3599e5193bae23cca6f492be5e70fe + public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + if (!state.canSurvive(world, pos)) { + world.destroyBlock(pos, true); -+ } else if (org.leavesmc.leaves.LeavesConfig.zeroTickPlants) { ++ } else if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.zeroTickPlants) { + this.randomTick(state, world, pos, random); + } + } + // Leaves end - zero tick plants } 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 c48c622e92cedeaa46b929c7adfedec98dd5a3fb..5415285dbb597eb3f5e6ca4749dc45820b571808 100644 +index 547ea09ed84595286c97c128b3b96f6d387ae25f..2c0b84fe8d3d891a32b1a50f265f7cffd8b9371f 100644 --- a/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SugarCaneBlock.java @@ -46,8 +46,11 @@ public class SugarCaneBlock extends Block { @@ -84,7 +84,7 @@ index c48c622e92cedeaa46b929c7adfedec98dd5a3fb..5415285dbb597eb3f5e6ca4749dc4582 if (!state.canSurvive(world, pos)) { world.destroyBlock(pos, true); + // Leaves start - zero tick plants -+ } else if (org.leavesmc.leaves.LeavesConfig.zeroTickPlants) { ++ } else if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.zeroTickPlants) { + this.randomTick(state, world, pos, random); + // Leaves end - zero tick plants } diff --git a/patches/server/0093-Leaves-Updater.patch b/patches/server/0086-Leaves-Updater.patch similarity index 97% rename from patches/server/0093-Leaves-Updater.patch rename to patches/server/0086-Leaves-Updater.patch index d765c7cc..ad53c227 100644 --- a/patches/server/0093-Leaves-Updater.patch +++ b/patches/server/0086-Leaves-Updater.patch @@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..7f94df607e8ffd48ab2cb7c90d520c2b +} diff --git a/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java new file mode 100644 -index 0000000000000000000000000000000000000000..f72e8bca8c2978abaf1acab30ca0853d484c1e6f +index 0000000000000000000000000000000000000000..0b48f91f0390092f08c157a822acf7af3eb96588 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/LeavesUpdateHelper.java @@ -0,0 +1,249 @@ @@ -131,11 +131,11 @@ index 0000000000000000000000000000000000000000..f72e8bca8c2978abaf1acab30ca0853d + } + } + -+ if (LeavesConfig.autoUpdate) { ++ if (LeavesConfig.mics.autoUpdate.enable) { + LocalTime currentTime = LocalTime.now(); + long dailyTaskPeriod = 24 * 60 * 60 * 1000; + -+ for (String time : LeavesConfig.autoUpdateTime) { ++ for (String time : LeavesConfig.mics.autoUpdate.updateTime) { + try { + LocalTime taskTime = LocalTime.of(Integer.parseInt(time.split(":")[0]), Integer.parseInt(time.split(":")[1])); + Duration task = Duration.between(currentTime, taskTime); @@ -188,7 +188,7 @@ index 0000000000000000000000000000000000000000..f72e8bca8c2978abaf1acab30ca0853d + + try ( + final ReadableByteChannel source = Channels.newChannel(new URI( -+ buildInfo.url + LeavesConfig.autoUpdateSource).toURL().openStream() ++ buildInfo.url + LeavesConfig.mics.autoUpdate.source).toURL().openStream() + ); + final FileChannel fileChannel = FileChannel.open(outFile, CREATE, WRITE, TRUNCATE_EXISTING) + ) { @@ -267,7 +267,7 @@ index 0000000000000000000000000000000000000000..f72e8bca8c2978abaf1acab30ca0853d + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), Charsets.UTF_8))) { + JsonObject obj = new Gson().fromJson(reader, JsonObject.class); + String channel = obj.get("channel").getAsString(); -+ if ("experimental".equals(channel) && !LeavesConfig.autoUpdateAllowExperimental) { ++ if ("experimental".equals(channel) && !LeavesConfig.mics.autoUpdate.allowExperimental) { + LeavesLogger.LOGGER.warning("Experimental version is not allowed to update for default, if you really want to update, please set misc.auto-update.allow-experimental to true in leaves.yml"); + return LeavesBuildInfo.ERROR; + } diff --git a/patches/server/0094-Force-peaceful-mode-switch.patch b/patches/server/0087-Force-peaceful-mode-switch.patch similarity index 71% rename from patches/server/0094-Force-peaceful-mode-switch.patch rename to patches/server/0087-Force-peaceful-mode-switch.patch index 5433e1a9..2e9fd014 100644 --- a/patches/server/0094-Force-peaceful-mode-switch.patch +++ b/patches/server/0087-Force-peaceful-mode-switch.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Force peaceful mode switch diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -index 68e445c21e0acbdf6bb74d50ddd32e0ef2c0e9ad..021a9e557a186cb4439ef46b6cb9d014256c3f9e 100644 +index d021cd5b6136f0125076513977f430c6d4dd4f9f..f2b46b264762f9f58eebc37ab3c217d949625506 100644 --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java -@@ -128,6 +128,12 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - // Paper end - rewrite chunk system - private ServerChunkCache.ChunkAndHolder[] iterationCopy; // Paper - chunk tick iteration optimisations +@@ -176,6 +176,12 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + // Paper end - chunk tick iteration optimisations + + // Leaves start - peaceful mode switch -+ public int peacefulModeSwitchTick = org.leavesmc.leaves.LeavesConfig.forcePeacefulMode; ++ public int peacefulModeSwitchTick = org.leavesmc.leaves.LeavesConfig.modify.forcePeacefulMode; + public int peacefulModeSwitchCount = -1; + private final List> peacefulModeSwitchEntityTypes = List.of(net.minecraft.world.entity.boss.wither.WitherBoss.class, net.minecraft.world.entity.monster.Shulker.class, net.minecraft.world.entity.monster.warden.Warden.class); + // Leaves end - peaceful mode switch @@ -21,11 +21,10 @@ index 68e445c21e0acbdf6bb74d50ddd32e0ef2c0e9ad..021a9e557a186cb4439ef46b6cb9d014 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; this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(world); -@@ -421,6 +427,22 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon +@@ -482,6 +488,21 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + if (!this.level.isDebug()) { + ProfilerFiller gameprofilerfiller = Profiler.get(); - gameprofilerfiller.push("pollingChunks"); - gameprofilerfiller.push("filteringLoadedChunks"); -+ + // Leaves start - peaceful mode switch + if (peacefulModeSwitchTick > 0) { + if (this.level.getLevelData().getGameTime() % peacefulModeSwitchTick == 0) { @@ -41,52 +40,52 @@ index 68e445c21e0acbdf6bb74d50ddd32e0ef2c0e9ad..021a9e557a186cb4439ef46b6cb9d014 + } + // Leaves end - peaceful mode switch + - // Paper start - chunk tick iteration optimisations - List list; - { -@@ -475,6 +497,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - gameprofilerfiller.popPush("spawnAndTick"); - boolean flag = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit + gameprofilerfiller.push("pollingChunks"); + if (this.level.tickRateManager().runsNormally()) { + List list = this.tickingChunks; +@@ -579,6 +600,15 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + int k = this.level.getGameRules().getInt(GameRules.RULE_RANDOMTICKING); + List list1; -+ // Leaves start - peaceful mode switch -+ boolean peacefulModeSwitch = false; -+ if (lastSpawnState != null && peacefulModeSwitchCount != -1) { -+ if (peacefulModeSwitchCount >= NaturalSpawner.globalLimitForCategory(level, net.minecraft.world.entity.MobCategory.MONSTER, lastSpawnState.getSpawnableChunkCount())) { -+ peacefulModeSwitch = true; -+ } -+ } -+ // Leaves end - peaceful mode switch -+ - 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; -@@ -497,7 +528,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon - 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); -+ NaturalSpawner.spawnForChunk(this.level, chunk1, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1, peacefulModeSwitch); - } ++ // Leaves start - peaceful mode switch ++ boolean peacefulModeSwitch = false; ++ if (lastSpawnState != null && peacefulModeSwitchCount != -1) { ++ if (peacefulModeSwitchCount >= NaturalSpawner.globalLimitForCategory(level, net.minecraft.world.entity.MobCategory.MONSTER, lastSpawnState.getSpawnableChunkCount())) { ++ peacefulModeSwitch = true; ++ } ++ } ++ // Leaves end - peaceful mode switch ++ + if (flag && (this.spawnEnemies || this.spawnFriendlies)) { + // Paper start - PlayerNaturallySpawnCreaturesEvent + for (ServerPlayer entityPlayer : this.level.players()) { +@@ -590,7 +620,7 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon + // 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 - if (true) { // Paper - rewrite chunk system +- list1 = NaturalSpawner.getFilteredSpawningCategories(spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1, this.level); // CraftBukkit ++ list1 = NaturalSpawner.getFilteredSpawningCategories(spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag1, this.level, peacefulModeSwitch); // CraftBukkit Leaves start - peaceful mode switch + } else { + list1 = List.of(); + } diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 7cb97b7623b603aa5469c92f5a6816673c994540..adc3169fb375f03c532d0abdaf336bab8079c559 100644 +index f817fd922ffcf857e8a5fc803b10421f640a8cd1..d5ece1268e7cab245a2ef2885bb83323d961bbd7 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -127,6 +127,12 @@ public final class NaturalSpawner { +@@ -131,7 +131,12 @@ public final class NaturalSpawner { } - public static void spawnForChunk(ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnState info, boolean spawnAnimals, boolean spawnMonsters, boolean rareSpawn) { -+ // Leaves start - peaceful mode switch -+ spawnForChunk(world, chunk, info, spawnAnimals, spawnMonsters, rareSpawn, false); + // CraftBukkit start - add server ++ // Leaves start - peaceful mode switch + public static List getFilteredSpawningCategories(NaturalSpawner.SpawnState spawnercreature_d, boolean flag, boolean flag1, boolean flag2, ServerLevel worldserver) { ++ return getFilteredSpawningCategories(spawnercreature_d, flag, flag1, flag2, worldserver, false); + } -+ -+ public static void spawnForChunk(ServerLevel world, LevelChunk chunk, NaturalSpawner.SpawnState info, boolean spawnAnimals, boolean spawnMonsters, boolean rareSpawn, boolean peacefulModeSwitch) { -+ // Leaves end - peaceful mode switch - world.getProfiler().push("spawner"); - MobCategory[] aenumcreaturetype = NaturalSpawner.SPAWNING_CATEGORIES; - int i = aenumcreaturetype.length; -@@ -135,6 +141,11 @@ public final class NaturalSpawner { ++ public static List getFilteredSpawningCategories(NaturalSpawner.SpawnState spawnercreature_d, boolean flag, boolean flag1, boolean flag2, ServerLevel worldserver, boolean peacefulModeSwitch) { ++ // Leaves end - peaceful mode switch + LevelData worlddata = worldserver.getLevelData(); // CraftBukkit - Other mob type spawn tick rate + // CraftBukkit end + List list = new ArrayList(NaturalSpawner.SPAWNING_CATEGORIES.length); +@@ -140,6 +145,11 @@ public final class NaturalSpawner { for (int j = 0; j < i; ++j) { MobCategory enumcreaturetype = aenumcreaturetype[j]; @@ -99,10 +98,10 @@ index 7cb97b7623b603aa5469c92f5a6816673c994540..adc3169fb375f03c532d0abdaf336bab boolean spawnThisTick = true; int limit = enumcreaturetype.getMaxInstancesPerChunk(); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index db2c1139f8471d12d6b80aab630b1426a084e47c..e08019b2191bf648a0a95ba0ef78d484ee4ff4ad 100644 +index df51d6d7909d407d8dcdbe1bfc5ca3a423005d5c..43a698baf88c7be00abbff517b95abc07ab67765 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -@@ -2417,6 +2417,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { +@@ -2410,6 +2410,18 @@ public class CraftWorld extends CraftRegionAccessor implements World { // Paper - replace feature flag API diff --git a/patches/server/0095-Replay-Mod-API.patch b/patches/server/0088-Replay-Mod-API.patch similarity index 95% rename from patches/server/0095-Replay-Mod-API.patch rename to patches/server/0088-Replay-Mod-API.patch index 8e81e931..db43c478 100644 --- a/patches/server/0095-Replay-Mod-API.patch +++ b/patches/server/0088-Replay-Mod-API.patch @@ -108,10 +108,10 @@ index c8d39e6e1c570c9219f6066da273dc0130920519..96a074281d16a7f64058619da4b102f3 if (((List) object).size() >= i) { return (List) object; diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 53c97644f30e61d7e2ccab2024714b8aa135287f..0c43170b31363beca32407bddeee33ef9404d09a 100644 +index 98d1e4c934e25e5c0dfe844e6aa3dd236d411da0..585d5d98abbd0a9842bef5d5cff24f8429f378d9 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -1690,7 +1690,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop !playerList.isOp(player.getGameProfile())) .map(player -> player.getGameProfile().getName()), diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index fc7ce6a031c50d270a979ec57e05cec0de7426c2..1337c4c2e966a8eeeee3480206025a6ee520747a 100644 +index a88ca4aaaca3c9e6370bba7e6fbdb0f57c6065f7..6952bd0b9229aa2c1c4db5d5659c315374e927a9 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2524,7 +2524,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2712,7 +2712,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); // Leaves start - skip @@ -159,7 +159,7 @@ index fc7ce6a031c50d270a979ec57e05cec0de7426c2..1337c4c2e966a8eeeee3480206025a6e ServerLevel.this.realPlayers.add(entityplayer); } // Leaves end - skip -@@ -2606,7 +2606,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2794,7 +2794,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.remove(entityplayer); // Leaves start - skip @@ -169,10 +169,10 @@ index fc7ce6a031c50d270a979ec57e05cec0de7426c2..1337c4c2e966a8eeeee3480206025a6e } // Leaves end - skip diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0dd70d03a 100644 +index aa864ac20bb3d0ddef8376768bf5921e81eb9597..0a88fb90b72e9f4bda6067cb42e024bb44b5101b 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -124,6 +124,7 @@ import org.bukkit.event.player.PlayerSpawnChangeEvent; +@@ -125,6 +125,7 @@ import org.bukkit.event.player.PlayerSpawnChangeEvent; // CraftBukkit end import org.leavesmc.leaves.bot.ServerBot; @@ -180,7 +180,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 public abstract class PlayerList { -@@ -156,6 +157,7 @@ public abstract class PlayerList { +@@ -157,6 +158,7 @@ public abstract class PlayerList { private boolean allowCommandsForAllPlayers; private static final boolean ALLOW_LOGOUTIVATOR = false; private int sendAllPlayerInfoIn; @@ -188,7 +188,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 // CraftBukkit start private CraftServer cserver; -@@ -182,6 +184,118 @@ public abstract class PlayerList { +@@ -183,6 +185,119 @@ public abstract class PlayerList { } abstract public void loadAndSaveFiles(); // Paper - fix converting txt to json file; moved from DedicatedPlayerList constructor @@ -216,8 +216,10 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 + player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit + playerconnection.send(new ClientboundChangeDifficultyPacket(worlddata.getDifficulty(), worlddata.isDifficultyLocked())); + playerconnection.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); -+ playerconnection.send(new ClientboundSetCarriedItemPacket(player.getInventory().selected)); -+ playerconnection.send(new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getRecipes())); ++ playerconnection.send(new ClientboundSetHeldSlotPacket(player.getInventory().selected)); ++ RecipeManager craftingmanager = this.server.getRecipeManager(); ++ playerconnection.send(new ClientboundUpdateRecipesPacket(craftingmanager.getSynchronizedItemProperties(), craftingmanager.getSynchronizedStonecutterRecipes())); ++ + this.sendPlayerPermissionLevel(player); + player.getStats().markAllDirty(); + player.getRecipeBook().sendInitialRecipeBook(player); @@ -238,7 +240,6 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 + player.supressTrackerForLogin = true; + worldserver1.addNewPlayer(player); + this.server.getCustomBossEvents().onPlayerConnect(player); -+ mountSavedVehicle(player, worldserver1, Optional.empty()); + CraftPlayer bukkitPlayer = player.getBukkitEntity(); + + player.containerMenu.transferTo(player.containerMenu, bukkitPlayer); @@ -249,7 +250,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 + // org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerJoin(player); // Leaves - protocol + + // Leaves start - bot support -+ if (org.leavesmc.leaves.LeavesConfig.fakeplayerSupport) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.fakeplayer.enable) { + ServerBot bot = this.server.getBotList().getBotByName(player.getScoreboardName()); + if (bot != null) { + this.server.getBotList().removeBot(bot, org.leavesmc.leaves.event.bot.BotRemoveEvent.RemoveReason.INTERNAL, player.getBukkitEntity(), false); @@ -287,18 +288,18 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 + } + + worldserver1 = player.serverLevel(); -+ Iterator iterator = player.getActiveEffects().iterator(); ++ Iterator iterator = player.getActiveEffects().iterator(); + while (iterator.hasNext()) { -+ MobEffectInstance mobeffect = (MobEffectInstance) iterator.next(); ++ MobEffectInstance mobeffect = iterator.next(); + playerconnection.send(new ClientboundUpdateMobEffectPacket(player.getId(), mobeffect, false)); + } + + 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) ++ .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, false) ++ worldserver1.getLightEngine(), null, null, false) + ); + } + } @@ -307,7 +308,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) { player.isRealPlayer = true; // Paper player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed -@@ -328,6 +442,7 @@ public abstract class PlayerList { +@@ -331,6 +446,7 @@ public abstract class PlayerList { // entityplayer.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below this.players.add(player); @@ -315,7 +316,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot this.playersByUUID.put(player.getUUID(), player); // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(entityplayer))); // CraftBukkit - replaced with loop below -@@ -397,6 +512,12 @@ public abstract class PlayerList { +@@ -401,6 +517,12 @@ public abstract class PlayerList { continue; } @@ -328,7 +329,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join } // Paper start - Use single player info update packet on join -@@ -601,6 +722,43 @@ public abstract class PlayerList { +@@ -551,6 +673,43 @@ public abstract class PlayerList { } @@ -372,7 +373,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // CraftBukkit - return string // Paper - return Component // Paper start - Fix kick event leave message not being sent return this.remove(entityplayer, 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()))); -@@ -669,6 +827,7 @@ public abstract class PlayerList { +@@ -633,6 +792,7 @@ public abstract class PlayerList { entityplayer.retireScheduler(); // Paper - Folia schedulers entityplayer.getAdvancements().stopListening(); this.players.remove(entityplayer); @@ -380,7 +381,7 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 this.playersByName.remove(entityplayer.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot this.server.getCustomBossEvents().onPlayerDisconnect(entityplayer); UUID uuid = entityplayer.getUUID(); -@@ -763,7 +922,7 @@ public abstract class PlayerList { +@@ -727,7 +887,7 @@ public abstract class PlayerList { event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure } else { // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameprofile) ? IChatBaseComponent.translatable("multiplayer.disconnect.server_full") : null; @@ -390,10 +391,10 @@ index 3322ee4e6720c8b06e6d6684cbac95c2d14babb1..fc6d2d5febe4a8c7f315997b3dde38b0 } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 61dd71c2d5efbcb5dd363e2ac16757011b454082..8649eae46402d53290f17181003bda5e97114d82 100644 +index 26ef09c86315c1125167af044323dbd3dbcfc6f0..ea4def367b645a442e7ee4fd8b1b2075b8604ccb 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -311,6 +311,7 @@ public final class CraftServer implements Server { +@@ -314,6 +314,7 @@ public final class CraftServer implements Server { private final io.papermc.paper.potion.PaperPotionBrewer potionBrewer; // Paper - Custom Potion Mixes public final io.papermc.paper.SparksFly spark; // Paper - spark private final org.leavesmc.leaves.entity.CraftBotManager botManager; // Leaves @@ -401,7 +402,7 @@ index 61dd71c2d5efbcb5dd363e2ac16757011b454082..8649eae46402d53290f17181003bda5e // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); -@@ -393,7 +394,7 @@ public final class CraftServer implements Server { +@@ -408,7 +409,7 @@ public final class CraftServer implements Server { public CraftServer(DedicatedServer console, PlayerList playerList) { this.console = console; this.playerList = (DedicatedPlayerList) playerList; @@ -410,7 +411,7 @@ index 61dd71c2d5efbcb5dd363e2ac16757011b454082..8649eae46402d53290f17181003bda5e @Override public CraftPlayer apply(ServerPlayer player) { return player.getBukkitEntity(); -@@ -3237,4 +3238,11 @@ public final class CraftServer implements Server { +@@ -3290,4 +3291,11 @@ public final class CraftServer implements Server { return botManager; } // Leaves end - Bot API @@ -423,10 +424,10 @@ index 61dd71c2d5efbcb5dd363e2ac16757011b454082..8649eae46402d53290f17181003bda5e + // Leaves end - replay mod api } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index 48d3e8c718fb0d2926f6b2f26855bbbe115ccf7a..10593c39418f8483975865a218078f4ed8e85d4d 100644 +index dea387f418cd173980be2e6e24797b55f9f58409..3e230983586f044c3a5e021fc8e27f6b88978bf6 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -95,6 +95,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { +@@ -96,6 +96,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } if (entity instanceof org.leavesmc.leaves.bot.ServerBot bot) { return new org.leavesmc.leaves.entity.CraftBot(server, bot); } @@ -435,10 +436,10 @@ index 48d3e8c718fb0d2926f6b2f26855bbbe115ccf7a..10593c39418f8483975865a218078f4e // Special case complex part, since there is no extra entity type for them if (entity instanceof EnderDragonPart complexPart) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 42d7660efe5baa6f796f2a7606686c765b6f2478..79ebcaac331c8f8860928668701c791b54bdb66b 100644 +index 554714e449d1d2439b05d7e15f72afccd17d4df5..08de38dfc4b2f6f48e9f3ae1d303712ea619e21f 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -2247,7 +2247,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -2259,7 +2259,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public boolean canSee(Player player) { @@ -699,10 +700,10 @@ index 0000000000000000000000000000000000000000..0e8cd7e878ec1294d6cb830a004eeefd +} diff --git a/src/main/java/org/leavesmc/leaves/replay/Recorder.java b/src/main/java/org/leavesmc/leaves/replay/Recorder.java new file mode 100644 -index 0000000000000000000000000000000000000000..49cf69a916eed2ec4753f286e3a53cc8d0429a41 +index 0000000000000000000000000000000000000000..ba0dde3f006b43ef04d252f970ea1315566c45e6 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/replay/Recorder.java -@@ -0,0 +1,288 @@ +@@ -0,0 +1,286 @@ +package org.leavesmc.leaves.replay; + +import com.mojang.serialization.DynamicOps; @@ -732,7 +733,7 @@ index 0000000000000000000000000000000000000000..49cf69a916eed2ec4753f286e3a53cc8 +import net.minecraft.network.protocol.game.ClientboundPlayerChatPacket; +import net.minecraft.network.protocol.game.ClientboundSetTimePacket; +import net.minecraft.network.protocol.game.ClientboundSystemChatPacket; -+import net.minecraft.network.protocol.login.ClientboundGameProfilePacket; ++import net.minecraft.network.protocol.login.ClientboundLoginFinishedPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.RegistryLayer; +import net.minecraft.server.packs.repository.KnownPack; @@ -797,7 +798,7 @@ index 0000000000000000000000000000000000000000..49cf69a916eed2ec4753f286e3a53cc8 + metaData.mcversion = SharedConstants.getCurrentVersion().getName(); + + // TODO start event -+ savePacket(new ClientboundGameProfilePacket(photographer.getGameProfile(), true), ConnectionProtocol.LOGIN); ++ savePacket(new ClientboundLoginFinishedPacket(photographer.getGameProfile()), ConnectionProtocol.LOGIN); + startConfiguration(); + + if (recorderOption.forceWeather != null) { @@ -880,9 +881,7 @@ index 0000000000000000000000000000000000000000..49cf69a916eed2ec4753f286e3a53cc8 + public void send(@NotNull Packet packet, @Nullable PacketSendListener callbacks, boolean flush) { + if (!stopped) { + if (packet instanceof BundlePacket packet1) { -+ packet1.subPackets().forEach(subPacket -> { -+ send(subPacket, null); -+ }); ++ packet1.subPackets().forEach(subPacket -> send(subPacket, null)); + return; + } + @@ -898,7 +897,7 @@ index 0000000000000000000000000000000000000000..49cf69a916eed2ec4753f286e3a53cc8 + } + + if (recorderOption.forceDayTime != -1 && packet instanceof ClientboundSetTimePacket packet1) { -+ packet = new ClientboundSetTimePacket(packet1.getDayTime(), recorderOption.forceDayTime, false); ++ packet = new ClientboundSetTimePacket(packet1.dayTime(), recorderOption.forceDayTime, false); + } + + if (recorderOption.forceWeather != null && packet instanceof ClientboundGameEventPacket packet1) { @@ -1310,7 +1309,7 @@ index 0000000000000000000000000000000000000000..1568f6928d5d4f38ca1919c6de6ec9bb +} diff --git a/src/main/java/org/leavesmc/leaves/replay/ServerPhotographer.java b/src/main/java/org/leavesmc/leaves/replay/ServerPhotographer.java new file mode 100644 -index 0000000000000000000000000000000000000000..f5c6e823d7ab9a61307e27e7b859e76bdfdd1e58 +index 0000000000000000000000000000000000000000..d8f8f071c67cd0e29411d3f0f3b5e931abe86f65 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/replay/ServerPhotographer.java @@ -0,0 +1,222 @@ @@ -1418,12 +1417,12 @@ index 0000000000000000000000000000000000000000..f5c6e823d7ab9a61307e27e7b859e76b + } + + @Override -+ public boolean isInvulnerableTo(@NotNull DamageSource damageSource) { ++ public boolean isInvulnerableTo(@NotNull ServerLevel world, @NotNull DamageSource damageSource) { + return true; + } + + @Override -+ public boolean hurt(@NotNull DamageSource source, float amount) { ++ public boolean hurtServer(@NotNull ServerLevel world, @NotNull DamageSource source, float amount) { + return false; + } + diff --git a/patches/server/0089-Fix-villagers-dont-release-memory.patch b/patches/server/0089-Fix-villagers-dont-release-memory.patch deleted file mode 100644 index b0b38955..00000000 --- a/patches/server/0089-Fix-villagers-dont-release-memory.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Sat, 22 Jul 2023 12:00:59 +0800 -Subject: [PATCH] Fix villagers dont release memory - - -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 7e1871401ec5e3e9a85232053490259f132aec0a..18642b4e43d0725690be44b53bbddb6d4486e5f1 100644 ---- a/src/main/java/net/minecraft/world/entity/npc/Villager.java -+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java -@@ -1071,4 +1071,20 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - - return optional.isPresent() ? worldTime - (Long) optional.get() < 24000L : false; - } -+ -+ // Leaves start - fixes a memory leak when villagers get moved to another world -+ @Nullable -+ @Override -+ public Entity changeDimension(net.minecraft.world.level.portal.DimensionTransition destination) { -+ if (org.leavesmc.leaves.LeavesConfig.villagersDontReleaseMemoryFix) { -+ this.releaseAllPois(); -+ this.getBrain().eraseMemory(MemoryModuleType.HOME); -+ this.getBrain().eraseMemory(MemoryModuleType.JOB_SITE); -+ this.getBrain().eraseMemory(MemoryModuleType.POTENTIAL_JOB_SITE); -+ this.getBrain().eraseMemory(MemoryModuleType.MEETING_POINT); -+ this.refreshBrain(destination.newLevel()); -+ } -+ return super.changeDimension(destination); -+ } -+ // Leaves end - fixes a memory leak when villagers get moved to another world - } diff --git a/patches/server/0096-Leaves-I18n.patch b/patches/server/0089-Leaves-I18n.patch similarity index 99% rename from patches/server/0096-Leaves-I18n.patch rename to patches/server/0089-Leaves-I18n.patch index 72724b25..65a81166 100644 --- a/patches/server/0096-Leaves-I18n.patch +++ b/patches/server/0089-Leaves-I18n.patch @@ -5,28 +5,30 @@ Subject: [PATCH] Leaves I18n diff --git a/src/main/java/net/minecraft/locale/Language.java b/src/main/java/net/minecraft/locale/Language.java -index a9bca1d10553f1406f7dbce3f7c40378b6abdc10..aa7f4f738c637ffc3d50f2bdb5ee61ffdc6cea1f 100644 +index 93bf8a8adbf9082982fa01fc999d14d11afe0168..f2ed44f4cf7ac490424ae84d21b3a4644f52acfd 100644 --- a/src/main/java/net/minecraft/locale/Language.java +++ b/src/main/java/net/minecraft/locale/Language.java -@@ -32,6 +32,41 @@ public abstract class Language { +@@ -31,6 +31,42 @@ public abstract class Language { public static final String DEFAULT = "en_us"; private static volatile Language instance = loadDefault(); + // Leaves start - i18n + public static void loadI18N(String lang) { -+ ImmutableMap.Builder builder = ImmutableMap.builder(); -+ BiConsumer biConsumer = builder::put; ++ DeprecatedTranslationsInfo deprecatedTranslationsInfo = DeprecatedTranslationsInfo.loadFromDefaultResource(); ++ Map map = new HashMap<>(); ++ BiConsumer biConsumer = map::put; + parseTranslations(biConsumer, "/assets/minecraft/lang/" + lang + ".json"); -+ final Map map = builder.build(); ++ deprecatedTranslationsInfo.applyToMap(map); ++ final Map map2 = Map.copyOf(map); + Language language = new Language() { + @Override + public String getOrDefault(String key, String fallback) { -+ return map.getOrDefault(key, fallback); ++ return map2.getOrDefault(key, fallback); + } + + @Override + public boolean has(String key) { -+ return map.containsKey(key); ++ return map2.containsKey(key); + } + + @Override @@ -36,11 +38,10 @@ index a9bca1d10553f1406f7dbce3f7c40378b6abdc10..aa7f4f738c637ffc3d50f2bdb5ee61ff + + @Override + public FormattedCharSequence getVisualOrder(FormattedText text) { -+ return (visitor) -> { -+ return text.visit((style, string) -> { -+ return StringDecomposer.iterateFormatted(string, style, visitor) ? Optional.empty() : FormattedText.STOP_ITERATION; -+ }, Style.EMPTY).isPresent(); -+ }; ++ return visitor -> text.visit( ++ (style, string) -> StringDecomposer.iterateFormatted(string, style, visitor) ? Optional.empty() : FormattedText.STOP_ITERATION, ++ Style.EMPTY ++ ).isPresent(); + } + }; + inject(language); @@ -48,17 +49,17 @@ index a9bca1d10553f1406f7dbce3f7c40378b6abdc10..aa7f4f738c637ffc3d50f2bdb5ee61ff + // Leaves end - i18n + private static Language loadDefault() { - Builder builder = ImmutableMap.builder(); - BiConsumer biConsumer = builder::put; + DeprecatedTranslationsInfo deprecatedTranslationsInfo = DeprecatedTranslationsInfo.loadFromDefaultResource(); + Map map = new HashMap<>(); diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index e45acea31d61462c877c902b238209f14f2c8ad1..3e4d4c417904fba6aeba0dee2e01d3b5bd95ac20 100644 +index 679a40aeedc7e259401a6c244ed54136d6c75a40..f6c081b3362d9b84d16874e8af30e2f865b3ef7c 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -241,6 +241,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -239,6 +239,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface org.leavesmc.leaves.LeavesConfig.init((java.io.File) options.valueOf("leaves-settings")); // Leaves - Server Config System.setProperty("spark.serverconfigs.extra", "leaves.yml"); // Leaves - spark config -+ net.minecraft.locale.Language.loadI18N(org.leavesmc.leaves.LeavesConfig.serverLang); // Leaves - i18n ++ net.minecraft.locale.Language.loadI18N(org.leavesmc.leaves.LeavesConfig.mics.serverLang); // Leaves - i18n com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics // Leaves - down diff --git a/patches/server/0097-Fix-minecraft-hopper-not-work-without-player.patch b/patches/server/0090-Fix-minecraft-hopper-not-work-without-player.patch similarity index 84% rename from patches/server/0097-Fix-minecraft-hopper-not-work-without-player.patch rename to patches/server/0090-Fix-minecraft-hopper-not-work-without-player.patch index 33bd32ad..fdd01a25 100644 --- a/patches/server/0097-Fix-minecraft-hopper-not-work-without-player.patch +++ b/patches/server/0090-Fix-minecraft-hopper-not-work-without-player.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix minecraft hopper not work without player 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 d7f8464bf3eed0e42a5fc7f14a5b243d171f8b5e..265022e4c56472c7d673eb7b03359b2d57ee507c 100644 +index d81a6874e8b25f098df619f84c359e146c7f64de..6c2045844bb18767c0645c24e6629b59beb25f4e 100644 --- a/src/main/java/net/minecraft/world/entity/vehicle/MinecartHopper.java +++ b/src/main/java/net/minecraft/world/entity/vehicle/MinecartHopper.java -@@ -91,6 +91,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -99,6 +99,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper } } diff --git a/patches/server/0098-RNG-Fishing.patch b/patches/server/0091-RNG-Fishing.patch similarity index 81% rename from patches/server/0098-RNG-Fishing.patch rename to patches/server/0091-RNG-Fishing.patch index 2d4155d5..f4e698fc 100644 --- a/patches/server/0098-RNG-Fishing.patch +++ b/patches/server/0091-RNG-Fishing.patch @@ -5,15 +5,15 @@ Subject: [PATCH] RNG 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 0e00f59a8962dd6356d483ef5be3209a3a410008..1c556f9cca2d21c3bdb49cb22263a597c6a8680f 100644 +index d5cb0d8ad7f7ed18ce38b39f245f5ec2c67042d5..74adc702a4503631df9fa575eee3ef388e8c3937 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java +++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java -@@ -523,7 +523,7 @@ public class FishingHook extends Projectile { +@@ -528,7 +528,7 @@ public class FishingHook extends Projectile { } else if (this.nibble > 0) { LootParams lootparams = (new LootParams.Builder((ServerLevel) this.level())).withParameter(LootContextParams.ORIGIN, this.position()).withParameter(LootContextParams.TOOL, usedItem).withParameter(LootContextParams.THIS_ENTITY, this).withLuck((float) this.luck + entityhuman.getLuck()).create(LootContextParamSets.FISHING); LootTable loottable = this.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.FISHING); - List list = loottable.getRandomItems(lootparams); -+ List list = org.leavesmc.leaves.LeavesConfig.rngFishing ? loottable.getRandomItems(lootparams, this.random) : loottable.getRandomItems(lootparams); // Leaves - world random ++ List list = org.leavesmc.leaves.LeavesConfig.modify.oldMC.rngFishing ? loottable.getRandomItems(lootparams, this.random) : loottable.getRandomItems(lootparams); // Leaves - world random CriteriaTriggers.FISHING_ROD_HOOKED.trigger((ServerPlayer) entityhuman, usedItem, this, list); Iterator iterator = list.iterator(); diff --git a/patches/server/0099-Wool-Hopper-Counter.patch b/patches/server/0092-Wool-Hopper-Counter.patch similarity index 64% rename from patches/server/0099-Wool-Hopper-Counter.patch rename to patches/server/0092-Wool-Hopper-Counter.patch index ef49ab5b..590416b1 100644 --- a/patches/server/0099-Wool-Hopper-Counter.patch +++ b/patches/server/0092-Wool-Hopper-Counter.patch @@ -5,21 +5,8 @@ Subject: [PATCH] Wool Hopper Counter This patch is Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet) -diff --git a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java -index e314f36951e9ac15c57137e24fce8c410373130a..dd232d9e86c5bf03cfb4597d3291a172d8c17741 100644 ---- a/src/main/java/net/minecraft/world/item/crafting/Ingredient.java -+++ b/src/main/java/net/minecraft/world/item/crafting/Ingredient.java -@@ -35,7 +35,7 @@ public final class Ingredient implements Predicate { - }, (recipeitemstack) -> { - return Arrays.asList(recipeitemstack.getItems()); - }); -- private final Ingredient.Value[] values; -+ public final Ingredient.Value[] values; // Leaves - private -> public - @Nullable - public ItemStack[] itemStacks; - @Nullable 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 cee74a6c47cd56a17a8faf68405fee09d6fd4655..9cc932fb547686db7c06f7ef29e3b07b2e755982 100644 +index 7280d2216dcbe09278a2447eb994c4bd2aa98576..af3846dbb29d4738d0cce20c85d2f40c7ccf4f70 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 @@ -447,7 +447,14 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -75,7 +62,7 @@ index 92a8c3e4fc400988b3d984e7632a8149a2ce152e..99823283690fcc1e6c0f76d8dcbcca9d .flatMap(entry -> entry.getKey().stream().map(s -> Map.entry(s, entry.getValue()))) diff --git a/src/main/java/org/leavesmc/leaves/command/subcommands/CounterCommand.java b/src/main/java/org/leavesmc/leaves/command/subcommands/CounterCommand.java new file mode 100644 -index 0000000000000000000000000000000000000000..06b4d287bf545a51b9eeb7cd24fdc6a0c05271d9 +index 0000000000000000000000000000000000000000..6d0e3c9a95f1e0f32ae6b3149a21abe268b22951 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/command/subcommands/CounterCommand.java @@ -0,0 +1,121 @@ @@ -103,7 +90,7 @@ index 0000000000000000000000000000000000000000..06b4d287bf545a51b9eeb7cd24fdc6a0 + + @Override + public boolean execute(CommandSender sender, String subCommand, String[] args) { -+ if (!LeavesConfig.hopperCounter) { ++ if (!LeavesConfig.modify.hopperCounter) { + return false; + } + @@ -169,7 +156,7 @@ index 0000000000000000000000000000000000000000..06b4d287bf545a51b9eeb7cd24fdc6a0 + + @Override + public List tabComplete(CommandSender sender, String subCommand, String[] args) { -+ if (!LeavesConfig.hopperCounter) { ++ if (!LeavesConfig.modify.hopperCounter) { + return Collections.emptyList(); + } + @@ -197,15 +184,15 @@ index 0000000000000000000000000000000000000000..06b4d287bf545a51b9eeb7cd24fdc6a0 + + @Override + public boolean tabCompletes() { -+ return LeavesConfig.hopperCounter; ++ return LeavesConfig.modify.hopperCounter; + } +} diff --git a/src/main/java/org/leavesmc/leaves/util/HopperCounter.java b/src/main/java/org/leavesmc/leaves/util/HopperCounter.java new file mode 100644 -index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a556c17a3 +index 0000000000000000000000000000000000000000..62f20b111944a429ee0f2a51fcdfe4ad7d9a44c3 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/HopperCounter.java -@@ -0,0 +1,338 @@ +@@ -0,0 +1,337 @@ +package org.leavesmc.leaves.util; + +import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap; @@ -216,11 +203,15 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.format.TextDecoration; ++import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; ++import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; ++import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; ++import net.minecraft.util.context.ContextMap; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.DyeItem; @@ -229,9 +220,10 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; -+import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeManager; -+import net.minecraft.world.item.crafting.RecipeType; ++import net.minecraft.world.item.crafting.display.RecipeDisplay; ++import net.minecraft.world.item.crafting.display.SlotDisplayContext; ++import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.AbstractBannerBlock; +import net.minecraft.world.level.block.BeaconBeamBlock; +import net.minecraft.world.level.block.Block; @@ -242,15 +234,16 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a +import org.leavesmc.leaves.LeavesConfig; + +import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; ++import java.util.Optional; + +import static java.util.Map.entry; + ++// Powered by fabric-carpet(https://github.com/gnembon/fabric-carpet) ++ +public class HopperCounter { + + private static boolean enabled = false; @@ -291,6 +284,15 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + startMillis = System.currentTimeMillis(); + } + ++ public static void resetAll(MinecraftServer server, boolean fresh) { ++ for (HopperCounter counter : COUNTERS.values()) { ++ counter.reset(server); ++ if (fresh) { ++ counter.startTick = -1; ++ } ++ } ++ } ++ + public List format(MinecraftServer server, boolean realTime) { + long ticks = Math.max(realTime ? (System.currentTimeMillis() - startMillis) / 50 : server.overworld().getGameTime() - startTick, -1); + @@ -301,23 +303,23 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + long total = getTotalItems(); + if (total <= 0) { + return Collections.singletonList(Component.text() -+ .append(Component.text("No items for "), coloredName) -+ .append(Component.text(" yet ("), Component.text(String.format("%.2f ", ticks / (20.0 * 60.0)), Style.style(TextDecoration.BOLD))) -+ .append(Component.text("min"), Component.text(realTime ? " - real time" : ""), Component.text(")")) -+ .build()); ++ .append(Component.text("No items for "), coloredName) ++ .append(Component.text(" yet ("), Component.text(String.format("%.2f ", ticks / (20.0 * 60.0)), Style.style(TextDecoration.BOLD))) ++ .append(Component.text("min"), Component.text(realTime ? " - real time" : ""), Component.text(")")) ++ .build()); + } + + List items = new ArrayList<>(); + items.add(Component.text() -+ .append(Component.text("Items for "), coloredName, Component.text(" ")) -+ .append(Component.text("("), Component.text(String.format("%.2f ", ticks * 1.0 / (20 * 60)), Style.style(TextDecoration.BOLD))) -+ .append(Component.text("min"), Component.text(realTime ? " - real time" : ""), Component.text("), ")) -+ .append(Component.text("total: "), Component.text(total, Style.style(TextDecoration.BOLD)), Component.text(", ")) -+ .append(Component.text("("), Component.text(String.format("%.1f", total * 1.0 * (20 * 60 * 60) / ticks), Style.style(TextDecoration.BOLD))) -+ .append(Component.text("/h):")) -+ .build()); -+ -+ counter.object2LongEntrySet().forEach(entry -> { ++ .append(Component.text("Items for "), coloredName, Component.text(" ")) ++ .append(Component.text("("), Component.text(String.format("%.2f ", ticks * 1.0 / (20 * 60)), Style.style(TextDecoration.BOLD))) ++ .append(Component.text("min"), Component.text(realTime ? " - real time" : ""), Component.text("), ")) ++ .append(Component.text("total: "), Component.text(total, Style.style(TextDecoration.BOLD)), Component.text(", ")) ++ .append(Component.text("("), Component.text(String.format("%.1f", total * 1.0 * (20 * 60 * 60) / ticks), Style.style(TextDecoration.BOLD))) ++ .append(Component.text("/h):")) ++ .build()); ++ ++ items.addAll(counter.object2LongEntrySet().stream().sorted((e, f) -> Long.compare(f.getLongValue(), e.getLongValue())).map(entry -> { + Item item = entry.getKey(); + Component name = Component.translatable(item.getDescriptionId()); + TextColor textColor = guessColor(server, item); @@ -329,103 +331,103 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + } + + long count = entry.getLongValue(); -+ items.add(Component.text() -+ .append(Component.text("- ", NamedTextColor.GRAY)) -+ .append(name) -+ .append(Component.text(": ", NamedTextColor.GRAY)) -+ .append(Component.text(count, Style.style(TextDecoration.BOLD)), Component.text(", ", NamedTextColor.GRAY)) -+ .append(Component.text(String.format("%.1f", count * (20.0 * 60.0 * 60.0) / ticks), Style.style(TextDecoration.BOLD))) -+ .append(Component.text("/h")) -+ .build()); -+ }); ++ return Component.text() ++ .append(Component.text("- ", NamedTextColor.GRAY)) ++ .append(name) ++ .append(Component.text(": ", NamedTextColor.GRAY)) ++ .append(Component.text(count, Style.style(TextDecoration.BOLD)), Component.text(", ", NamedTextColor.GRAY)) ++ .append(Component.text(String.format("%.1f", count * (20.0 * 60.0 * 60.0) / ticks), Style.style(TextDecoration.BOLD))) ++ .append(Component.text("/h")) ++ .build(); ++ }).toList()); + return items; + } + + private static final Map DEFAULTS = Map.ofEntries( -+ entry(Items.DANDELION, Blocks.YELLOW_WOOL), -+ entry(Items.POPPY, Blocks.RED_WOOL), -+ entry(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL), -+ entry(Items.ALLIUM, Blocks.MAGENTA_WOOL), -+ entry(Items.AZURE_BLUET, Blocks.SNOW_BLOCK), -+ entry(Items.RED_TULIP, Blocks.RED_WOOL), -+ entry(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL), -+ entry(Items.WHITE_TULIP, Blocks.SNOW_BLOCK), -+ entry(Items.PINK_TULIP, Blocks.PINK_WOOL), -+ entry(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK), -+ entry(Items.CORNFLOWER, Blocks.BLUE_WOOL), -+ entry(Items.WITHER_ROSE, Blocks.BLACK_WOOL), -+ entry(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL), -+ entry(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK), -+ entry(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK), -+ entry(Items.STICK, Blocks.OAK_PLANKS), -+ entry(Items.GOLD_INGOT, Blocks.GOLD_BLOCK), -+ entry(Items.IRON_INGOT, Blocks.IRON_BLOCK), -+ entry(Items.DIAMOND, Blocks.DIAMOND_BLOCK), -+ entry(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK), -+ entry(Items.SUNFLOWER, Blocks.YELLOW_WOOL), -+ entry(Items.LILAC, Blocks.MAGENTA_WOOL), -+ entry(Items.ROSE_BUSH, Blocks.RED_WOOL), -+ entry(Items.PEONY, Blocks.PINK_WOOL), -+ entry(Items.CARROT, Blocks.ORANGE_WOOL), -+ entry(Items.APPLE, Blocks.RED_WOOL), -+ entry(Items.WHEAT, Blocks.HAY_BLOCK), -+ entry(Items.PORKCHOP, Blocks.PINK_WOOL), -+ entry(Items.RABBIT, Blocks.PINK_WOOL), -+ entry(Items.CHICKEN, Blocks.WHITE_TERRACOTTA), -+ entry(Items.BEEF, Blocks.NETHERRACK), -+ entry(Items.ENCHANTED_GOLDEN_APPLE, Blocks.GOLD_BLOCK), -+ entry(Items.COD, Blocks.WHITE_TERRACOTTA), -+ entry(Items.SALMON, Blocks.ACACIA_PLANKS), -+ entry(Items.ROTTEN_FLESH, Blocks.BROWN_WOOL), -+ entry(Items.PUFFERFISH, Blocks.YELLOW_TERRACOTTA), -+ entry(Items.TROPICAL_FISH, Blocks.ORANGE_WOOL), -+ entry(Items.POTATO, Blocks.WHITE_TERRACOTTA), -+ entry(Items.MUTTON, Blocks.RED_WOOL), -+ entry(Items.BEETROOT, Blocks.NETHERRACK), -+ entry(Items.MELON_SLICE, Blocks.MELON), -+ entry(Items.POISONOUS_POTATO, Blocks.SLIME_BLOCK), -+ entry(Items.SPIDER_EYE, Blocks.NETHERRACK), -+ entry(Items.GUNPOWDER, Blocks.GRAY_WOOL), -+ entry(Items.TURTLE_SCUTE, Blocks.LIME_WOOL), -+ entry(Items.ARMADILLO_SCUTE, Blocks.ANCIENT_DEBRIS), -+ entry(Items.FEATHER, Blocks.WHITE_WOOL), -+ entry(Items.FLINT, Blocks.BLACK_WOOL), -+ entry(Items.LEATHER, Blocks.SPRUCE_PLANKS), -+ entry(Items.GLOWSTONE_DUST, Blocks.GLOWSTONE), -+ entry(Items.PAPER, Blocks.WHITE_WOOL), -+ entry(Items.BRICK, Blocks.BRICKS), -+ entry(Items.INK_SAC, Blocks.BLACK_WOOL), -+ entry(Items.SNOWBALL, Blocks.SNOW_BLOCK), -+ entry(Items.WATER_BUCKET, Blocks.WATER), -+ entry(Items.LAVA_BUCKET, Blocks.LAVA), -+ entry(Items.MILK_BUCKET, Blocks.WHITE_WOOL), -+ entry(Items.CLAY_BALL, Blocks.CLAY), -+ entry(Items.COCOA_BEANS, Blocks.COCOA), -+ entry(Items.BONE, Blocks.BONE_BLOCK), -+ entry(Items.COD_BUCKET, Blocks.BROWN_TERRACOTTA), -+ entry(Items.PUFFERFISH_BUCKET, Blocks.YELLOW_TERRACOTTA), -+ entry(Items.SALMON_BUCKET, Blocks.PINK_TERRACOTTA), -+ entry(Items.TROPICAL_FISH_BUCKET, Blocks.ORANGE_TERRACOTTA), -+ entry(Items.SUGAR, Blocks.WHITE_WOOL), -+ entry(Items.BLAZE_POWDER, Blocks.GOLD_BLOCK), -+ entry(Items.ENDER_PEARL, Blocks.WARPED_PLANKS), -+ entry(Items.NETHER_STAR, Blocks.DIAMOND_BLOCK), -+ entry(Items.PRISMARINE_CRYSTALS, Blocks.SEA_LANTERN), -+ entry(Items.PRISMARINE_SHARD, Blocks.PRISMARINE), -+ entry(Items.RABBIT_HIDE, Blocks.OAK_PLANKS), -+ entry(Items.CHORUS_FRUIT, Blocks.PURPUR_BLOCK), -+ entry(Items.SHULKER_SHELL, Blocks.SHULKER_BOX), -+ entry(Items.NAUTILUS_SHELL, Blocks.BONE_BLOCK), -+ entry(Items.HEART_OF_THE_SEA, Blocks.CONDUIT), -+ entry(Items.HONEYCOMB, Blocks.HONEYCOMB_BLOCK), -+ entry(Items.NAME_TAG, Blocks.BONE_BLOCK), -+ entry(Items.TOTEM_OF_UNDYING, Blocks.YELLOW_TERRACOTTA), -+ entry(Items.TRIDENT, Blocks.PRISMARINE), -+ entry(Items.GHAST_TEAR, Blocks.WHITE_WOOL), -+ entry(Items.PHANTOM_MEMBRANE, Blocks.BONE_BLOCK), -+ entry(Items.EGG, Blocks.BONE_BLOCK), -+ entry(Items.COPPER_INGOT, Blocks.COPPER_BLOCK), -+ entry(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK) ++ entry(Items.DANDELION, Blocks.YELLOW_WOOL), ++ entry(Items.POPPY, Blocks.RED_WOOL), ++ entry(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL), ++ entry(Items.ALLIUM, Blocks.MAGENTA_WOOL), ++ entry(Items.AZURE_BLUET, Blocks.SNOW_BLOCK), ++ entry(Items.RED_TULIP, Blocks.RED_WOOL), ++ entry(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL), ++ entry(Items.WHITE_TULIP, Blocks.SNOW_BLOCK), ++ entry(Items.PINK_TULIP, Blocks.PINK_WOOL), ++ entry(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK), ++ entry(Items.CORNFLOWER, Blocks.BLUE_WOOL), ++ entry(Items.WITHER_ROSE, Blocks.BLACK_WOOL), ++ entry(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL), ++ entry(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK), ++ entry(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK), ++ entry(Items.STICK, Blocks.OAK_PLANKS), ++ entry(Items.GOLD_INGOT, Blocks.GOLD_BLOCK), ++ entry(Items.IRON_INGOT, Blocks.IRON_BLOCK), ++ entry(Items.DIAMOND, Blocks.DIAMOND_BLOCK), ++ entry(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK), ++ entry(Items.SUNFLOWER, Blocks.YELLOW_WOOL), ++ entry(Items.LILAC, Blocks.MAGENTA_WOOL), ++ entry(Items.ROSE_BUSH, Blocks.RED_WOOL), ++ entry(Items.PEONY, Blocks.PINK_WOOL), ++ entry(Items.CARROT, Blocks.ORANGE_WOOL), ++ entry(Items.APPLE, Blocks.RED_WOOL), ++ entry(Items.WHEAT, Blocks.HAY_BLOCK), ++ entry(Items.PORKCHOP, Blocks.PINK_WOOL), ++ entry(Items.RABBIT, Blocks.PINK_WOOL), ++ entry(Items.CHICKEN, Blocks.WHITE_TERRACOTTA), ++ entry(Items.BEEF, Blocks.NETHERRACK), ++ entry(Items.ENCHANTED_GOLDEN_APPLE, Blocks.GOLD_BLOCK), ++ entry(Items.COD, Blocks.WHITE_TERRACOTTA), ++ entry(Items.SALMON, Blocks.ACACIA_PLANKS), ++ entry(Items.ROTTEN_FLESH, Blocks.BROWN_WOOL), ++ entry(Items.PUFFERFISH, Blocks.YELLOW_TERRACOTTA), ++ entry(Items.TROPICAL_FISH, Blocks.ORANGE_WOOL), ++ entry(Items.POTATO, Blocks.WHITE_TERRACOTTA), ++ entry(Items.MUTTON, Blocks.RED_WOOL), ++ entry(Items.BEETROOT, Blocks.NETHERRACK), ++ entry(Items.MELON_SLICE, Blocks.MELON), ++ entry(Items.POISONOUS_POTATO, Blocks.SLIME_BLOCK), ++ entry(Items.SPIDER_EYE, Blocks.NETHERRACK), ++ entry(Items.GUNPOWDER, Blocks.GRAY_WOOL), ++ entry(Items.TURTLE_SCUTE, Blocks.LIME_WOOL), ++ entry(Items.ARMADILLO_SCUTE, Blocks.ANCIENT_DEBRIS), ++ entry(Items.FEATHER, Blocks.WHITE_WOOL), ++ entry(Items.FLINT, Blocks.BLACK_WOOL), ++ entry(Items.LEATHER, Blocks.SPRUCE_PLANKS), ++ entry(Items.GLOWSTONE_DUST, Blocks.GLOWSTONE), ++ entry(Items.PAPER, Blocks.WHITE_WOOL), ++ entry(Items.BRICK, Blocks.BRICKS), ++ entry(Items.INK_SAC, Blocks.BLACK_WOOL), ++ entry(Items.SNOWBALL, Blocks.SNOW_BLOCK), ++ entry(Items.WATER_BUCKET, Blocks.WATER), ++ entry(Items.LAVA_BUCKET, Blocks.LAVA), ++ entry(Items.MILK_BUCKET, Blocks.WHITE_WOOL), ++ entry(Items.CLAY_BALL, Blocks.CLAY), ++ entry(Items.COCOA_BEANS, Blocks.COCOA), ++ entry(Items.BONE, Blocks.BONE_BLOCK), ++ entry(Items.COD_BUCKET, Blocks.BROWN_TERRACOTTA), ++ entry(Items.PUFFERFISH_BUCKET, Blocks.YELLOW_TERRACOTTA), ++ entry(Items.SALMON_BUCKET, Blocks.PINK_TERRACOTTA), ++ entry(Items.TROPICAL_FISH_BUCKET, Blocks.ORANGE_TERRACOTTA), ++ entry(Items.SUGAR, Blocks.WHITE_WOOL), ++ entry(Items.BLAZE_POWDER, Blocks.GOLD_BLOCK), ++ entry(Items.ENDER_PEARL, Blocks.WARPED_PLANKS), ++ entry(Items.NETHER_STAR, Blocks.DIAMOND_BLOCK), ++ entry(Items.PRISMARINE_CRYSTALS, Blocks.SEA_LANTERN), ++ entry(Items.PRISMARINE_SHARD, Blocks.PRISMARINE), ++ entry(Items.RABBIT_HIDE, Blocks.OAK_PLANKS), ++ entry(Items.CHORUS_FRUIT, Blocks.PURPUR_BLOCK), ++ entry(Items.SHULKER_SHELL, Blocks.SHULKER_BOX), ++ entry(Items.NAUTILUS_SHELL, Blocks.BONE_BLOCK), ++ entry(Items.HEART_OF_THE_SEA, Blocks.CONDUIT), ++ entry(Items.HONEYCOMB, Blocks.HONEYCOMB_BLOCK), ++ entry(Items.NAME_TAG, Blocks.BONE_BLOCK), ++ entry(Items.TOTEM_OF_UNDYING, Blocks.YELLOW_TERRACOTTA), ++ entry(Items.TRIDENT, Blocks.PRISMARINE), ++ entry(Items.GHAST_TEAR, Blocks.WHITE_WOOL), ++ entry(Items.PHANTOM_MEMBRANE, Blocks.BONE_BLOCK), ++ entry(Items.EGG, Blocks.BONE_BLOCK), ++ entry(Items.COPPER_INGOT, Blocks.COPPER_BLOCK), ++ entry(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK) + ); + + @Nullable @@ -436,24 +438,39 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + return direct; + } + -+ ResourceLocation id = registryAccess.registryOrThrow(Registries.ITEM).getKey(item); -+ for (RecipeType type : registryAccess.registryOrThrow(Registries.RECIPE_TYPE)) { -+ for (Recipe r : getAllMatching(server.getRecipeManager(), type, id, registryAccess)) { -+ for (Ingredient ingredient : r.getIngredients()) { -+ for (Collection stacks : getRecipeStacks(ingredient)) { -+ for (ItemStack itemStack : stacks) { -+ TextColor textColor = fromItem(itemStack.getItem(), registryAccess); -+ if (textColor != null) { -+ return textColor; -+ } -+ } -+ } ++ ResourceLocation id = registryAccess.lookupOrThrow(Registries.ITEM).getKey(item); ++ if (id == null) { ++ return null; ++ } ++ ++ ++ for (Recipe recipe : getRecipesForOutput(server.getRecipeManager(), id, server.overworld())) { ++ for (Ingredient ingredient : recipe.placementInfo().ingredients()) { ++ Optional> match = ingredient.items().stream().filter(stack -> fromItem(stack.value(), registryAccess) != null).findFirst(); ++ if (match.isPresent()) { ++ return fromItem(match.get().value(), registryAccess); + } + } + } + return null; + } + ++ @NotNull ++ public static List> getRecipesForOutput(@NotNull RecipeManager recipeManager, ResourceLocation id, Level level) { ++ List> results = new ArrayList<>(); ++ ContextMap context = SlotDisplayContext.fromLevel(level); ++ recipeManager.getRecipes().forEach(recipe -> { ++ for (RecipeDisplay recipeDisplay : recipe.value().display()) { ++ recipeDisplay.result().resolveForStacks(context).forEach(stack -> { ++ if (BuiltInRegistries.ITEM.wrapAsHolder(stack.getItem()).unwrapKey().map(ResourceKey::location).orElseThrow(IllegalStateException::new).equals(id)) { ++ results.add(recipe.value()); ++ } ++ }); ++ } ++ }); ++ return results; ++ } ++ + @Nullable + public static TextColor fromItem(Item item, RegistryAccess registryAccess) { + if (DEFAULTS.containsKey(item)) { @@ -464,13 +481,13 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + } + + Block block = null; -+ final Registry itemRegistry = registryAccess.registryOrThrow(Registries.ITEM); -+ final Registry blockRegistry = registryAccess.registryOrThrow(Registries.BLOCK); ++ final Registry itemRegistry = registryAccess.lookupOrThrow(Registries.ITEM); ++ final Registry blockRegistry = registryAccess.lookupOrThrow(Registries.BLOCK); + ResourceLocation id = itemRegistry.getKey(item); + if (item instanceof BlockItem blockItem) { + block = blockItem.getBlock(); + } else if (blockRegistry.getOptional(id).isPresent()) { -+ block = blockRegistry.get(id); ++ block = blockRegistry.getValue(id); + } + + if (block != null) { @@ -484,28 +501,6 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + return null; + } + -+ public static List> getAllMatching(@NotNull RecipeManager manager, RecipeType type, ResourceLocation output, final RegistryAccess registryAccess) { -+ RecipeHolder recipe = manager.byName.get(output); -+ if (recipe != null && recipe.value().getType().equals(type)) { -+ return List.of(recipe.value()); -+ } -+ if (!manager.byType.containsKey(type)) { -+ return List.of(); -+ } -+ -+ Collection> typeRecipes = manager.byType.get(type); -+ Registry regs = registryAccess.registryOrThrow(Registries.ITEM); -+ Item item = regs.get(output); -+ return typeRecipes.stream() -+ .>map(RecipeHolder::value) -+ .filter(r -> r.getResultItem(registryAccess).getItem() == item) -+ .toList(); -+ } -+ -+ public static List> getRecipeStacks(@NotNull Ingredient ingredient) { -+ return Arrays.stream(ingredient.values).map(Ingredient.Value::getItems).toList(); -+ } -+ + public static int appropriateColor(int color) { + if (color == 0) { + return MapColor.SNOW.col; @@ -523,15 +518,6 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + return counter.isEmpty() ? 0 : counter.values().longStream().sum(); + } + -+ public static void resetAll(MinecraftServer server, boolean fresh) { -+ for (HopperCounter counter : COUNTERS.values()) { -+ counter.reset(server); -+ if (fresh) { -+ counter.startTick = -1; -+ } -+ } -+ } -+ + public static HopperCounter getCounter(DyeColor color) { + return COUNTERS.get(color); + } @@ -541,7 +527,7 @@ index 0000000000000000000000000000000000000000..1a83b3918bc040ab32e648b54b498e9a + } + + public static boolean isEnabled() { -+ return LeavesConfig.hopperCounter && enabled; ++ return LeavesConfig.modify.hopperCounter && enabled; + } +} diff --git a/src/main/java/org/leavesmc/leaves/util/WoolUtils.java b/src/main/java/org/leavesmc/leaves/util/WoolUtils.java diff --git a/patches/server/0100-Leaves-Reload-Command.patch b/patches/server/0093-Leaves-Reload-Command.patch similarity index 100% rename from patches/server/0100-Leaves-Reload-Command.patch rename to patches/server/0093-Leaves-Reload-Command.patch diff --git a/patches/server/0101-Spider-jockeys-drop-gapples.patch b/patches/server/0094-Spider-jockeys-drop-gapples.patch similarity index 58% rename from patches/server/0101-Spider-jockeys-drop-gapples.patch rename to patches/server/0094-Spider-jockeys-drop-gapples.patch index fa5be2fe..62925eae 100644 --- a/patches/server/0101-Spider-jockeys-drop-gapples.patch +++ b/patches/server/0094-Spider-jockeys-drop-gapples.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Spider jockeys drop gapples 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 e675f1e3e5b6f9e1aa0d928ebb9abe76458edb38..902119c7501e98b2a4a67504216ad2cded138f87 100644 +index 91e521414c3ea5722aac7506b7589fbb399e9636..1b7c703464477d7c8b28f33edd5a971110e73908 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Spider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java @@ -145,6 +145,18 @@ public class Spider extends Monster { @@ -14,11 +14,11 @@ index e675f1e3e5b6f9e1aa0d928ebb9abe76458edb38..902119c7501e98b2a4a67504216ad2cd + // Leaves start - spider jockeys drop gapples + @Override -+ protected void dropFromLootTable(DamageSource damageSource, boolean causedByPlayer) { -+ super.dropFromLootTable(damageSource, causedByPlayer); -+ if (org.leavesmc.leaves.LeavesConfig.spiderJockeysDropGapples > 0.0D) { -+ if (this.hasPassenger(entity -> entity.getType() == EntityType.SKELETON) && this.random.nextDouble() < org.leavesmc.leaves.LeavesConfig.spiderJockeysDropGapples) { -+ this.spawnAtLocation(new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ENCHANTED_GOLDEN_APPLE)); ++ protected void dropFromLootTable(net.minecraft.server.level.ServerLevel wolrd, DamageSource damageSource, boolean causedByPlayer) { ++ super.dropFromLootTable(wolrd, damageSource, causedByPlayer); ++ if (org.leavesmc.leaves.LeavesConfig.modify.spiderJockeysDropGapples > 0.0D) { ++ if (this.hasPassenger(entity -> entity.getType() == EntityType.SKELETON) && this.random.nextDouble() < org.leavesmc.leaves.LeavesConfig.modify.spiderJockeysDropGapples) { ++ this.spawnAtLocation(wolrd, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.ENCHANTED_GOLDEN_APPLE)); + } + } + } @@ -26,4 +26,4 @@ index e675f1e3e5b6f9e1aa0d928ebb9abe76458edb38..902119c7501e98b2a4a67504216ad2cd + @Nullable @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, MobSpawnType spawnReason, @Nullable SpawnGroupData entityData) { + public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData entityData) { diff --git a/patches/server/0102-Force-Void-Trade.patch b/patches/server/0095-Force-Void-Trade.patch similarity index 87% rename from patches/server/0102-Force-Void-Trade.patch rename to patches/server/0095-Force-Void-Trade.patch index c3e0eb21..288b7c6b 100644 --- a/patches/server/0102-Force-Void-Trade.patch +++ b/patches/server/0095-Force-Void-Trade.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Force Void Trade 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 ebdb1546fb057bf4881d53538f8e44c14fe88b74..c3c70493e418e70c4cb6ef3cb67caf2a2cf23896 100644 +index 6c0cece094d36ddb2ae8d67d3c847a2c8faa3da8..cb5524ed59a07693d1d7ff03ca4f27e07774e3e5 100644 --- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java @@ -64,6 +64,7 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa @@ -74,7 +74,7 @@ index ebdb1546fb057bf4881d53538f8e44c14fe88b74..c3c70493e418e70c4cb6ef3cb67caf2a + // Leaves end - force void trade } 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 18642b4e43d0725690be44b53bbddb6d4486e5f1..8a21e03c012b047eef3948e10bdb23766194b670 100644 +index 8d3959e86ef1357e49aac6ef3c8285c770f2856a..d931e38924c2fbad84efdb2e9ac84061b1764870 100644 --- a/src/main/java/net/minecraft/world/entity/npc/Villager.java +++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java @@ -348,6 +348,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler @@ -85,7 +85,7 @@ index 18642b4e43d0725690be44b53bbddb6d4486e5f1..8a21e03c012b047eef3948e10bdb2376 this.updateSpecialPrices(customer); this.setTradingPlayer(customer); this.openTradingScreen(customer, this.getDisplayName(), this.getVillagerData().getLevel()); -@@ -645,8 +646,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -639,8 +640,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler protected void rewardTradeXp(MerchantOffer offer) { int i = 3 + this.random.nextInt(4); @@ -101,10 +101,10 @@ index 18642b4e43d0725690be44b53bbddb6d4486e5f1..8a21e03c012b047eef3948e10bdb2376 this.updateMerchantTimer = 40; this.increaseProfessionLevelOnUpdate = true; 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 0af34e0f9c9696fbcb11b12fb27472ef17ad532a..422d537014520383503f06e834ef6fb31813beb8 100644 +index 1e77cce428d9e53142aaa2cf780b7f862d536eca..2bac91f7f6943c7e1b5f63ea7dfeb3c3e390bcb7 100644 --- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -122,9 +122,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -123,9 +123,10 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill return InteractionResult.CONSUME; } @@ -116,10 +116,10 @@ index 0af34e0f9c9696fbcb11b12fb27472ef17ad532a..422d537014520383503f06e834ef6fb3 + this.openTradingScreen(player, this.getDisplayName(), 1); + } - return InteractionResult.sidedSuccess(this.level().isClientSide); + return InteractionResult.SUCCESS; } else { diff --git a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java -index 5de2030452b96a4df7ce0be82f07e002db595dee..7c2b12fcc8028fc029af17e3bae2901843b47b62 100644 +index 6a529b5e289c416c0ebdc0260086ec039777aa40..f41e9303c6e118a426e779d4bbca450011ed7246 100644 --- a/src/main/java/net/minecraft/world/inventory/MerchantMenu.java +++ b/src/main/java/net/minecraft/world/inventory/MerchantMenu.java @@ -27,7 +27,7 @@ public class MerchantMenu extends AbstractContainerMenu { @@ -178,15 +178,15 @@ index 0efc8d997b34302c3e0a5d7ec73a11a940dbeefe..d246c9932f3f98972124089306d6ed74 public void setToOutOfStock() { 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 3f5bb5c9ceb5b31fcc9ef0a7a6157e1e1cb2a09f..3087c60589de8fc38e12d322e58886ba76749507 100644 +index a7a21f071161fb7e73a046717d2462f871ab653c..50d726874af316a264fa0c2589f5b04559dffb50 100644 --- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java -@@ -118,6 +118,16 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { +@@ -120,6 +120,16 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { if (tileentity instanceof TheEndGatewayBlockEntity tileentityendgateway) { Vec3 vec3d = tileentityendgateway.getPortalPosition(world, pos); + // Leaves start - force void trade -+ if (org.leavesmc.leaves.LeavesConfig.forceVoidTrade && vec3d != null && entity instanceof net.minecraft.server.level.ServerPlayer player) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.forceVoidTrade && vec3d != null && entity instanceof net.minecraft.server.level.ServerPlayer player) { + if (player.containerMenu instanceof net.minecraft.world.inventory.MerchantMenu merchantMenu) { + if (merchantMenu.trader instanceof net.minecraft.world.entity.npc.AbstractVillager villager) { + villager.setVoidTrade(); @@ -195,6 +195,6 @@ index 3f5bb5c9ceb5b31fcc9ef0a7a6157e1e1cb2a09f..3087c60589de8fc38e12d322e58886ba + } + // Leaves end - force void trade + - return vec3d != null ? new DimensionTransition(world, vec3d, EndGatewayBlock.calculateExitMovement(entity), entity.getYRot(), entity.getXRot(), DimensionTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : null; // CraftBukkit + return vec3d == null ? null : (entity instanceof ThrownEnderpearl ? new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY)); // CraftBukkit } else { return null; diff --git a/patches/server/0103-Villager-infinite-discounts.patch b/patches/server/0096-Villager-infinite-discounts.patch similarity index 100% rename from patches/server/0103-Villager-infinite-discounts.patch rename to patches/server/0096-Villager-infinite-discounts.patch diff --git a/patches/server/0104-CCE-update-suppression.patch b/patches/server/0097-CCE-update-suppression.patch similarity index 60% rename from patches/server/0104-CCE-update-suppression.patch rename to patches/server/0097-CCE-update-suppression.patch index e46273b8..1c4600f1 100644 --- a/patches/server/0104-CCE-update-suppression.patch +++ b/patches/server/0097-CCE-update-suppression.patch @@ -5,27 +5,36 @@ Subject: [PATCH] CCE update suppression 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 8e899549f09b8429cd63bd5c895253325f65ccab..7d88524eb5b193600c8985c68bb9ed10e3fe3c4d 100644 +index b7c1050dfafa79f3ed86524ce37cd06651cbbdd9..b01918fc97926a3182c21145bb7411e7bc409d35 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -243,17 +243,21 @@ public class ShulkerBoxBlock extends BaseEntityBlock { +@@ -182,7 +182,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { + protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { + if (!state.is(newState.getBlock())) { + BlockEntity blockEntity = world.getBlockEntity(pos); +- super.onRemove(state, world, pos, newState, moved); ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- + if (blockEntity instanceof ShulkerBoxBlockEntity) { + world.updateNeighbourForOutputSignal(pos, state.getBlock()); + } +@@ -239,17 +239,21 @@ public class ShulkerBoxBlock extends BaseEntityBlock { @Override protected int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) { - // Leaves start - fix update suppression crash + // Leaves start - fix update suppression crash - and cce fix - if (org.leavesmc.leaves.LeavesConfig.updateSuppressionCrashFix) { + if (org.leavesmc.leaves.LeavesConfig.modify.updateSuppressionCrashFix) { try { - return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); -+ return org.leavesmc.leaves.LeavesConfig.cceUpdateSuppression ? ++ return org.leavesmc.leaves.LeavesConfig.modify.oldMC.updater.cceUpdateSuppression ? + AbstractContainerMenu.getRedstoneSignalFromContainer((net.minecraft.world.Container) world.getBlockEntity(pos)) : + AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); } catch (ClassCastException ex) { - throw new org.leavesmc.leaves.util.UpdateSuppressionException(null, pos); + throw new org.leavesmc.leaves.util.UpdateSuppressionException(pos, this); } } else { - return AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); -+ return org.leavesmc.leaves.LeavesConfig.cceUpdateSuppression ? ++ return org.leavesmc.leaves.LeavesConfig.modify.oldMC.updater.cceUpdateSuppression ? + AbstractContainerMenu.getRedstoneSignalFromContainer((net.minecraft.world.Container) world.getBlockEntity(pos)) : + AbstractContainerMenu.getRedstoneSignalFromBlockEntity(world.getBlockEntity(pos)); } diff --git a/patches/server/0105-Disable-offline-warn-if-use-proxy.patch b/patches/server/0098-Disable-offline-warn-if-use-proxy.patch similarity index 89% rename from patches/server/0105-Disable-offline-warn-if-use-proxy.patch rename to patches/server/0098-Disable-offline-warn-if-use-proxy.patch index 197a5386..4ca3ea1f 100644 --- a/patches/server/0105-Disable-offline-warn-if-use-proxy.patch +++ b/patches/server/0098-Disable-offline-warn-if-use-proxy.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Disable offline warn if use proxy diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -index 3e4d4c417904fba6aeba0dee2e01d3b5bd95ac20..85e7321c7b918db404fca1c75a16ec17bc6b0b2f 100644 +index e57aea5bc337e182f20ae2b90407f0ec15770bc1..beb0c55454e849de092cdf5cff5af73c178a6ed0 100644 --- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java +++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java -@@ -303,7 +303,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface +@@ -301,7 +301,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface String proxyFlavor = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "Velocity" : "BungeeCord"; String proxyLink = (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) ? "https://docs.papermc.io/velocity/security" : "http://www.spigotmc.org/wiki/firewall-guide/"; // Paper end - Add Velocity IP Forwarding Support diff --git a/patches/server/0107-Armor-stand-cant-kill-by-mob-projectile.patch b/patches/server/0099-Armor-stand-cant-kill-by-mob-projectile.patch similarity index 61% rename from patches/server/0107-Armor-stand-cant-kill-by-mob-projectile.patch rename to patches/server/0099-Armor-stand-cant-kill-by-mob-projectile.patch index 076446ed..bea53f0b 100644 --- a/patches/server/0107-Armor-stand-cant-kill-by-mob-projectile.patch +++ b/patches/server/0099-Armor-stand-cant-kill-by-mob-projectile.patch @@ -5,21 +5,21 @@ Subject: [PATCH] Armor stand cant kill by mob projectile 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 9ab1c4dccf0cc96ecc6f3a2a8dbcb38df0b530af..9883db7b41c44fdb878ae3e110b1339a87dfa7a3 100644 +index 49e8a9d5df9b20bced385019f5e7fb622536213a..44c0b846ee038d683f76de46e667d8d8173e896f 100644 --- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -531,6 +531,14 @@ public class ArmorStand extends LivingEntity { - boolean flag = source.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND); - boolean flag1 = source.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS); +@@ -532,6 +532,14 @@ public class ArmorStand extends LivingEntity { + boolean flag = source.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND); + boolean flag1 = source.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS); + // Leaves start - Armor stand cant kill by mob projectile -+ if (org.leavesmc.leaves.LeavesConfig.armorStandCantKillByMobProjectile) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.armorStandCantKillByMobProjectile) { + if (!flag && !(source.getDirectEntity() instanceof net.minecraft.world.entity.projectile.AbstractArrow)) { + return false; + } + } + // Leaves end - Armor stand cant kill by mob projectile + - if (!flag && !flag1) { - return false; - } else { + if (!flag && !flag1) { + return false; + } else { diff --git a/patches/server/0108-Make-Item-tick-vanilla.patch b/patches/server/0100-Make-Item-tick-vanilla.patch similarity index 83% rename from patches/server/0108-Make-Item-tick-vanilla.patch rename to patches/server/0100-Make-Item-tick-vanilla.patch index 0bde093b..52425ca2 100644 --- a/patches/server/0108-Make-Item-tick-vanilla.patch +++ b/patches/server/0100-Make-Item-tick-vanilla.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Make Item tick vanilla 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 510735cc63968265d2e1d9deb1a06beda3112ed9..2d885a09fc7bd7c2df76321147c75eeb46808b48 100644 +index 9e8a40f51337822ac55b5020778076c7466f5ef3..0d79396c4e65710e7b9f20c740cf2f8254ea120c 100644 --- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java -@@ -250,6 +250,9 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -251,6 +251,9 @@ public class ItemEntity extends Entity implements TraceableEntity { // Spigot start - copied from above @Override public void inactiveTick() { @@ -18,7 +18,7 @@ index 510735cc63968265d2e1d9deb1a06beda3112ed9..2d885a09fc7bd7c2df76321147c75eeb // Paper start - remove anti tick skipping measures / wall time - copied from above if (this.pickupDelay > 0 && this.pickupDelay != 32767) { --this.pickupDelay; -@@ -268,6 +271,8 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -269,6 +272,8 @@ public class ItemEntity extends Entity implements TraceableEntity { // CraftBukkit end this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } diff --git a/patches/server/0109-Copper-Bulb-1-gt-delay.patch b/patches/server/0101-Copper-Bulb-1-gt-delay.patch similarity index 78% rename from patches/server/0109-Copper-Bulb-1-gt-delay.patch rename to patches/server/0101-Copper-Bulb-1-gt-delay.patch index a1630015..26f6c426 100644 --- a/patches/server/0109-Copper-Bulb-1-gt-delay.patch +++ b/patches/server/0101-Copper-Bulb-1-gt-delay.patch @@ -5,16 +5,16 @@ Subject: [PATCH] Copper Bulb 1 gt delay diff --git a/src/main/java/net/minecraft/world/level/block/CopperBulbBlock.java b/src/main/java/net/minecraft/world/level/block/CopperBulbBlock.java -index b4250059a9068124b76268913f675babac379670..e6cfa8c1ce45c5e4b647ac6faceb838961e69dad 100644 +index 7c6481fc6e84f6477a4d113a222cae51cfa9053a..228fdf12ca2c85134efa527862f8901205a9064e 100644 --- a/src/main/java/net/minecraft/world/level/block/CopperBulbBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CopperBulbBlock.java -@@ -30,14 +30,26 @@ public class CopperBulbBlock extends Block { +@@ -32,14 +32,26 @@ public class CopperBulbBlock extends Block { @Override protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { if (oldState.getBlock() != state.getBlock() && world instanceof ServerLevel serverLevel) { - this.checkAndFlip(state, serverLevel, pos); + // Leaves start - copper bulb 1 gt delay -+ if (!org.leavesmc.leaves.LeavesConfig.copperBulb1gt) { ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.copperBulb1gt) { + this.checkAndFlip(state, serverLevel, pos); + } else { + world.scheduleTick(pos, this, 1); @@ -24,11 +24,11 @@ index b4250059a9068124b76268913f675babac379670..e6cfa8c1ce45c5e4b647ac6faceb8389 } @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 (world instanceof ServerLevel serverLevel) { - this.checkAndFlip(state, serverLevel, pos); + // Leaves start - copper bulb 1 gt -+ if (!org.leavesmc.leaves.LeavesConfig.copperBulb1gt) { ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.copperBulb1gt) { + this.checkAndFlip(state, serverLevel, pos); + } else { + world.scheduleTick(pos, this, 1); @@ -37,14 +37,14 @@ index b4250059a9068124b76268913f675babac379670..e6cfa8c1ce45c5e4b647ac6faceb8389 } } -@@ -54,6 +66,15 @@ public class CopperBulbBlock extends Block { +@@ -56,6 +68,15 @@ public class CopperBulbBlock extends Block { } } + // Leaves start - copper bulb 1 gt delay + @Override + public void tick(BlockState state, ServerLevel world, BlockPos pos, net.minecraft.util.RandomSource random) { -+ if (org.leavesmc.leaves.LeavesConfig.copperBulb1gt) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.copperBulb1gt) { + checkAndFlip(state, world, pos); + } + } diff --git a/patches/server/0110-Crafter-1-gt-delay.patch b/patches/server/0102-Crafter-1-gt-delay.patch similarity index 75% rename from patches/server/0110-Crafter-1-gt-delay.patch rename to patches/server/0102-Crafter-1-gt-delay.patch index 98ab68df..64722431 100644 --- a/patches/server/0110-Crafter-1-gt-delay.patch +++ b/patches/server/0102-Crafter-1-gt-delay.patch @@ -5,24 +5,24 @@ Subject: [PATCH] Crafter 1 gt delay diff --git a/src/main/java/net/minecraft/world/level/block/CrafterBlock.java b/src/main/java/net/minecraft/world/level/block/CrafterBlock.java -index deb5b4fab94618c08a51e432c33e49b1627bd717..cd141680fec975b1a286974178b90d89ed8e34f5 100644 +index 0e609b1e3abd50b415d8376dc550375a8a0251b6..37954c43b30c64d2d4748e1fd190784ed342e4c5 100644 --- a/src/main/java/net/minecraft/world/level/block/CrafterBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CrafterBlock.java -@@ -90,7 +90,7 @@ public class CrafterBlock extends BaseEntityBlock { +@@ -91,7 +91,7 @@ public class CrafterBlock extends BaseEntityBlock { BlockEntity tileentity = world.getBlockEntity(pos); if (flag1 && !flag2) { - world.scheduleTick(pos, (Block) this, 4); -+ world.scheduleTick(pos, (Block) this, !org.leavesmc.leaves.LeavesConfig.crafter1gt ? 4 : 1); // Leaves - crafter 1 gt delay ++ world.scheduleTick(pos, (Block) this, !org.leavesmc.leaves.LeavesConfig.modify.oldMC.crafter1gt ? 4 : 1); // Leaves - crafter 1 gt delay world.setBlock(pos, (BlockState) state.setValue(CrafterBlock.TRIGGERED, true), 2); this.setBlockEntityTriggered(tileentity, true); } else if (!flag1 && flag2) { -@@ -156,7 +156,7 @@ public class CrafterBlock extends BaseEntityBlock { +@@ -157,7 +157,7 @@ public class CrafterBlock extends BaseEntityBlock { @Override public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) { if ((Boolean) state.getValue(CrafterBlock.TRIGGERED)) { - world.scheduleTick(pos, (Block) this, 4); -+ world.scheduleTick(pos, (Block) this, !org.leavesmc.leaves.LeavesConfig.crafter1gt ? 4 : 1); // Leaves - crafter 1 gt delay ++ world.scheduleTick(pos, (Block) this, !org.leavesmc.leaves.LeavesConfig.modify.oldMC.crafter1gt ? 4 : 1); // Leaves - crafter 1 gt delay } } diff --git a/patches/server/0111-Linear-region-file-format.patch b/patches/server/0103-Linear-region-file-format.patch similarity index 78% rename from patches/server/0111-Linear-region-file-format.patch rename to patches/server/0103-Linear-region-file-format.patch index d578b218..b7fd7bae 100644 --- a/patches/server/0111-Linear-region-file-format.patch +++ b/patches/server/0103-Linear-region-file-format.patch @@ -6,10 +6,10 @@ Subject: [PATCH] Linear region file format This patch is Powered by LinearPurpur(https://github.com/StupidCraft/LinearPurpur) diff --git a/build.gradle.kts b/build.gradle.kts -index 51bf5df7bca5b32e171e452d62f6843a7a10fee1..ecc29f64b5cbd2849f86d22aee8a76d172b3def0 100644 +index 0add94373b7b38f271893b1c44a448051b845e8b..8559918f8f91e6137ac873b37af29aa3b6c0c4a0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -30,6 +30,10 @@ dependencies { +@@ -43,6 +43,10 @@ dependencies { alsoShade(log4jPlugins.output) implementation("io.netty:netty-codec-haproxy:4.1.97.Final") // Paper - Add support for proxy protocol // Paper end @@ -21,10 +21,10 @@ index 51bf5df7bca5b32e171e452d62f6843a7a10fee1..ecc29f64b5cbd2849f86d22aee8a76d1 implementation("org.ow2.asm:asm-commons:9.7.1") implementation("org.spongepowered:configurate-yaml:4.2.0-SNAPSHOT") // Paper - config files 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..f3bd1488da34ea796c8205088e83d4c5dbd9f6bc 100644 +index a814512fcfb85312474ae2c2c21443843bf57831..c56812494d2cd270eb66bde1f0a8a9b4100777bd 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 -@@ -7,8 +7,8 @@ public interface ChunkSystemRegionFileStorage { +@@ -8,9 +8,9 @@ public interface ChunkSystemRegionFileStorage { public boolean moonrise$doesRegionFileNotExistNoIO(final int chunkX, final int chunkZ); @@ -34,40 +34,37 @@ index 73df26b27146bbad2106d57b22dd3c792ed3dd1d..f3bd1488da34ea796c8205088e83d4c5 - public RegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) throws IOException; + public org.leavesmc.leaves.region.AbstractRegionFile moonrise$getRegionFileIfExists(final int chunkX, final int chunkZ) 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 -index 3218cbf84f54daf06e84442d5eb1a36d8da6b215..80dd90189d7790066b2e42285f256f21b146600c 100644 ---- 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 -@@ -1043,9 +1043,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - return ((ChunkSystemRegionFileStorage)(Object)this.getCache()).moonrise$doesRegionFileNotExistNoIO(chunkX, chunkZ); - } + public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite( + final int chunkX, final int chunkZ, final CompoundTag compound +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 +index 1acea58838f057ab87efd103cbecb6f5aeaef393..740cb0c60e6220ca20f3dd9b6f4063737c8adf06 100644 +--- 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 +@@ -1462,7 +1462,7 @@ public final class MoonriseRegionFileIO { + + public static interface IORunnable { + +- public void run(final RegionFile regionFile) throws IOException; ++ public void run(final org.leavesmc.leaves.region.AbstractRegionFile regionFile) throws IOException; // Leaves -- public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { -+ public T computeForRegionFile(final int chunkX, final int chunkZ, final boolean existingOnly, final Function function) { // Leaves - final RegionFileStorage cache = this.getCache(); -- final RegionFile regionFile; -+ final org.leavesmc.leaves.region.AbstractRegionFile regionFile; // Leaves - synchronized (cache) { - try { - if (existingOnly) { -@@ -1061,9 +1061,9 @@ public final class RegionFileIOThread extends PrioritisedQueueExecutorThread { - } } + } +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 +index 51c126735ace8fdde89ad97b5cab62f244212db0..054d03b0417077b30c34dbea1f3dc6b6de11b41b 100644 +--- 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 +@@ -8,5 +8,5 @@ public interface ChunkSystemChunkBuffer { -- public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { -+ public T computeForRegionFileIfLoaded(final int chunkX, final int chunkZ, final Function function) { // Leaves - final RegionFileStorage cache = this.getCache(); -- final RegionFile regionFile; -+ final org.leavesmc.leaves.region.AbstractRegionFile regionFile; // Leaves + public void moonrise$setWriteOnClose(final boolean value); - synchronized (cache) { - regionFile = ((ChunkSystemRegionFileStorage)(Object)cache).moonrise$getRegionFileIfLoaded(chunkX, chunkZ); +- public void moonrise$write(final RegionFile regionFile) throws IOException; ++ public void moonrise$write(final org.leavesmc.leaves.region.AbstractRegionFile regionFile) throws IOException; // Leaves + } diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -index cb39c629af1827078f35904a373d35a63fea17ff..4f8ec87adc72f096caeb4bb437c5f43b136fb4fc 100644 +index 622d0cbe023774d92d212f242b60b96317720835..c182e2d26a72ebd28636b50bbbc050e34fa600cc 100644 --- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java +++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java -@@ -76,7 +76,7 @@ public class WorldUpgrader { +@@ -75,7 +75,7 @@ public class WorldUpgrader implements AutoCloseable { volatile int skipped; final Reference2FloatMap> progressMap = Reference2FloatMaps.synchronize(new Reference2FloatOpenHashMap()); volatile Component status = Component.translatable("optimizeWorld.stage.counting"); @@ -76,7 +73,7 @@ index cb39c629af1827078f35904a373d35a63fea17ff..4f8ec87adc72f096caeb4bb437c5f43b final DimensionDataStorage overworldDataStorage; public WorldUpgrader(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, RegistryAccess dynamicRegistryManager, boolean eraseCache, boolean recreateRegionFiles) { -@@ -400,7 +400,7 @@ public class WorldUpgrader { +@@ -399,7 +399,7 @@ public class WorldUpgrader implements AutoCloseable { private static List getAllChunkPositions(RegionStorageInfo key, Path regionDirectory) { File[] afile = regionDirectory.toFile().listFiles((file, s) -> { @@ -85,7 +82,7 @@ index cb39c629af1827078f35904a373d35a63fea17ff..4f8ec87adc72f096caeb4bb437c5f43b }); if (afile == null) { -@@ -420,7 +420,7 @@ public class WorldUpgrader { +@@ -419,7 +419,7 @@ public class WorldUpgrader implements AutoCloseable { List list1 = Lists.newArrayList(); try { @@ -94,7 +91,7 @@ index cb39c629af1827078f35904a373d35a63fea17ff..4f8ec87adc72f096caeb4bb437c5f43b try { for (int i1 = 0; i1 < 32; ++i1) { -@@ -483,7 +483,7 @@ public class WorldUpgrader { +@@ -482,7 +482,7 @@ public class WorldUpgrader implements AutoCloseable { protected abstract boolean tryProcessOnePosition(T storage, ChunkPos chunkPos, ResourceKey worldKey); @@ -103,7 +100,7 @@ index cb39c629af1827078f35904a373d35a63fea17ff..4f8ec87adc72f096caeb4bb437c5f43b if (WorldUpgrader.this.recreateRegionFiles) { if (this.previousWriteFuture != null) { this.previousWriteFuture.join(); -@@ -508,7 +508,7 @@ public class WorldUpgrader { +@@ -507,7 +507,7 @@ public class WorldUpgrader implements AutoCloseable { } } @@ -113,19 +110,19 @@ index cb39c629af1827078f35904a373d35a63fea17ff..4f8ec87adc72f096caeb4bb437c5f43b } 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..d7475e04fbfd41bde70ffdbc1fffa7a023b7ca8e 100644 +index 16f07007a0f73ec0c6f421c9b082518e87e8cc7b..b171304ad750a70944f48ddacb93836d3696af90 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, org.leavesmc.leaves.region.AbstractRegionFile { // Leaves +-public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile { // Paper - rewrite chunk system ++public class RegionFile implements AutoCloseable, org.leavesmc.leaves.region.AbstractRegionFile { // Paper - rewrite chunk system // Leaves private static final Logger LOGGER = LogUtils.getLogger(); private static final int SECTOR_BYTES = 4096; -@@ -129,7 +129,7 @@ public class RegionFile implements AutoCloseable { +@@ -129,7 +129,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche } // note: only call for CHUNK regionfiles @@ -134,7 +131,16 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..d7475e04fbfd41bde70ffdbc1fffa7a0 if (!this.canRecalcHeader) { return false; } -@@ -928,10 +928,10 @@ public class RegionFile implements AutoCloseable { +@@ -810,7 +810,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche + } + } + +- protected synchronized void write(ChunkPos pos, ByteBuffer buf) throws IOException { ++ public synchronized void write(ChunkPos pos, ByteBuffer buf) throws IOException { // Leaves - protected -> public + int i = RegionFile.getOffsetIndex(pos); + int j = this.offsets.get(i); + int k = RegionFile.getSectorNumber(j); +@@ -952,10 +952,10 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche private static int getChunkIndex(int x, int z) { return (x & 31) + (z & 31) * 32; } @@ -147,7 +153,7 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..d7475e04fbfd41bde70ffdbc1fffa7a0 final int offset = getChunkIndex(x, z); boolean previous = this.oversized[offset] == 1; this.oversized[offset] = (byte) (oversized ? 1 : 0); -@@ -970,7 +970,7 @@ public class RegionFile implements AutoCloseable { +@@ -994,7 +994,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche return this.path.getParent().resolve(this.path.getFileName().toString().replaceAll("\\.mca$", "") + "_oversized_" + x + "_" + z + ".nbt"); } @@ -156,11 +162,20 @@ index 1e0439cf3f4008fa430acb90b45f5bc4cdd6d7f2..d7475e04fbfd41bde70ffdbc1fffa7a0 Path file = getOversizedFile(x, z); try (DataInputStream out = new DataInputStream(new java.io.BufferedInputStream(new InflaterInputStream(Files.newInputStream(file))))) { return NbtIo.read((java.io.DataInput) out); +@@ -1021,7 +1021,7 @@ public class RegionFile implements AutoCloseable, ca.spottedleaf.moonrise.patche + } + + @Override +- public final void moonrise$write(final RegionFile regionFile) throws IOException { ++ public final void moonrise$write(final org.leavesmc.leaves.region.AbstractRegionFile regionFile) throws IOException { // Leaves + regionFile.write(this.pos, ByteBuffer.wrap(this.buf, 0, this.count)); + } + // Paper end - 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..9cc7699eadf9401fc66b47c86e59cadfaeba9162 100644 +index e40665cead218502b44dd49051a53326ed94f061..a6f5d79b12a118bc9ed3d1bdba8a68dc10ed5be3 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 -@@ -21,7 +21,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -23,7 +23,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise public static final String ANVIL_EXTENSION = ".mca"; private static final int MAX_CACHE_SIZE = 256; @@ -169,24 +184,24 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf private final RegionStorageInfo info; private final Path folder; private final boolean sync; -@@ -31,9 +31,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - 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); +@@ -33,9 +33,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + 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"; -+ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + (org.leavesmc.leaves.LeavesConfig.regionFormat != org.leavesmc.leaves.region.RegionFileFormat.LINEAR ? ".mca" : ".linear"); // Leaves ++ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + (org.leavesmc.leaves.LeavesConfig.region.format != org.leavesmc.leaves.region.RegionFileFormat.LINEAR ? ".mca" : ".linear"); // Leaves } + // Leaves start + private static String getOtherRegionFileName(final int chunkX, final int chunkZ) { -+ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + (org.leavesmc.leaves.LeavesConfig.regionFormat == org.leavesmc.leaves.region.RegionFileFormat.LINEAR ? ".mca" : ".linear"); ++ return "r." + (chunkX >> REGION_SHIFT) + "." + (chunkZ >> REGION_SHIFT) + (org.leavesmc.leaves.LeavesConfig.region.format == org.leavesmc.leaves.region.RegionFileFormat.LINEAR ? ".mca" : ".linear"); + } + // Leaves end + private boolean doesRegionFilePossiblyExist(final long position) { synchronized (this.nonExistingRegionFiles) { if (this.nonExistingRegionFiles.contains(position)) { -@@ -66,15 +72,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -68,15 +74,15 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise } @Override @@ -205,7 +220,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf if (ret != null) { return ret; } -@@ -86,19 +92,23 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -88,19 +94,23 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper this.regionCache.removeLast().close(); } @@ -234,16 +249,49 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf this.regionCache.putAndMoveToFirst(key, ret); -@@ -143,7 +153,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise - this.isChunkData = isChunkDataFolder(this.folder); // Paper - recalculate region file headers +@@ -119,7 +129,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + } + + final ChunkPos pos = new ChunkPos(chunkX, chunkZ); +- final RegionFile regionFile = this.getRegionFile(pos); ++ final org.leavesmc.leaves.region.AbstractRegionFile regionFile = this.getRegionFile(pos); // Leaves + + // 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) +@@ -153,7 +163,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + ) 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); ++ final org.leavesmc.leaves.region.AbstractRegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); // Leaves + if (regionFile != null) { + regionFile.clear(pos); + } // else: didn't exist +@@ -168,7 +178,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise + 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 org.leavesmc.leaves.region.AbstractRegionFile regionFile = this.moonrise$getRegionFileIfExists(chunkX, chunkZ); // Leaves + + final DataInputStream input = regionFile == null ? null : regionFile.getChunkDataInputStream(new ChunkPos(chunkX, chunkZ)); + +@@ -250,12 +260,12 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise } + // Paper start - rewrite chunk system +- public RegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException { ++ public org.leavesmc.leaves.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair) throws IOException { // Leaves + return this.getRegionFile(chunkcoordintpair, false); + } + // Paper end - rewrite chunk system + - public RegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public + public org.leavesmc.leaves.region.AbstractRegionFile getRegionFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit // Paper - public // Leaves // Paper start - rewrite chunk system if (existingOnly) { return this.moonrise$getRegionFileIfExists(chunkcoordintpair.x, chunkcoordintpair.z); -@@ -151,7 +161,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -263,7 +273,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise synchronized (this) { final long key = ChunkPos.asLong(chunkcoordintpair.x >> REGION_SHIFT, chunkcoordintpair.z >> REGION_SHIFT); @@ -252,7 +300,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf if (ret != null) { return ret; } -@@ -166,7 +176,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -278,7 +288,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise FileUtil.createDirectoriesSafe(this.folder); @@ -261,7 +309,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf this.regionCache.putAndMoveToFirst(key, ret); -@@ -180,7 +190,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -292,7 +302,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); } @@ -270,7 +318,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf synchronized (regionfile) { try (DataInputStream datainputstream = regionfile.getChunkDataInputStream(chunkCoordinate)) { CompoundTag oversizedData = regionfile.getOversizedData(chunkCoordinate.x, chunkCoordinate.z); -@@ -215,7 +225,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -327,7 +337,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise @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 @@ -279,7 +327,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf if (regionfile == null) { return null; } -@@ -279,7 +289,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -391,7 +401,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise public void scanChunk(ChunkPos chunkPos, StreamTagVisitor scanner) throws IOException { // CraftBukkit start - SPIGOT-5680: There's no good reason to preemptively create files on read, save that for writing @@ -288,16 +336,16 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf if (regionfile == null) { return; } -@@ -309,7 +319,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -421,7 +431,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise } - public void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { // Paper - public + public void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException { // Paper - rewrite chunk system - public - RegionFile regionfile = this.getRegionFile(pos, nbt == null); // CraftBukkit // Paper - rewrite chunk system + org.leavesmc.leaves.region.AbstractRegionFile regionfile = this.getRegionFile(pos, nbt == null); // CraftBukkit // Paper - rewrite chunk system // Leaves // Paper start - rewrite chunk system if (regionfile == null) { // if the RegionFile doesn't exist, no point in deleting from it -@@ -325,8 +335,33 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -432,8 +442,33 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise if (nbt == null) { regionfile.clear(pos); } else { @@ -305,12 +353,12 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf + // Leaves start - auto convert anvil to linear + DataOutputStream dataoutputstream; + -+ if (regionfile instanceof RegionFile && org.leavesmc.leaves.LeavesConfig.regionFormat == org.leavesmc.leaves.region.RegionFileFormat.LINEAR && org.leavesmc.leaves.LeavesConfig.autoConvertAnvilToLinear) { ++ if (regionfile instanceof RegionFile && org.leavesmc.leaves.LeavesConfig.region.format == org.leavesmc.leaves.region.RegionFileFormat.LINEAR && org.leavesmc.leaves.LeavesConfig.region.linear.autoConvertAnvilToLinear) { + Path linearFilePath = Path.of(regionfile.getPath().toString().replaceAll(".mca", ".linear")); -+ try (org.leavesmc.leaves.region.LinearRegionFile linearRegionFile = new org.leavesmc.leaves.region.LinearRegionFile(linearFilePath, org.leavesmc.leaves.LeavesConfig.linearCompressionLevel)) { ++ try (org.leavesmc.leaves.region.LinearRegionFile linearRegionFile = new org.leavesmc.leaves.region.LinearRegionFile(linearFilePath, org.leavesmc.leaves.LeavesConfig.region.linear.compressionLevel)) { + DataInputStream regionDataInputStream = regionfile.getChunkDataInputStream(pos); + if (regionDataInputStream == null) { -+ continue; ++ return; // ? + } + CompoundTag compoundTag = NbtIo.read(regionDataInputStream); @@ -332,7 +380,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf try { NbtIo.write(nbt, (DataOutput) dataoutputstream); regionfile.setOversized(pos.x, pos.z, false); // Paper - We don't do this anymore, mojang stores differently, but clear old meta flag if it exists to get rid of our own meta file once last oversized is gone -@@ -368,7 +403,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -465,7 +500,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise // Paper start - rewrite chunk system synchronized (this) { final ExceptionCollector exceptionCollector = new ExceptionCollector<>(); @@ -341,7 +389,7 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf try { regionFile.close(); } catch (final IOException ex) { -@@ -385,7 +420,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise +@@ -482,7 +517,7 @@ public class RegionFileStorage implements AutoCloseable, ca.spottedleaf.moonrise // Paper start - rewrite chunk system synchronized (this) { final ExceptionCollector exceptionCollector = new ExceptionCollector<>(); @@ -352,23 +400,23 @@ index 40689256711cc94a806ca1da346f4f62eda31526..9cc7699eadf9401fc66b47c86e59cadf } catch (final IOException ex) { diff --git a/src/main/java/org/leavesmc/leaves/region/AbstractRegionFile.java b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFile.java new file mode 100644 -index 0000000000000000000000000000000000000000..1b9da27d9f409684917680e41a1aae583f021c20 +index 0000000000000000000000000000000000000000..3f95d7ffa880c598242d38899f71174e4e264338 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFile.java -@@ -0,0 +1,39 @@ +@@ -0,0 +1,41 @@ +package org.leavesmc.leaves.region; + ++import ca.spottedleaf.moonrise.patches.chunk_system.storage.ChunkSystemRegionFile; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.ChunkPos; -+import net.minecraft.world.level.chunk.status.ChunkStatus; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; ++import java.nio.ByteBuffer; +import java.nio.file.Path; -+import java.util.concurrent.locks.ReentrantLock; + -+public interface AbstractRegionFile { ++public interface AbstractRegionFile extends ChunkSystemRegionFile { + + Path getPath(); + @@ -393,11 +441,13 @@ index 0000000000000000000000000000000000000000..1b9da27d9f409684917680e41a1aae58 + void clear(ChunkPos pos) throws IOException; + + void setOversized(int x, int z, boolean oversized) throws IOException; ++ ++ void write(ChunkPos pos, ByteBuffer buf) throws IOException; +} + diff --git a/src/main/java/org/leavesmc/leaves/region/AbstractRegionFileFactory.java b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFileFactory.java new file mode 100644 -index 0000000000000000000000000000000000000000..72f4507aa10f2ecad545199ccb88038fd49dbe35 +index 0000000000000000000000000000000000000000..8df8f28d15736c4e363e2abdec0a56d6ccb15861 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/AbstractRegionFileFactory.java @@ -0,0 +1,24 @@ @@ -419,7 +469,7 @@ index 0000000000000000000000000000000000000000..72f4507aa10f2ecad545199ccb88038f + + public static AbstractRegionFile getAbstractRegionFile(RegionStorageInfo storageKey, Path path, Path directory, RegionFileVersion compressionFormat, boolean dsync) throws IOException { + if (path.toString().endsWith(".linear")) { -+ return new LinearRegionFile(path, LeavesConfig.linearCompressionLevel); ++ return new LinearRegionFile(path, LeavesConfig.region.linear.compressionLevel); + } else { + return new RegionFile(storageKey, path, directory, compressionFormat, dsync); + } @@ -427,12 +477,13 @@ index 0000000000000000000000000000000000000000..72f4507aa10f2ecad545199ccb88038f +} diff --git a/src/main/java/org/leavesmc/leaves/region/LinearRegionFile.java b/src/main/java/org/leavesmc/leaves/region/LinearRegionFile.java new file mode 100644 -index 0000000000000000000000000000000000000000..381897d87b10147a67dbb13194eb054d4823c9de +index 0000000000000000000000000000000000000000..f903895b53eada8795a6ee9ab33cf30bf69c2c98 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/LinearRegionFile.java -@@ -0,0 +1,319 @@ +@@ -0,0 +1,331 @@ +package org.leavesmc.leaves.region; + ++import ca.spottedleaf.moonrise.patches.chunk_system.io.MoonriseRegionFileIO; +import com.github.luben.zstd.ZstdInputStream; +import com.github.luben.zstd.ZstdOutputStream; +import com.mojang.logging.LogUtils; @@ -484,7 +535,6 @@ index 0000000000000000000000000000000000000000..381897d87b10147a67dbb13194eb054d + public boolean closed = false; + public Path path; + -+ + public LinearRegionFile(Path file, int compression) throws IOException { + this.path = file; + this.compressionLevel = compression; @@ -736,6 +786,18 @@ index 0000000000000000000000000000000000000000..381897d87b10147a67dbb13194eb054d + return false; + } + ++ @Override ++ public MoonriseRegionFileIO.RegionDataController.WriteData moonrise$startWrite(CompoundTag data, ChunkPos pos) { ++ DataOutputStream buff = getChunkDataOutputStream(pos); ++ return new MoonriseRegionFileIO.RegionDataController.WriteData( ++ data, MoonriseRegionFileIO.RegionDataController.WriteData.WriteResult.WRITE, ++ buff, LinearRegionFile::writeNothing ++ ); ++ } ++ ++ private static void writeNothing(AbstractRegionFile regionFile) { ++ } ++ + private class ChunkBuffer extends ByteArrayOutputStream { + private final ChunkPos pos; + @@ -752,7 +814,7 @@ index 0000000000000000000000000000000000000000..381897d87b10147a67dbb13194eb054d +} diff --git a/src/main/java/org/leavesmc/leaves/region/LinearRegionFileFlusher.java b/src/main/java/org/leavesmc/leaves/region/LinearRegionFileFlusher.java new file mode 100644 -index 0000000000000000000000000000000000000000..7793c1b870bfc223adc121e6bd98361a2e5d7117 +index 0000000000000000000000000000000000000000..ab6346b678dd619bb7e2fa5e79bd82b7268485f1 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/region/LinearRegionFileFlusher.java @@ -0,0 +1,56 @@ @@ -780,15 +842,15 @@ index 0000000000000000000000000000000000000000..7793c1b870bfc223adc121e6bd98361a + .build() + ); + private final ExecutorService executor = Executors.newFixedThreadPool( -+ LeavesConfig.getLinearFlushThreads(), ++ LeavesConfig.region.linear.getLinearFlushThreads(), + new ThreadFactoryBuilder() + .setNameFormat("linear-flusher-%d") + .build() + ); + + public LinearRegionFileFlusher() { -+ LeavesLogger.LOGGER.info("Using " + LeavesConfig.getLinearFlushThreads() + " threads for linear region flushing."); -+ scheduler.scheduleAtFixedRate(this::pollAndFlush, 0L, LeavesConfig.linearFlushFrequency, TimeUnit.SECONDS); ++ LeavesLogger.LOGGER.info("Using " + LeavesConfig.region.linear.getLinearFlushThreads() + " threads for linear region flushing."); ++ scheduler.scheduleAtFixedRate(this::pollAndFlush, 0L, LeavesConfig.region.linear.flushFrequency, TimeUnit.SECONDS); + } + + public void scheduleSave(LinearRegionFile regionFile) { diff --git a/patches/server/0112-No-TNT-place-update.patch b/patches/server/0104-No-TNT-place-update.patch similarity index 73% rename from patches/server/0112-No-TNT-place-update.patch rename to patches/server/0104-No-TNT-place-update.patch index 3a8db65a..cfdd9de6 100644 --- a/patches/server/0112-No-TNT-place-update.patch +++ b/patches/server/0104-No-TNT-place-update.patch @@ -5,15 +5,15 @@ Subject: [PATCH] No TNT place update 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 a3525ae6d83591664e1456f20d9732a8de0ec326..48412de89948175bab7f7060432afef92cdaa27c 100644 +index 2cbe2053dd5d0bcdcd89de69762c77b400b8697a..be5a34c87173f43969f97cf52f610dae663883de 100644 --- a/src/main/java/net/minecraft/world/level/block/TntBlock.java +++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java -@@ -49,7 +49,7 @@ public class TntBlock extends Block { +@@ -51,7 +51,7 @@ public class TntBlock extends Block { @Override 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 -+ if (!org.leavesmc.leaves.LeavesConfig.noTNTPlaceUpdate && world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent // Leaves - No tnt place update ++ if (!org.leavesmc.leaves.LeavesConfig.modify.noTNTPlaceUpdate && world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent // Leaves - No tnt place update // 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()) { diff --git a/patches/server/0113-Servux-Protocol.patch b/patches/server/0105-Servux-Protocol.patch similarity index 90% rename from patches/server/0113-Servux-Protocol.patch rename to patches/server/0105-Servux-Protocol.patch index 5aafc603..a10da9ac 100644 --- a/patches/server/0113-Servux-Protocol.patch +++ b/patches/server/0105-Servux-Protocol.patch @@ -4,28 +4,11 @@ Date: Wed, 13 Sep 2023 19:31:20 +0800 Subject: [PATCH] Servux Protocol -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..aea042e67daeacfb34bbb770bb267ef29921c517 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 -@@ -412,7 +412,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)); -+ // Leaves start - servux -+ LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); -+ org.leavesmc.leaves.protocol.servux.ServuxStructuresProtocol.onStartedWatchingChunk(player, chunk); -+ PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); -+ // Leaves end - servux - return; - } - throw new IllegalStateException(); diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java -index 1337c4c2e966a8eeeee3480206025a6ee520747a..631b83683b5297aeaa6f81f6b73c75ca4e64dd3c 100644 +index 6952bd0b9229aa2c1c4db5d5659c315374e927a9..e663b795f8656745ba27b24bb136491dab96c22d 100644 --- a/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java -@@ -2009,6 +2009,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf. +@@ -2162,6 +2162,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } this.lastSpawnChunkRadius = i; @@ -158,10 +141,10 @@ index 0000000000000000000000000000000000000000..3a0e790f0d8e6866950601f9936984a8 +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxEntityDataProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxEntityDataProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f38c24530 +index 0000000000000000000000000000000000000000..36cc207c87f7dc56309f2683f3a97fe2f9fff661 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxEntityDataProtocol.java -@@ -0,0 +1,295 @@ +@@ -0,0 +1,278 @@ +package org.leavesmc.leaves.protocol.servux; + +import io.netty.buffer.Unpooled; @@ -174,7 +157,6 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; -+import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.leavesmc.leaves.LeavesConfig; +import org.leavesmc.leaves.LeavesLogger; @@ -184,7 +166,6 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f +import org.leavesmc.leaves.protocol.core.ProtocolUtils; + +import java.util.HashMap; -+import java.util.List; +import java.util.Map; +import java.util.UUID; + @@ -200,7 +181,7 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f + + @ProtocolHandler.PlayerJoin + public static void onPlayerLoggedIn(ServerPlayer player) { -+ if (!LeavesConfig.servuxEntityProtocol) { ++ if (!LeavesConfig.protocol.servux.entityProtocol) { + return; + } + @@ -209,7 +190,7 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f + + @ProtocolHandler.PayloadReceiver(payload = EntityDataPayload.class, payloadId = "entity_data") + public static void onPacketReceive(ServerPlayer player, EntityDataPayload payload) { -+ if (!LeavesConfig.servuxEntityProtocol) { ++ if (!LeavesConfig.protocol.servux.entityProtocol) { + return; + } + @@ -275,7 +256,7 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f + } + + public static void sendPacket(ServerPlayer player, EntityDataPayload payload) { -+ if (!LeavesConfig.servuxEntityProtocol) { ++ if (!LeavesConfig.protocol.servux.entityProtocol) { + return; + } + @@ -307,9 +288,7 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f + PACKET_S2C_NBT_RESPONSE_DATA(11), + // For Packet Splitter (Oversize Packets, C2S) + PACKET_C2S_NBT_RESPONSE_START(12), -+ PACKET_C2S_NBT_RESPONSE_DATA(13), -+ PACKET_C2S_LITEMATICA_PASTE(14), -+ PACKET_C2S_REQUEST_ALL_ENTITIES_IN_CHUNK(15); ++ PACKET_C2S_NBT_RESPONSE_DATA(13); + + private static final class Helper { + static Map ID_TO_TYPE = new HashMap<>(); @@ -330,12 +309,11 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f + public static class EntityDataPayload implements LeavesCustomPayload { + + private final EntityDataPayloadType packetType; -+ private int transactionId; ++ private final int transactionId; + private int entityId; + private BlockPos pos; + private CompoundTag nbt; + private FriendlyByteBuf buffer; -+ private List requestingChunks; + + private EntityDataPayload(EntityDataPayloadType type) { + this.packetType = type; @@ -399,14 +377,6 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f + payload.nbt.merge(nbt); + } + } -+ -+ case PACKET_C2S_LITEMATICA_PASTE -> { -+ payload.nbt = buffer.readNbt(); -+ } -+ -+ case PACKET_C2S_REQUEST_ALL_ENTITIES_IN_CHUNK -> { -+ payload.requestingChunks = buffer.readList(FriendlyByteBuf::readChunkPos); -+ } + } + + return payload; @@ -441,11 +411,7 @@ index 0000000000000000000000000000000000000000..ffa483d369760faeb73555f9a93dac5f + buf.writeBytes(this.buffer.readBytes(this.buffer.readableBytes())); + } + -+ case PACKET_C2S_REQUEST_ALL_ENTITIES_IN_CHUNK -> { -+ buf.writeCollection(this.requestingChunks, FriendlyByteBuf::writeChunkPos); -+ } -+ -+ case PACKET_C2S_METADATA_REQUEST, PACKET_S2C_METADATA, PACKET_C2S_LITEMATICA_PASTE -> { ++ case PACKET_C2S_METADATA_REQUEST, PACKET_S2C_METADATA -> { + buf.writeNbt(this.nbt); + } + } @@ -482,10 +448,10 @@ index 0000000000000000000000000000000000000000..ea83d25b76f2e4814c82c1010ba4c0bc +} diff --git a/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java new file mode 100644 -index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101b4494b47 +index 0000000000000000000000000000000000000000..fb5779d445d693e0a533a61b0a66d786f9b9cb0e --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/protocol/servux/ServuxStructuresProtocol.java -@@ -0,0 +1,465 @@ +@@ -0,0 +1,452 @@ +package org.leavesmc.leaves.protocol.servux; + +import io.netty.buffer.Unpooled; @@ -544,7 +510,7 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + + @ProtocolHandler.PayloadReceiver(payload = StructuresPayload.class, payloadId = "structures") + public static void onPacketReceive(ServerPlayer player, StructuresPayload payload) { -+ if (!LeavesConfig.servuxStructureProtocol) { ++ if (!LeavesConfig.protocol.servux.structureProtocol) { + return; + } + @@ -560,7 +526,7 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + + @ProtocolHandler.PlayerJoin + public static void onPlayerLoggedIn(ServerPlayer player) { -+ if (!LeavesConfig.servuxStructureProtocol) { ++ if (!LeavesConfig.protocol.servux.structureProtocol) { + return; + } + @@ -569,7 +535,7 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + + @ProtocolHandler.PlayerLeave + public static void onPlayerLoggedOut(@NotNull ServerPlayer player) { -+ if (!LeavesConfig.servuxStructureProtocol) { ++ if (!LeavesConfig.protocol.servux.structureProtocol) { + return; + } + @@ -578,7 +544,7 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + + @ProtocolHandler.Ticker + public static void tick() { -+ if (!LeavesConfig.servuxStructureProtocol) { ++ if (!LeavesConfig.protocol.servux.structureProtocol) { + return; + } + @@ -602,7 +568,7 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + } + + public static void onStartedWatchingChunk(ServerPlayer player, LevelChunk chunk) { -+ if (!LeavesConfig.servuxStructureProtocol) { ++ if (!LeavesConfig.protocol.servux.structureProtocol) { + return; + } + @@ -629,10 +595,6 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + + ChunkAccess chunk = world.getChunk(chunkX, chunkZ, ChunkStatus.STRUCTURE_STARTS, false); + -+ if (chunk == null) { -+ return false; -+ } -+ + for (Map.Entry entry : chunk.getAllReferences().entrySet()) { + if (!entry.getValue().isEmpty()) { + return true; @@ -712,10 +674,6 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + + ChunkAccess chunk = world.getChunk(chunkX, chunkZ, ChunkStatus.STRUCTURE_STARTS, false); + -+ if (chunk == null) { -+ return; -+ } -+ + for (Map.Entry entry : chunk.getAllReferences().entrySet()) { + Structure feature = entry.getKey(); + LongSet startChunks = entry.getValue(); @@ -776,11 +734,6 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + } + + ChunkAccess chunk = world.getChunk(pos.x, pos.z, ChunkStatus.STRUCTURE_STARTS, false); -+ -+ if (chunk == null) { -+ continue; -+ } -+ + StructureStart start = chunk.getStartForStructure(structure); + + if (start != null) { @@ -934,7 +887,7 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + } + + public static void sendPacket(ServerPlayer player, StructuresPayload payload) { -+ if (!LeavesConfig.servuxStructureProtocol) { ++ if (!LeavesConfig.protocol.servux.structureProtocol) { + return; + } + @@ -951,3 +904,14 @@ index 0000000000000000000000000000000000000000..306eabf5ce384c863fc986a3a446c101 + sendPacket(player, new StructuresPayload(StructuresPayloadType.PACKET_S2C_STRUCTURE_DATA, buf)); + } +} +diff --git a/src/main/java/org/leavesmc/leaves/region/LeavesHooks.java b/src/main/java/org/leavesmc/leaves/region/LeavesHooks.java +index 47b6241ba0a23a0579b8b046f1e45832117b6581..59fe70c95e157824e12d9ebbf02a5da8cd95a107 100644 +--- a/src/main/java/org/leavesmc/leaves/region/LeavesHooks.java ++++ b/src/main/java/org/leavesmc/leaves/region/LeavesHooks.java +@@ -15,5 +15,6 @@ public final class LeavesHooks extends PaperHooks { + @Override + public void onChunkWatch(ServerLevel world, LevelChunk chunk, ServerPlayer player) { + super.onChunkWatch(world, chunk, player); ++ org.leavesmc.leaves.protocol.servux.ServuxStructuresProtocol.onStartedWatchingChunk(player, chunk); // servux + } + } diff --git a/patches/server/0114-Placing-locked-hopper-no-longer-send-NC-updates.patch b/patches/server/0106-Placing-locked-hopper-no-longer-send-NC-updates.patch similarity index 88% rename from patches/server/0114-Placing-locked-hopper-no-longer-send-NC-updates.patch rename to patches/server/0106-Placing-locked-hopper-no-longer-send-NC-updates.patch index 36cc9ba7..c3e2847b 100644 --- a/patches/server/0114-Placing-locked-hopper-no-longer-send-NC-updates.patch +++ b/patches/server/0106-Placing-locked-hopper-no-longer-send-NC-updates.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Placing locked hopper no longer send NC updates diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java -index 1848ed1dff8327db5c9a01e8e2019997e927692c..79f5a45cb0f4e2ffdbe82614afa6ad017fd1b09e 100644 +index 0df454c4e574aaf8b6d6e5210c399d452af26294..4dcf72b7cce6cf74326b1ffcc7d3648693bc58e8 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java -@@ -1128,7 +1128,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl +@@ -1202,7 +1202,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl } if ((i & 1) != 0) { diff --git a/patches/server/0115-Renewable-deepslate.patch b/patches/server/0107-Renewable-deepslate.patch similarity index 70% rename from patches/server/0115-Renewable-deepslate.patch rename to patches/server/0107-Renewable-deepslate.patch index 3d7b3acc..8a3da7ec 100644 --- a/patches/server/0115-Renewable-deepslate.patch +++ b/patches/server/0107-Renewable-deepslate.patch @@ -5,28 +5,28 @@ Subject: [PATCH] Renewable deepslate diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java -index 84623c632d8c2f0fa7ec939c711316d757117d23..bba79516a7e3765d6b04992dfae310eb30f889ce 100644 +index a2d023ff011f71f80032f02430a53d6a08a23623..3efec7e75c9666182ce728f5d1ba2f645a5a2386 100644 --- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java -@@ -190,7 +190,7 @@ public class LiquidBlock extends Block implements BucketPickup { +@@ -193,7 +193,7 @@ public class LiquidBlock extends Block implements BucketPickup { BlockPos blockposition1 = pos.relative(enumdirection.getOpposite()); if (world.getFluidState(blockposition1).is(FluidTags.WATER)) { - Block block = world.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : Blocks.COBBLESTONE; -+ Block block = world.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : (org.leavesmc.leaves.LeavesConfig.renewableDeepslate && world.dimension() == Level.OVERWORLD && pos.getY() < 0 ? Blocks.COBBLED_DEEPSLATE : Blocks.COBBLESTONE); // Leaves - renewable deepslate ++ Block block = world.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : (org.leavesmc.leaves.LeavesConfig.modify.renewableDeepslate && world.dimension() == Level.OVERWORLD && pos.getY() < 0 ? Blocks.COBBLED_DEEPSLATE : Blocks.COBBLESTONE); // Leaves - renewable deepslate // CraftBukkit start if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, pos, block.defaultBlockState())) { 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 3bb4a9a1a6249e8ba2de237f801210e7f4fd5825..8f849cd7ee32a2180fc46d5ee618add72b07de72 100644 +index 884db3e64cb22ed765beec8f11ea309fcf810207..1562a7a6a026115691bec2157fe4516db0b4a893 100644 --- a/src/main/java/net/minecraft/world/level/material/LavaFluid.java +++ b/src/main/java/net/minecraft/world/level/material/LavaFluid.java -@@ -211,7 +211,7 @@ public abstract class LavaFluid extends FlowingFluid { +@@ -212,7 +212,7 @@ public abstract class LavaFluid extends FlowingFluid { if (this.is(FluidTags.LAVA) && fluid1.is(FluidTags.WATER)) { if (state.getBlock() instanceof LiquidBlock) { // CraftBukkit start - if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world.getMinecraftWorld(), pos, Blocks.STONE.defaultBlockState(), 3)) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world.getMinecraftWorld(), pos, org.leavesmc.leaves.LeavesConfig.renewableDeepslate && world.getMinecraftWorld().dimension() == Level.OVERWORLD && pos.getY() < 0 ? Blocks.DEEPSLATE.defaultBlockState() : Blocks.STONE.defaultBlockState(), 3)) { // Leaves - renewable deepslate ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world.getMinecraftWorld(), pos, org.leavesmc.leaves.LeavesConfig.modify.renewableDeepslate && world.getMinecraftWorld().dimension() == Level.OVERWORLD && pos.getY() < 0 ? Blocks.DEEPSLATE.defaultBlockState() : Blocks.STONE.defaultBlockState(), 3)) { // Leaves - renewable deepslate return; } // CraftBukkit end diff --git a/patches/server/0116-Renewable-sponges.patch b/patches/server/0108-Renewable-sponges.patch similarity index 80% rename from patches/server/0116-Renewable-sponges.patch rename to patches/server/0108-Renewable-sponges.patch index 3a54b7bf..8792e3e4 100644 --- a/patches/server/0116-Renewable-sponges.patch +++ b/patches/server/0108-Renewable-sponges.patch @@ -5,20 +5,20 @@ Subject: [PATCH] Renewable sponges diff --git a/src/main/java/net/minecraft/world/entity/monster/Guardian.java b/src/main/java/net/minecraft/world/entity/monster/Guardian.java -index 5df07b59ff6e39687e361d89d7764381ca3ce9ca..465a46f497d726303859ca31688a848699441234 100644 +index 951f46684623582980901c1ebc1870aa5bcf25a1..4c42999ae3f92ede0e7908e9bb4b4efa59b63cfb 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Guardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/Guardian.java -@@ -345,6 +345,28 @@ public class Guardian extends Monster { +@@ -342,6 +342,28 @@ public class Guardian extends Monster { } + // Leaves start - renewable sponges + @Override + public void thunderHit(net.minecraft.server.level.ServerLevel world, net.minecraft.world.entity.LightningBolt lightning) { -+ if (org.leavesmc.leaves.LeavesConfig.renewableSponges && !this.isRemoved() && !(this instanceof ElderGuardian)) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.renewableSponges && !this.isRemoved() && !(this instanceof ElderGuardian)) { + ElderGuardian elderGuardian = new ElderGuardian(EntityType.ELDER_GUARDIAN ,this.level()); + elderGuardian.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); -+ elderGuardian.finalizeSpawn(world ,this.level().getCurrentDifficultyAt(elderGuardian.blockPosition()), MobSpawnType.CONVERSION, null); ++ elderGuardian.finalizeSpawn(world ,this.level().getCurrentDifficultyAt(elderGuardian.blockPosition()), EntitySpawnReason.CONVERSION, null); + elderGuardian.setNoAi(this.isNoAi()); + + if (this.hasCustomName()) { diff --git a/patches/server/0117-Renewable-coral.patch b/patches/server/0109-Renewable-coral.patch similarity index 85% rename from patches/server/0117-Renewable-coral.patch rename to patches/server/0109-Renewable-coral.patch index 2e8940a3..09c764be 100644 --- a/patches/server/0117-Renewable-coral.patch +++ b/patches/server/0109-Renewable-coral.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Renewable coral diff --git a/src/main/java/net/minecraft/world/level/block/CoralFanBlock.java b/src/main/java/net/minecraft/world/level/block/CoralFanBlock.java -index 7701683000132479d8c8eaa77ac3f93e41a960be..3bd4308bb2b8cce5091486f5fc57fbc7cb24b202 100644 +index 09849438e2170d8b2fbc82ee7dfc5df28ce91cc9..ea788e532b6964bd16ac9297064657df775e2323 100644 --- a/src/main/java/net/minecraft/world/level/block/CoralFanBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CoralFanBlock.java -@@ -13,7 +13,7 @@ import net.minecraft.world.level.block.state.BlockState; +@@ -14,7 +14,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; @@ -17,23 +17,23 @@ index 7701683000132479d8c8eaa77ac3f93e41a960be..3bd4308bb2b8cce5091486f5fc57fbc7 public static final MapCodec CODEC = RecordCodecBuilder.mapCodec((instance) -> { return instance.group(CoralBlock.DEAD_CORAL_FIELD.forGetter((blockcoralfan) -> { -@@ -63,4 +63,11 @@ public class CoralFanBlock extends BaseCoralFanBlock { - return super.updateShape(state, direction, neighborState, world, pos, neighborPos); +@@ -64,4 +64,11 @@ public class CoralFanBlock extends BaseCoralFanBlock { + return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); } } + + // Leaves start - renewable coral + @Override + public boolean isEnabled() { -+ return org.leavesmc.leaves.LeavesConfig.renewableCoral == org.leavesmc.leaves.LeavesConfig.RenewableCoralType.EXPANDED; ++ return org.leavesmc.leaves.LeavesConfig.modify.renewableCoral == org.leavesmc.leaves.LeavesConfig.ModifyConfig.RenewableCoralType.EXPANDED; + } + // Leaves end - renewable coral } diff --git a/src/main/java/net/minecraft/world/level/block/CoralPlantBlock.java b/src/main/java/net/minecraft/world/level/block/CoralPlantBlock.java -index 4c4aa2a63be84ff614a3dc0db2864266755545a2..208685f28509f92483f1efc89302e7a9ce6838c6 100644 +index 5200ceb141795dd7d4d28d861996ce360adeae01..954b2b19bdc19c18c9cdb9a867d6d9407367713b 100644 --- a/src/main/java/net/minecraft/world/level/block/CoralPlantBlock.java +++ b/src/main/java/net/minecraft/world/level/block/CoralPlantBlock.java -@@ -16,7 +16,7 @@ import net.minecraft.world.level.material.Fluids; +@@ -17,7 +17,7 @@ import net.minecraft.world.level.material.Fluids; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -42,7 +42,7 @@ index 4c4aa2a63be84ff614a3dc0db2864266755545a2..208685f28509f92483f1efc89302e7a9 public static final MapCodec CODEC = RecordCodecBuilder.mapCodec((instance) -> { return instance.group(CoralBlock.DEAD_CORAL_FIELD.forGetter((blockcoralplant) -> { -@@ -73,4 +73,12 @@ public class CoralPlantBlock extends BaseCoralPlantTypeBlock { +@@ -74,4 +74,12 @@ public class CoralPlantBlock extends BaseCoralPlantTypeBlock { protected VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { return CoralPlantBlock.SHAPE; } @@ -50,8 +50,8 @@ index 4c4aa2a63be84ff614a3dc0db2864266755545a2..208685f28509f92483f1efc89302e7a9 + // Leaves start - renewable coral + @Override + public boolean isEnabled() { -+ return org.leavesmc.leaves.LeavesConfig.renewableCoral == org.leavesmc.leaves.LeavesConfig.RenewableCoralType.EXPANDED -+ || org.leavesmc.leaves.LeavesConfig.renewableCoral == org.leavesmc.leaves.LeavesConfig.RenewableCoralType.TRUE; ++ return org.leavesmc.leaves.LeavesConfig.modify.renewableCoral == org.leavesmc.leaves.LeavesConfig.ModifyConfig.RenewableCoralType.EXPANDED ++ || org.leavesmc.leaves.LeavesConfig.modify.renewableCoral == org.leavesmc.leaves.LeavesConfig.ModifyConfig.RenewableCoralType.TRUE; + } + // Leaves end - renewable coral } @@ -70,7 +70,7 @@ index 7bc5ff8eb1174834dcc27363af4a5cef19017b3d..790686428b01127d0f94e044f0ec4bff BlockPos blockPos = pos.above(); diff --git a/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java b/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java new file mode 100644 -index 0000000000000000000000000000000000000000..f1cad30bd4c937b137305e790e1d372a123170a6 +index 0000000000000000000000000000000000000000..ec5aa65df54e2467d594a1885dbda850cee5a886 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/util/FertilizableCoral.java @@ -0,0 +1,72 @@ @@ -125,7 +125,7 @@ index 0000000000000000000000000000000000000000..f1cad30bd4c937b137305e790e1d372a + + MapColor color = blockUnder.getMapColor(worldIn, pos); + BlockState properBlock = blockUnder; -+ HolderSet.Named coralBlocks = worldIn.registryAccess().registryOrThrow(Registries.BLOCK).getTag(BlockTags.CORAL_BLOCKS).orElseThrow(); ++ HolderSet.Named coralBlocks = worldIn.registryAccess().lookupOrThrow(Registries.BLOCK).getOrThrow(BlockTags.CORAL_BLOCKS); + for (Holder block : coralBlocks) { + properBlock = block.value().defaultBlockState(); + if (properBlock.getMapColor(worldIn, pos) == color) { diff --git a/patches/server/0118-Fast-resume.patch b/patches/server/0110-Fast-resume.patch similarity index 93% rename from patches/server/0118-Fast-resume.patch rename to patches/server/0110-Fast-resume.patch index 9ead8e6a..eb1b9417 100644 --- a/patches/server/0118-Fast-resume.patch +++ b/patches/server/0110-Fast-resume.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fast resume 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..ea1ffe6b5e49ccf2b472829ed97e977b4938f3a5 100644 +index 91a6f57f35fc1553159cca138a0619e703b2b014..32a6f6e0d05ab43e1d5b48c45e55119d3cd65321 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 -@@ -582,6 +582,49 @@ public final class ChunkHolderManager { +@@ -602,6 +602,49 @@ public final class ChunkHolderManager { } } @@ -59,10 +59,10 @@ index 58d3d1a47e9f2423c467bb329c2d5f4b58a8b5ef..ea1ffe6b5e49ccf2b472829ed97e977b return this.removeTicketAtLevel(type, CoordinateUtils.getChunkKey(chunkPos), level, identifier); } diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java -index 0c43170b31363beca32407bddeee33ef9404d09a..3b4d1bd023904ead8b340021acd1d74b5aa53a87 100644 +index 585d5d98abbd0a9842bef5d5cff24f8429f378d9..96ca6702fa67e1d26d39367d0fe64a508787998e 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java -@@ -749,6 +749,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop> NEED_SAVED = Set.of(TicketType.PLAYER, TicketType.PORTAL, RegionizedPlayerChunkLoader.PLAYER_TICKET); + + public static void tryToLoadTickets() { -+ if (!LeavesConfig.fastResume) { ++ if (!LeavesConfig.modify.fastResume) { + return; + } + @@ -139,7 +139,7 @@ index 0000000000000000000000000000000000000000..36e9da7e68de086bc8572138eb14d0e0 + } + + public static void tryToSaveTickets() { -+ if (!LeavesConfig.fastResume) { ++ if (!LeavesConfig.modify.fastResume) { + return; + } + @@ -171,7 +171,7 @@ index 0000000000000000000000000000000000000000..36e9da7e68de086bc8572138eb14d0e0 + + for (JsonElement ticketElement : chunkJson.get("tickets").getAsJsonArray()) { + Ticket ticket = tickFormJson((JsonObject) ticketElement); -+ chunkDistanceManager.getChunkHolderManager().addTicketAtLevelCustom(ticket, chunkKey, true); ++ chunkDistanceManager.moonrise$getChunkHolderManager().addTicketAtLevelCustom(ticket, chunkKey, true); + } + } + } @@ -184,7 +184,7 @@ index 0000000000000000000000000000000000000000..36e9da7e68de086bc8572138eb14d0e0 + JsonArray levelArray = new JsonArray(); + DistanceManager chunkDistanceManager = level.getChunkSource().chunkMap.distanceManager; + -+ for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { ++ for (Long2ObjectMap.Entry>> chunkTickets : chunkDistanceManager.moonrise$getChunkHolderManager().getTicketsCopy().long2ObjectEntrySet()) { + long chunkKey = chunkTickets.getLongKey(); + JsonArray ticketArray = new JsonArray(); + SortedArraySet> tickets = chunkTickets.getValue(); diff --git a/patches/server/0119-Vanilla-hopper.patch b/patches/server/0111-Vanilla-hopper.patch similarity index 94% rename from patches/server/0119-Vanilla-hopper.patch rename to patches/server/0111-Vanilla-hopper.patch index 30fd7f8b..0220dde9 100644 --- a/patches/server/0119-Vanilla-hopper.patch +++ b/patches/server/0111-Vanilla-hopper.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Vanilla hopper This is a temporary solution designed to attempt to restore the vanilla behavior of the funnel while preserving optimizations as much as possible. It should ultimately be replaced by the optimization solution provided by lithium. 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 9cc932fb547686db7c06f7ef29e3b07b2e755982..134245c3b48162c603ca032e8fc0d4b7f0bc3637 100644 +index af3846dbb29d4738d0cce20c85d2f40c7ccf4f70..a20fcf4211f92dba56c5343bb2c0c7d0db7751b7 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 @@ -305,36 +305,49 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -24,7 +24,7 @@ index 9cc932fb547686db7c06f7ef29e3b07b2e755982..134245c3b48162c603ca032e8fc0d4b7 - // No plugin could of relied on the behavior of false as the other call - // site for IMIE did not exhibit the same behavior + // Leaves start - fix vanilla -+ if (org.leavesmc.leaves.LeavesConfig.vanillaHopper && movedItem.getCount() <= movedItemCount) { ++ if (org.leavesmc.leaves.LeavesConfig.fix.vanillaHopper && movedItem.getCount() <= movedItemCount) { + movedItem = origItemStack.copy(); + final ItemStack remainingItem = addItem(container, hopper, container.removeItem(i, movedItemCount), null); + if (remainingItem.isEmpty()) { @@ -81,5 +81,5 @@ index 9cc932fb547686db7c06f7ef29e3b07b2e755982..134245c3b48162c603ca032e8fc0d4b7 - origItemStack.setCount(originalItemCount); + // Leaves end - fix vanilla - if (level.paperConfig().hopper.cooldownWhenFull && !org.leavesmc.leaves.LeavesConfig.mcTechnicalMode) { // Leaves + if (level.paperConfig().hopper.cooldownWhenFull && !org.leavesmc.leaves.LeavesConfig.modify.mcTechnicalMode) { // Leaves cooldownHopper(hopper); diff --git a/patches/server/0120-Force-minecraft-command.patch b/patches/server/0112-Force-minecraft-command.patch similarity index 81% rename from patches/server/0120-Force-minecraft-command.patch rename to patches/server/0112-Force-minecraft-command.patch index 1b7ed0ec..0d3852af 100644 --- a/patches/server/0120-Force-minecraft-command.patch +++ b/patches/server/0112-Force-minecraft-command.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Force minecraft command diff --git a/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java b/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java -index 90ed57a7fbcd0625b64084347460e9864216f610..1dadec002e620b3e4906ab3381944cc9d807523b 100644 +index 90ed57a7fbcd0625b64084347460e9864216f610..e3598f7a0d183255ba17bc0f08cee284a0898cef 100644 --- a/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java +++ b/src/main/java/org/bukkit/craftbukkit/command/CraftCommandMap.java @@ -14,4 +14,18 @@ public class CraftCommandMap extends SimpleCommandMap { @@ -17,7 +17,7 @@ index 90ed57a7fbcd0625b64084347460e9864216f610..1dadec002e620b3e4906ab3381944cc9 + @Override + public Command getCommand(String name) { + Command target = super.getCommand(name); -+ if (org.leavesmc.leaves.LeavesConfig.forceMinecraftCommand && !(target instanceof org.bukkit.craftbukkit.command.VanillaCommandWrapper)) { ++ if (org.leavesmc.leaves.LeavesConfig.mics.forceMinecraftCommand && !(target instanceof org.bukkit.craftbukkit.command.VanillaCommandWrapper)) { + Command minecraftTarget = super.getCommand("minecraft:" + name); + if (minecraftTarget != null) { + return minecraftTarget; diff --git a/patches/server/0121-Fix-falling-block-s-block-location.patch b/patches/server/0113-Fix-falling-block-s-block-location.patch similarity index 87% rename from patches/server/0121-Fix-falling-block-s-block-location.patch rename to patches/server/0113-Fix-falling-block-s-block-location.patch index 945910cd..45c0df32 100644 --- a/patches/server/0121-Fix-falling-block-s-block-location.patch +++ b/patches/server/0113-Fix-falling-block-s-block-location.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix falling block's block location diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 9cb6528935879bb88659100417c96a1b3748668c..799df7c72e0d4c4ccd4d33a94681ff440ff81d08 100644 +index c317035db4f7456988dd02b72729ec6ad7703a7c..7dfa1dc42224eafc2196a532a00dc606d35b8d89 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -4755,6 +4755,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -5074,6 +5074,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess int j = Mth.floor(y); int k = Mth.floor(z); diff --git a/patches/server/0122-Bytebuf-API.patch b/patches/server/0114-Bytebuf-API.patch similarity index 87% rename from patches/server/0122-Bytebuf-API.patch rename to patches/server/0114-Bytebuf-API.patch index d63b4a5f..b2e1671c 100644 --- a/patches/server/0122-Bytebuf-API.patch +++ b/patches/server/0114-Bytebuf-API.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Bytebuf API diff --git a/src/main/java/net/minecraft/network/chat/Component.java b/src/main/java/net/minecraft/network/chat/Component.java -index 2de8da4dbe2f7b9da740a90829f18bff0b3d5b8c..a8af45393b4733ea3b6639ad7d890896752185fd 100644 +index 5941800692ed06e17925ec6526ea38793a65de12..f77b2e12fb43039cf16a8511c9820859874c5c97 100644 --- a/src/main/java/net/minecraft/network/chat/Component.java +++ b/src/main/java/net/minecraft/network/chat/Component.java -@@ -296,7 +296,7 @@ public interface Component extends Message, FormattedText, Iterable { +@@ -302,7 +302,7 @@ public interface Component extends Message, FormattedText, Iterable { return (MutableComponent) ComponentSerialization.CODEC.parse(registries.createSerializationContext(JsonOps.INSTANCE), json).getOrThrow(JsonParseException::new); } @@ -18,10 +18,10 @@ index 2de8da4dbe2f7b9da740a90829f18bff0b3d5b8c..a8af45393b4733ea3b6639ad7d890896 } diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java -index fc6d2d5febe4a8c7f315997b3dde38b0dd70d03a..b440103be9aaef22a0ea42d0ed05f92a0ceca924 100644 +index 0a88fb90b72e9f4bda6067cb42e024bb44b5101b..b39a6c5dd2cde112c5c5a317591f5ca51701a0a0 100644 --- a/src/main/java/net/minecraft/server/players/PlayerList.java +++ b/src/main/java/net/minecraft/server/players/PlayerList.java -@@ -466,6 +466,12 @@ public abstract class PlayerList { +@@ -471,6 +471,12 @@ public abstract class PlayerList { return; } @@ -35,10 +35,10 @@ index fc6d2d5febe4a8c7f315997b3dde38b0dd70d03a..b440103be9aaef22a0ea42d0ed05f92a // Leaves start - bot support diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 8649eae46402d53290f17181003bda5e97114d82..402e590454764117f3f20649bbf13148d0fce521 100644 +index ea4def367b645a442e7ee4fd8b1b2075b8604ccb..54d99e5b42082c306e0ac16b2b5ba9ff3c43a1b0 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 { +@@ -315,6 +315,7 @@ public final class CraftServer implements Server { public final io.papermc.paper.SparksFly spark; // Paper - spark private final org.leavesmc.leaves.entity.CraftBotManager botManager; // Leaves private final org.leavesmc.leaves.entity.CraftPhotographerManager photographerManager = new org.leavesmc.leaves.entity.CraftPhotographerManager(); // Leaves @@ -46,7 +46,7 @@ index 8649eae46402d53290f17181003bda5e97114d82..402e590454764117f3f20649bbf13148 // Paper start - Folia region threading API private final io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler regionizedScheduler = new io.papermc.paper.threadedregions.scheduler.FallbackRegionScheduler(); -@@ -3245,4 +3246,15 @@ public final class CraftServer implements Server { +@@ -3298,4 +3299,15 @@ public final class CraftServer implements Server { return photographerManager; } // Leaves end - replay mod api @@ -63,10 +63,10 @@ index 8649eae46402d53290f17181003bda5e97114d82..402e590454764117f3f20649bbf13148 + // Leaves end - Bytebuf API } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -index 79ebcaac331c8f8860928668701c791b54bdb66b..3b06bb785bf94e70662811eae62e579c5c111e82 100644 +index 08de38dfc4b2f6f48e9f3ae1d303712ea619e21f..707c64ec946bafd78da5f070ec3af750ebc1d5e7 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java -@@ -3568,4 +3568,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { +@@ -3580,4 +3580,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player { this.getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundEntityEventPacket(((CraftEntity) target).getHandle(), effect.getData())); } // Paper end - entity effect API @@ -126,10 +126,10 @@ index 0000000000000000000000000000000000000000..443f7f6e0b8d40eaafb8009b3b7e405c +} diff --git a/src/main/java/org/leavesmc/leaves/bytebuf/WrappedBytebuf.java b/src/main/java/org/leavesmc/leaves/bytebuf/WrappedBytebuf.java new file mode 100644 -index 0000000000000000000000000000000000000000..707d784cf17926e869481c39b0da908eab501708 +index 0000000000000000000000000000000000000000..9601eb5aa8cbcf1836cba7853af9ece2d93ec9c3 --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bytebuf/WrappedBytebuf.java -@@ -0,0 +1,260 @@ +@@ -0,0 +1,277 @@ +package org.leavesmc.leaves.bytebuf; + +import com.google.gson.JsonElement; @@ -143,6 +143,7 @@ index 0000000000000000000000000000000000000000..707d784cf17926e869481c39b0da908e +import org.bukkit.inventory.ItemStack; +import org.bukkit.craftbukkit.inventory.CraftItemStack; + ++import java.util.List; +import java.util.UUID; + +public class WrappedBytebuf implements Bytebuf { @@ -166,7 +167,10 @@ index 0000000000000000000000000000000000000000..707d784cf17926e869481c39b0da908e + + @Override + public byte[] toArray() { -+ return buf.array(); ++ int length = buf.readableBytes(); ++ byte[] data = new byte[length]; ++ buf.getBytes(buf.readerIndex(), data); ++ return data; + } + + @Override @@ -381,6 +385,19 @@ index 0000000000000000000000000000000000000000..707d784cf17926e869481c39b0da908e + } + + @Override ++ public Bytebuf writeItemStackList(List itemStacks) { ++ List nmsItemList = itemStacks.stream().map(CraftItemStack::unwrap).toList(); ++ net.minecraft.world.item.ItemStack.OPTIONAL_LIST_STREAM_CODEC.encode(this.registryBuf, nmsItemList); ++ return this; ++ } ++ ++ @Override ++ public List readItemStackList() { ++ List nmsItemList = net.minecraft.world.item.ItemStack.OPTIONAL_LIST_STREAM_CODEC.decode(this.registryBuf); ++ return nmsItemList.stream().map(net.minecraft.world.item.ItemStack::asBukkitMirror).toList(); ++ } ++ ++ @Override + public Bytebuf copy() { + return new WrappedBytebuf(this.buf.copy()); + } @@ -392,10 +409,10 @@ index 0000000000000000000000000000000000000000..707d784cf17926e869481c39b0da908e +} diff --git a/src/main/java/org/leavesmc/leaves/bytebuf/internal/InternalBytebufHandler.java b/src/main/java/org/leavesmc/leaves/bytebuf/internal/InternalBytebufHandler.java new file mode 100644 -index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704ca8f9b426 +index 0000000000000000000000000000000000000000..04dbb4cb7c3ea4979c33dba595208e22e6552b0a --- /dev/null +++ b/src/main/java/org/leavesmc/leaves/bytebuf/internal/InternalBytebufHandler.java -@@ -0,0 +1,225 @@ +@@ -0,0 +1,234 @@ +package org.leavesmc.leaves.bytebuf.internal; + +import com.google.common.cache.Cache; @@ -429,7 +446,6 @@ index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704c +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; -+import java.util.concurrent.ExecutionException; + +import static org.leavesmc.leaves.bytebuf.packet.PacketType.*; + @@ -452,13 +468,10 @@ index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704c + } + + if (msg instanceof net.minecraft.network.protocol.Packet nmsPacket) { -+ PacketType type = toEnumType(nmsPacket.type()); -+ if (type != null) { -+ try { -+ msg = callPacketInEvent(player, createBytebufPacket(type, nmsPacket)); -+ } catch (Exception e) { -+ MinecraftServer.LOGGER.error("Error on PacketInEvent.", e); -+ } ++ try { ++ msg = callPacketInEvent(player, nmsPacket); ++ } catch (Exception e) { ++ MinecraftServer.LOGGER.error("Error on PacketInEvent.", e); + } + } + @@ -475,13 +488,10 @@ index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704c + } + + if (msg instanceof net.minecraft.network.protocol.Packet nmsPacket) { -+ PacketType type = toEnumType(nmsPacket.type()); -+ if (type != null) { -+ try { -+ msg = callPacketOutEvent(player, createBytebufPacket(type, nmsPacket)); -+ } catch (Exception e) { -+ MinecraftServer.LOGGER.error("Error on PacketInEvent.", e); -+ } ++ try { ++ msg = callPacketOutEvent(player, nmsPacket); ++ } catch (Exception e) { ++ MinecraftServer.LOGGER.error("Error on PacketInEvent.", e); + } + } + @@ -533,7 +543,7 @@ index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704c + } + + public void injectPlayer(ServerPlayer player) { -+ if (LeavesConfig.leavesPacketEvent) { ++ if (LeavesConfig.mics.leavesPacketEvent) { + player.connection.connection.channel.pipeline().addBefore("packet_handler", PacketHandler.handlerName, new PacketHandler(player.getBukkitEntity())); + } + } @@ -542,7 +552,15 @@ index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704c + return manager; + } + -+ public net.minecraft.network.protocol.Packet callPacketInEvent(Player player, Packet packet) { ++ public net.minecraft.network.protocol.Packet callPacketInEvent(Player player, net.minecraft.network.protocol.Packet nmsPacket) { ++ if (listenerMap.isEmpty()) { ++ return nmsPacket; ++ } ++ PacketType type = toEnumType(nmsPacket.type()); ++ if (type == null) { ++ return nmsPacket; ++ } ++ Packet packet = createBytebufPacket(type, nmsPacket); + for (PacketListener listener : listenerMap.keySet()) { + if (listenerMap.get(listener).isEnabled()) { + packet = listener.onPacketIn(player, packet); @@ -554,7 +572,15 @@ index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704c + return createNMSPacket(packet); + } + -+ public net.minecraft.network.protocol.Packet callPacketOutEvent(Player player, Packet packet) { ++ public net.minecraft.network.protocol.Packet callPacketOutEvent(Player player, net.minecraft.network.protocol.Packet nmsPacket) { ++ if (listenerMap.isEmpty()) { ++ return nmsPacket; ++ } ++ PacketType type = toEnumType(nmsPacket.type()); ++ if (type == null) { ++ return nmsPacket; ++ } ++ Packet packet = createBytebufPacket(type, nmsPacket); + for (PacketListener listener : listenerMap.keySet()) { + if (listenerMap.get(listener).isEnabled()) { + packet = listener.onPacketOut(player, packet); @@ -606,13 +632,13 @@ index 0000000000000000000000000000000000000000..fb7625ce28d2d8c79aad680ff34d704c + throw new RuntimeException(e); + } + }); -+ } catch (ExecutionException ignore) { ++ } catch (Exception ignore) { + return null; + } + } + + public Packet createBytebufPacket(PacketType type, net.minecraft.network.protocol.Packet nmsPacket) { -+ RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(8192), MinecraftServer.getServer().registryAccess()); ++ RegistryFriendlyByteBuf buf = new RegistryFriendlyByteBuf(Unpooled.buffer(), MinecraftServer.getServer().registryAccess()); + StreamCodec> codec = type2CodecMap.get(type); + if (codec == null) { + throw new UnsupportedOperationException("This feature is not completely finished yet, packet type " + type + " is not supported temporary."); diff --git a/patches/server/0123-Allow-grindstone-overstacking.patch b/patches/server/0115-Allow-grindstone-overstacking.patch similarity index 64% rename from patches/server/0123-Allow-grindstone-overstacking.patch rename to patches/server/0115-Allow-grindstone-overstacking.patch index 8b57b8f0..9316177f 100644 --- a/patches/server/0123-Allow-grindstone-overstacking.patch +++ b/patches/server/0115-Allow-grindstone-overstacking.patch @@ -5,24 +5,24 @@ Subject: [PATCH] Allow grindstone overstacking diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -index 138f77d13dda574def523d74fa55bc71b5bfa01b..620fac433487caa4d22cb865e8b77c2e372462df 100644 +index 5687f492fc76f699e2a388790ca5380d9b8c8d0a..53e79f2ca799b8de7d6410dbb3dafa1cb2eff7b6 100644 --- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java +++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java -@@ -206,7 +206,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -194,7 +194,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { byte b0 = 1; if (!firstInput.isDamageableItem()) { - if (firstInput.getMaxStackSize() < 2 || !ItemStack.matches(firstInput, secondInput)) { -+ if (!org.leavesmc.leaves.LeavesConfig.allowGrindstoneOverstacking && firstInput.getMaxStackSize() < 2 || !ItemStack.matches(firstInput, secondInput)) { // Leaves - allowGrindstoneOverstaking ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && firstInput.getMaxStackSize() < 2 || !ItemStack.matches(firstInput, secondInput)) { // Leaves - allowGrindstoneOverstaking return ItemStack.EMPTY; } -@@ -290,7 +290,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { +@@ -278,7 +278,7 @@ public class GrindstoneMenu extends AbstractContainerMenu { ItemStack itemstack3 = this.repairSlots.getItem(1); if (slot == 2) { - if (!this.moveItemStackTo(itemstack1, 3, 39, true)) { -+ if (!this.moveItemStackTo(itemstack1, 3, 39, true, org.leavesmc.leaves.LeavesConfig.allowGrindstoneOverstacking)) { // Leaves - allowGrindstoneOverstacking: Disable stack check ++ if (!this.moveItemStackTo(itemstack1, 3, 39, true, org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowGrindstoneOverstacking)) { // Leaves - allowGrindstoneOverstacking: Disable stack check return ItemStack.EMPTY; } diff --git a/patches/server/0116-Configurable-MC-67.patch b/patches/server/0116-Configurable-MC-67.patch new file mode 100644 index 00000000..ea72d590 --- /dev/null +++ b/patches/server/0116-Configurable-MC-67.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> +Date: Wed, 26 Jun 2024 18:15:57 +0800 +Subject: [PATCH] Configurable MC-67 + + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 7dfa1dc42224eafc2196a532a00dc606d35b8d89..58906cda0432dc8d5988f83f19a5f2deac094566 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -4175,6 +4175,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public boolean canTeleport(Level from, Level to) { ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowEntityPortalWithPassenger && (this.isPassenger() || this.isVehicle())) return false; // Leaves - allowEntityPortalWithPassenger + 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(); diff --git a/patches/server/0117-Disable-end-gateway-portal-entity-ticking.patch b/patches/server/0117-Disable-end-gateway-portal-entity-ticking.patch new file mode 100644 index 00000000..9892ec6f --- /dev/null +++ b/patches/server/0117-Disable-end-gateway-portal-entity-ticking.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: violetc <58360096+s-yh-china@users.noreply.github.com> +Date: Mon, 1 Jul 2024 22:09:33 +0800 +Subject: [PATCH] Disable end gateway portal entity ticking + + +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 50d726874af316a264fa0c2589f5b04559dffb50..fd9c27cf12cca630b192f9cdf876b024157b6073 100644 +--- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java ++++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java +@@ -130,7 +130,10 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { + } + // Leaves end - force void trade + +- return vec3d == null ? null : (entity instanceof ThrownEnderpearl ? new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY)); // CraftBukkit ++ // Leaves start - Disable end gateway portal entity ticking ++ TeleportTransition.PostTeleportTransition postTeleportTransition = org.leavesmc.leaves.LeavesConfig.modify.oldMC.disableGatewayPortalEntityTicking ? TeleportTransition.DO_NOTHING : TeleportTransition.PLACE_PORTAL_TICKET; ++ return vec3d == null ? null : (entity instanceof ThrownEnderpearl ? new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Set.of(), postTeleportTransition, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), postTeleportTransition, PlayerTeleportEvent.TeleportCause.END_GATEWAY)); // CraftBukkit ++ // Leaves end - Disable end gateway portal entity ticking + } else { + return null; + } diff --git a/patches/server/0126-Disable-crystal-portal-proximity-check.patch b/patches/server/0118-Disable-crystal-portal-proximity-check.patch similarity index 90% rename from patches/server/0126-Disable-crystal-portal-proximity-check.patch rename to patches/server/0118-Disable-crystal-portal-proximity-check.patch index 6a86ba99..652016f6 100644 --- a/patches/server/0126-Disable-crystal-portal-proximity-check.patch +++ b/patches/server/0118-Disable-crystal-portal-proximity-check.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Disable crystal-portal proximity check diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java -index 5f51e64cb0611a4ba6bdcdcacbcba1063a7f3a5c..29c9543a1afa03b2d2864d366d526029c0f4f0d4 100644 +index b62db8c7c8c57e43869ee239ebf4b02f112355d9..b33ac3221ad9f91d466285a4b00b0e0c67000864 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 { @@ -28,10 +28,10 @@ index 5f51e64cb0611a4ba6bdcdcacbcba1063a7f3a5c..29c9543a1afa03b2d2864d366d526029 } 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 6f867139ef83ca6d1fc26f98c4d9e4b7ce689580..98b4c79b46f2ca073d92c3bbade826df8b7c9206 100644 +index e944a730503a9c50bcde819515a1d7e7f1ec59fd..65d338cc685bb3f5da23aa5bb8b632360cad66b3 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 -@@ -619,12 +619,14 @@ public class EndDragonFight { +@@ -622,12 +622,14 @@ public class EndDragonFight { } public boolean tryRespawn() { // CraftBukkit - return boolean @@ -46,7 +46,7 @@ index 6f867139ef83ca6d1fc26f98c4d9e4b7ce689580..98b4c79b46f2ca073d92c3bbade826df if (this.dragonKilled && this.respawnStage == null) { BlockPos blockposition = this.portalLocation; -@@ -642,6 +644,7 @@ public class EndDragonFight { +@@ -645,6 +647,7 @@ public class EndDragonFight { blockposition = this.portalLocation; } @@ -54,7 +54,7 @@ index 6f867139ef83ca6d1fc26f98c4d9e4b7ce689580..98b4c79b46f2ca073d92c3bbade826df // Paper start - Perf: Do crystal-portal proximity check before entity lookup if (placedEndCrystalPos != null) { // The end crystal must be 0 or 1 higher than the portal origin -@@ -657,6 +660,7 @@ public class EndDragonFight { +@@ -660,6 +663,7 @@ public class EndDragonFight { } } // Paper end - Perf: Do crystal-portal proximity check before entity lookup diff --git a/patches/server/0127-Can-disable-LivingEntity-aiStep-alive-check.patch b/patches/server/0119-Can-disable-LivingEntity-aiStep-alive-check.patch similarity index 67% rename from patches/server/0127-Can-disable-LivingEntity-aiStep-alive-check.patch rename to patches/server/0119-Can-disable-LivingEntity-aiStep-alive-check.patch index c03a24f9..cfd86593 100644 --- a/patches/server/0127-Can-disable-LivingEntity-aiStep-alive-check.patch +++ b/patches/server/0119-Can-disable-LivingEntity-aiStep-alive-check.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Can disable LivingEntity aiStep alive check diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java -index a55264e08b595005e30b3bf0b17a23e7de563bc3..dbe8f6f366e02a035cf4fea81a0bda0322c6b360 100644 +index b5a3606b0810290fbbd624a401977e24d5a6a178..c42367fd5971c124b3307738a3921f276c3ef570 100644 --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java -@@ -3193,7 +3193,7 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3327,7 +3327,7 @@ public abstract class LivingEntity extends Entity implements Attackable { } } - if (!this.isRemoved()) { -+ if (org.leavesmc.leaves.LeavesConfig.disableLivingEntityAiStepAliveCheck || !this.isRemoved()) { // Leaves - can disable check ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.disableLivingEntityAiStepAliveCheck || !this.isRemoved()) { // Leaves - can disable check this.aiStep(); } diff --git a/patches/server/0128-Leaves-plugins.patch b/patches/server/0120-Leaves-plugins.patch similarity index 99% rename from patches/server/0128-Leaves-plugins.patch rename to patches/server/0120-Leaves-plugins.patch index 6e15ba99..14492889 100644 --- a/patches/server/0128-Leaves-plugins.patch +++ b/patches/server/0120-Leaves-plugins.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves plugins diff --git a/build.gradle.kts b/build.gradle.kts -index ecc29f64b5cbd2849f86d22aee8a76d172b3def0..881896b9f25afc530f4c04096ee364b80f8e8e0c 100644 +index 8559918f8f91e6137ac873b37af29aa3b6c0c4a0..f2eb3b2eb2ad6a3c41f6ad84497fc65f22823f32 100644 --- a/build.gradle.kts +++ b/build.gradle.kts -@@ -34,6 +34,7 @@ dependencies { +@@ -47,6 +47,7 @@ dependencies { implementation("com.github.luben:zstd-jni:1.5.6-3") implementation("org.lz4:lz4-java:1.8.0") // Leaves end - Linear format diff --git a/patches/server/0129-Fix-fortress-mob-spawn.patch b/patches/server/0121-Fix-fortress-mob-spawn.patch similarity index 81% rename from patches/server/0129-Fix-fortress-mob-spawn.patch rename to patches/server/0121-Fix-fortress-mob-spawn.patch index 8b5226eb..d8d797b0 100644 --- a/patches/server/0129-Fix-fortress-mob-spawn.patch +++ b/patches/server/0121-Fix-fortress-mob-spawn.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Fix fortress mob spawn diff --git a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java -index cb7465ed9bdebe1b31f02d11725e75ff8b44ca66..f56da8b6741b81b7a51d0d9cb89a2192e059f6eb 100644 +index cb7465ed9bdebe1b31f02d11725e75ff8b44ca66..bc4b7bc3fe55b8c9c34a8bc22a035a3c4891a2af 100644 --- a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java +++ b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java @@ -176,6 +176,14 @@ public class MobSpawnSettings { @@ -15,7 +15,7 @@ index cb7465ed9bdebe1b31f02d11725e75ff8b44ca66..f56da8b6741b81b7a51d0d9cb89a2192 + // Leaves start - fix fortress mob spawn + @Override + public boolean equals(Object obj) { -+ if(!org.leavesmc.leaves.LeavesConfig.fixFortressMobSpawn || !(obj instanceof SpawnerData other)) return super.equals(obj); ++ if(!org.leavesmc.leaves.LeavesConfig.modify.oldMC.fixFortressMobSpawn || !(obj instanceof SpawnerData other)) return super.equals(obj); + return this.type == other.type && this.minCount == other.minCount && this.maxCount == other.maxCount; + } + // Leaves end - fix fortress mob spawn diff --git a/patches/server/0130-Fix-FallingBlockEntity-Duplicate.patch b/patches/server/0122-Fix-FallingBlockEntity-Duplicate.patch similarity index 81% rename from patches/server/0130-Fix-FallingBlockEntity-Duplicate.patch rename to patches/server/0122-Fix-FallingBlockEntity-Duplicate.patch index 6ff96f4f..853dab95 100644 --- a/patches/server/0130-Fix-FallingBlockEntity-Duplicate.patch +++ b/patches/server/0122-Fix-FallingBlockEntity-Duplicate.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Fix FallingBlockEntity Duplicate 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 b83be9bbb9f348da83c0fd1ecc7f65c8a58b45b9..e38f588e3043320a9c135e03f506a00924ed58b8 100644 +index 06d9a519e64d4b8b8764b3ad7691ad93b5cee065..e067e826aae963e30dd9e12e57e9a63912165b0d 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -419,7 +419,7 @@ public class FallingBlockEntity extends Entity { +@@ -435,7 +435,7 @@ public class FallingBlockEntity extends Entity { boolean flag = (resourcekey1 == Level.END || resourcekey == Level.END) && resourcekey1 != resourcekey; - Entity entity = super.changeDimension(teleportTarget); + Entity entity = super.teleport(teleportTarget); - this.forceTickAfterTeleportToDuplicate = entity != null && flag && io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowUnsafeEndPortalTeleportation; // Paper + this.forceTickAfterTeleportToDuplicate = entity != null && flag; // Paper // Leaves diff --git a/patches/server/0131-Old-BlockEntity-behaviour.patch b/patches/server/0123-Old-BlockEntity-behaviour.patch similarity index 59% rename from patches/server/0131-Old-BlockEntity-behaviour.patch rename to patches/server/0123-Old-BlockEntity-behaviour.patch index 5aa42751..d7393a08 100644 --- a/patches/server/0131-Old-BlockEntity-behaviour.patch +++ b/patches/server/0123-Old-BlockEntity-behaviour.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Old BlockEntity behaviour diff --git a/src/main/java/net/minecraft/world/level/block/ChiseledBookShelfBlock.java b/src/main/java/net/minecraft/world/level/block/ChiseledBookShelfBlock.java -index ca3a8ead09cf0d3c1352ac266b749bc0bca2ff9a..b705ee10371e77d027b88afc790f346f20c0087f 100644 +index 5a95ecd7e94652d2af3eb42ee9cf61913fb95a69..cadd3362e9993715cd47e5e5c6d7a3eb60d11d33 100644 --- a/src/main/java/net/minecraft/world/level/block/ChiseledBookShelfBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ChiseledBookShelfBlock.java -@@ -197,6 +197,13 @@ public class ChiseledBookShelfBlock extends BaseEntityBlock { +@@ -194,6 +194,13 @@ public class ChiseledBookShelfBlock extends BaseEntityBlock { } chiseledBookShelfBlockEntity.clearContent(); + // Leaves start - behaviour 1.21.1- -+ if (org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour) { + bl = false; + world.updateNeighbourForOutputSignal(pos, this); + break label32; @@ -23,58 +23,53 @@ index ca3a8ead09cf0d3c1352ac266b749bc0bca2ff9a..b705ee10371e77d027b88afc790f346f break label32; } 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 3a1e2f62b297f384cc0dcfb828e523a37c703d6f..c45a636f8c3542f7a073d6b76a7bf23a91b8c7dc 100644 +index 70f2e6278e2d970245ca5b46fbd9ffae4727b47b..cb1ef444efaaff0579154537db151d16efae357e 100644 --- a/src/main/java/net/minecraft/world/level/block/LecternBlock.java +++ b/src/main/java/net/minecraft/world/level/block/LecternBlock.java -@@ -226,10 +226,11 @@ public class LecternBlock extends BaseEntityBlock { +@@ -229,10 +229,11 @@ public class LecternBlock extends BaseEntityBlock { this.popBook(state, world, pos); } - super.onRemove(state, world, pos, newState, moved); -+ if (!org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- if ((Boolean) state.getValue(LecternBlock.POWERED)) { - world.updateNeighborsAt(pos.below(), this); + LecternBlock.updateBelow(world, pos, state); } -+ if (org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- } } 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 8d57c68d2f20f7c0d5c1be5d5b12e6926aad8c58..f1341d0f6545dfb13d14a37a68fda5b3403604b5 100644 +index 0ed449a188d98f87dbddd2d76009fed02a29ed25..e812d158cf56d4d1d67ea335433a23c7be0e4292 100644 --- a/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SculkSensorBlock.java -@@ -150,10 +150,11 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg +@@ -151,10 +151,11 @@ public class SculkSensorBlock extends BaseEntityBlock implements SimpleWaterlogg @Override protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { if (!state.is(newState.getBlock())) { - super.onRemove(state, world, pos, newState, moved); -+ if (!org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- ++ if (!org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- if (SculkSensorBlock.getPhase(state) == SculkSensorPhase.ACTIVE) { SculkSensorBlock.updateNeighbours(world, pos, state); } -+ if (org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- } } 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 7d88524eb5b193600c8985c68bb9ed10e3fe3c4d..7f966d72b3124a79a5941c574ede329184666389 100644 +index b01918fc97926a3182c21145bb7411e7bc409d35..0646a861cc04ad29ba850f34cd6a629228f2c640 100644 --- a/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java +++ b/src/main/java/net/minecraft/world/level/block/ShulkerBoxBlock.java -@@ -186,10 +186,11 @@ public class ShulkerBoxBlock extends BaseEntityBlock { - protected void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) { - if (!state.is(newState.getBlock())) { - BlockEntity blockEntity = world.getBlockEntity(pos); -- super.onRemove(state, world, pos, newState, moved); -+ if (!org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- +@@ -186,6 +186,7 @@ public class ShulkerBoxBlock extends BaseEntityBlock { if (blockEntity instanceof ShulkerBoxBlockEntity) { world.updateNeighbourForOutputSignal(pos, state.getBlock()); } -+ if (org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour) super.onRemove(state, world, pos, newState, moved); // Leaves - behaviour 1.21.1- } } 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 f2ef63d69bfc6fb3b3dc4b3b2938733d1c371746..e6c67426c9ea76eae2c677d796d0db579acaed6e 100644 +index 1f929b467a0ece3143af58a657cf5983c07a8d51..e8ab0901393844c9d2ea3595a28306bfd8bd40fb 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 @@ -67,7 +67,7 @@ public abstract class BlockEntity { @@ -82,7 +77,7 @@ index f2ef63d69bfc6fb3b3dc4b3b2938733d1c371746..e6c67426c9ea76eae2c677d796d0db57 public boolean isValidBlockState(BlockState state) { - return this.type.isValid(state); -+ return org.leavesmc.leaves.LeavesConfig.oldBlockEntityBehaviour || this.type.isValid(state); // Leaves - behaviour 1.21.1- ++ return org.leavesmc.leaves.LeavesConfig.modify.oldMC.oldBlockEntityBehaviour || this.type.isValid(state); // Leaves - behaviour 1.21.1- } public static BlockPos getPosFromTag(CompoundTag nbt) { diff --git a/patches/server/0124-Configurable-MC-67.patch b/patches/server/0124-Configurable-MC-67.patch deleted file mode 100644 index 4cc34bb8..00000000 --- a/patches/server/0124-Configurable-MC-67.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lumine1909 <133463833+Lumine1909@users.noreply.github.com> -Date: Wed, 26 Jun 2024 18:15:57 +0800 -Subject: [PATCH] Configurable MC-67 - - -diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java -index 799df7c72e0d4c4ccd4d33a94681ff440ff81d08..4e3bc9334af6b8d3131edb6ce2abffc165a82bb6 100644 ---- a/src/main/java/net/minecraft/world/entity/Entity.java -+++ b/src/main/java/net/minecraft/world/entity/Entity.java -@@ -3918,7 +3918,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - } - - public boolean canChangeDimensions(Level from, Level to) { -- return this.isAlive() && this.valid; // Paper - Fix item duplication and teleport issues -+ return !(!org.leavesmc.leaves.LeavesConfig.allowEntityPortalWithPassenger && (this.isPassenger() || this.isVehicle())) && this.isAlive() && this.valid; // Paper - Fix item duplication and teleport issues // Leaves - allowEntityPortalWithPassenger - } - - public float getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState, float max) { diff --git a/patches/server/0124-Revert-raid-changes.patch b/patches/server/0124-Revert-raid-changes.patch new file mode 100644 index 00000000..b19b61a8 --- /dev/null +++ b/patches/server/0124-Revert-raid-changes.patch @@ -0,0 +1,98 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: huanli233 <392352840@qq.com> +Date: Wed, 23 Oct 2024 23:10:48 +0800 +Subject: [PATCH] Revert raid changes + + +diff --git a/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java b/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java +index e33e8db5f24437081d2026e66c13256aa3893a15..07cdc52ad0aa3c246e1769c3dda3c17bb9a10e8b 100644 +--- a/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java ++++ b/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java +@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect { + && !serverPlayer.isSpectator() + && world.getDifficulty() != Difficulty.PEACEFUL + && world.isVillage(serverPlayer.blockPosition())) { ++ // Leaves start - Revert raid changes ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.raid.allowBadOmenTriggerRaid) { ++ return world.getRaids().createOrExtendRaid(serverPlayer, serverPlayer.blockPosition()) != null; ++ } ++ // Leaves end - Revert raid changes + Raid raid = world.getRaidAt(serverPlayer.blockPosition()); + if (raid == null || raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel()) { + serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier)); +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 9b911254b24bc77930c518a9c61916983ba72e3c..124bfe881356fcee25e8d66c18c918a4c31bafa4 100644 +--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java ++++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java +@@ -17,8 +17,11 @@ import net.minecraft.network.syncher.EntityDataSerializers; + import net.minecraft.network.syncher.SynchedEntityData; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.sounds.SoundEvent; ++import net.minecraft.util.Mth; + import net.minecraft.world.DifficultyInstance; + import net.minecraft.world.damagesource.DamageSource; ++import net.minecraft.world.effect.MobEffectInstance; ++import net.minecraft.world.effect.MobEffects; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.EntitySpawnReason; + import net.minecraft.world.entity.EntityType; +@@ -32,10 +35,13 @@ import net.minecraft.world.entity.ai.targeting.TargetingConditions; + import net.minecraft.world.entity.ai.util.DefaultRandomPos; + import net.minecraft.world.entity.ai.village.poi.PoiManager; + import net.minecraft.world.entity.ai.village.poi.PoiTypes; ++import net.minecraft.world.entity.animal.Wolf; + import net.minecraft.world.entity.item.ItemEntity; + import net.minecraft.world.entity.monster.AbstractIllager; + import net.minecraft.world.entity.monster.PatrollingMonster; ++import net.minecraft.world.entity.player.Player; + import net.minecraft.world.item.ItemStack; ++import net.minecraft.world.level.GameRules; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.ServerLevelAccessor; + import net.minecraft.world.level.pathfinder.Path; +@@ -134,6 +140,45 @@ public abstract class Raider extends PatrollingMonster { + + raid.removeFromRaid(this, false); + } ++ ++ // Leaves start - Revert raid changes ++ if (this.level() instanceof ServerLevel serverLevel) { ++ if (org.leavesmc.leaves.LeavesConfig.modify.oldMC.raid.giveBadOmenWhenKillPatrolLeader && this.isPatrolLeader() && raid == null && serverLevel.getRaidAt(this.blockPosition()) == null) { ++ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); ++ Player entityhuman = null; ++ ++ if (entity instanceof Player) { ++ entityhuman = (Player) entity; ++ } else if (entity instanceof Wolf) { ++ Wolf entitywolf = (Wolf) entity; ++ LivingEntity entityliving = entitywolf.getOwner(); ++ ++ if (entitywolf.isTame() && entityliving instanceof Player) { ++ entityhuman = (Player) entityliving; ++ } ++ } ++ ++ if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.getOminousBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN))) && entityhuman != null) { ++ MobEffectInstance mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); ++ int i = 1; ++ ++ if (mobeffect != null) { ++ i += mobeffect.getAmplifier(); ++ entityhuman.removeEffectNoUpdate(MobEffects.BAD_OMEN); ++ } else { ++ --i; ++ } ++ ++ i = Mth.clamp(i, 0, 4); ++ MobEffectInstance mobeffect1 = new MobEffectInstance(MobEffects.BAD_OMEN, 120000, i, false, false, true); ++ ++ if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_DISABLE_RAIDS)) { ++ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit ++ } ++ } ++ } ++ } ++ // Leaves end - Revert raid changes + } + + super.die(damageSource); diff --git a/patches/server/0133-Allow-anvil-destroy-item-entities.patch b/patches/server/0125-Allow-anvil-destroy-item-entities.patch similarity index 69% rename from patches/server/0133-Allow-anvil-destroy-item-entities.patch rename to patches/server/0125-Allow-anvil-destroy-item-entities.patch index 56d5254a..826d6c0b 100644 --- a/patches/server/0133-Allow-anvil-destroy-item-entities.patch +++ b/patches/server/0125-Allow-anvil-destroy-item-entities.patch @@ -5,15 +5,15 @@ Subject: [PATCH] Allow anvil destroy item entities 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 e38f588e3043320a9c135e03f506a00924ed58b8..5e91b222f9e6e908071d7b21a3fb782fa52eddab 100644 +index e067e826aae963e30dd9e12e57e9a63912165b0d..8b34cbe4a1bbabbfb281e758e65f3dc03ba8db78 100644 --- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -275,7 +275,7 @@ public class FallingBlockEntity extends Entity { +@@ -291,7 +291,7 @@ public class FallingBlockEntity extends Entity { if (i < 0) { return false; } else { - Predicate predicate = EntitySelector.NO_CREATIVE_OR_SPECTATOR.and(EntitySelector.LIVING_ENTITY_STILL_ALIVE); -+ Predicate predicate = org.leavesmc.leaves.LeavesConfig.allowAnvilDestroyItemEntities ? EntitySelector.NO_CREATIVE_OR_SPECTATOR : EntitySelector.NO_CREATIVE_OR_SPECTATOR.and(EntitySelector.LIVING_ENTITY_STILL_ALIVE); // Leaves - Allow anvil destroy item entities ++ Predicate predicate = org.leavesmc.leaves.LeavesConfig.modify.oldMC.allowAnvilDestroyItemEntities ? EntitySelector.NO_CREATIVE_OR_SPECTATOR : EntitySelector.NO_CREATIVE_OR_SPECTATOR.and(EntitySelector.LIVING_ENTITY_STILL_ALIVE); // Leaves - Allow anvil destroy item entities Block block = this.blockState.getBlock(); DamageSource damagesource1; diff --git a/patches/server/0125-Disable-end-gateway-portal-entity-ticking.patch b/patches/server/0125-Disable-end-gateway-portal-entity-ticking.patch deleted file mode 100644 index b8d4407c..00000000 --- a/patches/server/0125-Disable-end-gateway-portal-entity-ticking.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: violetc <58360096+s-yh-china@users.noreply.github.com> -Date: Mon, 1 Jul 2024 22:09:33 +0800 -Subject: [PATCH] Disable end gateway portal entity ticking - - -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 3087c60589de8fc38e12d322e58886ba76749507..d16f1defac4030248ad24b4c4a38ca1717908cd4 100644 ---- a/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java -+++ b/src/main/java/net/minecraft/world/level/block/EndGatewayBlock.java -@@ -128,7 +128,7 @@ public class EndGatewayBlock extends BaseEntityBlock implements Portal { - } - // Leaves end - force void trade - -- return vec3d != null ? new DimensionTransition(world, vec3d, EndGatewayBlock.calculateExitMovement(entity), entity.getYRot(), entity.getXRot(), DimensionTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : null; // CraftBukkit -+ return vec3d != null ? new DimensionTransition(world, vec3d, EndGatewayBlock.calculateExitMovement(entity), entity.getYRot(), entity.getXRot(), !org.leavesmc.leaves.LeavesConfig.disableGatewayPortalEntityTicking ? DimensionTransition.PLACE_PORTAL_TICKET : DimensionTransition.DO_NOTHING, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : null; // CraftBukkit // Leaves - disable-gateway-portal-entity-ticking - } else { - return null; - } diff --git a/patches/server/0134-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch b/patches/server/0126-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch similarity index 78% rename from patches/server/0134-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch rename to patches/server/0126-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch index ab154112..1869476a 100644 --- a/patches/server/0134-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch +++ b/patches/server/0126-Fix-Incorrect-Collision-Behavior-for-Block-Shape.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Fix Incorrect Collision Behavior for Block Shape 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..1de40570caed06942d6aba638ee4fa1acb2ecfd1 100644 +index aec503ca1551ce4b15b8975832cd664ebd670722..7815fd1f7aa621351905555fa63479cce1798d99 100644 --- a/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java +++ b/src/main/java/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java -@@ -56,6 +56,14 @@ public final class CollisionUtil { +@@ -101,6 +101,14 @@ public final class CollisionUtil { (box1.minZ - box2.maxZ) < -COLLISION_EPSILON && (box1.maxZ - box2.minZ) > COLLISION_EPSILON; } @@ -21,10 +21,10 @@ index 748ab4d637ce463272bae4fdbab6842a27385126..1de40570caed06942d6aba638ee4fa1a + // Leaves end + // 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 && -@@ -1700,7 +1708,10 @@ public final class CollisionUtil { - net.minecraft.world.phys.AABB singleAABB = ((ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); +@@ -2042,7 +2050,10 @@ public final class CollisionUtil { + AABB singleAABB = ((CollisionVoxelShape)blockCollision).moonrise$getSingleAABBRepresentation(); if (singleAABB != null) { singleAABB = singleAABB.move((double)blockX, (double)blockY, (double)blockZ); - if (!voxelShapeIntersect(aabb, singleAABB)) { diff --git a/patches/server/0135-Disable-vault-blacklist.patch b/patches/server/0127-Disable-vault-blacklist.patch similarity index 74% rename from patches/server/0135-Disable-vault-blacklist.patch rename to patches/server/0127-Disable-vault-blacklist.patch index 4859607f..4002c551 100644 --- a/patches/server/0135-Disable-vault-blacklist.patch +++ b/patches/server/0127-Disable-vault-blacklist.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Disable vault blacklist diff --git a/src/main/java/net/minecraft/world/level/block/entity/vault/VaultServerData.java b/src/main/java/net/minecraft/world/level/block/entity/vault/VaultServerData.java -index 30544783d959fbdf4b6fd53c10bd3806e718a066..0a7cd5fad1eb0cc5770a4dd14349168fe7933721 100644 +index 30544783d959fbdf4b6fd53c10bd3806e718a066..4319e2108b59aa78ed00d88859ba742e663edbd3 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/vault/VaultServerData.java +++ b/src/main/java/net/minecraft/world/level/block/entity/vault/VaultServerData.java @@ -57,11 +57,12 @@ public class VaultServerData { @@ -13,17 +13,17 @@ index 30544783d959fbdf4b6fd53c10bd3806e718a066..0a7cd5fad1eb0cc5770a4dd14349168f boolean hasRewardedPlayer(Player player) { - return this.rewardedPlayers.contains(player.getUUID()); -+ return !org.leavesmc.leaves.LeavesConfig.disableVaultBlacklist && this.rewardedPlayers.contains(player.getUUID()); // Leaves - disable vault blacklist ++ return !org.leavesmc.leaves.LeavesConfig.modify.disableVaultBlacklist && this.rewardedPlayers.contains(player.getUUID()); // Leaves - disable vault blacklist } @VisibleForTesting public void addToRewardedPlayers(Player player) { -+ if (org.leavesmc.leaves.LeavesConfig.disableVaultBlacklist) return; // Leaves - disable vault blacklist ++ if (org.leavesmc.leaves.LeavesConfig.modify.disableVaultBlacklist) return; // Leaves - disable vault blacklist this.rewardedPlayers.add(player.getUUID()); if (this.rewardedPlayers.size() > 128) { Iterator iterator = this.rewardedPlayers.iterator(); diff --git a/src/main/java/net/minecraft/world/level/block/entity/vault/VaultSharedData.java b/src/main/java/net/minecraft/world/level/block/entity/vault/VaultSharedData.java -index f09ce717869741bb2f027ab1216fad9d86425683..b113f44e7e6a1f5303392bff09914f0260bd3bc6 100644 +index f09ce717869741bb2f027ab1216fad9d86425683..a32c8920ef6c1ab4b6ec7a68b9ed10c37afdfbf3 100644 --- a/src/main/java/net/minecraft/world/level/block/entity/vault/VaultSharedData.java +++ b/src/main/java/net/minecraft/world/level/block/entity/vault/VaultSharedData.java @@ -68,8 +68,8 @@ public class VaultSharedData { @@ -32,7 +32,7 @@ index f09ce717869741bb2f027ab1216fad9d86425683..b113f44e7e6a1f5303392bff09914f02 .stream() - .filter(uuid -> !serverData.getRewardedPlayers().contains(uuid)) - .collect(Collectors.toSet()); -+ .filter(uuid -> org.leavesmc.leaves.LeavesConfig.disableVaultBlacklist || !serverData.getRewardedPlayers().contains(uuid)) ++ .filter(uuid -> org.leavesmc.leaves.LeavesConfig.modify.disableVaultBlacklist || !serverData.getRewardedPlayers().contains(uuid)) + .collect(Collectors.toSet()); // Leaves - disable vault blacklist if (!this.connectedPlayers.equals(set)) { this.connectedPlayers = set; diff --git a/patches/server/0132-Revert-raid-changes.patch b/patches/server/0132-Revert-raid-changes.patch deleted file mode 100644 index 80f0bc54..00000000 --- a/patches/server/0132-Revert-raid-changes.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: huanli233 <392352840@qq.com> -Date: Wed, 23 Oct 2024 23:10:48 +0800 -Subject: [PATCH] Revert raid changes - - -diff --git a/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java b/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java -index 038ee9e1ef4c7fc6a92efbba0f2ec9063c236df5..391be234ad2635cabb0eb39eecb1e07d2d872518 100644 ---- a/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java -+++ b/src/main/java/net/minecraft/world/effect/BadOmenMobEffect.java -@@ -1,5 +1,6 @@ - package net.minecraft.world.effect; - -+import net.minecraft.core.BlockPos; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.Difficulty; -@@ -20,6 +21,11 @@ class BadOmenMobEffect extends MobEffect { - public boolean applyEffectTick(LivingEntity entity, int amplifier) { - if (entity instanceof ServerPlayer serverPlayer && !serverPlayer.isSpectator()) { - ServerLevel serverLevel = serverPlayer.serverLevel(); -+ // Leaves start - Revert raid changes -+ if (org.leavesmc.leaves.LeavesConfig.allowBadOmenTriggerRaid) { -+ return this.legacyApplyEffectTick(serverPlayer, serverLevel); -+ } -+ // Leaves end - Revert raid changes - if (serverLevel.getDifficulty() != Difficulty.PEACEFUL && serverLevel.isVillage(serverPlayer.blockPosition())) { - Raid raid = serverLevel.getRaidAt(serverPlayer.blockPosition()); - if (raid == null || raid.getRaidOmenLevel() < raid.getMaxRaidOmenLevel()) { -@@ -32,4 +38,9 @@ class BadOmenMobEffect extends MobEffect { - - return true; - } -+ -+ private boolean legacyApplyEffectTick(ServerPlayer player, ServerLevel world) { -+ BlockPos blockPos = player.blockPosition(); -+ return world.getDifficulty() == Difficulty.PEACEFUL || !world.isVillage(blockPos) || world.getRaids().createOrExtendRaid(player, blockPos) == null; -+ } - } -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 6e68f8fa8280a106b1a262d86aa130e89d4f5cce..2401ebf4f2cbc841c7938eba2e0bd7dd54124c9e 100644 ---- a/src/main/java/net/minecraft/world/entity/raid/Raider.java -+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java -@@ -16,8 +16,11 @@ import net.minecraft.network.syncher.EntityDataSerializers; - import net.minecraft.network.syncher.SynchedEntityData; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.sounds.SoundEvent; -+import net.minecraft.util.Mth; - import net.minecraft.world.DifficultyInstance; - import net.minecraft.world.damagesource.DamageSource; -+import net.minecraft.world.effect.MobEffectInstance; -+import net.minecraft.world.effect.MobEffects; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.EntityType; - import net.minecraft.world.entity.EquipmentSlot; -@@ -30,10 +33,13 @@ import net.minecraft.world.entity.ai.targeting.TargetingConditions; - import net.minecraft.world.entity.ai.util.DefaultRandomPos; - import net.minecraft.world.entity.ai.village.poi.PoiManager; - import net.minecraft.world.entity.ai.village.poi.PoiTypes; -+import net.minecraft.world.entity.animal.Wolf; - import net.minecraft.world.entity.item.ItemEntity; - import net.minecraft.world.entity.monster.AbstractIllager; - import net.minecraft.world.entity.monster.PatrollingMonster; -+import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.ItemStack; -+import net.minecraft.world.level.GameRules; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.ServerLevelAccessor; - import net.minecraft.world.phys.Vec3; -@@ -131,6 +137,43 @@ public abstract class Raider extends PatrollingMonster { - - raid.removeFromRaid(this, false); - } -+ -+ // Leaves start - Revert raid changes -+ if (org.leavesmc.leaves.LeavesConfig.giveBadOmenWhenKillPatrolLeader && this.isPatrolLeader() && raid == null && ((ServerLevel) this.level()).getRaidAt(this.blockPosition()) == null) { -+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD); -+ Player entityhuman = null; -+ -+ if (entity instanceof Player) { -+ entityhuman = (Player) entity; -+ } else if (entity instanceof Wolf) { -+ Wolf entitywolf = (Wolf) entity; -+ LivingEntity entityliving = entitywolf.getOwner(); -+ -+ if (entitywolf.isTame() && entityliving instanceof Player) { -+ entityhuman = (Player) entityliving; -+ } -+ } -+ -+ if (!itemstack.isEmpty() && ItemStack.matches(itemstack, Raid.getLeaderBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN))) && entityhuman != null) { -+ MobEffectInstance mobeffect = entityhuman.getEffect(MobEffects.BAD_OMEN); -+ int i = 1; -+ -+ if (mobeffect != null) { -+ i += mobeffect.getAmplifier(); -+ entityhuman.removeEffectNoUpdate(MobEffects.BAD_OMEN); -+ } else { -+ --i; -+ } -+ -+ i = Mth.clamp(i, 0, 4); -+ MobEffectInstance mobeffect1 = new MobEffectInstance(MobEffects.BAD_OMEN, 120000, i, false, false, true); -+ -+ if (!this.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_RAIDS)) { -+ entityhuman.addEffect(mobeffect1, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.PATROL_CAPTAIN); // CraftBukkit -+ } -+ } -+ } -+ // Leaves end - Revert raid changes - } - - super.die(damageSource); diff --git a/patches/server/0030-Use-aging-cache-for-biome-temperatures.patch b/patches/unapplied/server/0030-Use-aging-cache-for-biome-temperatures.patch similarity index 100% rename from patches/server/0030-Use-aging-cache-for-biome-temperatures.patch rename to patches/unapplied/server/0030-Use-aging-cache-for-biome-temperatures.patch diff --git a/patches/server/0062-Spawn-ignore-lc.patch b/patches/unapplied/server/0058-Spawn-ignore-lc.patch similarity index 78% rename from patches/server/0062-Spawn-ignore-lc.patch rename to patches/unapplied/server/0058-Spawn-ignore-lc.patch index 9cc4f396..e43a352a 100644 --- a/patches/server/0062-Spawn-ignore-lc.patch +++ b/patches/unapplied/server/0058-Spawn-ignore-lc.patch @@ -5,12 +5,12 @@ Subject: [PATCH] Spawn ignore lc diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -index 63ca6becabdd12a61b7ce5b6046bfb7c72a5bf56..595f2480a61c9f8d3aa66667b93a1f0e90e7a7ac 100644 +index 4772d0b1c70213bb73aa22eca820ade21335b3a8..9f188a921781f9620b6dcdc6c7549a8a4709efa1 100644 --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java -@@ -198,6 +198,19 @@ public final class NaturalSpawner { +@@ -230,6 +230,19 @@ public final class NaturalSpawner { } - 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 + // Leaves start - ignore lc + if (org.leavesmc.leaves.LeavesConfig.ignoreLC) { @@ -27,9 +27,9 @@ index 63ca6becabdd12a61b7ce5b6046bfb7c72a5bf56..595f2480a61c9f8d3aa66667b93a1f0e + // Leaves stop - ignore lc BlockPos blockposition = NaturalSpawner.getRandomPosWithin(world, chunk); - if (blockposition.getY() >= world.getMinBuildHeight() + 1) { -@@ -206,6 +219,16 @@ public final class NaturalSpawner { - return 0; // Paper - Optional per player mob spawns + if (blockposition.getY() >= world.getMinY() + 1) { +@@ -237,6 +250,16 @@ public final class NaturalSpawner { + } } + // Leaves start - ignore lc diff --git a/patches/server/0088-Skip-negligible-planar-movement-multiplication.patch b/patches/unapplied/server/0088-Skip-negligible-planar-movement-multiplication.patch similarity index 100% rename from patches/server/0088-Skip-negligible-planar-movement-multiplication.patch rename to patches/unapplied/server/0088-Skip-negligible-planar-movement-multiplication.patch