From e1c003355296d70ea50e80d1933aba34e00d0763 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Sun, 16 Jun 2024 17:21:14 +0200 Subject: Updated Upstream (Bukkit/CraftBukkit) Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 2b4b6d14 PR-1023: Convert InventoryView to interface CraftBukkit Changes: 68603b1c1 Use expanded interaction ranges for traced interact events eae9f760c PR-1414: Convert InventoryView to interface ee9eafe67 Fix Implementation for DamageSource#isIndirect for internal custom causing entity --- patches/api/0006-Adventure.patch | 12 +- .../api/0166-Fix-Spigot-annotation-mistakes.patch | 25 +- ...ethod-to-remove-all-active-potion-effects.patch | 26 + ...move-the-experimental-smithing-inventory-.patch | 39 - ...ethod-to-remove-all-active-potion-effects.patch | 26 - ...0398-Folia-scheduler-and-owned-region-API.patch | 790 + .../0399-Add-event-for-player-editing-sign.patch | 135 + ...0399-Folia-scheduler-and-owned-region-API.patch | 790 - .../api/0400-Add-Sign-getInteractableSideFor.patch | 45 + .../0400-Add-event-for-player-editing-sign.patch | 135 - .../api/0401-Add-Sign-getInteractableSideFor.patch | 45 - patches/api/0401-Fix-BanList-API.patch | 162 + patches/api/0402-Add-whitelist-events.patch | 99 + patches/api/0402-Fix-BanList-API.patch | 162 - .../0403-API-for-updating-recipes-on-clients.patch | 169 + patches/api/0403-Add-whitelist-events.patch | 99 - .../0404-API-for-updating-recipes-on-clients.patch | 169 - patches/api/0404-Add-PlayerFailMoveEvent.patch | 130 + patches/api/0405-Add-PlayerFailMoveEvent.patch | 130 - ...05-Fix-custom-statistic-criteria-creation.patch | 30 + ...06-Fix-custom-statistic-criteria-creation.patch | 30 - patches/api/0406-SculkCatalyst-bloom-API.patch | 25 + .../0407-API-for-an-entity-s-scoreboard-name.patch | 28 + patches/api/0407-SculkCatalyst-bloom-API.patch | 25 - .../0408-API-for-an-entity-s-scoreboard-name.patch | 28 - ...nd-replace-methods-with-old-StructureType.patch | 159 + patches/api/0409-Add-Listing-API-for-Player.patch | 43 + ...nd-replace-methods-with-old-StructureType.patch | 159 - patches/api/0410-Add-Listing-API-for-Player.patch | 43 - ...clicked-BlockFace-during-BlockDamageEvent.patch | 52 + ...clicked-BlockFace-during-BlockDamageEvent.patch | 52 - patches/api/0411-Fix-NPE-on-Boat-getStatus.patch | 18 + patches/api/0412-Expand-Pose-API.patch | 53 + patches/api/0412-Fix-NPE-on-Boat-getStatus.patch | 18 - patches/api/0413-Expand-Pose-API.patch | 53 - .../0413-MerchantRecipe-add-copy-constructor.patch | 24 + .../0414-MerchantRecipe-add-copy-constructor.patch | 24 - patches/api/0414-More-DragonBattle-API.patch | 55 + patches/api/0415-Add-PlayerPickItemEvent.patch | 108 + patches/api/0415-More-DragonBattle-API.patch | 55 - patches/api/0416-Add-PlayerPickItemEvent.patch | 108 - patches/api/0416-Allow-trident-custom-damage.patch | 34 + patches/api/0417-Allow-trident-custom-damage.patch | 34 - ...417-Expose-hand-during-BlockCanBuildEvent.patch | 54 + ...418-Expose-hand-during-BlockCanBuildEvent.patch | 54 - ...8-Limit-setBurnTime-to-valid-short-values.patch | 21 + .../api/0419-Add-OfflinePlayer-isConnected.patch | 38 + ...9-Limit-setBurnTime-to-valid-short-values.patch | 21 - .../api/0420-Add-OfflinePlayer-isConnected.patch | 38 - ...0-Add-titleOverride-to-InventoryOpenEvent.patch | 52 + ...1-Add-titleOverride-to-InventoryOpenEvent.patch | 52 - ...llow-proper-checking-of-empty-item-stacks.patch | 36 + ...llow-proper-checking-of-empty-item-stacks.patch | 36 - ...wapHandItemsEvent-throwing-exception-when.patch | 47 + .../api/0423-Add-player-idle-duration-API.patch | 41 + ...wapHandItemsEvent-throwing-exception-when.patch | 47 - ...get-the-collision-shape-of-a-block-before.patch | 31 + .../api/0424-Add-player-idle-duration-API.patch | 41 - ...get-the-collision-shape-of-a-block-before.patch | 31 - ...-Add-predicate-for-blocks-when-raytracing.patch | 116 + ...to-fish-event-for-all-player-interactions.patch | 22 + ...-Add-predicate-for-blocks-when-raytracing.patch | 116 - .../api/0427-Add-UUID-attribute-modifier-API.patch | 93 + ...to-fish-event-for-all-player-interactions.patch | 22 - .../api/0428-Add-UUID-attribute-modifier-API.patch | 93 - patches/api/0428-Expand-LingeringPotion-API.patch | 45 + patches/api/0429-Expand-LingeringPotion-API.patch | 45 - ...cessary-durability-check-in-ItemStack-isS.patch | 23 + patches/api/0430-Add-Structure-check-API.patch | 41 + ...cessary-durability-check-in-ItemStack-isS.patch | 23 - patches/api/0431-Add-Structure-check-API.patch | 41 - ...0431-add-missing-Experimental-annotations.patch | 112 + patches/api/0432-Add-more-scoreboard-API.patch | 90 + ...0432-add-missing-Experimental-annotations.patch | 112 - patches/api/0433-Add-more-scoreboard-API.patch | 90 - patches/api/0433-Improve-Registry.patch | 173 + patches/api/0434-Add-experience-points-API.patch | 56 + patches/api/0434-Improve-Registry.patch | 173 - patches/api/0435-Add-experience-points-API.patch | 56 - patches/api/0435-Add-missing-InventoryType.patch | 24 + patches/api/0436-Add-drops-to-shear-events.patch | 103 + patches/api/0436-Add-missing-InventoryType.patch | 24 - patches/api/0437-Add-HiddenPotionEffect-API.patch | 170 + patches/api/0437-Add-drops-to-shear-events.patch | 103 - patches/api/0438-Add-HiddenPotionEffect-API.patch | 170 - .../api/0438-Add-PlayerShieldDisableEvent.patch | 115 + .../api/0439-Add-PlayerShieldDisableEvent.patch | 115 - ...-for-empty-String-in-NamespacedKey.fromSt.patch | 60 + .../0440-Add-BlockStateMeta-clearBlockState.patch | 24 + ...-for-empty-String-in-NamespacedKey.fromSt.patch | 60 - .../0441-Add-BlockStateMeta-clearBlockState.patch | 24 - .../0441-Expose-LootTable-of-DecoratedPot.patch | 19 + patches/api/0442-Add-ShulkerDuplicateEvent.patch | 83 + .../0442-Expose-LootTable-of-DecoratedPot.patch | 19 - patches/api/0443-Add-ShulkerDuplicateEvent.patch | 83 - ...0443-Add-api-for-spawn-egg-texture-colors.patch | 28 + patches/api/0444-Add-Lifecycle-Event-system.patch | 628 + ...0444-Add-api-for-spawn-egg-texture-colors.patch | 28 - patches/api/0445-Add-Lifecycle-Event-system.patch | 628 - patches/api/0445-ItemStack-Tooltip-API.patch | 146 + ...tChunkSnapshot-includeLightData-parameter.patch | 34 + patches/api/0446-ItemStack-Tooltip-API.patch | 146 - patches/api/0447-Add-FluidState-API.patch | 164 + ...tChunkSnapshot-includeLightData-parameter.patch | 34 - patches/api/0448-Add-FluidState-API.patch | 164 - patches/api/0448-add-number-format-api.patch | 229 + patches/api/0449-add-number-format-api.patch | 229 - patches/api/0449-improve-BanList-types.patch | 131 + patches/api/0450-Suspicious-Effect-Entry-API.patch | 216 + patches/api/0450-improve-BanList-types.patch | 131 - patches/api/0451-Fix-DamageSource-API.patch | 31 + patches/api/0451-Suspicious-Effect-Entry-API.patch | 216 - patches/api/0452-Expanded-Hopper-API.patch | 32 + patches/api/0452-Fix-DamageSource-API.patch | 31 - ...one-mutables-to-prevent-unexpected-issues.patch | 151 + patches/api/0453-Expanded-Hopper-API.patch | 32 - .../0454-Add-BlockBreakProgressUpdateEvent.patch | 68 + ...one-mutables-to-prevent-unexpected-issues.patch | 151 - .../0455-Add-BlockBreakProgressUpdateEvent.patch | 68 - patches/api/0455-Deprecate-ItemStack-setType.patch | 54 + patches/api/0456-Deprecate-ItemStack-setType.patch | 54 - patches/api/0456-Item-Mutation-Fixes.patch | 50 + .../api/0457-API-for-checking-sent-chunks.patch | 58 + patches/api/0457-Item-Mutation-Fixes.patch | 50 - .../api/0458-API-for-checking-sent-chunks.patch | 58 - patches/api/0458-Add-CartographyItemEvent.patch | 44 + patches/api/0459-Add-CartographyItemEvent.patch | 44 - patches/api/0459-More-Raid-API.patch | 62 + .../api/0460-Fix-SpawnerEntry-Equipment-API.patch | 46 + patches/api/0460-More-Raid-API.patch | 62 - patches/api/0461-Fix-ItemFlags.patch | 66 + .../api/0461-Fix-SpawnerEntry-Equipment-API.patch | 46 - ...ow-modifying-library-loader-jars-bytecode.patch | 34 + patches/api/0462-Fix-ItemFlags.patch | 66 - .../api/0463-Add-hook-to-remap-library-jars.patch | 38 + ...ow-modifying-library-loader-jars-bytecode.patch | 34 - patches/api/0464-Add-GameMode-isInvulnerable.patch | 27 + .../api/0464-Add-hook-to-remap-library-jars.patch | 38 - patches/api/0465-Add-GameMode-isInvulnerable.patch | 27 - .../0465-Expose-hasColor-to-leather-armor.patch | 24 + .../0466-Add-missing-wind-charge-damage-type.patch | 34 + .../0466-Expose-hasColor-to-leather-armor.patch | 24 - .../0467-Add-missing-wind-charge-damage-type.patch | 34 - ...-Added-API-to-get-player-ha-proxy-address.patch | 27 + ...-Added-API-to-get-player-ha-proxy-address.patch | 27 - patches/api/0468-More-Chest-Block-API.patch | 44 + patches/api/0469-Brigadier-based-command-API.patch | 1989 ++ patches/api/0469-More-Chest-Block-API.patch | 44 - patches/api/0470-Brigadier-based-command-API.patch | 1989 -- patches/api/0470-Fix-issues-with-recipe-API.patch | 383 + .../0471-Fix-equipment-slot-and-group-API.patch | 76 + patches/api/0471-Fix-issues-with-recipe-API.patch | 383 - ...kkit-plugin-to-use-Paper-PluginLoader-API.patch | 91 + .../0472-Fix-equipment-slot-and-group-API.patch | 76 - ...kkit-plugin-to-use-Paper-PluginLoader-API.patch | 91 - patches/api/0473-General-ItemMeta-fixes.patch | 21 + .../api/0474-Add-missing-fishing-event-state.patch | 24 + patches/api/0474-General-ItemMeta-fixes.patch | 21 - .../api/0475-Add-missing-fishing-event-state.patch | 24 - ...Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch | 20 + ...Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch | 20 - patches/api/0476-WIP-Tag-API.patch | 62 + patches/api/0477-WIP-Tag-API.patch | 62 - patches/server/0010-Adventure.patch | 8 +- .../server/0021-Hook-into-CB-plugin-rewrites.patch | 16 +- ...flection-calls-in-plugins-using-internals.patch | 6 +- patches/server/0023-Timings-v2.patch | 2 +- .../0056-Improve-Player-chat-API-handling.patch | 2 +- .../0084-Add-PlayerUseUnknownEntityEvent.patch | 2 +- ...107-Configurable-packet-in-spam-threshold.patch | 2 +- .../0108-Configurable-flying-kick-messages.patch | 2 +- ...to-make-parrots-stay-on-shoulders-despite.patch | 2 +- patches/server/0152-Add-PlayerJumpEvent.patch | 2 +- patches/server/0162-AsyncTabCompleteEvent.patch | 2 +- .../server/0177-Player.setPlayerProfile-API.patch | 6 +- .../0209-InventoryCloseEvent-Reason-API.patch | 2 +- ...yer-inventory-when-cancelling-PlayerInter.patch | 2 +- ...-up-and-make-tab-spam-limits-configurable.patch | 2 +- ...to-prevent-players-from-moving-into-unloa.patch | 2 +- ...65-Restore-custom-InventoryHolder-support.patch | 4 +- ...-Don-t-allow-digging-into-unloaded-chunks.patch | 2 +- patches/server/0271-Book-Size-Limits.patch | 2 +- patches/server/0278-Brigadier-Mojang-API.patch | 2 +- .../0280-Limit-Client-Sign-length-more.patch | 2 +- ...date-PickItem-Packet-and-kick-for-invalid.patch | 2 +- .../0355-Prevent-teleporting-dead-entities.patch | 2 +- ...revent-position-desync-causing-tp-exploit.patch | 2 +- .../0372-Add-PlayerRecipeBookClickEvent.patch | 2 +- .../0374-Add-permission-for-command-blocks.patch | 2 +- ...r-World-Difficulty-Remembering-Difficulty.patch | 2 +- ...382-Do-not-accept-invalid-client-settings.patch | 2 +- ...Teleportation-and-cancel-velocity-if-tele.patch | 2 +- ...ix-for-large-move-vectors-crashing-server.patch | 2 +- patches/server/0445-Limit-recipe-packets.patch | 2 +- ...interact-event-not-being-called-sometimes.patch | 6 +- ...Allow-using-signs-inside-spawn-protection.patch | 2 +- ...on-t-ignore-result-of-PlayerEditBookEvent.patch | 2 +- ...0519-fix-PlayerItemHeldEvent-firing-twice.patch | 2 +- .../0536-Expand-PlayerGameModeChangeEvent.patch | 2 +- ...539-Move-range-check-for-block-placing-up.patch | 2 +- .../0542-Add-Unix-domain-socket-support.patch | 2 +- .../server/0548-Add-PlayerKickEvent-causes.patch | 2 +- patches/server/0566-Add-PlayerArmSwingEvent.patch | 2 +- ...x-kick-event-leave-message-not-being-sent.patch | 2 +- ...event-AFK-kick-while-watching-end-credits.patch | 2 +- patches/server/0591-Add-more-advancement-API.patch | 4 +- .../0592-Add-ItemFactory-getSpawnEgg-API.patch | 4 +- .../0602-Improve-and-expand-AsyncCatcher.patch | 2 +- ...nd-to-ServerboundCommandSuggestionPacket-.patch | 2 +- ...-vehicle-movement-from-players-while-tele.patch | 2 +- ...Prevent-tile-entity-copies-loading-chunks.patch | 2 +- ...Config-not-using-commands.spam-exclusions.patch | 2 +- patches/server/0726-More-Teleport-API.patch | 2 +- ...d-block-entities-after-destroy-prediction.patch | 2 +- ...fects-of-WorldCreator-keepSpawnLoaded-ret.patch | 4 +- .../server/0788-Improve-logging-and-errors.patch | 2 +- ...dd-missing-SpigotConfig-logCommands-check.patch | 2 +- ...-single-player-info-update-packet-on-join.patch | 2 +- ...t-sequence-violations-like-they-should-be.patch | 2 +- ...sing-expired-keys-from-impacting-new-join.patch | 2 +- .../0850-Implement-PlayerFailMoveEvent.patch | 2 +- ...omplete-namespaced-commands-if-send-names.patch | 2 +- patches/server/0876-Add-PlayerPickItemEvent.patch | 2 +- ...dd-slot-sanity-checks-in-container-clicks.patch | 2 +- patches/server/0943-Add-CartographyItemEvent.patch | 2 +- patches/server/0950-Fix-DamageSource-API.patch | 4 +- .../server/0953-Improve-tag-parser-handling.patch | 2 +- .../server/0975-Brigadier-based-command-API.patch | 2 +- ...ding-oversized-item-data-in-equipment-and.patch | 2 +- ...Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch | 2 +- ...0990-Chunk-System-Starlight-from-Moonrise.patch | 28744 ------------------ ...move-the-experimental-smithing-inventory-.patch | 26 + ...0991-Chunk-System-Starlight-from-Moonrise.patch | 28744 ++++++++++++++++++ .../server/0991-Rewrite-dataconverter-system.patch | 29411 ------------------- .../server/0992-Rewrite-dataconverter-system.patch | 29411 +++++++++++++++++++ .../0992-disable-forced-empty-world-ticks.patch | 19 - ...InWorldBounds-and-getBlockState-for-inlin.patch | 99 - .../0993-disable-forced-empty-world-ticks.patch | 19 + ...s-in-item-frames-performance-and-bug-fixe.patch | 128 - ...InWorldBounds-and-getBlockState-for-inlin.patch | 99 + ...s-in-item-frames-performance-and-bug-fixe.patch | 128 + ...aytracing-for-EntityLiving-hasLineOfSight.patch | 158 - ...twork-Manager-and-add-advanced-packet-sup.patch | 395 - ...aytracing-for-EntityLiving-hasLineOfSight.patch | 158 + .../0997-Allow-Saving-of-Oversized-Chunks.patch | 204 - ...twork-Manager-and-add-advanced-packet-sup.patch | 395 + .../0998-Allow-Saving-of-Oversized-Chunks.patch | 204 + .../0998-Flat-bedrock-generator-settings.patch | 292 - .../server/0999-Entity-Activation-Range-2.0.patch | 812 - .../0999-Flat-bedrock-generator-settings.patch | 292 + .../server/1000-Entity-Activation-Range-2.0.patch | 812 + .../1000-Optional-per-player-mob-spawns.patch | 253 - patches/server/1001-Anti-Xray.patch | 1639 -- .../1001-Optional-per-player-mob-spawns.patch | 253 + patches/server/1002-Anti-Xray.patch | 1639 ++ .../1002-Eigencraft-redstone-implementation.patch | 1145 - ...Alternate-Current-redstone-implementation.patch | 2114 -- .../1003-Eigencraft-redstone-implementation.patch | 1145 + ...Alternate-Current-redstone-implementation.patch | 2114 ++ ...celling-PreCreatureSpawnEvent-with-per-pl.patch | 89 - ...celling-PreCreatureSpawnEvent-with-per-pl.patch | 89 + ...e-Velocity-compression-and-cipher-natives.patch | 375 - ...ize-GoalSelector-Goal.Flag-Set-operations.patch | 160 - ...e-Velocity-compression-and-cipher-natives.patch | 375 + ...ize-GoalSelector-Goal.Flag-Set-operations.patch | 160 + patches/server/1007-Optimize-Hoppers.patch | 644 - .../1008-Entity-load-save-limit-per-chunk.patch | 81 - patches/server/1008-Optimize-Hoppers.patch | 644 + .../1009-Entity-load-save-limit-per-chunk.patch | 81 + .../server/1009-Optimize-Voxel-Shape-Merging.patch | 123 - .../1010-Optimize-Bit-Operations-by-inlining.patch | 213 - .../server/1010-Optimize-Voxel-Shape-Merging.patch | 123 + .../1011-Optimize-Bit-Operations-by-inlining.patch | 213 + .../server/1011-Remove-streams-from-hot-code.patch | 215 - ...thfinder-Remove-Streams-Optimized-collect.patch | 133 - .../server/1012-Remove-streams-from-hot-code.patch | 215 + ...e-implementation-for-blockstate-state-loo.patch | 343 - ...thfinder-Remove-Streams-Optimized-collect.patch | 133 + ...e-implementation-for-blockstate-state-loo.patch | 343 + ...entity-type-tags-suggestions-in-selectors.patch | 156 - ...entity-type-tags-suggestions-in-selectors.patch | 156 + ...Handle-Oversized-block-entities-in-chunks.patch | 64 - .../server/1016-API-for-checking-sent-chunks.patch | 61 - ...Handle-Oversized-block-entities-in-chunks.patch | 64 + .../server/1017-API-for-checking-sent-chunks.patch | 61 + patches/server/1017-Configurable-Sand-Duping.patch | 19 - patches/server/1018-Configurable-Sand-Duping.patch | 19 + patches/server/1018-Properly-resend-entities.patch | 232 - patches/server/1020-Properly-resend-entities.patch | 232 + work/Bukkit | 2 +- work/CraftBukkit | 2 +- 291 files changed, 77468 insertions(+), 77468 deletions(-) create mode 100644 patches/api/0397-Add-method-to-remove-all-active-potion-effects.patch delete mode 100644 patches/api/0397-Properly-remove-the-experimental-smithing-inventory-.patch delete mode 100644 patches/api/0398-Add-method-to-remove-all-active-potion-effects.patch create mode 100644 patches/api/0398-Folia-scheduler-and-owned-region-API.patch create mode 100644 patches/api/0399-Add-event-for-player-editing-sign.patch delete mode 100644 patches/api/0399-Folia-scheduler-and-owned-region-API.patch create mode 100644 patches/api/0400-Add-Sign-getInteractableSideFor.patch delete mode 100644 patches/api/0400-Add-event-for-player-editing-sign.patch delete mode 100644 patches/api/0401-Add-Sign-getInteractableSideFor.patch create mode 100644 patches/api/0401-Fix-BanList-API.patch create mode 100644 patches/api/0402-Add-whitelist-events.patch delete mode 100644 patches/api/0402-Fix-BanList-API.patch create mode 100644 patches/api/0403-API-for-updating-recipes-on-clients.patch delete mode 100644 patches/api/0403-Add-whitelist-events.patch delete mode 100644 patches/api/0404-API-for-updating-recipes-on-clients.patch create mode 100644 patches/api/0404-Add-PlayerFailMoveEvent.patch delete mode 100644 patches/api/0405-Add-PlayerFailMoveEvent.patch create mode 100644 patches/api/0405-Fix-custom-statistic-criteria-creation.patch delete mode 100644 patches/api/0406-Fix-custom-statistic-criteria-creation.patch create mode 100644 patches/api/0406-SculkCatalyst-bloom-API.patch create mode 100644 patches/api/0407-API-for-an-entity-s-scoreboard-name.patch delete mode 100644 patches/api/0407-SculkCatalyst-bloom-API.patch delete mode 100644 patches/api/0408-API-for-an-entity-s-scoreboard-name.patch create mode 100644 patches/api/0408-Deprecate-and-replace-methods-with-old-StructureType.patch create mode 100644 patches/api/0409-Add-Listing-API-for-Player.patch delete mode 100644 patches/api/0409-Deprecate-and-replace-methods-with-old-StructureType.patch delete mode 100644 patches/api/0410-Add-Listing-API-for-Player.patch create mode 100644 patches/api/0410-Expose-clicked-BlockFace-during-BlockDamageEvent.patch delete mode 100644 patches/api/0411-Expose-clicked-BlockFace-during-BlockDamageEvent.patch create mode 100644 patches/api/0411-Fix-NPE-on-Boat-getStatus.patch create mode 100644 patches/api/0412-Expand-Pose-API.patch delete mode 100644 patches/api/0412-Fix-NPE-on-Boat-getStatus.patch delete mode 100644 patches/api/0413-Expand-Pose-API.patch create mode 100644 patches/api/0413-MerchantRecipe-add-copy-constructor.patch delete mode 100644 patches/api/0414-MerchantRecipe-add-copy-constructor.patch create mode 100644 patches/api/0414-More-DragonBattle-API.patch create mode 100644 patches/api/0415-Add-PlayerPickItemEvent.patch delete mode 100644 patches/api/0415-More-DragonBattle-API.patch delete mode 100644 patches/api/0416-Add-PlayerPickItemEvent.patch create mode 100644 patches/api/0416-Allow-trident-custom-damage.patch delete mode 100644 patches/api/0417-Allow-trident-custom-damage.patch create mode 100644 patches/api/0417-Expose-hand-during-BlockCanBuildEvent.patch delete mode 100644 patches/api/0418-Expose-hand-during-BlockCanBuildEvent.patch create mode 100644 patches/api/0418-Limit-setBurnTime-to-valid-short-values.patch create mode 100644 patches/api/0419-Add-OfflinePlayer-isConnected.patch delete mode 100644 patches/api/0419-Limit-setBurnTime-to-valid-short-values.patch delete mode 100644 patches/api/0420-Add-OfflinePlayer-isConnected.patch create mode 100644 patches/api/0420-Add-titleOverride-to-InventoryOpenEvent.patch delete mode 100644 patches/api/0421-Add-titleOverride-to-InventoryOpenEvent.patch create mode 100644 patches/api/0421-Allow-proper-checking-of-empty-item-stacks.patch delete mode 100644 patches/api/0422-Allow-proper-checking-of-empty-item-stacks.patch create mode 100644 patches/api/0422-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch create mode 100644 patches/api/0423-Add-player-idle-duration-API.patch delete mode 100644 patches/api/0423-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch create mode 100644 patches/api/0424-Add-API-to-get-the-collision-shape-of-a-block-before.patch delete mode 100644 patches/api/0424-Add-player-idle-duration-API.patch delete mode 100644 patches/api/0425-Add-API-to-get-the-collision-shape-of-a-block-before.patch create mode 100644 patches/api/0425-Add-predicate-for-blocks-when-raytracing.patch create mode 100644 patches/api/0426-Add-hand-to-fish-event-for-all-player-interactions.patch delete mode 100644 patches/api/0426-Add-predicate-for-blocks-when-raytracing.patch create mode 100644 patches/api/0427-Add-UUID-attribute-modifier-API.patch delete mode 100644 patches/api/0427-Add-hand-to-fish-event-for-all-player-interactions.patch delete mode 100644 patches/api/0428-Add-UUID-attribute-modifier-API.patch create mode 100644 patches/api/0428-Expand-LingeringPotion-API.patch delete mode 100644 patches/api/0429-Expand-LingeringPotion-API.patch create mode 100644 patches/api/0429-Remove-unnecessary-durability-check-in-ItemStack-isS.patch create mode 100644 patches/api/0430-Add-Structure-check-API.patch delete mode 100644 patches/api/0430-Remove-unnecessary-durability-check-in-ItemStack-isS.patch delete mode 100644 patches/api/0431-Add-Structure-check-API.patch create mode 100644 patches/api/0431-add-missing-Experimental-annotations.patch create mode 100644 patches/api/0432-Add-more-scoreboard-API.patch delete mode 100644 patches/api/0432-add-missing-Experimental-annotations.patch delete mode 100644 patches/api/0433-Add-more-scoreboard-API.patch create mode 100644 patches/api/0433-Improve-Registry.patch create mode 100644 patches/api/0434-Add-experience-points-API.patch delete mode 100644 patches/api/0434-Improve-Registry.patch delete mode 100644 patches/api/0435-Add-experience-points-API.patch create mode 100644 patches/api/0435-Add-missing-InventoryType.patch create mode 100644 patches/api/0436-Add-drops-to-shear-events.patch delete mode 100644 patches/api/0436-Add-missing-InventoryType.patch create mode 100644 patches/api/0437-Add-HiddenPotionEffect-API.patch delete mode 100644 patches/api/0437-Add-drops-to-shear-events.patch delete mode 100644 patches/api/0438-Add-HiddenPotionEffect-API.patch create mode 100644 patches/api/0438-Add-PlayerShieldDisableEvent.patch delete mode 100644 patches/api/0439-Add-PlayerShieldDisableEvent.patch create mode 100644 patches/api/0439-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch create mode 100644 patches/api/0440-Add-BlockStateMeta-clearBlockState.patch delete mode 100644 patches/api/0440-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch delete mode 100644 patches/api/0441-Add-BlockStateMeta-clearBlockState.patch create mode 100644 patches/api/0441-Expose-LootTable-of-DecoratedPot.patch create mode 100644 patches/api/0442-Add-ShulkerDuplicateEvent.patch delete mode 100644 patches/api/0442-Expose-LootTable-of-DecoratedPot.patch delete mode 100644 patches/api/0443-Add-ShulkerDuplicateEvent.patch create mode 100644 patches/api/0443-Add-api-for-spawn-egg-texture-colors.patch create mode 100644 patches/api/0444-Add-Lifecycle-Event-system.patch delete mode 100644 patches/api/0444-Add-api-for-spawn-egg-texture-colors.patch delete mode 100644 patches/api/0445-Add-Lifecycle-Event-system.patch create mode 100644 patches/api/0445-ItemStack-Tooltip-API.patch create mode 100644 patches/api/0446-Add-getChunkSnapshot-includeLightData-parameter.patch delete mode 100644 patches/api/0446-ItemStack-Tooltip-API.patch create mode 100644 patches/api/0447-Add-FluidState-API.patch delete mode 100644 patches/api/0447-Add-getChunkSnapshot-includeLightData-parameter.patch delete mode 100644 patches/api/0448-Add-FluidState-API.patch create mode 100644 patches/api/0448-add-number-format-api.patch delete mode 100644 patches/api/0449-add-number-format-api.patch create mode 100644 patches/api/0449-improve-BanList-types.patch create mode 100644 patches/api/0450-Suspicious-Effect-Entry-API.patch delete mode 100644 patches/api/0450-improve-BanList-types.patch create mode 100644 patches/api/0451-Fix-DamageSource-API.patch delete mode 100644 patches/api/0451-Suspicious-Effect-Entry-API.patch create mode 100644 patches/api/0452-Expanded-Hopper-API.patch delete mode 100644 patches/api/0452-Fix-DamageSource-API.patch create mode 100644 patches/api/0453-Clone-mutables-to-prevent-unexpected-issues.patch delete mode 100644 patches/api/0453-Expanded-Hopper-API.patch create mode 100644 patches/api/0454-Add-BlockBreakProgressUpdateEvent.patch delete mode 100644 patches/api/0454-Clone-mutables-to-prevent-unexpected-issues.patch delete mode 100644 patches/api/0455-Add-BlockBreakProgressUpdateEvent.patch create mode 100644 patches/api/0455-Deprecate-ItemStack-setType.patch delete mode 100644 patches/api/0456-Deprecate-ItemStack-setType.patch create mode 100644 patches/api/0456-Item-Mutation-Fixes.patch create mode 100644 patches/api/0457-API-for-checking-sent-chunks.patch delete mode 100644 patches/api/0457-Item-Mutation-Fixes.patch delete mode 100644 patches/api/0458-API-for-checking-sent-chunks.patch create mode 100644 patches/api/0458-Add-CartographyItemEvent.patch delete mode 100644 patches/api/0459-Add-CartographyItemEvent.patch create mode 100644 patches/api/0459-More-Raid-API.patch create mode 100644 patches/api/0460-Fix-SpawnerEntry-Equipment-API.patch delete mode 100644 patches/api/0460-More-Raid-API.patch create mode 100644 patches/api/0461-Fix-ItemFlags.patch delete mode 100644 patches/api/0461-Fix-SpawnerEntry-Equipment-API.patch create mode 100644 patches/api/0462-Allow-modifying-library-loader-jars-bytecode.patch delete mode 100644 patches/api/0462-Fix-ItemFlags.patch create mode 100644 patches/api/0463-Add-hook-to-remap-library-jars.patch delete mode 100644 patches/api/0463-Allow-modifying-library-loader-jars-bytecode.patch create mode 100644 patches/api/0464-Add-GameMode-isInvulnerable.patch delete mode 100644 patches/api/0464-Add-hook-to-remap-library-jars.patch delete mode 100644 patches/api/0465-Add-GameMode-isInvulnerable.patch create mode 100644 patches/api/0465-Expose-hasColor-to-leather-armor.patch create mode 100644 patches/api/0466-Add-missing-wind-charge-damage-type.patch delete mode 100644 patches/api/0466-Expose-hasColor-to-leather-armor.patch delete mode 100644 patches/api/0467-Add-missing-wind-charge-damage-type.patch create mode 100644 patches/api/0467-Added-API-to-get-player-ha-proxy-address.patch delete mode 100644 patches/api/0468-Added-API-to-get-player-ha-proxy-address.patch create mode 100644 patches/api/0468-More-Chest-Block-API.patch create mode 100644 patches/api/0469-Brigadier-based-command-API.patch delete mode 100644 patches/api/0469-More-Chest-Block-API.patch delete mode 100644 patches/api/0470-Brigadier-based-command-API.patch create mode 100644 patches/api/0470-Fix-issues-with-recipe-API.patch create mode 100644 patches/api/0471-Fix-equipment-slot-and-group-API.patch delete mode 100644 patches/api/0471-Fix-issues-with-recipe-API.patch create mode 100644 patches/api/0472-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch delete mode 100644 patches/api/0472-Fix-equipment-slot-and-group-API.patch delete mode 100644 patches/api/0473-Allow-Bukkit-plugin-to-use-Paper-PluginLoader-API.patch create mode 100644 patches/api/0473-General-ItemMeta-fixes.patch create mode 100644 patches/api/0474-Add-missing-fishing-event-state.patch delete mode 100644 patches/api/0474-General-ItemMeta-fixes.patch delete mode 100644 patches/api/0475-Add-missing-fishing-event-state.patch create mode 100644 patches/api/0475-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch delete mode 100644 patches/api/0476-Deprecate-InvAction-HOTBAR_MOVE_AND_READD.patch create mode 100644 patches/api/0476-WIP-Tag-API.patch delete mode 100644 patches/api/0477-WIP-Tag-API.patch delete mode 100644 patches/server/0990-Chunk-System-Starlight-from-Moonrise.patch create mode 100644 patches/server/0990-Properly-remove-the-experimental-smithing-inventory-.patch create mode 100644 patches/server/0991-Chunk-System-Starlight-from-Moonrise.patch delete mode 100644 patches/server/0991-Rewrite-dataconverter-system.patch create mode 100644 patches/server/0992-Rewrite-dataconverter-system.patch delete mode 100644 patches/server/0992-disable-forced-empty-world-ticks.patch delete mode 100644 patches/server/0993-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch create mode 100644 patches/server/0993-disable-forced-empty-world-ticks.patch delete mode 100644 patches/server/0994-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch create mode 100644 patches/server/0994-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch create mode 100644 patches/server/0995-Improve-Maps-in-item-frames-performance-and-bug-fixe.patch delete mode 100644 patches/server/0995-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch delete mode 100644 patches/server/0996-Optimize-Network-Manager-and-add-advanced-packet-sup.patch create mode 100644 patches/server/0996-Strip-raytracing-for-EntityLiving-hasLineOfSight.patch delete mode 100644 patches/server/0997-Allow-Saving-of-Oversized-Chunks.patch create mode 100644 patches/server/0997-Optimize-Network-Manager-and-add-advanced-packet-sup.patch create mode 100644 patches/server/0998-Allow-Saving-of-Oversized-Chunks.patch delete mode 100644 patches/server/0998-Flat-bedrock-generator-settings.patch delete mode 100644 patches/server/0999-Entity-Activation-Range-2.0.patch create mode 100644 patches/server/0999-Flat-bedrock-generator-settings.patch create mode 100644 patches/server/1000-Entity-Activation-Range-2.0.patch delete mode 100644 patches/server/1000-Optional-per-player-mob-spawns.patch delete mode 100644 patches/server/1001-Anti-Xray.patch create mode 100644 patches/server/1001-Optional-per-player-mob-spawns.patch create mode 100644 patches/server/1002-Anti-Xray.patch delete mode 100644 patches/server/1002-Eigencraft-redstone-implementation.patch delete mode 100644 patches/server/1003-Add-Alternate-Current-redstone-implementation.patch create mode 100644 patches/server/1003-Eigencraft-redstone-implementation.patch create mode 100644 patches/server/1004-Add-Alternate-Current-redstone-implementation.patch delete mode 100644 patches/server/1004-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch create mode 100644 patches/server/1005-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch delete mode 100644 patches/server/1005-Use-Velocity-compression-and-cipher-natives.patch delete mode 100644 patches/server/1006-Optimize-GoalSelector-Goal.Flag-Set-operations.patch create mode 100644 patches/server/1006-Use-Velocity-compression-and-cipher-natives.patch create mode 100644 patches/server/1007-Optimize-GoalSelector-Goal.Flag-Set-operations.patch delete mode 100644 patches/server/1007-Optimize-Hoppers.patch delete mode 100644 patches/server/1008-Entity-load-save-limit-per-chunk.patch create mode 100644 patches/server/1008-Optimize-Hoppers.patch create mode 100644 patches/server/1009-Entity-load-save-limit-per-chunk.patch delete mode 100644 patches/server/1009-Optimize-Voxel-Shape-Merging.patch delete mode 100644 patches/server/1010-Optimize-Bit-Operations-by-inlining.patch create mode 100644 patches/server/1010-Optimize-Voxel-Shape-Merging.patch create mode 100644 patches/server/1011-Optimize-Bit-Operations-by-inlining.patch delete mode 100644 patches/server/1011-Remove-streams-from-hot-code.patch delete mode 100644 patches/server/1012-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch create mode 100644 patches/server/1012-Remove-streams-from-hot-code.patch delete mode 100644 patches/server/1013-Custom-table-implementation-for-blockstate-state-loo.patch create mode 100644 patches/server/1013-Optimize-Pathfinder-Remove-Streams-Optimized-collect.patch create mode 100644 patches/server/1014-Custom-table-implementation-for-blockstate-state-loo.patch delete mode 100644 patches/server/1014-Fix-entity-type-tags-suggestions-in-selectors.patch create mode 100644 patches/server/1015-Fix-entity-type-tags-suggestions-in-selectors.patch delete mode 100644 patches/server/1015-Handle-Oversized-block-entities-in-chunks.patch delete mode 100644 patches/server/1016-API-for-checking-sent-chunks.patch create mode 100644 patches/server/1016-Handle-Oversized-block-entities-in-chunks.patch create mode 100644 patches/server/1017-API-for-checking-sent-chunks.patch delete mode 100644 patches/server/1017-Configurable-Sand-Duping.patch create mode 100644 patches/server/1018-Configurable-Sand-Duping.patch delete mode 100644 patches/server/1018-Properly-resend-entities.patch create mode 100644 patches/server/1020-Properly-resend-entities.patch diff --git a/patches/api/0006-Adventure.patch b/patches/api/0006-Adventure.patch index 3826a48b3e..819337ce6b 100644 --- a/patches/api/0006-Adventure.patch +++ b/patches/api/0006-Adventure.patch @@ -4307,12 +4307,12 @@ index 5adbe0514129abf3cfbc4b29a213f522359fe2e1..72ebc29db42d08d1d0361dba462fc8a5 /** diff --git a/src/main/java/org/bukkit/inventory/InventoryView.java b/src/main/java/org/bukkit/inventory/InventoryView.java -index e12996492c1558fed9fab30de9f8018e0ed7fac3..002acfbdce1db10f7ba1b6a013e678f504ac6e69 100644 +index 6a8a9eb4d50e371b003f34c3b522c4939826f5dc..8423a1d4ef4a39bb1734b56f8a396d73b264ac9a 100644 --- a/src/main/java/org/bukkit/inventory/InventoryView.java +++ b/src/main/java/org/bukkit/inventory/InventoryView.java -@@ -447,12 +447,26 @@ public abstract class InventoryView { - return getPlayer().setWindowProperty(prop, value); - } +@@ -271,12 +271,26 @@ public interface InventoryView { + */ + public boolean setProperty(@NotNull Property prop, int value); + // Paper start /** @@ -4321,7 +4321,7 @@ index e12996492c1558fed9fab30de9f8018e0ed7fac3..002acfbdce1db10f7ba1b6a013e678f5 * @return The title. */ @NotNull -+ public /*abstract*/ net.kyori.adventure.text.Component title() { ++ default net.kyori.adventure.text.Component title() { + return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.getTitle()); + } + // Paper end @@ -4334,7 +4334,7 @@ index e12996492c1558fed9fab30de9f8018e0ed7fac3..002acfbdce1db10f7ba1b6a013e678f5 + */ + @Deprecated // Paper + @NotNull - public abstract String getTitle(); + public String getTitle(); /** diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java diff --git a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch index 02217b6f29..b2e2507384 100644 --- a/patches/api/0166-Fix-Spigot-annotation-mistakes.patch +++ b/patches/api/0166-Fix-Spigot-annotation-mistakes.patch @@ -1139,6 +1139,19 @@ index f2a2a2ad9930499c5bf624e73571a3294a90db14..c8540a42ab44647fdd112ce4f731f3dc public ItemStack getCursor() { return getView().getCursor(); } +diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java +index 32cd8ee2e849df602a7e10aa5d0a218007faa0ac..fbdbd2f4da5e09d4b111ddcf72e2d7dd59046bd7 100644 +--- a/src/main/java/org/bukkit/event/inventory/InventoryType.java ++++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java +@@ -153,7 +153,7 @@ public enum InventoryType { + * + * @deprecated use {@link #SMITHING} + */ +- @Deprecated ++ @Deprecated(forRemoval = true) // Paper + SMITHING_NEW(4, "Upgrade Gear"), + ; + diff --git a/src/main/java/org/bukkit/event/player/PlayerBedLeaveEvent.java b/src/main/java/org/bukkit/event/player/PlayerBedLeaveEvent.java index 1cb70b5c8776863f44f1c4cdde152c35cb51edb5..f09b378508fcc6299e7cb40f174028f6f88ba067 100644 --- a/src/main/java/org/bukkit/event/player/PlayerBedLeaveEvent.java @@ -1369,10 +1382,10 @@ index f1a48eab1a357ae64545e1f1dc941c383cff8707..466d1bd7089b76f48f953e1a51c611ec /** * Checks if the inventory contains any ItemStacks with the given diff --git a/src/main/java/org/bukkit/inventory/InventoryView.java b/src/main/java/org/bukkit/inventory/InventoryView.java -index 002acfbdce1db10f7ba1b6a013e678f504ac6e69..8d14426eb1ebea27058d5f22ea652f22d00fccb9 100644 +index 8423a1d4ef4a39bb1734b56f8a396d73b264ac9a..1e50dba6bb8753e6c1adff59ee0ff93adf3bfd4f 100644 --- a/src/main/java/org/bukkit/inventory/InventoryView.java +++ b/src/main/java/org/bukkit/inventory/InventoryView.java -@@ -126,9 +126,9 @@ public abstract class InventoryView { +@@ -125,9 +125,9 @@ public interface InventoryView { * Gets the id of this view. * * @return the id of this view @@ -1384,7 +1397,7 @@ index 002acfbdce1db10f7ba1b6a013e678f504ac6e69..8d14426eb1ebea27058d5f22ea652f22 public int getId() { return id; } -@@ -210,10 +210,10 @@ public abstract class InventoryView { +@@ -197,10 +197,10 @@ public interface InventoryView { /** * Get the item on the cursor of one of the viewing players. * @@ -1395,9 +1408,9 @@ index 002acfbdce1db10f7ba1b6a013e678f504ac6e69..8d14426eb1ebea27058d5f22ea652f22 */ - @Nullable + @NotNull // Paper - fix nullability - public final ItemStack getCursor() { - return getPlayer().getItemOnCursor(); - } + public ItemStack getCursor(); + + /** diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java index 3d08beee52f2247db6f6e679206ed6a965fbf9a8..1b4f9b93860e58762ac28715adad5a67298b06d7 100644 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java diff --git a/patches/api/0397-Add-method-to-remove-all-active-potion-effects.patch b/patches/api/0397-Add-method-to-remove-all-active-potion-effects.patch new file mode 100644 index 0000000000..2b9703cf94 --- /dev/null +++ b/patches/api/0397-Add-method-to-remove-all-active-potion-effects.patch @@ -0,0 +1,26 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 17 Jun 2023 13:17:20 -0700 +Subject: [PATCH] Add method to remove all active potion effects + + +diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java +index 4974540e8277011e4eb00f691a5f6f96d3dde20c..5de7651f673cba9782f88f46dc938274b37a38ec 100644 +--- a/src/main/java/org/bukkit/entity/LivingEntity.java ++++ b/src/main/java/org/bukkit/entity/LivingEntity.java +@@ -657,6 +657,15 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource + @NotNull + public Collection getActivePotionEffects(); + ++ // Paper start - LivingEntity#clearActivePotionEffects(); ++ /** ++ * Removes all active potion effects for this entity. ++ * ++ * @return true if any were removed ++ */ ++ boolean clearActivePotionEffects(); ++ // Paper end ++ + /** + * Checks whether the living entity has block line of sight to another. + *

diff --git a/patches/api/0397-Properly-remove-the-experimental-smithing-inventory-.patch b/patches/api/0397-Properly-remove-the-experimental-smithing-inventory-.patch deleted file mode 100644 index 6448068df8..0000000000 --- a/patches/api/0397-Properly-remove-the-experimental-smithing-inventory-.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Thu, 8 Jun 2023 14:45:30 -0700 -Subject: [PATCH] Properly remove the experimental smithing inventory type - - -diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java -index 32cd8ee2e849df602a7e10aa5d0a218007faa0ac..fbdbd2f4da5e09d4b111ddcf72e2d7dd59046bd7 100644 ---- a/src/main/java/org/bukkit/event/inventory/InventoryType.java -+++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java -@@ -153,7 +153,7 @@ public enum InventoryType { - * - * @deprecated use {@link #SMITHING} - */ -- @Deprecated -+ @Deprecated(forRemoval = true) // Paper - SMITHING_NEW(4, "Upgrade Gear"), - ; - -diff --git a/src/main/java/org/bukkit/inventory/InventoryView.java b/src/main/java/org/bukkit/inventory/InventoryView.java -index 8d14426eb1ebea27058d5f22ea652f22d00fccb9..ac6c5c7a58c2c88b6cb0f6632fb53e8d67f8a059 100644 ---- a/src/main/java/org/bukkit/inventory/InventoryView.java -+++ b/src/main/java/org/bukkit/inventory/InventoryView.java -@@ -370,7 +370,6 @@ public abstract class InventoryView { - type = InventoryType.SlotType.CRAFTING; - break; - case ANVIL: -- case SMITHING: - case CARTOGRAPHY: - case GRINDSTONE: - case MERCHANT: -@@ -388,6 +387,7 @@ public abstract class InventoryView { - } - break; - case LOOM: -+ case SMITHING: // Paper - case SMITHING_NEW: - if (slot == 3) { - type = InventoryType.SlotType.RESULT; diff --git a/patches/api/0398-Add-method-to-remove-all-active-potion-effects.patch b/patches/api/0398-Add-method-to-remove-all-active-potion-effects.patch deleted file mode 100644 index 2b9703cf94..0000000000 --- a/patches/api/0398-Add-method-to-remove-all-active-potion-effects.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 17 Jun 2023 13:17:20 -0700 -Subject: [PATCH] Add method to remove all active potion effects - - -diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 4974540e8277011e4eb00f691a5f6f96d3dde20c..5de7651f673cba9782f88f46dc938274b37a38ec 100644 ---- a/src/main/java/org/bukkit/entity/LivingEntity.java -+++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -657,6 +657,15 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource - @NotNull - public Collection getActivePotionEffects(); - -+ // Paper start - LivingEntity#clearActivePotionEffects(); -+ /** -+ * Removes all active potion effects for this entity. -+ * -+ * @return true if any were removed -+ */ -+ boolean clearActivePotionEffects(); -+ // Paper end -+ - /** - * Checks whether the living entity has block line of sight to another. - *

diff --git a/patches/api/0398-Folia-scheduler-and-owned-region-API.patch b/patches/api/0398-Folia-scheduler-and-owned-region-API.patch new file mode 100644 index 0000000000..35af43df05 --- /dev/null +++ b/patches/api/0398-Folia-scheduler-and-owned-region-API.patch @@ -0,0 +1,790 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Sat, 17 Jun 2023 11:52:41 +0200 +Subject: [PATCH] Folia scheduler and owned region API + +Pulling Folia API to Paper is primarily intended for plugins +that want to target both Paper and Folia without unnecessary +compatibility layers. + +Add both a location based scheduler, an entity based scheduler, +and a global region scheduler. + +Owned region API may be useful for plugins which want to perform +operations over large areas outside of the buffer zone provided +by the regionaliser, as it is not guaranteed that anything +outside of the buffer zone is owned. Then, the plugins may use +the schedulers depending on the result of the ownership check. + +diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d9cdd04660c5e60e494a8fed91ae437e6cb733ed +--- /dev/null ++++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java +@@ -0,0 +1,51 @@ ++package io.papermc.paper.threadedregions.scheduler; ++ ++import org.bukkit.plugin.Plugin; ++import org.jetbrains.annotations.NotNull; ++ ++import java.util.concurrent.TimeUnit; ++import java.util.function.Consumer; ++ ++/** ++ * Scheduler that may be used by plugins to schedule tasks to execute asynchronously from the server tick process. ++ */ ++public interface AsyncScheduler { ++ ++ /** ++ * Schedules the specified task to be executed asynchronously immediately. ++ * @param plugin Plugin which owns the specified task. ++ * @param task Specified task. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask runNow(@NotNull Plugin plugin, @NotNull Consumer task); ++ ++ /** ++ * Schedules the specified task to be executed asynchronously after the time delay has passed. ++ * @param plugin Plugin which owns the specified task. ++ * @param task Specified task. ++ * @param delay The time delay to pass before the task should be executed. ++ * @param unit The time unit for the time delay. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer task, long delay, ++ @NotNull TimeUnit unit); ++ ++ /** ++ * Schedules the specified task to be executed asynchronously after the initial delay has passed, ++ * and then periodically executed with the specified period. ++ * @param plugin Plugin which owns the specified task. ++ * @param task Specified task. ++ * @param initialDelay The time delay to pass before the first execution of the task. ++ * @param period The time between task executions after the first execution of the task. ++ * @param unit The time unit for the initial delay and period. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer task, ++ long initialDelay, long period, @NotNull TimeUnit unit); ++ ++ /** ++ * Attempts to cancel all tasks scheduled by the specified plugin. ++ * @param plugin Specified plugin. ++ */ ++ void cancelTasks(@NotNull Plugin plugin); ++} +diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9f69e189be8202a0ab1450540f5d12187ba6c987 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java +@@ -0,0 +1,104 @@ ++package io.papermc.paper.threadedregions.scheduler; ++ ++import org.bukkit.plugin.Plugin; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++import java.util.function.Consumer; ++ ++/** ++ * An entity can move between worlds with an arbitrary tick delay, be temporarily removed ++ * for players (i.e end credits), be partially removed from world state (i.e inactive but not removed), ++ * teleport between ticking regions, teleport between worlds, and even be removed entirely from the server. ++ * The uncertainty of an entity's state can make it difficult to schedule tasks without worrying about undefined ++ * behaviors resulting from any of the states listed previously. ++ * ++ *

++ * This class is designed to eliminate those states by providing an interface to run tasks only when an entity ++ * is contained in a world, on the owning thread for the region, and by providing the current Entity object. ++ * The scheduler also allows a task to provide a callback, the "retired" callback, that will be invoked ++ * if the entity is removed before a task that was scheduled could be executed. The scheduler is also ++ * completely thread-safe, allowing tasks to be scheduled from any thread context. The scheduler also indicates ++ * properly whether a task was scheduled successfully (i.e scheduler not retired), thus the code scheduling any task ++ * knows whether the given callbacks will be invoked eventually or not - which may be critical for off-thread ++ * contexts. ++ *

++ */ ++public interface EntityScheduler { ++ ++ /** ++ * Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity ++ * removed), then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay, ++ * or the retired callback will be invoked if the scheduler is retired. ++ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove ++ * other entities, load chunks, load worlds, modify ticket levels, etc. ++ * ++ *

++ * It is guaranteed that the run and retired callback are invoked on the region which owns the entity. ++ *

++ * @param run The callback to run after the specified delay, may not be null. ++ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. ++ * @param delay The delay in ticks before the run callback is invoked. Any value less-than 1 is treated as 1. ++ * @return {@code true} if the task was scheduled, which means that either the run function or the retired function ++ * will be invoked (but never both), or {@code false} indicating neither the run nor retired function will be invoked ++ * since the scheduler has been retired. ++ */ ++ boolean execute(@NotNull Plugin plugin, @NotNull Runnable run, @Nullable Runnable retired, long delay); ++ ++ /** ++ * Schedules a task to execute on the next tick. If the task failed to schedule because the scheduler is retired (entity ++ * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, ++ * or the retired callback will be invoked if the scheduler is retired. ++ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove ++ * other entities, load chunks, load worlds, modify ticket levels, etc. ++ * ++ *

++ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. ++ *

++ * @param plugin The plugin that owns the task ++ * @param task The task to execute ++ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. ++ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. ++ */ ++ @Nullable ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer task, ++ @Nullable Runnable retired); ++ ++ /** ++ * Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity ++ * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, ++ * or the retired callback will be invoked if the scheduler is retired. ++ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove ++ * other entities, load chunks, load worlds, modify ticket levels, etc. ++ * ++ *

++ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. ++ *

++ * @param plugin The plugin that owns the task ++ * @param task The task to execute ++ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. ++ * @param delayTicks The delay, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. ++ */ ++ @Nullable ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer task, ++ @Nullable Runnable retired, long delayTicks); ++ ++ /** ++ * Schedules a repeating task with the given delay and period. If the task failed to schedule because the scheduler ++ * is retired (entity removed), then returns {@code null}. Otherwise, either the task callback will be invoked after ++ * the specified delay, or the retired callback will be invoked if the scheduler is retired. ++ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove ++ * other entities, load chunks, load worlds, modify ticket levels, etc. ++ * ++ *

++ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. ++ *

++ * @param plugin The plugin that owns the task ++ * @param task The task to execute ++ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. ++ * @param initialDelayTicks The initial delay, in ticks. ++ * @param periodTicks The period, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. ++ */ ++ @Nullable ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer task, ++ @Nullable Runnable retired, long initialDelayTicks, long periodTicks); ++} +diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java +new file mode 100644 +index 0000000000000000000000000000000000000000..365b53fea8dee09cdc11f4399dea5f00c6ee70e2 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java +@@ -0,0 +1,58 @@ ++package io.papermc.paper.threadedregions.scheduler; ++ ++import org.bukkit.plugin.Plugin; ++import org.jetbrains.annotations.NotNull; ++ ++import java.util.function.Consumer; ++ ++/** ++ * The global region task scheduler may be used to schedule tasks that will execute on the global region. ++ *

++ * The global region is responsible for maintaining world day time, world game time, weather cycle, ++ * sleep night skipping, executing commands for console, and other misc. tasks that do not belong to any specific region. ++ *

++ */ ++public interface GlobalRegionScheduler { ++ ++ /** ++ * Schedules a task to be executed on the global region. ++ * @param plugin The plugin that owns the task ++ * @param run The task to execute ++ */ ++ void execute(@NotNull Plugin plugin, @NotNull Runnable run); ++ ++ /** ++ * Schedules a task to be executed on the global region on the next tick. ++ * @param plugin The plugin that owns the task ++ * @param task The task to execute ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer task); ++ ++ /** ++ * Schedules a task to be executed on the global region after the specified delay in ticks. ++ * @param plugin The plugin that owns the task ++ * @param task The task to execute ++ * @param delayTicks The delay, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer task, long delayTicks); ++ ++ /** ++ * Schedules a repeating task to be executed on the global region after the initial delay with the ++ * specified period. ++ * @param plugin The plugin that owns the task ++ * @param task The task to execute ++ * @param initialDelayTicks The initial delay, in ticks. ++ * @param periodTicks The period, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer task, ++ long initialDelayTicks, long periodTicks); ++ ++ /** ++ * Attempts to cancel all tasks scheduled by the specified plugin. ++ * @param plugin Specified plugin. ++ */ ++ void cancelTasks(@NotNull Plugin plugin); ++} +diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7557e170f84cde7292869fbd92b44b0e6eb43b4f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java +@@ -0,0 +1,127 @@ ++package io.papermc.paper.threadedregions.scheduler; ++ ++import org.bukkit.Location; ++import org.bukkit.World; ++import org.bukkit.entity.Entity; ++import org.bukkit.plugin.Plugin; ++import org.jetbrains.annotations.NotNull; ++ ++import java.util.function.Consumer; ++ ++/** ++ * The region task scheduler can be used to schedule tasks by location to be executed on the region which owns the location. ++ *

++ * Note: It is entirely inappropriate to use the region scheduler to schedule tasks for entities. ++ * If you wish to schedule tasks to perform actions on entities, you should be using {@link Entity#getScheduler()} ++ * as the entity scheduler will "follow" an entity if it is teleported, whereas the region task scheduler ++ * will not. ++ *

++ */ ++public interface RegionScheduler { ++ ++ /** ++ * Schedules a task to be executed on the region which owns the location. ++ * ++ * @param plugin The plugin that owns the task ++ * @param world The world of the region that owns the task ++ * @param chunkX The chunk X coordinate of the region that owns the task ++ * @param chunkZ The chunk Z coordinate of the region that owns the task ++ * @param run The task to execute ++ */ ++ void execute(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Runnable run); ++ ++ /** ++ * Schedules a task to be executed on the region which owns the location. ++ * ++ * @param plugin The plugin that owns the task ++ * @param location The location at which the region executing should own ++ * @param run The task to execute ++ */ ++ default void execute(@NotNull Plugin plugin, @NotNull Location location, @NotNull Runnable run) { ++ this.execute(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, run); ++ } ++ ++ /** ++ * Schedules a task to be executed on the region which owns the location on the next tick. ++ * ++ * @param plugin The plugin that owns the task ++ * @param world The world of the region that owns the task ++ * @param chunkX The chunk X coordinate of the region that owns the task ++ * @param chunkZ The chunk Z coordinate of the region that owns the task ++ * @param task The task to execute ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer task); ++ ++ /** ++ * Schedules a task to be executed on the region which owns the location on the next tick. ++ * ++ * @param plugin The plugin that owns the task ++ * @param location The location at which the region executing should own ++ * @param task The task to execute ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ default @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer task) { ++ return this.run(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task); ++ } ++ ++ /** ++ * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. ++ * ++ * @param plugin The plugin that owns the task ++ * @param world The world of the region that owns the task ++ * @param chunkX The chunk X coordinate of the region that owns the task ++ * @param chunkZ The chunk Z coordinate of the region that owns the task ++ * @param task The task to execute ++ * @param delayTicks The delay, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer task, ++ long delayTicks); ++ ++ /** ++ * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. ++ * ++ * @param plugin The plugin that owns the task ++ * @param location The location at which the region executing should own ++ * @param task The task to execute ++ * @param delayTicks The delay, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ default @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer task, ++ long delayTicks) { ++ return this.runDelayed(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, delayTicks); ++ } ++ ++ /** ++ * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the ++ * specified period. ++ * ++ * @param plugin The plugin that owns the task ++ * @param world The world of the region that owns the task ++ * @param chunkX The chunk X coordinate of the region that owns the task ++ * @param chunkZ The chunk Z coordinate of the region that owns the task ++ * @param task The task to execute ++ * @param initialDelayTicks The initial delay, in ticks. ++ * @param periodTicks The period, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer task, ++ long initialDelayTicks, long periodTicks); ++ ++ /** ++ * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the ++ * specified period. ++ * ++ * @param plugin The plugin that owns the task ++ * @param location The location at which the region executing should own ++ * @param task The task to execute ++ * @param initialDelayTicks The initial delay, in ticks. ++ * @param periodTicks The period, in ticks. ++ * @return The {@link ScheduledTask} that represents the scheduled task. ++ */ ++ default @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer task, ++ long initialDelayTicks, long periodTicks) { ++ return this.runAtFixedRate(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, initialDelayTicks, periodTicks); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a6b50c9d8af589cc4747e14d343d2045216c249c +--- /dev/null ++++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java +@@ -0,0 +1,112 @@ ++package io.papermc.paper.threadedregions.scheduler; ++ ++import org.bukkit.plugin.Plugin; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Represents a task scheduled to a scheduler. ++ */ ++public interface ScheduledTask { ++ ++ /** ++ * Returns the plugin that scheduled this task. ++ * @return the plugin that scheduled this task. ++ */ ++ @NotNull Plugin getOwningPlugin(); ++ ++ /** ++ * Returns whether this task executes on a fixed period, as opposed to executing only once. ++ * @return whether this task executes on a fixed period, as opposed to executing only once. ++ */ ++ boolean isRepeatingTask(); ++ ++ /** ++ * Attempts to cancel this task, returning the result of the attempt. In all cases, if the task is currently ++ * being executed no attempt is made to halt the task, however any executions in the future are halted. ++ * @return the result of the cancellation attempt. ++ */ ++ @NotNull CancelledState cancel(); ++ ++ /** ++ * Returns the current execution state of this task. ++ * @return the current execution state of this task. ++ */ ++ @NotNull ExecutionState getExecutionState(); ++ ++ /** ++ * Returns whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}. ++ * @return whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}. ++ */ ++ default boolean isCancelled() { ++ final ExecutionState state = this.getExecutionState(); ++ return state == ExecutionState.CANCELLED || state == ExecutionState.CANCELLED_RUNNING; ++ } ++ ++ /** ++ * Represents the result of attempting to cancel a task. ++ */ ++ enum CancelledState { ++ /** ++ * The task (repeating or not) has been successfully cancelled by the caller thread. The task is not executing ++ * currently, and it will not begin execution in the future. ++ */ ++ CANCELLED_BY_CALLER, ++ /** ++ * The task (repeating or not) is already cancelled. The task is not executing currently, and it will not ++ * begin execution in the future. ++ */ ++ CANCELLED_ALREADY, ++ ++ /** ++ * The task is not a repeating task, and could not be cancelled because the task is being executed. ++ */ ++ RUNNING, ++ /** ++ * The task is not a repeating task, and could not be cancelled because the task has already finished execution. ++ */ ++ ALREADY_EXECUTED, ++ ++ /** ++ * The caller thread successfully stopped future executions of a repeating task, but the task is currently ++ * being executed. ++ */ ++ NEXT_RUNS_CANCELLED, ++ ++ /** ++ * The repeating task's future executions are cancelled already, but the task is currently ++ * being executed. ++ */ ++ NEXT_RUNS_CANCELLED_ALREADY, ++ } ++ ++ /** ++ * Represents the current execution state of the task. ++ */ ++ enum ExecutionState { ++ /** ++ * The task is currently not executing, but may begin execution in the future. ++ */ ++ IDLE, ++ ++ /** ++ * The task is currently executing. ++ */ ++ RUNNING, ++ ++ /** ++ * The task is not repeating, and the task finished executing. ++ */ ++ FINISHED, ++ ++ /** ++ * The task is not executing and will not begin execution in the future. If this task is not repeating, then ++ * this task was never executed. ++ */ ++ CANCELLED, ++ ++ /** ++ * The task is repeating and currently executing, but future executions are cancelled and will not occur. ++ */ ++ CANCELLED_RUNNING; ++ } ++} +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index 8028a9dd43e161556dcd97aa50648b05ae6ff188..53e86d17867e5c2eae2db6a10bfbed788019a1ad 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -2658,6 +2658,141 @@ public final class Bukkit { + } + // Paper end + ++ // Paper start - Folia region threading API ++ /** ++ * Returns the region task scheduler. The region task scheduler can be used to schedule ++ * tasks by location to be executed on the region which owns the location. ++ *

++ * Note: It is entirely inappropriate to use the region scheduler to schedule tasks for entities. ++ * If you wish to schedule tasks to perform actions on entities, you should be using {@link Entity#getScheduler()} ++ * as the entity scheduler will "follow" an entity if it is teleported, whereas the region task scheduler ++ * will not. ++ *

++ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

++ * @return the region task scheduler ++ */ ++ public static @NotNull io.papermc.paper.threadedregions.scheduler.RegionScheduler getRegionScheduler() { ++ return server.getRegionScheduler(); ++ } ++ ++ /** ++ * Returns the async task scheduler. The async task scheduler can be used to schedule tasks ++ * that execute asynchronously from the server tick process. ++ * @return the async task scheduler ++ */ ++ public static @NotNull io.papermc.paper.threadedregions.scheduler.AsyncScheduler getAsyncScheduler() { ++ return server.getAsyncScheduler(); ++ } ++ ++ /** ++ * Returns the global region task scheduler. The global task scheduler can be used to schedule ++ * tasks to execute on the global region. ++ *

++ * The global region is responsible for maintaining world day time, world game time, weather cycle, ++ * sleep night skipping, executing commands for console, and other misc. tasks that do not belong to any specific region. ++ *

++ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

++ * @return the global region scheduler ++ */ ++ public static @NotNull io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler getGlobalRegionScheduler() { ++ return server.getGlobalRegionScheduler(); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified world and block position. ++ * @param world Specified world. ++ * @param position Specified block position. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position) { ++ return server.isOwnedByCurrentRegion(world, position); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunks centered at the specified block position within the specified square radius. ++ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and ++ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. ++ * @param world Specified world. ++ * @param position Specified block position. ++ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared ++ * radius, but rather a Chebyshev Distance. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position, int squareRadiusChunks) { ++ return server.isOwnedByCurrentRegion(world, position, squareRadiusChunks); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified world and block position as included in the specified location. ++ * @param location Specified location, must have a non-null world. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull Location location) { ++ return server.isOwnedByCurrentRegion(location); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunks centered at the specified world and block position as included in the specified location ++ * within the specified square radius. ++ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and ++ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. ++ * @param location Specified location, must have a non-null world. ++ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared ++ * radius, but rather a Chebyshev Distance. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull Location location, int squareRadiusChunks) { ++ return server.isOwnedByCurrentRegion(location, squareRadiusChunks); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified block position. ++ * @param block Specified block position. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull org.bukkit.block.Block block) { ++ return server.isOwnedByCurrentRegion(block.getLocation()); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified world and chunk position. ++ * @param world Specified world. ++ * @param chunkX Specified x-coordinate of the chunk position. ++ * @param chunkZ Specified z-coordinate of the chunk position. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ) { ++ return server.isOwnedByCurrentRegion(world, chunkX, chunkZ); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunks centered at the specified world and chunk position within the specified ++ * square radius. ++ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and ++ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. ++ * @param world Specified world. ++ * @param chunkX Specified x-coordinate of the chunk position. ++ * @param chunkZ Specified z-coordinate of the chunk position. ++ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared ++ * radius, but rather a Chebyshev Distance. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ, int squareRadiusChunks) { ++ return server.isOwnedByCurrentRegion(world, chunkX, chunkZ, squareRadiusChunks); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the specified entity. Note that this function is the only appropriate method of checking ++ * for ownership of an entity, as retrieving the entity's location is undefined unless the entity is owned ++ * by the current region. ++ * @param entity Specified entity. ++ */ ++ public static boolean isOwnedByCurrentRegion(@NotNull Entity entity) { ++ return server.isOwnedByCurrentRegion(entity); ++ } ++ // Paper end - Folia region threading API ++ + @NotNull + 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 65620c67da99af7e84357fe91d90878ebe84798b..e9773ebcc76fb637ed19dce203ae0dfe226b0066 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -2319,4 +2319,119 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + */ + @NotNull org.bukkit.potion.PotionBrewer getPotionBrewer(); + // Paper end ++ ++ // Paper start - Folia region threading API ++ /** ++ * Returns the Folia region task scheduler. The region task scheduler can be used to schedule ++ * tasks by location to be executed on the region which owns the location. ++ *

++ * Note: It is entirely inappropriate to use the region scheduler to schedule tasks for entities. ++ * If you wish to schedule tasks to perform actions on entities, you should be using {@link Entity#getScheduler()} ++ * as the entity scheduler will "follow" an entity if it is teleported, whereas the region task scheduler ++ * will not. ++ *

++ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

++ * @return the region task scheduler ++ */ ++ @NotNull io.papermc.paper.threadedregions.scheduler.RegionScheduler getRegionScheduler(); ++ ++ /** ++ * Returns the Folia async task scheduler. The async task scheduler can be used to schedule tasks ++ * that execute asynchronously from the server tick process. ++ * @return the async task scheduler ++ */ ++ @NotNull io.papermc.paper.threadedregions.scheduler.AsyncScheduler getAsyncScheduler(); ++ ++ /** ++ * Returns the Folia global region task scheduler. The global task scheduler can be used to schedule ++ * tasks to execute on the global region. ++ *

++ * The global region is responsible for maintaining world day time, world game time, weather cycle, ++ * sleep night skipping, executing commands for console, and other misc. tasks that do not belong to any specific region. ++ *

++ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

++ * @return the global region scheduler ++ */ ++ @NotNull io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler getGlobalRegionScheduler(); ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified world and block position. ++ * @param world Specified world. ++ * @param position Specified block position. ++ */ ++ boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position); ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunks centered at the specified block position within the specified square radius. ++ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and ++ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. ++ * @param world Specified world. ++ * @param position Specified block position. ++ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared ++ * radius, but rather a Chebyshev Distance. ++ */ ++ boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position, int squareRadiusChunks); ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified world and block position as included in the specified location. ++ * @param location Specified location, must have a non-null world. ++ */ ++ boolean isOwnedByCurrentRegion(@NotNull Location location); ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunks centered at the specified world and block position as included in the specified location ++ * within the specified square radius. ++ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and ++ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. ++ * @param location Specified location, must have a non-null world. ++ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared ++ * radius, but rather a Chebyshev Distance. ++ */ ++ boolean isOwnedByCurrentRegion(@NotNull Location location, int squareRadiusChunks); ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified block position. ++ * @param block Specified block position. ++ */ ++ default boolean isOwnedByCurrentRegion(@NotNull org.bukkit.block.Block block) { ++ return isOwnedByCurrentRegion(block.getLocation()); ++ } ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunk at the specified world and chunk position. ++ * @param world Specified world. ++ * @param chunkX Specified x-coordinate of the chunk position. ++ * @param chunkZ Specified z-coordinate of the chunk position. ++ */ ++ boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ); ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the chunks centered at the specified world and chunk position within the specified ++ * square radius. ++ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and ++ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. ++ * @param world Specified world. ++ * @param chunkX Specified x-coordinate of the chunk position. ++ * @param chunkZ Specified z-coordinate of the chunk position. ++ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared ++ * radius, but rather a Chebyshev Distance. ++ */ ++ boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ, int squareRadiusChunks); ++ ++ /** ++ * Returns whether the current thread is ticking a region and that the region being ticked ++ * owns the specified entity. Note that this function is the only appropriate method of checking ++ * for ownership of an entity, as retrieving the entity's location is undefined unless the entity is owned ++ * by the current region. ++ * @param entity Specified entity. ++ */ ++ boolean isOwnedByCurrentRegion(@NotNull Entity entity); ++ // Paper end - Folia region threading API + } +diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java +index a76e537c9b3b9519cd46894c90b750f012182be9..4580c7613fac4f1eeccc2be2d15497cec5868736 100644 +--- a/src/main/java/org/bukkit/entity/Entity.java ++++ b/src/main/java/org/bukkit/entity/Entity.java +@@ -1101,4 +1101,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent + */ + boolean wouldCollideUsing(@NotNull BoundingBox boundingBox); + // Paper end - Collision API ++ ++ // Paper start - Folia schedulers ++ /** ++ * Returns the task scheduler for this entity. The entity scheduler can be used to schedule tasks ++ * that are guaranteed to always execute on the tick thread that owns the entity. ++ *

If you do not need/want to make your plugin run on Folia, use {@link org.bukkit.Server#getScheduler()} instead.

++ * @return the task scheduler for this entity. ++ * @see io.papermc.paper.threadedregions.scheduler.EntityScheduler ++ */ ++ @NotNull io.papermc.paper.threadedregions.scheduler.EntityScheduler getScheduler(); ++ // Paper end - Folia schedulers + } diff --git a/patches/api/0399-Add-event-for-player-editing-sign.patch b/patches/api/0399-Add-event-for-player-editing-sign.patch new file mode 100644 index 0000000000..ec38bf008b --- /dev/null +++ b/patches/api/0399-Add-event-for-player-editing-sign.patch @@ -0,0 +1,135 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: by77er +Date: Sat, 10 Jun 2023 19:06:24 -0400 +Subject: [PATCH] Add event for player editing sign + + +diff --git a/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d5fe361f5 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java +@@ -0,0 +1,108 @@ ++package io.papermc.paper.event.player; ++ ++import org.bukkit.block.Sign; ++import org.bukkit.block.sign.Side; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Called when a player begins editing a sign's text. ++ *

++ * Cancelling this event stops the sign editing menu from opening. ++ */ ++public class PlayerOpenSignEvent extends PlayerEvent implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private final Sign sign; ++ private final Side side; ++ private final Cause cause; ++ ++ private boolean cancelled; ++ ++ @ApiStatus.Internal ++ public PlayerOpenSignEvent(final @NotNull Player editor, final @NotNull Sign sign, final @NotNull Side side, final @NotNull Cause cause) { ++ super(editor); ++ this.sign = sign; ++ this.side = side; ++ this.cause = cause; ++ } ++ ++ /** ++ * Gets the sign that was clicked. ++ * ++ * @return {@link Sign} that was clicked ++ */ ++ @NotNull ++ public Sign getSign() { ++ return this.sign; ++ } ++ ++ /** ++ * Gets which side of the sign was clicked. ++ * ++ * @return {@link Side} that was clicked ++ * @see Sign#getSide(Side) ++ */ ++ @NotNull ++ public Side getSide() { ++ return this.side; ++ } ++ ++ /** ++ * The cause of this sign open. ++ * ++ * @return the cause ++ */ ++ public @NotNull Cause getCause() { ++ return this.cause; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++ ++ /** ++ * The cause of the {@link PlayerOpenSignEvent}. ++ */ ++ public enum Cause { ++ /** ++ * The event was triggered by the placement of a sign. ++ */ ++ PLACE, ++ /** ++ * The event was triggered by an interaction with a sign. ++ */ ++ INTERACT, ++ /** ++ * The event was triggered via a plugin with {@link HumanEntity#openSign(Sign, Side)} ++ */ ++ PLUGIN, ++ /** ++ * Fallback cause for any unknown cause. ++ */ ++ UNKNOWN, ++ } ++} +diff --git a/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java b/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java +index cf935d9c8d8f9a9684024507846a9754f0207986..72fe69c3830f07dd264cfd89e92410dc107034a4 100644 +--- a/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java ++++ b/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java +@@ -9,7 +9,10 @@ import org.jetbrains.annotations.NotNull; + + /** + * This event is fired when a sign is opened by the player. ++ * @deprecated use {@link io.papermc.paper.event.player.PlayerOpenSignEvent} + */ ++@Deprecated(forRemoval = true) // Paper ++@org.bukkit.Warning(false) // Paper + public class PlayerSignOpenEvent extends PlayerEvent implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); diff --git a/patches/api/0399-Folia-scheduler-and-owned-region-API.patch b/patches/api/0399-Folia-scheduler-and-owned-region-API.patch deleted file mode 100644 index 35af43df05..0000000000 --- a/patches/api/0399-Folia-scheduler-and-owned-region-API.patch +++ /dev/null @@ -1,790 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Sat, 17 Jun 2023 11:52:41 +0200 -Subject: [PATCH] Folia scheduler and owned region API - -Pulling Folia API to Paper is primarily intended for plugins -that want to target both Paper and Folia without unnecessary -compatibility layers. - -Add both a location based scheduler, an entity based scheduler, -and a global region scheduler. - -Owned region API may be useful for plugins which want to perform -operations over large areas outside of the buffer zone provided -by the regionaliser, as it is not guaranteed that anything -outside of the buffer zone is owned. Then, the plugins may use -the schedulers depending on the result of the ownership check. - -diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d9cdd04660c5e60e494a8fed91ae437e6cb733ed ---- /dev/null -+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/AsyncScheduler.java -@@ -0,0 +1,51 @@ -+package io.papermc.paper.threadedregions.scheduler; -+ -+import org.bukkit.plugin.Plugin; -+import org.jetbrains.annotations.NotNull; -+ -+import java.util.concurrent.TimeUnit; -+import java.util.function.Consumer; -+ -+/** -+ * Scheduler that may be used by plugins to schedule tasks to execute asynchronously from the server tick process. -+ */ -+public interface AsyncScheduler { -+ -+ /** -+ * Schedules the specified task to be executed asynchronously immediately. -+ * @param plugin Plugin which owns the specified task. -+ * @param task Specified task. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask runNow(@NotNull Plugin plugin, @NotNull Consumer task); -+ -+ /** -+ * Schedules the specified task to be executed asynchronously after the time delay has passed. -+ * @param plugin Plugin which owns the specified task. -+ * @param task Specified task. -+ * @param delay The time delay to pass before the task should be executed. -+ * @param unit The time unit for the time delay. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer task, long delay, -+ @NotNull TimeUnit unit); -+ -+ /** -+ * Schedules the specified task to be executed asynchronously after the initial delay has passed, -+ * and then periodically executed with the specified period. -+ * @param plugin Plugin which owns the specified task. -+ * @param task Specified task. -+ * @param initialDelay The time delay to pass before the first execution of the task. -+ * @param period The time between task executions after the first execution of the task. -+ * @param unit The time unit for the initial delay and period. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer task, -+ long initialDelay, long period, @NotNull TimeUnit unit); -+ -+ /** -+ * Attempts to cancel all tasks scheduled by the specified plugin. -+ * @param plugin Specified plugin. -+ */ -+ void cancelTasks(@NotNull Plugin plugin); -+} -diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java -new file mode 100644 -index 0000000000000000000000000000000000000000..9f69e189be8202a0ab1450540f5d12187ba6c987 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/EntityScheduler.java -@@ -0,0 +1,104 @@ -+package io.papermc.paper.threadedregions.scheduler; -+ -+import org.bukkit.plugin.Plugin; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Nullable; -+ -+import java.util.function.Consumer; -+ -+/** -+ * An entity can move between worlds with an arbitrary tick delay, be temporarily removed -+ * for players (i.e end credits), be partially removed from world state (i.e inactive but not removed), -+ * teleport between ticking regions, teleport between worlds, and even be removed entirely from the server. -+ * The uncertainty of an entity's state can make it difficult to schedule tasks without worrying about undefined -+ * behaviors resulting from any of the states listed previously. -+ * -+ *

-+ * This class is designed to eliminate those states by providing an interface to run tasks only when an entity -+ * is contained in a world, on the owning thread for the region, and by providing the current Entity object. -+ * The scheduler also allows a task to provide a callback, the "retired" callback, that will be invoked -+ * if the entity is removed before a task that was scheduled could be executed. The scheduler is also -+ * completely thread-safe, allowing tasks to be scheduled from any thread context. The scheduler also indicates -+ * properly whether a task was scheduled successfully (i.e scheduler not retired), thus the code scheduling any task -+ * knows whether the given callbacks will be invoked eventually or not - which may be critical for off-thread -+ * contexts. -+ *

-+ */ -+public interface EntityScheduler { -+ -+ /** -+ * Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity -+ * removed), then returns {@code false}. Otherwise, either the run callback will be invoked after the specified delay, -+ * or the retired callback will be invoked if the scheduler is retired. -+ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove -+ * other entities, load chunks, load worlds, modify ticket levels, etc. -+ * -+ *

-+ * It is guaranteed that the run and retired callback are invoked on the region which owns the entity. -+ *

-+ * @param run The callback to run after the specified delay, may not be null. -+ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. -+ * @param delay The delay in ticks before the run callback is invoked. Any value less-than 1 is treated as 1. -+ * @return {@code true} if the task was scheduled, which means that either the run function or the retired function -+ * will be invoked (but never both), or {@code false} indicating neither the run nor retired function will be invoked -+ * since the scheduler has been retired. -+ */ -+ boolean execute(@NotNull Plugin plugin, @NotNull Runnable run, @Nullable Runnable retired, long delay); -+ -+ /** -+ * Schedules a task to execute on the next tick. If the task failed to schedule because the scheduler is retired (entity -+ * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, -+ * or the retired callback will be invoked if the scheduler is retired. -+ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove -+ * other entities, load chunks, load worlds, modify ticket levels, etc. -+ * -+ *

-+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. -+ *

-+ * @param plugin The plugin that owns the task -+ * @param task The task to execute -+ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. -+ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. -+ */ -+ @Nullable ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer task, -+ @Nullable Runnable retired); -+ -+ /** -+ * Schedules a task with the given delay. If the task failed to schedule because the scheduler is retired (entity -+ * removed), then returns {@code null}. Otherwise, either the task callback will be invoked after the specified delay, -+ * or the retired callback will be invoked if the scheduler is retired. -+ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove -+ * other entities, load chunks, load worlds, modify ticket levels, etc. -+ * -+ *

-+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. -+ *

-+ * @param plugin The plugin that owns the task -+ * @param task The task to execute -+ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. -+ * @param delayTicks The delay, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. -+ */ -+ @Nullable ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer task, -+ @Nullable Runnable retired, long delayTicks); -+ -+ /** -+ * Schedules a repeating task with the given delay and period. If the task failed to schedule because the scheduler -+ * is retired (entity removed), then returns {@code null}. Otherwise, either the task callback will be invoked after -+ * the specified delay, or the retired callback will be invoked if the scheduler is retired. -+ * Note that the retired callback is invoked in critical code, so it should not attempt to remove the entity, remove -+ * other entities, load chunks, load worlds, modify ticket levels, etc. -+ * -+ *

-+ * It is guaranteed that the task and retired callback are invoked on the region which owns the entity. -+ *

-+ * @param plugin The plugin that owns the task -+ * @param task The task to execute -+ * @param retired Retire callback to run if the entity is retired before the run callback can be invoked, may be null. -+ * @param initialDelayTicks The initial delay, in ticks. -+ * @param periodTicks The period, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task, or {@code null} if the entity has been removed. -+ */ -+ @Nullable ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer task, -+ @Nullable Runnable retired, long initialDelayTicks, long periodTicks); -+} -diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java -new file mode 100644 -index 0000000000000000000000000000000000000000..365b53fea8dee09cdc11f4399dea5f00c6ee70e2 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/GlobalRegionScheduler.java -@@ -0,0 +1,58 @@ -+package io.papermc.paper.threadedregions.scheduler; -+ -+import org.bukkit.plugin.Plugin; -+import org.jetbrains.annotations.NotNull; -+ -+import java.util.function.Consumer; -+ -+/** -+ * The global region task scheduler may be used to schedule tasks that will execute on the global region. -+ *

-+ * The global region is responsible for maintaining world day time, world game time, weather cycle, -+ * sleep night skipping, executing commands for console, and other misc. tasks that do not belong to any specific region. -+ *

-+ */ -+public interface GlobalRegionScheduler { -+ -+ /** -+ * Schedules a task to be executed on the global region. -+ * @param plugin The plugin that owns the task -+ * @param run The task to execute -+ */ -+ void execute(@NotNull Plugin plugin, @NotNull Runnable run); -+ -+ /** -+ * Schedules a task to be executed on the global region on the next tick. -+ * @param plugin The plugin that owns the task -+ * @param task The task to execute -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Consumer task); -+ -+ /** -+ * Schedules a task to be executed on the global region after the specified delay in ticks. -+ * @param plugin The plugin that owns the task -+ * @param task The task to execute -+ * @param delayTicks The delay, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Consumer task, long delayTicks); -+ -+ /** -+ * Schedules a repeating task to be executed on the global region after the initial delay with the -+ * specified period. -+ * @param plugin The plugin that owns the task -+ * @param task The task to execute -+ * @param initialDelayTicks The initial delay, in ticks. -+ * @param periodTicks The period, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Consumer task, -+ long initialDelayTicks, long periodTicks); -+ -+ /** -+ * Attempts to cancel all tasks scheduled by the specified plugin. -+ * @param plugin Specified plugin. -+ */ -+ void cancelTasks(@NotNull Plugin plugin); -+} -diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java -new file mode 100644 -index 0000000000000000000000000000000000000000..7557e170f84cde7292869fbd92b44b0e6eb43b4f ---- /dev/null -+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/RegionScheduler.java -@@ -0,0 +1,127 @@ -+package io.papermc.paper.threadedregions.scheduler; -+ -+import org.bukkit.Location; -+import org.bukkit.World; -+import org.bukkit.entity.Entity; -+import org.bukkit.plugin.Plugin; -+import org.jetbrains.annotations.NotNull; -+ -+import java.util.function.Consumer; -+ -+/** -+ * The region task scheduler can be used to schedule tasks by location to be executed on the region which owns the location. -+ *

-+ * Note: It is entirely inappropriate to use the region scheduler to schedule tasks for entities. -+ * If you wish to schedule tasks to perform actions on entities, you should be using {@link Entity#getScheduler()} -+ * as the entity scheduler will "follow" an entity if it is teleported, whereas the region task scheduler -+ * will not. -+ *

-+ */ -+public interface RegionScheduler { -+ -+ /** -+ * Schedules a task to be executed on the region which owns the location. -+ * -+ * @param plugin The plugin that owns the task -+ * @param world The world of the region that owns the task -+ * @param chunkX The chunk X coordinate of the region that owns the task -+ * @param chunkZ The chunk Z coordinate of the region that owns the task -+ * @param run The task to execute -+ */ -+ void execute(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Runnable run); -+ -+ /** -+ * Schedules a task to be executed on the region which owns the location. -+ * -+ * @param plugin The plugin that owns the task -+ * @param location The location at which the region executing should own -+ * @param run The task to execute -+ */ -+ default void execute(@NotNull Plugin plugin, @NotNull Location location, @NotNull Runnable run) { -+ this.execute(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, run); -+ } -+ -+ /** -+ * Schedules a task to be executed on the region which owns the location on the next tick. -+ * -+ * @param plugin The plugin that owns the task -+ * @param world The world of the region that owns the task -+ * @param chunkX The chunk X coordinate of the region that owns the task -+ * @param chunkZ The chunk Z coordinate of the region that owns the task -+ * @param task The task to execute -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer task); -+ -+ /** -+ * Schedules a task to be executed on the region which owns the location on the next tick. -+ * -+ * @param plugin The plugin that owns the task -+ * @param location The location at which the region executing should own -+ * @param task The task to execute -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ default @NotNull ScheduledTask run(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer task) { -+ return this.run(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task); -+ } -+ -+ /** -+ * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. -+ * -+ * @param plugin The plugin that owns the task -+ * @param world The world of the region that owns the task -+ * @param chunkX The chunk X coordinate of the region that owns the task -+ * @param chunkZ The chunk Z coordinate of the region that owns the task -+ * @param task The task to execute -+ * @param delayTicks The delay, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer task, -+ long delayTicks); -+ -+ /** -+ * Schedules a task to be executed on the region which owns the location after the specified delay in ticks. -+ * -+ * @param plugin The plugin that owns the task -+ * @param location The location at which the region executing should own -+ * @param task The task to execute -+ * @param delayTicks The delay, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ default @NotNull ScheduledTask runDelayed(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer task, -+ long delayTicks) { -+ return this.runDelayed(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, delayTicks); -+ } -+ -+ /** -+ * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the -+ * specified period. -+ * -+ * @param plugin The plugin that owns the task -+ * @param world The world of the region that owns the task -+ * @param chunkX The chunk X coordinate of the region that owns the task -+ * @param chunkZ The chunk Z coordinate of the region that owns the task -+ * @param task The task to execute -+ * @param initialDelayTicks The initial delay, in ticks. -+ * @param periodTicks The period, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull World world, int chunkX, int chunkZ, @NotNull Consumer task, -+ long initialDelayTicks, long periodTicks); -+ -+ /** -+ * Schedules a repeating task to be executed on the region which owns the location after the initial delay with the -+ * specified period. -+ * -+ * @param plugin The plugin that owns the task -+ * @param location The location at which the region executing should own -+ * @param task The task to execute -+ * @param initialDelayTicks The initial delay, in ticks. -+ * @param periodTicks The period, in ticks. -+ * @return The {@link ScheduledTask} that represents the scheduled task. -+ */ -+ default @NotNull ScheduledTask runAtFixedRate(@NotNull Plugin plugin, @NotNull Location location, @NotNull Consumer task, -+ long initialDelayTicks, long periodTicks) { -+ return this.runAtFixedRate(plugin, location.getWorld(), location.getBlockX() >> 4, location.getBlockZ() >> 4, task, initialDelayTicks, periodTicks); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java -new file mode 100644 -index 0000000000000000000000000000000000000000..a6b50c9d8af589cc4747e14d343d2045216c249c ---- /dev/null -+++ b/src/main/java/io/papermc/paper/threadedregions/scheduler/ScheduledTask.java -@@ -0,0 +1,112 @@ -+package io.papermc.paper.threadedregions.scheduler; -+ -+import org.bukkit.plugin.Plugin; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Represents a task scheduled to a scheduler. -+ */ -+public interface ScheduledTask { -+ -+ /** -+ * Returns the plugin that scheduled this task. -+ * @return the plugin that scheduled this task. -+ */ -+ @NotNull Plugin getOwningPlugin(); -+ -+ /** -+ * Returns whether this task executes on a fixed period, as opposed to executing only once. -+ * @return whether this task executes on a fixed period, as opposed to executing only once. -+ */ -+ boolean isRepeatingTask(); -+ -+ /** -+ * Attempts to cancel this task, returning the result of the attempt. In all cases, if the task is currently -+ * being executed no attempt is made to halt the task, however any executions in the future are halted. -+ * @return the result of the cancellation attempt. -+ */ -+ @NotNull CancelledState cancel(); -+ -+ /** -+ * Returns the current execution state of this task. -+ * @return the current execution state of this task. -+ */ -+ @NotNull ExecutionState getExecutionState(); -+ -+ /** -+ * Returns whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}. -+ * @return whether the current execution state is {@link ExecutionState#CANCELLED} or {@link ExecutionState#CANCELLED_RUNNING}. -+ */ -+ default boolean isCancelled() { -+ final ExecutionState state = this.getExecutionState(); -+ return state == ExecutionState.CANCELLED || state == ExecutionState.CANCELLED_RUNNING; -+ } -+ -+ /** -+ * Represents the result of attempting to cancel a task. -+ */ -+ enum CancelledState { -+ /** -+ * The task (repeating or not) has been successfully cancelled by the caller thread. The task is not executing -+ * currently, and it will not begin execution in the future. -+ */ -+ CANCELLED_BY_CALLER, -+ /** -+ * The task (repeating or not) is already cancelled. The task is not executing currently, and it will not -+ * begin execution in the future. -+ */ -+ CANCELLED_ALREADY, -+ -+ /** -+ * The task is not a repeating task, and could not be cancelled because the task is being executed. -+ */ -+ RUNNING, -+ /** -+ * The task is not a repeating task, and could not be cancelled because the task has already finished execution. -+ */ -+ ALREADY_EXECUTED, -+ -+ /** -+ * The caller thread successfully stopped future executions of a repeating task, but the task is currently -+ * being executed. -+ */ -+ NEXT_RUNS_CANCELLED, -+ -+ /** -+ * The repeating task's future executions are cancelled already, but the task is currently -+ * being executed. -+ */ -+ NEXT_RUNS_CANCELLED_ALREADY, -+ } -+ -+ /** -+ * Represents the current execution state of the task. -+ */ -+ enum ExecutionState { -+ /** -+ * The task is currently not executing, but may begin execution in the future. -+ */ -+ IDLE, -+ -+ /** -+ * The task is currently executing. -+ */ -+ RUNNING, -+ -+ /** -+ * The task is not repeating, and the task finished executing. -+ */ -+ FINISHED, -+ -+ /** -+ * The task is not executing and will not begin execution in the future. If this task is not repeating, then -+ * this task was never executed. -+ */ -+ CANCELLED, -+ -+ /** -+ * The task is repeating and currently executing, but future executions are cancelled and will not occur. -+ */ -+ CANCELLED_RUNNING; -+ } -+} -diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 8028a9dd43e161556dcd97aa50648b05ae6ff188..53e86d17867e5c2eae2db6a10bfbed788019a1ad 100644 ---- a/src/main/java/org/bukkit/Bukkit.java -+++ b/src/main/java/org/bukkit/Bukkit.java -@@ -2658,6 +2658,141 @@ public final class Bukkit { - } - // Paper end - -+ // Paper start - Folia region threading API -+ /** -+ * Returns the region task scheduler. The region task scheduler can be used to schedule -+ * tasks by location to be executed on the region which owns the location. -+ *

-+ * Note: It is entirely inappropriate to use the region scheduler to schedule tasks for entities. -+ * If you wish to schedule tasks to perform actions on entities, you should be using {@link Entity#getScheduler()} -+ * as the entity scheduler will "follow" an entity if it is teleported, whereas the region task scheduler -+ * will not. -+ *

-+ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

-+ * @return the region task scheduler -+ */ -+ public static @NotNull io.papermc.paper.threadedregions.scheduler.RegionScheduler getRegionScheduler() { -+ return server.getRegionScheduler(); -+ } -+ -+ /** -+ * Returns the async task scheduler. The async task scheduler can be used to schedule tasks -+ * that execute asynchronously from the server tick process. -+ * @return the async task scheduler -+ */ -+ public static @NotNull io.papermc.paper.threadedregions.scheduler.AsyncScheduler getAsyncScheduler() { -+ return server.getAsyncScheduler(); -+ } -+ -+ /** -+ * Returns the global region task scheduler. The global task scheduler can be used to schedule -+ * tasks to execute on the global region. -+ *

-+ * The global region is responsible for maintaining world day time, world game time, weather cycle, -+ * sleep night skipping, executing commands for console, and other misc. tasks that do not belong to any specific region. -+ *

-+ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

-+ * @return the global region scheduler -+ */ -+ public static @NotNull io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler getGlobalRegionScheduler() { -+ return server.getGlobalRegionScheduler(); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified world and block position. -+ * @param world Specified world. -+ * @param position Specified block position. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position) { -+ return server.isOwnedByCurrentRegion(world, position); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunks centered at the specified block position within the specified square radius. -+ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and -+ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. -+ * @param world Specified world. -+ * @param position Specified block position. -+ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared -+ * radius, but rather a Chebyshev Distance. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position, int squareRadiusChunks) { -+ return server.isOwnedByCurrentRegion(world, position, squareRadiusChunks); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified world and block position as included in the specified location. -+ * @param location Specified location, must have a non-null world. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull Location location) { -+ return server.isOwnedByCurrentRegion(location); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunks centered at the specified world and block position as included in the specified location -+ * within the specified square radius. -+ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and -+ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. -+ * @param location Specified location, must have a non-null world. -+ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared -+ * radius, but rather a Chebyshev Distance. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull Location location, int squareRadiusChunks) { -+ return server.isOwnedByCurrentRegion(location, squareRadiusChunks); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified block position. -+ * @param block Specified block position. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull org.bukkit.block.Block block) { -+ return server.isOwnedByCurrentRegion(block.getLocation()); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified world and chunk position. -+ * @param world Specified world. -+ * @param chunkX Specified x-coordinate of the chunk position. -+ * @param chunkZ Specified z-coordinate of the chunk position. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ) { -+ return server.isOwnedByCurrentRegion(world, chunkX, chunkZ); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunks centered at the specified world and chunk position within the specified -+ * square radius. -+ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and -+ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. -+ * @param world Specified world. -+ * @param chunkX Specified x-coordinate of the chunk position. -+ * @param chunkZ Specified z-coordinate of the chunk position. -+ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared -+ * radius, but rather a Chebyshev Distance. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ, int squareRadiusChunks) { -+ return server.isOwnedByCurrentRegion(world, chunkX, chunkZ, squareRadiusChunks); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the specified entity. Note that this function is the only appropriate method of checking -+ * for ownership of an entity, as retrieving the entity's location is undefined unless the entity is owned -+ * by the current region. -+ * @param entity Specified entity. -+ */ -+ public static boolean isOwnedByCurrentRegion(@NotNull Entity entity) { -+ return server.isOwnedByCurrentRegion(entity); -+ } -+ // Paper end - Folia region threading API -+ - @NotNull - 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 65620c67da99af7e84357fe91d90878ebe84798b..e9773ebcc76fb637ed19dce203ae0dfe226b0066 100644 ---- a/src/main/java/org/bukkit/Server.java -+++ b/src/main/java/org/bukkit/Server.java -@@ -2319,4 +2319,119 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - */ - @NotNull org.bukkit.potion.PotionBrewer getPotionBrewer(); - // Paper end -+ -+ // Paper start - Folia region threading API -+ /** -+ * Returns the Folia region task scheduler. The region task scheduler can be used to schedule -+ * tasks by location to be executed on the region which owns the location. -+ *

-+ * Note: It is entirely inappropriate to use the region scheduler to schedule tasks for entities. -+ * If you wish to schedule tasks to perform actions on entities, you should be using {@link Entity#getScheduler()} -+ * as the entity scheduler will "follow" an entity if it is teleported, whereas the region task scheduler -+ * will not. -+ *

-+ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

-+ * @return the region task scheduler -+ */ -+ @NotNull io.papermc.paper.threadedregions.scheduler.RegionScheduler getRegionScheduler(); -+ -+ /** -+ * Returns the Folia async task scheduler. The async task scheduler can be used to schedule tasks -+ * that execute asynchronously from the server tick process. -+ * @return the async task scheduler -+ */ -+ @NotNull io.papermc.paper.threadedregions.scheduler.AsyncScheduler getAsyncScheduler(); -+ -+ /** -+ * Returns the Folia global region task scheduler. The global task scheduler can be used to schedule -+ * tasks to execute on the global region. -+ *

-+ * The global region is responsible for maintaining world day time, world game time, weather cycle, -+ * sleep night skipping, executing commands for console, and other misc. tasks that do not belong to any specific region. -+ *

-+ *

If you do not need/want to make your plugin run on Folia, use {@link #getScheduler()} instead.

-+ * @return the global region scheduler -+ */ -+ @NotNull io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler getGlobalRegionScheduler(); -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified world and block position. -+ * @param world Specified world. -+ * @param position Specified block position. -+ */ -+ boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position); -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunks centered at the specified block position within the specified square radius. -+ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and -+ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. -+ * @param world Specified world. -+ * @param position Specified block position. -+ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared -+ * radius, but rather a Chebyshev Distance. -+ */ -+ boolean isOwnedByCurrentRegion(@NotNull World world, @NotNull io.papermc.paper.math.Position position, int squareRadiusChunks); -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified world and block position as included in the specified location. -+ * @param location Specified location, must have a non-null world. -+ */ -+ boolean isOwnedByCurrentRegion(@NotNull Location location); -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunks centered at the specified world and block position as included in the specified location -+ * within the specified square radius. -+ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and -+ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. -+ * @param location Specified location, must have a non-null world. -+ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared -+ * radius, but rather a Chebyshev Distance. -+ */ -+ boolean isOwnedByCurrentRegion(@NotNull Location location, int squareRadiusChunks); -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified block position. -+ * @param block Specified block position. -+ */ -+ default boolean isOwnedByCurrentRegion(@NotNull org.bukkit.block.Block block) { -+ return isOwnedByCurrentRegion(block.getLocation()); -+ } -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunk at the specified world and chunk position. -+ * @param world Specified world. -+ * @param chunkX Specified x-coordinate of the chunk position. -+ * @param chunkZ Specified z-coordinate of the chunk position. -+ */ -+ boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ); -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the chunks centered at the specified world and chunk position within the specified -+ * square radius. -+ * Specifically, this function checks that every chunk with position x in [centerX - radius, centerX + radius] and -+ * position z in [centerZ - radius, centerZ + radius] is owned by the current ticking region. -+ * @param world Specified world. -+ * @param chunkX Specified x-coordinate of the chunk position. -+ * @param chunkZ Specified z-coordinate of the chunk position. -+ * @param squareRadiusChunks Specified square radius. Must be >= 0. Note that this parameter is not a squared -+ * radius, but rather a Chebyshev Distance. -+ */ -+ boolean isOwnedByCurrentRegion(@NotNull World world, int chunkX, int chunkZ, int squareRadiusChunks); -+ -+ /** -+ * Returns whether the current thread is ticking a region and that the region being ticked -+ * owns the specified entity. Note that this function is the only appropriate method of checking -+ * for ownership of an entity, as retrieving the entity's location is undefined unless the entity is owned -+ * by the current region. -+ * @param entity Specified entity. -+ */ -+ boolean isOwnedByCurrentRegion(@NotNull Entity entity); -+ // Paper end - Folia region threading API - } -diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java -index a76e537c9b3b9519cd46894c90b750f012182be9..4580c7613fac4f1eeccc2be2d15497cec5868736 100644 ---- a/src/main/java/org/bukkit/entity/Entity.java -+++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1101,4 +1101,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent - */ - boolean wouldCollideUsing(@NotNull BoundingBox boundingBox); - // Paper end - Collision API -+ -+ // Paper start - Folia schedulers -+ /** -+ * Returns the task scheduler for this entity. The entity scheduler can be used to schedule tasks -+ * that are guaranteed to always execute on the tick thread that owns the entity. -+ *

If you do not need/want to make your plugin run on Folia, use {@link org.bukkit.Server#getScheduler()} instead.

-+ * @return the task scheduler for this entity. -+ * @see io.papermc.paper.threadedregions.scheduler.EntityScheduler -+ */ -+ @NotNull io.papermc.paper.threadedregions.scheduler.EntityScheduler getScheduler(); -+ // Paper end - Folia schedulers - } diff --git a/patches/api/0400-Add-Sign-getInteractableSideFor.patch b/patches/api/0400-Add-Sign-getInteractableSideFor.patch new file mode 100644 index 0000000000..1e085323ca --- /dev/null +++ b/patches/api/0400-Add-Sign-getInteractableSideFor.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Fri, 23 Jun 2023 12:16:35 -0700 +Subject: [PATCH] Add Sign#getInteractableSideFor + + +diff --git a/src/main/java/org/bukkit/block/Sign.java b/src/main/java/org/bukkit/block/Sign.java +index 1fdb1144949adc3a2b5cbc3aca94d2f8e0c6d9ee..7983ccb54f5f358dea1ffb530b9cc5bd716fb9b1 100644 +--- a/src/main/java/org/bukkit/block/Sign.java ++++ b/src/main/java/org/bukkit/block/Sign.java +@@ -187,4 +187,34 @@ public interface Sign extends TileState, Colorable { + */ + @Nullable + public Player getAllowedEditor(); ++ // Paper start - get side for player ++ /** ++ * Compute the side facing the specified entity. ++ * ++ * @param entity the entity ++ * @return the side it is facing ++ */ ++ default @NotNull Side getInteractableSideFor(org.bukkit.entity.@NotNull Entity entity) { ++ return this.getInteractableSideFor(entity.getLocation()); ++ } ++ ++ /** ++ * Compute the side facing the specific position. ++ * ++ * @param position the position ++ * @return the side the position is facing ++ */ ++ default @NotNull Side getInteractableSideFor(io.papermc.paper.math.@NotNull Position position) { ++ return this.getInteractableSideFor(position.x(), position.z()); ++ } ++ ++ /** ++ * Compute the side facing the specific x and z coordinates. ++ * ++ * @param x the x coord ++ * @param z the z coord ++ * @return the side the coordinates are facing ++ */ ++ @NotNull Side getInteractableSideFor(double x, double z); ++ // Paper end + } diff --git a/patches/api/0400-Add-event-for-player-editing-sign.patch b/patches/api/0400-Add-event-for-player-editing-sign.patch deleted file mode 100644 index ec38bf008b..0000000000 --- a/patches/api/0400-Add-event-for-player-editing-sign.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: by77er -Date: Sat, 10 Jun 2023 19:06:24 -0400 -Subject: [PATCH] Add event for player editing sign - - -diff --git a/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c38c32ae349e094ffef84386607f4b9d5fe361f5 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/player/PlayerOpenSignEvent.java -@@ -0,0 +1,108 @@ -+package io.papermc.paper.event.player; -+ -+import org.bukkit.block.Sign; -+import org.bukkit.block.sign.Side; -+import org.bukkit.entity.HumanEntity; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.player.PlayerEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Called when a player begins editing a sign's text. -+ *

-+ * Cancelling this event stops the sign editing menu from opening. -+ */ -+public class PlayerOpenSignEvent extends PlayerEvent implements Cancellable { -+ -+ private static final HandlerList HANDLER_LIST = new HandlerList(); -+ -+ private final Sign sign; -+ private final Side side; -+ private final Cause cause; -+ -+ private boolean cancelled; -+ -+ @ApiStatus.Internal -+ public PlayerOpenSignEvent(final @NotNull Player editor, final @NotNull Sign sign, final @NotNull Side side, final @NotNull Cause cause) { -+ super(editor); -+ this.sign = sign; -+ this.side = side; -+ this.cause = cause; -+ } -+ -+ /** -+ * Gets the sign that was clicked. -+ * -+ * @return {@link Sign} that was clicked -+ */ -+ @NotNull -+ public Sign getSign() { -+ return this.sign; -+ } -+ -+ /** -+ * Gets which side of the sign was clicked. -+ * -+ * @return {@link Side} that was clicked -+ * @see Sign#getSide(Side) -+ */ -+ @NotNull -+ public Side getSide() { -+ return this.side; -+ } -+ -+ /** -+ * The cause of this sign open. -+ * -+ * @return the cause -+ */ -+ public @NotNull Cause getCause() { -+ return this.cause; -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return this.cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ this.cancelled = cancel; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return HANDLER_LIST; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return HANDLER_LIST; -+ } -+ -+ /** -+ * The cause of the {@link PlayerOpenSignEvent}. -+ */ -+ public enum Cause { -+ /** -+ * The event was triggered by the placement of a sign. -+ */ -+ PLACE, -+ /** -+ * The event was triggered by an interaction with a sign. -+ */ -+ INTERACT, -+ /** -+ * The event was triggered via a plugin with {@link HumanEntity#openSign(Sign, Side)} -+ */ -+ PLUGIN, -+ /** -+ * Fallback cause for any unknown cause. -+ */ -+ UNKNOWN, -+ } -+} -diff --git a/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java b/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java -index cf935d9c8d8f9a9684024507846a9754f0207986..72fe69c3830f07dd264cfd89e92410dc107034a4 100644 ---- a/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java -+++ b/src/main/java/org/bukkit/event/player/PlayerSignOpenEvent.java -@@ -9,7 +9,10 @@ import org.jetbrains.annotations.NotNull; - - /** - * This event is fired when a sign is opened by the player. -+ * @deprecated use {@link io.papermc.paper.event.player.PlayerOpenSignEvent} - */ -+@Deprecated(forRemoval = true) // Paper -+@org.bukkit.Warning(false) // Paper - public class PlayerSignOpenEvent extends PlayerEvent implements Cancellable { - - private static final HandlerList handlers = new HandlerList(); diff --git a/patches/api/0401-Add-Sign-getInteractableSideFor.patch b/patches/api/0401-Add-Sign-getInteractableSideFor.patch deleted file mode 100644 index 1e085323ca..0000000000 --- a/patches/api/0401-Add-Sign-getInteractableSideFor.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Fri, 23 Jun 2023 12:16:35 -0700 -Subject: [PATCH] Add Sign#getInteractableSideFor - - -diff --git a/src/main/java/org/bukkit/block/Sign.java b/src/main/java/org/bukkit/block/Sign.java -index 1fdb1144949adc3a2b5cbc3aca94d2f8e0c6d9ee..7983ccb54f5f358dea1ffb530b9cc5bd716fb9b1 100644 ---- a/src/main/java/org/bukkit/block/Sign.java -+++ b/src/main/java/org/bukkit/block/Sign.java -@@ -187,4 +187,34 @@ public interface Sign extends TileState, Colorable { - */ - @Nullable - public Player getAllowedEditor(); -+ // Paper start - get side for player -+ /** -+ * Compute the side facing the specified entity. -+ * -+ * @param entity the entity -+ * @return the side it is facing -+ */ -+ default @NotNull Side getInteractableSideFor(org.bukkit.entity.@NotNull Entity entity) { -+ return this.getInteractableSideFor(entity.getLocation()); -+ } -+ -+ /** -+ * Compute the side facing the specific position. -+ * -+ * @param position the position -+ * @return the side the position is facing -+ */ -+ default @NotNull Side getInteractableSideFor(io.papermc.paper.math.@NotNull Position position) { -+ return this.getInteractableSideFor(position.x(), position.z()); -+ } -+ -+ /** -+ * Compute the side facing the specific x and z coordinates. -+ * -+ * @param x the x coord -+ * @param z the z coord -+ * @return the side the coordinates are facing -+ */ -+ @NotNull Side getInteractableSideFor(double x, double z); -+ // Paper end - } diff --git a/patches/api/0401-Fix-BanList-API.patch b/patches/api/0401-Fix-BanList-API.patch new file mode 100644 index 0000000000..a9640f44a2 --- /dev/null +++ b/patches/api/0401-Fix-BanList-API.patch @@ -0,0 +1,162 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Tue, 4 Jul 2023 11:27:18 -0700 +Subject: [PATCH] Fix BanList API + + +diff --git a/src/main/java/org/bukkit/BanList.java b/src/main/java/org/bukkit/BanList.java +index 548f6d28c28d74bed8b58ee82875909354afe132..a77c0411a68a9bad33ddfb335b7a996a843e478c 100644 +--- a/src/main/java/org/bukkit/BanList.java ++++ b/src/main/java/org/bukkit/BanList.java +@@ -48,7 +48,7 @@ public interface BanList { + */ + @Deprecated + @Nullable +- public BanEntry getBanEntry(@NotNull String target); ++ public > E getBanEntry(@NotNull String target); // Paper + + /** + * Gets a {@link BanEntry} by target. +@@ -77,7 +77,7 @@ public interface BanList { + */ + @Deprecated + @Nullable +- public BanEntry addBan(@NotNull String target, @Nullable String reason, @Nullable Date expires, @Nullable String source); ++ public > E addBan(@NotNull String target, @Nullable String reason, @Nullable Date expires, @Nullable String source); // Paper + + /** + * Adds a ban to this list. If a previous ban exists, this will +@@ -140,7 +140,7 @@ public interface BanList { + * @return an immutable set containing every entry tracked by this list + */ + @NotNull +- public Set> getEntries(); ++ public > Set getEntries(); // Paper + + /** + * Gets if a {@link BanEntry} exists for the target, indicating an active +diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java +index d81701f0128bdeca180ff9957621f695c787f334..299d1cc510d24541c6bb47d02db0b6a86fb1d0eb 100644 +--- a/src/main/java/org/bukkit/OfflinePlayer.java ++++ b/src/main/java/org/bukkit/OfflinePlayer.java +@@ -147,7 +147,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio + * (updated) previous ban + */ + @Nullable +- public BanEntry ban(@Nullable String reason, @Nullable Date expires, @Nullable String source); ++ public > E ban(@Nullable String reason, @Nullable Date expires, @Nullable String source); // Paper - fix ban list API + + /** + * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will +@@ -161,7 +161,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio + * (updated) previous ban + */ + @Nullable +- public BanEntry ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source); ++ public > E ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source); // Paper - fix ban list API + + /** + * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will +@@ -175,7 +175,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio + * (updated) previous ban + */ + @Nullable +- public BanEntry ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source); ++ public > E ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source); // Paper - fix ban list API + + /** + * Checks if this player is whitelisted or not +diff --git a/src/main/java/org/bukkit/ban/ProfileBanList.java b/src/main/java/org/bukkit/ban/ProfileBanList.java +index e805e629cede1c4c0674282c930cb67852718c3e..5248cf08ef83c7304dd76c42a2f646bb81e0efae 100644 +--- a/src/main/java/org/bukkit/ban/ProfileBanList.java ++++ b/src/main/java/org/bukkit/ban/ProfileBanList.java +@@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; + /** + * A {@link BanList} targeting player profile bans. + */ +-public interface ProfileBanList extends BanList { ++public interface ProfileBanList extends BanList { // Paper + + /** + * {@inheritDoc} +@@ -23,8 +23,48 @@ public interface ProfileBanList extends BanList { + * @return the entry for the newly created ban, or the entry for the + * (updated) previous ban + * @throws IllegalArgumentException if ProfilePlayer has an invalid UUID ++ * @deprecated use {@link #addBan(com.destroystokyo.paper.profile.PlayerProfile, String, Date, String)} + */ + @Nullable +- public BanEntry addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable Date expires, @Nullable String source); ++ // Paper start ++ @Deprecated ++ public > E addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable Date expires, @Nullable String source); + ++ /** ++ * @throws IllegalArgumentException if ProfilePlayer has an invalid UUID ++ */ ++ @Nullable BanEntry addBan(com.destroystokyo.paper.profile.@NotNull PlayerProfile target, @Nullable String reason, @Nullable Date expires, @Nullable String source); ++ ++ // the 5 methods below are added to maintain compat for the bukkit.PlayerProfile parameter type ++ /** ++ * @deprecated use {@link #getBanEntry(Object)} ++ */ ++ @Deprecated ++ @Nullable > E getBanEntry(@NotNull PlayerProfile target); ++ ++ /** ++ * @deprecated use {@link #isBanned(Object)} ++ */ ++ @Deprecated ++ boolean isBanned(@NotNull PlayerProfile target); ++ ++ /** ++ * @deprecated use {@link #pardon(Object)} ++ */ ++ @Deprecated ++ void pardon(@NotNull PlayerProfile target); ++ ++ /** ++ * @deprecated use {@link #addBan(Object, String, java.time.Instant, String)} ++ */ ++ @Deprecated ++ @Nullable > E addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable java.time.Instant expires, @Nullable String source); ++ ++ /** ++ * @deprecated use {@link #addBan(Object, String, java.time.Duration, String)} ++ */ ++ @Deprecated ++ @Nullable > E addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable java.time.Duration duration, @Nullable String source); ++ ++ // Paper end + } +diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java +index c86d8b88a1501bd8fd7562a21ee111607e523962..fbaea481feccfc71d744d9f93de3bf637fdcaaad 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -343,7 +343,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * (updated) previous ban + */ + @Nullable +- public BanEntry ban(@Nullable String reason, @Nullable Date expires, @Nullable String source, boolean kickPlayer); ++ public > E ban(@Nullable String reason, @Nullable Date expires, @Nullable String source, boolean kickPlayer); // Paper - fix ban list API + + /** + * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will +@@ -359,7 +359,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * (updated) previous ban + */ + @Nullable +- public BanEntry ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source, boolean kickPlayer); ++ public > E ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source, boolean kickPlayer); // Paper - fix ban list API + + /** + * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will +@@ -375,7 +375,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * (updated) previous ban + */ + @Nullable +- public BanEntry ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source, boolean kickPlayer); ++ public > E ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source, boolean kickPlayer); // Paper - fix ban list API + + /** + * Adds this user's current IP address to the {@link IpBanList}. If a previous ban exists, this will diff --git a/patches/api/0402-Add-whitelist-events.patch b/patches/api/0402-Add-whitelist-events.patch new file mode 100644 index 0000000000..75458e78df --- /dev/null +++ b/patches/api/0402-Add-whitelist-events.patch @@ -0,0 +1,99 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SageSphinx63920 +Date: Sun, 14 May 2023 12:56:15 +0200 +Subject: [PATCH] Add whitelist events + + +diff --git a/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java b/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73ccc8779f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java +@@ -0,0 +1,87 @@ ++package io.papermc.paper.event.server; ++ ++import com.destroystokyo.paper.profile.PlayerProfile; ++import org.bukkit.Bukkit; ++import org.bukkit.OfflinePlayer; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.Event; ++import org.bukkit.event.HandlerList; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * This event gets called when the whitelist status of a player is changed ++ */ ++public class WhitelistStateUpdateEvent extends Event implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ @NotNull private final PlayerProfile playerProfile; ++ @NotNull private final WhitelistStatus status; ++ ++ private boolean cancelled; ++ ++ @ApiStatus.Internal ++ public WhitelistStateUpdateEvent(@NotNull PlayerProfile playerProfile, @NotNull WhitelistStatus status) { ++ this.playerProfile = playerProfile; ++ this.status = status; ++ } ++ ++ /** ++ * Gets the player whose whitelist status is being changed ++ * ++ * @return the player whose status is being changed ++ */ ++ @NotNull ++ public OfflinePlayer getPlayer() { ++ return Bukkit.getOfflinePlayer(this.playerProfile.getId()); ++ } ++ ++ /** ++ * Gets the player profile whose whitelist status is being changed ++ * ++ * @return the player profile whose status is being changed ++ */ ++ @NotNull ++ public PlayerProfile getPlayerProfile() { ++ return this.playerProfile; ++ } ++ ++ /** ++ * Gets the status change of the player profile ++ * ++ * @return the whitelist status ++ */ ++ @NotNull ++ public WhitelistStatus getStatus() { ++ return this.status; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++ ++ /** ++ * Enum for the whitelist status changes ++ */ ++ public enum WhitelistStatus { ++ ADDED, REMOVED ++ } ++} diff --git a/patches/api/0402-Fix-BanList-API.patch b/patches/api/0402-Fix-BanList-API.patch deleted file mode 100644 index a9640f44a2..0000000000 --- a/patches/api/0402-Fix-BanList-API.patch +++ /dev/null @@ -1,162 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Tue, 4 Jul 2023 11:27:18 -0700 -Subject: [PATCH] Fix BanList API - - -diff --git a/src/main/java/org/bukkit/BanList.java b/src/main/java/org/bukkit/BanList.java -index 548f6d28c28d74bed8b58ee82875909354afe132..a77c0411a68a9bad33ddfb335b7a996a843e478c 100644 ---- a/src/main/java/org/bukkit/BanList.java -+++ b/src/main/java/org/bukkit/BanList.java -@@ -48,7 +48,7 @@ public interface BanList { - */ - @Deprecated - @Nullable -- public BanEntry getBanEntry(@NotNull String target); -+ public > E getBanEntry(@NotNull String target); // Paper - - /** - * Gets a {@link BanEntry} by target. -@@ -77,7 +77,7 @@ public interface BanList { - */ - @Deprecated - @Nullable -- public BanEntry addBan(@NotNull String target, @Nullable String reason, @Nullable Date expires, @Nullable String source); -+ public > E addBan(@NotNull String target, @Nullable String reason, @Nullable Date expires, @Nullable String source); // Paper - - /** - * Adds a ban to this list. If a previous ban exists, this will -@@ -140,7 +140,7 @@ public interface BanList { - * @return an immutable set containing every entry tracked by this list - */ - @NotNull -- public Set> getEntries(); -+ public > Set getEntries(); // Paper - - /** - * Gets if a {@link BanEntry} exists for the target, indicating an active -diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java -index d81701f0128bdeca180ff9957621f695c787f334..299d1cc510d24541c6bb47d02db0b6a86fb1d0eb 100644 ---- a/src/main/java/org/bukkit/OfflinePlayer.java -+++ b/src/main/java/org/bukkit/OfflinePlayer.java -@@ -147,7 +147,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio - * (updated) previous ban - */ - @Nullable -- public BanEntry ban(@Nullable String reason, @Nullable Date expires, @Nullable String source); -+ public > E ban(@Nullable String reason, @Nullable Date expires, @Nullable String source); // Paper - fix ban list API - - /** - * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -161,7 +161,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio - * (updated) previous ban - */ - @Nullable -- public BanEntry ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source); -+ public > E ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source); // Paper - fix ban list API - - /** - * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -175,7 +175,7 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio - * (updated) previous ban - */ - @Nullable -- public BanEntry ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source); -+ public > E ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source); // Paper - fix ban list API - - /** - * Checks if this player is whitelisted or not -diff --git a/src/main/java/org/bukkit/ban/ProfileBanList.java b/src/main/java/org/bukkit/ban/ProfileBanList.java -index e805e629cede1c4c0674282c930cb67852718c3e..5248cf08ef83c7304dd76c42a2f646bb81e0efae 100644 ---- a/src/main/java/org/bukkit/ban/ProfileBanList.java -+++ b/src/main/java/org/bukkit/ban/ProfileBanList.java -@@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; - /** - * A {@link BanList} targeting player profile bans. - */ --public interface ProfileBanList extends BanList { -+public interface ProfileBanList extends BanList { // Paper - - /** - * {@inheritDoc} -@@ -23,8 +23,48 @@ public interface ProfileBanList extends BanList { - * @return the entry for the newly created ban, or the entry for the - * (updated) previous ban - * @throws IllegalArgumentException if ProfilePlayer has an invalid UUID -+ * @deprecated use {@link #addBan(com.destroystokyo.paper.profile.PlayerProfile, String, Date, String)} - */ - @Nullable -- public BanEntry addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable Date expires, @Nullable String source); -+ // Paper start -+ @Deprecated -+ public > E addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable Date expires, @Nullable String source); - -+ /** -+ * @throws IllegalArgumentException if ProfilePlayer has an invalid UUID -+ */ -+ @Nullable BanEntry addBan(com.destroystokyo.paper.profile.@NotNull PlayerProfile target, @Nullable String reason, @Nullable Date expires, @Nullable String source); -+ -+ // the 5 methods below are added to maintain compat for the bukkit.PlayerProfile parameter type -+ /** -+ * @deprecated use {@link #getBanEntry(Object)} -+ */ -+ @Deprecated -+ @Nullable > E getBanEntry(@NotNull PlayerProfile target); -+ -+ /** -+ * @deprecated use {@link #isBanned(Object)} -+ */ -+ @Deprecated -+ boolean isBanned(@NotNull PlayerProfile target); -+ -+ /** -+ * @deprecated use {@link #pardon(Object)} -+ */ -+ @Deprecated -+ void pardon(@NotNull PlayerProfile target); -+ -+ /** -+ * @deprecated use {@link #addBan(Object, String, java.time.Instant, String)} -+ */ -+ @Deprecated -+ @Nullable > E addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable java.time.Instant expires, @Nullable String source); -+ -+ /** -+ * @deprecated use {@link #addBan(Object, String, java.time.Duration, String)} -+ */ -+ @Deprecated -+ @Nullable > E addBan(@NotNull PlayerProfile target, @Nullable String reason, @Nullable java.time.Duration duration, @Nullable String source); -+ -+ // Paper end - } -diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index c86d8b88a1501bd8fd7562a21ee111607e523962..fbaea481feccfc71d744d9f93de3bf637fdcaaad 100644 ---- a/src/main/java/org/bukkit/entity/Player.java -+++ b/src/main/java/org/bukkit/entity/Player.java -@@ -343,7 +343,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - * (updated) previous ban - */ - @Nullable -- public BanEntry ban(@Nullable String reason, @Nullable Date expires, @Nullable String source, boolean kickPlayer); -+ public > E ban(@Nullable String reason, @Nullable Date expires, @Nullable String source, boolean kickPlayer); // Paper - fix ban list API - - /** - * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -359,7 +359,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - * (updated) previous ban - */ - @Nullable -- public BanEntry ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source, boolean kickPlayer); -+ public > E ban(@Nullable String reason, @Nullable Instant expires, @Nullable String source, boolean kickPlayer); // Paper - fix ban list API - - /** - * Adds this user to the {@link ProfileBanList}. If a previous ban exists, this will -@@ -375,7 +375,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - * (updated) previous ban - */ - @Nullable -- public BanEntry ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source, boolean kickPlayer); -+ public > E ban(@Nullable String reason, @Nullable Duration duration, @Nullable String source, boolean kickPlayer); // Paper - fix ban list API - - /** - * Adds this user's current IP address to the {@link IpBanList}. If a previous ban exists, this will diff --git a/patches/api/0403-API-for-updating-recipes-on-clients.patch b/patches/api/0403-API-for-updating-recipes-on-clients.patch new file mode 100644 index 0000000000..a3b3f4bb59 --- /dev/null +++ b/patches/api/0403-API-for-updating-recipes-on-clients.patch @@ -0,0 +1,169 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 21 Aug 2021 17:25:54 -0700 +Subject: [PATCH] API for updating recipes on clients + + +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index 53e86d17867e5c2eae2db6a10bfbed788019a1ad..89b797c3468f401a208ef2351ba9f91b234455fd 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -990,6 +990,26 @@ public final class Bukkit { + server.reloadData(); + } + ++ // Paper start - update reloadable data ++ /** ++ * Updates all advancement, tag, and recipe data for all connected clients. ++ * Useful for updating clients to new advancements/recipes/tags. ++ * @see #updateRecipes() ++ */ ++ public static void updateResources() { ++ server.updateResources(); ++ } ++ ++ /** ++ * Updates recipe data and the recipe book for all connected clients. Useful for ++ * updating clients to new recipes. ++ * @see #updateResources() ++ */ ++ public static void updateRecipes() { ++ server.updateRecipes(); ++ } ++ // Paper end - update reloadable data ++ + /** + * Returns the primary logger associated with this server instance. + * +@@ -1050,6 +1070,20 @@ public final class Bukkit { + return server.addRecipe(recipe); + } + ++ // Paper start - method to send recipes immediately ++ /** ++ * Adds a recipe to the crafting manager. ++ * ++ * @param recipe the recipe to add ++ * @param resendRecipes true to update the client with the full set of recipes ++ * @return true if the recipe was added, false if it wasn't for some reason ++ */ ++ @Contract("null, _ -> false") ++ public static boolean addRecipe(@Nullable Recipe recipe, boolean resendRecipes) { ++ return server.addRecipe(recipe, resendRecipes); ++ } ++ // Paper end - method to send recipes immediately ++ + /** + * Get a list of all recipes for a given item. The stack size is ignored + * in comparisons. If the durability is -1, it will match any data value. +@@ -1241,6 +1275,24 @@ public final class Bukkit { + return server.removeRecipe(key); + } + ++ // Paper start - method to resend recipes ++ /** ++ * Remove a recipe from the server. ++ *

++ * Note that removing a recipe may cause permanent loss of data ++ * associated with that recipe (eg whether it has been discovered by ++ * players). ++ * ++ * @param key NamespacedKey of recipe to remove. ++ * @param resendRecipes true to update all clients on the new recipe list. ++ * Will only update if a recipe was actually removed ++ * @return True if recipe was removed ++ */ ++ public static boolean removeRecipe(@NotNull NamespacedKey key, boolean resendRecipes) { ++ return server.removeRecipe(key, resendRecipes); ++ } ++ // Paper end - method to resend recipes ++ + /** + * Gets a list of command aliases defined in the server properties. + * +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index e9773ebcc76fb637ed19dce203ae0dfe226b0066..f834dd696d3a40af72ab03f4bd03a784ff5ef23e 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -839,6 +839,22 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + */ + public void reloadData(); + ++ // Paper start - update reloadable data ++ /** ++ * Updates all advancement, tag, and recipe data to all connected clients. ++ * Useful for updating clients to new advancements/recipes/tags. ++ * @see #updateRecipes() ++ */ ++ void updateResources(); ++ ++ /** ++ * Updates recipe data and the recipe book to each player. Useful for ++ * updating clients to new recipes. ++ * @see #updateResources() ++ */ ++ void updateRecipes(); ++ // Paper end - update reloadable data ++ + /** + * Returns the primary logger associated with this server instance. + * +@@ -880,15 +896,34 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + public boolean dispatchCommand(@NotNull CommandSender sender, @NotNull String commandLine) throws CommandException; + + /** +- * Adds a recipe to the crafting manager. ++ * Adds a recipe to the crafting manager. Recipes added with ++ * this method won't be sent to the client automatically. Use ++ * {@link #updateRecipes()} or {@link #updateResources()} to ++ * update clients to new recipes added. ++ *

++ * Player's still have to discover recipes via {@link Player#discoverRecipe(NamespacedKey)} ++ * before seeing them in their recipe book. + * + * @param recipe the recipe to add + * @return true if the recipe was added, false if it wasn't for some + * reason ++ * @see #addRecipe(Recipe, boolean) + */ + @Contract("null -> false") + public boolean addRecipe(@Nullable Recipe recipe); + ++ // Paper start - method to send recipes immediately ++ /** ++ * Adds a recipe to the crafting manager. ++ * ++ * @param recipe the recipe to add ++ * @param resendRecipes true to update the client with the full set of recipes ++ * @return true if the recipe was added, false if it wasn't for some reason ++ */ ++ @Contract("null, _ -> false") ++ boolean addRecipe(@Nullable Recipe recipe, boolean resendRecipes); ++ // Paper end - method to send recipes immediately ++ + /** + * Get a list of all recipes for a given item. The stack size is ignored + * in comparisons. If the durability is -1, it will match any data value. +@@ -1057,6 +1092,22 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + */ + public boolean removeRecipe(@NotNull NamespacedKey key); + ++ // Paper start - method to resend recipes ++ /** ++ * Remove a recipe from the server. ++ *

++ * Note that removing a recipe may cause permanent loss of data ++ * associated with that recipe (eg whether it has been discovered by ++ * players). ++ * ++ * @param key NamespacedKey of recipe to remove. ++ * @param resendRecipes true to update all clients on the new recipe list. ++ * Will only update if a recipe was actually removed ++ * @return True if recipe was removed ++ */ ++ boolean removeRecipe(@NotNull NamespacedKey key, boolean resendRecipes); ++ // Paper end - method to resend recipes ++ + /** + * Gets a list of command aliases defined in the server properties. + * diff --git a/patches/api/0403-Add-whitelist-events.patch b/patches/api/0403-Add-whitelist-events.patch deleted file mode 100644 index 75458e78df..0000000000 --- a/patches/api/0403-Add-whitelist-events.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: SageSphinx63920 -Date: Sun, 14 May 2023 12:56:15 +0200 -Subject: [PATCH] Add whitelist events - - -diff --git a/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java b/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2f4273d694278517e2613f0da5e89c73ccc8779f ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/server/WhitelistStateUpdateEvent.java -@@ -0,0 +1,87 @@ -+package io.papermc.paper.event.server; -+ -+import com.destroystokyo.paper.profile.PlayerProfile; -+import org.bukkit.Bukkit; -+import org.bukkit.OfflinePlayer; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.Event; -+import org.bukkit.event.HandlerList; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * This event gets called when the whitelist status of a player is changed -+ */ -+public class WhitelistStateUpdateEvent extends Event implements Cancellable { -+ -+ private static final HandlerList HANDLER_LIST = new HandlerList(); -+ -+ @NotNull private final PlayerProfile playerProfile; -+ @NotNull private final WhitelistStatus status; -+ -+ private boolean cancelled; -+ -+ @ApiStatus.Internal -+ public WhitelistStateUpdateEvent(@NotNull PlayerProfile playerProfile, @NotNull WhitelistStatus status) { -+ this.playerProfile = playerProfile; -+ this.status = status; -+ } -+ -+ /** -+ * Gets the player whose whitelist status is being changed -+ * -+ * @return the player whose status is being changed -+ */ -+ @NotNull -+ public OfflinePlayer getPlayer() { -+ return Bukkit.getOfflinePlayer(this.playerProfile.getId()); -+ } -+ -+ /** -+ * Gets the player profile whose whitelist status is being changed -+ * -+ * @return the player profile whose status is being changed -+ */ -+ @NotNull -+ public PlayerProfile getPlayerProfile() { -+ return this.playerProfile; -+ } -+ -+ /** -+ * Gets the status change of the player profile -+ * -+ * @return the whitelist status -+ */ -+ @NotNull -+ public WhitelistStatus getStatus() { -+ return this.status; -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return this.cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ this.cancelled = cancel; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return HANDLER_LIST; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return HANDLER_LIST; -+ } -+ -+ /** -+ * Enum for the whitelist status changes -+ */ -+ public enum WhitelistStatus { -+ ADDED, REMOVED -+ } -+} diff --git a/patches/api/0404-API-for-updating-recipes-on-clients.patch b/patches/api/0404-API-for-updating-recipes-on-clients.patch deleted file mode 100644 index a3b3f4bb59..0000000000 --- a/patches/api/0404-API-for-updating-recipes-on-clients.patch +++ /dev/null @@ -1,169 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 21 Aug 2021 17:25:54 -0700 -Subject: [PATCH] API for updating recipes on clients - - -diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 53e86d17867e5c2eae2db6a10bfbed788019a1ad..89b797c3468f401a208ef2351ba9f91b234455fd 100644 ---- a/src/main/java/org/bukkit/Bukkit.java -+++ b/src/main/java/org/bukkit/Bukkit.java -@@ -990,6 +990,26 @@ public final class Bukkit { - server.reloadData(); - } - -+ // Paper start - update reloadable data -+ /** -+ * Updates all advancement, tag, and recipe data for all connected clients. -+ * Useful for updating clients to new advancements/recipes/tags. -+ * @see #updateRecipes() -+ */ -+ public static void updateResources() { -+ server.updateResources(); -+ } -+ -+ /** -+ * Updates recipe data and the recipe book for all connected clients. Useful for -+ * updating clients to new recipes. -+ * @see #updateResources() -+ */ -+ public static void updateRecipes() { -+ server.updateRecipes(); -+ } -+ // Paper end - update reloadable data -+ - /** - * Returns the primary logger associated with this server instance. - * -@@ -1050,6 +1070,20 @@ public final class Bukkit { - return server.addRecipe(recipe); - } - -+ // Paper start - method to send recipes immediately -+ /** -+ * Adds a recipe to the crafting manager. -+ * -+ * @param recipe the recipe to add -+ * @param resendRecipes true to update the client with the full set of recipes -+ * @return true if the recipe was added, false if it wasn't for some reason -+ */ -+ @Contract("null, _ -> false") -+ public static boolean addRecipe(@Nullable Recipe recipe, boolean resendRecipes) { -+ return server.addRecipe(recipe, resendRecipes); -+ } -+ // Paper end - method to send recipes immediately -+ - /** - * Get a list of all recipes for a given item. The stack size is ignored - * in comparisons. If the durability is -1, it will match any data value. -@@ -1241,6 +1275,24 @@ public final class Bukkit { - return server.removeRecipe(key); - } - -+ // Paper start - method to resend recipes -+ /** -+ * Remove a recipe from the server. -+ *

-+ * Note that removing a recipe may cause permanent loss of data -+ * associated with that recipe (eg whether it has been discovered by -+ * players). -+ * -+ * @param key NamespacedKey of recipe to remove. -+ * @param resendRecipes true to update all clients on the new recipe list. -+ * Will only update if a recipe was actually removed -+ * @return True if recipe was removed -+ */ -+ public static boolean removeRecipe(@NotNull NamespacedKey key, boolean resendRecipes) { -+ return server.removeRecipe(key, resendRecipes); -+ } -+ // Paper end - method to resend recipes -+ - /** - * Gets a list of command aliases defined in the server properties. - * -diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index e9773ebcc76fb637ed19dce203ae0dfe226b0066..f834dd696d3a40af72ab03f4bd03a784ff5ef23e 100644 ---- a/src/main/java/org/bukkit/Server.java -+++ b/src/main/java/org/bukkit/Server.java -@@ -839,6 +839,22 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - */ - public void reloadData(); - -+ // Paper start - update reloadable data -+ /** -+ * Updates all advancement, tag, and recipe data to all connected clients. -+ * Useful for updating clients to new advancements/recipes/tags. -+ * @see #updateRecipes() -+ */ -+ void updateResources(); -+ -+ /** -+ * Updates recipe data and the recipe book to each player. Useful for -+ * updating clients to new recipes. -+ * @see #updateResources() -+ */ -+ void updateRecipes(); -+ // Paper end - update reloadable data -+ - /** - * Returns the primary logger associated with this server instance. - * -@@ -880,15 +896,34 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - public boolean dispatchCommand(@NotNull CommandSender sender, @NotNull String commandLine) throws CommandException; - - /** -- * Adds a recipe to the crafting manager. -+ * Adds a recipe to the crafting manager. Recipes added with -+ * this method won't be sent to the client automatically. Use -+ * {@link #updateRecipes()} or {@link #updateResources()} to -+ * update clients to new recipes added. -+ *

-+ * Player's still have to discover recipes via {@link Player#discoverRecipe(NamespacedKey)} -+ * before seeing them in their recipe book. - * - * @param recipe the recipe to add - * @return true if the recipe was added, false if it wasn't for some - * reason -+ * @see #addRecipe(Recipe, boolean) - */ - @Contract("null -> false") - public boolean addRecipe(@Nullable Recipe recipe); - -+ // Paper start - method to send recipes immediately -+ /** -+ * Adds a recipe to the crafting manager. -+ * -+ * @param recipe the recipe to add -+ * @param resendRecipes true to update the client with the full set of recipes -+ * @return true if the recipe was added, false if it wasn't for some reason -+ */ -+ @Contract("null, _ -> false") -+ boolean addRecipe(@Nullable Recipe recipe, boolean resendRecipes); -+ // Paper end - method to send recipes immediately -+ - /** - * Get a list of all recipes for a given item. The stack size is ignored - * in comparisons. If the durability is -1, it will match any data value. -@@ -1057,6 +1092,22 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - */ - public boolean removeRecipe(@NotNull NamespacedKey key); - -+ // Paper start - method to resend recipes -+ /** -+ * Remove a recipe from the server. -+ *

-+ * Note that removing a recipe may cause permanent loss of data -+ * associated with that recipe (eg whether it has been discovered by -+ * players). -+ * -+ * @param key NamespacedKey of recipe to remove. -+ * @param resendRecipes true to update all clients on the new recipe list. -+ * Will only update if a recipe was actually removed -+ * @return True if recipe was removed -+ */ -+ boolean removeRecipe(@NotNull NamespacedKey key, boolean resendRecipes); -+ // Paper end - method to resend recipes -+ - /** - * Gets a list of command aliases defined in the server properties. - * diff --git a/patches/api/0404-Add-PlayerFailMoveEvent.patch b/patches/api/0404-Add-PlayerFailMoveEvent.patch new file mode 100644 index 0000000000..c0687e2ae0 --- /dev/null +++ b/patches/api/0404-Add-PlayerFailMoveEvent.patch @@ -0,0 +1,130 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Moulberry +Date: Wed, 26 Jul 2023 20:57:11 +0800 +Subject: [PATCH] Add PlayerFailMoveEvent + + +diff --git a/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc2596b90aed +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java +@@ -0,0 +1,118 @@ ++package io.papermc.paper.event.player; ++ ++import org.bukkit.Location; ++import org.bukkit.entity.Player; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Runs when a player attempts to move, but is prevented from doing so by the server ++ */ ++public class PlayerFailMoveEvent extends PlayerEvent { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private final FailReason failReason; ++ private final Location from; ++ private final Location to; ++ private boolean allowed; ++ private boolean logWarning; ++ ++ @ApiStatus.Internal ++ public PlayerFailMoveEvent(@NotNull Player player, @NotNull FailReason failReason, boolean allowed, ++ boolean logWarning, @NotNull Location from, @NotNull Location to) { ++ super(player); ++ this.failReason = failReason; ++ this.allowed = allowed; ++ this.logWarning = logWarning; ++ this.from = from; ++ this.to = to; ++ } ++ ++ /** ++ * Gets the reason this movement was prevented by the server ++ * ++ * @return The reason the movement was prevented ++ */ ++ @NotNull ++ public FailReason getFailReason() { ++ return this.failReason; ++ } ++ ++ /** ++ * Gets the location this player moved from ++ * ++ * @return Location the player moved from ++ */ ++ @NotNull ++ public Location getFrom() { ++ return this.from.clone(); ++ } ++ ++ /** ++ * Gets the location this player tried to move to ++ * ++ * @return Location the player tried to move to ++ */ ++ @NotNull ++ public Location getTo() { ++ return this.to.clone(); ++ } ++ ++ /** ++ * Gets if the check should be bypassed, allowing the movement ++ * ++ * @return whether to bypass the check ++ */ ++ public boolean isAllowed() { ++ return this.allowed; ++ } ++ ++ /** ++ * Set if the check should be bypassed and the movement should be allowed ++ * ++ * @param allowed whether to bypass the check ++ */ ++ public void setAllowed(boolean allowed) { ++ this.allowed = allowed; ++ } ++ ++ /** ++ * Gets if warnings will be printed to console. e.g. "Player123 moved too quickly!" ++ * ++ * @return whether to log warnings ++ */ ++ public boolean getLogWarning() { ++ return this.logWarning; ++ } ++ ++ /** ++ * Set if a warning is printed to console. e.g. "Player123 moved too quickly!" ++ * ++ * @param logWarning whether to log warnings ++ */ ++ public void setLogWarning(boolean logWarning) { ++ this.logWarning = logWarning; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++ ++ public enum FailReason { ++ MOVED_INTO_UNLOADED_CHUNK, // Only fired if the world setting prevent-moving-into-unloaded-chunks is true ++ MOVED_TOO_QUICKLY, ++ MOVED_WRONGLY, ++ CLIPPED_INTO_BLOCK ++ } ++ ++} diff --git a/patches/api/0405-Add-PlayerFailMoveEvent.patch b/patches/api/0405-Add-PlayerFailMoveEvent.patch deleted file mode 100644 index c0687e2ae0..0000000000 --- a/patches/api/0405-Add-PlayerFailMoveEvent.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Moulberry -Date: Wed, 26 Jul 2023 20:57:11 +0800 -Subject: [PATCH] Add PlayerFailMoveEvent - - -diff --git a/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c848fa029bac07f80eef870c98eebc2596b90aed ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/player/PlayerFailMoveEvent.java -@@ -0,0 +1,118 @@ -+package io.papermc.paper.event.player; -+ -+import org.bukkit.Location; -+import org.bukkit.entity.Player; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.player.PlayerEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Runs when a player attempts to move, but is prevented from doing so by the server -+ */ -+public class PlayerFailMoveEvent extends PlayerEvent { -+ -+ private static final HandlerList HANDLER_LIST = new HandlerList(); -+ -+ private final FailReason failReason; -+ private final Location from; -+ private final Location to; -+ private boolean allowed; -+ private boolean logWarning; -+ -+ @ApiStatus.Internal -+ public PlayerFailMoveEvent(@NotNull Player player, @NotNull FailReason failReason, boolean allowed, -+ boolean logWarning, @NotNull Location from, @NotNull Location to) { -+ super(player); -+ this.failReason = failReason; -+ this.allowed = allowed; -+ this.logWarning = logWarning; -+ this.from = from; -+ this.to = to; -+ } -+ -+ /** -+ * Gets the reason this movement was prevented by the server -+ * -+ * @return The reason the movement was prevented -+ */ -+ @NotNull -+ public FailReason getFailReason() { -+ return this.failReason; -+ } -+ -+ /** -+ * Gets the location this player moved from -+ * -+ * @return Location the player moved from -+ */ -+ @NotNull -+ public Location getFrom() { -+ return this.from.clone(); -+ } -+ -+ /** -+ * Gets the location this player tried to move to -+ * -+ * @return Location the player tried to move to -+ */ -+ @NotNull -+ public Location getTo() { -+ return this.to.clone(); -+ } -+ -+ /** -+ * Gets if the check should be bypassed, allowing the movement -+ * -+ * @return whether to bypass the check -+ */ -+ public boolean isAllowed() { -+ return this.allowed; -+ } -+ -+ /** -+ * Set if the check should be bypassed and the movement should be allowed -+ * -+ * @param allowed whether to bypass the check -+ */ -+ public void setAllowed(boolean allowed) { -+ this.allowed = allowed; -+ } -+ -+ /** -+ * Gets if warnings will be printed to console. e.g. "Player123 moved too quickly!" -+ * -+ * @return whether to log warnings -+ */ -+ public boolean getLogWarning() { -+ return this.logWarning; -+ } -+ -+ /** -+ * Set if a warning is printed to console. e.g. "Player123 moved too quickly!" -+ * -+ * @param logWarning whether to log warnings -+ */ -+ public void setLogWarning(boolean logWarning) { -+ this.logWarning = logWarning; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return HANDLER_LIST; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return HANDLER_LIST; -+ } -+ -+ public enum FailReason { -+ MOVED_INTO_UNLOADED_CHUNK, // Only fired if the world setting prevent-moving-into-unloaded-chunks is true -+ MOVED_TOO_QUICKLY, -+ MOVED_WRONGLY, -+ CLIPPED_INTO_BLOCK -+ } -+ -+} diff --git a/patches/api/0405-Fix-custom-statistic-criteria-creation.patch b/patches/api/0405-Fix-custom-statistic-criteria-creation.patch new file mode 100644 index 0000000000..f4070d7bb4 --- /dev/null +++ b/patches/api/0405-Fix-custom-statistic-criteria-creation.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Noah van der Aa +Date: Sat, 12 Aug 2023 15:33:55 +0200 +Subject: [PATCH] Fix custom statistic criteria creation + + +diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java +index dad90b98413b57a878f940b8f423bd77e36fd179..f261bd5971003e542e4806c1a989add8e0143466 100644 +--- a/src/main/java/org/bukkit/UnsafeValues.java ++++ b/src/main/java/org/bukkit/UnsafeValues.java +@@ -250,4 +250,6 @@ public interface UnsafeValues { + */ + void setBiomeKey(RegionAccessor accessor, int x, int y, int z, NamespacedKey biomeKey); + // Paper end - namespaced key biome methods ++ ++ String getStatisticCriteriaKey(@NotNull org.bukkit.Statistic statistic); // Paper - fix custom stats criteria creation + } +diff --git a/src/main/java/org/bukkit/scoreboard/Criteria.java b/src/main/java/org/bukkit/scoreboard/Criteria.java +index 7d79d7fadab19bfbefc4797d7e5bbd3e9d733b53..3bc3abaf093d13e22b6ac2ee59ab584c92b4666a 100644 +--- a/src/main/java/org/bukkit/scoreboard/Criteria.java ++++ b/src/main/java/org/bukkit/scoreboard/Criteria.java +@@ -335,7 +335,7 @@ public interface Criteria { + @NotNull + public static Criteria statistic(@NotNull Statistic statistic) { + Preconditions.checkArgument(statistic != null, "statistic must not be null"); +- return Bukkit.getScoreboardCriteria("minecraft.custom:minecraft." + statistic.getKey().getKey()); ++ return Bukkit.getScoreboardCriteria(org.bukkit.Bukkit.getUnsafe().getStatisticCriteriaKey(statistic)); // Paper + } + + /** diff --git a/patches/api/0406-Fix-custom-statistic-criteria-creation.patch b/patches/api/0406-Fix-custom-statistic-criteria-creation.patch deleted file mode 100644 index f4070d7bb4..0000000000 --- a/patches/api/0406-Fix-custom-statistic-criteria-creation.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Noah van der Aa -Date: Sat, 12 Aug 2023 15:33:55 +0200 -Subject: [PATCH] Fix custom statistic criteria creation - - -diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index dad90b98413b57a878f940b8f423bd77e36fd179..f261bd5971003e542e4806c1a989add8e0143466 100644 ---- a/src/main/java/org/bukkit/UnsafeValues.java -+++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -250,4 +250,6 @@ public interface UnsafeValues { - */ - void setBiomeKey(RegionAccessor accessor, int x, int y, int z, NamespacedKey biomeKey); - // Paper end - namespaced key biome methods -+ -+ String getStatisticCriteriaKey(@NotNull org.bukkit.Statistic statistic); // Paper - fix custom stats criteria creation - } -diff --git a/src/main/java/org/bukkit/scoreboard/Criteria.java b/src/main/java/org/bukkit/scoreboard/Criteria.java -index 7d79d7fadab19bfbefc4797d7e5bbd3e9d733b53..3bc3abaf093d13e22b6ac2ee59ab584c92b4666a 100644 ---- a/src/main/java/org/bukkit/scoreboard/Criteria.java -+++ b/src/main/java/org/bukkit/scoreboard/Criteria.java -@@ -335,7 +335,7 @@ public interface Criteria { - @NotNull - public static Criteria statistic(@NotNull Statistic statistic) { - Preconditions.checkArgument(statistic != null, "statistic must not be null"); -- return Bukkit.getScoreboardCriteria("minecraft.custom:minecraft." + statistic.getKey().getKey()); -+ return Bukkit.getScoreboardCriteria(org.bukkit.Bukkit.getUnsafe().getStatisticCriteriaKey(statistic)); // Paper - } - - /** diff --git a/patches/api/0406-SculkCatalyst-bloom-API.patch b/patches/api/0406-SculkCatalyst-bloom-API.patch new file mode 100644 index 0000000000..49d8c8c2bd --- /dev/null +++ b/patches/api/0406-SculkCatalyst-bloom-API.patch @@ -0,0 +1,25 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Oliwier Miodun +Date: Mon, 10 Jul 2023 17:59:42 +0200 +Subject: [PATCH] SculkCatalyst bloom API + + +diff --git a/src/main/java/org/bukkit/block/SculkCatalyst.java b/src/main/java/org/bukkit/block/SculkCatalyst.java +index 46260df8938bb616dd0e26829a123a24736b0a70..7d53b24003d49c5d7623598e92a6b0603c5d3069 100644 +--- a/src/main/java/org/bukkit/block/SculkCatalyst.java ++++ b/src/main/java/org/bukkit/block/SculkCatalyst.java +@@ -24,4 +24,14 @@ public interface SculkCatalyst extends TileState { + * @param charges how much charge to spawn. + */ + void bloom(@NotNull Block block, int charges); ++ ++ // Paper start - SculkCatalyst bloom API ++ /** ++ * Bloom at the specified location as if an entity that drops experience just died there. ++ * ++ * @param position position to bloom at ++ * @param charge charge to bloom with, normally the amount of experience dropped from the dead entity ++ */ ++ void bloom(@org.jetbrains.annotations.NotNull io.papermc.paper.math.Position position, int charge); ++ // Paper end - SculkCatalyst bloom API + } diff --git a/patches/api/0407-API-for-an-entity-s-scoreboard-name.patch b/patches/api/0407-API-for-an-entity-s-scoreboard-name.patch new file mode 100644 index 0000000000..1fb9128be8 --- /dev/null +++ b/patches/api/0407-API-for-an-entity-s-scoreboard-name.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sun, 9 Jul 2023 11:54:54 -0700 +Subject: [PATCH] API for an entity's scoreboard name + +Was obtainable through different methods, but you had to use different +methods depending on the implementation of Entity you were working with. + +diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java +index 4580c7613fac4f1eeccc2be2d15497cec5868736..efd8108cee65e7b1a227ebb6c33f3c92eb4cea24 100644 +--- a/src/main/java/org/bukkit/entity/Entity.java ++++ b/src/main/java/org/bukkit/entity/Entity.java +@@ -1112,4 +1112,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent + */ + @NotNull io.papermc.paper.threadedregions.scheduler.EntityScheduler getScheduler(); + // Paper end - Folia schedulers ++ ++ // Paper start - entity scoreboard name ++ /** ++ * Gets the string name of the entity used to track it in {@link org.bukkit.scoreboard.Scoreboard Scoreboards}. ++ * ++ * @return the scoreboard entry name ++ * @see org.bukkit.scoreboard.Scoreboard#getScores(String) ++ * @see org.bukkit.scoreboard.Scoreboard#getEntries() ++ */ ++ @NotNull String getScoreboardEntryName(); ++ // Paper end - entity scoreboard name + } diff --git a/patches/api/0407-SculkCatalyst-bloom-API.patch b/patches/api/0407-SculkCatalyst-bloom-API.patch deleted file mode 100644 index 49d8c8c2bd..0000000000 --- a/patches/api/0407-SculkCatalyst-bloom-API.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Oliwier Miodun -Date: Mon, 10 Jul 2023 17:59:42 +0200 -Subject: [PATCH] SculkCatalyst bloom API - - -diff --git a/src/main/java/org/bukkit/block/SculkCatalyst.java b/src/main/java/org/bukkit/block/SculkCatalyst.java -index 46260df8938bb616dd0e26829a123a24736b0a70..7d53b24003d49c5d7623598e92a6b0603c5d3069 100644 ---- a/src/main/java/org/bukkit/block/SculkCatalyst.java -+++ b/src/main/java/org/bukkit/block/SculkCatalyst.java -@@ -24,4 +24,14 @@ public interface SculkCatalyst extends TileState { - * @param charges how much charge to spawn. - */ - void bloom(@NotNull Block block, int charges); -+ -+ // Paper start - SculkCatalyst bloom API -+ /** -+ * Bloom at the specified location as if an entity that drops experience just died there. -+ * -+ * @param position position to bloom at -+ * @param charge charge to bloom with, normally the amount of experience dropped from the dead entity -+ */ -+ void bloom(@org.jetbrains.annotations.NotNull io.papermc.paper.math.Position position, int charge); -+ // Paper end - SculkCatalyst bloom API - } diff --git a/patches/api/0408-API-for-an-entity-s-scoreboard-name.patch b/patches/api/0408-API-for-an-entity-s-scoreboard-name.patch deleted file mode 100644 index 1fb9128be8..0000000000 --- a/patches/api/0408-API-for-an-entity-s-scoreboard-name.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 9 Jul 2023 11:54:54 -0700 -Subject: [PATCH] API for an entity's scoreboard name - -Was obtainable through different methods, but you had to use different -methods depending on the implementation of Entity you were working with. - -diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java -index 4580c7613fac4f1eeccc2be2d15497cec5868736..efd8108cee65e7b1a227ebb6c33f3c92eb4cea24 100644 ---- a/src/main/java/org/bukkit/entity/Entity.java -+++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1112,4 +1112,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent - */ - @NotNull io.papermc.paper.threadedregions.scheduler.EntityScheduler getScheduler(); - // Paper end - Folia schedulers -+ -+ // Paper start - entity scoreboard name -+ /** -+ * Gets the string name of the entity used to track it in {@link org.bukkit.scoreboard.Scoreboard Scoreboards}. -+ * -+ * @return the scoreboard entry name -+ * @see org.bukkit.scoreboard.Scoreboard#getScores(String) -+ * @see org.bukkit.scoreboard.Scoreboard#getEntries() -+ */ -+ @NotNull String getScoreboardEntryName(); -+ // Paper end - entity scoreboard name - } diff --git a/patches/api/0408-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/api/0408-Deprecate-and-replace-methods-with-old-StructureType.patch new file mode 100644 index 0000000000..b1f1fc1cfc --- /dev/null +++ b/patches/api/0408-Deprecate-and-replace-methods-with-old-StructureType.patch @@ -0,0 +1,159 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 10 Dec 2022 17:52:45 -0800 +Subject: [PATCH] Deprecate and replace methods with old StructureType + + +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index 89b797c3468f401a208ef2351ba9f91b234455fd..50d6784c488041ce416845373efebce14321b1ec 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -935,9 +935,6 @@ public final class Bukkit { + /** + * Create a new explorer map targeting the closest nearby structure of a + * given {@link StructureType}. +- *
+- * This method uses implementation default values for radius and +- * findUnexplored (usually 100, true). + * + * @param world the world the map will belong to + * @param location the origin location to find the nearest structure +@@ -946,7 +943,9 @@ public final class Bukkit { + * + * @see World#locateNearestStructure(org.bukkit.Location, + * org.bukkit.StructureType, int, boolean) ++ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type)} + */ ++ @Deprecated // Paper + @NotNull + public static ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType) { + return server.createExplorerMap(world, location, structureType); +@@ -969,11 +968,54 @@ public final class Bukkit { + * + * @see World#locateNearestStructure(org.bukkit.Location, + * org.bukkit.StructureType, int, boolean) ++ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type, int, boolean)} + */ ++ @Deprecated // Paper + @NotNull + public static ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType, int radius, boolean findUnexplored) { + return server.createExplorerMap(world, location, structureType, radius, findUnexplored); + } ++ // Paper start ++ /** ++ * Create a new explorer map targeting the closest nearby structure of a ++ * given {@link org.bukkit.generator.structure.StructureType}. ++ *
++ * This method uses implementation default values for radius and ++ * findUnexplored (usually 100, true). ++ * ++ * @param world the world the map will belong to ++ * @param location the origin location to find the nearest structure ++ * @param structureType the type of structure to find ++ * @param mapIcon the map icon to use on the map ++ * @return a newly created item stack or null if it can't find a location ++ * ++ * @see World#locateNearestStructure(org.bukkit.Location, ++ * org.bukkit.generator.structure.StructureType, int, boolean) ++ */ ++ public static @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon) { ++ return server.createExplorerMap(world, location, structureType, mapIcon); ++ } ++ ++ /** ++ * Create a new explorer map targeting the closest nearby structure of a ++ * given {@link org.bukkit.generator.structure.StructureType}. ++ * ++ * @param world the world the map will belong to ++ * @param location the origin location to find the nearest structure ++ * @param structureType the type of structure to find ++ * @param mapIcon the map icon to use on the map ++ * @param radius radius to search, see World#locateNearestStructure for more ++ * information ++ * @param findUnexplored whether to find unexplored structures ++ * @return the newly created item stack or null if it can't find a location ++ * ++ * @see World#locateNearestStructure(org.bukkit.Location, ++ * org.bukkit.generator.structure.StructureType, int, boolean) ++ */ ++ public static @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon, int radius, boolean findUnexplored) { ++ return server.createExplorerMap(world, location, structureType, mapIcon, radius, findUnexplored); ++ } ++ // Paper end + + /** + * Reloads the server, refreshing settings and plugin information. +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index f834dd696d3a40af72ab03f4bd03a784ff5ef23e..23af0b4fa239de8926a36346f38224a00f85284e 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -803,16 +803,15 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + * + * @see World#locateNearestStructure(org.bukkit.Location, + * org.bukkit.StructureType, int, boolean) ++ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type)} + */ ++ @Deprecated // Paper + @NotNull + public ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType); + + /** + * Create a new explorer map targeting the closest nearby structure of a + * given {@link StructureType}. +- *
+- * This method uses implementation default values for radius and +- * findUnexplored (usually 100, true). + * + * @param world the world the map will belong to + * @param location the origin location to find the nearest structure +@@ -824,9 +823,50 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + * + * @see World#locateNearestStructure(org.bukkit.Location, + * org.bukkit.StructureType, int, boolean) ++ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type, int, boolean)} + */ ++ @Deprecated // Paper + @NotNull + public ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType, int radius, boolean findUnexplored); ++ // Paper start ++ /** ++ * Create a new explorer map targeting the closest nearby structure of a ++ * given {@link org.bukkit.generator.structure.StructureType}. ++ *
++ * This method uses implementation default values for radius and ++ * findUnexplored (usually 100, true). ++ * ++ * @param world the world the map will belong to ++ * @param location the origin location to find the nearest structure ++ * @param structureType the type of structure to find ++ * @param mapIcon the map icon to use on the map ++ * @return a newly created item stack or null if it can't find a location ++ * ++ * @see World#locateNearestStructure(org.bukkit.Location, ++ * org.bukkit.generator.structure.StructureType, int, boolean) ++ */ ++ default @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon) { ++ return this.createExplorerMap(world, location, structureType, mapIcon, 100, true); ++ } ++ ++ /** ++ * Create a new explorer map targeting the closest nearby structure of a ++ * given {@link org.bukkit.generator.structure.StructureType}. ++ * ++ * @param world the world the map will belong to ++ * @param location the origin location to find the nearest structure ++ * @param structureType the type of structure to find ++ * @param mapIcon the map icon to use on the map ++ * @param radius radius to search, see World#locateNearestStructure for more ++ * information ++ * @param findUnexplored whether to find unexplored structures ++ * @return the newly created item stack or null if it can't find a location ++ * ++ * @see World#locateNearestStructure(org.bukkit.Location, ++ * org.bukkit.generator.structure.StructureType, int, boolean) ++ */ ++ @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon, int radius, boolean findUnexplored); ++ // Paper end + + /** + * Reloads the server, refreshing settings and plugin information. diff --git a/patches/api/0409-Add-Listing-API-for-Player.patch b/patches/api/0409-Add-Listing-API-for-Player.patch new file mode 100644 index 0000000000..47a8946b80 --- /dev/null +++ b/patches/api/0409-Add-Listing-API-for-Player.patch @@ -0,0 +1,43 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Corey Shupe +Date: Wed, 11 Jan 2023 16:40:31 -0500 +Subject: [PATCH] Add Listing API for Player + + +diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java +index fbaea481feccfc71d744d9f93de3bf637fdcaaad..24dc710f61d08253f66e7ecfd69873e7ebf68d1b 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -2038,6 +2038,32 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + */ + public boolean canSee(@NotNull Entity entity); + ++ // Paper start ++ /** ++ * Returns whether the {@code other} player is listed for {@code this}. ++ * ++ * @param other The other {@link Player} to check for listing. ++ * @return True if the {@code other} player is listed for {@code this}. ++ */ ++ boolean isListed(@NotNull Player other); ++ ++ /** ++ * Unlists the {@code other} player from the tablist. ++ * ++ * @param other The other {@link Player} to de-list. ++ * @return True if the {@code other} player was listed. ++ */ ++ boolean unlistPlayer(@NotNull Player other); ++ ++ /** ++ * Lists the {@code other} player. ++ * ++ * @param other The other {@link Player} to list. ++ * @return True if the {@code other} player was not listed. ++ */ ++ boolean listPlayer(@NotNull Player other); ++ // Paper end ++ + /** + * Checks to see if this player is currently flying or not. + * diff --git a/patches/api/0409-Deprecate-and-replace-methods-with-old-StructureType.patch b/patches/api/0409-Deprecate-and-replace-methods-with-old-StructureType.patch deleted file mode 100644 index b1f1fc1cfc..0000000000 --- a/patches/api/0409-Deprecate-and-replace-methods-with-old-StructureType.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 10 Dec 2022 17:52:45 -0800 -Subject: [PATCH] Deprecate and replace methods with old StructureType - - -diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 89b797c3468f401a208ef2351ba9f91b234455fd..50d6784c488041ce416845373efebce14321b1ec 100644 ---- a/src/main/java/org/bukkit/Bukkit.java -+++ b/src/main/java/org/bukkit/Bukkit.java -@@ -935,9 +935,6 @@ public final class Bukkit { - /** - * Create a new explorer map targeting the closest nearby structure of a - * given {@link StructureType}. -- *
-- * This method uses implementation default values for radius and -- * findUnexplored (usually 100, true). - * - * @param world the world the map will belong to - * @param location the origin location to find the nearest structure -@@ -946,7 +943,9 @@ public final class Bukkit { - * - * @see World#locateNearestStructure(org.bukkit.Location, - * org.bukkit.StructureType, int, boolean) -+ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type)} - */ -+ @Deprecated // Paper - @NotNull - public static ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType) { - return server.createExplorerMap(world, location, structureType); -@@ -969,11 +968,54 @@ public final class Bukkit { - * - * @see World#locateNearestStructure(org.bukkit.Location, - * org.bukkit.StructureType, int, boolean) -+ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type, int, boolean)} - */ -+ @Deprecated // Paper - @NotNull - public static ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType, int radius, boolean findUnexplored) { - return server.createExplorerMap(world, location, structureType, radius, findUnexplored); - } -+ // Paper start -+ /** -+ * Create a new explorer map targeting the closest nearby structure of a -+ * given {@link org.bukkit.generator.structure.StructureType}. -+ *
-+ * This method uses implementation default values for radius and -+ * findUnexplored (usually 100, true). -+ * -+ * @param world the world the map will belong to -+ * @param location the origin location to find the nearest structure -+ * @param structureType the type of structure to find -+ * @param mapIcon the map icon to use on the map -+ * @return a newly created item stack or null if it can't find a location -+ * -+ * @see World#locateNearestStructure(org.bukkit.Location, -+ * org.bukkit.generator.structure.StructureType, int, boolean) -+ */ -+ public static @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon) { -+ return server.createExplorerMap(world, location, structureType, mapIcon); -+ } -+ -+ /** -+ * Create a new explorer map targeting the closest nearby structure of a -+ * given {@link org.bukkit.generator.structure.StructureType}. -+ * -+ * @param world the world the map will belong to -+ * @param location the origin location to find the nearest structure -+ * @param structureType the type of structure to find -+ * @param mapIcon the map icon to use on the map -+ * @param radius radius to search, see World#locateNearestStructure for more -+ * information -+ * @param findUnexplored whether to find unexplored structures -+ * @return the newly created item stack or null if it can't find a location -+ * -+ * @see World#locateNearestStructure(org.bukkit.Location, -+ * org.bukkit.generator.structure.StructureType, int, boolean) -+ */ -+ public static @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon, int radius, boolean findUnexplored) { -+ return server.createExplorerMap(world, location, structureType, mapIcon, radius, findUnexplored); -+ } -+ // Paper end - - /** - * Reloads the server, refreshing settings and plugin information. -diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index f834dd696d3a40af72ab03f4bd03a784ff5ef23e..23af0b4fa239de8926a36346f38224a00f85284e 100644 ---- a/src/main/java/org/bukkit/Server.java -+++ b/src/main/java/org/bukkit/Server.java -@@ -803,16 +803,15 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - * - * @see World#locateNearestStructure(org.bukkit.Location, - * org.bukkit.StructureType, int, boolean) -+ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type)} - */ -+ @Deprecated // Paper - @NotNull - public ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType); - - /** - * Create a new explorer map targeting the closest nearby structure of a - * given {@link StructureType}. -- *
-- * This method uses implementation default values for radius and -- * findUnexplored (usually 100, true). - * - * @param world the world the map will belong to - * @param location the origin location to find the nearest structure -@@ -824,9 +823,50 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - * - * @see World#locateNearestStructure(org.bukkit.Location, - * org.bukkit.StructureType, int, boolean) -+ * @deprecated use {@link #createExplorerMap(World, Location, org.bukkit.generator.structure.StructureType, org.bukkit.map.MapCursor.Type, int, boolean)} - */ -+ @Deprecated // Paper - @NotNull - public ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull StructureType structureType, int radius, boolean findUnexplored); -+ // Paper start -+ /** -+ * Create a new explorer map targeting the closest nearby structure of a -+ * given {@link org.bukkit.generator.structure.StructureType}. -+ *
-+ * This method uses implementation default values for radius and -+ * findUnexplored (usually 100, true). -+ * -+ * @param world the world the map will belong to -+ * @param location the origin location to find the nearest structure -+ * @param structureType the type of structure to find -+ * @param mapIcon the map icon to use on the map -+ * @return a newly created item stack or null if it can't find a location -+ * -+ * @see World#locateNearestStructure(org.bukkit.Location, -+ * org.bukkit.generator.structure.StructureType, int, boolean) -+ */ -+ default @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon) { -+ return this.createExplorerMap(world, location, structureType, mapIcon, 100, true); -+ } -+ -+ /** -+ * Create a new explorer map targeting the closest nearby structure of a -+ * given {@link org.bukkit.generator.structure.StructureType}. -+ * -+ * @param world the world the map will belong to -+ * @param location the origin location to find the nearest structure -+ * @param structureType the type of structure to find -+ * @param mapIcon the map icon to use on the map -+ * @param radius radius to search, see World#locateNearestStructure for more -+ * information -+ * @param findUnexplored whether to find unexplored structures -+ * @return the newly created item stack or null if it can't find a location -+ * -+ * @see World#locateNearestStructure(org.bukkit.Location, -+ * org.bukkit.generator.structure.StructureType, int, boolean) -+ */ -+ @Nullable ItemStack createExplorerMap(@NotNull World world, @NotNull Location location, @NotNull org.bukkit.generator.structure.StructureType structureType, @NotNull org.bukkit.map.MapCursor.Type mapIcon, int radius, boolean findUnexplored); -+ // Paper end - - /** - * Reloads the server, refreshing settings and plugin information. diff --git a/patches/api/0410-Add-Listing-API-for-Player.patch b/patches/api/0410-Add-Listing-API-for-Player.patch deleted file mode 100644 index 47a8946b80..0000000000 --- a/patches/api/0410-Add-Listing-API-for-Player.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Corey Shupe -Date: Wed, 11 Jan 2023 16:40:31 -0500 -Subject: [PATCH] Add Listing API for Player - - -diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index fbaea481feccfc71d744d9f93de3bf637fdcaaad..24dc710f61d08253f66e7ecfd69873e7ebf68d1b 100644 ---- a/src/main/java/org/bukkit/entity/Player.java -+++ b/src/main/java/org/bukkit/entity/Player.java -@@ -2038,6 +2038,32 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - */ - public boolean canSee(@NotNull Entity entity); - -+ // Paper start -+ /** -+ * Returns whether the {@code other} player is listed for {@code this}. -+ * -+ * @param other The other {@link Player} to check for listing. -+ * @return True if the {@code other} player is listed for {@code this}. -+ */ -+ boolean isListed(@NotNull Player other); -+ -+ /** -+ * Unlists the {@code other} player from the tablist. -+ * -+ * @param other The other {@link Player} to de-list. -+ * @return True if the {@code other} player was listed. -+ */ -+ boolean unlistPlayer(@NotNull Player other); -+ -+ /** -+ * Lists the {@code other} player. -+ * -+ * @param other The other {@link Player} to list. -+ * @return True if the {@code other} player was not listed. -+ */ -+ boolean listPlayer(@NotNull Player other); -+ // Paper end -+ - /** - * Checks to see if this player is currently flying or not. - * diff --git a/patches/api/0410-Expose-clicked-BlockFace-during-BlockDamageEvent.patch b/patches/api/0410-Expose-clicked-BlockFace-during-BlockDamageEvent.patch new file mode 100644 index 0000000000..34d1940866 --- /dev/null +++ b/patches/api/0410-Expose-clicked-BlockFace-during-BlockDamageEvent.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: aerulion +Date: Mon, 21 Aug 2023 04:36:07 +0200 +Subject: [PATCH] Expose clicked BlockFace during BlockDamageEvent + + +diff --git a/src/main/java/org/bukkit/event/block/BlockDamageEvent.java b/src/main/java/org/bukkit/event/block/BlockDamageEvent.java +index cd04a0bd9d232857408b38605787016a217cb8d2..392cde07d578d684423e1bf369af28696eb7e484 100644 +--- a/src/main/java/org/bukkit/event/block/BlockDamageEvent.java ++++ b/src/main/java/org/bukkit/event/block/BlockDamageEvent.java +@@ -19,9 +19,20 @@ public class BlockDamageEvent extends BlockEvent implements Cancellable { + private boolean instaBreak; + private boolean cancel; + private final ItemStack itemstack; ++ private final org.bukkit.block.BlockFace blockFace; // Paper - Expose BlockFace + ++ // Paper start - expose blockface ++ @Deprecated(forRemoval = true) ++ @io.papermc.paper.annotation.DoNotUse + public BlockDamageEvent(@NotNull final Player player, @NotNull final Block block, @NotNull final ItemStack itemInHand, final boolean instaBreak) { ++ this(player, block, null, itemInHand, instaBreak); // Some plugin do bad things... ++ } ++ ++ @org.jetbrains.annotations.ApiStatus.Internal // Paper ++ public BlockDamageEvent(@NotNull final Player player, @NotNull final Block block, @NotNull final org.bukkit.block.BlockFace blockFace, @NotNull final ItemStack itemInHand, final boolean instaBreak) { // Paper - Expose BlockFace + super(block); ++ this.blockFace = blockFace; ++ // Paper end - expose blockface + this.instaBreak = instaBreak; + this.player = player; + this.itemstack = itemInHand; +@@ -67,6 +78,20 @@ public class BlockDamageEvent extends BlockEvent implements Cancellable { + public ItemStack getItemInHand() { + return itemstack; + } ++ // Paper start - Expose BlockFace ++ /** ++ * Gets the BlockFace the player is interacting with. ++ * ++ * @return The BlockFace clicked to damage the block ++ */ ++ @NotNull ++ public org.bukkit.block.BlockFace getBlockFace() { ++ if (this.blockFace == null) { ++ throw new IllegalStateException("BlockFace is not available for this event, most likely due to a bad constructor call by a plugin"); ++ } ++ return this.blockFace; ++ } ++ //Paper end + + @Override + public boolean isCancelled() { diff --git a/patches/api/0411-Expose-clicked-BlockFace-during-BlockDamageEvent.patch b/patches/api/0411-Expose-clicked-BlockFace-during-BlockDamageEvent.patch deleted file mode 100644 index 34d1940866..0000000000 --- a/patches/api/0411-Expose-clicked-BlockFace-during-BlockDamageEvent.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: aerulion -Date: Mon, 21 Aug 2023 04:36:07 +0200 -Subject: [PATCH] Expose clicked BlockFace during BlockDamageEvent - - -diff --git a/src/main/java/org/bukkit/event/block/BlockDamageEvent.java b/src/main/java/org/bukkit/event/block/BlockDamageEvent.java -index cd04a0bd9d232857408b38605787016a217cb8d2..392cde07d578d684423e1bf369af28696eb7e484 100644 ---- a/src/main/java/org/bukkit/event/block/BlockDamageEvent.java -+++ b/src/main/java/org/bukkit/event/block/BlockDamageEvent.java -@@ -19,9 +19,20 @@ public class BlockDamageEvent extends BlockEvent implements Cancellable { - private boolean instaBreak; - private boolean cancel; - private final ItemStack itemstack; -+ private final org.bukkit.block.BlockFace blockFace; // Paper - Expose BlockFace - -+ // Paper start - expose blockface -+ @Deprecated(forRemoval = true) -+ @io.papermc.paper.annotation.DoNotUse - public BlockDamageEvent(@NotNull final Player player, @NotNull final Block block, @NotNull final ItemStack itemInHand, final boolean instaBreak) { -+ this(player, block, null, itemInHand, instaBreak); // Some plugin do bad things... -+ } -+ -+ @org.jetbrains.annotations.ApiStatus.Internal // Paper -+ public BlockDamageEvent(@NotNull final Player player, @NotNull final Block block, @NotNull final org.bukkit.block.BlockFace blockFace, @NotNull final ItemStack itemInHand, final boolean instaBreak) { // Paper - Expose BlockFace - super(block); -+ this.blockFace = blockFace; -+ // Paper end - expose blockface - this.instaBreak = instaBreak; - this.player = player; - this.itemstack = itemInHand; -@@ -67,6 +78,20 @@ public class BlockDamageEvent extends BlockEvent implements Cancellable { - public ItemStack getItemInHand() { - return itemstack; - } -+ // Paper start - Expose BlockFace -+ /** -+ * Gets the BlockFace the player is interacting with. -+ * -+ * @return The BlockFace clicked to damage the block -+ */ -+ @NotNull -+ public org.bukkit.block.BlockFace getBlockFace() { -+ if (this.blockFace == null) { -+ throw new IllegalStateException("BlockFace is not available for this event, most likely due to a bad constructor call by a plugin"); -+ } -+ return this.blockFace; -+ } -+ //Paper end - - @Override - public boolean isCancelled() { diff --git a/patches/api/0411-Fix-NPE-on-Boat-getStatus.patch b/patches/api/0411-Fix-NPE-on-Boat-getStatus.patch new file mode 100644 index 0000000000..1cf6096a92 --- /dev/null +++ b/patches/api/0411-Fix-NPE-on-Boat-getStatus.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: LemonCaramel +Date: Tue, 11 Apr 2023 04:04:41 +0900 +Subject: [PATCH] Fix NPE on Boat getStatus + + +diff --git a/src/main/java/org/bukkit/entity/Boat.java b/src/main/java/org/bukkit/entity/Boat.java +index f7548098bcdd033d9c530fdc584fc5538c635ca1..2ac685fb1817f3ce06ebe6391cc863712d68367c 100644 +--- a/src/main/java/org/bukkit/entity/Boat.java ++++ b/src/main/java/org/bukkit/entity/Boat.java +@@ -169,6 +169,7 @@ public interface Boat extends Vehicle { + */ + public enum Status { + ++ NOT_IN_WORLD, // Paper + IN_WATER, + UNDER_WATER, + UNDER_FLOWING_WATER, diff --git a/patches/api/0412-Expand-Pose-API.patch b/patches/api/0412-Expand-Pose-API.patch new file mode 100644 index 0000000000..a7ac9f7567 --- /dev/null +++ b/patches/api/0412-Expand-Pose-API.patch @@ -0,0 +1,53 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SoSeDiK +Date: Wed, 11 Jan 2023 20:59:02 +0200 +Subject: [PATCH] Expand Pose API + + +diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java +index efd8108cee65e7b1a227ebb6c33f3c92eb4cea24..725ef320f929d5e3d141c1ed3246d73a7d741f31 100644 +--- a/src/main/java/org/bukkit/entity/Entity.java ++++ b/src/main/java/org/bukkit/entity/Entity.java +@@ -840,6 +840,42 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent + * @param sneak true if the entity should be sneaking + */ + void setSneaking(boolean sneak); ++ ++ /** ++ * Sets the entity's current {@link Pose}. ++ * ++ *

Note: While poses affect some things like hitboxes, they do not change the entity's state ++ * (e.g. having {@link Pose#SNEAKING} does not guarantee {@link #isSneaking()} being {@code true}). ++ * ++ *

If applied to the {@link Player}, they might see a different pose client-side. ++ * ++ * @param pose a new {@link Pose} ++ * @see #setPose(Pose, boolean) ++ */ ++ default void setPose(@NotNull Pose pose) { ++ setPose(pose, false); ++ } ++ ++ /** ++ * Sets the entity's current {@link Pose}. ++ * ++ *

Note: While poses affect some things like hitboxes, they do not change the entity's state ++ * (e.g. having {@link Pose#SNEAKING} does not guarantee {@link #isSneaking()} being {@code true}). ++ * ++ *

If applied to the {@link Player}, they might see a different pose client-side. ++ * ++ * @param pose a new {@link Pose} ++ * @param fixed whether the new {@link Pose} should stay until manually changed ++ */ ++ void setPose(@NotNull Pose pose, boolean fixed); ++ ++ /** ++ * Checks whether the entity has a fixed {@link Pose} ++ * ++ * @see #setPose(Pose, boolean) ++ * @return whether the entity has a fixed {@link Pose} ++ */ ++ boolean hasFixedPose(); + // Paper end + + /** diff --git a/patches/api/0412-Fix-NPE-on-Boat-getStatus.patch b/patches/api/0412-Fix-NPE-on-Boat-getStatus.patch deleted file mode 100644 index 1cf6096a92..0000000000 --- a/patches/api/0412-Fix-NPE-on-Boat-getStatus.patch +++ /dev/null @@ -1,18 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: LemonCaramel -Date: Tue, 11 Apr 2023 04:04:41 +0900 -Subject: [PATCH] Fix NPE on Boat getStatus - - -diff --git a/src/main/java/org/bukkit/entity/Boat.java b/src/main/java/org/bukkit/entity/Boat.java -index f7548098bcdd033d9c530fdc584fc5538c635ca1..2ac685fb1817f3ce06ebe6391cc863712d68367c 100644 ---- a/src/main/java/org/bukkit/entity/Boat.java -+++ b/src/main/java/org/bukkit/entity/Boat.java -@@ -169,6 +169,7 @@ public interface Boat extends Vehicle { - */ - public enum Status { - -+ NOT_IN_WORLD, // Paper - IN_WATER, - UNDER_WATER, - UNDER_FLOWING_WATER, diff --git a/patches/api/0413-Expand-Pose-API.patch b/patches/api/0413-Expand-Pose-API.patch deleted file mode 100644 index a7ac9f7567..0000000000 --- a/patches/api/0413-Expand-Pose-API.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: SoSeDiK -Date: Wed, 11 Jan 2023 20:59:02 +0200 -Subject: [PATCH] Expand Pose API - - -diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java -index efd8108cee65e7b1a227ebb6c33f3c92eb4cea24..725ef320f929d5e3d141c1ed3246d73a7d741f31 100644 ---- a/src/main/java/org/bukkit/entity/Entity.java -+++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -840,6 +840,42 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent - * @param sneak true if the entity should be sneaking - */ - void setSneaking(boolean sneak); -+ -+ /** -+ * Sets the entity's current {@link Pose}. -+ * -+ *

Note: While poses affect some things like hitboxes, they do not change the entity's state -+ * (e.g. having {@link Pose#SNEAKING} does not guarantee {@link #isSneaking()} being {@code true}). -+ * -+ *

If applied to the {@link Player}, they might see a different pose client-side. -+ * -+ * @param pose a new {@link Pose} -+ * @see #setPose(Pose, boolean) -+ */ -+ default void setPose(@NotNull Pose pose) { -+ setPose(pose, false); -+ } -+ -+ /** -+ * Sets the entity's current {@link Pose}. -+ * -+ *

Note: While poses affect some things like hitboxes, they do not change the entity's state -+ * (e.g. having {@link Pose#SNEAKING} does not guarantee {@link #isSneaking()} being {@code true}). -+ * -+ *

If applied to the {@link Player}, they might see a different pose client-side. -+ * -+ * @param pose a new {@link Pose} -+ * @param fixed whether the new {@link Pose} should stay until manually changed -+ */ -+ void setPose(@NotNull Pose pose, boolean fixed); -+ -+ /** -+ * Checks whether the entity has a fixed {@link Pose} -+ * -+ * @see #setPose(Pose, boolean) -+ * @return whether the entity has a fixed {@link Pose} -+ */ -+ boolean hasFixedPose(); - // Paper end - - /** diff --git a/patches/api/0413-MerchantRecipe-add-copy-constructor.patch b/patches/api/0413-MerchantRecipe-add-copy-constructor.patch new file mode 100644 index 0000000000..1c5ba2803c --- /dev/null +++ b/patches/api/0413-MerchantRecipe-add-copy-constructor.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Joo200 +Date: Tue, 20 Dec 2022 15:26:36 +0100 +Subject: [PATCH] MerchantRecipe: add copy constructor + + +diff --git a/src/main/java/org/bukkit/inventory/MerchantRecipe.java b/src/main/java/org/bukkit/inventory/MerchantRecipe.java +index afaa21b9347683fa373a938d9b1aa01c2058192a..39f9766a03d420340d79841197f75c8b1dd49f4a 100644 +--- a/src/main/java/org/bukkit/inventory/MerchantRecipe.java ++++ b/src/main/java/org/bukkit/inventory/MerchantRecipe.java +@@ -91,6 +91,13 @@ public class MerchantRecipe implements Recipe { + this.specialPrice = specialPrice; + } + ++ // Paper start - add copy ctor ++ public MerchantRecipe(@NotNull MerchantRecipe recipe) { ++ this(recipe.result.clone(), recipe.uses, recipe.maxUses, recipe.experienceReward, recipe.villagerExperience, recipe.priceMultiplier, recipe.demand, recipe.specialPrice, recipe.ignoreDiscounts); ++ this.setIngredients(recipe.ingredients); ++ } ++ // Paper end ++ + @NotNull + @Override + public ItemStack getResult() { diff --git a/patches/api/0414-MerchantRecipe-add-copy-constructor.patch b/patches/api/0414-MerchantRecipe-add-copy-constructor.patch deleted file mode 100644 index 1c5ba2803c..0000000000 --- a/patches/api/0414-MerchantRecipe-add-copy-constructor.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Joo200 -Date: Tue, 20 Dec 2022 15:26:36 +0100 -Subject: [PATCH] MerchantRecipe: add copy constructor - - -diff --git a/src/main/java/org/bukkit/inventory/MerchantRecipe.java b/src/main/java/org/bukkit/inventory/MerchantRecipe.java -index afaa21b9347683fa373a938d9b1aa01c2058192a..39f9766a03d420340d79841197f75c8b1dd49f4a 100644 ---- a/src/main/java/org/bukkit/inventory/MerchantRecipe.java -+++ b/src/main/java/org/bukkit/inventory/MerchantRecipe.java -@@ -91,6 +91,13 @@ public class MerchantRecipe implements Recipe { - this.specialPrice = specialPrice; - } - -+ // Paper start - add copy ctor -+ public MerchantRecipe(@NotNull MerchantRecipe recipe) { -+ this(recipe.result.clone(), recipe.uses, recipe.maxUses, recipe.experienceReward, recipe.villagerExperience, recipe.priceMultiplier, recipe.demand, recipe.specialPrice, recipe.ignoreDiscounts); -+ this.setIngredients(recipe.ingredients); -+ } -+ // Paper end -+ - @NotNull - @Override - public ItemStack getResult() { diff --git a/patches/api/0414-More-DragonBattle-API.patch b/patches/api/0414-More-DragonBattle-API.patch new file mode 100644 index 0000000000..e25208ec19 --- /dev/null +++ b/patches/api/0414-More-DragonBattle-API.patch @@ -0,0 +1,55 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sun, 18 Dec 2022 13:40:17 -0800 +Subject: [PATCH] More DragonBattle API + + +diff --git a/src/main/java/org/bukkit/boss/DragonBattle.java b/src/main/java/org/bukkit/boss/DragonBattle.java +index 6e5fc92243ee63c2a965f8a4905e29a7993588fd..5dbd12a786a66640ce80acafe2a42e35adef41eb 100644 +--- a/src/main/java/org/bukkit/boss/DragonBattle.java ++++ b/src/main/java/org/bukkit/boss/DragonBattle.java +@@ -145,4 +145,44 @@ public interface DragonBattle { + */ + NONE; + } ++ // Paper start ++ /** ++ * Gets the number of gateways tracked by this DragonBattle. ++ * This starts out at 0 and will increase to 20, once for each ++ * kill of the {@link EnderDragon}. ++ * ++ * @return the number of gateways around the end island tracked by this ++ */ ++ int getGatewayCount(); ++ ++ /** ++ * Tries to spawn a new end gateway using default game mechanics. ++ * ++ * @return true if successful, false if there is already the maximum. ++ */ ++ boolean spawnNewGateway(); ++ ++ /** ++ * Spawns a new end gateway at the specified position. This will ++ * spawn regardless of the number of gateways already present. ++ * ++ * @param position position for the new gateway ++ */ ++ void spawnNewGateway(@NotNull io.papermc.paper.math.Position position); ++ ++ /** ++ * Gets the {@link org.bukkit.entity.EnderCrystal}s being used to respawn the dragon. If no respawn ++ * is ongoing, the list will be empty. ++ * ++ * @return the respawn crystals ++ */ ++ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getRespawnCrystals(); ++ ++ /** ++ * Gets the {@link org.bukkit.entity.EnderCrystal}s on top of the pillars that heal the dragon. ++ * ++ * @return the healing crystals ++ */ ++ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getHealingCrystals(); ++ // Paper end + } diff --git a/patches/api/0415-Add-PlayerPickItemEvent.patch b/patches/api/0415-Add-PlayerPickItemEvent.patch new file mode 100644 index 0000000000..6dd0be80a8 --- /dev/null +++ b/patches/api/0415-Add-PlayerPickItemEvent.patch @@ -0,0 +1,108 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: RodneyMKay <36546810+RodneyMKay@users.noreply.github.com> +Date: Wed, 8 Sep 2021 22:15:43 +0200 +Subject: [PATCH] Add PlayerPickItemEvent + + +diff --git a/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad1533b7b0ca6 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java +@@ -0,0 +1,96 @@ ++package io.papermc.paper.event.player; ++ ++import com.google.common.base.Preconditions; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Range; ++ ++/** ++ * Event that is fired when a player uses the pick item functionality (middle-clicking a block to get the appropriate ++ * item). However, note that this event will only trigger if an item has to be moved from the inventory to the hotbar. ++ * After the handling of this event, the contents of the source and the target slot will be swapped and the currently ++ * selected hotbar slot of the player will be set to the target slot. ++ *

++ * Note: This event will not be fired for players in creative mode. ++ */ ++public class PlayerPickItemEvent extends PlayerEvent implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private int targetSlot; ++ private int sourceSlot; ++ ++ private boolean cancelled; ++ ++ @ApiStatus.Internal ++ public PlayerPickItemEvent(@NotNull Player player, int targetSlot, int sourceSlot) { ++ super(player); ++ this.targetSlot = targetSlot; ++ this.sourceSlot = sourceSlot; ++ } ++ ++ /** ++ * Returns the slot the item that is being picked goes into. ++ * ++ * @return hotbar slot (0-8 inclusive) ++ */ ++ @Range(from = 0, to = 8) ++ public int getTargetSlot() { ++ return this.targetSlot; ++ } ++ ++ /** ++ * Changes the slot the item that is being picked goes into. ++ * ++ * @param targetSlot hotbar slot (0-8 inclusive) ++ */ ++ public void setTargetSlot(@Range(from = 0, to = 8) int targetSlot) { ++ Preconditions.checkArgument(targetSlot >= 0 && targetSlot <= 8, "Target slot must be in range 0 - 8 (inclusive)"); ++ this.targetSlot = targetSlot; ++ } ++ ++ /** ++ * Returns the slot in which the item that will be put into the players hotbar is located. ++ * ++ * @return player inventory slot (0-35 inclusive) ++ */ ++ @Range(from = 0, to = 35) ++ public int getSourceSlot() { ++ return this.sourceSlot; ++ } ++ ++ /** ++ * Change the source slot from which the item that will be put in the players hotbar will be taken. ++ * ++ * @param sourceSlot player inventory slot (0-35 inclusive) ++ */ ++ public void setSourceSlot(@Range(from = 0, to = 35) int sourceSlot) { ++ Preconditions.checkArgument(sourceSlot >= 0 && sourceSlot <= 35, "Source slot must be in range of the player's inventory slot"); ++ this.sourceSlot = sourceSlot; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++} diff --git a/patches/api/0415-More-DragonBattle-API.patch b/patches/api/0415-More-DragonBattle-API.patch deleted file mode 100644 index e25208ec19..0000000000 --- a/patches/api/0415-More-DragonBattle-API.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sun, 18 Dec 2022 13:40:17 -0800 -Subject: [PATCH] More DragonBattle API - - -diff --git a/src/main/java/org/bukkit/boss/DragonBattle.java b/src/main/java/org/bukkit/boss/DragonBattle.java -index 6e5fc92243ee63c2a965f8a4905e29a7993588fd..5dbd12a786a66640ce80acafe2a42e35adef41eb 100644 ---- a/src/main/java/org/bukkit/boss/DragonBattle.java -+++ b/src/main/java/org/bukkit/boss/DragonBattle.java -@@ -145,4 +145,44 @@ public interface DragonBattle { - */ - NONE; - } -+ // Paper start -+ /** -+ * Gets the number of gateways tracked by this DragonBattle. -+ * This starts out at 0 and will increase to 20, once for each -+ * kill of the {@link EnderDragon}. -+ * -+ * @return the number of gateways around the end island tracked by this -+ */ -+ int getGatewayCount(); -+ -+ /** -+ * Tries to spawn a new end gateway using default game mechanics. -+ * -+ * @return true if successful, false if there is already the maximum. -+ */ -+ boolean spawnNewGateway(); -+ -+ /** -+ * Spawns a new end gateway at the specified position. This will -+ * spawn regardless of the number of gateways already present. -+ * -+ * @param position position for the new gateway -+ */ -+ void spawnNewGateway(@NotNull io.papermc.paper.math.Position position); -+ -+ /** -+ * Gets the {@link org.bukkit.entity.EnderCrystal}s being used to respawn the dragon. If no respawn -+ * is ongoing, the list will be empty. -+ * -+ * @return the respawn crystals -+ */ -+ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getRespawnCrystals(); -+ -+ /** -+ * Gets the {@link org.bukkit.entity.EnderCrystal}s on top of the pillars that heal the dragon. -+ * -+ * @return the healing crystals -+ */ -+ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getHealingCrystals(); -+ // Paper end - } diff --git a/patches/api/0416-Add-PlayerPickItemEvent.patch b/patches/api/0416-Add-PlayerPickItemEvent.patch deleted file mode 100644 index 6dd0be80a8..0000000000 --- a/patches/api/0416-Add-PlayerPickItemEvent.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: RodneyMKay <36546810+RodneyMKay@users.noreply.github.com> -Date: Wed, 8 Sep 2021 22:15:43 +0200 -Subject: [PATCH] Add PlayerPickItemEvent - - -diff --git a/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c5987ebea49e4b99c9ff7fa967aad1533b7b0ca6 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/player/PlayerPickItemEvent.java -@@ -0,0 +1,96 @@ -+package io.papermc.paper.event.player; -+ -+import com.google.common.base.Preconditions; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.player.PlayerEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Range; -+ -+/** -+ * Event that is fired when a player uses the pick item functionality (middle-clicking a block to get the appropriate -+ * item). However, note that this event will only trigger if an item has to be moved from the inventory to the hotbar. -+ * After the handling of this event, the contents of the source and the target slot will be swapped and the currently -+ * selected hotbar slot of the player will be set to the target slot. -+ *

-+ * Note: This event will not be fired for players in creative mode. -+ */ -+public class PlayerPickItemEvent extends PlayerEvent implements Cancellable { -+ -+ private static final HandlerList HANDLER_LIST = new HandlerList(); -+ -+ private int targetSlot; -+ private int sourceSlot; -+ -+ private boolean cancelled; -+ -+ @ApiStatus.Internal -+ public PlayerPickItemEvent(@NotNull Player player, int targetSlot, int sourceSlot) { -+ super(player); -+ this.targetSlot = targetSlot; -+ this.sourceSlot = sourceSlot; -+ } -+ -+ /** -+ * Returns the slot the item that is being picked goes into. -+ * -+ * @return hotbar slot (0-8 inclusive) -+ */ -+ @Range(from = 0, to = 8) -+ public int getTargetSlot() { -+ return this.targetSlot; -+ } -+ -+ /** -+ * Changes the slot the item that is being picked goes into. -+ * -+ * @param targetSlot hotbar slot (0-8 inclusive) -+ */ -+ public void setTargetSlot(@Range(from = 0, to = 8) int targetSlot) { -+ Preconditions.checkArgument(targetSlot >= 0 && targetSlot <= 8, "Target slot must be in range 0 - 8 (inclusive)"); -+ this.targetSlot = targetSlot; -+ } -+ -+ /** -+ * Returns the slot in which the item that will be put into the players hotbar is located. -+ * -+ * @return player inventory slot (0-35 inclusive) -+ */ -+ @Range(from = 0, to = 35) -+ public int getSourceSlot() { -+ return this.sourceSlot; -+ } -+ -+ /** -+ * Change the source slot from which the item that will be put in the players hotbar will be taken. -+ * -+ * @param sourceSlot player inventory slot (0-35 inclusive) -+ */ -+ public void setSourceSlot(@Range(from = 0, to = 35) int sourceSlot) { -+ Preconditions.checkArgument(sourceSlot >= 0 && sourceSlot <= 35, "Source slot must be in range of the player's inventory slot"); -+ this.sourceSlot = sourceSlot; -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return this.cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ this.cancelled = cancel; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return HANDLER_LIST; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return HANDLER_LIST; -+ } -+} diff --git a/patches/api/0416-Allow-trident-custom-damage.patch b/patches/api/0416-Allow-trident-custom-damage.patch new file mode 100644 index 0000000000..870b735548 --- /dev/null +++ b/patches/api/0416-Allow-trident-custom-damage.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> +Date: Wed, 13 Jul 2022 15:29:53 +0200 +Subject: [PATCH] Allow trident custom damage + + +diff --git a/src/main/java/org/bukkit/entity/Trident.java b/src/main/java/org/bukkit/entity/Trident.java +index 02584eced96944a551140f8150c65a7c0f4bb55e..d21df39ceef657575f3c2e9070bf6d2671978c7a 100644 +--- a/src/main/java/org/bukkit/entity/Trident.java ++++ b/src/main/java/org/bukkit/entity/Trident.java +@@ -57,5 +57,23 @@ public interface Trident extends AbstractArrow, ThrowableProjectile { + * @param hasDealtDamage has dealt damage or hit the floor + */ + void setHasDealtDamage(boolean hasDealtDamage); ++ ++ /** ++ * Sets the base amount of damage this trident will do. ++ * ++ * @param damage new damage amount ++ */ ++ void setDamage(double damage); ++ ++ /** ++ * Gets the base amount of damage this trident will do. ++ * ++ * Defaults to 8.0 for a normal trident with ++ * 0.5 * (1 + power level) added for trident fired from ++ * damage enchanted bows. ++ * ++ * @return base damage amount ++ */ ++ double getDamage(); + } + // Paper end diff --git a/patches/api/0417-Allow-trident-custom-damage.patch b/patches/api/0417-Allow-trident-custom-damage.patch deleted file mode 100644 index 870b735548..0000000000 --- a/patches/api/0417-Allow-trident-custom-damage.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> -Date: Wed, 13 Jul 2022 15:29:53 +0200 -Subject: [PATCH] Allow trident custom damage - - -diff --git a/src/main/java/org/bukkit/entity/Trident.java b/src/main/java/org/bukkit/entity/Trident.java -index 02584eced96944a551140f8150c65a7c0f4bb55e..d21df39ceef657575f3c2e9070bf6d2671978c7a 100644 ---- a/src/main/java/org/bukkit/entity/Trident.java -+++ b/src/main/java/org/bukkit/entity/Trident.java -@@ -57,5 +57,23 @@ public interface Trident extends AbstractArrow, ThrowableProjectile { - * @param hasDealtDamage has dealt damage or hit the floor - */ - void setHasDealtDamage(boolean hasDealtDamage); -+ -+ /** -+ * Sets the base amount of damage this trident will do. -+ * -+ * @param damage new damage amount -+ */ -+ void setDamage(double damage); -+ -+ /** -+ * Gets the base amount of damage this trident will do. -+ * -+ * Defaults to 8.0 for a normal trident with -+ * 0.5 * (1 + power level) added for trident fired from -+ * damage enchanted bows. -+ * -+ * @return base damage amount -+ */ -+ double getDamage(); - } - // Paper end diff --git a/patches/api/0417-Expose-hand-during-BlockCanBuildEvent.patch b/patches/api/0417-Expose-hand-during-BlockCanBuildEvent.patch new file mode 100644 index 0000000000..97d99a40d2 --- /dev/null +++ b/patches/api/0417-Expose-hand-during-BlockCanBuildEvent.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: The456gamer +Date: Mon, 21 Aug 2023 14:13:43 +0100 +Subject: [PATCH] Expose hand during BlockCanBuildEvent + + +diff --git a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java +index a1350c0f74d445dca09eea6e10abac050bb06990..08d09c2a92d8aa6adf6610cc05905d58a76fce1f 100644 +--- a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java ++++ b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java +@@ -25,10 +25,11 @@ public class BlockCanBuildEvent extends BlockEvent { + + protected BlockData blockData; + private final Player player; ++ private final org.bukkit.inventory.EquipmentSlot hand; // Paper - expose hand + + @Deprecated + public BlockCanBuildEvent(@NotNull final Block block, @NotNull final BlockData type, final boolean canBuild) { +- this(block, null, type, canBuild); ++ this(block, null, type, canBuild, org.bukkit.inventory.EquipmentSlot.HAND); // Paper - expose hand + } + + /** +@@ -37,12 +38,30 @@ public class BlockCanBuildEvent extends BlockEvent { + * @param type the id of the block to place + * @param canBuild whether we can build + */ ++ @java.lang.Deprecated // Paper ++ @io.papermc.paper.annotation.DoNotUse // Paper + public BlockCanBuildEvent(@NotNull final Block block, @Nullable final Player player, @NotNull final BlockData type, final boolean canBuild) { ++ this(block, player, type, canBuild, org.bukkit.inventory.EquipmentSlot.HAND); // Paper start - expose hand ++ } ++ @org.jetbrains.annotations.ApiStatus.Internal ++ public BlockCanBuildEvent(@NotNull final Block block, @Nullable final Player player, @NotNull final BlockData type, final boolean canBuild, @NotNull final org.bukkit.inventory.EquipmentSlot hand) { // Paper end - expose hand + super(block); + this.player = player; + this.buildable = canBuild; + this.blockData = type; ++ this.hand = hand; // Paper ++ } ++ // Paper start ++ /** ++ * Gets the hand the player will use to place the block ++ * ++ * @return the EquipmentSlot representing the players hand. ++ */ ++ @NotNull ++ public org.bukkit.inventory.EquipmentSlot getHand() { ++ return hand; + } ++ // Paper end + + /** + * Gets whether or not the block can be built here. diff --git a/patches/api/0418-Expose-hand-during-BlockCanBuildEvent.patch b/patches/api/0418-Expose-hand-during-BlockCanBuildEvent.patch deleted file mode 100644 index 97d99a40d2..0000000000 --- a/patches/api/0418-Expose-hand-during-BlockCanBuildEvent.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: The456gamer -Date: Mon, 21 Aug 2023 14:13:43 +0100 -Subject: [PATCH] Expose hand during BlockCanBuildEvent - - -diff --git a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java -index a1350c0f74d445dca09eea6e10abac050bb06990..08d09c2a92d8aa6adf6610cc05905d58a76fce1f 100644 ---- a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java -+++ b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java -@@ -25,10 +25,11 @@ public class BlockCanBuildEvent extends BlockEvent { - - protected BlockData blockData; - private final Player player; -+ private final org.bukkit.inventory.EquipmentSlot hand; // Paper - expose hand - - @Deprecated - public BlockCanBuildEvent(@NotNull final Block block, @NotNull final BlockData type, final boolean canBuild) { -- this(block, null, type, canBuild); -+ this(block, null, type, canBuild, org.bukkit.inventory.EquipmentSlot.HAND); // Paper - expose hand - } - - /** -@@ -37,12 +38,30 @@ public class BlockCanBuildEvent extends BlockEvent { - * @param type the id of the block to place - * @param canBuild whether we can build - */ -+ @java.lang.Deprecated // Paper -+ @io.papermc.paper.annotation.DoNotUse // Paper - public BlockCanBuildEvent(@NotNull final Block block, @Nullable final Player player, @NotNull final BlockData type, final boolean canBuild) { -+ this(block, player, type, canBuild, org.bukkit.inventory.EquipmentSlot.HAND); // Paper start - expose hand -+ } -+ @org.jetbrains.annotations.ApiStatus.Internal -+ public BlockCanBuildEvent(@NotNull final Block block, @Nullable final Player player, @NotNull final BlockData type, final boolean canBuild, @NotNull final org.bukkit.inventory.EquipmentSlot hand) { // Paper end - expose hand - super(block); - this.player = player; - this.buildable = canBuild; - this.blockData = type; -+ this.hand = hand; // Paper -+ } -+ // Paper start -+ /** -+ * Gets the hand the player will use to place the block -+ * -+ * @return the EquipmentSlot representing the players hand. -+ */ -+ @NotNull -+ public org.bukkit.inventory.EquipmentSlot getHand() { -+ return hand; - } -+ // Paper end - - /** - * Gets whether or not the block can be built here. diff --git a/patches/api/0418-Limit-setBurnTime-to-valid-short-values.patch b/patches/api/0418-Limit-setBurnTime-to-valid-short-values.patch new file mode 100644 index 0000000000..2faac56fd8 --- /dev/null +++ b/patches/api/0418-Limit-setBurnTime-to-valid-short-values.patch @@ -0,0 +1,21 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Warrior <50800980+Warriorrrr@users.noreply.github.com> +Date: Fri, 18 Aug 2023 08:07:38 +0200 +Subject: [PATCH] Limit setBurnTime to valid short values + + +diff --git a/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java b/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java +index ba4dc8aed85169e55cac276bdd51116919305019..2f80910dd23dacb30c41189a07a4e54117110bb8 100644 +--- a/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java ++++ b/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java +@@ -52,8 +52,8 @@ public class FurnaceBurnEvent extends BlockEvent implements Cancellable { + * + * @param burnTime the burn time for this fuel + */ +- public void setBurnTime(int burnTime) { +- this.burnTime = burnTime; ++ public void setBurnTime(@org.jetbrains.annotations.Range(from = Short.MIN_VALUE, to = Short.MAX_VALUE) int burnTime) { // Paper ++ this.burnTime = Math.max(Short.MIN_VALUE, Math.min(Short.MAX_VALUE, burnTime)); // Paper + } + + /** diff --git a/patches/api/0419-Add-OfflinePlayer-isConnected.patch b/patches/api/0419-Add-OfflinePlayer-isConnected.patch new file mode 100644 index 0000000000..08e2f91095 --- /dev/null +++ b/patches/api/0419-Add-OfflinePlayer-isConnected.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aeltumn +Date: Thu, 24 Aug 2023 13:05:07 +0200 +Subject: [PATCH] Add OfflinePlayer#isConnected + +This adds an alternative to OfflinePlayer#isOnline that returns true only if the same instance of the player is still online. This is generally more useful than isOnline as it allows you to determine if you have an instance of a Player that still exists. If a player relogs an old Player instance becomes unlinked leading to e.g. messages sent to the old player no longer arriving despite isOnline returning true. Checking against isConnected is more useful there to discard invalid instances. + +diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java +index 299d1cc510d24541c6bb47d02db0b6a86fb1d0eb..3993fecec5b4c2bbd77e175a168afcad571ce4d1 100644 +--- a/src/main/java/org/bukkit/OfflinePlayer.java ++++ b/src/main/java/org/bukkit/OfflinePlayer.java +@@ -24,10 +24,26 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio + /** + * Checks if this player is currently online + * ++ * It should be noted that this will return true if any instance of this player is ++ * online! This instance may have disconnected. If you wish to check if this specific ++ * instance of the player is still online, see {@link OfflinePlayer#isConnected()}. ++ * + * @return true if they are online + */ + public boolean isOnline(); + ++ // Paper start ++ /** ++ * Checks whether the connection to this player is still valid. This will return ++ * true as long as this specific instance of the player is still connected. This ++ * will return false after this instance has disconnected, even if the same player ++ * has reconnected since. ++ * ++ * @return true if this player instance is connected ++ */ ++ public boolean isConnected(); ++ // Paper end ++ + /** + * Returns the name of this player + *

diff --git a/patches/api/0419-Limit-setBurnTime-to-valid-short-values.patch b/patches/api/0419-Limit-setBurnTime-to-valid-short-values.patch deleted file mode 100644 index 2faac56fd8..0000000000 --- a/patches/api/0419-Limit-setBurnTime-to-valid-short-values.patch +++ /dev/null @@ -1,21 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Warrior <50800980+Warriorrrr@users.noreply.github.com> -Date: Fri, 18 Aug 2023 08:07:38 +0200 -Subject: [PATCH] Limit setBurnTime to valid short values - - -diff --git a/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java b/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java -index ba4dc8aed85169e55cac276bdd51116919305019..2f80910dd23dacb30c41189a07a4e54117110bb8 100644 ---- a/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java -+++ b/src/main/java/org/bukkit/event/inventory/FurnaceBurnEvent.java -@@ -52,8 +52,8 @@ public class FurnaceBurnEvent extends BlockEvent implements Cancellable { - * - * @param burnTime the burn time for this fuel - */ -- public void setBurnTime(int burnTime) { -- this.burnTime = burnTime; -+ public void setBurnTime(@org.jetbrains.annotations.Range(from = Short.MIN_VALUE, to = Short.MAX_VALUE) int burnTime) { // Paper -+ this.burnTime = Math.max(Short.MIN_VALUE, Math.min(Short.MAX_VALUE, burnTime)); // Paper - } - - /** diff --git a/patches/api/0420-Add-OfflinePlayer-isConnected.patch b/patches/api/0420-Add-OfflinePlayer-isConnected.patch deleted file mode 100644 index 08e2f91095..0000000000 --- a/patches/api/0420-Add-OfflinePlayer-isConnected.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aeltumn -Date: Thu, 24 Aug 2023 13:05:07 +0200 -Subject: [PATCH] Add OfflinePlayer#isConnected - -This adds an alternative to OfflinePlayer#isOnline that returns true only if the same instance of the player is still online. This is generally more useful than isOnline as it allows you to determine if you have an instance of a Player that still exists. If a player relogs an old Player instance becomes unlinked leading to e.g. messages sent to the old player no longer arriving despite isOnline returning true. Checking against isConnected is more useful there to discard invalid instances. - -diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java -index 299d1cc510d24541c6bb47d02db0b6a86fb1d0eb..3993fecec5b4c2bbd77e175a168afcad571ce4d1 100644 ---- a/src/main/java/org/bukkit/OfflinePlayer.java -+++ b/src/main/java/org/bukkit/OfflinePlayer.java -@@ -24,10 +24,26 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio - /** - * Checks if this player is currently online - * -+ * It should be noted that this will return true if any instance of this player is -+ * online! This instance may have disconnected. If you wish to check if this specific -+ * instance of the player is still online, see {@link OfflinePlayer#isConnected()}. -+ * - * @return true if they are online - */ - public boolean isOnline(); - -+ // Paper start -+ /** -+ * Checks whether the connection to this player is still valid. This will return -+ * true as long as this specific instance of the player is still connected. This -+ * will return false after this instance has disconnected, even if the same player -+ * has reconnected since. -+ * -+ * @return true if this player instance is connected -+ */ -+ public boolean isConnected(); -+ // Paper end -+ - /** - * Returns the name of this player - *

diff --git a/patches/api/0420-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/api/0420-Add-titleOverride-to-InventoryOpenEvent.patch new file mode 100644 index 0000000000..68e755f010 --- /dev/null +++ b/patches/api/0420-Add-titleOverride-to-InventoryOpenEvent.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Fri, 4 Mar 2022 12:45:21 -0800 +Subject: [PATCH] Add titleOverride to InventoryOpenEvent + + +diff --git a/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java +index ceae092eb782698803c6c3df41267dde20ba62b2..8e2afeab4c62724148e8bb0c83fb7eec569c7a0c 100644 +--- a/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java ++++ b/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java +@@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; + public class InventoryOpenEvent extends InventoryEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; ++ private net.kyori.adventure.text.Component titleOverride; // Paper + + public InventoryOpenEvent(@NotNull InventoryView transaction) { + super(transaction); +@@ -56,6 +57,33 @@ public class InventoryOpenEvent extends InventoryEvent implements Cancellable { + cancelled = cancel; + } + ++ // Paper start ++ /** ++ * Gets the title override set by another event or null ++ * if not set. ++ * ++ * @return the title override or null ++ */ ++ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component titleOverride() { ++ return this.titleOverride; ++ } ++ ++ /** ++ * Sets the title override or clears the override. ++ *

++ * This is only the title sent to the client in the open packet, this doesn't change ++ * the title returned by {@link InventoryView#title()}, hence "override". ++ *

++ * NOTE: Horse inventories are a special case where setting this will ++ * have no effect. Horse inventory titles are set by the horse display name. ++ * ++ * @param titleOverride the title override or null ++ */ ++ public void titleOverride(net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component titleOverride) { ++ this.titleOverride = titleOverride; ++ } ++ // Paper end ++ + @NotNull + @Override + public HandlerList getHandlers() { diff --git a/patches/api/0421-Add-titleOverride-to-InventoryOpenEvent.patch b/patches/api/0421-Add-titleOverride-to-InventoryOpenEvent.patch deleted file mode 100644 index 68e755f010..0000000000 --- a/patches/api/0421-Add-titleOverride-to-InventoryOpenEvent.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Fri, 4 Mar 2022 12:45:21 -0800 -Subject: [PATCH] Add titleOverride to InventoryOpenEvent - - -diff --git a/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java -index ceae092eb782698803c6c3df41267dde20ba62b2..8e2afeab4c62724148e8bb0c83fb7eec569c7a0c 100644 ---- a/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java -+++ b/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java -@@ -12,6 +12,7 @@ import org.jetbrains.annotations.NotNull; - public class InventoryOpenEvent extends InventoryEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private boolean cancelled; -+ private net.kyori.adventure.text.Component titleOverride; // Paper - - public InventoryOpenEvent(@NotNull InventoryView transaction) { - super(transaction); -@@ -56,6 +57,33 @@ public class InventoryOpenEvent extends InventoryEvent implements Cancellable { - cancelled = cancel; - } - -+ // Paper start -+ /** -+ * Gets the title override set by another event or null -+ * if not set. -+ * -+ * @return the title override or null -+ */ -+ public net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component titleOverride() { -+ return this.titleOverride; -+ } -+ -+ /** -+ * Sets the title override or clears the override. -+ *

-+ * This is only the title sent to the client in the open packet, this doesn't change -+ * the title returned by {@link InventoryView#title()}, hence "override". -+ *

-+ * NOTE: Horse inventories are a special case where setting this will -+ * have no effect. Horse inventory titles are set by the horse display name. -+ * -+ * @param titleOverride the title override or null -+ */ -+ public void titleOverride(net.kyori.adventure.text.@org.jetbrains.annotations.Nullable Component titleOverride) { -+ this.titleOverride = titleOverride; -+ } -+ // Paper end -+ - @NotNull - @Override - public HandlerList getHandlers() { diff --git a/patches/api/0421-Allow-proper-checking-of-empty-item-stacks.patch b/patches/api/0421-Allow-proper-checking-of-empty-item-stacks.patch new file mode 100644 index 0000000000..7c74a0781c --- /dev/null +++ b/patches/api/0421-Allow-proper-checking-of-empty-item-stacks.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aeltumn +Date: Mon, 28 Aug 2023 13:41:09 +0200 +Subject: [PATCH] Allow proper checking of empty item stacks + +This adds a method to check if an item stack is empty or not. This mirrors vanilla's implementation of the same method. + +diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java +index db128d14931ec2afea5205faa58fb5410ec9a54c..9d397c395d777f337a421fac8fea064680065661 100644 +--- a/src/main/java/org/bukkit/inventory/ItemStack.java ++++ b/src/main/java/org/bukkit/inventory/ItemStack.java +@@ -1017,5 +1017,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat + public @NotNull ItemStack damage(int amount, @NotNull org.bukkit.entity.LivingEntity livingEntity) { + return livingEntity.damageItemStack(this, amount); + } ++ ++ /** ++ * Returns an empty item stack, consists of an air material and a stack size of 0. ++ * ++ * Any item stack with a material of air or a stack size of 0 is seen ++ * as being empty by {@link ItemStack#isEmpty}. ++ */ ++ @NotNull ++ public static ItemStack empty() { ++ return new ItemStack(); ++ } ++ ++ /** ++ * Returns whether this item stack is empty and contains no item. This means ++ * it is either air or the stack has a size of 0. ++ */ ++ public boolean isEmpty() { ++ return type.isAir() || amount <= 0; ++ } + // Paper end + } diff --git a/patches/api/0422-Allow-proper-checking-of-empty-item-stacks.patch b/patches/api/0422-Allow-proper-checking-of-empty-item-stacks.patch deleted file mode 100644 index 7c74a0781c..0000000000 --- a/patches/api/0422-Allow-proper-checking-of-empty-item-stacks.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aeltumn -Date: Mon, 28 Aug 2023 13:41:09 +0200 -Subject: [PATCH] Allow proper checking of empty item stacks - -This adds a method to check if an item stack is empty or not. This mirrors vanilla's implementation of the same method. - -diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index db128d14931ec2afea5205faa58fb5410ec9a54c..9d397c395d777f337a421fac8fea064680065661 100644 ---- a/src/main/java/org/bukkit/inventory/ItemStack.java -+++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -1017,5 +1017,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat - public @NotNull ItemStack damage(int amount, @NotNull org.bukkit.entity.LivingEntity livingEntity) { - return livingEntity.damageItemStack(this, amount); - } -+ -+ /** -+ * Returns an empty item stack, consists of an air material and a stack size of 0. -+ * -+ * Any item stack with a material of air or a stack size of 0 is seen -+ * as being empty by {@link ItemStack#isEmpty}. -+ */ -+ @NotNull -+ public static ItemStack empty() { -+ return new ItemStack(); -+ } -+ -+ /** -+ * Returns whether this item stack is empty and contains no item. This means -+ * it is either air or the stack has a size of 0. -+ */ -+ public boolean isEmpty() { -+ return type.isAir() || amount <= 0; -+ } - // Paper end - } diff --git a/patches/api/0422-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch b/patches/api/0422-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch new file mode 100644 index 0000000000..e72f86be5d --- /dev/null +++ b/patches/api/0422-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch @@ -0,0 +1,47 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tamion <70228790+notTamion@users.noreply.github.com> +Date: Mon, 25 Sep 2023 19:55:51 +0200 +Subject: [PATCH] Fix PlayerSwapHandItemsEvent throwing exception when mainhand + or offhand set to null + + +diff --git a/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java b/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java +index 9f592317c920589c22a5fb8e916c6ca58ebe5c59..39dd08de71b8b52fe3462c105ecdbfc1cd2cd9a3 100644 +--- a/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java ++++ b/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java +@@ -31,7 +31,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable + * + * @return item in the main hand + */ +- @Nullable ++ @NotNull // Paper + public ItemStack getMainHandItem() { + return mainHandItem; + } +@@ -42,7 +42,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable + * @param mainHandItem new item in the main hand + */ + public void setMainHandItem(@Nullable ItemStack mainHandItem) { +- this.mainHandItem = mainHandItem; ++ this.mainHandItem = mainHandItem == null ? ItemStack.empty() : mainHandItem; // Paper + } + + /** +@@ -50,7 +50,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable + * + * @return item in the off hand + */ +- @Nullable ++ @NotNull // Paper + public ItemStack getOffHandItem() { + return offHandItem; + } +@@ -61,7 +61,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable + * @param offHandItem new item in the off hand + */ + public void setOffHandItem(@Nullable ItemStack offHandItem) { +- this.offHandItem = offHandItem; ++ this.offHandItem = offHandItem == null ? ItemStack.empty() : offHandItem; // Paper + } + + @Override diff --git a/patches/api/0423-Add-player-idle-duration-API.patch b/patches/api/0423-Add-player-idle-duration-API.patch new file mode 100644 index 0000000000..2fbfc5dc58 --- /dev/null +++ b/patches/api/0423-Add-player-idle-duration-API.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: booky10 +Date: Sat, 14 Oct 2023 03:11:11 +0200 +Subject: [PATCH] Add player idle duration API + +Implements API for getting and resetting a player's idle duration. + +diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java +index 24dc710f61d08253f66e7ecfd69873e7ebf68d1b..09094f55509eaf66670c27409b4d5ec3d73412b0 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -3742,6 +3742,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + void increaseWardenWarningLevel(); + // Paper end + ++ // Paper start ++ /** ++ * The idle duration is reset when the player ++ * sends specific action packets. ++ *

++ * After the idle duration exceeds {@link org.bukkit.Bukkit#getIdleTimeout()}, the ++ * player will be kicked for {@link org.bukkit.event.player.PlayerKickEvent.Cause#IDLING}. ++ * ++ * @return the current idle duration of this player ++ */ ++ @NotNull Duration getIdleDuration(); ++ ++ /** ++ * Resets this player's idle duration. ++ *

++ * After the idle duration exceeds {@link org.bukkit.Bukkit#getIdleTimeout()}, the ++ * player will be kicked for {@link org.bukkit.event.player.PlayerKickEvent.Cause#IDLING}. ++ * ++ * @see #getIdleDuration() ++ */ ++ void resetIdleDuration(); ++ // Paper end ++ + @NotNull + @Override + Spigot spigot(); diff --git a/patches/api/0423-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch b/patches/api/0423-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch deleted file mode 100644 index e72f86be5d..0000000000 --- a/patches/api/0423-Fix-PlayerSwapHandItemsEvent-throwing-exception-when.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tamion <70228790+notTamion@users.noreply.github.com> -Date: Mon, 25 Sep 2023 19:55:51 +0200 -Subject: [PATCH] Fix PlayerSwapHandItemsEvent throwing exception when mainhand - or offhand set to null - - -diff --git a/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java b/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java -index 9f592317c920589c22a5fb8e916c6ca58ebe5c59..39dd08de71b8b52fe3462c105ecdbfc1cd2cd9a3 100644 ---- a/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java -+++ b/src/main/java/org/bukkit/event/player/PlayerSwapHandItemsEvent.java -@@ -31,7 +31,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable - * - * @return item in the main hand - */ -- @Nullable -+ @NotNull // Paper - public ItemStack getMainHandItem() { - return mainHandItem; - } -@@ -42,7 +42,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable - * @param mainHandItem new item in the main hand - */ - public void setMainHandItem(@Nullable ItemStack mainHandItem) { -- this.mainHandItem = mainHandItem; -+ this.mainHandItem = mainHandItem == null ? ItemStack.empty() : mainHandItem; // Paper - } - - /** -@@ -50,7 +50,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable - * - * @return item in the off hand - */ -- @Nullable -+ @NotNull // Paper - public ItemStack getOffHandItem() { - return offHandItem; - } -@@ -61,7 +61,7 @@ public class PlayerSwapHandItemsEvent extends PlayerEvent implements Cancellable - * @param offHandItem new item in the off hand - */ - public void setOffHandItem(@Nullable ItemStack offHandItem) { -- this.offHandItem = offHandItem; -+ this.offHandItem = offHandItem == null ? ItemStack.empty() : offHandItem; // Paper - } - - @Override diff --git a/patches/api/0424-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/api/0424-Add-API-to-get-the-collision-shape-of-a-block-before.patch new file mode 100644 index 0000000000..3bb30787dc --- /dev/null +++ b/patches/api/0424-Add-API-to-get-the-collision-shape-of-a-block-before.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: TrollyLoki +Date: Wed, 11 Oct 2023 00:45:54 -0400 +Subject: [PATCH] Add API to get the collision shape of a block before it's + placed + + +diff --git a/src/main/java/org/bukkit/block/data/BlockData.java b/src/main/java/org/bukkit/block/data/BlockData.java +index 54664651f34311e95f6c2dcfd93e58477beda8c2..0ecc54bd810a2805b7209d9433b76743500e45a8 100644 +--- a/src/main/java/org/bukkit/block/data/BlockData.java ++++ b/src/main/java/org/bukkit/block/data/BlockData.java +@@ -205,6 +205,19 @@ public interface BlockData extends Cloneable { + */ + boolean isFaceSturdy(@NotNull BlockFace face, @NotNull BlockSupport support); + ++ // Paper start ++ /** ++ * Calculates the collision shape this block data would have at a particular location. ++ *

++ * This does not take into account any block updates that may occur if the block was to be actually placed in the world. ++ * ++ * @param location the location to calculate the collision shape at ++ * ++ * @return a {@link org.bukkit.util.VoxelShape} representing the collision shape of this block data. ++ */ ++ @NotNull org.bukkit.util.VoxelShape getCollisionShape(@NotNull Location location); ++ // Paper end ++ + /** + * Gets the color this block should appear as when rendered on a map. + * diff --git a/patches/api/0424-Add-player-idle-duration-API.patch b/patches/api/0424-Add-player-idle-duration-API.patch deleted file mode 100644 index 2fbfc5dc58..0000000000 --- a/patches/api/0424-Add-player-idle-duration-API.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: booky10 -Date: Sat, 14 Oct 2023 03:11:11 +0200 -Subject: [PATCH] Add player idle duration API - -Implements API for getting and resetting a player's idle duration. - -diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 24dc710f61d08253f66e7ecfd69873e7ebf68d1b..09094f55509eaf66670c27409b4d5ec3d73412b0 100644 ---- a/src/main/java/org/bukkit/entity/Player.java -+++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3742,6 +3742,29 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - void increaseWardenWarningLevel(); - // Paper end - -+ // Paper start -+ /** -+ * The idle duration is reset when the player -+ * sends specific action packets. -+ *

-+ * After the idle duration exceeds {@link org.bukkit.Bukkit#getIdleTimeout()}, the -+ * player will be kicked for {@link org.bukkit.event.player.PlayerKickEvent.Cause#IDLING}. -+ * -+ * @return the current idle duration of this player -+ */ -+ @NotNull Duration getIdleDuration(); -+ -+ /** -+ * Resets this player's idle duration. -+ *

-+ * After the idle duration exceeds {@link org.bukkit.Bukkit#getIdleTimeout()}, the -+ * player will be kicked for {@link org.bukkit.event.player.PlayerKickEvent.Cause#IDLING}. -+ * -+ * @see #getIdleDuration() -+ */ -+ void resetIdleDuration(); -+ // Paper end -+ - @NotNull - @Override - Spigot spigot(); diff --git a/patches/api/0425-Add-API-to-get-the-collision-shape-of-a-block-before.patch b/patches/api/0425-Add-API-to-get-the-collision-shape-of-a-block-before.patch deleted file mode 100644 index 3bb30787dc..0000000000 --- a/patches/api/0425-Add-API-to-get-the-collision-shape-of-a-block-before.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: TrollyLoki -Date: Wed, 11 Oct 2023 00:45:54 -0400 -Subject: [PATCH] Add API to get the collision shape of a block before it's - placed - - -diff --git a/src/main/java/org/bukkit/block/data/BlockData.java b/src/main/java/org/bukkit/block/data/BlockData.java -index 54664651f34311e95f6c2dcfd93e58477beda8c2..0ecc54bd810a2805b7209d9433b76743500e45a8 100644 ---- a/src/main/java/org/bukkit/block/data/BlockData.java -+++ b/src/main/java/org/bukkit/block/data/BlockData.java -@@ -205,6 +205,19 @@ public interface BlockData extends Cloneable { - */ - boolean isFaceSturdy(@NotNull BlockFace face, @NotNull BlockSupport support); - -+ // Paper start -+ /** -+ * Calculates the collision shape this block data would have at a particular location. -+ *

-+ * This does not take into account any block updates that may occur if the block was to be actually placed in the world. -+ * -+ * @param location the location to calculate the collision shape at -+ * -+ * @return a {@link org.bukkit.util.VoxelShape} representing the collision shape of this block data. -+ */ -+ @NotNull org.bukkit.util.VoxelShape getCollisionShape(@NotNull Location location); -+ // Paper end -+ - /** - * Gets the color this block should appear as when rendered on a map. - * diff --git a/patches/api/0425-Add-predicate-for-blocks-when-raytracing.patch b/patches/api/0425-Add-predicate-for-blocks-when-raytracing.patch new file mode 100644 index 0000000000..13d64df888 --- /dev/null +++ b/patches/api/0425-Add-predicate-for-blocks-when-raytracing.patch @@ -0,0 +1,116 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: TonytheMacaroni +Date: Wed, 6 Sep 2023 19:24:53 -0400 +Subject: [PATCH] Add predicate for blocks when raytracing + + +diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java +index 907906e15c9250fea385e49f10d3c248236fd004..02184b68cc126b278985fd966e3c8e4ade18c464 100644 +--- a/src/main/java/org/bukkit/World.java ++++ b/src/main/java/org/bukkit/World.java +@@ -1649,6 +1649,27 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient + @Nullable + public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate filter); + ++ // Paper start ++ /** ++ * Performs a ray trace that checks for entity collisions. ++ *

++ * This may not consider entities in currently unloaded chunks. Some ++ * implementations may impose artificial restrictions on the maximum ++ * distance. ++ * ++ * @param start the start position ++ * @param direction the ray direction ++ * @param maxDistance the maximum distance ++ * @param raySize entity bounding boxes will be uniformly expanded (or ++ * shrinked) by this value before doing collision checks ++ * @param filter only entities that fulfill this predicate are considered, ++ * or null to consider all entities ++ * @return the closest ray trace hit result, or null if there ++ * is no hit ++ */ ++ @Nullable RayTraceResult rayTraceEntities(io.papermc.paper.math.@NotNull Position start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate filter); ++ // Paper end ++ + /** + * Performs a ray trace that checks for block collisions using the blocks' + * precise collision shapes. +@@ -1712,6 +1733,34 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient + @Nullable + public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks); + ++ // Paper start ++ /** ++ * Performs a ray trace that checks for block collisions using the blocks' ++ * precise collision shapes. ++ *

++ * If collisions with passable blocks are ignored, fluid collisions are ++ * ignored as well regardless of the fluid collision mode. ++ *

++ * Portal blocks are only considered passable if the ray starts within ++ * them. Apart from that collisions with portal blocks will be considered ++ * even if collisions with passable blocks are otherwise ignored. ++ *

++ * This may cause loading of chunks! Some implementations may impose ++ * artificial restrictions on the maximum distance. ++ * ++ * @param start the start position ++ * @param direction the ray direction ++ * @param maxDistance the maximum distance ++ * @param fluidCollisionMode the fluid collision mode ++ * @param ignorePassableBlocks whether to ignore passable but collidable ++ * blocks (ex. tall grass, signs, fluids, ..) ++ * @param canCollide predicate for blocks the ray can potentially collide ++ * with, or null to consider all blocks ++ * @return the ray trace hit result, or null if there is no hit ++ */ ++ @Nullable RayTraceResult rayTraceBlocks(io.papermc.paper.math.@NotNull Position start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, @Nullable Predicate canCollide); ++ // Paper end ++ + /** + * Performs a ray trace that checks for both block and entity collisions. + *

+@@ -1745,6 +1794,42 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient + @Nullable + public RayTraceResult rayTrace(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate filter); + ++ // Paper start ++ /** ++ * Performs a ray trace that checks for both block and entity collisions. ++ *

++ * Block collisions use the blocks' precise collision shapes. The ++ * raySize parameter is only taken into account for entity ++ * collision checks. ++ *

++ * If collisions with passable blocks are ignored, fluid collisions are ++ * ignored as well regardless of the fluid collision mode. ++ *

++ * Portal blocks are only considered passable if the ray starts within them. ++ * Apart from that collisions with portal blocks will be considered even if ++ * collisions with passable blocks are otherwise ignored. ++ *

++ * This may cause loading of chunks! Some implementations may impose ++ * artificial restrictions on the maximum distance. ++ * ++ * @param start the start position ++ * @param direction the ray direction ++ * @param maxDistance the maximum distance ++ * @param fluidCollisionMode the fluid collision mode ++ * @param ignorePassableBlocks whether to ignore passable but collidable ++ * blocks (ex. tall grass, signs, fluids, ..) ++ * @param raySize entity bounding boxes will be uniformly expanded (or ++ * shrinked) by this value before doing collision checks ++ * @param filter only entities that fulfill this predicate are considered, ++ * or null to consider all entities ++ * @param canCollide predicate for blocks the ray can potentially collide ++ * with, or null to consider all blocks ++ * @return the closest ray trace hit result with either a block or an ++ * entity, or null if there is no hit ++ */ ++ @Nullable RayTraceResult rayTrace(io.papermc.paper.math.@NotNull Position start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate filter, @Nullable Predicate canCollide); ++ // Paper end ++ + /** + * Gets the default spawn {@link Location} of this world + * diff --git a/patches/api/0426-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/api/0426-Add-hand-to-fish-event-for-all-player-interactions.patch new file mode 100644 index 0000000000..b431332b9a --- /dev/null +++ b/patches/api/0426-Add-hand-to-fish-event-for-all-player-interactions.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: booky10 +Date: Mon, 3 Jul 2023 01:55:32 +0200 +Subject: [PATCH] Add hand to fish event for all player interactions + + +diff --git a/src/main/java/org/bukkit/event/player/PlayerFishEvent.java b/src/main/java/org/bukkit/event/player/PlayerFishEvent.java +index 45342030ad0f46632d3ee9a6d0348251f8ee375f..d4001f64a7ee9d5173e9bafd9c45860cbda1fc85 100644 +--- a/src/main/java/org/bukkit/event/player/PlayerFishEvent.java ++++ b/src/main/java/org/bukkit/event/player/PlayerFishEvent.java +@@ -94,8 +94,9 @@ public class PlayerFishEvent extends PlayerEvent implements Cancellable { + /** + * Get the hand that was used in this event. + *

+- * The hand used is only present when the event state is {@link State#FISHING}. +- * In all other states, the hand is null. ++ * The hand used is only present for player interactions. ++ * This means it will be null if state is set ++ * to {@link State#BITE} or {@link State#FAILED_ATTEMPT}. + * + * @return the hand + */ diff --git a/patches/api/0426-Add-predicate-for-blocks-when-raytracing.patch b/patches/api/0426-Add-predicate-for-blocks-when-raytracing.patch deleted file mode 100644 index 13d64df888..0000000000 --- a/patches/api/0426-Add-predicate-for-blocks-when-raytracing.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: TonytheMacaroni -Date: Wed, 6 Sep 2023 19:24:53 -0400 -Subject: [PATCH] Add predicate for blocks when raytracing - - -diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 907906e15c9250fea385e49f10d3c248236fd004..02184b68cc126b278985fd966e3c8e4ade18c464 100644 ---- a/src/main/java/org/bukkit/World.java -+++ b/src/main/java/org/bukkit/World.java -@@ -1649,6 +1649,27 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient - @Nullable - public RayTraceResult rayTraceEntities(@NotNull Location start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate filter); - -+ // Paper start -+ /** -+ * Performs a ray trace that checks for entity collisions. -+ *

-+ * This may not consider entities in currently unloaded chunks. Some -+ * implementations may impose artificial restrictions on the maximum -+ * distance. -+ * -+ * @param start the start position -+ * @param direction the ray direction -+ * @param maxDistance the maximum distance -+ * @param raySize entity bounding boxes will be uniformly expanded (or -+ * shrinked) by this value before doing collision checks -+ * @param filter only entities that fulfill this predicate are considered, -+ * or null to consider all entities -+ * @return the closest ray trace hit result, or null if there -+ * is no hit -+ */ -+ @Nullable RayTraceResult rayTraceEntities(io.papermc.paper.math.@NotNull Position start, @NotNull Vector direction, double maxDistance, double raySize, @Nullable Predicate filter); -+ // Paper end -+ - /** - * Performs a ray trace that checks for block collisions using the blocks' - * precise collision shapes. -@@ -1712,6 +1733,34 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient - @Nullable - public RayTraceResult rayTraceBlocks(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks); - -+ // Paper start -+ /** -+ * Performs a ray trace that checks for block collisions using the blocks' -+ * precise collision shapes. -+ *

-+ * If collisions with passable blocks are ignored, fluid collisions are -+ * ignored as well regardless of the fluid collision mode. -+ *

-+ * Portal blocks are only considered passable if the ray starts within -+ * them. Apart from that collisions with portal blocks will be considered -+ * even if collisions with passable blocks are otherwise ignored. -+ *

-+ * This may cause loading of chunks! Some implementations may impose -+ * artificial restrictions on the maximum distance. -+ * -+ * @param start the start position -+ * @param direction the ray direction -+ * @param maxDistance the maximum distance -+ * @param fluidCollisionMode the fluid collision mode -+ * @param ignorePassableBlocks whether to ignore passable but collidable -+ * blocks (ex. tall grass, signs, fluids, ..) -+ * @param canCollide predicate for blocks the ray can potentially collide -+ * with, or null to consider all blocks -+ * @return the ray trace hit result, or null if there is no hit -+ */ -+ @Nullable RayTraceResult rayTraceBlocks(io.papermc.paper.math.@NotNull Position start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, @Nullable Predicate canCollide); -+ // Paper end -+ - /** - * Performs a ray trace that checks for both block and entity collisions. - *

-@@ -1745,6 +1794,42 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient - @Nullable - public RayTraceResult rayTrace(@NotNull Location start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate filter); - -+ // Paper start -+ /** -+ * Performs a ray trace that checks for both block and entity collisions. -+ *

-+ * Block collisions use the blocks' precise collision shapes. The -+ * raySize parameter is only taken into account for entity -+ * collision checks. -+ *

-+ * If collisions with passable blocks are ignored, fluid collisions are -+ * ignored as well regardless of the fluid collision mode. -+ *

-+ * Portal blocks are only considered passable if the ray starts within them. -+ * Apart from that collisions with portal blocks will be considered even if -+ * collisions with passable blocks are otherwise ignored. -+ *

-+ * This may cause loading of chunks! Some implementations may impose -+ * artificial restrictions on the maximum distance. -+ * -+ * @param start the start position -+ * @param direction the ray direction -+ * @param maxDistance the maximum distance -+ * @param fluidCollisionMode the fluid collision mode -+ * @param ignorePassableBlocks whether to ignore passable but collidable -+ * blocks (ex. tall grass, signs, fluids, ..) -+ * @param raySize entity bounding boxes will be uniformly expanded (or -+ * shrinked) by this value before doing collision checks -+ * @param filter only entities that fulfill this predicate are considered, -+ * or null to consider all entities -+ * @param canCollide predicate for blocks the ray can potentially collide -+ * with, or null to consider all blocks -+ * @return the closest ray trace hit result with either a block or an -+ * entity, or null if there is no hit -+ */ -+ @Nullable RayTraceResult rayTrace(io.papermc.paper.math.@NotNull Position start, @NotNull Vector direction, double maxDistance, @NotNull FluidCollisionMode fluidCollisionMode, boolean ignorePassableBlocks, double raySize, @Nullable Predicate filter, @Nullable Predicate canCollide); -+ // Paper end -+ - /** - * Gets the default spawn {@link Location} of this world - * diff --git a/patches/api/0427-Add-UUID-attribute-modifier-API.patch b/patches/api/0427-Add-UUID-attribute-modifier-API.patch new file mode 100644 index 0000000000..64de52c83e --- /dev/null +++ b/patches/api/0427-Add-UUID-attribute-modifier-API.patch @@ -0,0 +1,93 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: TonytheMacaroni +Date: Thu, 9 Nov 2023 20:35:35 -0500 +Subject: [PATCH] Add UUID attribute modifier API + + +diff --git a/src/main/java/org/bukkit/attribute/AttributeInstance.java b/src/main/java/org/bukkit/attribute/AttributeInstance.java +index 5513174ea545bb5b4fdc028cbaa4c1bb763e2c6d..f1fa86ddf1f50a357c9e94cc61261d8c96a2da6f 100644 +--- a/src/main/java/org/bukkit/attribute/AttributeInstance.java ++++ b/src/main/java/org/bukkit/attribute/AttributeInstance.java +@@ -39,6 +39,42 @@ public interface AttributeInstance { + @NotNull + Collection getModifiers(); + ++ // Paper start ++ /** ++ * Gets the modifier with the corresponding key. ++ * ++ * @param key the jey of the modifier ++ * @return the modifier, if it exists ++ */ ++ @org.jetbrains.annotations.Nullable AttributeModifier getModifier(@NotNull net.kyori.adventure.key.Key key); ++ ++ /** ++ * Remove a modifier with the corresponding key from this instance. ++ * ++ * @param key the key of the modifier ++ */ ++ void removeModifier(@NotNull net.kyori.adventure.key.Key key); ++ ++ /** ++ * Gets the modifier with the corresponding UUID. ++ * ++ * @param uuid the UUID of the modifier ++ * @return the modifier, if it exists ++ * @deprecated use {@link #getModifier(net.kyori.adventure.key.Key)}, modifiers are no longer stored by UUID ++ */ ++ @Deprecated(forRemoval = true, since = "1.21") ++ @org.jetbrains.annotations.Nullable AttributeModifier getModifier(@NotNull java.util.UUID uuid); ++ ++ /** ++ * Remove a modifier with the corresponding UUID from this instance. ++ * ++ * @param uuid the UUID of the modifier ++ * @deprecated use {@link #removeModifier(net.kyori.adventure.key.Key)}, modifiers are no longer stored by UUID ++ */ ++ @Deprecated(forRemoval = true, since = "1.21") ++ void removeModifier(@NotNull java.util.UUID uuid); ++ // Paper end ++ + /** + * Add a modifier to this instance. + * +diff --git a/src/main/java/org/bukkit/attribute/AttributeModifier.java b/src/main/java/org/bukkit/attribute/AttributeModifier.java +index d66502c9df2592cd18694481e7e90a71a5c3a359..90f18f355a6a236a7e4273cc1258e7c8034b8276 100644 +--- a/src/main/java/org/bukkit/attribute/AttributeModifier.java ++++ b/src/main/java/org/bukkit/attribute/AttributeModifier.java +@@ -25,22 +25,22 @@ public class AttributeModifier implements ConfigurationSerializable, Keyed { + private final Operation operation; + private final EquipmentSlotGroup slot; + +- @Deprecated ++ @Deprecated(forRemoval = true, since = "1.21") + public AttributeModifier(@NotNull String name, double amount, @NotNull Operation operation) { + this(UUID.randomUUID(), name, amount, operation); + } + +- @Deprecated ++ @Deprecated(forRemoval = true, since = "1.21") + public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation) { + this(uuid, name, amount, operation, (EquipmentSlot) null); + } + +- @Deprecated ++ @Deprecated(forRemoval = true, since = "1.21") + public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation, @Nullable EquipmentSlot slot) { + this(uuid, name, amount, operation, (slot) == null ? EquipmentSlotGroup.ANY : slot.getGroup()); + } + +- @Deprecated ++ @Deprecated(forRemoval = true, since = "1.21") + public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation, @NotNull EquipmentSlotGroup slot) { + this(NamespacedKey.fromString(uuid.toString()), amount, operation, slot); + } +@@ -63,7 +63,7 @@ public class AttributeModifier implements ConfigurationSerializable, Keyed { + * @deprecated attributes are now identified by keys + */ + @NotNull +- @Deprecated ++ @Deprecated(forRemoval = true, since = "1.21") + public UUID getUniqueId() { + return UUID.fromString(getKey().toString()); + } diff --git a/patches/api/0427-Add-hand-to-fish-event-for-all-player-interactions.patch b/patches/api/0427-Add-hand-to-fish-event-for-all-player-interactions.patch deleted file mode 100644 index b431332b9a..0000000000 --- a/patches/api/0427-Add-hand-to-fish-event-for-all-player-interactions.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: booky10 -Date: Mon, 3 Jul 2023 01:55:32 +0200 -Subject: [PATCH] Add hand to fish event for all player interactions - - -diff --git a/src/main/java/org/bukkit/event/player/PlayerFishEvent.java b/src/main/java/org/bukkit/event/player/PlayerFishEvent.java -index 45342030ad0f46632d3ee9a6d0348251f8ee375f..d4001f64a7ee9d5173e9bafd9c45860cbda1fc85 100644 ---- a/src/main/java/org/bukkit/event/player/PlayerFishEvent.java -+++ b/src/main/java/org/bukkit/event/player/PlayerFishEvent.java -@@ -94,8 +94,9 @@ public class PlayerFishEvent extends PlayerEvent implements Cancellable { - /** - * Get the hand that was used in this event. - *

-- * The hand used is only present when the event state is {@link State#FISHING}. -- * In all other states, the hand is null. -+ * The hand used is only present for player interactions. -+ * This means it will be null if state is set -+ * to {@link State#BITE} or {@link State#FAILED_ATTEMPT}. - * - * @return the hand - */ diff --git a/patches/api/0428-Add-UUID-attribute-modifier-API.patch b/patches/api/0428-Add-UUID-attribute-modifier-API.patch deleted file mode 100644 index 64de52c83e..0000000000 --- a/patches/api/0428-Add-UUID-attribute-modifier-API.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: TonytheMacaroni -Date: Thu, 9 Nov 2023 20:35:35 -0500 -Subject: [PATCH] Add UUID attribute modifier API - - -diff --git a/src/main/java/org/bukkit/attribute/AttributeInstance.java b/src/main/java/org/bukkit/attribute/AttributeInstance.java -index 5513174ea545bb5b4fdc028cbaa4c1bb763e2c6d..f1fa86ddf1f50a357c9e94cc61261d8c96a2da6f 100644 ---- a/src/main/java/org/bukkit/attribute/AttributeInstance.java -+++ b/src/main/java/org/bukkit/attribute/AttributeInstance.java -@@ -39,6 +39,42 @@ public interface AttributeInstance { - @NotNull - Collection getModifiers(); - -+ // Paper start -+ /** -+ * Gets the modifier with the corresponding key. -+ * -+ * @param key the jey of the modifier -+ * @return the modifier, if it exists -+ */ -+ @org.jetbrains.annotations.Nullable AttributeModifier getModifier(@NotNull net.kyori.adventure.key.Key key); -+ -+ /** -+ * Remove a modifier with the corresponding key from this instance. -+ * -+ * @param key the key of the modifier -+ */ -+ void removeModifier(@NotNull net.kyori.adventure.key.Key key); -+ -+ /** -+ * Gets the modifier with the corresponding UUID. -+ * -+ * @param uuid the UUID of the modifier -+ * @return the modifier, if it exists -+ * @deprecated use {@link #getModifier(net.kyori.adventure.key.Key)}, modifiers are no longer stored by UUID -+ */ -+ @Deprecated(forRemoval = true, since = "1.21") -+ @org.jetbrains.annotations.Nullable AttributeModifier getModifier(@NotNull java.util.UUID uuid); -+ -+ /** -+ * Remove a modifier with the corresponding UUID from this instance. -+ * -+ * @param uuid the UUID of the modifier -+ * @deprecated use {@link #removeModifier(net.kyori.adventure.key.Key)}, modifiers are no longer stored by UUID -+ */ -+ @Deprecated(forRemoval = true, since = "1.21") -+ void removeModifier(@NotNull java.util.UUID uuid); -+ // Paper end -+ - /** - * Add a modifier to this instance. - * -diff --git a/src/main/java/org/bukkit/attribute/AttributeModifier.java b/src/main/java/org/bukkit/attribute/AttributeModifier.java -index d66502c9df2592cd18694481e7e90a71a5c3a359..90f18f355a6a236a7e4273cc1258e7c8034b8276 100644 ---- a/src/main/java/org/bukkit/attribute/AttributeModifier.java -+++ b/src/main/java/org/bukkit/attribute/AttributeModifier.java -@@ -25,22 +25,22 @@ public class AttributeModifier implements ConfigurationSerializable, Keyed { - private final Operation operation; - private final EquipmentSlotGroup slot; - -- @Deprecated -+ @Deprecated(forRemoval = true, since = "1.21") - public AttributeModifier(@NotNull String name, double amount, @NotNull Operation operation) { - this(UUID.randomUUID(), name, amount, operation); - } - -- @Deprecated -+ @Deprecated(forRemoval = true, since = "1.21") - public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation) { - this(uuid, name, amount, operation, (EquipmentSlot) null); - } - -- @Deprecated -+ @Deprecated(forRemoval = true, since = "1.21") - public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation, @Nullable EquipmentSlot slot) { - this(uuid, name, amount, operation, (slot) == null ? EquipmentSlotGroup.ANY : slot.getGroup()); - } - -- @Deprecated -+ @Deprecated(forRemoval = true, since = "1.21") - public AttributeModifier(@NotNull UUID uuid, @NotNull String name, double amount, @NotNull Operation operation, @NotNull EquipmentSlotGroup slot) { - this(NamespacedKey.fromString(uuid.toString()), amount, operation, slot); - } -@@ -63,7 +63,7 @@ public class AttributeModifier implements ConfigurationSerializable, Keyed { - * @deprecated attributes are now identified by keys - */ - @NotNull -- @Deprecated -+ @Deprecated(forRemoval = true, since = "1.21") - public UUID getUniqueId() { - return UUID.fromString(getKey().toString()); - } diff --git a/patches/api/0428-Expand-LingeringPotion-API.patch b/patches/api/0428-Expand-LingeringPotion-API.patch new file mode 100644 index 0000000000..40b5a5f547 --- /dev/null +++ b/patches/api/0428-Expand-LingeringPotion-API.patch @@ -0,0 +1,45 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tamion <70228790+notTamion@users.noreply.github.com> +Date: Sat, 4 Nov 2023 23:56:23 +0100 +Subject: [PATCH] Expand LingeringPotion API + + +diff --git a/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java b/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java +index 1584c6c41c3ca51b8ab7f48efb140b0fe31f535b..34efe59493729449fe1316ab8f2f7211acf679be 100644 +--- a/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java ++++ b/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java +@@ -17,6 +17,7 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + private final AreaEffectCloud entity; ++ private boolean allowEmptyAreaEffectCreation; // Paper + + @Deprecated + public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud entity) { +@@ -44,6 +45,26 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca + return entity; + } + ++ // Paper start ++ /** ++ * Sets if an Empty AreaEffectCloud may be created ++ * ++ * @param allowEmptyAreaEffectCreation If an Empty AreaEffectCloud may be created ++ */ ++ public void allowsEmptyCreation(boolean allowEmptyAreaEffectCreation) { ++ this.allowEmptyAreaEffectCreation = allowEmptyAreaEffectCreation; ++ } ++ ++ /** ++ * Gets if an empty AreaEffectCloud may be created ++ * ++ * @return if an empty AreaEffectCloud may be created ++ */ ++ public boolean allowsEmptyCreation() { ++ return allowEmptyAreaEffectCreation; ++ } ++ // Paper end ++ + @Override + public boolean isCancelled() { + return cancelled; diff --git a/patches/api/0429-Expand-LingeringPotion-API.patch b/patches/api/0429-Expand-LingeringPotion-API.patch deleted file mode 100644 index 40b5a5f547..0000000000 --- a/patches/api/0429-Expand-LingeringPotion-API.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tamion <70228790+notTamion@users.noreply.github.com> -Date: Sat, 4 Nov 2023 23:56:23 +0100 -Subject: [PATCH] Expand LingeringPotion API - - -diff --git a/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java b/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java -index 1584c6c41c3ca51b8ab7f48efb140b0fe31f535b..34efe59493729449fe1316ab8f2f7211acf679be 100644 ---- a/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java -+++ b/src/main/java/org/bukkit/event/entity/LingeringPotionSplashEvent.java -@@ -17,6 +17,7 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca - private static final HandlerList handlers = new HandlerList(); - private boolean cancelled; - private final AreaEffectCloud entity; -+ private boolean allowEmptyAreaEffectCreation; // Paper - - @Deprecated - public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud entity) { -@@ -44,6 +45,26 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca - return entity; - } - -+ // Paper start -+ /** -+ * Sets if an Empty AreaEffectCloud may be created -+ * -+ * @param allowEmptyAreaEffectCreation If an Empty AreaEffectCloud may be created -+ */ -+ public void allowsEmptyCreation(boolean allowEmptyAreaEffectCreation) { -+ this.allowEmptyAreaEffectCreation = allowEmptyAreaEffectCreation; -+ } -+ -+ /** -+ * Gets if an empty AreaEffectCloud may be created -+ * -+ * @return if an empty AreaEffectCloud may be created -+ */ -+ public boolean allowsEmptyCreation() { -+ return allowEmptyAreaEffectCreation; -+ } -+ // Paper end -+ - @Override - public boolean isCancelled() { - return cancelled; diff --git a/patches/api/0429-Remove-unnecessary-durability-check-in-ItemStack-isS.patch b/patches/api/0429-Remove-unnecessary-durability-check-in-ItemStack-isS.patch new file mode 100644 index 0000000000..72deb7498e --- /dev/null +++ b/patches/api/0429-Remove-unnecessary-durability-check-in-ItemStack-isS.patch @@ -0,0 +1,23 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrPowerGamerBR +Date: Sun, 26 Nov 2023 20:00:50 -0300 +Subject: [PATCH] Remove unnecessary durability check in + "ItemStack#isSimilar(...)" + +By removing this check we avoid unnecessarily allocating useless `ItemMeta` objects if we are comparing two items, or one of the two items, that don't have any durability. Don't worry, the durability of the item is checked when it checks if both item metas are equal. + +This is a leftover from when checking for the item's durability was "free" because the durability was stored in the `ItemStack` itself, this [was changed in Minecraft 1.13](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/f8b2086d60942eb2cd7ac25a2a1408cb790c222c#src/main/java/org/bukkit/inventory/ItemStack.java). + +diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java +index 9d397c395d777f337a421fac8fea064680065661..c5e22bca27f3199eb2a466f41aa82047f5fd0e44 100644 +--- a/src/main/java/org/bukkit/inventory/ItemStack.java ++++ b/src/main/java/org/bukkit/inventory/ItemStack.java +@@ -307,7 +307,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat + return true; + } + Material comparisonType = (this.type.isLegacy()) ? Bukkit.getUnsafe().fromLegacy(this.getData(), true) : this.type; // This may be called from legacy item stacks, try to get the right material +- return comparisonType == stack.getType() && getDurability() == stack.getDurability() && hasItemMeta() == stack.hasItemMeta() && (hasItemMeta() ? Bukkit.getItemFactory().equals(getItemMeta(), stack.getItemMeta()) : true); ++ return comparisonType == stack.getType() && /* getDurability() == stack.getDurability() && */hasItemMeta() == stack.hasItemMeta() && (hasItemMeta() ? Bukkit.getItemFactory().equals(getItemMeta(), stack.getItemMeta()) : true); // Paper - remove redundant item durability check + } + + @NotNull diff --git a/patches/api/0430-Add-Structure-check-API.patch b/patches/api/0430-Add-Structure-check-API.patch new file mode 100644 index 0000000000..e2d19afb32 --- /dev/null +++ b/patches/api/0430-Add-Structure-check-API.patch @@ -0,0 +1,41 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Mon, 27 Mar 2023 10:20:06 -0700 +Subject: [PATCH] Add Structure check API + + +diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java +index 02184b68cc126b278985fd966e3c8e4ade18c464..ecc2d486cfec79cce27a947dfeed4853575a594d 100644 +--- a/src/main/java/org/bukkit/World.java ++++ b/src/main/java/org/bukkit/World.java +@@ -78,6 +78,30 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient + */ + int getPlayerCount(); + // Paper end ++ // Paper start - structure check API ++ /** ++ * Check if the naturally-generated structure exists at the position. ++ *

++ * Note that if the position is not loaded, this may cause chunk loads/generation ++ * to check if a structure is at that position. Use {@link #isPositionLoaded(io.papermc.paper.math.Position)} ++ * to check if a position is loaded ++ * ++ * @param position the position to check at ++ * @param structure the structure to check for ++ * @return true if that structure exists at the position ++ */ ++ boolean hasStructureAt(io.papermc.paper.math.@NotNull Position position, @NotNull Structure structure); ++ ++ /** ++ * Checks if this position is loaded. ++ * ++ * @param position position to check ++ * @return true if loaded ++ */ ++ default boolean isPositionLoaded(io.papermc.paper.math.@NotNull Position position) { ++ return this.isChunkLoaded(position.blockX() >> 4, position.blockZ() >> 4); ++ } ++ // Paper end + + /** + * Gets the {@link Block} at the given coordinates diff --git a/patches/api/0430-Remove-unnecessary-durability-check-in-ItemStack-isS.patch b/patches/api/0430-Remove-unnecessary-durability-check-in-ItemStack-isS.patch deleted file mode 100644 index 72deb7498e..0000000000 --- a/patches/api/0430-Remove-unnecessary-durability-check-in-ItemStack-isS.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: MrPowerGamerBR -Date: Sun, 26 Nov 2023 20:00:50 -0300 -Subject: [PATCH] Remove unnecessary durability check in - "ItemStack#isSimilar(...)" - -By removing this check we avoid unnecessarily allocating useless `ItemMeta` objects if we are comparing two items, or one of the two items, that don't have any durability. Don't worry, the durability of the item is checked when it checks if both item metas are equal. - -This is a leftover from when checking for the item's durability was "free" because the durability was stored in the `ItemStack` itself, this [was changed in Minecraft 1.13](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/commits/f8b2086d60942eb2cd7ac25a2a1408cb790c222c#src/main/java/org/bukkit/inventory/ItemStack.java). - -diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 9d397c395d777f337a421fac8fea064680065661..c5e22bca27f3199eb2a466f41aa82047f5fd0e44 100644 ---- a/src/main/java/org/bukkit/inventory/ItemStack.java -+++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -307,7 +307,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat - return true; - } - Material comparisonType = (this.type.isLegacy()) ? Bukkit.getUnsafe().fromLegacy(this.getData(), true) : this.type; // This may be called from legacy item stacks, try to get the right material -- return comparisonType == stack.getType() && getDurability() == stack.getDurability() && hasItemMeta() == stack.hasItemMeta() && (hasItemMeta() ? Bukkit.getItemFactory().equals(getItemMeta(), stack.getItemMeta()) : true); -+ return comparisonType == stack.getType() && /* getDurability() == stack.getDurability() && */hasItemMeta() == stack.hasItemMeta() && (hasItemMeta() ? Bukkit.getItemFactory().equals(getItemMeta(), stack.getItemMeta()) : true); // Paper - remove redundant item durability check - } - - @NotNull diff --git a/patches/api/0431-Add-Structure-check-API.patch b/patches/api/0431-Add-Structure-check-API.patch deleted file mode 100644 index e2d19afb32..0000000000 --- a/patches/api/0431-Add-Structure-check-API.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Mon, 27 Mar 2023 10:20:06 -0700 -Subject: [PATCH] Add Structure check API - - -diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index 02184b68cc126b278985fd966e3c8e4ade18c464..ecc2d486cfec79cce27a947dfeed4853575a594d 100644 ---- a/src/main/java/org/bukkit/World.java -+++ b/src/main/java/org/bukkit/World.java -@@ -78,6 +78,30 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient - */ - int getPlayerCount(); - // Paper end -+ // Paper start - structure check API -+ /** -+ * Check if the naturally-generated structure exists at the position. -+ *

-+ * Note that if the position is not loaded, this may cause chunk loads/generation -+ * to check if a structure is at that position. Use {@link #isPositionLoaded(io.papermc.paper.math.Position)} -+ * to check if a position is loaded -+ * -+ * @param position the position to check at -+ * @param structure the structure to check for -+ * @return true if that structure exists at the position -+ */ -+ boolean hasStructureAt(io.papermc.paper.math.@NotNull Position position, @NotNull Structure structure); -+ -+ /** -+ * Checks if this position is loaded. -+ * -+ * @param position position to check -+ * @return true if loaded -+ */ -+ default boolean isPositionLoaded(io.papermc.paper.math.@NotNull Position position) { -+ return this.isChunkLoaded(position.blockX() >> 4, position.blockZ() >> 4); -+ } -+ // Paper end - - /** - * Gets the {@link Block} at the given coordinates diff --git a/patches/api/0431-add-missing-Experimental-annotations.patch b/patches/api/0431-add-missing-Experimental-annotations.patch new file mode 100644 index 0000000000..5646e558f5 --- /dev/null +++ b/patches/api/0431-add-missing-Experimental-annotations.patch @@ -0,0 +1,112 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 9 Dec 2023 11:47:53 -0800 +Subject: [PATCH] add missing Experimental annotations + + +diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java +index 7522c611b5214dd09867c434d5f7cf161f5c04ca..026b1832bcd163ab89668c991bf002e608e36aef 100644 +--- a/src/main/java/org/bukkit/FeatureFlag.java ++++ b/src/main/java/org/bukkit/FeatureFlag.java +@@ -13,6 +13,7 @@ public interface FeatureFlag extends Keyed { + + public static final FeatureFlag VANILLA = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("vanilla")); + ++ @ApiStatus.Experimental // Paper - add missing annotation + public static final FeatureFlag BUNDLE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("bundle")); + + /** +@@ -23,6 +24,7 @@ public interface FeatureFlag extends Keyed { + @Deprecated + public static final FeatureFlag UPDATE_1_20 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_20")); + ++ @ApiStatus.Experimental // Paper - add missing annotation + public static final FeatureFlag TRADE_REBALANCE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("trade_rebalance")); + + /** +diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java +index c4f067598a40b0381bc9e601a3809e2683c10407..54704da43cf9c429f3914f0580246dde99aa93c0 100644 +--- a/src/main/java/org/bukkit/Material.java ++++ b/src/main/java/org/bukkit/Material.java +@@ -2497,6 +2497,8 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla + EGG(21603, 16), + COMPASS(24139), + RECOVERY_COMPASS(12710), ++ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation ++ @ApiStatus.Experimental // Paper - add missing annotation + BUNDLE(16835, 1), + FISHING_ROD(4167, 1, 64), + CLOCK(14980), +diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java +index b2ff1da3386223a544ab5fc363a90c66c8869242..8c7b50906fc5b84c5570408f357410810bbfbded 100644 +--- a/src/main/java/org/bukkit/Sound.java ++++ b/src/main/java/org/bukkit/Sound.java +@@ -1506,8 +1506,14 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa + ITEM_BUCKET_FILL_LAVA("item.bucket.fill_lava"), + ITEM_BUCKET_FILL_POWDER_SNOW("item.bucket.fill_powder_snow"), + ITEM_BUCKET_FILL_TADPOLE("item.bucket.fill_tadpole"), ++ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + ITEM_BUNDLE_DROP_CONTENTS("item.bundle.drop_contents"), ++ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + ITEM_BUNDLE_INSERT("item.bundle.insert"), ++ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"), + ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), + ITEM_CROP_PLANT("item.crop.plant"), +diff --git a/src/main/java/org/bukkit/Tag.java b/src/main/java/org/bukkit/Tag.java +index 8bfec649f7c6dda956bc388a21b489f3565ff384..a303bb1a8d8b5749de5d69d079383e6da2e446d1 100644 +--- a/src/main/java/org/bukkit/Tag.java ++++ b/src/main/java/org/bukkit/Tag.java +@@ -1253,6 +1253,7 @@ public interface Tag extends Keyed { + /** + * Vanilla tag representing entities which can turn in boats. + */ ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + Tag ENTITY_TYPES_CAN_TURN_IN_BOATS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_turn_in_boats"), EntityType.class); + /** + * Vanilla tag representing all entities sensitive to illager enchantments. +diff --git a/src/main/java/org/bukkit/inventory/meta/BundleMeta.java b/src/main/java/org/bukkit/inventory/meta/BundleMeta.java +index e404cd1e2ba44e4c2d09524bc7cf730d8ffbdabd..cea0ebf50876dd32ab7fba6025b30f297d0a69c4 100644 +--- a/src/main/java/org/bukkit/inventory/meta/BundleMeta.java ++++ b/src/main/java/org/bukkit/inventory/meta/BundleMeta.java +@@ -6,6 +6,7 @@ import org.jetbrains.annotations.ApiStatus; + import org.jetbrains.annotations.NotNull; + import org.jetbrains.annotations.Nullable; + ++@org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation + @ApiStatus.Experimental + public interface BundleMeta extends ItemMeta { + +diff --git a/src/main/java/org/bukkit/map/MapCursor.java b/src/main/java/org/bukkit/map/MapCursor.java +index 82993302cb3cf62ad4a94a0ebaa7711cc4d8e550..44773ab211f11e924aadea14b965ec52b0483377 100644 +--- a/src/main/java/org/bukkit/map/MapCursor.java ++++ b/src/main/java/org/bukkit/map/MapCursor.java +@@ -309,12 +309,25 @@ public final class MapCursor { + BANNER_RED(24, "banner_red"), + BANNER_BLACK(25, "banner_black"), + RED_X(26, "red_x"), ++ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + VILLAGE_DESERT(27, "village_desert"), ++ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + VILLAGE_PLAINS(28, "village_plains"), ++ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + VILLAGE_SAVANNA(29, "village_savanna"), ++ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + VILLAGE_SNOWY(30, "village_snowy"), ++ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + VILLAGE_TAIGA(31, "village_taiga"), ++ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation ++ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation + JUNGLE_TEMPLE(32, "jungle_temple"), ++ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation + SWAMP_HUT(33, "swamp_hut"), + TRIAL_CHAMBERS(34, "trial_chambers") + ; diff --git a/patches/api/0432-Add-more-scoreboard-API.patch b/patches/api/0432-Add-more-scoreboard-API.patch new file mode 100644 index 0000000000..201af36b0c --- /dev/null +++ b/patches/api/0432-Add-more-scoreboard-API.patch @@ -0,0 +1,90 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 16 Dec 2023 14:45:46 -0800 +Subject: [PATCH] Add more scoreboard API + + +diff --git a/src/main/java/org/bukkit/scoreboard/Objective.java b/src/main/java/org/bukkit/scoreboard/Objective.java +index a193ffabb05160b462dee1ba8f687fdbc84405b6..bd4d84cbf220ab02f09ece97873bbf0bdf7a45ba 100644 +--- a/src/main/java/org/bukkit/scoreboard/Objective.java ++++ b/src/main/java/org/bukkit/scoreboard/Objective.java +@@ -175,4 +175,24 @@ public interface Objective { + */ + @NotNull Score getScoreFor(@NotNull org.bukkit.entity.Entity entity) throws IllegalArgumentException, IllegalStateException; + // Paper end - improve scoreboard entries ++ ++ // Paper start - add more score API ++ /** ++ * Gets if this objective will auto update score ++ * displays on changes. ++ * ++ * @return true if auto updating ++ * @throws IllegalStateException if this objective has been unregistered ++ */ ++ boolean willAutoUpdateDisplay(); ++ ++ /** ++ * Sets if this objective will auto update ++ * score displays on changes. ++ * ++ * @param autoUpdateDisplay true to auto update ++ * @throws IllegalStateException if this objective has been unregistered ++ */ ++ void setAutoUpdateDisplay(boolean autoUpdateDisplay); ++ // Paper end - add more score API + } +diff --git a/src/main/java/org/bukkit/scoreboard/Score.java b/src/main/java/org/bukkit/scoreboard/Score.java +index 1eaa9a93f8eff5f18a6cce2d74f21eb19db273c8..5b6f243492d55d2db0d6944dc6daca9b181551d6 100644 +--- a/src/main/java/org/bukkit/scoreboard/Score.java ++++ b/src/main/java/org/bukkit/scoreboard/Score.java +@@ -83,4 +83,50 @@ public interface Score { + */ + void resetScore() throws IllegalStateException; + // Paper end ++ ++ // Paper start - add more score API ++ /** ++ * Gets if this score is triggerable and cannot ++ * be used by the {@code /trigger} command executed ++ * by the owner of this score. ++ * ++ * @return true if triggerable, false if not triggerable, score isn't set, or the objective isn't {@link Criteria#TRIGGER} ++ * @throws IllegalStateException if the associated objective has been unregistered ++ */ ++ boolean isTriggerable(); ++ ++ /** ++ * Sets if this score is triggerable and can ++ * be used by the {@code /trigger} command ++ * executed by the owner of this score. Can ++ * only be set on {@link Criteria#TRIGGER} objectives. ++ *

++ * If the score doesn't exist (aka {@link #isScoreSet()} returns false), ++ * this will create the score with a 0 value. ++ * ++ * @param triggerable true to enable trigger, false to disable ++ * @throws IllegalArgumentException if this objective isn't {@link Criteria#TRIGGER} ++ * @throws IllegalStateException if the associated objective has been unregistered ++ */ ++ void setTriggerable(boolean triggerable); ++ ++ /** ++ * Get the custom name for this entry. ++ * ++ * @return the custom name or null if not set (or score isn't set) ++ * @throws IllegalStateException if the associated objective has been unregistered ++ */ ++ @Nullable net.kyori.adventure.text.Component customName(); ++ ++ /** ++ * Sets the custom name for this entry. ++ *

++ * If the score doesn't exist (aka {@link #isScoreSet()} returns false), ++ * this will create the score with a 0 value. ++ * ++ * @param customName the custom name or null to reset ++ * @throws IllegalStateException if the associated objective has been unregistered ++ */ ++ void customName(net.kyori.adventure.text.@Nullable Component customName); ++ // Paper end - add more score API + } diff --git a/patches/api/0432-add-missing-Experimental-annotations.patch b/patches/api/0432-add-missing-Experimental-annotations.patch deleted file mode 100644 index 5646e558f5..0000000000 --- a/patches/api/0432-add-missing-Experimental-annotations.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 9 Dec 2023 11:47:53 -0800 -Subject: [PATCH] add missing Experimental annotations - - -diff --git a/src/main/java/org/bukkit/FeatureFlag.java b/src/main/java/org/bukkit/FeatureFlag.java -index 7522c611b5214dd09867c434d5f7cf161f5c04ca..026b1832bcd163ab89668c991bf002e608e36aef 100644 ---- a/src/main/java/org/bukkit/FeatureFlag.java -+++ b/src/main/java/org/bukkit/FeatureFlag.java -@@ -13,6 +13,7 @@ public interface FeatureFlag extends Keyed { - - public static final FeatureFlag VANILLA = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("vanilla")); - -+ @ApiStatus.Experimental // Paper - add missing annotation - public static final FeatureFlag BUNDLE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("bundle")); - - /** -@@ -23,6 +24,7 @@ public interface FeatureFlag extends Keyed { - @Deprecated - public static final FeatureFlag UPDATE_1_20 = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("update_1_20")); - -+ @ApiStatus.Experimental // Paper - add missing annotation - public static final FeatureFlag TRADE_REBALANCE = Bukkit.getUnsafe().getFeatureFlag(NamespacedKey.minecraft("trade_rebalance")); - - /** -diff --git a/src/main/java/org/bukkit/Material.java b/src/main/java/org/bukkit/Material.java -index c4f067598a40b0381bc9e601a3809e2683c10407..54704da43cf9c429f3914f0580246dde99aa93c0 100644 ---- a/src/main/java/org/bukkit/Material.java -+++ b/src/main/java/org/bukkit/Material.java -@@ -2497,6 +2497,8 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla - EGG(21603, 16), - COMPASS(24139), - RECOVERY_COMPASS(12710), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @ApiStatus.Experimental // Paper - add missing annotation - BUNDLE(16835, 1), - FISHING_ROD(4167, 1, 64), - CLOCK(14980), -diff --git a/src/main/java/org/bukkit/Sound.java b/src/main/java/org/bukkit/Sound.java -index b2ff1da3386223a544ab5fc363a90c66c8869242..8c7b50906fc5b84c5570408f357410810bbfbded 100644 ---- a/src/main/java/org/bukkit/Sound.java -+++ b/src/main/java/org/bukkit/Sound.java -@@ -1506,8 +1506,14 @@ public enum Sound implements Keyed, net.kyori.adventure.sound.Sound.Type { // Pa - ITEM_BUCKET_FILL_LAVA("item.bucket.fill_lava"), - ITEM_BUCKET_FILL_POWDER_SNOW("item.bucket.fill_powder_snow"), - ITEM_BUCKET_FILL_TADPOLE("item.bucket.fill_tadpole"), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_DROP_CONTENTS("item.bundle.drop_contents"), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_INSERT("item.bundle.insert"), -+ @MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - ITEM_BUNDLE_REMOVE_ONE("item.bundle.remove_one"), - ITEM_CHORUS_FRUIT_TELEPORT("item.chorus_fruit.teleport"), - ITEM_CROP_PLANT("item.crop.plant"), -diff --git a/src/main/java/org/bukkit/Tag.java b/src/main/java/org/bukkit/Tag.java -index 8bfec649f7c6dda956bc388a21b489f3565ff384..a303bb1a8d8b5749de5d69d079383e6da2e446d1 100644 ---- a/src/main/java/org/bukkit/Tag.java -+++ b/src/main/java/org/bukkit/Tag.java -@@ -1253,6 +1253,7 @@ public interface Tag extends Keyed { - /** - * Vanilla tag representing entities which can turn in boats. - */ -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - Tag ENTITY_TYPES_CAN_TURN_IN_BOATS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_turn_in_boats"), EntityType.class); - /** - * Vanilla tag representing all entities sensitive to illager enchantments. -diff --git a/src/main/java/org/bukkit/inventory/meta/BundleMeta.java b/src/main/java/org/bukkit/inventory/meta/BundleMeta.java -index e404cd1e2ba44e4c2d09524bc7cf730d8ffbdabd..cea0ebf50876dd32ab7fba6025b30f297d0a69c4 100644 ---- a/src/main/java/org/bukkit/inventory/meta/BundleMeta.java -+++ b/src/main/java/org/bukkit/inventory/meta/BundleMeta.java -@@ -6,6 +6,7 @@ import org.jetbrains.annotations.ApiStatus; - import org.jetbrains.annotations.NotNull; - import org.jetbrains.annotations.Nullable; - -+@org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.BUNDLE) // Paper - add missing annotation - @ApiStatus.Experimental - public interface BundleMeta extends ItemMeta { - -diff --git a/src/main/java/org/bukkit/map/MapCursor.java b/src/main/java/org/bukkit/map/MapCursor.java -index 82993302cb3cf62ad4a94a0ebaa7711cc4d8e550..44773ab211f11e924aadea14b965ec52b0483377 100644 ---- a/src/main/java/org/bukkit/map/MapCursor.java -+++ b/src/main/java/org/bukkit/map/MapCursor.java -@@ -309,12 +309,25 @@ public final class MapCursor { - BANNER_RED(24, "banner_red"), - BANNER_BLACK(25, "banner_black"), - RED_X(26, "red_x"), -+ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - VILLAGE_DESERT(27, "village_desert"), -+ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - VILLAGE_PLAINS(28, "village_plains"), -+ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - VILLAGE_SAVANNA(29, "village_savanna"), -+ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - VILLAGE_SNOWY(30, "village_snowy"), -+ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - VILLAGE_TAIGA(31, "village_taiga"), -+ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation -+ @org.jetbrains.annotations.ApiStatus.Experimental // Paper - add missing annotation - JUNGLE_TEMPLE(32, "jungle_temple"), -+ @org.bukkit.MinecraftExperimental(org.bukkit.MinecraftExperimental.Requires.TRADE_REBALANCE) // Paper - add missing annotation - SWAMP_HUT(33, "swamp_hut"), - TRIAL_CHAMBERS(34, "trial_chambers") - ; diff --git a/patches/api/0433-Add-more-scoreboard-API.patch b/patches/api/0433-Add-more-scoreboard-API.patch deleted file mode 100644 index 201af36b0c..0000000000 --- a/patches/api/0433-Add-more-scoreboard-API.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 16 Dec 2023 14:45:46 -0800 -Subject: [PATCH] Add more scoreboard API - - -diff --git a/src/main/java/org/bukkit/scoreboard/Objective.java b/src/main/java/org/bukkit/scoreboard/Objective.java -index a193ffabb05160b462dee1ba8f687fdbc84405b6..bd4d84cbf220ab02f09ece97873bbf0bdf7a45ba 100644 ---- a/src/main/java/org/bukkit/scoreboard/Objective.java -+++ b/src/main/java/org/bukkit/scoreboard/Objective.java -@@ -175,4 +175,24 @@ public interface Objective { - */ - @NotNull Score getScoreFor(@NotNull org.bukkit.entity.Entity entity) throws IllegalArgumentException, IllegalStateException; - // Paper end - improve scoreboard entries -+ -+ // Paper start - add more score API -+ /** -+ * Gets if this objective will auto update score -+ * displays on changes. -+ * -+ * @return true if auto updating -+ * @throws IllegalStateException if this objective has been unregistered -+ */ -+ boolean willAutoUpdateDisplay(); -+ -+ /** -+ * Sets if this objective will auto update -+ * score displays on changes. -+ * -+ * @param autoUpdateDisplay true to auto update -+ * @throws IllegalStateException if this objective has been unregistered -+ */ -+ void setAutoUpdateDisplay(boolean autoUpdateDisplay); -+ // Paper end - add more score API - } -diff --git a/src/main/java/org/bukkit/scoreboard/Score.java b/src/main/java/org/bukkit/scoreboard/Score.java -index 1eaa9a93f8eff5f18a6cce2d74f21eb19db273c8..5b6f243492d55d2db0d6944dc6daca9b181551d6 100644 ---- a/src/main/java/org/bukkit/scoreboard/Score.java -+++ b/src/main/java/org/bukkit/scoreboard/Score.java -@@ -83,4 +83,50 @@ public interface Score { - */ - void resetScore() throws IllegalStateException; - // Paper end -+ -+ // Paper start - add more score API -+ /** -+ * Gets if this score is triggerable and cannot -+ * be used by the {@code /trigger} command executed -+ * by the owner of this score. -+ * -+ * @return true if triggerable, false if not triggerable, score isn't set, or the objective isn't {@link Criteria#TRIGGER} -+ * @throws IllegalStateException if the associated objective has been unregistered -+ */ -+ boolean isTriggerable(); -+ -+ /** -+ * Sets if this score is triggerable and can -+ * be used by the {@code /trigger} command -+ * executed by the owner of this score. Can -+ * only be set on {@link Criteria#TRIGGER} objectives. -+ *

-+ * If the score doesn't exist (aka {@link #isScoreSet()} returns false), -+ * this will create the score with a 0 value. -+ * -+ * @param triggerable true to enable trigger, false to disable -+ * @throws IllegalArgumentException if this objective isn't {@link Criteria#TRIGGER} -+ * @throws IllegalStateException if the associated objective has been unregistered -+ */ -+ void setTriggerable(boolean triggerable); -+ -+ /** -+ * Get the custom name for this entry. -+ * -+ * @return the custom name or null if not set (or score isn't set) -+ * @throws IllegalStateException if the associated objective has been unregistered -+ */ -+ @Nullable net.kyori.adventure.text.Component customName(); -+ -+ /** -+ * Sets the custom name for this entry. -+ *

-+ * If the score doesn't exist (aka {@link #isScoreSet()} returns false), -+ * this will create the score with a 0 value. -+ * -+ * @param customName the custom name or null to reset -+ * @throws IllegalStateException if the associated objective has been unregistered -+ */ -+ void customName(net.kyori.adventure.text.@Nullable Component customName); -+ // Paper end - add more score API - } diff --git a/patches/api/0433-Improve-Registry.patch b/patches/api/0433-Improve-Registry.patch new file mode 100644 index 0000000000..8a49d39633 --- /dev/null +++ b/patches/api/0433-Improve-Registry.patch @@ -0,0 +1,173 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Wed, 20 Dec 2023 02:03:10 -0800 +Subject: [PATCH] Improve Registry + +Adds Registry#getKey(Object) which should be the +primary way people get the key for an object. Registry +items need to exist without having a key and so +getKey() methods on Keyed objects that have a registry +are marked as Deprecated or Obsolete. + +diff --git a/src/main/java/org/bukkit/MusicInstrument.java b/src/main/java/org/bukkit/MusicInstrument.java +index 62d2b3f950860dee0898d77b0a29635c3f9a7e23..704dba92f9246ef398ed8d162ebee3cf305960e1 100644 +--- a/src/main/java/org/bukkit/MusicInstrument.java ++++ b/src/main/java/org/bukkit/MusicInstrument.java +@@ -53,6 +53,16 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran + return instrument; + } + ++ // Paper start - deprecate getKey ++ /** ++ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#INSTRUMENT}. MusicInstruments ++ * can exist without a key. ++ */ ++ @Deprecated ++ @Override ++ public abstract @NotNull NamespacedKey getKey(); ++ // Paper end - deprecate getKey ++ + // Paper start - translation key + @Override + public @NotNull String translationKey() { +diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java +index 17714f04fdd87ed4332ea62bcfab7063560bf1be..bc7144f02ac6857dbeec13c3995b71f6920e022a 100644 +--- a/src/main/java/org/bukkit/Registry.java ++++ b/src/main/java/org/bukkit/Registry.java +@@ -358,6 +358,49 @@ public interface Registry extends Iterable { + @Nullable + T get(@NotNull NamespacedKey key); + ++ // Paper start - improve Registry ++ /** ++ * Gets the key for this object or throws if it doesn't exist. ++ *

++ * Some types can exist without being in a registry ++ * and such will have no key associated with them. This ++ * method throw an exception if it isn't in this registry. ++ * ++ * @param value the value to get the key of in this registry ++ * @return the key for the value ++ * @throws java.util.NoSuchElementException if the value doesn't exist in this registry ++ * @see #getKey(Keyed) ++ */ ++ default @NotNull NamespacedKey getKeyOrThrow(final @NotNull T value) { ++ Preconditions.checkArgument(value != null, "value cannot be null"); ++ final NamespacedKey key = this.getKey(value); ++ if (key == null) { ++ throw new java.util.NoSuchElementException(value + " has no key in " + this); ++ } ++ return key; ++ } ++ ++ /** ++ * Get the key for this object. ++ *

++ * Some types can exist without being in a registry ++ * and such will have no key associated with them. This ++ * method will return null. ++ * ++ * @param value the value to get the key of in this registry ++ * @return the key for the value or null if not in the registry ++ * @see #getKeyOrThrow(Keyed) ++ */ ++ default @Nullable NamespacedKey getKey(final @NotNull T value) { ++ Preconditions.checkArgument(value != null, "value cannot be null"); ++ //noinspection ConstantValue (it might not be in the future...) ++ if (value instanceof Keyed) { ++ return value.getKey(); ++ } ++ return null; ++ } ++ // Paper end - improve Registry ++ + /** + * Returns a new stream, which contains all registry items, which are registered to the registry. + * +@@ -432,5 +475,12 @@ public interface Registry extends Iterable { + public Class getType() { + return this.type; + } ++ ++ // Paper start - improve Registry ++ @Override ++ public @NotNull NamespacedKey getKey(final @NotNull T value) { ++ return value.getKey(); ++ } ++ // Paper end - improve Registry + } + } +diff --git a/src/main/java/org/bukkit/block/banner/PatternType.java b/src/main/java/org/bukkit/block/banner/PatternType.java +index 6a6be0287255cf38a735bfc83ec91644dc96b903..1883183157c875d87656fdc86a589e9b95dc4895 100644 +--- a/src/main/java/org/bukkit/block/banner/PatternType.java ++++ b/src/main/java/org/bukkit/block/banner/PatternType.java +@@ -69,6 +69,13 @@ public enum PatternType implements Keyed { + this.key = NamespacedKey.minecraft(key); + } + ++ // Paper start - deprecate getKey ++ /** ++ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#BANNER_PATTERN}. PatternTypes ++ * can exist without a key. ++ */ ++ @Deprecated ++ // Paper end - deprecate getKey + @Override + @NotNull + public NamespacedKey getKey() { +diff --git a/src/main/java/org/bukkit/generator/structure/Structure.java b/src/main/java/org/bukkit/generator/structure/Structure.java +index 1a766e68713d4014783b3224b9395644116784fa..978054ee364f9a3330525b9b50da5325ebb6ef57 100644 +--- a/src/main/java/org/bukkit/generator/structure/Structure.java ++++ b/src/main/java/org/bukkit/generator/structure/Structure.java +@@ -60,4 +60,13 @@ public abstract class Structure implements Keyed { + */ + @NotNull + public abstract StructureType getStructureType(); ++ // Paper start - deprecate getKey ++ /** ++ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#STRUCTURE}. Structures ++ * can exist without a key. ++ */ ++ @Override ++ @Deprecated(since = "1.20.4") ++ public abstract @NotNull NamespacedKey getKey(); ++ // Paper end - deprecate getKey + } +diff --git a/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java b/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java +index 941fac4eee338870d8c30cb1f64cab572cf54548..74816d6da4d7c8d2fa8a7b93fdc4bf29c8d12803 100644 +--- a/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java ++++ b/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java +@@ -68,4 +68,14 @@ public interface TrimMaterial extends Keyed, Translatable { + @Deprecated(forRemoval = true) + @org.jetbrains.annotations.NotNull String getTranslationKey(); + // Paper end - adventure ++ ++ // Paper start - Registry#getKey ++ /** ++ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#TRIM_MATERIAL}. TrimMaterials ++ * can exist without a key. ++ */ ++ @Deprecated(forRemoval = true, since = "1.20.4") ++ @Override ++ org.bukkit.@org.jetbrains.annotations.NotNull NamespacedKey getKey(); ++ // Paper end - Registry#getKey + } +diff --git a/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java b/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java +index f2242ddc4085f7e7cdd748d860857822e3d9b007..087e99ed281c0b282d91345067bfca80762faa0b 100644 +--- a/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java ++++ b/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java +@@ -100,4 +100,14 @@ public interface TrimPattern extends Keyed, Translatable { + @Deprecated(forRemoval = true) + @org.jetbrains.annotations.NotNull String getTranslationKey(); + // Paper end - adventure ++ ++ // Paper start - Registry#getKey ++ /** ++ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#TRIM_PATTERN}. TrimPatterns ++ * can exist without a key. ++ */ ++ @Deprecated(forRemoval = true, since = "1.20.4") ++ @Override ++ org.bukkit.@org.jetbrains.annotations.NotNull NamespacedKey getKey(); ++ // Paper end - Registry#getKey + } diff --git a/patches/api/0434-Add-experience-points-API.patch b/patches/api/0434-Add-experience-points-API.patch new file mode 100644 index 0000000000..9b489a9ded --- /dev/null +++ b/patches/api/0434-Add-experience-points-API.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lukas Planz +Date: Tue, 5 Sep 2023 20:33:52 +0200 +Subject: [PATCH] Add experience points API + + +diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java +index 09094f55509eaf66670c27409b4d5ec3d73412b0..4bc4a1c0c6f6759f984843823f1bbec6ffed92bc 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -1907,6 +1907,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + * @param exp New total experience points + */ + public void setTotalExperience(int exp); ++ // Paper start ++ /** ++ * Gets the players total amount of experience points he collected to reach the current level and level progress. ++ * ++ *

This method differs from {@link #getTotalExperience()} in that this method always returns an ++ * up-to-date value that reflects the players{@link #getLevel() level} and {@link #getExp() level progress}

++ * ++ * @return Current total experience points ++ * @see #getLevel() ++ * @see #getExp() ++ * @see #setExperienceLevelAndProgress(int) ++ */ ++ @org.jetbrains.annotations.Range(from = 0, to = Integer.MAX_VALUE) int calculateTotalExperiencePoints(); ++ ++ /** ++ * Updates the players level and level progress to that what would be reached when the total amount of experience ++ * had been collected. ++ * ++ *

This method differs from {@link #setTotalExperience(int)} in that this method actually updates the ++ * {@link #getLevel() level} and {@link #getExp() level progress} so that a subsequent call of ++ * {@link #calculateTotalExperiencePoints()} yields the same amount of points that have been set

++ * ++ * @param totalExperience New total experience points ++ * @see #setLevel(int) ++ * @see #setExp(float) ++ * @see #calculateTotalExperiencePoints() ++ */ ++ void setExperienceLevelAndProgress(@org.jetbrains.annotations.Range(from = 0, to = Integer.MAX_VALUE) int totalExperience); ++ ++ /** ++ * Gets the total amount of experience points that are needed to reach the next level from zero progress towards it. ++ * ++ *

Can be used with {@link #getExp()} to calculate the current points for the current level and alike

++ * ++ * @return The required experience points ++ * @see #getExp() ++ */ ++ int getExperiencePointsNeededForNextLevel(); ++ // Paper end + + /** + * Send an experience change. diff --git a/patches/api/0434-Improve-Registry.patch b/patches/api/0434-Improve-Registry.patch deleted file mode 100644 index 8a49d39633..0000000000 --- a/patches/api/0434-Improve-Registry.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Wed, 20 Dec 2023 02:03:10 -0800 -Subject: [PATCH] Improve Registry - -Adds Registry#getKey(Object) which should be the -primary way people get the key for an object. Registry -items need to exist without having a key and so -getKey() methods on Keyed objects that have a registry -are marked as Deprecated or Obsolete. - -diff --git a/src/main/java/org/bukkit/MusicInstrument.java b/src/main/java/org/bukkit/MusicInstrument.java -index 62d2b3f950860dee0898d77b0a29635c3f9a7e23..704dba92f9246ef398ed8d162ebee3cf305960e1 100644 ---- a/src/main/java/org/bukkit/MusicInstrument.java -+++ b/src/main/java/org/bukkit/MusicInstrument.java -@@ -53,6 +53,16 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran - return instrument; - } - -+ // Paper start - deprecate getKey -+ /** -+ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#INSTRUMENT}. MusicInstruments -+ * can exist without a key. -+ */ -+ @Deprecated -+ @Override -+ public abstract @NotNull NamespacedKey getKey(); -+ // Paper end - deprecate getKey -+ - // Paper start - translation key - @Override - public @NotNull String translationKey() { -diff --git a/src/main/java/org/bukkit/Registry.java b/src/main/java/org/bukkit/Registry.java -index 17714f04fdd87ed4332ea62bcfab7063560bf1be..bc7144f02ac6857dbeec13c3995b71f6920e022a 100644 ---- a/src/main/java/org/bukkit/Registry.java -+++ b/src/main/java/org/bukkit/Registry.java -@@ -358,6 +358,49 @@ public interface Registry extends Iterable { - @Nullable - T get(@NotNull NamespacedKey key); - -+ // Paper start - improve Registry -+ /** -+ * Gets the key for this object or throws if it doesn't exist. -+ *

-+ * Some types can exist without being in a registry -+ * and such will have no key associated with them. This -+ * method throw an exception if it isn't in this registry. -+ * -+ * @param value the value to get the key of in this registry -+ * @return the key for the value -+ * @throws java.util.NoSuchElementException if the value doesn't exist in this registry -+ * @see #getKey(Keyed) -+ */ -+ default @NotNull NamespacedKey getKeyOrThrow(final @NotNull T value) { -+ Preconditions.checkArgument(value != null, "value cannot be null"); -+ final NamespacedKey key = this.getKey(value); -+ if (key == null) { -+ throw new java.util.NoSuchElementException(value + " has no key in " + this); -+ } -+ return key; -+ } -+ -+ /** -+ * Get the key for this object. -+ *

-+ * Some types can exist without being in a registry -+ * and such will have no key associated with them. This -+ * method will return null. -+ * -+ * @param value the value to get the key of in this registry -+ * @return the key for the value or null if not in the registry -+ * @see #getKeyOrThrow(Keyed) -+ */ -+ default @Nullable NamespacedKey getKey(final @NotNull T value) { -+ Preconditions.checkArgument(value != null, "value cannot be null"); -+ //noinspection ConstantValue (it might not be in the future...) -+ if (value instanceof Keyed) { -+ return value.getKey(); -+ } -+ return null; -+ } -+ // Paper end - improve Registry -+ - /** - * Returns a new stream, which contains all registry items, which are registered to the registry. - * -@@ -432,5 +475,12 @@ public interface Registry extends Iterable { - public Class getType() { - return this.type; - } -+ -+ // Paper start - improve Registry -+ @Override -+ public @NotNull NamespacedKey getKey(final @NotNull T value) { -+ return value.getKey(); -+ } -+ // Paper end - improve Registry - } - } -diff --git a/src/main/java/org/bukkit/block/banner/PatternType.java b/src/main/java/org/bukkit/block/banner/PatternType.java -index 6a6be0287255cf38a735bfc83ec91644dc96b903..1883183157c875d87656fdc86a589e9b95dc4895 100644 ---- a/src/main/java/org/bukkit/block/banner/PatternType.java -+++ b/src/main/java/org/bukkit/block/banner/PatternType.java -@@ -69,6 +69,13 @@ public enum PatternType implements Keyed { - this.key = NamespacedKey.minecraft(key); - } - -+ // Paper start - deprecate getKey -+ /** -+ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#BANNER_PATTERN}. PatternTypes -+ * can exist without a key. -+ */ -+ @Deprecated -+ // Paper end - deprecate getKey - @Override - @NotNull - public NamespacedKey getKey() { -diff --git a/src/main/java/org/bukkit/generator/structure/Structure.java b/src/main/java/org/bukkit/generator/structure/Structure.java -index 1a766e68713d4014783b3224b9395644116784fa..978054ee364f9a3330525b9b50da5325ebb6ef57 100644 ---- a/src/main/java/org/bukkit/generator/structure/Structure.java -+++ b/src/main/java/org/bukkit/generator/structure/Structure.java -@@ -60,4 +60,13 @@ public abstract class Structure implements Keyed { - */ - @NotNull - public abstract StructureType getStructureType(); -+ // Paper start - deprecate getKey -+ /** -+ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#STRUCTURE}. Structures -+ * can exist without a key. -+ */ -+ @Override -+ @Deprecated(since = "1.20.4") -+ public abstract @NotNull NamespacedKey getKey(); -+ // Paper end - deprecate getKey - } -diff --git a/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java b/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java -index 941fac4eee338870d8c30cb1f64cab572cf54548..74816d6da4d7c8d2fa8a7b93fdc4bf29c8d12803 100644 ---- a/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java -+++ b/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java -@@ -68,4 +68,14 @@ public interface TrimMaterial extends Keyed, Translatable { - @Deprecated(forRemoval = true) - @org.jetbrains.annotations.NotNull String getTranslationKey(); - // Paper end - adventure -+ -+ // Paper start - Registry#getKey -+ /** -+ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#TRIM_MATERIAL}. TrimMaterials -+ * can exist without a key. -+ */ -+ @Deprecated(forRemoval = true, since = "1.20.4") -+ @Override -+ org.bukkit.@org.jetbrains.annotations.NotNull NamespacedKey getKey(); -+ // Paper end - Registry#getKey - } -diff --git a/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java b/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java -index f2242ddc4085f7e7cdd748d860857822e3d9b007..087e99ed281c0b282d91345067bfca80762faa0b 100644 ---- a/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java -+++ b/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java -@@ -100,4 +100,14 @@ public interface TrimPattern extends Keyed, Translatable { - @Deprecated(forRemoval = true) - @org.jetbrains.annotations.NotNull String getTranslationKey(); - // Paper end - adventure -+ -+ // Paper start - Registry#getKey -+ /** -+ * @deprecated use {@link Registry#getKey(Keyed)} and {@link Registry#TRIM_PATTERN}. TrimPatterns -+ * can exist without a key. -+ */ -+ @Deprecated(forRemoval = true, since = "1.20.4") -+ @Override -+ org.bukkit.@org.jetbrains.annotations.NotNull NamespacedKey getKey(); -+ // Paper end - Registry#getKey - } diff --git a/patches/api/0435-Add-experience-points-API.patch b/patches/api/0435-Add-experience-points-API.patch deleted file mode 100644 index 9b489a9ded..0000000000 --- a/patches/api/0435-Add-experience-points-API.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lukas Planz -Date: Tue, 5 Sep 2023 20:33:52 +0200 -Subject: [PATCH] Add experience points API - - -diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 09094f55509eaf66670c27409b4d5ec3d73412b0..4bc4a1c0c6f6759f984843823f1bbec6ffed92bc 100644 ---- a/src/main/java/org/bukkit/entity/Player.java -+++ b/src/main/java/org/bukkit/entity/Player.java -@@ -1907,6 +1907,45 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - * @param exp New total experience points - */ - public void setTotalExperience(int exp); -+ // Paper start -+ /** -+ * Gets the players total amount of experience points he collected to reach the current level and level progress. -+ * -+ *

This method differs from {@link #getTotalExperience()} in that this method always returns an -+ * up-to-date value that reflects the players{@link #getLevel() level} and {@link #getExp() level progress}

-+ * -+ * @return Current total experience points -+ * @see #getLevel() -+ * @see #getExp() -+ * @see #setExperienceLevelAndProgress(int) -+ */ -+ @org.jetbrains.annotations.Range(from = 0, to = Integer.MAX_VALUE) int calculateTotalExperiencePoints(); -+ -+ /** -+ * Updates the players level and level progress to that what would be reached when the total amount of experience -+ * had been collected. -+ * -+ *

This method differs from {@link #setTotalExperience(int)} in that this method actually updates the -+ * {@link #getLevel() level} and {@link #getExp() level progress} so that a subsequent call of -+ * {@link #calculateTotalExperiencePoints()} yields the same amount of points that have been set

-+ * -+ * @param totalExperience New total experience points -+ * @see #setLevel(int) -+ * @see #setExp(float) -+ * @see #calculateTotalExperiencePoints() -+ */ -+ void setExperienceLevelAndProgress(@org.jetbrains.annotations.Range(from = 0, to = Integer.MAX_VALUE) int totalExperience); -+ -+ /** -+ * Gets the total amount of experience points that are needed to reach the next level from zero progress towards it. -+ * -+ *

Can be used with {@link #getExp()} to calculate the current points for the current level and alike

-+ * -+ * @return The required experience points -+ * @see #getExp() -+ */ -+ int getExperiencePointsNeededForNextLevel(); -+ // Paper end - - /** - * Send an experience change. diff --git a/patches/api/0435-Add-missing-InventoryType.patch b/patches/api/0435-Add-missing-InventoryType.patch new file mode 100644 index 0000000000..88ed48c3e6 --- /dev/null +++ b/patches/api/0435-Add-missing-InventoryType.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Wed, 27 Dec 2023 16:46:13 -0800 +Subject: [PATCH] Add missing InventoryType + +Upstream did not add a DECORATED_POT inventory type + +diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java +index fbdbd2f4da5e09d4b111ddcf72e2d7dd59046bd7..851e40dc8af6dcb5670785e006b078af7e72fb76 100644 +--- a/src/main/java/org/bukkit/event/inventory/InventoryType.java ++++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java +@@ -143,6 +143,12 @@ public enum InventoryType { + * Pseudo jukebox inventory with 1 slot of undefined type. + */ + JUKEBOX(1, "Jukebox", false), ++ // Paper start - add missing type ++ /** ++ * Pseudo decorated pot with 1 slot of undefined type. ++ */ ++ DECORATED_POT(1, "Decorated Pot", false), ++ // Paper end - add missing type + /** + * A crafter inventory, with 9 CRAFTING slots. + */ diff --git a/patches/api/0436-Add-drops-to-shear-events.patch b/patches/api/0436-Add-drops-to-shear-events.patch new file mode 100644 index 0000000000..c87460e48d --- /dev/null +++ b/patches/api/0436-Add-drops-to-shear-events.patch @@ -0,0 +1,103 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Tue, 18 May 2021 12:31:54 -0700 +Subject: [PATCH] Add drops to shear events + + +diff --git a/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java b/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java +index 71c0af9373069cfaa074e1fbad592eab81025b1c..610768bd329b8612627d361fd9a773a7b91ff108 100644 +--- a/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java ++++ b/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java +@@ -17,11 +17,14 @@ public class BlockShearEntityEvent extends BlockEvent implements Cancellable { + private final Entity sheared; + private final ItemStack tool; + private boolean cancelled; ++ private java.util.List drops; // Paper + +- public BlockShearEntityEvent(@NotNull Block dispenser, @NotNull Entity sheared, @NotNull ItemStack tool) { ++ @org.jetbrains.annotations.ApiStatus.Internal // Paper ++ public BlockShearEntityEvent(@NotNull Block dispenser, @NotNull Entity sheared, @NotNull ItemStack tool, final @NotNull java.util.List drops) { // Paper - custom shear drops + super(dispenser); + this.sheared = sheared; + this.tool = tool; ++ this.drops = drops; // Paper + } + + /** +@@ -64,4 +67,24 @@ public class BlockShearEntityEvent extends BlockEvent implements Cancellable { + public static HandlerList getHandlerList() { + return handlers; + } ++ // Paper start - custom shear drops ++ /** ++ * Get an immutable list of drops for this shearing. ++ * ++ * @return the shearing drops ++ * @see #setDrops(java.util.List) ++ */ ++ public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getDrops() { ++ return java.util.Collections.unmodifiableList(this.drops); ++ } ++ ++ /** ++ * Sets the drops for the shearing. ++ * ++ * @param drops the shear drops ++ */ ++ public void setDrops(final java.util.@NotNull List drops) { ++ this.drops = java.util.List.copyOf(drops); ++ } ++ // Paper end - custom shear drops + } +diff --git a/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java b/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java +index 04b3dce008edefb045162d0f69f87462ea1f3534..63f6799c2543ba67ce9fe6484002062d7a754fd0 100644 +--- a/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java ++++ b/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java +@@ -18,17 +18,20 @@ public class PlayerShearEntityEvent extends PlayerEvent implements Cancellable { + private final Entity what; + private final ItemStack item; + private final EquipmentSlot hand; ++ private java.util.List drops; // Paper - custom shear drops + +- public PlayerShearEntityEvent(@NotNull Player who, @NotNull Entity what, @NotNull ItemStack item, @NotNull EquipmentSlot hand) { ++ @org.jetbrains.annotations.ApiStatus.Internal // Paper ++ public PlayerShearEntityEvent(@NotNull Player who, @NotNull Entity what, @NotNull ItemStack item, @NotNull EquipmentSlot hand, final java.util.@NotNull List drops) { // Paper - custom shear drops + super(who); + this.what = what; + this.item = item; + this.hand = hand; ++ this.drops = drops; // Paper - custom shear drops + } + + @Deprecated + public PlayerShearEntityEvent(@NotNull final Player who, @NotNull final Entity what) { +- this(who, what, new ItemStack(Material.SHEARS), EquipmentSlot.HAND); ++ this(who, what, new ItemStack(Material.SHEARS), EquipmentSlot.HAND, java.util.Collections.emptyList()); // Paper - custom shear drops + } + + @Override +@@ -82,4 +85,24 @@ public class PlayerShearEntityEvent extends PlayerEvent implements Cancellable { + return handlers; + } + ++ // Paper start - custom shear drops ++ /** ++ * Get an immutable list of drops for this shearing. ++ * ++ * @return the shearing drops ++ * @see #setDrops(java.util.List) ++ */ ++ public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getDrops() { ++ return this.drops; ++ } ++ ++ /** ++ * Sets the drops for the shearing. ++ * ++ * @param drops the shear drops ++ */ ++ public void setDrops(final java.util.@NotNull List drops) { ++ this.drops = java.util.List.copyOf(drops); ++ } ++ // Paper end - custom shear drops + } diff --git a/patches/api/0436-Add-missing-InventoryType.patch b/patches/api/0436-Add-missing-InventoryType.patch deleted file mode 100644 index 88ed48c3e6..0000000000 --- a/patches/api/0436-Add-missing-InventoryType.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Wed, 27 Dec 2023 16:46:13 -0800 -Subject: [PATCH] Add missing InventoryType - -Upstream did not add a DECORATED_POT inventory type - -diff --git a/src/main/java/org/bukkit/event/inventory/InventoryType.java b/src/main/java/org/bukkit/event/inventory/InventoryType.java -index fbdbd2f4da5e09d4b111ddcf72e2d7dd59046bd7..851e40dc8af6dcb5670785e006b078af7e72fb76 100644 ---- a/src/main/java/org/bukkit/event/inventory/InventoryType.java -+++ b/src/main/java/org/bukkit/event/inventory/InventoryType.java -@@ -143,6 +143,12 @@ public enum InventoryType { - * Pseudo jukebox inventory with 1 slot of undefined type. - */ - JUKEBOX(1, "Jukebox", false), -+ // Paper start - add missing type -+ /** -+ * Pseudo decorated pot with 1 slot of undefined type. -+ */ -+ DECORATED_POT(1, "Decorated Pot", false), -+ // Paper end - add missing type - /** - * A crafter inventory, with 9 CRAFTING slots. - */ diff --git a/patches/api/0437-Add-HiddenPotionEffect-API.patch b/patches/api/0437-Add-HiddenPotionEffect-API.patch new file mode 100644 index 0000000000..94799bbf65 --- /dev/null +++ b/patches/api/0437-Add-HiddenPotionEffect-API.patch @@ -0,0 +1,170 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tamion <70228790+notTamion@users.noreply.github.com> +Date: Sun, 5 Nov 2023 09:50:48 +0100 +Subject: [PATCH] Add HiddenPotionEffect API + + +diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java +index 5de7651f673cba9782f88f46dc938274b37a38ec..5c29956c6db53440322330ff723c7087193641f1 100644 +--- a/src/main/java/org/bukkit/entity/LivingEntity.java ++++ b/src/main/java/org/bukkit/entity/LivingEntity.java +@@ -591,6 +591,9 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource + + /** + * Adds the given {@link PotionEffect} to the living entity. ++ *

++ * Note: {@link PotionEffect#getHiddenPotionEffect()} is ignored when ++ * adding the effect to the entity. + * + * @param effect PotionEffect to be added + * @return whether the effect could be added +@@ -615,6 +618,9 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource + /** + * Attempts to add all of the given {@link PotionEffect} to the living + * entity. ++ *

++ * Note: {@link PotionEffect#getHiddenPotionEffect()} is ignored when ++ * adding the effect to the entity. + * + * @param effects the effects to add + * @return whether all of the effects could be added +diff --git a/src/main/java/org/bukkit/potion/PotionEffect.java b/src/main/java/org/bukkit/potion/PotionEffect.java +index 575156c089e45a3d6a43ca6b7adfbc7b473a60ab..704b6d615e7490d433b703f5a6a8d3c40aa6425e 100644 +--- a/src/main/java/org/bukkit/potion/PotionEffect.java ++++ b/src/main/java/org/bukkit/potion/PotionEffect.java +@@ -28,6 +28,7 @@ public class PotionEffect implements ConfigurationSerializable { + */ + public static final int INFINITE_DURATION = -1; + ++ private static final String HIDDEN_EFFECT = "hidden_effect"; // Paper + private static final String AMPLIFIER = "amplifier"; + private static final String DURATION = "duration"; + private static final String TYPE = "effect"; +@@ -40,6 +41,7 @@ public class PotionEffect implements ConfigurationSerializable { + private final boolean ambient; + private final boolean particles; + private final boolean icon; ++ private final PotionEffect hiddenEffect; // Paper + + /** + * Creates a potion effect. +@@ -50,8 +52,11 @@ public class PotionEffect implements ConfigurationSerializable { + * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} + * @param particles the particle status, see {@link PotionEffect#hasParticles()} + * @param icon the icon status, see {@link PotionEffect#hasIcon()} ++ * @param hiddenEffect the hidden PotionEffect ++ * @hidden Internal-- hidden effects are only shown internally + */ +- public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon) { ++ @org.jetbrains.annotations.ApiStatus.Internal // Paper ++ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable PotionEffect hiddenEffect) { // Paper + Preconditions.checkArgument(type != null, "effect type cannot be null"); + this.type = type; + this.duration = duration; +@@ -59,6 +64,23 @@ public class PotionEffect implements ConfigurationSerializable { + this.ambient = ambient; + this.particles = particles; + this.icon = icon; ++ // Paper start ++ this.hiddenEffect = hiddenEffect; ++ } ++ ++ /** ++ * Creates a potion effect. ++ * @param type effect type ++ * @param duration measured in ticks, see {@link ++ * PotionEffect#getDuration()} ++ * @param amplifier the amplifier, see {@link PotionEffect#getAmplifier()} ++ * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} ++ * @param particles the particle status, see {@link PotionEffect#hasParticles()} ++ * @param icon the icon status, see {@link PotionEffect#hasIcon()} ++ */ ++ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon) { ++ this(type, duration, amplifier, ambient, particles, icon, null); ++ // Paper end + } + + /** +@@ -106,7 +128,7 @@ public class PotionEffect implements ConfigurationSerializable { + * @param map the map to deserialize from + */ + public PotionEffect(@NotNull Map map) { +- this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true))); ++ this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)), (PotionEffect) map.get(HIDDEN_EFFECT)); // Paper + } + + // Paper start +@@ -134,6 +156,19 @@ public class PotionEffect implements ConfigurationSerializable { + public PotionEffect withIcon(boolean icon) { + return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon); + } ++ ++ /** ++ * Returns the PotionEffect that will become active ++ * after the current PotionEffect has run out. ++ *

++ * Note: This value is only applicable to type applied to living entities. ++ * ++ * @return The hidden PotionEffect. ++ */ ++ @Nullable ++ public PotionEffect getHiddenPotionEffect() { ++ return hiddenEffect; ++ } + // Paper end + + @NotNull +@@ -170,19 +205,27 @@ public class PotionEffect implements ConfigurationSerializable { + @Override + @NotNull + public Map serialize() { +- return ImmutableMap.builder() ++ ImmutableMap.Builder builder = ImmutableMap.builder() // Paper + .put(TYPE, type.getKey().toString()) + .put(DURATION, duration) + .put(AMPLIFIER, amplifier) + .put(AMBIENT, ambient) + .put(PARTICLES, particles) +- .put(ICON, icon) +- .build(); ++ .put(ICON, icon); ++ // Paper start ++ if (this.hiddenEffect != null) { ++ builder.put(HIDDEN_EFFECT, this.hiddenEffect); ++ } ++ return builder.build(); ++ // Paper end + } + + /** + * Attempts to add the effect represented by this object to the given + * {@link LivingEntity}. ++ *

++ * Note: {@link PotionEffect#getHiddenPotionEffect()} is ignored when ++ * adding the effect to the entity. + * + * @param entity The entity to add this effect to + * @return Whether the effect could be added +@@ -201,7 +244,7 @@ public class PotionEffect implements ConfigurationSerializable { + return false; + } + PotionEffect that = (PotionEffect) obj; +- return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon; ++ return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon && java.util.Objects.equals(this.hiddenEffect, that.hiddenEffect); // Paper + } + + /** +@@ -306,11 +349,12 @@ public class PotionEffect implements ConfigurationSerializable { + hash ^= 0x22222222 >> (ambient ? 1 : -1); + hash ^= 0x22222222 >> (particles ? 1 : -1); + hash ^= 0x22222222 >> (icon ? 1 : -1); ++ if (hiddenEffect != null) hash = hash * 31 + hiddenEffect.hashCode(); // Paper + return hash; + } + + @Override + public String toString() { +- return type.getName() + (ambient ? ":(" : ":") + duration + "t-x" + amplifier + (ambient ? ")" : ""); ++ return "PotionEffect{" + "amplifier=" + amplifier + ", duration=" + duration + ", type=" + type + ", ambient=" + ambient + ", particles=" + particles + ", icon=" + icon + ", hiddenEffect=" + hiddenEffect + '}'; // Paper + } + } diff --git a/patches/api/0437-Add-drops-to-shear-events.patch b/patches/api/0437-Add-drops-to-shear-events.patch deleted file mode 100644 index c87460e48d..0000000000 --- a/patches/api/0437-Add-drops-to-shear-events.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Tue, 18 May 2021 12:31:54 -0700 -Subject: [PATCH] Add drops to shear events - - -diff --git a/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java b/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java -index 71c0af9373069cfaa074e1fbad592eab81025b1c..610768bd329b8612627d361fd9a773a7b91ff108 100644 ---- a/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java -+++ b/src/main/java/org/bukkit/event/block/BlockShearEntityEvent.java -@@ -17,11 +17,14 @@ public class BlockShearEntityEvent extends BlockEvent implements Cancellable { - private final Entity sheared; - private final ItemStack tool; - private boolean cancelled; -+ private java.util.List drops; // Paper - -- public BlockShearEntityEvent(@NotNull Block dispenser, @NotNull Entity sheared, @NotNull ItemStack tool) { -+ @org.jetbrains.annotations.ApiStatus.Internal // Paper -+ public BlockShearEntityEvent(@NotNull Block dispenser, @NotNull Entity sheared, @NotNull ItemStack tool, final @NotNull java.util.List drops) { // Paper - custom shear drops - super(dispenser); - this.sheared = sheared; - this.tool = tool; -+ this.drops = drops; // Paper - } - - /** -@@ -64,4 +67,24 @@ public class BlockShearEntityEvent extends BlockEvent implements Cancellable { - public static HandlerList getHandlerList() { - return handlers; - } -+ // Paper start - custom shear drops -+ /** -+ * Get an immutable list of drops for this shearing. -+ * -+ * @return the shearing drops -+ * @see #setDrops(java.util.List) -+ */ -+ public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getDrops() { -+ return java.util.Collections.unmodifiableList(this.drops); -+ } -+ -+ /** -+ * Sets the drops for the shearing. -+ * -+ * @param drops the shear drops -+ */ -+ public void setDrops(final java.util.@NotNull List drops) { -+ this.drops = java.util.List.copyOf(drops); -+ } -+ // Paper end - custom shear drops - } -diff --git a/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java b/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java -index 04b3dce008edefb045162d0f69f87462ea1f3534..63f6799c2543ba67ce9fe6484002062d7a754fd0 100644 ---- a/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java -+++ b/src/main/java/org/bukkit/event/player/PlayerShearEntityEvent.java -@@ -18,17 +18,20 @@ public class PlayerShearEntityEvent extends PlayerEvent implements Cancellable { - private final Entity what; - private final ItemStack item; - private final EquipmentSlot hand; -+ private java.util.List drops; // Paper - custom shear drops - -- public PlayerShearEntityEvent(@NotNull Player who, @NotNull Entity what, @NotNull ItemStack item, @NotNull EquipmentSlot hand) { -+ @org.jetbrains.annotations.ApiStatus.Internal // Paper -+ public PlayerShearEntityEvent(@NotNull Player who, @NotNull Entity what, @NotNull ItemStack item, @NotNull EquipmentSlot hand, final java.util.@NotNull List drops) { // Paper - custom shear drops - super(who); - this.what = what; - this.item = item; - this.hand = hand; -+ this.drops = drops; // Paper - custom shear drops - } - - @Deprecated - public PlayerShearEntityEvent(@NotNull final Player who, @NotNull final Entity what) { -- this(who, what, new ItemStack(Material.SHEARS), EquipmentSlot.HAND); -+ this(who, what, new ItemStack(Material.SHEARS), EquipmentSlot.HAND, java.util.Collections.emptyList()); // Paper - custom shear drops - } - - @Override -@@ -82,4 +85,24 @@ public class PlayerShearEntityEvent extends PlayerEvent implements Cancellable { - return handlers; - } - -+ // Paper start - custom shear drops -+ /** -+ * Get an immutable list of drops for this shearing. -+ * -+ * @return the shearing drops -+ * @see #setDrops(java.util.List) -+ */ -+ public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getDrops() { -+ return this.drops; -+ } -+ -+ /** -+ * Sets the drops for the shearing. -+ * -+ * @param drops the shear drops -+ */ -+ public void setDrops(final java.util.@NotNull List drops) { -+ this.drops = java.util.List.copyOf(drops); -+ } -+ // Paper end - custom shear drops - } diff --git a/patches/api/0438-Add-HiddenPotionEffect-API.patch b/patches/api/0438-Add-HiddenPotionEffect-API.patch deleted file mode 100644 index 94799bbf65..0000000000 --- a/patches/api/0438-Add-HiddenPotionEffect-API.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tamion <70228790+notTamion@users.noreply.github.com> -Date: Sun, 5 Nov 2023 09:50:48 +0100 -Subject: [PATCH] Add HiddenPotionEffect API - - -diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java -index 5de7651f673cba9782f88f46dc938274b37a38ec..5c29956c6db53440322330ff723c7087193641f1 100644 ---- a/src/main/java/org/bukkit/entity/LivingEntity.java -+++ b/src/main/java/org/bukkit/entity/LivingEntity.java -@@ -591,6 +591,9 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource - - /** - * Adds the given {@link PotionEffect} to the living entity. -+ *

-+ * Note: {@link PotionEffect#getHiddenPotionEffect()} is ignored when -+ * adding the effect to the entity. - * - * @param effect PotionEffect to be added - * @return whether the effect could be added -@@ -615,6 +618,9 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource - /** - * Attempts to add all of the given {@link PotionEffect} to the living - * entity. -+ *

-+ * Note: {@link PotionEffect#getHiddenPotionEffect()} is ignored when -+ * adding the effect to the entity. - * - * @param effects the effects to add - * @return whether all of the effects could be added -diff --git a/src/main/java/org/bukkit/potion/PotionEffect.java b/src/main/java/org/bukkit/potion/PotionEffect.java -index 575156c089e45a3d6a43ca6b7adfbc7b473a60ab..704b6d615e7490d433b703f5a6a8d3c40aa6425e 100644 ---- a/src/main/java/org/bukkit/potion/PotionEffect.java -+++ b/src/main/java/org/bukkit/potion/PotionEffect.java -@@ -28,6 +28,7 @@ public class PotionEffect implements ConfigurationSerializable { - */ - public static final int INFINITE_DURATION = -1; - -+ private static final String HIDDEN_EFFECT = "hidden_effect"; // Paper - private static final String AMPLIFIER = "amplifier"; - private static final String DURATION = "duration"; - private static final String TYPE = "effect"; -@@ -40,6 +41,7 @@ public class PotionEffect implements ConfigurationSerializable { - private final boolean ambient; - private final boolean particles; - private final boolean icon; -+ private final PotionEffect hiddenEffect; // Paper - - /** - * Creates a potion effect. -@@ -50,8 +52,11 @@ public class PotionEffect implements ConfigurationSerializable { - * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} - * @param particles the particle status, see {@link PotionEffect#hasParticles()} - * @param icon the icon status, see {@link PotionEffect#hasIcon()} -+ * @param hiddenEffect the hidden PotionEffect -+ * @hidden Internal-- hidden effects are only shown internally - */ -- public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon) { -+ @org.jetbrains.annotations.ApiStatus.Internal // Paper -+ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon, @Nullable PotionEffect hiddenEffect) { // Paper - Preconditions.checkArgument(type != null, "effect type cannot be null"); - this.type = type; - this.duration = duration; -@@ -59,6 +64,23 @@ public class PotionEffect implements ConfigurationSerializable { - this.ambient = ambient; - this.particles = particles; - this.icon = icon; -+ // Paper start -+ this.hiddenEffect = hiddenEffect; -+ } -+ -+ /** -+ * Creates a potion effect. -+ * @param type effect type -+ * @param duration measured in ticks, see {@link -+ * PotionEffect#getDuration()} -+ * @param amplifier the amplifier, see {@link PotionEffect#getAmplifier()} -+ * @param ambient the ambient status, see {@link PotionEffect#isAmbient()} -+ * @param particles the particle status, see {@link PotionEffect#hasParticles()} -+ * @param icon the icon status, see {@link PotionEffect#hasIcon()} -+ */ -+ public PotionEffect(@NotNull PotionEffectType type, int duration, int amplifier, boolean ambient, boolean particles, boolean icon) { -+ this(type, duration, amplifier, ambient, particles, icon, null); -+ // Paper end - } - - /** -@@ -106,7 +128,7 @@ public class PotionEffect implements ConfigurationSerializable { - * @param map the map to deserialize from - */ - public PotionEffect(@NotNull Map map) { -- this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true))); -+ this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)), (PotionEffect) map.get(HIDDEN_EFFECT)); // Paper - } - - // Paper start -@@ -134,6 +156,19 @@ public class PotionEffect implements ConfigurationSerializable { - public PotionEffect withIcon(boolean icon) { - return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon); - } -+ -+ /** -+ * Returns the PotionEffect that will become active -+ * after the current PotionEffect has run out. -+ *

-+ * Note: This value is only applicable to type applied to living entities. -+ * -+ * @return The hidden PotionEffect. -+ */ -+ @Nullable -+ public PotionEffect getHiddenPotionEffect() { -+ return hiddenEffect; -+ } - // Paper end - - @NotNull -@@ -170,19 +205,27 @@ public class PotionEffect implements ConfigurationSerializable { - @Override - @NotNull - public Map serialize() { -- return ImmutableMap.builder() -+ ImmutableMap.Builder builder = ImmutableMap.builder() // Paper - .put(TYPE, type.getKey().toString()) - .put(DURATION, duration) - .put(AMPLIFIER, amplifier) - .put(AMBIENT, ambient) - .put(PARTICLES, particles) -- .put(ICON, icon) -- .build(); -+ .put(ICON, icon); -+ // Paper start -+ if (this.hiddenEffect != null) { -+ builder.put(HIDDEN_EFFECT, this.hiddenEffect); -+ } -+ return builder.build(); -+ // Paper end - } - - /** - * Attempts to add the effect represented by this object to the given - * {@link LivingEntity}. -+ *

-+ * Note: {@link PotionEffect#getHiddenPotionEffect()} is ignored when -+ * adding the effect to the entity. - * - * @param entity The entity to add this effect to - * @return Whether the effect could be added -@@ -201,7 +244,7 @@ public class PotionEffect implements ConfigurationSerializable { - return false; - } - PotionEffect that = (PotionEffect) obj; -- return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon; -+ return this.type.equals(that.type) && this.ambient == that.ambient && this.amplifier == that.amplifier && this.duration == that.duration && this.particles == that.particles && this.icon == that.icon && java.util.Objects.equals(this.hiddenEffect, that.hiddenEffect); // Paper - } - - /** -@@ -306,11 +349,12 @@ public class PotionEffect implements ConfigurationSerializable { - hash ^= 0x22222222 >> (ambient ? 1 : -1); - hash ^= 0x22222222 >> (particles ? 1 : -1); - hash ^= 0x22222222 >> (icon ? 1 : -1); -+ if (hiddenEffect != null) hash = hash * 31 + hiddenEffect.hashCode(); // Paper - return hash; - } - - @Override - public String toString() { -- return type.getName() + (ambient ? ":(" : ":") + duration + "t-x" + amplifier + (ambient ? ")" : ""); -+ return "PotionEffect{" + "amplifier=" + amplifier + ", duration=" + duration + ", type=" + type + ", ambient=" + ambient + ", particles=" + particles + ", icon=" + icon + ", hiddenEffect=" + hiddenEffect + '}'; // Paper - } - } diff --git a/patches/api/0438-Add-PlayerShieldDisableEvent.patch b/patches/api/0438-Add-PlayerShieldDisableEvent.patch new file mode 100644 index 0000000000..29c7daa0e3 --- /dev/null +++ b/patches/api/0438-Add-PlayerShieldDisableEvent.patch @@ -0,0 +1,115 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Cryptite +Date: Mon, 1 May 2023 16:22:43 -0500 +Subject: [PATCH] Add PlayerShieldDisableEvent + +Called whenever a players shield is disabled. This is mainly caused by +attacking players or monsters that carry axes. + +The event, while similar to the PlayerItemCooldownEvent, offers other +behaviour and can hence not be implemented as a childtype of said event. +Specifically, cancelling the event prevents the game events from being +sent to the player. + +Plugins listening to just the PlayerItemCooldownEvent may not want said +sideeffects, meaning the disable event cannot share a handlerlist with +the cooldown event. + +diff --git a/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779763e4e42 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java +@@ -0,0 +1,92 @@ ++package io.papermc.paper.event.player; ++ ++import com.google.common.base.Preconditions; ++import org.bukkit.entity.Entity; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Called whenever a players shield is disabled due to an attack from another entity that was capable of disabling the ++ * shield. This, most commonly, may be another player attacking with an axe. ++ *

++ * Notably, this even is distinct from a {@link PlayerItemCooldownEvent} and will fire prior to the item going on ++ * cooldown. ++ * It follows that, if this event is cancelled, no {@link PlayerItemCooldownEvent} is called as the shield is never ++ * disabled in the first place. ++ */ ++public class PlayerShieldDisableEvent extends PlayerEvent implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private final Entity damager; ++ private int cooldown; ++ ++ private boolean cancelled; ++ ++ @ApiStatus.Internal ++ public PlayerShieldDisableEvent(@NotNull final Player player, @NotNull final Entity damager, final int cooldown) { ++ super(player); ++ this.damager = damager; ++ this.cooldown = cooldown; ++ } ++ ++ /** ++ * Provides the damager that disabled the shield. ++ * ++ * @return the entity instance that damaged the player in a way that caused the shield to be disabled. ++ */ ++ @NotNull ++ public Entity getDamager() { ++ return this.damager; ++ } ++ ++ /** ++ * Gets the cooldown the disabled shield will be disabled for in ticks. ++ *

++ * Notably, this value is not final as it might be changed by a {@link PlayerItemCooldownEvent} down the line, ++ * as said event is called if this event is not cancelled. ++ * ++ * @return cooldown in ticks ++ */ ++ public int getCooldown() { ++ return this.cooldown; ++ } ++ ++ /** ++ * Sets the cooldown of the shield in ticks. ++ *

++ * Notably, this value is not final as it might be changed by a {@link PlayerItemCooldownEvent} down the line, ++ * as said event is called if this event is not cancelled. ++ * ++ * @param cooldown cooldown in ticks, has to be a positive number ++ */ ++ public void setCooldown(int cooldown) { ++ Preconditions.checkArgument(cooldown >= 0, "The cooldown has to be equal to or greater than 0!"); ++ this.cooldown = cooldown; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ @Override ++ public void setCancelled(final boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++} diff --git a/patches/api/0439-Add-PlayerShieldDisableEvent.patch b/patches/api/0439-Add-PlayerShieldDisableEvent.patch deleted file mode 100644 index 29c7daa0e3..0000000000 --- a/patches/api/0439-Add-PlayerShieldDisableEvent.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Cryptite -Date: Mon, 1 May 2023 16:22:43 -0500 -Subject: [PATCH] Add PlayerShieldDisableEvent - -Called whenever a players shield is disabled. This is mainly caused by -attacking players or monsters that carry axes. - -The event, while similar to the PlayerItemCooldownEvent, offers other -behaviour and can hence not be implemented as a childtype of said event. -Specifically, cancelling the event prevents the game events from being -sent to the player. - -Plugins listening to just the PlayerItemCooldownEvent may not want said -sideeffects, meaning the disable event cannot share a handlerlist with -the cooldown event. - -diff --git a/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java b/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..25c13b01c5630a6de30058532458d779763e4e42 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/player/PlayerShieldDisableEvent.java -@@ -0,0 +1,92 @@ -+package io.papermc.paper.event.player; -+ -+import com.google.common.base.Preconditions; -+import org.bukkit.entity.Entity; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.player.PlayerEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Called whenever a players shield is disabled due to an attack from another entity that was capable of disabling the -+ * shield. This, most commonly, may be another player attacking with an axe. -+ *

-+ * Notably, this even is distinct from a {@link PlayerItemCooldownEvent} and will fire prior to the item going on -+ * cooldown. -+ * It follows that, if this event is cancelled, no {@link PlayerItemCooldownEvent} is called as the shield is never -+ * disabled in the first place. -+ */ -+public class PlayerShieldDisableEvent extends PlayerEvent implements Cancellable { -+ -+ private static final HandlerList HANDLER_LIST = new HandlerList(); -+ -+ private final Entity damager; -+ private int cooldown; -+ -+ private boolean cancelled; -+ -+ @ApiStatus.Internal -+ public PlayerShieldDisableEvent(@NotNull final Player player, @NotNull final Entity damager, final int cooldown) { -+ super(player); -+ this.damager = damager; -+ this.cooldown = cooldown; -+ } -+ -+ /** -+ * Provides the damager that disabled the shield. -+ * -+ * @return the entity instance that damaged the player in a way that caused the shield to be disabled. -+ */ -+ @NotNull -+ public Entity getDamager() { -+ return this.damager; -+ } -+ -+ /** -+ * Gets the cooldown the disabled shield will be disabled for in ticks. -+ *

-+ * Notably, this value is not final as it might be changed by a {@link PlayerItemCooldownEvent} down the line, -+ * as said event is called if this event is not cancelled. -+ * -+ * @return cooldown in ticks -+ */ -+ public int getCooldown() { -+ return this.cooldown; -+ } -+ -+ /** -+ * Sets the cooldown of the shield in ticks. -+ *

-+ * Notably, this value is not final as it might be changed by a {@link PlayerItemCooldownEvent} down the line, -+ * as said event is called if this event is not cancelled. -+ * -+ * @param cooldown cooldown in ticks, has to be a positive number -+ */ -+ public void setCooldown(int cooldown) { -+ Preconditions.checkArgument(cooldown >= 0, "The cooldown has to be equal to or greater than 0!"); -+ this.cooldown = cooldown; -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return this.cancelled; -+ } -+ -+ @Override -+ public void setCancelled(final boolean cancel) { -+ this.cancelled = cancel; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return HANDLER_LIST; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return HANDLER_LIST; -+ } -+} diff --git a/patches/api/0439-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch b/patches/api/0439-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch new file mode 100644 index 0000000000..93ba48c77c --- /dev/null +++ b/patches/api/0439-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch @@ -0,0 +1,60 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Nassim Jahnke +Date: Sat, 6 Jan 2024 14:18:58 +0100 +Subject: [PATCH] Return null for empty String in NamespacedKey.fromString + + +diff --git a/src/main/java/org/bukkit/NamespacedKey.java b/src/main/java/org/bukkit/NamespacedKey.java +index cbdaa121dbc1876d0cd55f4b7b57f283ecaa8f1a..7ff6d60deb129e23b2a4d772aee123eb6c0b6433 100644 +--- a/src/main/java/org/bukkit/NamespacedKey.java ++++ b/src/main/java/org/bukkit/NamespacedKey.java +@@ -90,7 +90,7 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key { // Pap + this.key = key; + + String string = toString(); +- Preconditions.checkArgument(string.length() < 256, "NamespacedKey must be less than 256 characters", string); ++ Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation + } + + /** +@@ -117,7 +117,7 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key { // Pap + Preconditions.checkArgument(isValidKey(this.key), "Invalid key. Must be [a-z0-9/._-]: %s", this.key); + + String string = toString(); +- Preconditions.checkArgument(string.length() < 256, "NamespacedKey must be less than 256 characters (%s)", string); ++ Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation + } + + @NotNull +@@ -205,7 +205,10 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key { // Pap + */ + @Nullable + public static NamespacedKey fromString(@NotNull String string, @Nullable Plugin defaultNamespace) { +- Preconditions.checkArgument(string != null && !string.isEmpty(), "Input string must not be empty or null"); ++ // Paper - Return null for empty string, check length ++ Preconditions.checkArgument(string != null, "Input string must not be null"); ++ if (string.isEmpty() || string.length() > Short.MAX_VALUE) return null; ++ // Paper end - Return null for empty string, check length + + String[] components = string.split(":", 3); + if (components.length > 2) { +diff --git a/src/test/java/org/bukkit/NamespacedKeyTest.java b/src/test/java/org/bukkit/NamespacedKeyTest.java +index 6317798e43332f34f79970ded0f023beee868fed..d4e9e24b705a7ac3e9f4fc27eefa44ecb16aa35c 100644 +--- a/src/test/java/org/bukkit/NamespacedKeyTest.java ++++ b/src/test/java/org/bukkit/NamespacedKeyTest.java +@@ -29,6 +29,7 @@ public class NamespacedKeyTest { + assertNull(NamespacedKey.fromString("foo:bar:bazz")); + } + ++ @org.junit.jupiter.api.Disabled // Paper - Fixup NamespacedKey handling + @Test + public void testFromStringEmptyInput() { + assertThrows(IllegalArgumentException.class, () -> NamespacedKey.fromString("")); +@@ -75,6 +76,7 @@ public class NamespacedKeyTest { + "loremipsumdolorsitametconsecteturadipiscingelitduisvolutpatvelitsitametmaximusscelerisquemorbiullamcorperexacconsequategestas").toString(); + } + ++ @org.junit.jupiter.api.Disabled // Paper - Fixup NamespacedKey handling + @Test + public void testAboveLength() { + assertThrows(IllegalArgumentException.class, () -> new NamespacedKey("loremipsumdolorsitametconsecteturadipiscingelitduisvolutpatvelitsitametmaximusscelerisquemorbiullamcorperexacconsequategestas", diff --git a/patches/api/0440-Add-BlockStateMeta-clearBlockState.patch b/patches/api/0440-Add-BlockStateMeta-clearBlockState.patch new file mode 100644 index 0000000000..7e8c47a8e2 --- /dev/null +++ b/patches/api/0440-Add-BlockStateMeta-clearBlockState.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Thu, 11 Jan 2024 12:41:54 -0800 +Subject: [PATCH] Add BlockStateMeta#clearBlockState + + +diff --git a/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java b/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java +index c7d3041221742f6655155f19ef2addcaf2401015..dedb33e3d7f99e12fddba438af0874e6973d9372 100644 +--- a/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java ++++ b/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java +@@ -14,6 +14,13 @@ public interface BlockStateMeta extends ItemMeta { + */ + boolean hasBlockState(); + ++ // Paper start - add method to clear block state ++ /** ++ * Clears the block state currently attached to this item. ++ */ ++ void clearBlockState(); ++ // Paper end - add method to clear block state ++ + /** + * Returns the currently attached block state for this + * item or creates a new one if one doesn't exist. diff --git a/patches/api/0440-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch b/patches/api/0440-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch deleted file mode 100644 index 93ba48c77c..0000000000 --- a/patches/api/0440-Return-null-for-empty-String-in-NamespacedKey.fromSt.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Nassim Jahnke -Date: Sat, 6 Jan 2024 14:18:58 +0100 -Subject: [PATCH] Return null for empty String in NamespacedKey.fromString - - -diff --git a/src/main/java/org/bukkit/NamespacedKey.java b/src/main/java/org/bukkit/NamespacedKey.java -index cbdaa121dbc1876d0cd55f4b7b57f283ecaa8f1a..7ff6d60deb129e23b2a4d772aee123eb6c0b6433 100644 ---- a/src/main/java/org/bukkit/NamespacedKey.java -+++ b/src/main/java/org/bukkit/NamespacedKey.java -@@ -90,7 +90,7 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key { // Pap - this.key = key; - - String string = toString(); -- Preconditions.checkArgument(string.length() < 256, "NamespacedKey must be less than 256 characters", string); -+ Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation - } - - /** -@@ -117,7 +117,7 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key { // Pap - Preconditions.checkArgument(isValidKey(this.key), "Invalid key. Must be [a-z0-9/._-]: %s", this.key); - - String string = toString(); -- Preconditions.checkArgument(string.length() < 256, "NamespacedKey must be less than 256 characters (%s)", string); -+ Preconditions.checkArgument(string.length() <= Short.MAX_VALUE, "NamespacedKey must be less than 32768 characters", string); // Paper - Fix improper length validation - } - - @NotNull -@@ -205,7 +205,10 @@ public final class NamespacedKey implements net.kyori.adventure.key.Key { // Pap - */ - @Nullable - public static NamespacedKey fromString(@NotNull String string, @Nullable Plugin defaultNamespace) { -- Preconditions.checkArgument(string != null && !string.isEmpty(), "Input string must not be empty or null"); -+ // Paper - Return null for empty string, check length -+ Preconditions.checkArgument(string != null, "Input string must not be null"); -+ if (string.isEmpty() || string.length() > Short.MAX_VALUE) return null; -+ // Paper end - Return null for empty string, check length - - String[] components = string.split(":", 3); - if (components.length > 2) { -diff --git a/src/test/java/org/bukkit/NamespacedKeyTest.java b/src/test/java/org/bukkit/NamespacedKeyTest.java -index 6317798e43332f34f79970ded0f023beee868fed..d4e9e24b705a7ac3e9f4fc27eefa44ecb16aa35c 100644 ---- a/src/test/java/org/bukkit/NamespacedKeyTest.java -+++ b/src/test/java/org/bukkit/NamespacedKeyTest.java -@@ -29,6 +29,7 @@ public class NamespacedKeyTest { - assertNull(NamespacedKey.fromString("foo:bar:bazz")); - } - -+ @org.junit.jupiter.api.Disabled // Paper - Fixup NamespacedKey handling - @Test - public void testFromStringEmptyInput() { - assertThrows(IllegalArgumentException.class, () -> NamespacedKey.fromString("")); -@@ -75,6 +76,7 @@ public class NamespacedKeyTest { - "loremipsumdolorsitametconsecteturadipiscingelitduisvolutpatvelitsitametmaximusscelerisquemorbiullamcorperexacconsequategestas").toString(); - } - -+ @org.junit.jupiter.api.Disabled // Paper - Fixup NamespacedKey handling - @Test - public void testAboveLength() { - assertThrows(IllegalArgumentException.class, () -> new NamespacedKey("loremipsumdolorsitametconsecteturadipiscingelitduisvolutpatvelitsitametmaximusscelerisquemorbiullamcorperexacconsequategestas", diff --git a/patches/api/0441-Add-BlockStateMeta-clearBlockState.patch b/patches/api/0441-Add-BlockStateMeta-clearBlockState.patch deleted file mode 100644 index 7e8c47a8e2..0000000000 --- a/patches/api/0441-Add-BlockStateMeta-clearBlockState.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Thu, 11 Jan 2024 12:41:54 -0800 -Subject: [PATCH] Add BlockStateMeta#clearBlockState - - -diff --git a/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java b/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java -index c7d3041221742f6655155f19ef2addcaf2401015..dedb33e3d7f99e12fddba438af0874e6973d9372 100644 ---- a/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java -+++ b/src/main/java/org/bukkit/inventory/meta/BlockStateMeta.java -@@ -14,6 +14,13 @@ public interface BlockStateMeta extends ItemMeta { - */ - boolean hasBlockState(); - -+ // Paper start - add method to clear block state -+ /** -+ * Clears the block state currently attached to this item. -+ */ -+ void clearBlockState(); -+ // Paper end - add method to clear block state -+ - /** - * Returns the currently attached block state for this - * item or creates a new one if one doesn't exist. diff --git a/patches/api/0441-Expose-LootTable-of-DecoratedPot.patch b/patches/api/0441-Expose-LootTable-of-DecoratedPot.patch new file mode 100644 index 0000000000..42a8de4123 --- /dev/null +++ b/patches/api/0441-Expose-LootTable-of-DecoratedPot.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: FireInstall +Date: Sat, 20 Jan 2024 16:20:07 +0100 +Subject: [PATCH] Expose LootTable of DecoratedPot + + +diff --git a/src/main/java/org/bukkit/block/DecoratedPot.java b/src/main/java/org/bukkit/block/DecoratedPot.java +index f76230e0bba49639fc2e70ee32a53e3a9182f217..feae34e459523d17a10b673bbec28abcac9cdadd 100644 +--- a/src/main/java/org/bukkit/block/DecoratedPot.java ++++ b/src/main/java/org/bukkit/block/DecoratedPot.java +@@ -12,7 +12,7 @@ import org.jetbrains.annotations.Nullable; + /** + * Represents a captured state of a decorated pot. + */ +-public interface DecoratedPot extends TileState, BlockInventoryHolder { ++public interface DecoratedPot extends TileState, BlockInventoryHolder , org.bukkit.loot.Lootable { // Paper - expose loot table + + /** + * Set the sherd on the provided side. diff --git a/patches/api/0442-Add-ShulkerDuplicateEvent.patch b/patches/api/0442-Add-ShulkerDuplicateEvent.patch new file mode 100644 index 0000000000..a0a81094ce --- /dev/null +++ b/patches/api/0442-Add-ShulkerDuplicateEvent.patch @@ -0,0 +1,83 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Chase Henderson +Date: Fri, 5 Jan 2024 03:50:10 -0500 +Subject: [PATCH] Add ShulkerDuplicateEvent + + +diff --git a/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java b/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4a59534e2 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java +@@ -0,0 +1,71 @@ ++package io.papermc.paper.event.entity; ++ ++import org.bukkit.entity.Shulker; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.entity.EntityEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Fired when a shulker duplicates itself by spawning a new shulker. ++ *

++ * The event is fired prior to the newly created shulker, accessible via {@link #getEntity()}, being added to the world. ++ */ ++public class ShulkerDuplicateEvent extends EntityEvent implements Cancellable { ++ ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private final Shulker parent; ++ private boolean cancelled; ++ ++ @ApiStatus.Internal ++ public ShulkerDuplicateEvent(@NotNull Shulker child, @NotNull Shulker parent) { ++ super(child); ++ this.parent = parent; ++ } ++ ++ /** ++ * Provides the newly created shulker, which did not exist prior to the duplication. ++ * At the point of this event, said shulker is not part of the world yet. ++ * ++ * @return the newly duplicated shulker. ++ */ ++ @Override ++ @NotNull ++ public Shulker getEntity() { ++ return (Shulker) super.getEntity(); ++ } ++ ++ /** ++ * Provides the "parent" of the freshly created shulker. ++ * The parent shulker is the one that initiated the duplication. ++ * ++ * @return the previously existing shulker which duplicated. ++ */ ++ @NotNull ++ public Shulker getParent() { ++ return this.parent; ++ } ++ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @NotNull ++ @Override ++ public HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++} diff --git a/patches/api/0442-Expose-LootTable-of-DecoratedPot.patch b/patches/api/0442-Expose-LootTable-of-DecoratedPot.patch deleted file mode 100644 index 42a8de4123..0000000000 --- a/patches/api/0442-Expose-LootTable-of-DecoratedPot.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: FireInstall -Date: Sat, 20 Jan 2024 16:20:07 +0100 -Subject: [PATCH] Expose LootTable of DecoratedPot - - -diff --git a/src/main/java/org/bukkit/block/DecoratedPot.java b/src/main/java/org/bukkit/block/DecoratedPot.java -index f76230e0bba49639fc2e70ee32a53e3a9182f217..feae34e459523d17a10b673bbec28abcac9cdadd 100644 ---- a/src/main/java/org/bukkit/block/DecoratedPot.java -+++ b/src/main/java/org/bukkit/block/DecoratedPot.java -@@ -12,7 +12,7 @@ import org.jetbrains.annotations.Nullable; - /** - * Represents a captured state of a decorated pot. - */ --public interface DecoratedPot extends TileState, BlockInventoryHolder { -+public interface DecoratedPot extends TileState, BlockInventoryHolder , org.bukkit.loot.Lootable { // Paper - expose loot table - - /** - * Set the sherd on the provided side. diff --git a/patches/api/0443-Add-ShulkerDuplicateEvent.patch b/patches/api/0443-Add-ShulkerDuplicateEvent.patch deleted file mode 100644 index a0a81094ce..0000000000 --- a/patches/api/0443-Add-ShulkerDuplicateEvent.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chase Henderson -Date: Fri, 5 Jan 2024 03:50:10 -0500 -Subject: [PATCH] Add ShulkerDuplicateEvent - - -diff --git a/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java b/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..88d8278e49f1bb32e97ee551d8ad31d4a59534e2 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/entity/ShulkerDuplicateEvent.java -@@ -0,0 +1,71 @@ -+package io.papermc.paper.event.entity; -+ -+import org.bukkit.entity.Shulker; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.entity.EntityEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Fired when a shulker duplicates itself by spawning a new shulker. -+ *

-+ * The event is fired prior to the newly created shulker, accessible via {@link #getEntity()}, being added to the world. -+ */ -+public class ShulkerDuplicateEvent extends EntityEvent implements Cancellable { -+ -+ private static final HandlerList HANDLER_LIST = new HandlerList(); -+ -+ private final Shulker parent; -+ private boolean cancelled; -+ -+ @ApiStatus.Internal -+ public ShulkerDuplicateEvent(@NotNull Shulker child, @NotNull Shulker parent) { -+ super(child); -+ this.parent = parent; -+ } -+ -+ /** -+ * Provides the newly created shulker, which did not exist prior to the duplication. -+ * At the point of this event, said shulker is not part of the world yet. -+ * -+ * @return the newly duplicated shulker. -+ */ -+ @Override -+ @NotNull -+ public Shulker getEntity() { -+ return (Shulker) super.getEntity(); -+ } -+ -+ /** -+ * Provides the "parent" of the freshly created shulker. -+ * The parent shulker is the one that initiated the duplication. -+ * -+ * @return the previously existing shulker which duplicated. -+ */ -+ @NotNull -+ public Shulker getParent() { -+ return this.parent; -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return this.cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ this.cancelled = cancel; -+ } -+ -+ @NotNull -+ @Override -+ public HandlerList getHandlers() { -+ return HANDLER_LIST; -+ } -+ -+ @NotNull -+ public static HandlerList getHandlerList() { -+ return HANDLER_LIST; -+ } -+} diff --git a/patches/api/0443-Add-api-for-spawn-egg-texture-colors.patch b/patches/api/0443-Add-api-for-spawn-egg-texture-colors.patch new file mode 100644 index 0000000000..23541c0b38 --- /dev/null +++ b/patches/api/0443-Add-api-for-spawn-egg-texture-colors.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Luis +Date: Thu, 11 Jan 2024 19:58:17 +0100 +Subject: [PATCH] Add api for spawn egg texture colors + + +diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java +index f261bd5971003e542e4806c1a989add8e0143466..02d34db5f44ed63c4635077eb2b3cb98ac94b7b2 100644 +--- a/src/main/java/org/bukkit/UnsafeValues.java ++++ b/src/main/java/org/bukkit/UnsafeValues.java +@@ -252,4 +252,17 @@ public interface UnsafeValues { + // Paper end - namespaced key biome methods + + String getStatisticCriteriaKey(@NotNull org.bukkit.Statistic statistic); // Paper - fix custom stats criteria creation ++ ++ // Paper start - spawn egg color visibility ++ /** ++ * Obtains the underlying color informating for a spawn egg of a given ++ * entity type, or null if the entity passed does not have a spawn egg. ++ * Spawn eggs have two colors - the background layer (0), and the ++ * foreground layer (1) ++ * @param entityType The entity type to get the color for ++ * @param layer The texture layer to get a color for ++ * @return The color of the layer for the entity's spawn egg ++ */ ++ @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); ++ // Paper end - spawn egg color visibility + } diff --git a/patches/api/0444-Add-Lifecycle-Event-system.patch b/patches/api/0444-Add-Lifecycle-Event-system.patch new file mode 100644 index 0000000000..d4b3f0411e --- /dev/null +++ b/patches/api/0444-Add-Lifecycle-Event-system.patch @@ -0,0 +1,628 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Tue, 18 Jul 2023 14:47:02 -0700 +Subject: [PATCH] Add Lifecycle Event system + +This event system is separate from Bukkit's event system and is +meant for managing resources across reloads and from points in the +PluginBootstrap. + +diff --git a/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java b/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java +index 08f2050356acaf74e3210416760e3873c2dafd2c..37dfdcfcbd14947e0550e7528aca68f452e53eb6 100644 +--- a/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java ++++ b/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java +@@ -1,6 +1,9 @@ + package io.papermc.paper.plugin.bootstrap; + ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; + import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; + + /** + * Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin +@@ -10,5 +13,13 @@ import org.jetbrains.annotations.ApiStatus; + */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable +-public interface BootstrapContext extends PluginProviderContext { ++public interface BootstrapContext extends PluginProviderContext, LifecycleEventOwner { ++ ++ /** ++ * Get the lifecycle event manager for registering handlers ++ * for lifecycle events allowed on the {@link BootstrapContext}. ++ * ++ * @return the lifecycle event manager ++ */ ++ @NotNull LifecycleEventManager getLifecycleManager(); + } +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0b8eafd3e79494d4a750cd9182387fbaead24011 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java +@@ -0,0 +1,17 @@ ++package io.papermc.paper.plugin.lifecycle.event; ++ ++import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * Base type for all Lifecycle Events. ++ *

++ * Lifecycle events are generally fired when the older ++ * event system is not available, like during early ++ * server initialization. ++ * @see LifecycleEvents ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface LifecycleEvent { ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3626ce3da17f20ec44f0c15baa13f40e1dc2bc9c +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java +@@ -0,0 +1,52 @@ ++package io.papermc.paper.plugin.lifecycle.event; ++ ++import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; ++import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Manages a plugin's lifecycle events. Can be obtained ++ * from {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext}. ++ * ++ * @param the owning type, {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext} ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface LifecycleEventManager { ++ ++ /** ++ * Registers an event handler for a specific event type. ++ *

++ * This is shorthand for creating a new {@link LifecycleEventHandlerConfiguration} and ++ * just passing in the {@link LifecycleEventHandler}. ++ *

{@code
++     * LifecycleEventHandler> handler = new Handler();
++     * manager.registerEventHandler(LifecycleEvents.COMMANDS, handler);
++     * }
++ * is equivalent to ++ *
{@code
++     * LifecycleEventHandler> handler = new Handler();
++     * manager.registerEventHandler(LifecycleEvents.COMMANDS.newHandler(handler));
++     * }
++ * ++ * @param eventType the event type to listen to ++ * @param eventHandler the handler for that event ++ * @param the type of the event object ++ */ ++ default void registerEventHandler(final @NotNull LifecycleEventType eventType, final @NotNull LifecycleEventHandler eventHandler) { ++ this.registerEventHandler(eventType.newHandler(eventHandler)); ++ } ++ ++ /** ++ * Registers an event handler configuration. ++ *

++ * Configurations are created via {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. ++ * Event types may have different configurations options available on the builder-like object ++ * returned by {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. ++ * ++ * @param handlerConfiguration the handler configuration to register ++ */ ++ void registerEventHandler(@NotNull LifecycleEventHandlerConfiguration handlerConfiguration); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1160474f94476b580426cec29756c4699e163bf7 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java +@@ -0,0 +1,24 @@ ++package io.papermc.paper.plugin.lifecycle.event; ++ ++import io.papermc.paper.plugin.configuration.PluginMeta; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Implemented by types that are considered owners ++ * of registered handlers for lifecycle events. Generally ++ * the types that implement this interface also provide ++ * a {@link LifecycleEventManager} where you can register ++ * event handlers. ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface LifecycleEventOwner { ++ ++ /** ++ * Get the plugin meta for this plugin. ++ * ++ * @return the plugin meta ++ */ ++ @NotNull PluginMeta getPluginMeta(); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8239ba3c0147c0e8e8d28987d3f543a67641892a +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java +@@ -0,0 +1,18 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * A handler for a specific event. Can be implemented ++ * in a concrete class or as a lambda. ++ * ++ * @param the event ++ */ ++@ApiStatus.Experimental ++@FunctionalInterface ++public interface LifecycleEventHandler { ++ ++ void run(@NotNull E event); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0831794fad1f6eb8960225909d40f4a3b20a2a3b +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java +@@ -0,0 +1,18 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler.configuration; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * Base type for constructing configured event handlers for ++ * lifecycle events. Usually created via {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType#newHandler(LifecycleEventHandler)} ++ * from event types in {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents} ++ * ++ * @param ++ */ ++@SuppressWarnings("unused") ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface LifecycleEventHandlerConfiguration { ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d307ede51a66279f2eeef4e5b41c71779503f0d4 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java +@@ -0,0 +1,25 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler.configuration; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++ ++/** ++ * Handler configuration for event types that allow "monitor" handlers. ++ * ++ * @param the required owner type ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface MonitorLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { ++ ++ /** ++ * Sets this handler configuration to be considered a "monitor". ++ * These handlers will run last and should only be used by plugins ++ * to observe changes from previously run handlers. ++ * ++ * @return this configuration for chaining ++ */ ++ @Contract("-> this") ++ MonitorLifecycleEventHandlerConfiguration monitor(); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1c404df0be359ceac7fb52fec03027c771395e07 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java +@@ -0,0 +1,39 @@ ++package io.papermc.paper.plugin.lifecycle.event.handler.configuration; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++ ++/** ++ * Handler configuration that allows both "monitor" and prioritized handlers. ++ * The default priority is 0. ++ * ++ * @param the required owner type ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface PrioritizedLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { ++ ++ /** ++ * Sets the priority for this handler. Resets ++ * all previous calls to {@link #monitor()}. A ++ * lower numeric value correlates to the handler ++ * being run earlier. ++ * ++ * @param priority the numerical priority ++ * @return this configuration for chaining ++ */ ++ @Contract("_ -> this") ++ PrioritizedLifecycleEventHandlerConfiguration priority(int priority); ++ ++ /** ++ * Sets this handler configuration to be considered a "monitor". ++ * These handlers will run last and should only be used by plugins ++ * to observe any changes from previously ran handlers. ++ * ++ * @return this configuration for chaining ++ */ ++ @Contract("-> this") ++ PrioritizedLifecycleEventHandlerConfiguration monitor(); ++ ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fd9c3605a8f5e6bdd31e42f18a45154d4074eb67 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java +@@ -0,0 +1,12 @@ ++package io.papermc.paper.plugin.lifecycle.event.registrar; ++ ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * To be implemented by types that provide ways to register types ++ * either on server start or during a reload ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface Registrar { ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2e5758d1af6215f33f89b12984a5594df592147f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java +@@ -0,0 +1,27 @@ ++package io.papermc.paper.plugin.lifecycle.event.registrar; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * A lifecycle event that exposes a {@link Registrar} of some kind ++ * to allow management of various things. Look at implementations of ++ * {@link Registrar} for an idea of what uses this event. ++ * ++ * @param registrar type ++ * @see ReloadableRegistrarEvent ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface RegistrarEvent extends LifecycleEvent { ++ ++ /** ++ * Get the registrar related to this event. ++ * ++ * @return the registrar ++ */ ++ @Contract(pure = true) ++ @NotNull R registrar(); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b8b439bdad2e47c7c715fe30e0c1e69aa25374dd +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java +@@ -0,0 +1,38 @@ ++package io.papermc.paper.plugin.lifecycle.event.registrar; ++ ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * A lifecycle event that exposes a {@link Registrar} that is ++ * reloadable. ++ * ++ * @param the registrar type ++ * @see RegistrarEvent ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface ReloadableRegistrarEvent extends RegistrarEvent { ++ ++ /** ++ * Get the cause of this reload. ++ * ++ * @return the cause ++ */ ++ @Contract(pure = true) ++ @NotNull Cause cause(); ++ ++ @ApiStatus.Experimental ++ enum Cause { ++ /** ++ * The initial load of the server. ++ */ ++ INITIAL, ++ /** ++ * A reload, triggered via one of the various mechanisms like ++ * the bukkit or minecraft reload commands. ++ */ ++ RELOAD ++ } ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..92ea0374079a228ccc59c00fcf58abff2f6c46fe +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java +@@ -0,0 +1,73 @@ ++package io.papermc.paper.plugin.lifecycle.event.types; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfiguration; ++import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Base type for all types of lifecycle events. Differs from ++ * {@link LifecycleEvent} which is the actual event object, whereas ++ * this is an object representing the type of the event. Used ++ * to construct subtypes of {@link LifecycleEventHandlerConfiguration} for ++ * use in {@link LifecycleEventManager} ++ * ++ * @param the required owner type ++ * @param the event object type ++ * @param the configuration type ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface LifecycleEventType> { ++ ++ /** ++ * Gets the name of the lifecycle event. ++ * ++ * @return the name ++ */ ++ @Contract(pure = true) ++ @NotNull String name(); ++ ++ /** ++ * Create a configuration for this event with the specified ++ * handler. ++ * ++ * @param handler the event handler ++ * @return a new configuration ++ * @see LifecycleEventManager#registerEventHandler(LifecycleEventHandlerConfiguration) ++ */ ++ @Contract("_ -> new") ++ @NotNull C newHandler(@NotNull LifecycleEventHandler handler); ++ ++ /** ++ * Lifecycle event type that supports separate registration ++ * of handlers as "monitors" that are run last. Useful ++ * if a plugin wants to only observe the changes other handlers ++ * made. ++ * ++ * @param the required owner type ++ * @param the event object type ++ */ ++ @ApiStatus.Experimental ++ @ApiStatus.NonExtendable ++ interface Monitorable extends LifecycleEventType> { ++ } ++ ++ /** ++ * Lifecycle event type that supports both {@link Monitorable "monitors"} and ++ * specific numeric-based priorities. ++ * ++ * @param the required owner type ++ * @param the event object type ++ */ ++ @ApiStatus.Experimental ++ @ApiStatus.NonExtendable ++ interface Prioritizable extends LifecycleEventType> { ++ } ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1588f6943a909bed053a952e650e043c44028c2d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java +@@ -0,0 +1,18 @@ ++package io.papermc.paper.plugin.lifecycle.event.types; ++ ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import java.util.ServiceLoader; ++import org.jetbrains.annotations.ApiStatus; ++ ++@ApiStatus.Internal ++interface LifecycleEventTypeProvider { ++ ++ LifecycleEventTypeProvider PROVIDER = ServiceLoader.load(LifecycleEventTypeProvider.class) ++ .findFirst() ++ .orElseThrow(); ++ ++ LifecycleEventType.Monitorable monitor(String name, Class ownerType); ++ ++ LifecycleEventType.Prioritizable prioritized(String name, Class ownerType); ++} +diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java +new file mode 100644 +index 0000000000000000000000000000000000000000..304f978e40e1759bb19704cc5cec399500905195 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java +@@ -0,0 +1,52 @@ ++package io.papermc.paper.plugin.lifecycle.event.types; ++ ++import io.papermc.paper.plugin.bootstrap.BootstrapContext; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; ++import org.bukkit.plugin.Plugin; ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * Holds various types of lifecycle events for ++ * use when creating event handler configurations ++ * in {@link LifecycleEventManager}. ++ */ ++@ApiStatus.Experimental ++public final class LifecycleEvents { ++ ++ // ++ @ApiStatus.Internal ++ private static LifecycleEventType.Monitorable plugin(final String name) { ++ return monitor(name, Plugin.class); ++ } ++ ++ @ApiStatus.Internal ++ private static LifecycleEventType.Prioritizable pluginPrioritized(final String name) { ++ return prioritized(name, Plugin.class); ++ } ++ ++ @ApiStatus.Internal ++ private static LifecycleEventType.Monitorable bootstrap(final String name) { ++ return monitor(name, BootstrapContext.class); ++ } ++ ++ @ApiStatus.Internal ++ private static LifecycleEventType.Prioritizable bootstrapPrioritized(final String name) { ++ return prioritized(name, BootstrapContext.class); ++ } ++ ++ @ApiStatus.Internal ++ private static LifecycleEventType.Monitorable monitor(final String name, final Class ownerType) { ++ return LifecycleEventTypeProvider.PROVIDER.monitor(name, ownerType); ++ } ++ ++ @ApiStatus.Internal ++ private static LifecycleEventType.Prioritizable prioritized(final String name, final Class ownerType) { ++ return LifecycleEventTypeProvider.PROVIDER.prioritized(name, ownerType); ++ } ++ // ++ ++ private LifecycleEvents() { ++ } ++} +diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java +index 02d34db5f44ed63c4635077eb2b3cb98ac94b7b2..3f1b48fd65df954e874e6dc6b9093cb12370e2c5 100644 +--- a/src/main/java/org/bukkit/UnsafeValues.java ++++ b/src/main/java/org/bukkit/UnsafeValues.java +@@ -265,4 +265,12 @@ public interface UnsafeValues { + */ + @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); + // Paper end - spawn egg color visibility ++ ++ // Paper start - lifecycle event API ++ /** ++ * @hidden ++ */ ++ @org.jetbrains.annotations.ApiStatus.Internal ++ io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck); ++ // Paper end - lifecycle event API + } +diff --git a/src/main/java/org/bukkit/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/Plugin.java +index 4eb639fbb46a0848be207149ea433455550fae1c..ef431219fd2bce48bad63b6b92c99d54348d480e 100644 +--- a/src/main/java/org/bukkit/plugin/Plugin.java ++++ b/src/main/java/org/bukkit/plugin/Plugin.java +@@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; + *

+ * The use of {@link PluginBase} is recommended for actual Implementation + */ +-public interface Plugin extends TabExecutor { ++public interface Plugin extends TabExecutor, io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner { // Paper + /** + * Returns the folder that the plugin data's files are located in. The + * folder may not yet exist. +@@ -224,4 +224,14 @@ public interface Plugin extends TabExecutor { + */ + @NotNull + public String getName(); ++ ++ // Paper start - lifecycle events ++ /** ++ * Get the lifecycle event manager for registering handlers ++ * for lifecycle events allowed on the {@link Plugin}. ++ * ++ * @return the lifecycle event manager ++ */ ++ io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager(); ++ // Paper end - lifecycle events + } +diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +index d359ea9b02952f981b9cf9d778c56eb995454c60..d5a3c3dce76c4ed0f1184ab5ba21db9c5f1c01ec 100644 +--- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java ++++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java +@@ -48,6 +48,11 @@ public abstract class JavaPlugin extends PluginBase { + private FileConfiguration newConfig = null; + private File configFile = null; + private Logger logger = null; // Paper - PluginLogger -> Logger ++ // Paper start - lifecycle events ++ @SuppressWarnings("deprecation") ++ private final io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager lifecycleEventManager = org.bukkit.Bukkit.getUnsafe().createPluginLifecycleEventManager(this, () -> this.allowsLifecycleRegistration); ++ private boolean allowsLifecycleRegistration = true; ++ // Paper end + + public JavaPlugin() { + // Paper start +@@ -279,7 +284,9 @@ public abstract class JavaPlugin extends PluginBase { + isEnabled = enabled; + + if (isEnabled) { ++ try { // Paper - lifecycle events + onEnable(); ++ } finally { this.allowsLifecycleRegistration = false; } // Paper - lifecycle events + } else { + onDisable(); + } +@@ -457,4 +464,11 @@ public abstract class JavaPlugin extends PluginBase { + } + return plugin; + } ++ ++ // Paper start - lifecycle events ++ @Override ++ public final io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager() { ++ return this.lifecycleEventManager; ++ } ++ // Paper end - lifecycle events + } +diff --git a/src/test/java/org/bukkit/plugin/TestPlugin.java b/src/test/java/org/bukkit/plugin/TestPlugin.java +index 43b58e920e739bb949ac0673e9ef73ba7b500dc9..affe88cf8e98a787e197936f5fc443464a2343c6 100644 +--- a/src/test/java/org/bukkit/plugin/TestPlugin.java ++++ b/src/test/java/org/bukkit/plugin/TestPlugin.java +@@ -133,4 +133,11 @@ public class TestPlugin extends PluginBase { + public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { + throw new UnsupportedOperationException("Not supported."); + } ++ ++ // Paper start - lifecycle events ++ @Override ++ public io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager getLifecycleManager() { ++ throw new UnsupportedOperationException("Not supported."); ++ } ++ // Paper end - lifecycle events + } diff --git a/patches/api/0444-Add-api-for-spawn-egg-texture-colors.patch b/patches/api/0444-Add-api-for-spawn-egg-texture-colors.patch deleted file mode 100644 index 23541c0b38..0000000000 --- a/patches/api/0444-Add-api-for-spawn-egg-texture-colors.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Luis -Date: Thu, 11 Jan 2024 19:58:17 +0100 -Subject: [PATCH] Add api for spawn egg texture colors - - -diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index f261bd5971003e542e4806c1a989add8e0143466..02d34db5f44ed63c4635077eb2b3cb98ac94b7b2 100644 ---- a/src/main/java/org/bukkit/UnsafeValues.java -+++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -252,4 +252,17 @@ public interface UnsafeValues { - // Paper end - namespaced key biome methods - - String getStatisticCriteriaKey(@NotNull org.bukkit.Statistic statistic); // Paper - fix custom stats criteria creation -+ -+ // Paper start - spawn egg color visibility -+ /** -+ * Obtains the underlying color informating for a spawn egg of a given -+ * entity type, or null if the entity passed does not have a spawn egg. -+ * Spawn eggs have two colors - the background layer (0), and the -+ * foreground layer (1) -+ * @param entityType The entity type to get the color for -+ * @param layer The texture layer to get a color for -+ * @return The color of the layer for the entity's spawn egg -+ */ -+ @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); -+ // Paper end - spawn egg color visibility - } diff --git a/patches/api/0445-Add-Lifecycle-Event-system.patch b/patches/api/0445-Add-Lifecycle-Event-system.patch deleted file mode 100644 index d4b3f0411e..0000000000 --- a/patches/api/0445-Add-Lifecycle-Event-system.patch +++ /dev/null @@ -1,628 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Tue, 18 Jul 2023 14:47:02 -0700 -Subject: [PATCH] Add Lifecycle Event system - -This event system is separate from Bukkit's event system and is -meant for managing resources across reloads and from points in the -PluginBootstrap. - -diff --git a/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java b/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java -index 08f2050356acaf74e3210416760e3873c2dafd2c..37dfdcfcbd14947e0550e7528aca68f452e53eb6 100644 ---- a/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java -+++ b/src/main/java/io/papermc/paper/plugin/bootstrap/BootstrapContext.java -@@ -1,6 +1,9 @@ - package io.papermc.paper.plugin.bootstrap; - -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; - import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; - - /** - * Represents the context provided to a {@link PluginBootstrap} during both the bootstrapping and plugin -@@ -10,5 +13,13 @@ import org.jetbrains.annotations.ApiStatus; - */ - @ApiStatus.Experimental - @ApiStatus.NonExtendable --public interface BootstrapContext extends PluginProviderContext { -+public interface BootstrapContext extends PluginProviderContext, LifecycleEventOwner { -+ -+ /** -+ * Get the lifecycle event manager for registering handlers -+ * for lifecycle events allowed on the {@link BootstrapContext}. -+ * -+ * @return the lifecycle event manager -+ */ -+ @NotNull LifecycleEventManager getLifecycleManager(); - } -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0b8eafd3e79494d4a750cd9182387fbaead24011 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java -@@ -0,0 +1,17 @@ -+package io.papermc.paper.plugin.lifecycle.event; -+ -+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; -+import org.jetbrains.annotations.ApiStatus; -+ -+/** -+ * Base type for all Lifecycle Events. -+ *

-+ * Lifecycle events are generally fired when the older -+ * event system is not available, like during early -+ * server initialization. -+ * @see LifecycleEvents -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface LifecycleEvent { -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java -new file mode 100644 -index 0000000000000000000000000000000000000000..3626ce3da17f20ec44f0c15baa13f40e1dc2bc9c ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java -@@ -0,0 +1,52 @@ -+package io.papermc.paper.plugin.lifecycle.event; -+ -+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; -+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; -+import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Manages a plugin's lifecycle events. Can be obtained -+ * from {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext}. -+ * -+ * @param the owning type, {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext} -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface LifecycleEventManager { -+ -+ /** -+ * Registers an event handler for a specific event type. -+ *

-+ * This is shorthand for creating a new {@link LifecycleEventHandlerConfiguration} and -+ * just passing in the {@link LifecycleEventHandler}. -+ *

{@code
-+     * LifecycleEventHandler> handler = new Handler();
-+     * manager.registerEventHandler(LifecycleEvents.COMMANDS, handler);
-+     * }
-+ * is equivalent to -+ *
{@code
-+     * LifecycleEventHandler> handler = new Handler();
-+     * manager.registerEventHandler(LifecycleEvents.COMMANDS.newHandler(handler));
-+     * }
-+ * -+ * @param eventType the event type to listen to -+ * @param eventHandler the handler for that event -+ * @param the type of the event object -+ */ -+ default void registerEventHandler(final @NotNull LifecycleEventType eventType, final @NotNull LifecycleEventHandler eventHandler) { -+ this.registerEventHandler(eventType.newHandler(eventHandler)); -+ } -+ -+ /** -+ * Registers an event handler configuration. -+ *

-+ * Configurations are created via {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. -+ * Event types may have different configurations options available on the builder-like object -+ * returned by {@link LifecycleEventType#newHandler(LifecycleEventHandler)}. -+ * -+ * @param handlerConfiguration the handler configuration to register -+ */ -+ void registerEventHandler(@NotNull LifecycleEventHandlerConfiguration handlerConfiguration); -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java -new file mode 100644 -index 0000000000000000000000000000000000000000..1160474f94476b580426cec29756c4699e163bf7 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java -@@ -0,0 +1,24 @@ -+package io.papermc.paper.plugin.lifecycle.event; -+ -+import io.papermc.paper.plugin.configuration.PluginMeta; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Implemented by types that are considered owners -+ * of registered handlers for lifecycle events. Generally -+ * the types that implement this interface also provide -+ * a {@link LifecycleEventManager} where you can register -+ * event handlers. -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface LifecycleEventOwner { -+ -+ /** -+ * Get the plugin meta for this plugin. -+ * -+ * @return the plugin meta -+ */ -+ @NotNull PluginMeta getPluginMeta(); -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java -new file mode 100644 -index 0000000000000000000000000000000000000000..8239ba3c0147c0e8e8d28987d3f543a67641892a ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java -@@ -0,0 +1,18 @@ -+package io.papermc.paper.plugin.lifecycle.event.handler; -+ -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * A handler for a specific event. Can be implemented -+ * in a concrete class or as a lambda. -+ * -+ * @param the event -+ */ -+@ApiStatus.Experimental -+@FunctionalInterface -+public interface LifecycleEventHandler { -+ -+ void run(@NotNull E event); -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0831794fad1f6eb8960225909d40f4a3b20a2a3b ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java -@@ -0,0 +1,18 @@ -+package io.papermc.paper.plugin.lifecycle.event.handler.configuration; -+ -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; -+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; -+import org.jetbrains.annotations.ApiStatus; -+ -+/** -+ * Base type for constructing configured event handlers for -+ * lifecycle events. Usually created via {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType#newHandler(LifecycleEventHandler)} -+ * from event types in {@link io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents} -+ * -+ * @param -+ */ -+@SuppressWarnings("unused") -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface LifecycleEventHandlerConfiguration { -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java -new file mode 100644 -index 0000000000000000000000000000000000000000..d307ede51a66279f2eeef4e5b41c71779503f0d4 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java -@@ -0,0 +1,25 @@ -+package io.papermc.paper.plugin.lifecycle.event.handler.configuration; -+ -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.Contract; -+ -+/** -+ * Handler configuration for event types that allow "monitor" handlers. -+ * -+ * @param the required owner type -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface MonitorLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { -+ -+ /** -+ * Sets this handler configuration to be considered a "monitor". -+ * These handlers will run last and should only be used by plugins -+ * to observe changes from previously run handlers. -+ * -+ * @return this configuration for chaining -+ */ -+ @Contract("-> this") -+ MonitorLifecycleEventHandlerConfiguration monitor(); -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java -new file mode 100644 -index 0000000000000000000000000000000000000000..1c404df0be359ceac7fb52fec03027c771395e07 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java -@@ -0,0 +1,39 @@ -+package io.papermc.paper.plugin.lifecycle.event.handler.configuration; -+ -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.Contract; -+ -+/** -+ * Handler configuration that allows both "monitor" and prioritized handlers. -+ * The default priority is 0. -+ * -+ * @param the required owner type -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface PrioritizedLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { -+ -+ /** -+ * Sets the priority for this handler. Resets -+ * all previous calls to {@link #monitor()}. A -+ * lower numeric value correlates to the handler -+ * being run earlier. -+ * -+ * @param priority the numerical priority -+ * @return this configuration for chaining -+ */ -+ @Contract("_ -> this") -+ PrioritizedLifecycleEventHandlerConfiguration priority(int priority); -+ -+ /** -+ * Sets this handler configuration to be considered a "monitor". -+ * These handlers will run last and should only be used by plugins -+ * to observe any changes from previously ran handlers. -+ * -+ * @return this configuration for chaining -+ */ -+ @Contract("-> this") -+ PrioritizedLifecycleEventHandlerConfiguration monitor(); -+ -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fd9c3605a8f5e6bdd31e42f18a45154d4074eb67 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java -@@ -0,0 +1,12 @@ -+package io.papermc.paper.plugin.lifecycle.event.registrar; -+ -+import org.jetbrains.annotations.ApiStatus; -+ -+/** -+ * To be implemented by types that provide ways to register types -+ * either on server start or during a reload -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface Registrar { -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2e5758d1af6215f33f89b12984a5594df592147f ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java -@@ -0,0 +1,27 @@ -+package io.papermc.paper.plugin.lifecycle.event.registrar; -+ -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * A lifecycle event that exposes a {@link Registrar} of some kind -+ * to allow management of various things. Look at implementations of -+ * {@link Registrar} for an idea of what uses this event. -+ * -+ * @param registrar type -+ * @see ReloadableRegistrarEvent -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface RegistrarEvent extends LifecycleEvent { -+ -+ /** -+ * Get the registrar related to this event. -+ * -+ * @return the registrar -+ */ -+ @Contract(pure = true) -+ @NotNull R registrar(); -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..b8b439bdad2e47c7c715fe30e0c1e69aa25374dd ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java -@@ -0,0 +1,38 @@ -+package io.papermc.paper.plugin.lifecycle.event.registrar; -+ -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * A lifecycle event that exposes a {@link Registrar} that is -+ * reloadable. -+ * -+ * @param the registrar type -+ * @see RegistrarEvent -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface ReloadableRegistrarEvent extends RegistrarEvent { -+ -+ /** -+ * Get the cause of this reload. -+ * -+ * @return the cause -+ */ -+ @Contract(pure = true) -+ @NotNull Cause cause(); -+ -+ @ApiStatus.Experimental -+ enum Cause { -+ /** -+ * The initial load of the server. -+ */ -+ INITIAL, -+ /** -+ * A reload, triggered via one of the various mechanisms like -+ * the bukkit or minecraft reload commands. -+ */ -+ RELOAD -+ } -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java -new file mode 100644 -index 0000000000000000000000000000000000000000..92ea0374079a228ccc59c00fcf58abff2f6c46fe ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java -@@ -0,0 +1,73 @@ -+package io.papermc.paper.plugin.lifecycle.event.types; -+ -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; -+import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; -+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; -+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLifecycleEventHandlerConfiguration; -+import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Base type for all types of lifecycle events. Differs from -+ * {@link LifecycleEvent} which is the actual event object, whereas -+ * this is an object representing the type of the event. Used -+ * to construct subtypes of {@link LifecycleEventHandlerConfiguration} for -+ * use in {@link LifecycleEventManager} -+ * -+ * @param the required owner type -+ * @param the event object type -+ * @param the configuration type -+ */ -+@ApiStatus.Experimental -+@ApiStatus.NonExtendable -+public interface LifecycleEventType> { -+ -+ /** -+ * Gets the name of the lifecycle event. -+ * -+ * @return the name -+ */ -+ @Contract(pure = true) -+ @NotNull String name(); -+ -+ /** -+ * Create a configuration for this event with the specified -+ * handler. -+ * -+ * @param handler the event handler -+ * @return a new configuration -+ * @see LifecycleEventManager#registerEventHandler(LifecycleEventHandlerConfiguration) -+ */ -+ @Contract("_ -> new") -+ @NotNull C newHandler(@NotNull LifecycleEventHandler handler); -+ -+ /** -+ * Lifecycle event type that supports separate registration -+ * of handlers as "monitors" that are run last. Useful -+ * if a plugin wants to only observe the changes other handlers -+ * made. -+ * -+ * @param the required owner type -+ * @param the event object type -+ */ -+ @ApiStatus.Experimental -+ @ApiStatus.NonExtendable -+ interface Monitorable extends LifecycleEventType> { -+ } -+ -+ /** -+ * Lifecycle event type that supports both {@link Monitorable "monitors"} and -+ * specific numeric-based priorities. -+ * -+ * @param the required owner type -+ * @param the event object type -+ */ -+ @ApiStatus.Experimental -+ @ApiStatus.NonExtendable -+ interface Prioritizable extends LifecycleEventType> { -+ } -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java -new file mode 100644 -index 0000000000000000000000000000000000000000..1588f6943a909bed053a952e650e043c44028c2d ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java -@@ -0,0 +1,18 @@ -+package io.papermc.paper.plugin.lifecycle.event.types; -+ -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; -+import java.util.ServiceLoader; -+import org.jetbrains.annotations.ApiStatus; -+ -+@ApiStatus.Internal -+interface LifecycleEventTypeProvider { -+ -+ LifecycleEventTypeProvider PROVIDER = ServiceLoader.load(LifecycleEventTypeProvider.class) -+ .findFirst() -+ .orElseThrow(); -+ -+ LifecycleEventType.Monitorable monitor(String name, Class ownerType); -+ -+ LifecycleEventType.Prioritizable prioritized(String name, Class ownerType); -+} -diff --git a/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java -new file mode 100644 -index 0000000000000000000000000000000000000000..304f978e40e1759bb19704cc5cec399500905195 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java -@@ -0,0 +1,52 @@ -+package io.papermc.paper.plugin.lifecycle.event.types; -+ -+import io.papermc.paper.plugin.bootstrap.BootstrapContext; -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; -+import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; -+import org.bukkit.plugin.Plugin; -+import org.jetbrains.annotations.ApiStatus; -+ -+/** -+ * Holds various types of lifecycle events for -+ * use when creating event handler configurations -+ * in {@link LifecycleEventManager}. -+ */ -+@ApiStatus.Experimental -+public final class LifecycleEvents { -+ -+ // -+ @ApiStatus.Internal -+ private static LifecycleEventType.Monitorable plugin(final String name) { -+ return monitor(name, Plugin.class); -+ } -+ -+ @ApiStatus.Internal -+ private static LifecycleEventType.Prioritizable pluginPrioritized(final String name) { -+ return prioritized(name, Plugin.class); -+ } -+ -+ @ApiStatus.Internal -+ private static LifecycleEventType.Monitorable bootstrap(final String name) { -+ return monitor(name, BootstrapContext.class); -+ } -+ -+ @ApiStatus.Internal -+ private static LifecycleEventType.Prioritizable bootstrapPrioritized(final String name) { -+ return prioritized(name, BootstrapContext.class); -+ } -+ -+ @ApiStatus.Internal -+ private static LifecycleEventType.Monitorable monitor(final String name, final Class ownerType) { -+ return LifecycleEventTypeProvider.PROVIDER.monitor(name, ownerType); -+ } -+ -+ @ApiStatus.Internal -+ private static LifecycleEventType.Prioritizable prioritized(final String name, final Class ownerType) { -+ return LifecycleEventTypeProvider.PROVIDER.prioritized(name, ownerType); -+ } -+ // -+ -+ private LifecycleEvents() { -+ } -+} -diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 02d34db5f44ed63c4635077eb2b3cb98ac94b7b2..3f1b48fd65df954e874e6dc6b9093cb12370e2c5 100644 ---- a/src/main/java/org/bukkit/UnsafeValues.java -+++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -265,4 +265,12 @@ public interface UnsafeValues { - */ - @Nullable org.bukkit.Color getSpawnEggLayerColor(org.bukkit.entity.EntityType entityType, int layer); - // Paper end - spawn egg color visibility -+ -+ // Paper start - lifecycle event API -+ /** -+ * @hidden -+ */ -+ @org.jetbrains.annotations.ApiStatus.Internal -+ io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck); -+ // Paper end - lifecycle event API - } -diff --git a/src/main/java/org/bukkit/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/Plugin.java -index 4eb639fbb46a0848be207149ea433455550fae1c..ef431219fd2bce48bad63b6b92c99d54348d480e 100644 ---- a/src/main/java/org/bukkit/plugin/Plugin.java -+++ b/src/main/java/org/bukkit/plugin/Plugin.java -@@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; - *

- * The use of {@link PluginBase} is recommended for actual Implementation - */ --public interface Plugin extends TabExecutor { -+public interface Plugin extends TabExecutor, io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner { // Paper - /** - * Returns the folder that the plugin data's files are located in. The - * folder may not yet exist. -@@ -224,4 +224,14 @@ public interface Plugin extends TabExecutor { - */ - @NotNull - public String getName(); -+ -+ // Paper start - lifecycle events -+ /** -+ * Get the lifecycle event manager for registering handlers -+ * for lifecycle events allowed on the {@link Plugin}. -+ * -+ * @return the lifecycle event manager -+ */ -+ io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager(); -+ // Paper end - lifecycle events - } -diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -index d359ea9b02952f981b9cf9d778c56eb995454c60..d5a3c3dce76c4ed0f1184ab5ba21db9c5f1c01ec 100644 ---- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java -@@ -48,6 +48,11 @@ public abstract class JavaPlugin extends PluginBase { - private FileConfiguration newConfig = null; - private File configFile = null; - private Logger logger = null; // Paper - PluginLogger -> Logger -+ // Paper start - lifecycle events -+ @SuppressWarnings("deprecation") -+ private final io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager lifecycleEventManager = org.bukkit.Bukkit.getUnsafe().createPluginLifecycleEventManager(this, () -> this.allowsLifecycleRegistration); -+ private boolean allowsLifecycleRegistration = true; -+ // Paper end - - public JavaPlugin() { - // Paper start -@@ -279,7 +284,9 @@ public abstract class JavaPlugin extends PluginBase { - isEnabled = enabled; - - if (isEnabled) { -+ try { // Paper - lifecycle events - onEnable(); -+ } finally { this.allowsLifecycleRegistration = false; } // Paper - lifecycle events - } else { - onDisable(); - } -@@ -457,4 +464,11 @@ public abstract class JavaPlugin extends PluginBase { - } - return plugin; - } -+ -+ // Paper start - lifecycle events -+ @Override -+ public final io.papermc.paper.plugin.lifecycle.event.@NotNull LifecycleEventManager getLifecycleManager() { -+ return this.lifecycleEventManager; -+ } -+ // Paper end - lifecycle events - } -diff --git a/src/test/java/org/bukkit/plugin/TestPlugin.java b/src/test/java/org/bukkit/plugin/TestPlugin.java -index 43b58e920e739bb949ac0673e9ef73ba7b500dc9..affe88cf8e98a787e197936f5fc443464a2343c6 100644 ---- a/src/test/java/org/bukkit/plugin/TestPlugin.java -+++ b/src/test/java/org/bukkit/plugin/TestPlugin.java -@@ -133,4 +133,11 @@ public class TestPlugin extends PluginBase { - public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { - throw new UnsupportedOperationException("Not supported."); - } -+ -+ // Paper start - lifecycle events -+ @Override -+ public io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager getLifecycleManager() { -+ throw new UnsupportedOperationException("Not supported."); -+ } -+ // Paper end - lifecycle events - } diff --git a/patches/api/0445-ItemStack-Tooltip-API.patch b/patches/api/0445-ItemStack-Tooltip-API.patch new file mode 100644 index 0000000000..7fa28ddc99 --- /dev/null +++ b/patches/api/0445-ItemStack-Tooltip-API.patch @@ -0,0 +1,146 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Yannick Lamprecht +Date: Mon, 22 Jan 2024 13:27:18 +0100 +Subject: [PATCH] ItemStack Tooltip API + + +diff --git a/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java +new file mode 100644 +index 0000000000000000000000000000000000000000..39ac768b3c5148544cb1aaf2c817e661f6856f64 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java +@@ -0,0 +1,75 @@ ++package io.papermc.paper.inventory.tooltip; ++ ++import org.bukkit.entity.Player; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Context for computing itemstack tooltips via ++ * {@link org.bukkit.inventory.ItemStack#computeTooltipLines(TooltipContext, Player)} ++ */ ++public interface TooltipContext { ++ ++ /** ++ * Creates a new context with the given advanced and creative ++ * mode settings. ++ * ++ * @param advanced whether the context is for advanced tooltips ++ * @param creative whether the context is for the creative inventory ++ * @return a new context ++ */ ++ @Contract("_, _ -> new") ++ static @NotNull TooltipContext create(final boolean advanced, final boolean creative) { ++ return new TooltipContextImpl(advanced, creative); ++ } ++ ++ /** ++ * Creates a new context that is neither advanced nor creative. ++ * ++ * @return a new context ++ */ ++ @Contract("-> new") ++ static @NotNull TooltipContext create() { ++ return new TooltipContextImpl(false, false); ++ } ++ ++ /** ++ * Returns whether the context is for advanced ++ * tooltips. ++ *

++ * Advanced tooltips are shown by default ++ * when a player has {@code F3+H} enabled. ++ * ++ * @return true if for advanced tooltips ++ */ ++ boolean isAdvanced(); ++ ++ /** ++ * Returns whether the context is for the creative ++ * mode inventory. ++ *

++ * Creative tooltips are shown by default when a player is ++ * in the creative inventory. ++ * ++ * @return true if for creative mode inventory ++ */ ++ boolean isCreative(); ++ ++ /** ++ * Returns a new context with {@link #isAdvanced()} ++ * set to true. ++ * ++ * @return a new context ++ */ ++ @Contract("-> new") ++ @NotNull TooltipContext asAdvanced(); ++ ++ /** ++ * Returns a new context with {@link #isCreative()} ++ * set to true. ++ * ++ * @return a new context ++ */ ++ @Contract("-> new") ++ @NotNull TooltipContext asCreative(); ++} +diff --git a/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1d9bed6691f581529c53b577b26f1d0f902ccb0d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java +@@ -0,0 +1,16 @@ ++package io.papermc.paper.inventory.tooltip; ++ ++import org.jetbrains.annotations.NotNull; ++ ++record TooltipContextImpl(boolean isCreative, boolean isAdvanced) implements TooltipContext { ++ ++ @Override ++ public @NotNull TooltipContext asCreative() { ++ return new TooltipContextImpl(true, this.isAdvanced); ++ } ++ ++ @Override ++ public @NotNull TooltipContext asAdvanced() { ++ return new TooltipContextImpl(this.isCreative, true); ++ } ++} +diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java +index 3f1b48fd65df954e874e6dc6b9093cb12370e2c5..0e9ccfee7a03d341e7c4d271f53b4ed168b404ef 100644 +--- a/src/main/java/org/bukkit/UnsafeValues.java ++++ b/src/main/java/org/bukkit/UnsafeValues.java +@@ -273,4 +273,6 @@ public interface UnsafeValues { + @org.jetbrains.annotations.ApiStatus.Internal + io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck); + // Paper end - lifecycle event API ++ ++ @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines + } +diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java +index c5e22bca27f3199eb2a466f41aa82047f5fd0e44..235d41b0078bb513470b17a0dad46fae3ac73a16 100644 +--- a/src/main/java/org/bukkit/inventory/ItemStack.java ++++ b/src/main/java/org/bukkit/inventory/ItemStack.java +@@ -1037,4 +1037,21 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat + return type.isAir() || amount <= 0; + } + // Paper end ++ // Paper start - expose itemstack tooltip lines ++ /** ++ * Computes the tooltip lines for this stack. ++ *

++ * Disclaimer: ++ * Tooltip contents are not guaranteed to be consistent across different ++ * Minecraft versions. ++ * ++ * @param tooltipContext the tooltip context ++ * @param player a player for player-specific tooltip lines ++ * @return an immutable list of components (can be empty) ++ */ ++ @SuppressWarnings("deprecation") // abusing unsafe as a bridge ++ public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List computeTooltipLines(final @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, final @Nullable org.bukkit.entity.Player player) { ++ return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player); ++ } ++ // Paper end - expose itemstack tooltip lines + } diff --git a/patches/api/0446-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/api/0446-Add-getChunkSnapshot-includeLightData-parameter.patch new file mode 100644 index 0000000000..9b950f9493 --- /dev/null +++ b/patches/api/0446-Add-getChunkSnapshot-includeLightData-parameter.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Warrior <50800980+Warriorrrr@users.noreply.github.com> +Date: Sat, 10 Feb 2024 10:05:59 +0100 +Subject: [PATCH] Add getChunkSnapshot includeLightData parameter + + +diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java +index c2eb2edd87b4087bfcdffd98f0f8904fbfd4e657..bc8b5bc17706250b8535b1b309134843d2ce2bb1 100644 +--- a/src/main/java/org/bukkit/Chunk.java ++++ b/src/main/java/org/bukkit/Chunk.java +@@ -103,6 +103,23 @@ public interface Chunk extends PersistentDataHolder { + @NotNull + ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain); + ++ // Paper start - Add getChunkSnapshot includeLightData parameter ++ /** ++ * Capture thread-safe read-only snapshot of chunk data ++ * ++ * @param includeMaxblocky if true, snapshot includes per-coordinate ++ * maximum Y values ++ * @param includeBiome if true, snapshot includes per-coordinate biome ++ * type ++ * @param includeBiomeTempRain if true, snapshot includes per-coordinate ++ * raw biome temperature and rainfall ++ * @param includeLightData Whether to include per-coordinate light emitted by blocks and sky light data ++ * @return ChunkSnapshot ++ */ ++ @NotNull ++ ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain, boolean includeLightData); ++ // Paper end - Add getChunkSnapshot includeLightData parameter ++ + /** + * Checks if entities in this chunk are loaded. + * diff --git a/patches/api/0446-ItemStack-Tooltip-API.patch b/patches/api/0446-ItemStack-Tooltip-API.patch deleted file mode 100644 index 7fa28ddc99..0000000000 --- a/patches/api/0446-ItemStack-Tooltip-API.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Yannick Lamprecht -Date: Mon, 22 Jan 2024 13:27:18 +0100 -Subject: [PATCH] ItemStack Tooltip API - - -diff --git a/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java -new file mode 100644 -index 0000000000000000000000000000000000000000..39ac768b3c5148544cb1aaf2c817e661f6856f64 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContext.java -@@ -0,0 +1,75 @@ -+package io.papermc.paper.inventory.tooltip; -+ -+import org.bukkit.entity.Player; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Context for computing itemstack tooltips via -+ * {@link org.bukkit.inventory.ItemStack#computeTooltipLines(TooltipContext, Player)} -+ */ -+public interface TooltipContext { -+ -+ /** -+ * Creates a new context with the given advanced and creative -+ * mode settings. -+ * -+ * @param advanced whether the context is for advanced tooltips -+ * @param creative whether the context is for the creative inventory -+ * @return a new context -+ */ -+ @Contract("_, _ -> new") -+ static @NotNull TooltipContext create(final boolean advanced, final boolean creative) { -+ return new TooltipContextImpl(advanced, creative); -+ } -+ -+ /** -+ * Creates a new context that is neither advanced nor creative. -+ * -+ * @return a new context -+ */ -+ @Contract("-> new") -+ static @NotNull TooltipContext create() { -+ return new TooltipContextImpl(false, false); -+ } -+ -+ /** -+ * Returns whether the context is for advanced -+ * tooltips. -+ *

-+ * Advanced tooltips are shown by default -+ * when a player has {@code F3+H} enabled. -+ * -+ * @return true if for advanced tooltips -+ */ -+ boolean isAdvanced(); -+ -+ /** -+ * Returns whether the context is for the creative -+ * mode inventory. -+ *

-+ * Creative tooltips are shown by default when a player is -+ * in the creative inventory. -+ * -+ * @return true if for creative mode inventory -+ */ -+ boolean isCreative(); -+ -+ /** -+ * Returns a new context with {@link #isAdvanced()} -+ * set to true. -+ * -+ * @return a new context -+ */ -+ @Contract("-> new") -+ @NotNull TooltipContext asAdvanced(); -+ -+ /** -+ * Returns a new context with {@link #isCreative()} -+ * set to true. -+ * -+ * @return a new context -+ */ -+ @Contract("-> new") -+ @NotNull TooltipContext asCreative(); -+} -diff --git a/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java -new file mode 100644 -index 0000000000000000000000000000000000000000..1d9bed6691f581529c53b577b26f1d0f902ccb0d ---- /dev/null -+++ b/src/main/java/io/papermc/paper/inventory/tooltip/TooltipContextImpl.java -@@ -0,0 +1,16 @@ -+package io.papermc.paper.inventory.tooltip; -+ -+import org.jetbrains.annotations.NotNull; -+ -+record TooltipContextImpl(boolean isCreative, boolean isAdvanced) implements TooltipContext { -+ -+ @Override -+ public @NotNull TooltipContext asCreative() { -+ return new TooltipContextImpl(true, this.isAdvanced); -+ } -+ -+ @Override -+ public @NotNull TooltipContext asAdvanced() { -+ return new TooltipContextImpl(this.isCreative, true); -+ } -+} -diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java -index 3f1b48fd65df954e874e6dc6b9093cb12370e2c5..0e9ccfee7a03d341e7c4d271f53b4ed168b404ef 100644 ---- a/src/main/java/org/bukkit/UnsafeValues.java -+++ b/src/main/java/org/bukkit/UnsafeValues.java -@@ -273,4 +273,6 @@ public interface UnsafeValues { - @org.jetbrains.annotations.ApiStatus.Internal - io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager createPluginLifecycleEventManager(final org.bukkit.plugin.java.JavaPlugin plugin, final java.util.function.BooleanSupplier registrationCheck); - // Paper end - lifecycle event API -+ -+ @NotNull java.util.List computeTooltipLines(@NotNull ItemStack itemStack, @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, @Nullable org.bukkit.entity.Player player); // Paper - expose itemstack tooltip lines - } -diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index c5e22bca27f3199eb2a466f41aa82047f5fd0e44..235d41b0078bb513470b17a0dad46fae3ac73a16 100644 ---- a/src/main/java/org/bukkit/inventory/ItemStack.java -+++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -1037,4 +1037,21 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat - return type.isAir() || amount <= 0; - } - // Paper end -+ // Paper start - expose itemstack tooltip lines -+ /** -+ * Computes the tooltip lines for this stack. -+ *

-+ * Disclaimer: -+ * Tooltip contents are not guaranteed to be consistent across different -+ * Minecraft versions. -+ * -+ * @param tooltipContext the tooltip context -+ * @param player a player for player-specific tooltip lines -+ * @return an immutable list of components (can be empty) -+ */ -+ @SuppressWarnings("deprecation") // abusing unsafe as a bridge -+ public java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List computeTooltipLines(final @NotNull io.papermc.paper.inventory.tooltip.TooltipContext tooltipContext, final @Nullable org.bukkit.entity.Player player) { -+ return Bukkit.getUnsafe().computeTooltipLines(this, tooltipContext, player); -+ } -+ // Paper end - expose itemstack tooltip lines - } diff --git a/patches/api/0447-Add-FluidState-API.patch b/patches/api/0447-Add-FluidState-API.patch new file mode 100644 index 0000000000..3235c393f5 --- /dev/null +++ b/patches/api/0447-Add-FluidState-API.patch @@ -0,0 +1,164 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: vicisacat +Date: Fri, 17 Nov 2023 20:21:47 +0100 +Subject: [PATCH] Add FluidState API + + +diff --git a/src/main/java/io/papermc/paper/block/fluid/FluidData.java b/src/main/java/io/papermc/paper/block/fluid/FluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..913acd58547d97cafc1466f6e2b3b4d22cf0b02d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/FluidData.java +@@ -0,0 +1,68 @@ ++package io.papermc.paper.block.fluid; ++ ++import org.bukkit.Fluid; ++import org.bukkit.Location; ++import org.bukkit.util.Vector; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Range; ++ ++/** ++ * A representation of a fluid in a specific state of data. ++ * This type is not linked to a specific location and hence mostly resembles a {@link org.bukkit.block.data.BlockData}. ++ */ ++public interface FluidData extends Cloneable { ++ ++ /** ++ * Gets the fluid type of this fluid data. ++ * ++ * @return the fluid type ++ */ ++ @NotNull Fluid getFluidType(); ++ ++ /** ++ * Returns a copy of this FluidData. ++ * ++ * @return a copy of the fluid data ++ */ ++ @NotNull FluidData clone(); ++ ++ /** ++ * Computes the direction of the flow of the liquid at the given location as a vector. ++ *

++ * This method requires the passed location's chunk to be loaded. ++ * If said chunk is not loaded when this method is called, the chunk will first be loaded prior to the computation ++ * which leads to a potentially slow sync chunk load. ++ * ++ * @param location - the location to check the liquid flow ++ * @return the flow direction vector at the given location ++ */ ++ @NotNull Vector computeFlowDirection(@NotNull Location location); ++ ++ /** ++ * Returns the level of liquid this fluid data holds. ++ * ++ * @return the amount as an integer, between 0 and 8 ++ */ ++ @Range(from = 0, to = 8) ++ int getLevel(); ++ ++ /** ++ * Computes the height of the fluid in the world. ++ *

++ * This method requires the passed location's chunk to be loaded. ++ * If said chunk is not loaded when this method is called, the chunk will first be loaded prior to the computation ++ * which leads to a potentially slow sync chunk load. ++ * ++ * @param location the location at which to check the high of this fluid data. ++ * @return the height as a float value ++ */ ++ @Range(from = 0, to = 1) ++ float computeHeight(@NotNull Location location); ++ ++ /** ++ * Returns whether this fluid is a source block ++ * ++ * @return true if the fluid is a source block, false otherwise ++ */ ++ boolean isSource(); ++} +diff --git a/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7bd9f28ba646f09080b5c29b9d3be5af676c912e +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java +@@ -0,0 +1,16 @@ ++package io.papermc.paper.block.fluid.type; ++ ++import io.papermc.paper.block.fluid.FluidData; ++ ++/** ++ * A specific subtype of {@link FluidData} that is returned by the API for fluid data of potentially falling fluids. ++ */ ++public interface FallingFluidData extends FluidData { ++ ++ /** ++ * Get if this liquid is falling. ++ * ++ * @return true if falling ++ */ ++ boolean isFalling(); ++} +diff --git a/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fbccdffe8d73e517204081c73bca9154f8c7d69f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java +@@ -0,0 +1,10 @@ ++package io.papermc.paper.block.fluid.type; ++ ++import io.papermc.paper.block.fluid.FluidData; ++ ++/** ++ * A specific subtype of {@link FluidData} that is returned by the API for fluid data of potentially falling fluids. ++ */ ++public interface FlowingFluidData extends FallingFluidData { ++ ++} +diff --git a/src/main/java/org/bukkit/RegionAccessor.java b/src/main/java/org/bukkit/RegionAccessor.java +index 43dd6c59cceba12f27e6b265acc3ad97eea37abd..eb33e8e671972aa308ad75a7ce9aa9ac526f470f 100644 +--- a/src/main/java/org/bukkit/RegionAccessor.java ++++ b/src/main/java/org/bukkit/RegionAccessor.java +@@ -102,6 +102,41 @@ public interface RegionAccessor extends Keyed { // Paper + @NotNull + BlockState getBlockState(int x, int y, int z); + ++ // Paper start - FluidState API ++ /** ++ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the specified position. ++ * ++ * @param x The x-coordinate of the position ++ * @param y The y-coordinate of the position ++ * @param z The z-coordinate of the position ++ * @return The {@link io.papermc.paper.block.fluid.FluidData} at the specified position ++ */ ++ @NotNull ++ io.papermc.paper.block.fluid.FluidData getFluidData(int x, int y, int z); ++ ++ /** ++ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the given position ++ * ++ * @param position The position of the fluid ++ * @return The fluid data at the given position ++ */ ++ @NotNull ++ default io.papermc.paper.block.fluid.FluidData getFluidData(@NotNull io.papermc.paper.math.Position position) { ++ return getFluidData(position.blockX(), position.blockY(), position.blockZ()); ++ } ++ ++ /** ++ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the given position ++ * ++ * @param location The location of the fluid ++ * @return The fluid data at the given position ++ */ ++ @NotNull ++ default io.papermc.paper.block.fluid.FluidData getFluidData(@NotNull Location location) { ++ return getFluidData(location.blockX(), location.blockY(), location.blockZ()); ++ } ++ // Paper end ++ + /** + * Gets the {@link BlockData} at the given {@link Location}. + * diff --git a/patches/api/0447-Add-getChunkSnapshot-includeLightData-parameter.patch b/patches/api/0447-Add-getChunkSnapshot-includeLightData-parameter.patch deleted file mode 100644 index 9b950f9493..0000000000 --- a/patches/api/0447-Add-getChunkSnapshot-includeLightData-parameter.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Warrior <50800980+Warriorrrr@users.noreply.github.com> -Date: Sat, 10 Feb 2024 10:05:59 +0100 -Subject: [PATCH] Add getChunkSnapshot includeLightData parameter - - -diff --git a/src/main/java/org/bukkit/Chunk.java b/src/main/java/org/bukkit/Chunk.java -index c2eb2edd87b4087bfcdffd98f0f8904fbfd4e657..bc8b5bc17706250b8535b1b309134843d2ce2bb1 100644 ---- a/src/main/java/org/bukkit/Chunk.java -+++ b/src/main/java/org/bukkit/Chunk.java -@@ -103,6 +103,23 @@ public interface Chunk extends PersistentDataHolder { - @NotNull - ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain); - -+ // Paper start - Add getChunkSnapshot includeLightData parameter -+ /** -+ * Capture thread-safe read-only snapshot of chunk data -+ * -+ * @param includeMaxblocky if true, snapshot includes per-coordinate -+ * maximum Y values -+ * @param includeBiome if true, snapshot includes per-coordinate biome -+ * type -+ * @param includeBiomeTempRain if true, snapshot includes per-coordinate -+ * raw biome temperature and rainfall -+ * @param includeLightData Whether to include per-coordinate light emitted by blocks and sky light data -+ * @return ChunkSnapshot -+ */ -+ @NotNull -+ ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain, boolean includeLightData); -+ // Paper end - Add getChunkSnapshot includeLightData parameter -+ - /** - * Checks if entities in this chunk are loaded. - * diff --git a/patches/api/0448-Add-FluidState-API.patch b/patches/api/0448-Add-FluidState-API.patch deleted file mode 100644 index 3235c393f5..0000000000 --- a/patches/api/0448-Add-FluidState-API.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: vicisacat -Date: Fri, 17 Nov 2023 20:21:47 +0100 -Subject: [PATCH] Add FluidState API - - -diff --git a/src/main/java/io/papermc/paper/block/fluid/FluidData.java b/src/main/java/io/papermc/paper/block/fluid/FluidData.java -new file mode 100644 -index 0000000000000000000000000000000000000000..913acd58547d97cafc1466f6e2b3b4d22cf0b02d ---- /dev/null -+++ b/src/main/java/io/papermc/paper/block/fluid/FluidData.java -@@ -0,0 +1,68 @@ -+package io.papermc.paper.block.fluid; -+ -+import org.bukkit.Fluid; -+import org.bukkit.Location; -+import org.bukkit.util.Vector; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Range; -+ -+/** -+ * A representation of a fluid in a specific state of data. -+ * This type is not linked to a specific location and hence mostly resembles a {@link org.bukkit.block.data.BlockData}. -+ */ -+public interface FluidData extends Cloneable { -+ -+ /** -+ * Gets the fluid type of this fluid data. -+ * -+ * @return the fluid type -+ */ -+ @NotNull Fluid getFluidType(); -+ -+ /** -+ * Returns a copy of this FluidData. -+ * -+ * @return a copy of the fluid data -+ */ -+ @NotNull FluidData clone(); -+ -+ /** -+ * Computes the direction of the flow of the liquid at the given location as a vector. -+ *

-+ * This method requires the passed location's chunk to be loaded. -+ * If said chunk is not loaded when this method is called, the chunk will first be loaded prior to the computation -+ * which leads to a potentially slow sync chunk load. -+ * -+ * @param location - the location to check the liquid flow -+ * @return the flow direction vector at the given location -+ */ -+ @NotNull Vector computeFlowDirection(@NotNull Location location); -+ -+ /** -+ * Returns the level of liquid this fluid data holds. -+ * -+ * @return the amount as an integer, between 0 and 8 -+ */ -+ @Range(from = 0, to = 8) -+ int getLevel(); -+ -+ /** -+ * Computes the height of the fluid in the world. -+ *

-+ * This method requires the passed location's chunk to be loaded. -+ * If said chunk is not loaded when this method is called, the chunk will first be loaded prior to the computation -+ * which leads to a potentially slow sync chunk load. -+ * -+ * @param location the location at which to check the high of this fluid data. -+ * @return the height as a float value -+ */ -+ @Range(from = 0, to = 1) -+ float computeHeight(@NotNull Location location); -+ -+ /** -+ * Returns whether this fluid is a source block -+ * -+ * @return true if the fluid is a source block, false otherwise -+ */ -+ boolean isSource(); -+} -diff --git a/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java -new file mode 100644 -index 0000000000000000000000000000000000000000..7bd9f28ba646f09080b5c29b9d3be5af676c912e ---- /dev/null -+++ b/src/main/java/io/papermc/paper/block/fluid/type/FallingFluidData.java -@@ -0,0 +1,16 @@ -+package io.papermc.paper.block.fluid.type; -+ -+import io.papermc.paper.block.fluid.FluidData; -+ -+/** -+ * A specific subtype of {@link FluidData} that is returned by the API for fluid data of potentially falling fluids. -+ */ -+public interface FallingFluidData extends FluidData { -+ -+ /** -+ * Get if this liquid is falling. -+ * -+ * @return true if falling -+ */ -+ boolean isFalling(); -+} -diff --git a/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java b/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fbccdffe8d73e517204081c73bca9154f8c7d69f ---- /dev/null -+++ b/src/main/java/io/papermc/paper/block/fluid/type/FlowingFluidData.java -@@ -0,0 +1,10 @@ -+package io.papermc.paper.block.fluid.type; -+ -+import io.papermc.paper.block.fluid.FluidData; -+ -+/** -+ * A specific subtype of {@link FluidData} that is returned by the API for fluid data of potentially falling fluids. -+ */ -+public interface FlowingFluidData extends FallingFluidData { -+ -+} -diff --git a/src/main/java/org/bukkit/RegionAccessor.java b/src/main/java/org/bukkit/RegionAccessor.java -index 43dd6c59cceba12f27e6b265acc3ad97eea37abd..eb33e8e671972aa308ad75a7ce9aa9ac526f470f 100644 ---- a/src/main/java/org/bukkit/RegionAccessor.java -+++ b/src/main/java/org/bukkit/RegionAccessor.java -@@ -102,6 +102,41 @@ public interface RegionAccessor extends Keyed { // Paper - @NotNull - BlockState getBlockState(int x, int y, int z); - -+ // Paper start - FluidState API -+ /** -+ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the specified position. -+ * -+ * @param x The x-coordinate of the position -+ * @param y The y-coordinate of the position -+ * @param z The z-coordinate of the position -+ * @return The {@link io.papermc.paper.block.fluid.FluidData} at the specified position -+ */ -+ @NotNull -+ io.papermc.paper.block.fluid.FluidData getFluidData(int x, int y, int z); -+ -+ /** -+ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the given position -+ * -+ * @param position The position of the fluid -+ * @return The fluid data at the given position -+ */ -+ @NotNull -+ default io.papermc.paper.block.fluid.FluidData getFluidData(@NotNull io.papermc.paper.math.Position position) { -+ return getFluidData(position.blockX(), position.blockY(), position.blockZ()); -+ } -+ -+ /** -+ * Gets the {@link io.papermc.paper.block.fluid.FluidData} at the given position -+ * -+ * @param location The location of the fluid -+ * @return The fluid data at the given position -+ */ -+ @NotNull -+ default io.papermc.paper.block.fluid.FluidData getFluidData(@NotNull Location location) { -+ return getFluidData(location.blockX(), location.blockY(), location.blockZ()); -+ } -+ // Paper end -+ - /** - * Gets the {@link BlockData} at the given {@link Location}. - * diff --git a/patches/api/0448-add-number-format-api.patch b/patches/api/0448-add-number-format-api.patch new file mode 100644 index 0000000000..6d32302ad0 --- /dev/null +++ b/patches/api/0448-add-number-format-api.patch @@ -0,0 +1,229 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: David Mayr +Date: Sat, 16 Dec 2023 10:40:29 +0100 +Subject: [PATCH] add number format api + +Signed-off-by: David Mayr + +diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/BlankFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/BlankFormatImpl.java +new file mode 100644 +index 0000000000000000000000000000000000000000..486da6ebe0137bb3280e8b33c8e35e309507f118 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/scoreboard/numbers/BlankFormatImpl.java +@@ -0,0 +1,5 @@ ++package io.papermc.paper.scoreboard.numbers; ++ ++record BlankFormatImpl() implements NumberFormat { ++ public static final BlankFormatImpl INSTANCE = new BlankFormatImpl(); ++} +diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormat.java b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormat.java +new file mode 100644 +index 0000000000000000000000000000000000000000..66e0569789d523076cb571fb32be78ecff74305b +--- /dev/null ++++ b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormat.java +@@ -0,0 +1,19 @@ ++package io.papermc.paper.scoreboard.numbers; ++ ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.ComponentLike; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * A scoreboard number format that replaces the score number with a chat component. ++ */ ++public interface FixedFormat extends NumberFormat, ComponentLike { ++ ++ /** ++ * The component shown instead of the number for a score ++ * ++ * @return the chat component ++ */ ++ @NotNull Component component(); ++ ++} +diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java +new file mode 100644 +index 0000000000000000000000000000000000000000..969bbfcdb68ffb5a207207e20e4d79621900c0f5 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java +@@ -0,0 +1,12 @@ ++package io.papermc.paper.scoreboard.numbers; ++ ++import net.kyori.adventure.text.Component; ++import org.jetbrains.annotations.NotNull; ++ ++record FixedFormatImpl(@NotNull Component component) implements FixedFormat { ++ ++ @Override ++ public @NotNull Component asComponent() { ++ return this.component(); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/NumberFormat.java b/src/main/java/io/papermc/paper/scoreboard/numbers/NumberFormat.java +new file mode 100644 +index 0000000000000000000000000000000000000000..eadf637f5fc582a2af5db71274ac1f01b2a28913 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/scoreboard/numbers/NumberFormat.java +@@ -0,0 +1,60 @@ ++package io.papermc.paper.scoreboard.numbers; ++ ++import net.kyori.adventure.text.ComponentLike; ++import net.kyori.adventure.text.format.Style; ++import net.kyori.adventure.text.format.StyleBuilderApplicable; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Describes a scoreboard number format that applies custom formatting to scoreboard scores. ++ */ ++public interface NumberFormat { ++ ++ /** ++ * Creates a blank scoreboard number format that removes the score number entirely. ++ * ++ * @return a blank number format ++ */ ++ static @NotNull NumberFormat blank() { ++ return BlankFormatImpl.INSTANCE; ++ } ++ ++ /** ++ * Gets an un-styled number format. ++ * ++ * @return an un-styled number format ++ */ ++ static @NotNull StyledFormat noStyle() { ++ return StyledFormatImpl.NO_STYLE; ++ } ++ ++ /** ++ * Creates a scoreboard number format that applies a custom formatting to the score number. ++ * ++ * @param style the style to apply on the number ++ * @return a styled number format ++ */ ++ static @NotNull StyledFormat styled(final @NotNull Style style) { ++ return new StyledFormatImpl(style); ++ } ++ ++ /** ++ * Creates a scoreboard number format that applies a custom formatting to the score number. ++ * ++ * @param styleBuilderApplicables the style to apply on the number ++ * @return a styled number format ++ */ ++ static @NotNull StyledFormat styled(final @NotNull StyleBuilderApplicable @NotNull... styleBuilderApplicables) { ++ return styled(Style.style(styleBuilderApplicables)); ++ } ++ ++ /** ++ * Creates a scoreboard number format that replaces the score number with a chat component. ++ * ++ * @param component the component to replace the number with ++ * @return a fixed number format ++ */ ++ static @NotNull FixedFormat fixed(final @NotNull ComponentLike component) { ++ return new FixedFormatImpl(component.asComponent()); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormat.java b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormat.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fe844677d689c3afe5ff2b706d562724e4121137 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormat.java +@@ -0,0 +1,19 @@ ++package io.papermc.paper.scoreboard.numbers; ++ ++import net.kyori.adventure.text.format.Style; ++import net.kyori.adventure.text.format.StyleBuilderApplicable; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * A scoreboard number format that applies a custom formatting to the score number. ++ */ ++public interface StyledFormat extends NumberFormat, StyleBuilderApplicable { ++ ++ /** ++ * The style that is being applied to the number in the score ++ * ++ * @return the style to apply ++ */ ++ @NotNull Style style(); ++ ++} +diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0421e6c7cb32a912cf4aa281623c4311d5d1a34f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java +@@ -0,0 +1,13 @@ ++package io.papermc.paper.scoreboard.numbers; ++ ++import net.kyori.adventure.text.format.Style; ++import org.jetbrains.annotations.NotNull; ++ ++record StyledFormatImpl(@NotNull Style style) implements StyledFormat { ++ static final StyledFormat NO_STYLE = new StyledFormatImpl(Style.empty()); ++ ++ @Override ++ public void styleApply(final Style.@NotNull Builder style) { ++ style.merge(this.style); ++ } ++} +diff --git a/src/main/java/org/bukkit/scoreboard/Objective.java b/src/main/java/org/bukkit/scoreboard/Objective.java +index bd4d84cbf220ab02f09ece97873bbf0bdf7a45ba..1750f97d2122e6e597b9549df8f6fa74bf5e2e2d 100644 +--- a/src/main/java/org/bukkit/scoreboard/Objective.java ++++ b/src/main/java/org/bukkit/scoreboard/Objective.java +@@ -195,4 +195,22 @@ public interface Objective { + */ + void setAutoUpdateDisplay(boolean autoUpdateDisplay); + // Paper end - add more score API ++ ++ // Paper start - number format api ++ /** ++ * Gets the number format for this objective's scores or null if the client default is used. ++ * ++ * @return this objective's number format, or null if the client default is used ++ * @throws IllegalStateException if this objective has been unregistered ++ */ ++ @Nullable io.papermc.paper.scoreboard.numbers.NumberFormat numberFormat(); ++ ++ /** ++ * Sets the number format for this objective's scores. ++ * ++ * @param format the number format to set, pass null to reset format to default ++ * @throws IllegalStateException if this objective has been unregistered ++ */ ++ void numberFormat(@Nullable io.papermc.paper.scoreboard.numbers.NumberFormat format); ++ // Paper end - number format api + } +diff --git a/src/main/java/org/bukkit/scoreboard/Score.java b/src/main/java/org/bukkit/scoreboard/Score.java +index 5b6f243492d55d2db0d6944dc6daca9b181551d6..fba8e475c1f1a410c44a95fcc474cce19e0f515c 100644 +--- a/src/main/java/org/bukkit/scoreboard/Score.java ++++ b/src/main/java/org/bukkit/scoreboard/Score.java +@@ -129,4 +129,26 @@ public interface Score { + */ + void customName(net.kyori.adventure.text.@Nullable Component customName); + // Paper end - add more score API ++ ++ // Paper start - number format api ++ /** ++ * Gets the number format for this score or null if the score has not been set yet ++ * or the objective's default is being used. ++ * ++ * @return this score's number format, or null if the objective's default is used or the score doesn't exist ++ * @throws IllegalStateException if the associated objective has been ++ * unregistered ++ */ ++ @Nullable io.papermc.paper.scoreboard.numbers.NumberFormat numberFormat(); ++ ++ /** ++ * Sets the number format for this score. If this score has not been set yet {@link #isScoreSet()}, it will be created ++ * ++ * @param format the number format to set, pass null to reset format to default ++ * @throws IllegalStateException if the associated objective has been ++ * unregistered ++ */ ++ void numberFormat(@Nullable io.papermc.paper.scoreboard.numbers.NumberFormat format); ++ // Paper end - number format api ++ + } diff --git a/patches/api/0449-add-number-format-api.patch b/patches/api/0449-add-number-format-api.patch deleted file mode 100644 index 6d32302ad0..0000000000 --- a/patches/api/0449-add-number-format-api.patch +++ /dev/null @@ -1,229 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: David Mayr -Date: Sat, 16 Dec 2023 10:40:29 +0100 -Subject: [PATCH] add number format api - -Signed-off-by: David Mayr - -diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/BlankFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/BlankFormatImpl.java -new file mode 100644 -index 0000000000000000000000000000000000000000..486da6ebe0137bb3280e8b33c8e35e309507f118 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/scoreboard/numbers/BlankFormatImpl.java -@@ -0,0 +1,5 @@ -+package io.papermc.paper.scoreboard.numbers; -+ -+record BlankFormatImpl() implements NumberFormat { -+ public static final BlankFormatImpl INSTANCE = new BlankFormatImpl(); -+} -diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormat.java b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormat.java -new file mode 100644 -index 0000000000000000000000000000000000000000..66e0569789d523076cb571fb32be78ecff74305b ---- /dev/null -+++ b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormat.java -@@ -0,0 +1,19 @@ -+package io.papermc.paper.scoreboard.numbers; -+ -+import net.kyori.adventure.text.Component; -+import net.kyori.adventure.text.ComponentLike; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * A scoreboard number format that replaces the score number with a chat component. -+ */ -+public interface FixedFormat extends NumberFormat, ComponentLike { -+ -+ /** -+ * The component shown instead of the number for a score -+ * -+ * @return the chat component -+ */ -+ @NotNull Component component(); -+ -+} -diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java -new file mode 100644 -index 0000000000000000000000000000000000000000..969bbfcdb68ffb5a207207e20e4d79621900c0f5 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/scoreboard/numbers/FixedFormatImpl.java -@@ -0,0 +1,12 @@ -+package io.papermc.paper.scoreboard.numbers; -+ -+import net.kyori.adventure.text.Component; -+import org.jetbrains.annotations.NotNull; -+ -+record FixedFormatImpl(@NotNull Component component) implements FixedFormat { -+ -+ @Override -+ public @NotNull Component asComponent() { -+ return this.component(); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/NumberFormat.java b/src/main/java/io/papermc/paper/scoreboard/numbers/NumberFormat.java -new file mode 100644 -index 0000000000000000000000000000000000000000..eadf637f5fc582a2af5db71274ac1f01b2a28913 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/scoreboard/numbers/NumberFormat.java -@@ -0,0 +1,60 @@ -+package io.papermc.paper.scoreboard.numbers; -+ -+import net.kyori.adventure.text.ComponentLike; -+import net.kyori.adventure.text.format.Style; -+import net.kyori.adventure.text.format.StyleBuilderApplicable; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Describes a scoreboard number format that applies custom formatting to scoreboard scores. -+ */ -+public interface NumberFormat { -+ -+ /** -+ * Creates a blank scoreboard number format that removes the score number entirely. -+ * -+ * @return a blank number format -+ */ -+ static @NotNull NumberFormat blank() { -+ return BlankFormatImpl.INSTANCE; -+ } -+ -+ /** -+ * Gets an un-styled number format. -+ * -+ * @return an un-styled number format -+ */ -+ static @NotNull StyledFormat noStyle() { -+ return StyledFormatImpl.NO_STYLE; -+ } -+ -+ /** -+ * Creates a scoreboard number format that applies a custom formatting to the score number. -+ * -+ * @param style the style to apply on the number -+ * @return a styled number format -+ */ -+ static @NotNull StyledFormat styled(final @NotNull Style style) { -+ return new StyledFormatImpl(style); -+ } -+ -+ /** -+ * Creates a scoreboard number format that applies a custom formatting to the score number. -+ * -+ * @param styleBuilderApplicables the style to apply on the number -+ * @return a styled number format -+ */ -+ static @NotNull StyledFormat styled(final @NotNull StyleBuilderApplicable @NotNull... styleBuilderApplicables) { -+ return styled(Style.style(styleBuilderApplicables)); -+ } -+ -+ /** -+ * Creates a scoreboard number format that replaces the score number with a chat component. -+ * -+ * @param component the component to replace the number with -+ * @return a fixed number format -+ */ -+ static @NotNull FixedFormat fixed(final @NotNull ComponentLike component) { -+ return new FixedFormatImpl(component.asComponent()); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormat.java b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormat.java -new file mode 100644 -index 0000000000000000000000000000000000000000..fe844677d689c3afe5ff2b706d562724e4121137 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormat.java -@@ -0,0 +1,19 @@ -+package io.papermc.paper.scoreboard.numbers; -+ -+import net.kyori.adventure.text.format.Style; -+import net.kyori.adventure.text.format.StyleBuilderApplicable; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * A scoreboard number format that applies a custom formatting to the score number. -+ */ -+public interface StyledFormat extends NumberFormat, StyleBuilderApplicable { -+ -+ /** -+ * The style that is being applied to the number in the score -+ * -+ * @return the style to apply -+ */ -+ @NotNull Style style(); -+ -+} -diff --git a/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0421e6c7cb32a912cf4aa281623c4311d5d1a34f ---- /dev/null -+++ b/src/main/java/io/papermc/paper/scoreboard/numbers/StyledFormatImpl.java -@@ -0,0 +1,13 @@ -+package io.papermc.paper.scoreboard.numbers; -+ -+import net.kyori.adventure.text.format.Style; -+import org.jetbrains.annotations.NotNull; -+ -+record StyledFormatImpl(@NotNull Style style) implements StyledFormat { -+ static final StyledFormat NO_STYLE = new StyledFormatImpl(Style.empty()); -+ -+ @Override -+ public void styleApply(final Style.@NotNull Builder style) { -+ style.merge(this.style); -+ } -+} -diff --git a/src/main/java/org/bukkit/scoreboard/Objective.java b/src/main/java/org/bukkit/scoreboard/Objective.java -index bd4d84cbf220ab02f09ece97873bbf0bdf7a45ba..1750f97d2122e6e597b9549df8f6fa74bf5e2e2d 100644 ---- a/src/main/java/org/bukkit/scoreboard/Objective.java -+++ b/src/main/java/org/bukkit/scoreboard/Objective.java -@@ -195,4 +195,22 @@ public interface Objective { - */ - void setAutoUpdateDisplay(boolean autoUpdateDisplay); - // Paper end - add more score API -+ -+ // Paper start - number format api -+ /** -+ * Gets the number format for this objective's scores or null if the client default is used. -+ * -+ * @return this objective's number format, or null if the client default is used -+ * @throws IllegalStateException if this objective has been unregistered -+ */ -+ @Nullable io.papermc.paper.scoreboard.numbers.NumberFormat numberFormat(); -+ -+ /** -+ * Sets the number format for this objective's scores. -+ * -+ * @param format the number format to set, pass null to reset format to default -+ * @throws IllegalStateException if this objective has been unregistered -+ */ -+ void numberFormat(@Nullable io.papermc.paper.scoreboard.numbers.NumberFormat format); -+ // Paper end - number format api - } -diff --git a/src/main/java/org/bukkit/scoreboard/Score.java b/src/main/java/org/bukkit/scoreboard/Score.java -index 5b6f243492d55d2db0d6944dc6daca9b181551d6..fba8e475c1f1a410c44a95fcc474cce19e0f515c 100644 ---- a/src/main/java/org/bukkit/scoreboard/Score.java -+++ b/src/main/java/org/bukkit/scoreboard/Score.java -@@ -129,4 +129,26 @@ public interface Score { - */ - void customName(net.kyori.adventure.text.@Nullable Component customName); - // Paper end - add more score API -+ -+ // Paper start - number format api -+ /** -+ * Gets the number format for this score or null if the score has not been set yet -+ * or the objective's default is being used. -+ * -+ * @return this score's number format, or null if the objective's default is used or the score doesn't exist -+ * @throws IllegalStateException if the associated objective has been -+ * unregistered -+ */ -+ @Nullable io.papermc.paper.scoreboard.numbers.NumberFormat numberFormat(); -+ -+ /** -+ * Sets the number format for this score. If this score has not been set yet {@link #isScoreSet()}, it will be created -+ * -+ * @param format the number format to set, pass null to reset format to default -+ * @throws IllegalStateException if the associated objective has been -+ * unregistered -+ */ -+ void numberFormat(@Nullable io.papermc.paper.scoreboard.numbers.NumberFormat format); -+ // Paper end - number format api -+ - } diff --git a/patches/api/0449-improve-BanList-types.patch b/patches/api/0449-improve-BanList-types.patch new file mode 100644 index 0000000000..f392d209de --- /dev/null +++ b/patches/api/0449-improve-BanList-types.patch @@ -0,0 +1,131 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Yannick Lamprecht +Date: Sat, 10 Feb 2024 20:49:47 +0100 +Subject: [PATCH] improve BanList types + + +diff --git a/src/main/java/io/papermc/paper/ban/BanListType.java b/src/main/java/io/papermc/paper/ban/BanListType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2980abf2f41cb14f0ee5c829c365f8e304130618 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/ban/BanListType.java +@@ -0,0 +1,29 @@ ++package io.papermc.paper.ban; ++ ++import org.bukkit.BanList; ++import org.bukkit.ban.IpBanList; ++import org.bukkit.ban.ProfileBanList; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Represents a ban-type that a {@link BanList} may track. ++ * It enforces the correct return value at compile time. ++ */ ++public interface BanListType { ++ ++ /** ++ * Banned IP addresses ++ */ ++ BanListType IP = new BanListTypeImpl<>(IpBanList.class); ++ /** ++ * Banned player profiles ++ */ ++ BanListType PROFILE = new BanListTypeImpl<>(ProfileBanList.class); ++ ++ /** ++ * Returns the type class of the ban list used generically ++ * ++ * @return the type class ++ */ ++ @NotNull Class typeClass(); ++} +diff --git a/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java b/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1159e7cd29fbf11f3fa1448fcf9d0768e1bcb0a3 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java +@@ -0,0 +1,8 @@ ++package io.papermc.paper.ban; ++ ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++@ApiStatus.Internal ++record BanListTypeImpl(@NotNull Class typeClass) implements BanListType { ++} +diff --git a/src/main/java/org/bukkit/BanList.java b/src/main/java/org/bukkit/BanList.java +index a77c0411a68a9bad33ddfb335b7a996a843e478c..739d9d3ec789e58c10c8d818a9ca59ce447600d5 100644 +--- a/src/main/java/org/bukkit/BanList.java ++++ b/src/main/java/org/bukkit/BanList.java +@@ -16,7 +16,9 @@ public interface BanList { + + /** + * Represents a ban-type that a {@link BanList} may track. ++ * @deprecated use {@link io.papermc.paper.ban.BanListType} to enforce the correct return value at compile time. + */ ++ @Deprecated(since = "1.20.4") // Paper - BanList Type Improvements + public enum Type { + /** + * Banned player names +diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java +index 50d6784c488041ce416845373efebce14321b1ec..b9b751ea0d11381e846d5f35f39f285c075c171a 100644 +--- a/src/main/java/org/bukkit/Bukkit.java ++++ b/src/main/java/org/bukkit/Bukkit.java +@@ -1649,11 +1649,27 @@ public final class Bukkit { + * @param The ban target + * + * @return a ban list of the specified type ++ * @deprecated use {@link #getBanList(io.papermc.paper.ban.BanListType)} to enforce the correct return value at compile time. + */ + @NotNull ++ @Deprecated(since = "1.20.4") // Paper - add BanListType (which has a generic) + public static > T getBanList(@NotNull BanList.Type type) { + return server.getBanList(type); + } ++ // Paper start - add BanListType (which has a generic) ++ /** ++ * Gets a ban list for the supplied type. ++ * ++ * @param type the type of list to fetch, cannot be null ++ * @param The ban target ++ * ++ * @return a ban list of the specified type ++ */ ++ @NotNull ++ public static , E> B getBanList(final io.papermc.paper.ban.@NotNull BanListType type) { ++ return server.getBanList(type); ++ } ++ // Paper end - add BanListType (which has a generic) + + /** + * Gets a set containing all player operators. +diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java +index 23af0b4fa239de8926a36346f38224a00f85284e..bbc4d7d3ca84642828f9a3f788ca26bba900d15b 100644 +--- a/src/main/java/org/bukkit/Server.java ++++ b/src/main/java/org/bukkit/Server.java +@@ -1411,10 +1411,25 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi + * @param The ban target + * + * @return a ban list of the specified type ++ * @deprecated use {@link #getBanList(io.papermc.paper.ban.BanListType)} to enforce the correct return value at compile time. + */ ++ @Deprecated // Paper - add BanListType (which has a generic) + @NotNull + public > T getBanList(@NotNull BanList.Type type); + ++ // Paper start - add BanListType (which has a generic) ++ /** ++ * Gets a ban list for the supplied type. ++ * ++ * @param type the type of list to fetch, cannot be null ++ * @param The ban target ++ * ++ * @return a ban list of the specified type ++ */ ++ @NotNull ++ , E> B getBanList(@NotNull io.papermc.paper.ban.BanListType type); ++ // Paper end - add BanListType (which has a generic) ++ + /** + * Gets a set containing all player operators. + * diff --git a/patches/api/0450-Suspicious-Effect-Entry-API.patch b/patches/api/0450-Suspicious-Effect-Entry-API.patch new file mode 100644 index 0000000000..bcf3db2033 --- /dev/null +++ b/patches/api/0450-Suspicious-Effect-Entry-API.patch @@ -0,0 +1,216 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Sun, 3 Mar 2024 19:45:52 +0100 +Subject: [PATCH] Suspicious Effect Entry API + +Exposes a new suspicious effect entry type that properly represents +storable effects in the context of suspicious effects as they only +define the potion effect type and duration. + +This differentiates them from the existing PotionEffect API found in +bukkit and hence clarifies that storable values in the parts of the API +in which it replaces PotionEffect. + +Co-authored-by: Yannick Lamprecht + +diff --git a/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntry.java b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6a96e339ff1466df5743b5d42a31ce6a67e48f16 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntry.java +@@ -0,0 +1,38 @@ ++package io.papermc.paper.potion; ++ ++import org.bukkit.potion.PotionEffect; ++import org.bukkit.potion.PotionEffectType; ++import org.jetbrains.annotations.Contract; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Represents a {@link PotionEffectType} paired with a duration. ++ */ ++public sealed interface SuspiciousEffectEntry permits SuspiciousEffectEntryImpl { ++ ++ /** ++ * Gets the effect type. ++ * ++ * @return effect type ++ */ ++ @NotNull PotionEffectType effect(); ++ ++ /** ++ * Gets the duration for this effect instance. ++ * ++ * @return duration (in ticks) or {@link PotionEffect#INFINITE_DURATION} ++ */ ++ int duration(); ++ ++ /** ++ * Creates a new instance of SuspiciousEffectEntry. ++ * ++ * @param effectType effect type ++ * @param duration duration (in ticks) or {@link PotionEffect#INFINITE_DURATION} ++ * @return new instance of an entry ++ */ ++ @Contract(value = "_, _ -> new", pure = true) ++ static @NotNull SuspiciousEffectEntry create(final @NotNull PotionEffectType effectType, final int duration) { ++ return new SuspiciousEffectEntryImpl(effectType, duration); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntryImpl.java b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntryImpl.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e5002ccaef9ea7a9db94296ad0d66cdae050cdd1 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntryImpl.java +@@ -0,0 +1,7 @@ ++package io.papermc.paper.potion; ++ ++import org.bukkit.potion.PotionEffectType; ++import org.jetbrains.annotations.NotNull; ++ ++record SuspiciousEffectEntryImpl(@NotNull PotionEffectType effect, int duration) implements SuspiciousEffectEntry { ++} +diff --git a/src/main/java/org/bukkit/entity/MushroomCow.java b/src/main/java/org/bukkit/entity/MushroomCow.java +index 86c0043ef4e1288b6fe2f68a9b6d01c3de2c3454..3677f19ef1c05b76d946b1b2b491a6c3cec76140 100644 +--- a/src/main/java/org/bukkit/entity/MushroomCow.java ++++ b/src/main/java/org/bukkit/entity/MushroomCow.java +@@ -34,14 +34,30 @@ public interface MushroomCow extends Cow, io.papermc.paper.entity.Shearable { // + * Adds a custom potion effect to be applied to the next suspicious stew + * received from milking this {@link MushroomCow}. + * ++ * @deprecated use {@link #addEffectToNextStew(io.papermc.paper.potion.SuspiciousEffectEntry, boolean)} as PotionEffect suggests that all attributes are used. In fact, only the PotionEffectType and the duration are used. + * @param effect the potion effect to add + * @param overwrite true if any existing effect of the same type should be + * overwritten + * @return true if the effects to be applied to the suspicious stew changed + * as a result of this call + */ ++ @Deprecated(forRemoval = true, since = "1.20.2") // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta + boolean addEffectToNextStew(@NotNull PotionEffect effect, boolean overwrite); + ++ // Paper start - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta ++ /** ++ * Adds a suspicious effect entry to be applied to the next suspicious stew ++ * received from milking this {@link MushroomCow}. ++ * ++ * @param suspiciousEffectEntry the suspicious effect entry to add ++ * @param overwrite true if any existing effect of the same type should be ++ * overwritten ++ * @return true if the effects to be applied to the suspicious stew changed ++ * as a result of this call ++ */ ++ boolean addEffectToNextStew(@NotNull io.papermc.paper.potion.SuspiciousEffectEntry suspiciousEffectEntry, boolean overwrite); ++ // Paper end - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta ++ + /** + * Removes a custom potion effect from being applied to the next suspicious + * stew received from milking this {@link MushroomCow}. +@@ -95,4 +111,75 @@ public interface MushroomCow extends Cow, io.papermc.paper.entity.Shearable { // + */ + BROWN; + } ++ // Paper start ++ /** ++ * Gets how long the effect applied to stew ++ * from this mushroom cow is. ++ * ++ * @return duration of the effect (in ticks) ++ * @deprecated Mushroom cows can now hold multiple effects, use {@link #getStewEffects()} ++ */ ++ @Deprecated(forRemoval = true, since = "1.20.2") ++ @org.jetbrains.annotations.Contract("-> fail") ++ default int getStewEffectDuration() { ++ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #getStewEffects"); ++ } ++ ++ /** ++ * Sets how long the effect applied to stew ++ * from this mushroom cow is. ++ * ++ * @param duration duration of the effect (in ticks) ++ * @deprecated Mushroom cows can now hold multiple effects, use {@link #setStewEffects(java.util.List)} ++ */ ++ @Deprecated(forRemoval = true, since = "1.20.2") ++ @org.jetbrains.annotations.Contract("_ -> fail") ++ default void setStewEffectDuration(int duration) { ++ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #setStewEffects"); ++ } ++ ++ /** ++ * Gets the type of effect applied to stew ++ * from this mushroom cow is. ++ * ++ * @return effect type, or null if an effect is currently not set ++ * @deprecated Mushroom cows can now hold multiple effects, use {@link #getStewEffects()} ++ * @throws UnsupportedOperationException ++ */ ++ @Deprecated(forRemoval = true, since = "1.20.2") ++ @org.jetbrains.annotations.Contract("-> fail") ++ default org.bukkit.potion.PotionEffectType getStewEffectType() { ++ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #getStewEffects"); ++ } ++ ++ /** ++ * Sets the type of effect applied to stew ++ * from this mushroom cow is. ++ * ++ * @param type new effect type ++ * or null if this cow does not give effects ++ * @deprecated Mushroom cows can now hold multiple effects, use {@link #setStewEffects(java.util.List)} ++ * @throws UnsupportedOperationException ++ */ ++ @Deprecated(forRemoval = true, since = "1.20.2") ++ @org.jetbrains.annotations.Contract("_ -> fail") ++ default void setStewEffect(@org.jetbrains.annotations.Nullable org.bukkit.potion.PotionEffectType type) { ++ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #setStewEffects"); ++ } ++ ++ /** ++ * Returns an immutable collection of the effects applied to stew ++ * items for this mushroom cow. ++ * ++ * @return immutable effect entry collection ++ */ ++ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getStewEffects(); ++ ++ /** ++ * Sets effects applied to stew items for this mushroom cow. ++ * ++ * @param effects effect entry list ++ */ ++ void setStewEffects(java.util.@NotNull List effects); ++ // Paper end + } +diff --git a/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java b/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java +index c2f4282c188e7d8041459cb3acaad674443ba147..c5bfc062fcca56495f44039d83356fc1fd7568d0 100644 +--- a/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java ++++ b/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java +@@ -32,13 +32,28 @@ public interface SuspiciousStewMeta extends ItemMeta { + /** + * Adds a custom potion effect to this suspicious stew. + * ++ * @deprecated use {@link #addCustomEffect(io.papermc.paper.potion.SuspiciousEffectEntry, boolean)} as PotionEffect suggests that all attributes are used. In fact, only the PotionEffectType and the duration are used. + * @param effect the potion effect to add + * @param overwrite true if any existing effect of the same type should be + * overwritten + * @return true if the suspicious stew meta changed as a result of this call + */ ++ @Deprecated // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta + boolean addCustomEffect(@NotNull PotionEffect effect, boolean overwrite); + ++ // Paper start - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta ++ /** ++ * Adds a custom potion effect to this suspicious stew. ++ * ++ * @param suspiciousEffectEntry the suspicious effect entry to add ++ * @param overwrite true if any existing effect of the same type should be ++ * overwritten ++ * @return true if the suspicious stew meta changed as a result of this call ++ * as a result of this call ++ */ ++ boolean addCustomEffect(@NotNull io.papermc.paper.potion.SuspiciousEffectEntry suspiciousEffectEntry, boolean overwrite); ++ // Paper end - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta ++ + /** + * Removes a custom potion effect from this suspicious stew. + * diff --git a/patches/api/0450-improve-BanList-types.patch b/patches/api/0450-improve-BanList-types.patch deleted file mode 100644 index f392d209de..0000000000 --- a/patches/api/0450-improve-BanList-types.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Yannick Lamprecht -Date: Sat, 10 Feb 2024 20:49:47 +0100 -Subject: [PATCH] improve BanList types - - -diff --git a/src/main/java/io/papermc/paper/ban/BanListType.java b/src/main/java/io/papermc/paper/ban/BanListType.java -new file mode 100644 -index 0000000000000000000000000000000000000000..2980abf2f41cb14f0ee5c829c365f8e304130618 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/ban/BanListType.java -@@ -0,0 +1,29 @@ -+package io.papermc.paper.ban; -+ -+import org.bukkit.BanList; -+import org.bukkit.ban.IpBanList; -+import org.bukkit.ban.ProfileBanList; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Represents a ban-type that a {@link BanList} may track. -+ * It enforces the correct return value at compile time. -+ */ -+public interface BanListType { -+ -+ /** -+ * Banned IP addresses -+ */ -+ BanListType IP = new BanListTypeImpl<>(IpBanList.class); -+ /** -+ * Banned player profiles -+ */ -+ BanListType PROFILE = new BanListTypeImpl<>(ProfileBanList.class); -+ -+ /** -+ * Returns the type class of the ban list used generically -+ * -+ * @return the type class -+ */ -+ @NotNull Class typeClass(); -+} -diff --git a/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java b/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java -new file mode 100644 -index 0000000000000000000000000000000000000000..1159e7cd29fbf11f3fa1448fcf9d0768e1bcb0a3 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/ban/BanListTypeImpl.java -@@ -0,0 +1,8 @@ -+package io.papermc.paper.ban; -+ -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+ -+@ApiStatus.Internal -+record BanListTypeImpl(@NotNull Class typeClass) implements BanListType { -+} -diff --git a/src/main/java/org/bukkit/BanList.java b/src/main/java/org/bukkit/BanList.java -index a77c0411a68a9bad33ddfb335b7a996a843e478c..739d9d3ec789e58c10c8d818a9ca59ce447600d5 100644 ---- a/src/main/java/org/bukkit/BanList.java -+++ b/src/main/java/org/bukkit/BanList.java -@@ -16,7 +16,9 @@ public interface BanList { - - /** - * Represents a ban-type that a {@link BanList} may track. -+ * @deprecated use {@link io.papermc.paper.ban.BanListType} to enforce the correct return value at compile time. - */ -+ @Deprecated(since = "1.20.4") // Paper - BanList Type Improvements - public enum Type { - /** - * Banned player names -diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java -index 50d6784c488041ce416845373efebce14321b1ec..b9b751ea0d11381e846d5f35f39f285c075c171a 100644 ---- a/src/main/java/org/bukkit/Bukkit.java -+++ b/src/main/java/org/bukkit/Bukkit.java -@@ -1649,11 +1649,27 @@ public final class Bukkit { - * @param The ban target - * - * @return a ban list of the specified type -+ * @deprecated use {@link #getBanList(io.papermc.paper.ban.BanListType)} to enforce the correct return value at compile time. - */ - @NotNull -+ @Deprecated(since = "1.20.4") // Paper - add BanListType (which has a generic) - public static > T getBanList(@NotNull BanList.Type type) { - return server.getBanList(type); - } -+ // Paper start - add BanListType (which has a generic) -+ /** -+ * Gets a ban list for the supplied type. -+ * -+ * @param type the type of list to fetch, cannot be null -+ * @param The ban target -+ * -+ * @return a ban list of the specified type -+ */ -+ @NotNull -+ public static , E> B getBanList(final io.papermc.paper.ban.@NotNull BanListType type) { -+ return server.getBanList(type); -+ } -+ // Paper end - add BanListType (which has a generic) - - /** - * Gets a set containing all player operators. -diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 23af0b4fa239de8926a36346f38224a00f85284e..bbc4d7d3ca84642828f9a3f788ca26bba900d15b 100644 ---- a/src/main/java/org/bukkit/Server.java -+++ b/src/main/java/org/bukkit/Server.java -@@ -1411,10 +1411,25 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - * @param The ban target - * - * @return a ban list of the specified type -+ * @deprecated use {@link #getBanList(io.papermc.paper.ban.BanListType)} to enforce the correct return value at compile time. - */ -+ @Deprecated // Paper - add BanListType (which has a generic) - @NotNull - public > T getBanList(@NotNull BanList.Type type); - -+ // Paper start - add BanListType (which has a generic) -+ /** -+ * Gets a ban list for the supplied type. -+ * -+ * @param type the type of list to fetch, cannot be null -+ * @param The ban target -+ * -+ * @return a ban list of the specified type -+ */ -+ @NotNull -+ , E> B getBanList(@NotNull io.papermc.paper.ban.BanListType type); -+ // Paper end - add BanListType (which has a generic) -+ - /** - * Gets a set containing all player operators. - * diff --git a/patches/api/0451-Fix-DamageSource-API.patch b/patches/api/0451-Fix-DamageSource-API.patch new file mode 100644 index 0000000000..efe4403e2c --- /dev/null +++ b/patches/api/0451-Fix-DamageSource-API.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 16 Mar 2024 11:21:14 -0700 +Subject: [PATCH] Fix DamageSource API + + +diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +index 6b24d1281cb8f0253430c9c1a1323e2670bb9c93..8ea4be529400b34df3d31b0f17c2d145345523d9 100644 +--- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java ++++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java +@@ -60,6 +60,20 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent { + } + // Paper end + ++ // Paper start ++ /** ++ * {@inheritDoc} ++ *

++ * The {@link DamageSource#getDirectEntity()} may be different from the {@link #getDamager()} ++ * if the Minecraft damage source did not originally include an damager entity, but one was included ++ * for this event {@link #getDamager()}. ++ */ ++ @Override ++ public @NotNull DamageSource getDamageSource() { ++ return super.getDamageSource(); ++ } ++ // Paper end ++ + /** + * Returns the entity that damaged the defender. + * diff --git a/patches/api/0451-Suspicious-Effect-Entry-API.patch b/patches/api/0451-Suspicious-Effect-Entry-API.patch deleted file mode 100644 index bcf3db2033..0000000000 --- a/patches/api/0451-Suspicious-Effect-Entry-API.patch +++ /dev/null @@ -1,216 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> -Date: Sun, 3 Mar 2024 19:45:52 +0100 -Subject: [PATCH] Suspicious Effect Entry API - -Exposes a new suspicious effect entry type that properly represents -storable effects in the context of suspicious effects as they only -define the potion effect type and duration. - -This differentiates them from the existing PotionEffect API found in -bukkit and hence clarifies that storable values in the parts of the API -in which it replaces PotionEffect. - -Co-authored-by: Yannick Lamprecht - -diff --git a/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntry.java b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntry.java -new file mode 100644 -index 0000000000000000000000000000000000000000..6a96e339ff1466df5743b5d42a31ce6a67e48f16 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntry.java -@@ -0,0 +1,38 @@ -+package io.papermc.paper.potion; -+ -+import org.bukkit.potion.PotionEffect; -+import org.bukkit.potion.PotionEffectType; -+import org.jetbrains.annotations.Contract; -+import org.jetbrains.annotations.NotNull; -+ -+/** -+ * Represents a {@link PotionEffectType} paired with a duration. -+ */ -+public sealed interface SuspiciousEffectEntry permits SuspiciousEffectEntryImpl { -+ -+ /** -+ * Gets the effect type. -+ * -+ * @return effect type -+ */ -+ @NotNull PotionEffectType effect(); -+ -+ /** -+ * Gets the duration for this effect instance. -+ * -+ * @return duration (in ticks) or {@link PotionEffect#INFINITE_DURATION} -+ */ -+ int duration(); -+ -+ /** -+ * Creates a new instance of SuspiciousEffectEntry. -+ * -+ * @param effectType effect type -+ * @param duration duration (in ticks) or {@link PotionEffect#INFINITE_DURATION} -+ * @return new instance of an entry -+ */ -+ @Contract(value = "_, _ -> new", pure = true) -+ static @NotNull SuspiciousEffectEntry create(final @NotNull PotionEffectType effectType, final int duration) { -+ return new SuspiciousEffectEntryImpl(effectType, duration); -+ } -+} -diff --git a/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntryImpl.java b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntryImpl.java -new file mode 100644 -index 0000000000000000000000000000000000000000..e5002ccaef9ea7a9db94296ad0d66cdae050cdd1 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/potion/SuspiciousEffectEntryImpl.java -@@ -0,0 +1,7 @@ -+package io.papermc.paper.potion; -+ -+import org.bukkit.potion.PotionEffectType; -+import org.jetbrains.annotations.NotNull; -+ -+record SuspiciousEffectEntryImpl(@NotNull PotionEffectType effect, int duration) implements SuspiciousEffectEntry { -+} -diff --git a/src/main/java/org/bukkit/entity/MushroomCow.java b/src/main/java/org/bukkit/entity/MushroomCow.java -index 86c0043ef4e1288b6fe2f68a9b6d01c3de2c3454..3677f19ef1c05b76d946b1b2b491a6c3cec76140 100644 ---- a/src/main/java/org/bukkit/entity/MushroomCow.java -+++ b/src/main/java/org/bukkit/entity/MushroomCow.java -@@ -34,14 +34,30 @@ public interface MushroomCow extends Cow, io.papermc.paper.entity.Shearable { // - * Adds a custom potion effect to be applied to the next suspicious stew - * received from milking this {@link MushroomCow}. - * -+ * @deprecated use {@link #addEffectToNextStew(io.papermc.paper.potion.SuspiciousEffectEntry, boolean)} as PotionEffect suggests that all attributes are used. In fact, only the PotionEffectType and the duration are used. - * @param effect the potion effect to add - * @param overwrite true if any existing effect of the same type should be - * overwritten - * @return true if the effects to be applied to the suspicious stew changed - * as a result of this call - */ -+ @Deprecated(forRemoval = true, since = "1.20.2") // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta - boolean addEffectToNextStew(@NotNull PotionEffect effect, boolean overwrite); - -+ // Paper start - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta -+ /** -+ * Adds a suspicious effect entry to be applied to the next suspicious stew -+ * received from milking this {@link MushroomCow}. -+ * -+ * @param suspiciousEffectEntry the suspicious effect entry to add -+ * @param overwrite true if any existing effect of the same type should be -+ * overwritten -+ * @return true if the effects to be applied to the suspicious stew changed -+ * as a result of this call -+ */ -+ boolean addEffectToNextStew(@NotNull io.papermc.paper.potion.SuspiciousEffectEntry suspiciousEffectEntry, boolean overwrite); -+ // Paper end - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta -+ - /** - * Removes a custom potion effect from being applied to the next suspicious - * stew received from milking this {@link MushroomCow}. -@@ -95,4 +111,75 @@ public interface MushroomCow extends Cow, io.papermc.paper.entity.Shearable { // - */ - BROWN; - } -+ // Paper start -+ /** -+ * Gets how long the effect applied to stew -+ * from this mushroom cow is. -+ * -+ * @return duration of the effect (in ticks) -+ * @deprecated Mushroom cows can now hold multiple effects, use {@link #getStewEffects()} -+ */ -+ @Deprecated(forRemoval = true, since = "1.20.2") -+ @org.jetbrains.annotations.Contract("-> fail") -+ default int getStewEffectDuration() { -+ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #getStewEffects"); -+ } -+ -+ /** -+ * Sets how long the effect applied to stew -+ * from this mushroom cow is. -+ * -+ * @param duration duration of the effect (in ticks) -+ * @deprecated Mushroom cows can now hold multiple effects, use {@link #setStewEffects(java.util.List)} -+ */ -+ @Deprecated(forRemoval = true, since = "1.20.2") -+ @org.jetbrains.annotations.Contract("_ -> fail") -+ default void setStewEffectDuration(int duration) { -+ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #setStewEffects"); -+ } -+ -+ /** -+ * Gets the type of effect applied to stew -+ * from this mushroom cow is. -+ * -+ * @return effect type, or null if an effect is currently not set -+ * @deprecated Mushroom cows can now hold multiple effects, use {@link #getStewEffects()} -+ * @throws UnsupportedOperationException -+ */ -+ @Deprecated(forRemoval = true, since = "1.20.2") -+ @org.jetbrains.annotations.Contract("-> fail") -+ default org.bukkit.potion.PotionEffectType getStewEffectType() { -+ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #getStewEffects"); -+ } -+ -+ /** -+ * Sets the type of effect applied to stew -+ * from this mushroom cow is. -+ * -+ * @param type new effect type -+ * or null if this cow does not give effects -+ * @deprecated Mushroom cows can now hold multiple effects, use {@link #setStewEffects(java.util.List)} -+ * @throws UnsupportedOperationException -+ */ -+ @Deprecated(forRemoval = true, since = "1.20.2") -+ @org.jetbrains.annotations.Contract("_ -> fail") -+ default void setStewEffect(@org.jetbrains.annotations.Nullable org.bukkit.potion.PotionEffectType type) { -+ throw new UnsupportedOperationException("Mushroom cows can now hold multiple effects. Use #setStewEffects"); -+ } -+ -+ /** -+ * Returns an immutable collection of the effects applied to stew -+ * items for this mushroom cow. -+ * -+ * @return immutable effect entry collection -+ */ -+ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable List getStewEffects(); -+ -+ /** -+ * Sets effects applied to stew items for this mushroom cow. -+ * -+ * @param effects effect entry list -+ */ -+ void setStewEffects(java.util.@NotNull List effects); -+ // Paper end - } -diff --git a/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java b/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java -index c2f4282c188e7d8041459cb3acaad674443ba147..c5bfc062fcca56495f44039d83356fc1fd7568d0 100644 ---- a/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java -+++ b/src/main/java/org/bukkit/inventory/meta/SuspiciousStewMeta.java -@@ -32,13 +32,28 @@ public interface SuspiciousStewMeta extends ItemMeta { - /** - * Adds a custom potion effect to this suspicious stew. - * -+ * @deprecated use {@link #addCustomEffect(io.papermc.paper.potion.SuspiciousEffectEntry, boolean)} as PotionEffect suggests that all attributes are used. In fact, only the PotionEffectType and the duration are used. - * @param effect the potion effect to add - * @param overwrite true if any existing effect of the same type should be - * overwritten - * @return true if the suspicious stew meta changed as a result of this call - */ -+ @Deprecated // Paper - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta - boolean addCustomEffect(@NotNull PotionEffect effect, boolean overwrite); - -+ // Paper start - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta -+ /** -+ * Adds a custom potion effect to this suspicious stew. -+ * -+ * @param suspiciousEffectEntry the suspicious effect entry to add -+ * @param overwrite true if any existing effect of the same type should be -+ * overwritten -+ * @return true if the suspicious stew meta changed as a result of this call -+ * as a result of this call -+ */ -+ boolean addCustomEffect(@NotNull io.papermc.paper.potion.SuspiciousEffectEntry suspiciousEffectEntry, boolean overwrite); -+ // Paper end - add overloads to use suspicious effect entry to mushroom cow and suspicious stew meta -+ - /** - * Removes a custom potion effect from this suspicious stew. - * diff --git a/patches/api/0452-Expanded-Hopper-API.patch b/patches/api/0452-Expanded-Hopper-API.patch new file mode 100644 index 0000000000..51cb6dfee2 --- /dev/null +++ b/patches/api/0452-Expanded-Hopper-API.patch @@ -0,0 +1,32 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: vicisacat +Date: Fri, 15 Mar 2024 17:35:18 +0100 +Subject: [PATCH] Expanded Hopper API + + +diff --git a/src/main/java/org/bukkit/block/Hopper.java b/src/main/java/org/bukkit/block/Hopper.java +index 7ade312f180b7e30871d3a3240c76325cc369c26..61ea33c1f2dbb546a66f945a01feae437b1381e0 100644 +--- a/src/main/java/org/bukkit/block/Hopper.java ++++ b/src/main/java/org/bukkit/block/Hopper.java +@@ -6,4 +6,20 @@ import org.bukkit.loot.Lootable; + /** + * Represents a captured state of a hopper. + */ +-public interface Hopper extends Container, LootableBlockInventory { } // Paper ++public interface Hopper extends Container, LootableBlockInventory { // Paper ++ // Paper start - Expanded Hopper API ++ /** ++ * Sets the cooldown before the hopper transfers or sucks in another item ++ * @param cooldown the cooldown in ticks ++ * @throws IllegalArgumentException if the passed cooldown value is negative. ++ */ ++ void setTransferCooldown(@org.jetbrains.annotations.Range(from = 0, to = Integer.MAX_VALUE) int cooldown); ++ ++ /** ++ * Returns the cooldown before the hopper transfers or sucks in another item ++ * @return the cooldown in ticks ++ */ ++ int getTransferCooldown(); ++ // Paper end - Expanded Hopper API ++} ++ diff --git a/patches/api/0452-Fix-DamageSource-API.patch b/patches/api/0452-Fix-DamageSource-API.patch deleted file mode 100644 index efe4403e2c..0000000000 --- a/patches/api/0452-Fix-DamageSource-API.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 16 Mar 2024 11:21:14 -0700 -Subject: [PATCH] Fix DamageSource API - - -diff --git a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java -index 6b24d1281cb8f0253430c9c1a1323e2670bb9c93..8ea4be529400b34df3d31b0f17c2d145345523d9 100644 ---- a/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java -+++ b/src/main/java/org/bukkit/event/entity/EntityDamageByEntityEvent.java -@@ -60,6 +60,20 @@ public class EntityDamageByEntityEvent extends EntityDamageEvent { - } - // Paper end - -+ // Paper start -+ /** -+ * {@inheritDoc} -+ *

-+ * The {@link DamageSource#getDirectEntity()} may be different from the {@link #getDamager()} -+ * if the Minecraft damage source did not originally include an damager entity, but one was included -+ * for this event {@link #getDamager()}. -+ */ -+ @Override -+ public @NotNull DamageSource getDamageSource() { -+ return super.getDamageSource(); -+ } -+ // Paper end -+ - /** - * Returns the entity that damaged the defender. - * diff --git a/patches/api/0453-Clone-mutables-to-prevent-unexpected-issues.patch b/patches/api/0453-Clone-mutables-to-prevent-unexpected-issues.patch new file mode 100644 index 0000000000..e84ea7d3aa --- /dev/null +++ b/patches/api/0453-Clone-mutables-to-prevent-unexpected-issues.patch @@ -0,0 +1,151 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 16 Mar 2024 11:10:48 -0700 +Subject: [PATCH] Clone mutables to prevent unexpected issues + +There are lots of locations in the API where mutable +types are not cloned, either on return or when passed +as a parameter and assigned to a field, which can cause +unexpected behaviors. Let this be a lesson to use +immutable types for simple things Location, Vector, and +others. + +diff --git a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java +index 08d09c2a92d8aa6adf6610cc05905d58a76fce1f..c74ac0cb004aa219ce2f761969a4bb46cb7c9160 100644 +--- a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java ++++ b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java +@@ -102,7 +102,7 @@ public class BlockCanBuildEvent extends BlockEvent { + */ + @NotNull + public BlockData getBlockData() { +- return blockData; ++ return blockData.clone(); // Paper - clone because mutation isn't used + } + + /** +diff --git a/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java +index 1a9575ad4c81aefa5ef0b927f6ac8f7064b55c49..24e1a49e48dd8f9eb2515b2ffe472a0c4d2bc09b 100644 +--- a/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java ++++ b/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java +@@ -61,7 +61,7 @@ public class EntityChangeBlockEvent extends EntityEvent implements Cancellable { + */ + @NotNull + public BlockData getBlockData() { +- return to; ++ return to.clone(); // Paper - clone because mutation isn't used + } + + @NotNull +diff --git a/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java b/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java +index 099efafa14c10910e4ed04abb1823f0c1a96b6a6..8506fa03293c575c35b55b052224807470fdbd98 100644 +--- a/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java ++++ b/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java +@@ -59,7 +59,7 @@ public class EntityExplodeEvent extends EntityEvent implements Cancellable { + */ + @NotNull + public Location getLocation() { +- return location; ++ return location.clone(); // Paper - clone to avoid changes + } + + /** +diff --git a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java +index 6818e9f0ba32ca1a1e612703f7526b29f5a6438f..e4e3d2e22c28ef251d76c48ade267b4eb3749e7d 100644 +--- a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java ++++ b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java +@@ -24,7 +24,7 @@ public class EntityPortalEnterEvent extends EntityEvent { + */ + @NotNull + public Location getLocation() { +- return location; ++ return location.clone(); // Paper - clone to avoid changes + } + + @NotNull +diff --git a/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java b/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java +index 6fc66197eb2c5d59c70d8d028b7963748371edbe..2bb29fa449cd6c90b52d2786ed15b6154d591607 100644 +--- a/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java ++++ b/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java +@@ -46,7 +46,7 @@ public class ItemDespawnEvent extends EntityEvent implements Cancellable { + */ + @NotNull + public Location getLocation() { +- return location; ++ return location.clone(); // Paper - clone to avoid changes + } + + @NotNull +diff --git a/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java b/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java +index d0a437bd8aeec18f800893f51ece06deb0c8972c..50fad23cf4d9f591b12a9eaebeb4e26f18e8528d 100644 +--- a/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java ++++ b/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java +@@ -31,7 +31,7 @@ public class VehicleBlockCollisionEvent extends VehicleCollisionEvent { + */ + @NotNull + public org.bukkit.util.Vector getVelocity() { +- return velocity; ++ return velocity.clone(); + } + // Paper end + +diff --git a/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java b/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java +index 7bfb84d3948c773e943374316ea25a19288ec7d0..fc4cf7b21b24fe38617fa150f697bc29da76754e 100644 +--- a/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java ++++ b/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java +@@ -27,7 +27,7 @@ public class VehicleMoveEvent extends VehicleEvent { + */ + @NotNull + public Location getFrom() { +- return from; ++ return from.clone(); // Paper - clone to avoid changes + } + + /** +@@ -37,7 +37,7 @@ public class VehicleMoveEvent extends VehicleEvent { + */ + @NotNull + public Location getTo() { +- return to; ++ return to.clone(); // Paper - clone to avoid changes + } + + +diff --git a/src/main/java/org/bukkit/event/world/GenericGameEvent.java b/src/main/java/org/bukkit/event/world/GenericGameEvent.java +index 2a2a329877d8da45c2d6afecf78ce88d52635cad..fb975fefc74d8c9746cab4c02860f55654cf92f7 100644 +--- a/src/main/java/org/bukkit/event/world/GenericGameEvent.java ++++ b/src/main/java/org/bukkit/event/world/GenericGameEvent.java +@@ -49,7 +49,7 @@ public class GenericGameEvent extends WorldEvent implements Cancellable { + */ + @NotNull + public Location getLocation() { +- return location; ++ return location.clone(); // Paper - clone to avoid changes + } + + /** +diff --git a/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java b/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java +index 9ce93d00935446589cb2bb970cb540d109616e85..73997ae04ff39ac3984c59de32aaced9eb72ce16 100644 +--- a/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java ++++ b/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java +@@ -25,7 +25,7 @@ public class SpawnChangeEvent extends WorldEvent { + */ + @NotNull + public Location getPreviousLocation() { +- return previousLocation; ++ return previousLocation.clone(); // Paper - clone to avoid changes + } + + @NotNull +diff --git a/src/main/java/org/bukkit/event/world/StructureGrowEvent.java b/src/main/java/org/bukkit/event/world/StructureGrowEvent.java +index 7af8d6e51c824cf0592b722b834f1d4986e3cc08..783e74bc382f0f6d24203fde7b811f588a674731 100644 +--- a/src/main/java/org/bukkit/event/world/StructureGrowEvent.java ++++ b/src/main/java/org/bukkit/event/world/StructureGrowEvent.java +@@ -39,7 +39,7 @@ public class StructureGrowEvent extends WorldEvent implements Cancellable { + */ + @NotNull + public Location getLocation() { +- return location; ++ return location.clone(); // Paper - clone to avoid changes + } + + /** diff --git a/patches/api/0453-Expanded-Hopper-API.patch b/patches/api/0453-Expanded-Hopper-API.patch deleted file mode 100644 index 51cb6dfee2..0000000000 --- a/patches/api/0453-Expanded-Hopper-API.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: vicisacat -Date: Fri, 15 Mar 2024 17:35:18 +0100 -Subject: [PATCH] Expanded Hopper API - - -diff --git a/src/main/java/org/bukkit/block/Hopper.java b/src/main/java/org/bukkit/block/Hopper.java -index 7ade312f180b7e30871d3a3240c76325cc369c26..61ea33c1f2dbb546a66f945a01feae437b1381e0 100644 ---- a/src/main/java/org/bukkit/block/Hopper.java -+++ b/src/main/java/org/bukkit/block/Hopper.java -@@ -6,4 +6,20 @@ import org.bukkit.loot.Lootable; - /** - * Represents a captured state of a hopper. - */ --public interface Hopper extends Container, LootableBlockInventory { } // Paper -+public interface Hopper extends Container, LootableBlockInventory { // Paper -+ // Paper start - Expanded Hopper API -+ /** -+ * Sets the cooldown before the hopper transfers or sucks in another item -+ * @param cooldown the cooldown in ticks -+ * @throws IllegalArgumentException if the passed cooldown value is negative. -+ */ -+ void setTransferCooldown(@org.jetbrains.annotations.Range(from = 0, to = Integer.MAX_VALUE) int cooldown); -+ -+ /** -+ * Returns the cooldown before the hopper transfers or sucks in another item -+ * @return the cooldown in ticks -+ */ -+ int getTransferCooldown(); -+ // Paper end - Expanded Hopper API -+} -+ diff --git a/patches/api/0454-Add-BlockBreakProgressUpdateEvent.patch b/patches/api/0454-Add-BlockBreakProgressUpdateEvent.patch new file mode 100644 index 0000000000..a2b5a83baf --- /dev/null +++ b/patches/api/0454-Add-BlockBreakProgressUpdateEvent.patch @@ -0,0 +1,68 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Badbird5907 <50347938+Badbird5907@users.noreply.github.com> +Date: Mon, 4 Mar 2024 22:18:33 -0500 +Subject: [PATCH] Add BlockBreakProgressUpdateEvent + + +diff --git a/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java b/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0cd1ab085222eae1a8df8ad85b26b49b6dd93a09 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java +@@ -0,0 +1,56 @@ ++package io.papermc.paper.event.block; ++ ++import org.bukkit.block.Block; ++import org.bukkit.entity.Entity; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.block.BlockEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Range; ++ ++/** ++ * Called when the progress of a block break is updated. ++ */ ++public class BlockBreakProgressUpdateEvent extends BlockEvent { ++ private static final HandlerList HANDLER_LIST = new HandlerList(); ++ ++ private final float progress; ++ private final Entity entity; ++ ++ @ApiStatus.Internal ++ public BlockBreakProgressUpdateEvent(@NotNull final Block block, final float progress, @NotNull final Entity entity) { ++ super(block); ++ this.progress = progress; ++ this.entity = entity; ++ } ++ ++ /** ++ * The progress of the block break ++ *

++ * The progress ranges from 0.0 - 1.0, where 0 is no damage and ++ * 1.0 is the most damaged ++ * ++ * @return The progress of the block break ++ */ ++ public float getProgress() { ++ return progress; ++ } ++ ++ /** ++ * The entity breaking the block. ++ * ++ * @return The entity breaking the block ++ */ ++ @NotNull ++ public Entity getEntity() { ++ return entity; ++ } ++ ++ @Override ++ public @NotNull HandlerList getHandlers() { ++ return HANDLER_LIST; ++ } ++ public static @NotNull HandlerList getHandlerList() { ++ return HANDLER_LIST; ++ } ++} diff --git a/patches/api/0454-Clone-mutables-to-prevent-unexpected-issues.patch b/patches/api/0454-Clone-mutables-to-prevent-unexpected-issues.patch deleted file mode 100644 index e84ea7d3aa..0000000000 --- a/patches/api/0454-Clone-mutables-to-prevent-unexpected-issues.patch +++ /dev/null @@ -1,151 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 16 Mar 2024 11:10:48 -0700 -Subject: [PATCH] Clone mutables to prevent unexpected issues - -There are lots of locations in the API where mutable -types are not cloned, either on return or when passed -as a parameter and assigned to a field, which can cause -unexpected behaviors. Let this be a lesson to use -immutable types for simple things Location, Vector, and -others. - -diff --git a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java -index 08d09c2a92d8aa6adf6610cc05905d58a76fce1f..c74ac0cb004aa219ce2f761969a4bb46cb7c9160 100644 ---- a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java -+++ b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java -@@ -102,7 +102,7 @@ public class BlockCanBuildEvent extends BlockEvent { - */ - @NotNull - public BlockData getBlockData() { -- return blockData; -+ return blockData.clone(); // Paper - clone because mutation isn't used - } - - /** -diff --git a/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java b/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java -index 1a9575ad4c81aefa5ef0b927f6ac8f7064b55c49..24e1a49e48dd8f9eb2515b2ffe472a0c4d2bc09b 100644 ---- a/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java -+++ b/src/main/java/org/bukkit/event/entity/EntityChangeBlockEvent.java -@@ -61,7 +61,7 @@ public class EntityChangeBlockEvent extends EntityEvent implements Cancellable { - */ - @NotNull - public BlockData getBlockData() { -- return to; -+ return to.clone(); // Paper - clone because mutation isn't used - } - - @NotNull -diff --git a/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java b/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java -index 099efafa14c10910e4ed04abb1823f0c1a96b6a6..8506fa03293c575c35b55b052224807470fdbd98 100644 ---- a/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java -+++ b/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java -@@ -59,7 +59,7 @@ public class EntityExplodeEvent extends EntityEvent implements Cancellable { - */ - @NotNull - public Location getLocation() { -- return location; -+ return location.clone(); // Paper - clone to avoid changes - } - - /** -diff --git a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java -index 6818e9f0ba32ca1a1e612703f7526b29f5a6438f..e4e3d2e22c28ef251d76c48ade267b4eb3749e7d 100644 ---- a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java -+++ b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java -@@ -24,7 +24,7 @@ public class EntityPortalEnterEvent extends EntityEvent { - */ - @NotNull - public Location getLocation() { -- return location; -+ return location.clone(); // Paper - clone to avoid changes - } - - @NotNull -diff --git a/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java b/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java -index 6fc66197eb2c5d59c70d8d028b7963748371edbe..2bb29fa449cd6c90b52d2786ed15b6154d591607 100644 ---- a/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java -+++ b/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java -@@ -46,7 +46,7 @@ public class ItemDespawnEvent extends EntityEvent implements Cancellable { - */ - @NotNull - public Location getLocation() { -- return location; -+ return location.clone(); // Paper - clone to avoid changes - } - - @NotNull -diff --git a/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java b/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java -index d0a437bd8aeec18f800893f51ece06deb0c8972c..50fad23cf4d9f591b12a9eaebeb4e26f18e8528d 100644 ---- a/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java -+++ b/src/main/java/org/bukkit/event/vehicle/VehicleBlockCollisionEvent.java -@@ -31,7 +31,7 @@ public class VehicleBlockCollisionEvent extends VehicleCollisionEvent { - */ - @NotNull - public org.bukkit.util.Vector getVelocity() { -- return velocity; -+ return velocity.clone(); - } - // Paper end - -diff --git a/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java b/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java -index 7bfb84d3948c773e943374316ea25a19288ec7d0..fc4cf7b21b24fe38617fa150f697bc29da76754e 100644 ---- a/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java -+++ b/src/main/java/org/bukkit/event/vehicle/VehicleMoveEvent.java -@@ -27,7 +27,7 @@ public class VehicleMoveEvent extends VehicleEvent { - */ - @NotNull - public Location getFrom() { -- return from; -+ return from.clone(); // Paper - clone to avoid changes - } - - /** -@@ -37,7 +37,7 @@ public class VehicleMoveEvent extends VehicleEvent { - */ - @NotNull - public Location getTo() { -- return to; -+ return to.clone(); // Paper - clone to avoid changes - } - - -diff --git a/src/main/java/org/bukkit/event/world/GenericGameEvent.java b/src/main/java/org/bukkit/event/world/GenericGameEvent.java -index 2a2a329877d8da45c2d6afecf78ce88d52635cad..fb975fefc74d8c9746cab4c02860f55654cf92f7 100644 ---- a/src/main/java/org/bukkit/event/world/GenericGameEvent.java -+++ b/src/main/java/org/bukkit/event/world/GenericGameEvent.java -@@ -49,7 +49,7 @@ public class GenericGameEvent extends WorldEvent implements Cancellable { - */ - @NotNull - public Location getLocation() { -- return location; -+ return location.clone(); // Paper - clone to avoid changes - } - - /** -diff --git a/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java b/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java -index 9ce93d00935446589cb2bb970cb540d109616e85..73997ae04ff39ac3984c59de32aaced9eb72ce16 100644 ---- a/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java -+++ b/src/main/java/org/bukkit/event/world/SpawnChangeEvent.java -@@ -25,7 +25,7 @@ public class SpawnChangeEvent extends WorldEvent { - */ - @NotNull - public Location getPreviousLocation() { -- return previousLocation; -+ return previousLocation.clone(); // Paper - clone to avoid changes - } - - @NotNull -diff --git a/src/main/java/org/bukkit/event/world/StructureGrowEvent.java b/src/main/java/org/bukkit/event/world/StructureGrowEvent.java -index 7af8d6e51c824cf0592b722b834f1d4986e3cc08..783e74bc382f0f6d24203fde7b811f588a674731 100644 ---- a/src/main/java/org/bukkit/event/world/StructureGrowEvent.java -+++ b/src/main/java/org/bukkit/event/world/StructureGrowEvent.java -@@ -39,7 +39,7 @@ public class StructureGrowEvent extends WorldEvent implements Cancellable { - */ - @NotNull - public Location getLocation() { -- return location; -+ return location.clone(); // Paper - clone to avoid changes - } - - /** diff --git a/patches/api/0455-Add-BlockBreakProgressUpdateEvent.patch b/patches/api/0455-Add-BlockBreakProgressUpdateEvent.patch deleted file mode 100644 index a2b5a83baf..0000000000 --- a/patches/api/0455-Add-BlockBreakProgressUpdateEvent.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Badbird5907 <50347938+Badbird5907@users.noreply.github.com> -Date: Mon, 4 Mar 2024 22:18:33 -0500 -Subject: [PATCH] Add BlockBreakProgressUpdateEvent - - -diff --git a/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java b/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0cd1ab085222eae1a8df8ad85b26b49b6dd93a09 ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/block/BlockBreakProgressUpdateEvent.java -@@ -0,0 +1,56 @@ -+package io.papermc.paper.event.block; -+ -+import org.bukkit.block.Block; -+import org.bukkit.entity.Entity; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.block.BlockEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.Range; -+ -+/** -+ * Called when the progress of a block break is updated. -+ */ -+public class BlockBreakProgressUpdateEvent extends BlockEvent { -+ private static final HandlerList HANDLER_LIST = new HandlerList(); -+ -+ private final float progress; -+ private final Entity entity; -+ -+ @ApiStatus.Internal -+ public BlockBreakProgressUpdateEvent(@NotNull final Block block, final float progress, @NotNull final Entity entity) { -+ super(block); -+ this.progress = progress; -+ this.entity = entity; -+ } -+ -+ /** -+ * The progress of the block break -+ *

-+ * The progress ranges from 0.0 - 1.0, where 0 is no damage and -+ * 1.0 is the most damaged -+ * -+ * @return The progress of the block break -+ */ -+ public float getProgress() { -+ return progress; -+ } -+ -+ /** -+ * The entity breaking the block. -+ * -+ * @return The entity breaking the block -+ */ -+ @NotNull -+ public Entity getEntity() { -+ return entity; -+ } -+ -+ @Override -+ public @NotNull HandlerList getHandlers() { -+ return HANDLER_LIST; -+ } -+ public static @NotNull HandlerList getHandlerList() { -+ return HANDLER_LIST; -+ } -+} diff --git a/patches/api/0455-Deprecate-ItemStack-setType.patch b/patches/api/0455-Deprecate-ItemStack-setType.patch new file mode 100644 index 0000000000..910f35e09e --- /dev/null +++ b/patches/api/0455-Deprecate-ItemStack-setType.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Thu, 29 Feb 2024 17:54:26 -0500 +Subject: [PATCH] Deprecate ItemStack#setType + + +diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java +index 235d41b0078bb513470b17a0dad46fae3ac73a16..2866f10f954f6d3fb1d58c216a2d5ae1372adbad 100644 +--- a/src/main/java/org/bukkit/inventory/ItemStack.java ++++ b/src/main/java/org/bukkit/inventory/ItemStack.java +@@ -143,8 +143,18 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat + * {@link Material#isItem()} returns false. + * + * @param type New type to set the items in this stack to ++ * @deprecated Setting the material type of ItemStacks is no longer supported. ++ *

++ * This method is deprecated due to potential illegal behavior that may occur ++ * during the context of which this ItemStack is being used, allowing for certain item validation to be bypassed. ++ * It is recommended to instead create a new ItemStack object with the desired ++ * Material type, and if possible, set it in the appropriate context. ++ * ++ * Using this method in ItemStacks passed in events will result in undefined behavior. ++ * @see ItemStack#withType(Material) + */ + @Utility ++ @Deprecated // Paper + public void setType(@NotNull Material type) { + Preconditions.checkArgument(type != null, "Material cannot be null"); + this.type = type; +@@ -157,6 +167,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat + this.data = null; + } + } ++ // Paper start ++ /** ++ * Creates a new ItemStack with the specified Material type, where the item count and item meta is preserved. ++ * ++ * @param type The Material type of the new ItemStack. ++ * @return A new ItemStack instance with the specified Material type. ++ */ ++ @NotNull ++ @org.jetbrains.annotations.Contract(value = "_ -> new", pure = true) ++ public ItemStack withType(@NotNull Material type) { ++ ItemStack itemStack = new ItemStack(type, this.amount); ++ if (this.hasItemMeta()) { ++ itemStack.setItemMeta(this.getItemMeta()); ++ } ++ ++ return itemStack; ++ } ++ // Paper end + + /** + * Gets the amount of items in this stack diff --git a/patches/api/0456-Deprecate-ItemStack-setType.patch b/patches/api/0456-Deprecate-ItemStack-setType.patch deleted file mode 100644 index 910f35e09e..0000000000 --- a/patches/api/0456-Deprecate-ItemStack-setType.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> -Date: Thu, 29 Feb 2024 17:54:26 -0500 -Subject: [PATCH] Deprecate ItemStack#setType - - -diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 235d41b0078bb513470b17a0dad46fae3ac73a16..2866f10f954f6d3fb1d58c216a2d5ae1372adbad 100644 ---- a/src/main/java/org/bukkit/inventory/ItemStack.java -+++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -143,8 +143,18 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat - * {@link Material#isItem()} returns false. - * - * @param type New type to set the items in this stack to -+ * @deprecated Setting the material type of ItemStacks is no longer supported. -+ *

-+ * This method is deprecated due to potential illegal behavior that may occur -+ * during the context of which this ItemStack is being used, allowing for certain item validation to be bypassed. -+ * It is recommended to instead create a new ItemStack object with the desired -+ * Material type, and if possible, set it in the appropriate context. -+ * -+ * Using this method in ItemStacks passed in events will result in undefined behavior. -+ * @see ItemStack#withType(Material) - */ - @Utility -+ @Deprecated // Paper - public void setType(@NotNull Material type) { - Preconditions.checkArgument(type != null, "Material cannot be null"); - this.type = type; -@@ -157,6 +167,24 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat - this.data = null; - } - } -+ // Paper start -+ /** -+ * Creates a new ItemStack with the specified Material type, where the item count and item meta is preserved. -+ * -+ * @param type The Material type of the new ItemStack. -+ * @return A new ItemStack instance with the specified Material type. -+ */ -+ @NotNull -+ @org.jetbrains.annotations.Contract(value = "_ -> new", pure = true) -+ public ItemStack withType(@NotNull Material type) { -+ ItemStack itemStack = new ItemStack(type, this.amount); -+ if (this.hasItemMeta()) { -+ itemStack.setItemMeta(this.getItemMeta()); -+ } -+ -+ return itemStack; -+ } -+ // Paper end - - /** - * Gets the amount of items in this stack diff --git a/patches/api/0456-Item-Mutation-Fixes.patch b/patches/api/0456-Item-Mutation-Fixes.patch new file mode 100644 index 0000000000..ccd77b7fbc --- /dev/null +++ b/patches/api/0456-Item-Mutation-Fixes.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Wed, 20 Mar 2024 20:42:31 -0400 +Subject: [PATCH] Item Mutation Fixes + + +diff --git a/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java b/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java +index 1ebd45295a29fbc990a1311a7f0fe7f42ac79275..b70450919e78e869c9f158c4e3e25944bcaa73f2 100644 +--- a/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java ++++ b/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java +@@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; + public class InventoryBlockStartEvent extends BlockEvent { + + private static final HandlerList handlers = new HandlerList(); +- private final ItemStack source; ++ protected ItemStack source; // Paper + + public InventoryBlockStartEvent(@NotNull final Block block, @NotNull ItemStack source) { + super(block); +diff --git a/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java b/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java +index 1829529c9915937dcdd0e6d1ceba9e64819fb93f..e7c243038b70ca13b7eabdf88ce518b6198c6db9 100644 +--- a/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java ++++ b/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java +@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull; + public class EnchantItemEvent extends InventoryEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Block table; +- private final ItemStack item; ++ private ItemStack item; // Paper + private int level; + private boolean cancelled; + private final Map enchants; +@@ -72,6 +72,17 @@ public class EnchantItemEvent extends InventoryEvent implements Cancellable { + return item; + } + ++ // Paper start ++ /** ++ * Sets the item to be enchanted ++ * ++ * @param item item ++ */ ++ public void setItem(@NotNull final ItemStack item) { ++ this.item = item; ++ } ++ // Paper end ++ + /** + * Gets the cost (minimum level) which is displayed as a number on the right + * hand side of the enchantment offer. diff --git a/patches/api/0457-API-for-checking-sent-chunks.patch b/patches/api/0457-API-for-checking-sent-chunks.patch new file mode 100644 index 0000000000..a3844b5401 --- /dev/null +++ b/patches/api/0457-API-for-checking-sent-chunks.patch @@ -0,0 +1,58 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Flo0 +Date: Mon, 8 Apr 2024 16:22:07 +0200 +Subject: [PATCH] API for checking sent chunks + + +diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java +index 4bc4a1c0c6f6759f984843823f1bbec6ffed92bc..7b699c1e63cf5bc805754101f28066f836877ee2 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -3804,6 +3804,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + void resetIdleDuration(); + // Paper end + ++ // Paper start - Add chunk view API ++ /** ++ * Gets the a set of chunk keys for all chunks that have been sent to the player. ++ * ++ * @return an immutable set of chunk keys ++ * @apiNote currently marked as experimental to gather feedback regarding the returned set being an immutable copy ++ * vs it potentially being an unmodifiable view of the set chunks. ++ */ ++ @ApiStatus.Experimental ++ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable Set getSentChunkKeys(); ++ ++ /** ++ * Gets the set of chunks that have been sent to the player. ++ * ++ * @return an immutable set of chunks ++ * @apiNote currently marked as experimental to gather feedback regarding the returned set being an immutable copy ++ * vs it potentially being an unmodifiable view of the set chunks. ++ */ ++ @ApiStatus.Experimental ++ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable Set getSentChunks(); ++ ++ /** ++ * Checks if the player has been sent a specific chunk. ++ * ++ * @param chunk the chunk to check ++ * @return true if the player has been sent the chunk, false otherwise ++ */ ++ default boolean isChunkSent(@NotNull org.bukkit.Chunk chunk) { ++ return this.isChunkSent(chunk.getChunkKey()); ++ } ++ ++ /** ++ * Checks if the player has been sent a specific chunk. ++ * ++ * @param chunkKey the chunk key to check ++ * @return true if the player has been sent the chunk, false otherwise ++ * @see org.bukkit.Chunk#getChunkKey() ++ */ ++ boolean isChunkSent(long chunkKey); ++ // Paper end ++ + @NotNull + @Override + Spigot spigot(); diff --git a/patches/api/0457-Item-Mutation-Fixes.patch b/patches/api/0457-Item-Mutation-Fixes.patch deleted file mode 100644 index ccd77b7fbc..0000000000 --- a/patches/api/0457-Item-Mutation-Fixes.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> -Date: Wed, 20 Mar 2024 20:42:31 -0400 -Subject: [PATCH] Item Mutation Fixes - - -diff --git a/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java b/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java -index 1ebd45295a29fbc990a1311a7f0fe7f42ac79275..b70450919e78e869c9f158c4e3e25944bcaa73f2 100644 ---- a/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java -+++ b/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java -@@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; - public class InventoryBlockStartEvent extends BlockEvent { - - private static final HandlerList handlers = new HandlerList(); -- private final ItemStack source; -+ protected ItemStack source; // Paper - - public InventoryBlockStartEvent(@NotNull final Block block, @NotNull ItemStack source) { - super(block); -diff --git a/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java b/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java -index 1829529c9915937dcdd0e6d1ceba9e64819fb93f..e7c243038b70ca13b7eabdf88ce518b6198c6db9 100644 ---- a/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java -+++ b/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java -@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull; - public class EnchantItemEvent extends InventoryEvent implements Cancellable { - private static final HandlerList handlers = new HandlerList(); - private final Block table; -- private final ItemStack item; -+ private ItemStack item; // Paper - private int level; - private boolean cancelled; - private final Map enchants; -@@ -72,6 +72,17 @@ public class EnchantItemEvent extends InventoryEvent implements Cancellable { - return item; - } - -+ // Paper start -+ /** -+ * Sets the item to be enchanted -+ * -+ * @param item item -+ */ -+ public void setItem(@NotNull final ItemStack item) { -+ this.item = item; -+ } -+ // Paper end -+ - /** - * Gets the cost (minimum level) which is displayed as a number on the right - * hand side of the enchantment offer. diff --git a/patches/api/0458-API-for-checking-sent-chunks.patch b/patches/api/0458-API-for-checking-sent-chunks.patch deleted file mode 100644 index a3844b5401..0000000000 --- a/patches/api/0458-API-for-checking-sent-chunks.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Flo0 -Date: Mon, 8 Apr 2024 16:22:07 +0200 -Subject: [PATCH] API for checking sent chunks - - -diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 4bc4a1c0c6f6759f984843823f1bbec6ffed92bc..7b699c1e63cf5bc805754101f28066f836877ee2 100644 ---- a/src/main/java/org/bukkit/entity/Player.java -+++ b/src/main/java/org/bukkit/entity/Player.java -@@ -3804,6 +3804,47 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - void resetIdleDuration(); - // Paper end - -+ // Paper start - Add chunk view API -+ /** -+ * Gets the a set of chunk keys for all chunks that have been sent to the player. -+ * -+ * @return an immutable set of chunk keys -+ * @apiNote currently marked as experimental to gather feedback regarding the returned set being an immutable copy -+ * vs it potentially being an unmodifiable view of the set chunks. -+ */ -+ @ApiStatus.Experimental -+ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable Set getSentChunkKeys(); -+ -+ /** -+ * Gets the set of chunks that have been sent to the player. -+ * -+ * @return an immutable set of chunks -+ * @apiNote currently marked as experimental to gather feedback regarding the returned set being an immutable copy -+ * vs it potentially being an unmodifiable view of the set chunks. -+ */ -+ @ApiStatus.Experimental -+ java.util.@NotNull @org.jetbrains.annotations.Unmodifiable Set getSentChunks(); -+ -+ /** -+ * Checks if the player has been sent a specific chunk. -+ * -+ * @param chunk the chunk to check -+ * @return true if the player has been sent the chunk, false otherwise -+ */ -+ default boolean isChunkSent(@NotNull org.bukkit.Chunk chunk) { -+ return this.isChunkSent(chunk.getChunkKey()); -+ } -+ -+ /** -+ * Checks if the player has been sent a specific chunk. -+ * -+ * @param chunkKey the chunk key to check -+ * @return true if the player has been sent the chunk, false otherwise -+ * @see org.bukkit.Chunk#getChunkKey() -+ */ -+ boolean isChunkSent(long chunkKey); -+ // Paper end -+ - @NotNull - @Override - Spigot spigot(); diff --git a/patches/api/0458-Add-CartographyItemEvent.patch b/patches/api/0458-Add-CartographyItemEvent.patch new file mode 100644 index 0000000000..1f19663c9f --- /dev/null +++ b/patches/api/0458-Add-CartographyItemEvent.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Janet Blackquill +Date: Sun, 7 Apr 2024 16:51:04 -0400 +Subject: [PATCH] Add CartographyItemEvent + +Similar to SmithItemEvent, but for cartography tables. + +diff --git a/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java b/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..659b620696e5cc0784ed707c70876e4348897c7f +--- /dev/null ++++ b/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java +@@ -0,0 +1,31 @@ ++package io.papermc.paper.event.player; ++ ++import org.bukkit.inventory.InventoryView; ++import org.bukkit.inventory.CartographyInventory; ++import org.bukkit.event.inventory.ClickType; ++import org.bukkit.event.inventory.InventoryType; ++import org.bukkit.event.inventory.InventoryAction; ++import org.bukkit.event.inventory.InventoryClickEvent; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * Called when the recipe of an Item is completed inside a cartography table. ++ */ ++public class CartographyItemEvent extends InventoryClickEvent { ++ @ApiStatus.Internal ++ public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action) { ++ super(view, type, slot, click, action); ++ } ++ ++ @ApiStatus.Internal ++ public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action, int key) { ++ super(view, type, slot, click, action, key); ++ } ++ ++ @NotNull ++ @Override ++ public CartographyInventory getInventory() { ++ return (CartographyInventory) super.getInventory(); ++ } ++} diff --git a/patches/api/0459-Add-CartographyItemEvent.patch b/patches/api/0459-Add-CartographyItemEvent.patch deleted file mode 100644 index 1f19663c9f..0000000000 --- a/patches/api/0459-Add-CartographyItemEvent.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Janet Blackquill -Date: Sun, 7 Apr 2024 16:51:04 -0400 -Subject: [PATCH] Add CartographyItemEvent - -Similar to SmithItemEvent, but for cartography tables. - -diff --git a/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java b/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..659b620696e5cc0784ed707c70876e4348897c7f ---- /dev/null -+++ b/src/main/java/io/papermc/paper/event/player/CartographyItemEvent.java -@@ -0,0 +1,31 @@ -+package io.papermc.paper.event.player; -+ -+import org.bukkit.inventory.InventoryView; -+import org.bukkit.inventory.CartographyInventory; -+import org.bukkit.event.inventory.ClickType; -+import org.bukkit.event.inventory.InventoryType; -+import org.bukkit.event.inventory.InventoryAction; -+import org.bukkit.event.inventory.InventoryClickEvent; -+import org.jetbrains.annotations.NotNull; -+import org.jetbrains.annotations.ApiStatus; -+ -+/** -+ * Called when the recipe of an Item is completed inside a cartography table. -+ */ -+public class CartographyItemEvent extends InventoryClickEvent { -+ @ApiStatus.Internal -+ public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action) { -+ super(view, type, slot, click, action); -+ } -+ -+ @ApiStatus.Internal -+ public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action, int key) { -+ super(view, type, slot, click, action, key); -+ } -+ -+ @NotNull -+ @Override -+ public CartographyInventory getInventory() { -+ return (CartographyInventory) super.getInventory(); -+ } -+} diff --git a/patches/api/0459-More-Raid-API.patch b/patches/api/0459-More-Raid-API.patch new file mode 100644 index 0000000000..b365913e82 --- /dev/null +++ b/patches/api/0459-More-Raid-API.patch @@ -0,0 +1,62 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Fri, 4 Mar 2022 09:46:40 -0800 +Subject: [PATCH] More Raid API + + +diff --git a/src/main/java/org/bukkit/Raid.java b/src/main/java/org/bukkit/Raid.java +index 983a8c20a06d2b509602b27f49c090598b8ecc42..fa98599e3eee37bf68f0e9813497c718f457485c 100644 +--- a/src/main/java/org/bukkit/Raid.java ++++ b/src/main/java/org/bukkit/Raid.java +@@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; + /** + * Represents a raid event. + */ +-public interface Raid { ++public interface Raid extends org.bukkit.persistence.PersistentDataHolder { // Paper + + /** + * Get whether this raid started. +@@ -131,4 +131,20 @@ public interface Raid { + */ + STOPPED; + } ++ ++ // Paper start ++ /** ++ * Gets the id of this raid. ++ * ++ * @return the raid id ++ */ ++ int getId(); ++ ++ /** ++ * Get the boss bar to be displayed for this raid. ++ * ++ * @return the boss bar ++ */ ++ org.bukkit.boss.@NotNull BossBar getBossBar(); ++ // Paper end + } +diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java +index ecc2d486cfec79cce27a947dfeed4853575a594d..d8a23aa0d898ca3360757721e38ddb97387f7d21 100644 +--- a/src/main/java/org/bukkit/World.java ++++ b/src/main/java/org/bukkit/World.java +@@ -4111,6 +4111,17 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient + @Nullable + public Raid locateNearestRaid(@NotNull Location location, int radius); + ++ // Paper start - more Raid API ++ /** ++ * Get a raid with the specific id from {@link Raid#getId} ++ * from this world. ++ * ++ * @param id the id of the raid ++ * @return the raid or null if none with that id ++ */ ++ @Nullable Raid getRaid(int id); ++ // Paper end - more Raid API ++ + /** + * Gets all raids that are going on over this world. + * diff --git a/patches/api/0460-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0460-Fix-SpawnerEntry-Equipment-API.patch new file mode 100644 index 0000000000..0a16b34cd5 --- /dev/null +++ b/patches/api/0460-Fix-SpawnerEntry-Equipment-API.patch @@ -0,0 +1,46 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Fri, 26 Apr 2024 17:00:00 -0700 +Subject: [PATCH] Fix SpawnerEntry$Equipment API + + +diff --git a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java +index 02b3471774ff1fd4ad15c2f04064fd485ef8f3e5..0fc5f04b8bb475e8afce61c6187a390cd36c3d9f 100644 +--- a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java ++++ b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java +@@ -121,28 +121,29 @@ public class SpawnerEntry { + private final Map dropChances; + + public Equipment(@NotNull LootTable equipmentLootTable, @NotNull Map dropChances) { ++ Preconditions.checkArgument(equipmentLootTable != null, "table cannot be null"); // Paper + this.equipmentLootTable = equipmentLootTable; + this.dropChances = dropChances; + } + + /** +- * Set the loot table for the entity. ++ * Set the loot table for the spawned entity's equipment slots. + *
+- * To remove a loot table use null. Do not use {@link LootTables#EMPTY} +- * to clear a LootTable. ++ * To remove a loot table use {@link LootTables#EMPTY}. + * + * @param table this {@link org.bukkit.entity.Mob} will have. + */ + public void setEquipmentLootTable(@NotNull LootTable table) { ++ Preconditions.checkArgument(table != null, "table cannot be null"); // Paper + this.equipmentLootTable = table; + } + + /** +- * Gets the loot table for the entity. ++ * Gets the loot table for the spawned entity's equipment. + *
+ * +- * If an entity does not have a loot table, this will return null, NOT +- * an empty loot table. ++ * If an entity does not have a loot table, this will return an ++ * empty loot table. + * + * @return the loot table for this entity. + */ diff --git a/patches/api/0460-More-Raid-API.patch b/patches/api/0460-More-Raid-API.patch deleted file mode 100644 index b365913e82..0000000000 --- a/patches/api/0460-More-Raid-API.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Fri, 4 Mar 2022 09:46:40 -0800 -Subject: [PATCH] More Raid API - - -diff --git a/src/main/java/org/bukkit/Raid.java b/src/main/java/org/bukkit/Raid.java -index 983a8c20a06d2b509602b27f49c090598b8ecc42..fa98599e3eee37bf68f0e9813497c718f457485c 100644 ---- a/src/main/java/org/bukkit/Raid.java -+++ b/src/main/java/org/bukkit/Raid.java -@@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; - /** - * Represents a raid event. - */ --public interface Raid { -+public interface Raid extends org.bukkit.persistence.PersistentDataHolder { // Paper - - /** - * Get whether this raid started. -@@ -131,4 +131,20 @@ public interface Raid { - */ - STOPPED; - } -+ -+ // Paper start -+ /** -+ * Gets the id of this raid. -+ * -+ * @return the raid id -+ */ -+ int getId(); -+ -+ /** -+ * Get the boss bar to be displayed for this raid. -+ * -+ * @return the boss bar -+ */ -+ org.bukkit.boss.@NotNull BossBar getBossBar(); -+ // Paper end - } -diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java -index ecc2d486cfec79cce27a947dfeed4853575a594d..d8a23aa0d898ca3360757721e38ddb97387f7d21 100644 ---- a/src/main/java/org/bukkit/World.java -+++ b/src/main/java/org/bukkit/World.java -@@ -4111,6 +4111,17 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient - @Nullable - public Raid locateNearestRaid(@NotNull Location location, int radius); - -+ // Paper start - more Raid API -+ /** -+ * Get a raid with the specific id from {@link Raid#getId} -+ * from this world. -+ * -+ * @param id the id of the raid -+ * @return the raid or null if none with that id -+ */ -+ @Nullable Raid getRaid(int id); -+ // Paper end - more Raid API -+ - /** - * Gets all raids that are going on over this world. - * diff --git a/patches/api/0461-Fix-ItemFlags.patch b/patches/api/0461-Fix-ItemFlags.patch new file mode 100644 index 0000000000..1b1eb619b9 --- /dev/null +++ b/patches/api/0461-Fix-ItemFlags.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jake Potrebic +Date: Sat, 27 Apr 2024 13:28:17 -0700 +Subject: [PATCH] Fix ItemFlags + +Adds new flag in HIDE_STORED_ENCHANTS which was split +from HIDE_ADDITIONAL_INFO. Adds a migration to account for +this, adding the new flag if the itemstack is old and had the +old flag. + +diff --git a/src/main/java/org/bukkit/inventory/ItemFlag.java b/src/main/java/org/bukkit/inventory/ItemFlag.java +index 5b8dac777bb1640dc00bbe98feb6460c36eebb98..1af15fd327e0613cd1a179bd7fef1e83cbe31761 100644 +--- a/src/main/java/org/bukkit/inventory/ItemFlag.java ++++ b/src/main/java/org/bukkit/inventory/ItemFlag.java +@@ -2,6 +2,8 @@ package org.bukkit.inventory; + + /** + * A ItemFlag can hide some Attributes from ItemStacks ++ * @apiNote Setting these without also setting the data they are hiding ++ * may not result in the item flag being persisted in the ItemMeta/ItemStack. + */ + public enum ItemFlag { + +@@ -27,7 +29,8 @@ public enum ItemFlag { + HIDE_PLACED_ON, + /** + * Setting to show/hide potion effects, book and firework information, map +- * tooltips, patterns of banners, and enchantments of enchanted books. ++ * tooltips, patterns of banners. ++ * @see #HIDE_STORED_ENCHANTS HIDE_STORED_ENCHANTS for hiding stored enchants (like on enchanted books) + */ + HIDE_ADDITIONAL_TOOLTIP, + /** +@@ -37,7 +40,13 @@ public enum ItemFlag { + /** + * Setting to show/hide armor trim from armor. + */ +- HIDE_ARMOR_TRIM; ++ HIDE_ARMOR_TRIM, ++ /** ++ * Setting to show/hide stored enchants on an item, such as enchantments ++ * on an enchanted book. ++ */ ++ HIDE_STORED_ENCHANTS, ++ ; + // Paper start + /** + * Setting to show/hide item-specific information, including, but not limited to: +diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java +index 2866f10f954f6d3fb1d58c216a2d5ae1372adbad..7f5633e7689b82b937d5b985c3e6ae15dc94a20f 100644 +--- a/src/main/java/org/bukkit/inventory/ItemStack.java ++++ b/src/main/java/org/bukkit/inventory/ItemStack.java +@@ -588,6 +588,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat + Object raw = args.get("meta"); + if (raw instanceof ItemMeta) { + ((ItemMeta) raw).setVersion(version); ++ // Paper start - for pre 1.20.5 itemstacks, add HIDE_STORED_ENCHANTS flag if HIDE_ADDITIONAL_TOOLTIP is set ++ if (version < 3837) { // 1.20.5 ++ if (((ItemMeta) raw).hasItemFlag(ItemFlag.HIDE_ADDITIONAL_TOOLTIP)) { ++ ((ItemMeta) raw).addItemFlags(ItemFlag.HIDE_STORED_ENCHANTS); ++ } ++ } ++ // Paper end + result.setItemMeta((ItemMeta) raw); + } + } diff --git a/patches/api/0461-Fix-SpawnerEntry-Equipment-API.patch b/patches/api/0461-Fix-SpawnerEntry-Equipment-API.patch deleted file mode 100644 index 0a16b34cd5..0000000000 --- a/patches/api/0461-Fix-SpawnerEntry-Equipment-API.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Fri, 26 Apr 2024 17:00:00 -0700 -Subject: [PATCH] Fix SpawnerEntry$Equipment API - - -diff --git a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -index 02b3471774ff1fd4ad15c2f04064fd485ef8f3e5..0fc5f04b8bb475e8afce61c6187a390cd36c3d9f 100644 ---- a/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -+++ b/src/main/java/org/bukkit/block/spawner/SpawnerEntry.java -@@ -121,28 +121,29 @@ public class SpawnerEntry { - private final Map dropChances; - - public Equipment(@NotNull LootTable equipmentLootTable, @NotNull Map dropChances) { -+ Preconditions.checkArgument(equipmentLootTable != null, "table cannot be null"); // Paper - this.equipmentLootTable = equipmentLootTable; - this.dropChances = dropChances; - } - - /** -- * Set the loot table for the entity. -+ * Set the loot table for the spawned entity's equipment slots. - *
-- * To remove a loot table use null. Do not use {@link LootTables#EMPTY} -- * to clear a LootTable. -+ * To remove a loot table use {@link LootTables#EMPTY}. - * - * @param table this {@link org.bukkit.entity.Mob} will have. - */ - public void setEquipmentLootTable(@NotNull LootTable table) { -+ Preconditions.checkArgument(table != null, "table cannot be null"); // Paper - this.equipmentLootTable = table; - } - - /** -- * Gets the loot table for the entity. -+ * Gets the loot table for the spawned entity's equipment. - *
- * -- * If an entity does not have a loot table, this will return null, NOT -- * an empty loot table. -+ * If an entity does not have a loot table, this will return an -+ * empty loot table. - * - * @return the loot table for this entity. - */ diff --git a/patches/api/0462-Allow-modifying-library-loader-jars-bytecode.patch b/patches/api/0462-Allow-modifying-library-loader-jars-bytecode.patch new file mode 100644 index 0000000000..0c0311e790 --- /dev/null +++ b/patches/api/0462-Allow-modifying-library-loader-jars-bytecode.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Sun, 28 Apr 2024 11:11:26 -0700 +Subject: [PATCH] Allow modifying library loader jars bytecode + + +diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java +index f4d655a158410039305ac68cebe0d79000f73df8..5b0203e908f84c531886b8ea8faeb591eb045636 100644 +--- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java ++++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java +@@ -46,6 +46,7 @@ public class LibraryLoader + private final RepositorySystem repository; + private final DefaultRepositorySystemSession session; + private final List repositories; ++ public static java.util.function.BiFunction LIBRARY_LOADER_FACTORY; // Paper - rewrite reflection in libraries + + public LibraryLoader(@NotNull Logger logger) + { +@@ -130,7 +131,14 @@ public class LibraryLoader + } ); + } + +- URLClassLoader loader = new URLClassLoader( jarFiles.toArray( new URL[ jarFiles.size() ] ), getClass().getClassLoader() ); ++ // Paper start - rewrite reflection in libraries ++ URLClassLoader loader; ++ if (LIBRARY_LOADER_FACTORY == null) { ++ loader = new URLClassLoader( jarFiles.toArray( new URL[ jarFiles.size() ] ), getClass().getClassLoader() ); ++ } else { ++ loader = LIBRARY_LOADER_FACTORY.apply(jarFiles.toArray( new URL[ jarFiles.size() ] ), getClass().getClassLoader()); ++ } ++ // Paper end - rewrite reflection in libraries + + return loader; + } diff --git a/patches/api/0462-Fix-ItemFlags.patch b/patches/api/0462-Fix-ItemFlags.patch deleted file mode 100644 index 1b1eb619b9..0000000000 --- a/patches/api/0462-Fix-ItemFlags.patch +++ /dev/null @@ -1,66 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jake Potrebic -Date: Sat, 27 Apr 2024 13:28:17 -0700 -Subject: [PATCH] Fix ItemFlags - -Adds new flag in HIDE_STORED_ENCHANTS which was split -from HIDE_ADDITIONAL_INFO. Adds a migration to account for -this, adding the new flag if the itemstack is old and had the -old flag. - -diff --git a/src/main/java/org/bukkit/inventory/ItemFlag.java b/src/main/java/org/bukkit/inventory/ItemFlag.java -index 5b8dac777bb1640dc00bbe98feb6460c36eebb98..1af15fd327e0613cd1a179bd7fef1e83cbe31761 100644 ---- a/src/main/java/org/bukkit/inventory/ItemFlag.java -+++ b/src/main/java/org/bukkit/inventory/ItemFlag.java -@@ -2,6 +2,8 @@ package org.bukkit.inventory; - - /** - * A ItemFlag can hide some Attributes from ItemStacks -+ * @apiNote Setting these without also setting the data they are hiding -+ * may not result in the item flag being persisted in the ItemMeta/ItemStack. - */ - public enum ItemFlag { - -@@ -27,7 +29,8 @@ public enum ItemFlag { - HIDE_PLACED_ON, - /** - * Setting to show/hide potion effects, book and firework information, map -- * tooltips, patterns of banners, and enchantments of enchanted books. -+ * tooltips, patterns of banners. -+ * @see #HIDE_STORED_ENCHANTS HIDE_STORED_ENCHANTS for hiding stored enchants (like on enchanted books) - */ - HIDE_ADDITIONAL_TOOLTIP, - /** -@@ -37,7 +40,13 @@ public enum ItemFlag { - /** - * Setting to show/hide armor trim from armor. - */ -- HIDE_ARMOR_TRIM; -+ HIDE_ARMOR_TRIM, -+ /** -+ * Setting to show/hide stored enchants on an item, such as enchantments -+ * on an enchanted book. -+ */ -+ HIDE_STORED_ENCHANTS, -+ ; - // Paper start - /** - * Setting to show/hide item-specific information, including, but not limited to: -diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java -index 2866f10f954f6d3fb1d58c216a2d5ae1372adbad..7f5633e7689b82b937d5b985c3e6ae15dc94a20f 100644 ---- a/src/main/java/org/bukkit/inventory/ItemStack.java -+++ b/src/main/java/org/bukkit/inventory/ItemStack.java -@@ -588,6 +588,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat - Object raw = args.get("meta"); - if (raw instanceof ItemMeta) { - ((ItemMeta) raw).setVersion(version); -+ // Paper start - for pre 1.20.5 itemstacks, add HIDE_STORED_ENCHANTS flag if HIDE_ADDITIONAL_TOOLTIP is set -+ if (version < 3837) { // 1.20.5 -+ if (((ItemMeta) raw).hasItemFlag(ItemFlag.HIDE_ADDITIONAL_TOOLTIP)) { -+ ((ItemMeta) raw).addItemFlags(ItemFlag.HIDE_STORED_ENCHANTS); -+ } -+ } -+ // Paper end - result.setItemMeta((ItemMeta) raw); - } - } diff --git a/patches/api/0463-Add-hook-to-remap-library-jars.patch b/patches/api/0463-Add-hook-to-remap-library-jars.patch new file mode 100644 index 0000000000..fe1609629e --- /dev/null +++ b/patches/api/0463-Add-hook-to-remap-library-jars.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Sun, 28 Apr 2024 13:51:08 -0700 +Subject: [PATCH] Add hook to remap library jars + + +diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java +index 5b0203e908f84c531886b8ea8faeb591eb045636..8e1b6be2462aaa692efa1f72986921a6dc357196 100644 +--- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java ++++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java +@@ -47,6 +47,7 @@ public class LibraryLoader + private final DefaultRepositorySystemSession session; + private final List repositories; + public static java.util.function.BiFunction LIBRARY_LOADER_FACTORY; // Paper - rewrite reflection in libraries ++ public static java.util.function.Function, List> REMAPPER; // Paper - remap libraries + + public LibraryLoader(@NotNull Logger logger) + { +@@ -111,9 +112,18 @@ public class LibraryLoader + } + + List jarFiles = new ArrayList<>(); ++ List jarPaths = new ArrayList<>(); // Paper - remap libraries + for ( ArtifactResult artifact : result.getArtifactResults() ) + { +- File file = artifact.getArtifact().getFile(); ++ // Paper start - remap libraries ++ jarPaths.add(artifact.getArtifact().getFile().toPath()); ++ } ++ if (REMAPPER != null) { ++ jarPaths = REMAPPER.apply(jarPaths); ++ } ++ for (java.nio.file.Path path : jarPaths) { ++ File file = path.toFile(); ++ // Paper end - remap libraries + + URL url; + try diff --git a/patches/api/0463-Allow-modifying-library-loader-jars-bytecode.patch b/patches/api/0463-Allow-modifying-library-loader-jars-bytecode.patch deleted file mode 100644 index 0c0311e790..0000000000 --- a/patches/api/0463-Allow-modifying-library-loader-jars-bytecode.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> -Date: Sun, 28 Apr 2024 11:11:26 -0700 -Subject: [PATCH] Allow modifying library loader jars bytecode - - -diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -index f4d655a158410039305ac68cebe0d79000f73df8..5b0203e908f84c531886b8ea8faeb591eb045636 100644 ---- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -+++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -@@ -46,6 +46,7 @@ public class LibraryLoader - private final RepositorySystem repository; - private final DefaultRepositorySystemSession session; - private final List repositories; -+ public static java.util.function.BiFunction LIBRARY_LOADER_FACTORY; // Paper - rewrite reflection in libraries - - public LibraryLoader(@NotNull Logger logger) - { -@@ -130,7 +131,14 @@ public class LibraryLoader - } ); - } - -- URLClassLoader loader = new URLClassLoader( jarFiles.toArray( new URL[ jarFiles.size() ] ), getClass().getClassLoader() ); -+ // Paper start - rewrite reflection in libraries -+ URLClassLoader loader; -+ if (LIBRARY_LOADER_FACTORY == null) { -+ loader = new URLClassLoader( jarFiles.toArray( new URL[ jarFiles.size() ] ), getClass().getClassLoader() ); -+ } else { -+ loader = LIBRARY_LOADER_FACTORY.apply(jarFiles.toArray( new URL[ jarFiles.size() ] ), getClass().getClassLoader()); -+ } -+ // Paper end - rewrite reflection in libraries - - return loader; - } diff --git a/patches/api/0464-Add-GameMode-isInvulnerable.patch b/patches/api/0464-Add-GameMode-isInvulnerable.patch new file mode 100644 index 0000000000..b4b81c5f52 --- /dev/null +++ b/patches/api/0464-Add-GameMode-isInvulnerable.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SoSeDiK +Date: Wed, 1 May 2024 06:56:21 +0300 +Subject: [PATCH] Add GameMode#isInvulnerable + + +diff --git a/src/main/java/org/bukkit/GameMode.java b/src/main/java/org/bukkit/GameMode.java +index fdc42a79c5af30fdade41ee99245e6641f353571..ddc56524b3bd2bdebba81c61a5600e6f46a4aaa4 100644 +--- a/src/main/java/org/bukkit/GameMode.java ++++ b/src/main/java/org/bukkit/GameMode.java +@@ -79,4 +79,16 @@ public enum GameMode implements net.kyori.adventure.translation.Translatable { / + BY_ID.put(mode.getValue(), mode); + } + } ++ ++ // Paper start - Add GameMode#isInvulnerable ++ /** ++ * Checks whether this game mode is invulnerable ++ * (i.e. is either {@link #CREATIVE} or {@link #SPECTATOR}) ++ * ++ * @return whether this game mode is invulnerable ++ */ ++ public boolean isInvulnerable() { ++ return this == CREATIVE || this == SPECTATOR; ++ } ++ // Paper end - Add GameMode#isInvulnerable + } diff --git a/patches/api/0464-Add-hook-to-remap-library-jars.patch b/patches/api/0464-Add-hook-to-remap-library-jars.patch deleted file mode 100644 index fe1609629e..0000000000 --- a/patches/api/0464-Add-hook-to-remap-library-jars.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> -Date: Sun, 28 Apr 2024 13:51:08 -0700 -Subject: [PATCH] Add hook to remap library jars - - -diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -index 5b0203e908f84c531886b8ea8faeb591eb045636..8e1b6be2462aaa692efa1f72986921a6dc357196 100644 ---- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -+++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java -@@ -47,6 +47,7 @@ public class LibraryLoader - private final DefaultRepositorySystemSession session; - private final List repositories; - public static java.util.function.BiFunction LIBRARY_LOADER_FACTORY; // Paper - rewrite reflection in libraries -+ public static java.util.function.Function, List> REMAPPER; // Paper - remap libraries - - public LibraryLoader(@NotNull Logger logger) - { -@@ -111,9 +112,18 @@ public class LibraryLoader - } - - List jarFiles = new ArrayList<>(); -+ List jarPaths = new ArrayList<>(); // Paper - remap libraries - for ( ArtifactResult artifact : result.getArtifactResults() ) - { -- File file = artifact.getArtifact().getFile(); -+ // Paper start - remap libraries -+ jarPaths.add(artifact.getArtifact().getFile().toPath()); -+ } -+ if (REMAPPER != null) { -+ jarPaths = REMAPPER.apply(jarPaths); -+ } -+ for (java.nio.file.Path path : jarPaths) { -+ File file = path.toFile(); -+ // Paper end - remap libraries - - URL url; - try diff --git a/patches/api/0465-Add-GameMode-isInvulnerable.patch b/patches/api/0465-Add-GameMode-isInvulnerable.patch deleted file mode 100644 index b4b81c5f52..0000000000 --- a/patches/api/0465-Add-GameMode-isInvulnerable.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: SoSeDiK -Date: Wed, 1 May 2024 06:56:21 +0300 -Subject: [PATCH] Add GameMode#isInvulnerable - - -diff --git a/src/main/java/org/bukkit/GameMode.java b/src/main/java/org/bukkit/GameMode.java -index fdc42a79c5af30fdade41ee99245e6641f353571..ddc56524b3bd2bdebba81c61a5600e6f46a4aaa4 100644 ---- a/src/main/java/org/bukkit/GameMode.java -+++ b/src/main/java/org/bukkit/GameMode.java -@@ -79,4 +79,16 @@ public enum GameMode implements net.kyori.adventure.translation.Translatable { / - BY_ID.put(mode.getValue(), mode); - } - } -+ -+ // Paper start - Add GameMode#isInvulnerable -+ /** -+ * Checks whether this game mode is invulnerable -+ * (i.e. is either {@link #CREATIVE} or {@link #SPECTATOR}) -+ * -+ * @return whether this game mode is invulnerable -+ */ -+ public boolean isInvulnerable() { -+ return this == CREATIVE || this == SPECTATOR; -+ } -+ // Paper end - Add GameMode#isInvulnerable - } diff --git a/patches/api/0465-Expose-hasColor-to-leather-armor.patch b/patches/api/0465-Expose-hasColor-to-leather-armor.patch new file mode 100644 index 0000000000..e2c609b4f0 --- /dev/null +++ b/patches/api/0465-Expose-hasColor-to-leather-armor.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SoSeDiK +Date: Wed, 1 May 2024 10:58:50 +0300 +Subject: [PATCH] Expose #hasColor to leather armor + + +diff --git a/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java b/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java +index c701d5fbc5fef503f18a3a46fa54c983bf96e895..2d68f93c371e4a40638f56e5cd4d39472d4e462b 100644 +--- a/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java ++++ b/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java +@@ -36,4 +36,13 @@ public interface LeatherArmorMeta extends ItemMeta { + @Override + @NotNull + LeatherArmorMeta clone(); ++ ++ // Paper start - Expose #hasColor to leather armor ++ /** ++ * Checks whether this leather armor is dyed. ++ * ++ * @return whether this leather armor is dyed ++ */ ++ boolean isDyed(); ++ // Paper end - Expose #hasColor to leather armor + } diff --git a/patches/api/0466-Add-missing-wind-charge-damage-type.patch b/patches/api/0466-Add-missing-wind-charge-damage-type.patch new file mode 100644 index 0000000000..8b5bd35be7 --- /dev/null +++ b/patches/api/0466-Add-missing-wind-charge-damage-type.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> +Date: Fri, 3 May 2024 22:56:12 +0200 +Subject: [PATCH] Add missing wind charge damage type + + +diff --git a/src/main/java/org/bukkit/damage/DamageType.java b/src/main/java/org/bukkit/damage/DamageType.java +index 69abda41ef3a1d8948982d16b193a9a565fafa38..9ec1abbd741198705d2a7685bbd2e2660679461d 100644 +--- a/src/main/java/org/bukkit/damage/DamageType.java ++++ b/src/main/java/org/bukkit/damage/DamageType.java +@@ -66,6 +66,10 @@ public interface DamageType extends Keyed, Translatable { + public static final DamageType BAD_RESPAWN_POINT = getDamageType("bad_respawn_point"); + public static final DamageType OUTSIDE_BORDER = getDamageType("outside_border"); + public static final DamageType GENERIC_KILL = getDamageType("generic_kill"); ++ // Paper start ++ @org.jetbrains.annotations.Nullable ++ DamageType WIND_CHARGE = getExperimentalDamageType("wind_charge"); ++ // Paper end + + @NotNull + private static DamageType getDamageType(@NotNull String key) { +@@ -73,6 +77,12 @@ public interface DamageType extends Keyed, Translatable { + return Preconditions.checkNotNull(Registry.DAMAGE_TYPE.get(namespacedKey), "No DamageType found for %s. This is a bug.", namespacedKey); + } + ++ // Paper start ++ private static @org.jetbrains.annotations.Nullable DamageType getExperimentalDamageType(@NotNull String key) { ++ return Registry.DAMAGE_TYPE.get(NamespacedKey.minecraft(key)); ++ } ++ // Paper end ++ + /** + * {@inheritDoc} + *

diff --git a/patches/api/0466-Expose-hasColor-to-leather-armor.patch b/patches/api/0466-Expose-hasColor-to-leather-armor.patch deleted file mode 100644 index e2c609b4f0..0000000000 --- a/patches/api/0466-Expose-hasColor-to-leather-armor.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: SoSeDiK -Date: Wed, 1 May 2024 10:58:50 +0300 -Subject: [PATCH] Expose #hasColor to leather armor - - -diff --git a/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java b/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java -index c701d5fbc5fef503f18a3a46fa54c983bf96e895..2d68f93c371e4a40638f56e5cd4d39472d4e462b 100644 ---- a/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java -+++ b/src/main/java/org/bukkit/inventory/meta/LeatherArmorMeta.java -@@ -36,4 +36,13 @@ public interface LeatherArmorMeta extends ItemMeta { - @Override - @NotNull - LeatherArmorMeta clone(); -+ -+ // Paper start - Expose #hasColor to leather armor -+ /** -+ * Checks whether this leather armor is dyed. -+ * -+ * @return whether this leather armor is dyed -+ */ -+ boolean isDyed(); -+ // Paper end - Expose #hasColor to leather armor - } diff --git a/patches/api/0467-Add-missing-wind-charge-damage-type.patch b/patches/api/0467-Add-missing-wind-charge-damage-type.patch deleted file mode 100644 index 8b5bd35be7..0000000000 --- a/patches/api/0467-Add-missing-wind-charge-damage-type.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> -Date: Fri, 3 May 2024 22:56:12 +0200 -Subject: [PATCH] Add missing wind charge damage type - - -diff --git a/src/main/java/org/bukkit/damage/DamageType.java b/src/main/java/org/bukkit/damage/DamageType.java -index 69abda41ef3a1d8948982d16b193a9a565fafa38..9ec1abbd741198705d2a7685bbd2e2660679461d 100644 ---- a/src/main/java/org/bukkit/damage/DamageType.java -+++ b/src/main/java/org/bukkit/damage/DamageType.java -@@ -66,6 +66,10 @@ public interface DamageType extends Keyed, Translatable { - public static final DamageType BAD_RESPAWN_POINT = getDamageType("bad_respawn_point"); - public static final DamageType OUTSIDE_BORDER = getDamageType("outside_border"); - public static final DamageType GENERIC_KILL = getDamageType("generic_kill"); -+ // Paper start -+ @org.jetbrains.annotations.Nullable -+ DamageType WIND_CHARGE = getExperimentalDamageType("wind_charge"); -+ // Paper end - - @NotNull - private static DamageType getDamageType(@NotNull String key) { -@@ -73,6 +77,12 @@ public interface DamageType extends Keyed, Translatable { - return Preconditions.checkNotNull(Registry.DAMAGE_TYPE.get(namespacedKey), "No DamageType found for %s. This is a bug.", namespacedKey); - } - -+ // Paper start -+ private static @org.jetbrains.annotations.Nullable DamageType getExperimentalDamageType(@NotNull String key) { -+ return Registry.DAMAGE_TYPE.get(NamespacedKey.minecraft(key)); -+ } -+ // Paper end -+ - /** - * {@inheritDoc} - *

diff --git a/patches/api/0467-Added-API-to-get-player-ha-proxy-address.patch b/patches/api/0467-Added-API-to-get-player-ha-proxy-address.patch new file mode 100644 index 0000000000..b1702bee61 --- /dev/null +++ b/patches/api/0467-Added-API-to-get-player-ha-proxy-address.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: nostalfinals +Date: Mon, 8 Apr 2024 23:24:38 +0800 +Subject: [PATCH] Added API to get player ha proxy address + + +diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java +index 7b699c1e63cf5bc805754101f28066f836877ee2..7c56182acaf827f4b1a986a61cea8e9960604c98 100644 +--- a/src/main/java/org/bukkit/entity/Player.java ++++ b/src/main/java/org/bukkit/entity/Player.java +@@ -251,6 +251,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM + @Nullable + public InetSocketAddress getAddress(); + ++ // Paper start - Add API to get player's proxy address ++ /** ++ * Gets the socket address of this player's proxy ++ * ++ * @return the player's proxy address, null if the server doesn't have Proxy Protocol enabled, or the player didn't connect to an HAProxy instance ++ */ ++ @Nullable ++ public InetSocketAddress getHAProxyAddress(); ++ // Paper end - Add API to get player's proxy address ++ + /** + * Gets if this connection has been transferred from another server. + * diff --git a/patches/api/0468-Added-API-to-get-player-ha-proxy-address.patch b/patches/api/0468-Added-API-to-get-player-ha-proxy-address.patch deleted file mode 100644 index b1702bee61..0000000000 --- a/patches/api/0468-Added-API-to-get-player-ha-proxy-address.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: nostalfinals -Date: Mon, 8 Apr 2024 23:24:38 +0800 -Subject: [PATCH] Added API to get player ha proxy address - - -diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java -index 7b699c1e63cf5bc805754101f28066f836877ee2..7c56182acaf827f4b1a986a61cea8e9960604c98 100644 ---- a/src/main/java/org/bukkit/entity/Player.java -+++ b/src/main/java/org/bukkit/entity/Player.java -@@ -251,6 +251,16 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM - @Nullable - public InetSocketAddress getAddress(); - -+ // Paper start - Add API to get player's proxy address -+ /** -+ * Gets the socket address of this player's proxy -+ * -+ * @return the player's proxy address, null if the server doesn't have Proxy Protocol enabled, or the player didn't connect to an HAProxy instance -+ */ -+ @Nullable -+ public InetSocketAddress getHAProxyAddress(); -+ // Paper end - Add API to get player's proxy address -+ - /** - * Gets if this connection has been transferred from another server. - * diff --git a/patches/api/0468-More-Chest-Block-API.patch b/patches/api/0468-More-Chest-Block-API.patch new file mode 100644 index 0000000000..1fc3614c74 --- /dev/null +++ b/patches/api/0468-More-Chest-Block-API.patch @@ -0,0 +1,44 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: SoSeDiK +Date: Wed, 1 May 2024 08:22:13 +0300 +Subject: [PATCH] More Chest Block API + + +diff --git a/src/main/java/org/bukkit/block/Chest.java b/src/main/java/org/bukkit/block/Chest.java +index db6affbc78106b2d93b41953b624a0bca0ca1d72..5d02f9c938d0d7d0f4e491ccfaf6beb0a7a61aa4 100644 +--- a/src/main/java/org/bukkit/block/Chest.java ++++ b/src/main/java/org/bukkit/block/Chest.java +@@ -27,4 +27,14 @@ public interface Chest extends Container, LootableBlockInventory, Lidded { // Pa + */ + @NotNull + Inventory getBlockInventory(); ++ ++ // Paper start - More Chest Block API ++ /** ++ * Checks whether this chest is blocked ++ * by either a block above or a sitting cat ++ * ++ * @return whether this chest is blocked ++ */ ++ boolean isBlocked(); ++ // Paper end - More Chest Block API + } +diff --git a/src/main/java/org/bukkit/block/EnderChest.java b/src/main/java/org/bukkit/block/EnderChest.java +index 1150b449a3f5c40fe10136779c2ccc65ab4d884c..6b66f38e5509f90aad5ee1fffca01003dcbe9896 100644 +--- a/src/main/java/org/bukkit/block/EnderChest.java ++++ b/src/main/java/org/bukkit/block/EnderChest.java +@@ -3,4 +3,13 @@ package org.bukkit.block; + /** + * Represents a captured state of an ender chest. + */ +-public interface EnderChest extends Lidded, TileState { } ++public interface EnderChest extends Lidded, TileState { ++ // Paper start - More Chest Block API ++ /** ++ * Checks whether this ender chest is blocked by a block above ++ * ++ * @return whether this ender chest is blocked ++ */ ++ boolean isBlocked(); ++ // Paper end - More Chest Block API ++} diff --git a/patches/api/0469-Brigadier-based-command-API.patch b/patches/api/0469-Brigadier-based-command-API.patch new file mode 100644 index 0000000000..20c58c3c82 --- /dev/null +++ b/patches/api/0469-Brigadier-based-command-API.patch @@ -0,0 +1,1989 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Mon, 1 Aug 2022 22:50:29 -0400 +Subject: [PATCH] Brigadier based command API + +Co-authored-by: Jake Potrebic + +diff --git a/build.gradle.kts b/build.gradle.kts +index eecf458e1250ee9968630cf5c3c3287a1693e52e..fd39ed209b20c927054b8482c400beeeeab460a3 100644 +--- a/build.gradle.kts ++++ b/build.gradle.kts +@@ -27,6 +27,7 @@ configurations.api { + } + + dependencies { ++ api("com.mojang:brigadier:1.2.9") // Paper - Brigadier command api + // api dependencies are listed transitively to API consumers + api("com.google.guava:guava:32.1.2-jre") + api("com.google.code.gson:gson:2.10.1") +@@ -92,9 +93,29 @@ sourceSets { + } + } + // Paper end ++// Paper start - brigadier API ++val outgoingVariants = arrayOf("runtimeElements", "apiElements", "sourcesElements", "javadocElements") ++configurations { ++ val outgoing = outgoingVariants.map { named(it) } ++ for (config in outgoing) { ++ config { ++ outgoing { ++ capability("${project.group}:${project.name}:${project.version}") ++ capability("io.papermc.paper:paper-mojangapi:${project.version}") ++ capability("com.destroystokyo.paper:paper-mojangapi:${project.version}") ++ } ++ } ++ } ++} ++// Paper end + + configure { + publications.create("maven") { ++ // Paper start - brigadier API ++ outgoingVariants.forEach { ++ suppressPomMetadataWarningsFor(it) ++ } ++ // Paper end + from(components["java"]) + } + } +diff --git a/src/main/java/com/destroystokyo/paper/brigadier/BukkitBrigadierCommand.java b/src/main/java/com/destroystokyo/paper/brigadier/BukkitBrigadierCommand.java +new file mode 100644 +index 0000000000000000000000000000000000000000..03a1078446f84b998cd7fe8d64abecb2e36bab0a +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/brigadier/BukkitBrigadierCommand.java +@@ -0,0 +1,16 @@ ++package com.destroystokyo.paper.brigadier; ++ ++import com.mojang.brigadier.Command; ++import com.mojang.brigadier.suggestion.SuggestionProvider; ++ ++import java.util.function.Predicate; ++ ++/** ++ * Brigadier {@link Command}, {@link SuggestionProvider}, and permission checker for Bukkit {@link Command}s. ++ * ++ * @param command source type ++ * @deprecated For removal, see {@link io.papermc.paper.command.brigadier.Commands} on how to use the new Brigadier API. ++ */ ++@Deprecated(forRemoval = true, since = "1.20.6") ++public interface BukkitBrigadierCommand extends Command, Predicate, SuggestionProvider { ++} +diff --git a/src/main/java/com/destroystokyo/paper/brigadier/BukkitBrigadierCommandSource.java b/src/main/java/com/destroystokyo/paper/brigadier/BukkitBrigadierCommandSource.java +new file mode 100644 +index 0000000000000000000000000000000000000000..28b44789e3be586c4b680fff56e5d2ff095f9ac2 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/brigadier/BukkitBrigadierCommandSource.java +@@ -0,0 +1,25 @@ ++package com.destroystokyo.paper.brigadier; ++ ++import org.bukkit.Location; ++import org.bukkit.World; ++import org.bukkit.command.CommandSender; ++import org.bukkit.entity.Entity; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * @deprecated For removal, see {@link io.papermc.paper.command.brigadier.Commands} on how to use the new Brigadier API. ++ */ ++@Deprecated(forRemoval = true) ++public interface BukkitBrigadierCommandSource { ++ ++ @Nullable ++ Entity getBukkitEntity(); ++ ++ @Nullable ++ World getBukkitWorld(); ++ ++ @Nullable ++ Location getBukkitLocation(); ++ ++ CommandSender getBukkitSender(); ++} +diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendCommandsEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendCommandsEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ba5472a068075f8f7fb5b9bce05e783ca9b4ffdf +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendCommandsEvent.java +@@ -0,0 +1,73 @@ ++package com.destroystokyo.paper.event.brigadier; ++ ++import com.mojang.brigadier.tree.RootCommandNode; ++import io.papermc.paper.command.brigadier.CommandSourceStack; ++import org.bukkit.Bukkit; ++import org.bukkit.entity.Player; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Fired any time a Brigadier RootCommandNode is generated for a player to inform the client of commands. ++ * You may manipulate this CommandNode to change what the client sees. ++ * ++ *

This event may fire on login, world change, and permission rebuilds, by plugin request, and potentially future means.

++ * ++ *

This event will fire before {@link org.bukkit.event.player.PlayerCommandSendEvent}, so no filtering has been done by ++ * other plugins yet.

++ * ++ *

WARNING: This event will potentially (and most likely) fire twice! Once for Async, and once again for Sync. ++ * It is important that you check event.isAsynchronous() and event.hasFiredAsync() to ensure you only act once. ++ * If for some reason we are unable to send this asynchronously in the future, only the sync method will fire.

++ * ++ *

Your logic should look like this: ++ * {@code if (event.isAsynchronous() || !event.hasFiredAsync()) { // do stuff }}

++ * ++ *

If your logic is not safe to run asynchronously, only react to the synchronous version.

++ * ++ *

This is a draft/experimental API and is subject to change.

++ */ ++@ApiStatus.Experimental ++public class AsyncPlayerSendCommandsEvent extends PlayerEvent { ++ ++ private static final HandlerList handlers = new HandlerList(); ++ private final RootCommandNode node; ++ private final boolean hasFiredAsync; ++ ++ @ApiStatus.Internal ++ public AsyncPlayerSendCommandsEvent(@NotNull Player player, @NotNull RootCommandNode node, boolean hasFiredAsync) { ++ super(player, !Bukkit.isPrimaryThread()); ++ this.node = node; ++ this.hasFiredAsync = hasFiredAsync; ++ } ++ ++ /** ++ * Gets the full Root Command Node being sent to the client, which is mutable. ++ * ++ * @return the root command node ++ */ ++ public @NotNull RootCommandNode getCommandNode() { ++ return node; ++ } ++ ++ /** ++ * Gets if this event has already fired asynchronously. ++ * ++ * @return whether this event has already fired asynchronously ++ */ ++ public boolean hasFiredAsync() { ++ return hasFiredAsync; ++ } ++ ++ @NotNull ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++} +diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6ac205de582983863bd5b3c0fa70d4375dd751c5 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java +@@ -0,0 +1,85 @@ ++package com.destroystokyo.paper.event.brigadier; ++ ++import com.mojang.brigadier.suggestion.Suggestions; ++import org.bukkit.Bukkit; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.player.PlayerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Called when sending {@link Suggestions} to the client. Will be called asynchronously if a plugin ++ * marks the {@link com.destroystokyo.paper.event.server.AsyncTabCompleteEvent} event handled asynchronously, ++ * otherwise called synchronously. ++ */ ++public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Cancellable { ++ ++ private static final HandlerList handlers = new HandlerList(); ++ private boolean cancelled = false; ++ ++ private Suggestions suggestions; ++ private final String buffer; ++ ++ @ApiStatus.Internal ++ public AsyncPlayerSendSuggestionsEvent(@NotNull Player player, @NotNull Suggestions suggestions, @NotNull String buffer) { ++ super(player, !Bukkit.isPrimaryThread()); ++ this.suggestions = suggestions; ++ this.buffer = buffer; ++ } ++ ++ /** ++ * Gets the input buffer sent to request these suggestions. ++ * ++ * @return the input buffer ++ */ ++ public @NotNull String getBuffer() { ++ return buffer; ++ } ++ ++ /** ++ * Gets the suggestions to be sent to client. ++ * ++ * @return the suggestions ++ */ ++ public @NotNull Suggestions getSuggestions() { ++ return suggestions; ++ } ++ ++ /** ++ * Sets the suggestions to be sent to client. ++ * ++ * @param suggestions suggestions ++ */ ++ public void setSuggestions(@NotNull Suggestions suggestions) { ++ this.suggestions = suggestions; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ /** ++ * Cancels sending suggestions to the client. ++ * {@inheritDoc} ++ */ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @NotNull ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++} +diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..acc2bd2ec56e64b9d4bd8677d99448a97ecb5201 +--- /dev/null ++++ b/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java +@@ -0,0 +1,171 @@ ++package com.destroystokyo.paper.event.brigadier; ++ ++import com.destroystokyo.paper.brigadier.BukkitBrigadierCommand; ++import com.mojang.brigadier.tree.ArgumentCommandNode; ++import com.mojang.brigadier.tree.LiteralCommandNode; ++import com.mojang.brigadier.tree.RootCommandNode; ++import org.bukkit.Warning; ++import org.bukkit.command.Command; ++import org.bukkit.event.Cancellable; ++import org.bukkit.event.HandlerList; ++import org.bukkit.event.server.ServerEvent; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Fired anytime the server synchronizes Bukkit commands to Brigadier. ++ * ++ *

Allows a plugin to control the command node structure for its commands. ++ * This is done at Plugin Enable time after commands have been registered, but may also ++ * run at a later point in the server lifetime due to plugins, a server reload, etc.

++ * ++ *

This is a draft/experimental API and is subject to change.

++ * @deprecated For removal, use the new brigadier api. ++ */ ++@ApiStatus.Experimental ++@Deprecated(since = "1.20.6") ++@Warning(reason = "This event has been superseded by the Commands API and will be removed in a future release. Listen to LifecycleEvents.COMMANDS instead.", value = true) ++public class CommandRegisteredEvent extends ServerEvent implements Cancellable { ++ ++ private static final HandlerList handlers = new HandlerList(); ++ private final String commandLabel; ++ private final Command command; ++ private final com.destroystokyo.paper.brigadier.BukkitBrigadierCommand brigadierCommand; ++ private final RootCommandNode root; ++ private final ArgumentCommandNode defaultArgs; ++ private LiteralCommandNode literal; ++ private boolean rawCommand = false; ++ private boolean cancelled = false; ++ ++ public CommandRegisteredEvent(String commandLabel, com.destroystokyo.paper.brigadier.BukkitBrigadierCommand brigadierCommand, Command command, RootCommandNode root, LiteralCommandNode literal, ArgumentCommandNode defaultArgs) { ++ this.commandLabel = commandLabel; ++ this.brigadierCommand = brigadierCommand; ++ this.command = command; ++ this.root = root; ++ this.literal = literal; ++ this.defaultArgs = defaultArgs; ++ } ++ ++ /** ++ * Gets the command label of the {@link Command} being registered. ++ * ++ * @return the command label ++ */ ++ public String getCommandLabel() { ++ return this.commandLabel; ++ } ++ ++ /** ++ * Gets the {@link BukkitBrigadierCommand} for the {@link Command} being registered. This can be used ++ * as the {@link com.mojang.brigadier.Command command executor} or ++ * {@link com.mojang.brigadier.suggestion.SuggestionProvider} of a {@link com.mojang.brigadier.tree.CommandNode} ++ * to delegate to the {@link Command} being registered. ++ * ++ * @return the {@link BukkitBrigadierCommand} ++ */ ++ public BukkitBrigadierCommand getBrigadierCommand() { ++ return this.brigadierCommand; ++ } ++ ++ /** ++ * Gets the {@link Command} being registered. ++ * ++ * @return the {@link Command} ++ */ ++ public Command getCommand() { ++ return this.command; ++ } ++ ++ /** ++ * Gets the {@link RootCommandNode} which is being registered to. ++ * ++ * @return the {@link RootCommandNode} ++ */ ++ public RootCommandNode getRoot() { ++ return this.root; ++ } ++ ++ /** ++ * Gets the Bukkit APIs default arguments node (greedy string), for if ++ * you wish to reuse it. ++ * ++ * @return default arguments node ++ */ ++ public ArgumentCommandNode getDefaultArgs() { ++ return this.defaultArgs; ++ } ++ ++ /** ++ * Gets the {@link LiteralCommandNode} to be registered for the {@link Command}. ++ * ++ * @return the {@link LiteralCommandNode} ++ */ ++ public LiteralCommandNode getLiteral() { ++ return this.literal; ++ } ++ ++ /** ++ * Sets the {@link LiteralCommandNode} used to register this command. The default literal is mutable, so ++ * this is primarily if you want to completely replace the object. ++ * ++ * @param literal new node ++ */ ++ public void setLiteral(LiteralCommandNode literal) { ++ this.literal = literal; ++ } ++ ++ /** ++ * Gets whether this command should is treated as "raw". ++ * ++ * @see #setRawCommand(boolean) ++ * @return whether this command is treated as "raw" ++ */ ++ public boolean isRawCommand() { ++ return this.rawCommand; ++ } ++ ++ /** ++ * Sets whether this command should be treated as "raw". ++ * ++ *

A "raw" command will only use the node provided by this event for ++ * sending the command tree to the client. For execution purposes, the default ++ * greedy string execution of a standard Bukkit {@link Command} is used.

++ * ++ *

On older versions of Paper, this was the default and only behavior of this ++ * event.

++ * ++ * @param rawCommand whether this command should be treated as "raw" ++ */ ++ public void setRawCommand(final boolean rawCommand) { ++ this.rawCommand = rawCommand; ++ } ++ ++ /** ++ * {@inheritDoc} ++ */ ++ @Override ++ public boolean isCancelled() { ++ return this.cancelled; ++ } ++ ++ /** ++ * Cancels registering this command to Brigadier, but will remain in Bukkit Command Map. Can be used to hide a ++ * command from all players. ++ * ++ * {@inheritDoc} ++ */ ++ @Override ++ public void setCancelled(boolean cancel) { ++ this.cancelled = cancel; ++ } ++ ++ @NotNull ++ public HandlerList getHandlers() { ++ return handlers; ++ } ++ ++ @NotNull ++ public static HandlerList getHandlerList() { ++ return handlers; ++ } ++} +diff --git a/src/main/java/io/papermc/paper/brigadier/PaperBrigadier.java b/src/main/java/io/papermc/paper/brigadier/PaperBrigadier.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9df87708206e26167a2c4934deff7fc6f1657106 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/brigadier/PaperBrigadier.java +@@ -0,0 +1,47 @@ ++package io.papermc.paper.brigadier; ++ ++import com.mojang.brigadier.Message; ++import io.papermc.paper.command.brigadier.MessageComponentSerializer; ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.ComponentLike; ++import net.kyori.adventure.text.TextComponent; ++import org.checkerframework.checker.nullness.qual.NonNull; ++ ++/** ++ * Helper methods to bridge the gaps between Brigadier and Paper-MojangAPI. ++ * @deprecated for removal. See {@link MessageComponentSerializer} for a direct replacement of functionality found in ++ * this class. ++ * As a general entrypoint to brigadier on paper, see {@link io.papermc.paper.command.brigadier.Commands}. ++ */ ++@Deprecated(forRemoval = true, since = "1.20.6") ++public final class PaperBrigadier { ++ private PaperBrigadier() { ++ throw new RuntimeException("PaperBrigadier is not to be instantiated!"); ++ } ++ ++ /** ++ * Create a new Brigadier {@link Message} from a {@link ComponentLike}. ++ * ++ *

Mostly useful for creating rich suggestion tooltips in combination with other Paper-MojangAPI APIs.

++ * ++ * @param componentLike The {@link ComponentLike} to use for the {@link Message} contents ++ * @return A new Brigadier {@link Message} ++ */ ++ public static @NonNull Message message(final @NonNull ComponentLike componentLike) { ++ return MessageComponentSerializer.message().serialize(componentLike.asComponent()); ++ } ++ ++ /** ++ * Create a new {@link Component} from a Brigadier {@link Message}. ++ * ++ *

If the {@link Message} was created from a {@link Component}, it will simply be ++ * converted back, otherwise a new {@link TextComponent} will be created with the ++ * content of {@link Message#getString()}

++ * ++ * @param message The {@link Message} to create a {@link Component} from ++ * @return The created {@link Component} ++ */ ++ public static @NonNull Component componentFromMessage(final @NonNull Message message) { ++ return MessageComponentSerializer.message().deserialize(message); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/command/brigadier/BasicCommand.java b/src/main/java/io/papermc/paper/command/brigadier/BasicCommand.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0f6b921b4bcf983cf25188823f78a061eec5263d +--- /dev/null ++++ b/src/main/java/io/papermc/paper/command/brigadier/BasicCommand.java +@@ -0,0 +1,36 @@ ++package io.papermc.paper.command.brigadier; ++ ++import java.util.Collection; ++import java.util.Collections; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * Implementing this interface allows for easily creating "Bukkit-style" {@code String[] args} commands. ++ * The implementation handles converting the command to a representation compatible with Brigadier on registration, usually in the form of {@literal /commandlabel }. ++ */ ++@ApiStatus.Experimental ++@FunctionalInterface ++public interface BasicCommand { ++ ++ /** ++ * Executes the command with the given {@link CommandSourceStack} and arguments. ++ * ++ * @param commandSourceStack the commandSourceStack of the command ++ * @param args the arguments of the command ignoring repeated spaces ++ */ ++ @ApiStatus.OverrideOnly ++ void execute(@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args); ++ ++ /** ++ * Suggests possible completions for the given command {@link CommandSourceStack} and arguments. ++ * ++ * @param commandSourceStack the commandSourceStack of the command ++ * @param args the arguments of the command including repeated spaces ++ * @return a collection of suggestions ++ */ ++ @ApiStatus.OverrideOnly ++ default @NotNull Collection suggest(final @NotNull CommandSourceStack commandSourceStack, final @NotNull String[] args) { ++ return Collections.emptyList(); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java b/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7e24babf746de474c8deec4b147e22031e8dadb2 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java +@@ -0,0 +1,14 @@ ++package io.papermc.paper.command.brigadier; ++ ++import org.jetbrains.annotations.ApiStatus; ++ ++/** ++ * A {@link CommandRegistrationFlag} is used in {@link Commands} registration for internal purposes. ++ *

++ * A command library may use this to achieve more specific customization on how their commands are registered. ++ * @apiNote Stability of these flags is not promised! This api is not intended for public use. ++ */ ++@ApiStatus.Internal ++public enum CommandRegistrationFlag { ++ FLATTEN_ALIASES ++} +diff --git a/src/main/java/io/papermc/paper/command/brigadier/CommandSourceStack.java b/src/main/java/io/papermc/paper/command/brigadier/CommandSourceStack.java +new file mode 100644 +index 0000000000000000000000000000000000000000..54288dbe7185b875a74184f002ee4de4405e91b1 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/command/brigadier/CommandSourceStack.java +@@ -0,0 +1,50 @@ ++package io.papermc.paper.command.brigadier; ++ ++import org.bukkit.Location; ++import org.bukkit.command.CommandSender; ++import org.bukkit.entity.Entity; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++ ++/** ++ * The command source type for Brigadier commands registered using Paper API. ++ *

++ * While the general use case for CommandSourceStack is similar to that of {@link CommandSender}, it provides access to ++ * important additional context for the command execution. ++ * Specifically, commands such as {@literal /execute} may alter the location or executor of the source stack before ++ * passing it to another command. ++ *

The {@link CommandSender} returned by {@link #getSender()} may be a "no-op" ++ * instance of {@link CommandSender} in cases where the server either doesn't ++ * exist yet, or no specific sender is available. Methods on such a {@link CommandSender} ++ * will either have no effect or throw an {@link UnsupportedOperationException}.

++ */ ++@ApiStatus.NonExtendable ++@ApiStatus.Experimental ++public interface CommandSourceStack { ++ ++ /** ++ * Gets the location that this command is being executed at. ++ * ++ * @return a cloned location instance. ++ */ ++ @NotNull Location getLocation(); ++ ++ /** ++ * Gets the command sender that executed this command. ++ * The sender of a command source stack is the one that initiated/triggered the execution of a command. ++ * It differs to {@link #getExecutor()} as the executor can be changed by a command, e.g. {@literal /execute}. ++ * ++ * @return the command sender instance ++ */ ++ @NotNull CommandSender getSender(); ++ ++ /** ++ * Gets the entity that executes this command. ++ * May not always be {@link #getSender()} as the executor of a command can be changed to a different entity ++ * than the one that triggered the command. ++ * ++ * @return entity that executes this command ++ */ ++ @Nullable Entity getExecutor(); ++} +diff --git a/src/main/java/io/papermc/paper/command/brigadier/Commands.java b/src/main/java/io/papermc/paper/command/brigadier/Commands.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ce60b618de10da7638f5aefa974aebe02600465c +--- /dev/null ++++ b/src/main/java/io/papermc/paper/command/brigadier/Commands.java +@@ -0,0 +1,266 @@ ++package io.papermc.paper.command.brigadier; ++ ++import com.mojang.brigadier.CommandDispatcher; ++import com.mojang.brigadier.arguments.ArgumentType; ++import com.mojang.brigadier.builder.LiteralArgumentBuilder; ++import com.mojang.brigadier.builder.RequiredArgumentBuilder; ++import com.mojang.brigadier.tree.LiteralCommandNode; ++import io.papermc.paper.plugin.bootstrap.BootstrapContext; ++import io.papermc.paper.plugin.bootstrap.PluginBootstrap; ++import io.papermc.paper.plugin.configuration.PluginMeta; ++import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; ++import io.papermc.paper.plugin.lifecycle.event.registrar.Registrar; ++import java.util.Collection; ++import java.util.Collections; ++import java.util.Set; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++import org.jetbrains.annotations.Nullable; ++import org.jetbrains.annotations.Unmodifiable; ++ ++/** ++ * The registrar for custom commands. Supports Brigadier commands and {@link BasicCommand}. ++ *

++ * An example of a command being registered is below ++ *

{@code
++ * class YourPluginClass extends JavaPlugin {
++ *
++ *     @Override
++ *     public void onEnable() {
++ *         LifecycleEventManager manager = this.getLifecycleManager();
++ *         manager.registerEventHandler(LifecycleEvents.COMMANDS, event -> {
++ *             final Commands commands = event.registrar();
++ *             commands.register(
++ *                 Commands.literal("new-command")
++ *                     .executes(ctx -> {
++ *                         ctx.getSource().getSender().sendPlainMessage("some message");
++ *                         return Command.SINGLE_SUCCESS;
++ *                     })
++ *                     .build(),
++ *                 "some bukkit help description string",
++ *                 List.of("an-alias")
++ *             );
++ *         });
++ *     }
++ * }
++ * }
++ *

++ * You can also register commands in {@link PluginBootstrap} by getting the {@link LifecycleEventManager} from ++ * {@link BootstrapContext}. ++ * Commands registered in the {@link PluginBootstrap} will be available for datapack's ++ * command function parsing. ++ * Note that commands registered via {@link PluginBootstrap} with the same literals as a vanilla command will override ++ * that command within all loaded datapacks. ++ *

++ *

The {@code register} methods that do not have {@link PluginMeta} as a parameter will ++ * implicitly use the {@link PluginMeta} for the plugin that the {@link io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler} ++ * was registered with.

++ * ++ * @see io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#COMMANDS ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface Commands extends Registrar { ++ ++ /** ++ * Utility to create a literal command node builder with the correct generic. ++ * ++ * @param literal literal name ++ * @return a new builder instance ++ */ ++ static @NotNull LiteralArgumentBuilder literal(final @NotNull String literal) { ++ return LiteralArgumentBuilder.literal(literal); ++ } ++ ++ /** ++ * Utility to create a required argument builder with the correct generic. ++ * ++ * @param name the name of the argument ++ * @param argumentType the type of the argument ++ * @param the generic type of the argument value ++ * @return a new required argument builder ++ */ ++ static @NotNull RequiredArgumentBuilder argument(final @NotNull String name, final @NotNull ArgumentType argumentType) { ++ return RequiredArgumentBuilder.argument(name, argumentType); ++ } ++ ++ /** ++ * Gets the underlying {@link CommandDispatcher}. ++ * ++ *

Note: This is a delicate API that must be used with care to ensure a consistent user experience.

++ * ++ *

When registering commands, it should be preferred to use the {@link #register(PluginMeta, LiteralCommandNode, String, Collection) register methods} ++ * over directly registering to the dispatcher wherever possible. ++ * {@link #register(PluginMeta, LiteralCommandNode, String, Collection) Register methods} automatically handle ++ * command namespacing, command help, plugin association with commands, and more.

++ * ++ *

Example use cases for this method may include: ++ *

    ++ *
  • Implementing integration between an external command framework and Paper (although {@link #register(PluginMeta, LiteralCommandNode, String, Collection) register methods} should still be preferred where possible)
  • ++ *
  • Registering new child nodes to an existing plugin command (for example an "addon" plugin to another plugin may want to do this)
  • ++ *
  • Retrieving existing command nodes to build redirects
  • ++ *
++ * ++ * @return the dispatcher instance ++ */ ++ @ApiStatus.Experimental ++ @NotNull CommandDispatcher getDispatcher(); ++ ++ /** ++ * Registers a command for the current plugin context. ++ * ++ *

Commands have certain overriding behavior: ++ *

    ++ *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • ++ *
  • The main command/namespaced label will override already existing commands
  • ++ *
++ * ++ * @param node the built literal command node ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ default @Unmodifiable @NotNull Set register(final @NotNull LiteralCommandNode node) { ++ return this.register(node, null, Collections.emptyList()); ++ } ++ ++ /** ++ * Registers a command for the current plugin context. ++ * ++ *

Commands have certain overriding behavior: ++ *

    ++ *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • ++ *
  • The main command/namespaced label will override already existing commands
  • ++ *
++ * ++ * @param node the built literal command node ++ * @param description the help description for the root literal node ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ default @Unmodifiable @NotNull Set register(final @NotNull LiteralCommandNode node, final @Nullable String description) { ++ return this.register(node, description, Collections.emptyList()); ++ } ++ ++ /** ++ * Registers a command for the current plugin context. ++ * ++ *

Commands have certain overriding behavior: ++ *

    ++ *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • ++ *
  • The main command/namespaced label will override already existing commands
  • ++ *
++ * ++ * @param node the built literal command node ++ * @param aliases a collection of aliases to register the literal node's command to ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ default @Unmodifiable @NotNull Set register(final @NotNull LiteralCommandNode node, final @NotNull Collection aliases) { ++ return this.register(node, null, aliases); ++ } ++ ++ /** ++ * Registers a command for the current plugin context. ++ * ++ *

Commands have certain overriding behavior: ++ *

    ++ *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • ++ *
  • The main command/namespaced label will override already existing commands
  • ++ *
++ * ++ * @param node the built literal command node ++ * @param description the help description for the root literal node ++ * @param aliases a collection of aliases to register the literal node's command to ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ @Unmodifiable @NotNull Set register(@NotNull LiteralCommandNode node, @Nullable String description, @NotNull Collection aliases); ++ ++ /** ++ * Registers a command for a plugin. ++ * ++ *

Commands have certain overriding behavior: ++ *

    ++ *
  • Aliases will not override already existing commands (excluding namespaced ones)
  • ++ *
  • The main command/namespaced label will override already existing commands
  • ++ *
++ * ++ * @param pluginMeta the owning plugin's meta ++ * @param node the built literal command node ++ * @param description the help description for the root literal node ++ * @param aliases a collection of aliases to register the literal node's command to ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ @Unmodifiable @NotNull Set register(@NotNull PluginMeta pluginMeta, @NotNull LiteralCommandNode node, @Nullable String description, @NotNull Collection aliases); ++ ++ /** ++ * This allows configuring the registration of your command, which is not intended for public use. ++ * See {@link Commands#register(PluginMeta, LiteralCommandNode, String, Collection)} for more information. ++ * ++ * @param pluginMeta the owning plugin's meta ++ * @param node the built literal command node ++ * @param description the help description for the root literal node ++ * @param aliases a collection of aliases to register the literal node's command to ++ * @param flags a collection of registration flags that control registration behaviour. ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ * ++ * @apiNote This method is not guaranteed to be stable as it is not intended for public use. ++ * See {@link CommandRegistrationFlag} for a more indepth explanation of this method's use-case. ++ */ ++ @ApiStatus.Internal ++ @Unmodifiable @NotNull Set registerWithFlags(@NotNull PluginMeta pluginMeta, @NotNull LiteralCommandNode node, @Nullable String description, @NotNull Collection aliases, @NotNull Set flags); ++ ++ /** ++ * Registers a command under the same logic as {@link Commands#register(LiteralCommandNode, String, Collection)}. ++ * ++ * @param label the label of the to-be-registered command ++ * @param basicCommand the basic command instance to register ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ default @Unmodifiable @NotNull Set register(final @NotNull String label, final @NotNull BasicCommand basicCommand) { ++ return this.register(label, null, Collections.emptyList(), basicCommand); ++ } ++ ++ /** ++ * Registers a command under the same logic as {@link Commands#register(LiteralCommandNode, String, Collection)}. ++ * ++ * @param label the label of the to-be-registered command ++ * @param description the help description for the root literal node ++ * @param basicCommand the basic command instance to register ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ default @Unmodifiable @NotNull Set register(final @NotNull String label, final @Nullable String description, final @NotNull BasicCommand basicCommand) { ++ return this.register(label, description, Collections.emptyList(), basicCommand); ++ } ++ ++ /** ++ * Registers a command under the same logic as {@link Commands#register(LiteralCommandNode, String, Collection)}. ++ * ++ * @param label the label of the to-be-registered command ++ * @param aliases a collection of aliases to register the basic command under. ++ * @param basicCommand the basic command instance to register ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ default @Unmodifiable @NotNull Set register(final @NotNull String label, final @NotNull Collection aliases, final @NotNull BasicCommand basicCommand) { ++ return this.register(label, null, aliases, basicCommand); ++ } ++ ++ /** ++ * Registers a command under the same logic as {@link Commands#register(LiteralCommandNode, String, Collection)}. ++ * ++ * @param label the label of the to-be-registered command ++ * @param description the help description for the root literal node ++ * @param aliases a collection of aliases to register the basic command under. ++ * @param basicCommand the basic command instance to register ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ @Unmodifiable @NotNull Set register(@NotNull String label, @Nullable String description, @NotNull Collection aliases, @NotNull BasicCommand basicCommand); ++ ++ /** ++ * Registers a command under the same logic as {@link Commands#register(PluginMeta, LiteralCommandNode, String, Collection)}. ++ * ++ * @param pluginMeta the owning plugin's meta ++ * @param label the label of the to-be-registered command ++ * @param description the help description for the root literal node ++ * @param aliases a collection of aliases to register the basic command under. ++ * @param basicCommand the basic command instance to register ++ * @return successfully registered root command labels (including aliases and namespaced variants) ++ */ ++ @Unmodifiable @NotNull Set register(@NotNull PluginMeta pluginMeta, @NotNull String label, @Nullable String description, @NotNull Collection aliases, @NotNull BasicCommand basicCommand); ++} +diff --git a/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializer.java b/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializer.java +new file mode 100644 +index 0000000000000000000000000000000000000000..57061a3dd738416c2045e641b6080dc3f096de1a +--- /dev/null ++++ b/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializer.java +@@ -0,0 +1,24 @@ ++package io.papermc.paper.command.brigadier; ++ ++import com.mojang.brigadier.Message; ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.serializer.ComponentSerializer; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++/** ++ * A component serializer for converting between {@link Message} and {@link Component}. ++ */ ++@ApiStatus.Experimental ++@ApiStatus.NonExtendable ++public interface MessageComponentSerializer extends ComponentSerializer { ++ ++ /** ++ * A component serializer for converting between {@link Message} and {@link Component}. ++ * ++ * @return serializer instance ++ */ ++ static @NotNull MessageComponentSerializer message() { ++ return MessageComponentSerializerHolder.PROVIDER.orElseThrow(); ++ } ++} +diff --git a/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializerHolder.java b/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializerHolder.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2db12952461c92a64505d6646f6f49f824e83050 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/command/brigadier/MessageComponentSerializerHolder.java +@@ -0,0 +1,12 @@ ++package io.papermc.paper.command.brigadier; ++ ++import java.util.Optional; ++import java.util.ServiceLoader; ++import org.jetbrains.annotations.ApiStatus; ++ ++@ApiStatus.Internal ++final class MessageComponentSerializerHolder { ++ ++ static final Optional PROVIDER = ServiceLoader.load(MessageComponentSerializer.class) ++ .findFirst(); ++} +diff --git a/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java b/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1d5c599d1b9c8bf07720e651bdbe9dadb1335b45 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/command/brigadier/argument/ArgumentTypes.java +@@ -0,0 +1,349 @@ ++package io.papermc.paper.command.brigadier.argument; ++ ++import com.mojang.brigadier.arguments.ArgumentType; ++import io.papermc.paper.command.brigadier.argument.predicate.ItemStackPredicate; ++import io.papermc.paper.command.brigadier.argument.range.DoubleRangeProvider; ++import io.papermc.paper.command.brigadier.argument.range.IntegerRangeProvider; ++import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver; ++import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver; ++import io.papermc.paper.command.brigadier.argument.resolvers.selector.EntitySelectorArgumentResolver; ++import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; ++import io.papermc.paper.entity.LookAnchor; ++import io.papermc.paper.registry.RegistryKey; ++import io.papermc.paper.registry.TypedKey; ++import java.util.UUID; ++import net.kyori.adventure.key.Key; ++import net.kyori.adventure.text.Component; ++import net.kyori.adventure.text.format.NamedTextColor; ++import net.kyori.adventure.text.format.Style; ++import org.bukkit.GameMode; ++import org.bukkit.HeightMap; ++import org.bukkit.NamespacedKey; ++import org.bukkit.World; ++import org.bukkit.block.BlockState; ++import org.bukkit.block.structure.Mirror; ++import org.bukkit.block.structure.StructureRotation; ++import org.bukkit.inventory.ItemStack; ++import org.bukkit.scoreboard.Criteria; ++import org.bukkit.scoreboard.DisplaySlot; ++import org.jetbrains.annotations.ApiStatus; ++import org.jetbrains.annotations.NotNull; ++ ++import static io.papermc.paper.command.brigadier.argument.VanillaArgumentProvider.provider; ++ ++/** ++ * Vanilla Minecraft includes several custom {@link ArgumentType}s that are recognized by the client. ++ * Many of these argument types include client-side completions and validation, and some include command signing context. ++ * ++ *

This class allows creating instances of these types for use in plugin commands, with friendly API result types.

++ * ++ *

{@link CustomArgumentType} is provided for customizing parsing or result types server-side, while sending the vanilla argument type to the client.

++ */ ++@ApiStatus.Experimental ++public final class ArgumentTypes { ++ ++ /** ++ * Represents a selector that can capture any ++ * single entity. ++ * ++ * @return argument that takes one entity ++ */ ++ public static @NotNull ArgumentType entity() { ++ return provider().entity(); ++ } ++ ++ /** ++ * Represents a selector that can capture multiple ++ * entities. ++ * ++ * @return argument that takes multiple entities ++ */ ++ public static @NotNull ArgumentType entities() { ++ return provider().entities(); ++ } ++ ++ /** ++ * Represents a selector that can capture a ++ * singular player entity. ++ * ++ * @return argument that takes one player ++ */ ++ public static @NotNull ArgumentType player() { ++ return provider().player(); ++ } ++ ++ /** ++ * Represents a selector that can capture multiple ++ * player entities. ++ * ++ * @return argument that takes multiple players ++ */ ++ public static @NotNull ArgumentType players() { ++ return provider().players(); ++ } ++ ++ /** ++ * A selector argument that provides a list ++ * of player profiles. ++ * ++ * @return player profile arguments ++ */ ++ public static @NotNull ArgumentType playerProfiles() { ++ return provider().playerProfiles(); ++ } ++ ++ /** ++ * A block position argument. ++ * ++ * @return argument ++ */ ++ public static @NotNull ArgumentType blockPosition() { ++ return provider().blockPosition(); ++ } ++ ++ /** ++ * A blockstate argument which will provide rich parsing for specifying ++ * the specific block variant and then the block entity NBT if applicable. ++ * ++ * @return argument ++ */ ++ public static @NotNull ArgumentType blockState() { ++ return provider().blockState(); ++ } ++ ++ /** ++ * An ItemStack argument which provides rich parsing for ++ * specifying item material and item NBT information. ++ * ++ * @return argument ++ */ ++ public static @NotNull ArgumentType itemStack() { ++ return provider().itemStack(); ++ } ++ ++ /** ++ * An item predicate argument. ++ * ++ * @return argument ++ */ ++ public static @NotNull ArgumentType itemPredicate() { ++ return provider().itemStackPredicate(); ++ } ++ ++ /** ++ * An argument for parsing {@link NamedTextColor}s. ++ * ++ * @return argument ++ */ ++ public static @NotNull ArgumentType namedColor() { ++ return provider().namedColor(); ++ } ++ ++ /** ++ * A component argument. ++ * ++ * @return argument ++ */ ++ public static @NotNull ArgumentType component() { ++ return provider().component(); ++ } ++ ++ /** ++ * A style argument. ++ * ++ * @return argument ++ */ ++ public static @NotNull ArgumentType