Compare commits

..
Author SHA1 Message Date
Lulu13022002 6483f4fc43 add back inconsistent tags for compat 2025-02-25 17:41:27 +01:00
Lulu13022002 d8cf62ae9c Generators 2025-02-25 17:23:35 +01:00
Spottedleaf 636ae0cd87 Add missing Paper comments to player movement patch 2025-02-24 21:32:39 -08:00
Jason Penilla fcb2e81590 Clear lastSection on game event listener removal
Fixes https://github.com/Tuinity/Moonrise/issues/87

See comments in code
2025-02-24 21:32:39 -08:00
bonanandTamion e5a8ee849f Hide soul speed particles for vanished players (#12152)
Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com>
2025-02-21 12:02:32 +01:00
Bjarne Koll 7b4d44f573 Revert "Always pass event block to damage source (#12158)"
This reverts commit ab984a0711.

The block damage is null *and has been* null in cases where the block
has already been cleared. Consumers are supposed to use the
getDamagerBlockState instead.
2025-02-21 11:52:04 +01:00
Bjarne Koll ab984a0711 Always pass event block to damage source (#12158)
Always passes the respective block to a damage source when passing a
block state. While we could technically use the damageSourcePosition
here by, we'd have to translate it back to a block position by
subtracting .5 from all its components.
Such behaviour however relies on the caller logic's mutation of the
damageSourcePosition and will break once this position is not the centre
of the block.

Passing in the block at the specific callsite is a lot more future
proof.
2025-02-20 20:22:46 +01:00
Emilia Kond 5e2a3bc0e2 Call EntityChangeBlockEvent with correct block when waxing (#12154) 2025-02-20 10:46:11 +01:00
Warrior edda0db18b Fix server crash when no enchantments are present (#12149) 2025-02-18 15:44:52 +01:00
Warrior 09f1f88f58 Fix getForwards/SidewaysMovement for players (#12140) 2025-02-18 01:03:48 +01:00
Jake Potrebic f070081825 Remove Experimental from TypedKey (#12134) 2025-02-17 15:33:26 -08:00
Jake Potrebic b386a8f527 Add simpler JavaPlugin command registration (#12142) 2025-02-18 00:21:29 +01:00
Epic e494f2894e Correctly call BlockFadeEvents (#12141) 2025-02-18 00:19:30 +01:00
Bjarne Koll 142695eb00 Default minecraft alias to redirect (#12146)
While the running server will still be using the recently introduced
copy-mechanic for vanilla command namespacing, the data converter logic
relies on the fact that namespaced aliases were redirects as well.

To not break the converted, the commands type now takes a modern flag
only set by the running server.
2025-02-18 00:09:54 +01:00
Jake Potrebic d26a9e90c8 Fix plugin commands (#12144) 2025-02-17 15:00:06 -08:00
Bjarne Koll 3b9106c7d1 Readd dead redirect recovery (#12136)
While the paper command system no longer uses redirects for namespaced
registration, vanilla still does. This means that removal of vanilla
redirecting target nodes still causes issues, e.g. the removal of the
vanilla 'msg' node in favour of a command alias one.
Redirecting nodes like tell, minecraft:msg and minecraft:tell are broken
by this and need to by flattened before sending them to the client.
2025-02-17 23:51:52 +01:00
Dqu1J fd69140d80 Fix disable-tripwire-updates option not cancelling tripwire hook updates (#12129) 2025-02-17 20:07:02 +01:00
Miles 8eb8e44ac3 Allow For Default Titles in InventoryView Builders (#12013) 2025-02-16 23:07:00 +01:00
Jake Potrebic 84609dc046 Don't auto-create any brig redirects (#11954) 2025-02-16 13:55:27 -08:00
FlorianMichael 88cdd22076 Fixup luck and random implementation in CB loot-tables (#11926) 2025-02-16 13:06:01 -08:00
Warrior b27e11cce6 Fix bad world to chunk coordinate example in javadocs (#12131) 2025-02-16 13:04:15 -08:00
Tamion 60394c5b98 Fix PlayerReadyArrowEvent cancellation desync (#12111) 2025-02-16 21:44:08 +01:00
Jake Potrebic 28d07dc5ab use correct spigot plugin count 2025-02-16 12:18:29 -08:00
Pedro 06f96dd655 Improvement in /plugins command (#12121) 2025-02-16 12:10:45 -08:00
TonytheMacaroni 2a4a115432 Add EntityEquipmentChangedEvent (#12011) 2025-02-16 20:46:59 +01:00
Creeam a3781ff3be Separate tick count to ensure vanilla parity (#12077) 2025-02-16 20:46:37 +01:00
Chaosdave34 b9023b5dc3 Add EntityAttemptSmashAttackEvent (#12113) 2025-02-16 20:19:28 +01:00
Lulu13022002 7bee99714a Cleanup damage source a bit (#12106) 2025-02-16 20:14:00 +01:00
Jake Potrebic 608f004a2c add method on ItemStack to edit pdc (#12022) 2025-02-16 11:01:37 -08:00
Pedro 00701267c8 [ci skip] improvement example in javadoc for DatapackRegistrar (#12122) 2025-02-16 19:19:42 +01:00
Pedro cb25c0cf31 [ci skip] Fix annotation fields used in NMS getBukkitEntity (#12120) 2025-02-16 19:17:26 +01:00
Warrior a6e82d90ce [ci skip] Clarify getChunkAtAsyncUrgently javadocs (#12125) 2025-02-16 19:13:35 +01:00
masmc05andBjarne Koll 404167841d [ci-skip] Mention missing World#regenerateChunk implementation in jd (#12109)
* Mention missing impl

* Clean the implementation out of years old code

* Change the jd comment

* Move to default method

---------

Co-authored-by: Bjarne Koll <lynxplay101@gmail.com>
2025-02-15 23:31:42 +01:00
Epic c62252e19f Add lore content guard (#12116)
* add content guard

* use preconditions for null check
2025-02-15 23:30:32 +01:00
Space Walker 9b9de82706 Update Alternate Current patch to v1.9.1 (#12115) 2025-02-15 12:40:31 +01:00
David 6cfa2f7f31 [ci skip] Add missing nullability annotation to sendEquipmentChange method (#12112)
Marked ItemStack parameter as `@Nullable` to explicitly indicate it can be null. This improves clarity, avoids nullability problems, and aligns with the method's documented behavior for handling null values.
2025-02-14 18:39:44 +01:00
David 46f4fdaae3 Add support for rotation argument handling (#12090) 2025-02-12 23:30:41 +01:00
Pedro 0680485095 Expand TrialSpawner API (#12025) 2025-02-12 23:24:46 +01:00
Lulu13022002 0a04c3fe22 Fix some NPEs (#12105) 2025-02-12 23:15:37 +01:00
Warrior e616498ed7 Add Vault block API (#12068) 2025-02-12 23:15:22 +01:00
Lulu13022002 a06179a018 Update entity effect (#12104) 2025-02-12 23:14:07 +01:00
Warrior 1be2e5f311 Fix vanilla map decorations sending when not dirty (#12098) 2025-02-12 23:13:34 +01:00
Tamion 072a8317b2 Add proper attached blocks API to AbstractArrow (#12099) 2025-02-12 23:13:07 +01:00
Pedro cf7c6c7483 [ci skip] Fix incomplete example in javadocs for PostFlattenTagRegistrar (#12103) 2025-02-12 11:27:13 +01:00
Pedro db2aa1803d [ci skip] Fix incomplete example in javadocs for PreFlattenTagRegistrar (#12102) 2025-02-12 11:16:40 +01:00
aerulion 13c80a5eb3 [ci skip] Fix PlayerShearBlockEvent javadoc typos (#12101) 2025-02-12 11:06:42 +01:00
David 3bd69f2e56 [ci skip] Enhance javadoc for World#setAutoSave method (#12088)
Clarify that disabling auto-save does not stop all saving operations. This addition explicitly mentions that the world will still save on shutdown and explains the intended purpose of the method.
2025-02-10 23:07:46 +01:00
Owen fa5824e4c8 Add skipTripwireHookPlacementValidation (#12091)
This allows for the configuration of tripwire hook duping.
2025-02-10 23:04:38 +01:00
Dreeam cafef9ce9b [ci skip] Move EntityUtil to correct directory (#12092) 2025-02-10 13:34:52 +01:00
Bjarne Koll edacfdf462 Do not queue player info packets (#12080)
Player info packets carry chat state to other clients since the
introduction of chat signatures. Queuing these packets while force
pushing chat packets allows for potentially inverted packet order, which
may cause chain corruption on clients.
2025-02-09 11:51:11 +01:00
Lulu13022002 eff617b8f8 [ci skip] Deprecate Server#setSpawnRadius (#12024) 2025-02-08 22:10:08 +01:00
Lulu13022002 1a04e96ab7 Fix EntityBreedEvent cancellation (#12046) 2025-02-08 20:59:13 +01:00
Jason Penilla 61312fdb59 Switch to jspecify annotations for Player (#12042)
Fixes compilation issues for plugins from recent API addition with double-annotated parameter (JetBrains annotations are type-use and parameter, so nonnull array of nonnull elements ends up with duplicates)
2025-02-08 20:57:35 +01:00
Lulu13022002 51acc802b8 Prevent duplicate raider in RaidSpawnWaveEvent list (#12040) 2025-02-08 20:55:57 +01:00
Roni Äikäs cb6c57e0f8 Fix Squid and Dolphin spawn height (#12045) 2025-02-08 20:24:07 +01:00
masmc05 786ddf53c6 Default piston block entity direction to DOWN (#12039) 2025-02-08 20:17:45 +01:00
David 53ae5c95b7 Make Sittable interface extend Entity (#12016) 2025-02-08 20:16:23 +01:00
Shane Freeder 597dcfffb9 Add support for lz4 (#12053)
Mojang added this early 2024, however, it wasn't ever added to the actual config option
inside of paper
2025-02-08 19:07:43 +01:00
Warrior 742968e078 [ci skip] Increase outdated build delay to two weeks (#12063) 2025-02-04 18:34:11 +00:00
Warrior 5395ae37bd Fix composter block setting bukkit owner twice (#12058) 2025-02-02 22:38:01 +01:00
Spottedleaf 8927091a08 Do not record movement for vehicles/players unaffected by blocks
If the player is not affected by movement through blocks, then
storing the movement would eventually invoke logic to apply effects
caused by moving through such blocks. For example, moving through
a portal in spectator mode and then later switching to creative mode
would portal the player.
2025-02-02 11:16:59 -08:00
Lulu13022002 e0711af5d5 Deprecate UnsafeValues#getSpawnEggLayerColor (#12041) 2025-01-31 13:17:45 +01:00
Lulu13022002 5bcfb12a99 Fix activation range config and water animal status (#12047) 2025-01-31 13:13:14 +01:00
Lulu13022002 d4a957849c Experimental annotation changes (#12028) 2025-01-30 20:02:14 +01:00
Spottedleaf 54b2e9d973 Add buffer to CraftWorld#warnUnsafeChunk
This allows plugins to access chunks slightly outside of the
max world border (such as ones which may be loaded naturally
by players) without tripping any logs.
2025-01-28 17:43:30 -08:00
Spottedleaf e2f0efd1af Remove nms.Entity#isChunkLoaded
This method was used pre 1.17 era where an Entity was explicitly
tied to a (then called) Chunk's entity slices. If an entity
was not inside a Chunk, then it was considered invalid as
it was not possible to save the entity.

In 1.17+, entities are now tied to a separately tracked entity
section management system. This system is far more reliable now
as it no longer requires a full chunk load to properly track
entities for saving. As a result, an Entity if inside the world
is always attached to some entity chunk section (except in rare
cases in Vanilla which are fixed in Moonrise).

As a result, whether the chunk the entity is in is loaded is no
longer an indication of whether they are tracked in the world
and we can reliably infer that the entity is correctly in the
world through the valid field alone.

Additionally drop the isInWorld() check, as valid=true implies
isInWorld=true. More importantly, the isInWorld() check invokes
getHandle which may trip a thread check on Folia. This will fix
World#getEntities() and friends exploding on Folia.

However, World#getEntities() on Folia still cannot reliably return
all entities in the world as actions such as cross-region
(not cross-world) teleporting will remove entities from the world.
2025-01-28 17:33:48 -08:00
Spottedleaf 1004374a83 Add further information to thread check errors
The entity data is more complete, which will help debug problems
on Folia.
2025-01-28 13:43:34 -08:00
Spottedleaf a392d475c2 Make Watchdog thread extend TickThread
This allows the watchdog thread to be seen as the
primary thread during shutdown, which prevents it
from tripping thread checks in various areas.

Fixes https://github.com/PaperMC/Paper/issues/12030
2025-01-27 16:35:23 -08:00
Spottedleaf 5a34bf0425 Correctly retrun true for empty input shapes in EntityGetter#isUnobstructed
Vanilla will return true for empty shapes, so we should as well.
2025-01-27 13:45:44 -08:00
caramelandBjarne Koll 7e21cb8181 fix PlayerChangedMainHandEvent javadoc (#12020)
* fix PlayerChangedMainHandEvent javadoc

* Obsolete

---------

Co-authored-by: Bjarne Koll <lynxplay101@gmail.com>
2025-01-26 14:00:32 -08:00
masmc05 3af5e77132 Add Player#give (#11995) 2025-01-26 21:19:00 +01:00
EnZaXD fb5b173c6a Add PlayerClientLoadedWorldEvent (#11940) 2025-01-25 21:47:08 +01:00
Pedro 2477f1f6a9 [ci skip] fix and improvements for docs in ConsumeEffect component (#11998) 2025-01-25 21:39:25 +01:00
Warrior ce95b5d653 Use proper default for setting null display background color (#12010) 2025-01-25 21:33:47 +01:00
Creeam 81bb82f521 Fix wrong piston world border check (#12007) 2025-01-25 21:13:21 +01:00
Tamion 939bb7828f Add RayTraceConfigurationBuilder (#11907) 2025-01-25 20:58:16 +01:00
Creeam 336ea9dfeb Check for empty when sending equipment changes (#12008) 2025-01-25 20:04:47 +01:00
Spottedleaf 88bbead13b Flush regionfiles on save configuration option
The windows file system does not write metadata unless
the FileChannel is explicitly flushed with metaData=true.

Note: Setting SYNC (not DSYNC) on the FileChannel does not appear
to write the metadata.

Specifically, we are interested in writing the last modified
timestamp so that fs watchers can detect when RegionFiles are
modified.
2025-01-22 11:55:39 -08:00
TomTom 30046e0410 Fix a rare crash with a concurrent modification of scaled health attributes (#12002) 2025-01-22 18:58:44 +00:00
Bjarne Koll 6b7650d81b Only add goat horn once (#12001) 2025-01-22 18:20:24 +01:00
Pedro 30fdfb1aa1 [ci skip] Fix docs for DamageResistant (#11992) 2025-01-20 15:47:07 +01:00
Pedro 73f7736eb9 Drop patch for MC-273635 fixed in MC 1.21.4 (#11987) 2025-01-18 14:30:13 +01:00
Shane Freeder a35cfe93f9 Correct version of some network related dependencies 2025-01-17 15:31:45 +00:00
Shane Freeder e150ffd272 Add missing final
"muh checkstyle" more like "muh missing style config"
2025-01-17 13:49:38 +00:00
Shane Freeder 938a84fc39 Add missing TagSerializable to GsonDataComponentValue converter (Fixes #11768) 2025-01-17 13:47:28 +00:00
Jason Penilla b1b88cd316 [ci skip] Update paperweight to 2.0.0-beta.14 2025-01-15 12:58:10 -07:00
Nassim Jahnke cd9d6d6998 Allow duplicate relative flags in entity teleport
Fixes #11976
2025-01-15 12:13:58 +01:00
Jason Penilla b6be7cd0ae [ci skip] Move generated API sources to src/generated/java (#11977)
This removes a required patch set for forks.
2025-01-14 21:38:56 -07:00
Bjarne Koll 8e80d4e158 Correctly construct StructureManager 2025-01-14 19:21:52 +01:00
Bjarne Koll 209e5f8580 Readd dropped hunk for ender dragon fight data (#11975)
Dragon fight data should be read from the now split world instead of the
main world level.dat.
Partial hunk was dropped during hardfork.
2025-01-14 19:03:30 +01:00
Bjarne Koll eeec611b9d Fix zombie villager infection chance hunk (#11974)
Dropped during hardfork, now moved to a false-ed out if statement to
prevent dropping in future updates.
2025-01-14 17:15:47 +01:00
Bjarne Koll 9f74858760 [ci skip] Cleanup test plugin 2025-01-14 14:36:30 +01:00
masmc05 e82f7e6bb6 [ci skip] Fix Inventory#setMaxStackSize jd (#11968) 2025-01-14 13:43:28 +01:00
masmc05 85d0040f57 [ci skip] Fix getTemperature javadocs (#11967)
In 1.15 spigot changed the behavior of all temperature methods to always return height adjusted temperature.
Correctly reflect this in the javadocs.
2025-01-14 13:42:34 +01:00
masmc05 c44f891d99 Fix PlayerUseUnknownEntityEvent jd (#11969) 2025-01-14 12:11:20 +01:00
Jake Potrebic fe75eaf09a split direct holder support up from ctor accepting Holder
Enchantment shouldn't support direct holders despite the ctor
accepting a Holder type. We want to limit the types
to ones that are actually used as direct holders in the game
2025-01-13 20:12:13 -08:00
Jake Potrebic 6fde26d7f8 remove .paperassetsroot
No longer needed with new build system
2025-01-13 18:48:51 -08:00
Jason Penilla d69981b611 [ci skip] Remove redundant build configuration
This is already the default path for the reobf mappings patch.
2025-01-13 13:51:40 -07:00
Bjarne KollandTonytheMacaroni 1bb3677651 Remove deprecation from EntityRemoveEvent (#11961)
Bukkits entity remove event is called at a different time than the
existing paper event, specifically it is called after an entity has been
stored during chunk unloads.

This means that, while the bukkit event can have a defined reason, it
does not allow modification to the entity data. In this regard it
differs from the paper implementation and prevents developers from using
the paper event as an alternative.

Co-authored-by: TonytheMacaroni <tonythemacaroni123@gmail.com>
2025-01-13 17:51:58 +01:00
Tamion ab1b312064 Call PlayerItemDamageEvent for tridents (#11899) 2025-01-12 15:29:52 -08:00
Jake Potrebic 5e23d28ad2 Remove entity tag selector tag completion fix (#11964)
The fix was causing too many issues, it really needs a client-side fix
MC-235045
2025-01-12 15:07:24 -08:00
masmc05 3709150bc1 Expose all possible block data states (#11958) 2025-01-12 14:56:56 -08:00
Emily 50c2c59c4e Fix unstable Suggestion comparison by sorting int suggestions before text ones (#11941) 2025-01-12 23:49:29 +01:00
Pedro ad74b673fa Fix client visual desync if cooldown events are cancelled (#11892) 2025-01-12 22:56:11 +01:00
Lulu13022002 2ea6aee343 Deprecate Turtle#isDigging (#11959) 2025-01-12 12:49:25 -08:00
Creeam 86c6308faf Fix locate command dist overflow/underflow (#11956) 2025-01-12 17:55:45 +01:00
caramel 76617ddf43 Add EntityEffectTickEvent (#11838) 2025-01-12 17:50:22 +01:00
Tamion eb4db794eb Make CommandSourceStack respect hidden players (#11898) 2025-01-12 17:50:08 +01:00
Bjarne Koll e5542cfdc3 Hide unnecessary decorated pot data (#11957)
Prevent decorated pots from sending their contents to clients as
contents are not needed for rendering.
2025-01-12 17:49:49 +01:00
Nassim Jahnke 9746d73ade Add back known movement check 2025-01-12 15:29:07 +01:00
masmc05 08ac057fda Rename getPotentialBedLocation to getPotentialRespawnLocation (#11950) 2025-01-12 02:17:46 +01:00
Noah van der Aaandleguan ed75b0e54b Disallow calling JavaPlugin#getCommand during onEnable for Paper plugins (#11914)
Co-authored-by: leguan <longboard.noah@gmail.com>
2025-01-11 22:46:36 +01:00
Strokkur24 c2f24e1567 Feat: Add 'with' methods to CommandSourceStack (#11868) 2025-01-11 13:29:16 -08:00
Miles c94922514a MenuType API addition InventoryView Builders (#11816) 2025-01-11 20:21:24 +01:00
David 775002a357 [ci skip] Remove nullable from SyncedEntityData#packAll (#11949) 2025-01-11 20:03:13 +01:00
Jake Potrebic ac3aaa248b Don't use delayed registries in impl anywhere (#11918) 2025-01-11 20:02:28 +01:00
Tamion 19ddbeff9e Fix InventoryAction wrong for Bundles (#11902) 2025-01-11 19:50:24 +01:00
Miles 79ffcd1536 Fix vanilla parity on enchantable items with no targets (#11896) 2025-01-11 18:44:20 +01:00
Spottedleaf 3ad3fbc19a Update to Concurrentutil 0.0.3 2025-01-11 06:28:56 -08:00
Spottedleaf 3d9ecc4e08 Log thread check parameters when the thread check fails
This provides additional debug information that may be useful.
2025-01-11 04:56:54 -08:00
Shane Bee 3e42518b34 Fix snow accumulating in custom biomes without precipitation (#11854) 2025-01-11 11:10:32 +01:00
SoSeDiK b242f1eb15 Prevent day cycle on the client when using fixed time (#11924) 2025-01-11 10:59:50 +01:00
Owen ea7b961926 Fix MapItem incorectly fetching water biomes on treasure maps (#11936) 2025-01-11 10:49:31 +01:00
Spottedleaf 6316a50dbd Make CraftServer#isPrimaryThread use TickThread check
This diff was accidentally dropped when updating to hard fork.

This diff importantly:
 - Does not return true if the async catcher is disabled
 - Does not return true during shutdown
 - Returns true for any instance of TickThread (enables
   watchdog and Folia threads to be considered main)
2025-01-11 00:13:45 -08:00
Jason Penilla b03d39b5ce [ci skip] Update paperweight to 2.0.0-beta.13 2025-01-10 21:01:17 -07:00
Bjarne Koll 1b38f2810e Fix reading recipes used on furnace (#11947) 2025-01-10 19:49:58 +01:00
Bjarne Koll 400717174e Correct obfuscation of oversized items (#11944) 2025-01-10 14:38:50 +01:00
Pedro 5e14504f20 [ci skip] Add missing deprecated docs for isEnabledByFeature (#11938) 2025-01-09 21:08:28 +01:00
spring-dependency-management 08fc33ca03 Update CustomTimingsHandler Nag Message (#11923) 2025-01-09 19:02:03 +01:00
55f3f280cb Reimplement ItemStack Obfuscation (#11817)
Reimplementation of the itemstack obfuscation config that
leverages the component patch map codec to drop
unwanted components on items or replaces them with
sanitized versions.

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
2025-01-09 18:58:18 +01:00
Isaac - The456 efdcaa25ee Fix removing the "LootTable" nbt tag from Block entities (#11929)
This bug affects vanilla, and was reported as MC-279196
2025-01-09 18:44:50 +01:00
Warrior b34ae4fb3c Fix wolves ignoring result of damage event (#11932) 2025-01-08 21:46:58 +01:00
Lulu13022002 49d15f6345 Fix DiscoveredDatapack#getSource (#11928) 2025-01-07 19:40:45 +01:00
Warrior 337557044e Fix MapCanvas#drawImage (#11865) 2025-01-07 13:54:34 +01:00
Jake Potrebic 486e521105 Re-add droped MapLike spam fix (#11917) 2025-01-05 19:07:35 +01:00
Tamion 9f90b4c324 Fix ItemDamageEvents called for 0 damage (#11900) 2025-01-04 21:54:40 +01:00
Pedro f367f107cf Add rotation helpers to Location (#11908) 2025-01-04 21:54:27 +01:00
Pedro 33a590bca6 Fix TargetHitEvent#getSignalStrength() post-hard-fork (#11897) 2025-01-04 21:30:41 +01:00
ChromMob 6ab13521b7 Improve performance of PoiCompetitorScan by unrolling stream (#11871) 2025-01-04 21:23:21 +01:00
Shane Bee 4106da712c Fix retain passengers teleport flag (#11858) 2025-01-04 21:19:07 +01:00
Pedro edde7264c6 [ci skip] Add missing Nullable annotations for NMS DamageSource (#11875) 2025-01-03 11:22:20 -08:00
Hannes Greule daddcf6742 Fix JOML javadoc URL (#11883) 2025-01-02 08:15:47 +00:00
Noah van der Aa 83995d7e80 Fix settings changes not being saved (#11881)
Closes #11878
2025-01-01 21:56:23 +01:00
Nassim Jahnke 1dd52bed49 Use playerlist whitelist status instead of properties
The actual property value is final, only the serialized output is changed. This uses the correct value from PlayerList instead
Fixes #11878
2025-01-01 18:53:23 +01:00
powercas_gamer bdfad1c838 Add sendRich/PlainMessage methods to Server (#11872) 2024-12-31 19:47:57 -05:00
Jason Penilla 9298f593b7 Update paperweight to 2.0.0-beta.10 2024-12-30 12:35:18 -08:00
David 1e4669e8be [ci skip] Clarify loot table behavior when set to null. (#11861)
Updated documentation to specify that setting a null loot table resets it to its default behavior.
2024-12-30 11:07:40 +01:00
Nassim Jahnke a81990e0e8 Update mache, fixes dev bundle use with Java 23 2024-12-30 11:04:58 +01:00
Nicolas RAYNAUD 60edd611f2 [ci skip] Fix spelling of ignition's word into javadoc (#11864) 2024-12-29 22:30:51 +01:00
Jake Potrebic d00344af65 update jb annotations to 26.0.1 (#11860) 2024-12-29 06:53:38 -08:00
Bjarne Koll 887f3f74d1 [ci skip] Replace FQN with import in EventExecutor 2024-12-29 00:34:45 +01:00
Hannes Greule 287eb52fa4 Use hidden classes for event executors (#11848)
Static final MethodHandles perform similar to direct calls. Additionally,
hidden classes simplify logic around ClassLoaders as they can be defined
weakly coupled to their defining class loader. All variants of methods
(static, private, non-void) can be covered by this mechanism.
2024-12-29 00:11:09 +01:00
Strokkur24 93a3df085c Extend HumanEntity#dropItem API (#11810) 2024-12-28 23:47:21 +01:00
Jake Potrebic 18da1ae4c0 [ci skip] update DiscoveredDatapack javadoc 2024-12-28 13:49:11 -08:00
Jake Potrebic feb8756567 Add datapack registration lifecycle event (#11804) 2024-12-28 13:30:43 -08:00
Bjarne Koll dac977a106 Correctly force particles (#11850) 2024-12-28 16:42:11 +01:00
Bjarne Koll e0abc5f85d Do not spawn fire for visual lightning (#11845) 2024-12-28 14:58:22 +01:00
Jake Potrebic 0629524cb2 Directly build Art (#11813) 2024-12-27 16:07:48 -08:00
Bjarne Koll 33411ec0a1 Properly remove UnsafeValues#getDamageEffect 2024-12-28 00:21:27 +01:00
Chaosdave34 5c7537cb5c Add DamageType RegistryEvent (#11783) 2024-12-28 00:13:27 +01:00
Warrior 4b893907f6 Fix contextual map renderer memory leak (#11841) 2024-12-27 23:25:02 +01:00
Jake Potrebic b4051dbff7 Handle disabled vanilla registry values correctly (#11781) 2024-12-27 23:11:26 +01:00
Bjarne Koll e10dcbf7ca [ci skip] Improve build workflow conditions (#11842)
The goal of the build workflow is split into multiple requirements.
  1. Run on pushes to same repo.
  2. Run on PR open/reopen/syncs from repos that are not the same
     (PRs from the same repo are covered by 1)
  3. Run on labeled PRs that have the build-pr-jar flag.
2024-12-27 22:43:08 +01:00
Jake Potrebic ca8709b30f Fix more incorrect array nullability annotations (#11836) 2024-12-27 22:24:16 +01:00
96DarkCode96 13c94e40ad Updated adventure to 4.18.0 (#11809) 2024-12-27 22:04:17 +01:00
Nassim Jahnke 326c687047 Fix whack diff from last commit 2024-12-27 13:47:25 +01:00
Nassim Jahnke 2b73d1957c More var name fixes 2024-12-27 13:45:04 +01:00
Nassim Jahnke c530c39f4e More var name fixes 2024-12-27 12:31:54 +01:00
Jake Potrebic a5b8df6674 add tagkey file for entity type (#11832) 2024-12-26 16:49:07 -08:00
kokiriglade 953f6f929e Banner pattern registry modification (#11803) 2024-12-26 18:57:34 -05:00
SoSeDiK aac246ae29 Expand on entity serialization API (#11807) 2024-12-27 00:08:00 +01:00
YoungSoulluoS 0efd3012c9 Fix suggestions for ResourceLocation (#11830) 2024-12-27 00:07:02 +01:00
1086 changed files with 34957 additions and 28859 deletions

No files matched your search

+19 -12
View File
@@ -1,39 +1,46 @@
root = true
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=true
indent_style=space
indent_size=4
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
ij_any_block_comment_add_space = false
ij_any_block_comment_at_first_column = false
ij_any_line_comment_at_first_column = false
ij_any_line_comment_add_space = true
[*.tiny]
indent_style=tab
indent_style = tab
[*.bat]
end_of_line=crlf
end_of_line = crlf
[*.yml]
indent_size=2
indent_size = 2
[*.patch]
trim_trailing_whitespace=false
trim_trailing_whitespace = false
[*.java]
ij_continuation_indent_size = 4
ij_java_class_count_to_use_import_on_demand = 999999
ij_java_insert_inner_class_imports = false
ij_java_names_count_to_use_import_on_demand = 999999
ij_java_imports_layout = *,|,$*
ij_java_imports_layout = *, |, $*
ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true
ij_java_method_parameters_new_line_after_left_paren = true
ij_java_method_parameters_right_paren_on_new_line = true
ij_java_use_fq_class_names = false
ij_java_class_names_in_javadoc = 1
[paper-server/src/minecraft/java/**/*.java]
ij_java_use_fq_class_names = true
[paper-server/src/minecraft/resources/data/**/*.json]
indent_size = 2
[paper-api-generator/generated/**/*.java]
ij_java_imports_layout = $*,|,*
[paper-{server,api}/src/generated/java/**/*.java]
ij_java_imports_layout = $*, |, *
+11 -2
View File
@@ -16,8 +16,17 @@ on:
jobs:
build:
# Run on all label events (won't be duplicated) or all push events or on PR syncs not from the same repo
if: (github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'build-pr-jar') || github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name
# The goal of the build workflow is split into multiple requirements.
# 1. Run on pushes to same repo.
# 2. Run on PR open/reopen/syncs from repos that are not the same (PRs from the same repo are covered by 1)
# 3. Run on labeled PRs that have the build-pr-jar flag.
if: >
(
(github.event_name == 'push')
|| (github.event_name == 'pull_request' && github.repository != github.event.pull_request.head.repo.full_name && contains(fromJSON('["opened", "reopened", "synchronize"]'), github.event.action))
|| (github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'build-pr-jar')
)
runs-on: ubuntu-latest
strategy:
matrix:
+1 -1
View File
@@ -45,7 +45,7 @@ logs/
!gradle/wrapper/gradle-wrapper.jar
test-plugin.settings.gradle.kts
paper-api-generator.settings.gradle.kts
paper-generator.settings.gradle.kts
# Don't track patched vanilla submodules
paper-server/src/minecraft/
+2 -1
View File
@@ -208,7 +208,8 @@ required.
with `// Paper end - <COMMIT DESCRIPTION>`.
- One-line changes should have `// Paper - <COMMIT DESCRIPTION>` at the end of the line.
> [!NOTE] These comments are incredibly important to be able to keep track of changes
> [!NOTE]
> These comments are incredibly important to be able to keep track of changes
> across files and to remember what they are for, even a decade into the future.
Here's an example of how to mark changes by Paper:
+1 -1
View File
@@ -1,4 +1,4 @@
tiny 2 0 spigot mojang+yarn
tiny 2 0 spigot mojang
# Originally DistanceManager, which also implements DistanceManager, so clashes since the implemented class
# is imported and not fully qualified. Easiest fix is to just change the name
+13
View File
@@ -110,6 +110,8 @@ public net.minecraft.server.network.ServerLoginPacketListenerImpl connection
public net.minecraft.server.network.ServerLoginPacketListenerImpl state
public net.minecraft.server.network.ServerLoginPacketListenerImpl$State
public net.minecraft.server.packs.VanillaPackResourcesBuilder safeGetPath(Ljava/net/URI;)Ljava/nio/file/Path;
public net.minecraft.server.packs.repository.FolderRepositorySource$FolderPackDetector
public net.minecraft.server.packs.repository.FolderRepositorySource$FolderPackDetector <init>(Lnet/minecraft/world/level/validation/DirectoryValidator;)V
public net.minecraft.server.packs.repository.Pack resources
public net.minecraft.server.players.PlayerList playerIo
public net.minecraft.server.players.PlayerList players
@@ -184,6 +186,7 @@ public net.minecraft.world.entity.Entity getEncodeId()Ljava/lang/String;
public net.minecraft.world.entity.Entity getFireImmuneTicks()I
public net.minecraft.world.entity.Entity getSharedFlag(I)Z
public net.minecraft.world.entity.Entity hasVisualFire
public net.minecraft.world.entity.Entity isAffectedByBlocks()Z
public net.minecraft.world.entity.Entity isInBubbleColumn()Z
public net.minecraft.world.entity.Entity isInRain()Z
public net.minecraft.world.entity.Entity isInvulnerableToBase(Lnet/minecraft/world/damagesource/DamageSource;)Z
@@ -194,6 +197,7 @@ public net.minecraft.world.entity.Entity random
public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V
public net.minecraft.world.entity.Entity setRot(FF)V
public net.minecraft.world.entity.Entity setSharedFlag(IZ)V
public net.minecraft.world.entity.Entity teleportPassengers()V
public net.minecraft.world.entity.Entity unsetRemoved()V
public net.minecraft.world.entity.Entity wasTouchingWater
public net.minecraft.world.entity.ExperienceOrb count
@@ -501,6 +505,7 @@ public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG
public net.minecraft.world.item.JukeboxSongPlayer song
public net.minecraft.world.item.MapItem createNewSavedData(Lnet/minecraft/world/level/Level;IIIZZLnet/minecraft/resources/ResourceKey;)Lnet/minecraft/world/level/saveddata/maps/MapId;
public net.minecraft.world.item.StandingAndWallBlockItem wallBlock
public net.minecraft.world.item.component.BundleContents$Mutable getMaxAmountToAdd(Lnet/minecraft/world/item/ItemStack;)I
public net.minecraft.world.item.component.ItemContainerContents MAX_SIZE
public net.minecraft.world.item.component.ItemContainerContents items
public net.minecraft.world.item.context.UseOnContext <init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/phys/BlockHitResult;)V
@@ -620,9 +625,16 @@ public net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity exitPorta
public net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity trialSpawner
public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner isOminous
public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner stateAccessor
public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData cooldownEndsAt
public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData currentMobs
public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData detectedPlayers
public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData nextMobSpawnsAt
public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData nextSpawnData
public net.minecraft.world.level.block.entity.vault.VaultBlockEntity serverData
public net.minecraft.world.level.block.entity.vault.VaultServerData getRewardedPlayers()Ljava/util/Set;
public net.minecraft.world.level.block.entity.vault.VaultServerData pauseStateUpdatingUntil(J)V
public net.minecraft.world.level.block.entity.vault.VaultServerData stateUpdatingResumesAt()J
public net.minecraft.world.level.block.entity.vault.VaultSharedData getConnectedPlayers()Ljava/util/Set;
public net.minecraft.world.level.block.state.BlockBehaviour getMenuProvider(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/MenuProvider;
public net.minecraft.world.level.block.state.BlockBehaviour hasCollision
public net.minecraft.world.level.block.state.BlockBehaviour$BlockStateBase destroySpeed
@@ -721,6 +733,7 @@ public-f net.minecraft.world.item.trading.MerchantOffer rewardExp
public-f net.minecraft.world.item.trading.MerchantOffer xp
public-f net.minecraft.world.level.LevelSettings hardcore
public-f net.minecraft.world.level.LevelSettings levelName
public-f net.minecraft.world.level.block.ChestBlock MENU_PROVIDER_COMBINER
public-f net.minecraft.world.level.block.entity.BannerBlockEntity baseColor
public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner normalConfig
public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner ominousConfig
+1 -1
View File
@@ -10,7 +10,7 @@
# a significant amount of time for us to track down every possible issue, so this file will likely be around and in
# use - at least in some capacity - for a long time.
tiny 2 0 mojang+yarn spigot
tiny 2 0 mojang spigot
# CraftBukkit changes type
c net/minecraft/server/level/ServerLevel net/minecraft/server/level/WorldServer
+1 -1
View File
@@ -12,7 +12,7 @@ import java.nio.file.Path
import kotlin.random.Random
plugins {
id("io.papermc.paperweight.core") version "2.0.0-beta.8" apply false
id("io.papermc.paperweight.core") version "2.0.0-beta.14" apply false
}
subprojects {
-37
View File
@@ -1,37 +0,0 @@
import io.papermc.paperweight.util.defaultJavaLauncher
plugins {
java
id("io.papermc.paperweight.source-generator")
}
paperweight {
atFile.set(layout.projectDirectory.file("wideners.at"))
}
dependencies {
minecraftJar(project(":paper-server", "mappedJarOutgoing"))
implementation(project(":paper-server", "macheMinecraftLibraries"))
implementation("com.squareup:javapoet:1.13.0")
implementation(project(":paper-api"))
implementation("io.github.classgraph:classgraph:4.8.47")
implementation("org.jetbrains:annotations:24.1.0")
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
tasks.register<JavaExec>("generate") {
dependsOn(tasks.check)
mainClass.set("io.papermc.generator.Main")
classpath(sourceSets.main.map { it.runtimeClasspath })
args(projectDir.toPath().resolve("generated").toString())
javaLauncher = javaToolchains.defaultJavaLauncher(project)
}
tasks.test {
useJUnitPlatform()
}
group = "io.papermc.paper"
version = "1.0-SNAPSHOT"
@@ -1,92 +0,0 @@
package io.papermc.generator;
import io.papermc.generator.types.GeneratedKeyType;
import io.papermc.generator.types.GeneratedTagKeyType;
import io.papermc.generator.types.SourceGenerator;
import io.papermc.generator.types.goal.MobGoalGenerator;
import io.papermc.paper.registry.RegistryKey;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import org.bukkit.Art;
import org.bukkit.Fluid;
import org.bukkit.GameEvent;
import org.bukkit.JukeboxSong;
import org.bukkit.MusicInstrument;
import org.bukkit.Sound;
import org.bukkit.attribute.Attribute;
import org.bukkit.block.Biome;
import org.bukkit.block.BlockType;
import org.bukkit.block.banner.PatternType;
import org.bukkit.damage.DamageType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Frog;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Wolf;
import org.bukkit.generator.structure.Structure;
import org.bukkit.generator.structure.StructureType;
import org.bukkit.inventory.ItemType;
import org.bukkit.inventory.MenuType;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.bukkit.inventory.meta.trim.TrimPattern;
import org.bukkit.map.MapCursor;
import org.bukkit.potion.PotionEffectType;
public interface Generators {
SourceGenerator[] API = {
// built-ins
simpleKey("GameEventKeys", GameEvent.class, Registries.GAME_EVENT, RegistryKey.GAME_EVENT, true),
simpleKey("StructureTypeKeys", StructureType.class, Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, false),
simpleKey("MobEffectKeys", PotionEffectType.class, Registries.MOB_EFFECT, RegistryKey.MOB_EFFECT, false),
simpleKey("BlockTypeKeys", BlockType.class, Registries.BLOCK, RegistryKey.BLOCK, false),
simpleKey("ItemTypeKeys", ItemType.class, Registries.ITEM, RegistryKey.ITEM, false),
simpleKey("CatVariantKeys", Cat.Type.class, Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT, false),
simpleKey("FrogVariantKeys", Frog.Variant.class, Registries.FROG_VARIANT, RegistryKey.FROG_VARIANT, false),
simpleKey("VillagerProfessionKeys", Villager.Profession.class, Registries.VILLAGER_PROFESSION, RegistryKey.VILLAGER_PROFESSION, false),
simpleKey("VillagerTypeKeys", Villager.Type.class, Registries.VILLAGER_TYPE, RegistryKey.VILLAGER_TYPE, false),
simpleKey("MapDecorationTypeKeys", MapCursor.Type.class, Registries.MAP_DECORATION_TYPE, RegistryKey.MAP_DECORATION_TYPE, false),
simpleKey("MenuTypeKeys", MenuType.class, Registries.MENU, RegistryKey.MENU, false),
simpleKey("AttributeKeys", Attribute.class, Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE, false),
simpleKey("FluidKeys", Fluid.class, Registries.FLUID, RegistryKey.FLUID, false),
simpleKey("SoundEventKeys", Sound.class, Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT, false),
// data-driven
simpleKey("BiomeKeys", Biome.class, Registries.BIOME, RegistryKey.BIOME, true),
simpleKey("StructureKeys", Structure.class, Registries.STRUCTURE, RegistryKey.STRUCTURE, true),
simpleKey("TrimMaterialKeys", TrimMaterial.class, Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL, true),
simpleKey("TrimPatternKeys", TrimPattern.class, Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN, true),
simpleKey("DamageTypeKeys", DamageType.class, Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE, true),
simpleKey("WolfVariantKeys", Wolf.Variant.class, Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT, true),
simpleKey("EnchantmentKeys", Enchantment.class, Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT, true),
simpleKey("JukeboxSongKeys", JukeboxSong.class, Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG, true),
simpleKey("BannerPatternKeys", PatternType.class, Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN, true),
simpleKey("PaintingVariantKeys", Art.class, Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT, true),
simpleKey("InstrumentKeys", MusicInstrument.class, Registries.INSTRUMENT, RegistryKey.INSTRUMENT, true),
// tags
simpleTagKey("GameEventTagKeys", GameEvent.class, Registries.GAME_EVENT, RegistryKey.GAME_EVENT),
simpleTagKey("BlockTypeTagKeys", BlockType.class, Registries.BLOCK, RegistryKey.BLOCK),
simpleTagKey("ItemTypeTagKeys", ItemType.class, Registries.ITEM, RegistryKey.ITEM),
simpleTagKey("CatVariantTagKeys", Cat.Type.class, Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT),
simpleTagKey("FluidTagKeys", Fluid.class, Registries.FLUID, RegistryKey.FLUID),
simpleTagKey("BiomeTagKeys", Biome.class, Registries.BIOME, RegistryKey.BIOME),
simpleTagKey("StructureTagKeys", Structure.class, Registries.STRUCTURE, RegistryKey.STRUCTURE),
simpleTagKey("DamageTypeTagKeys", DamageType.class, Registries.DAMAGE_TYPE, RegistryKey.DAMAGE_TYPE),
simpleTagKey("EnchantmentTagKeys", Enchantment.class, Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT),
simpleTagKey("BannerPatternTagKeys", PatternType.class, Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN),
simpleTagKey("PaintingVariantTagKeys", Art.class, Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT),
simpleTagKey("InstrumentTagKeys", MusicInstrument.class, Registries.INSTRUMENT, RegistryKey.INSTRUMENT),
new MobGoalGenerator("VanillaGoal", "com.destroystokyo.paper.entity.ai")
};
private static <T, A> SourceGenerator simpleKey(final String className, final Class<A> apiType, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> apiRegistryKey, final boolean publicCreateKeyMethod) {
return new GeneratedKeyType<>(className, apiType, "io.papermc.paper.registry.keys", registryKey, apiRegistryKey, publicCreateKeyMethod);
}
private static <T, A> SourceGenerator simpleTagKey(final String className, final Class<A> apiType, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> apiRegistryKey) {
return new GeneratedTagKeyType<>(className, apiType, "io.papermc.paper.registry.keys.tags", registryKey, apiRegistryKey, true);
}
}
@@ -1,93 +0,0 @@
package io.papermc.generator;
import com.google.common.util.concurrent.MoreExecutors;
import com.mojang.logging.LogUtils;
import io.papermc.generator.types.SourceGenerator;
import io.papermc.generator.utils.TagCollector;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import net.minecraft.SharedConstants;
import net.minecraft.commands.Commands;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.LayeredRegistryAccess;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.resources.RegistryDataLoader;
import net.minecraft.server.Bootstrap;
import net.minecraft.server.RegistryLayer;
import net.minecraft.server.ReloadableServerResources;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.repository.Pack;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.server.packs.repository.ServerPacksSource;
import net.minecraft.server.packs.resources.MultiPackResourceManager;
import net.minecraft.tags.TagKey;
import net.minecraft.tags.TagLoader;
import net.minecraft.world.flag.FeatureFlags;
import org.apache.commons.io.file.PathUtils;
import org.slf4j.Logger;
public final class Main {
private static final Logger LOGGER = LogUtils.getLogger();
public static final RegistryAccess.Frozen REGISTRY_ACCESS;
public static final Map<TagKey<?>, String> EXPERIMENTAL_TAGS;
static {
SharedConstants.tryDetectVersion();
Bootstrap.bootStrap();
Bootstrap.validate();
final PackRepository resourceRepository = ServerPacksSource.createVanillaTrustedRepository();
resourceRepository.reload();
final MultiPackResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, resourceRepository.getAvailablePacks().stream().map(Pack::open).toList());
LayeredRegistryAccess<RegistryLayer> layers = RegistryLayer.createRegistryAccess();
final List<Registry.PendingTags<?>> pendingTags = TagLoader.loadTagsForExistingRegistries(resourceManager, layers.getLayer(RegistryLayer.STATIC));
final List<HolderLookup.RegistryLookup<?>> worldGenLayer = TagLoader.buildUpdatedLookups(layers.getAccessForLoading(RegistryLayer.WORLDGEN), pendingTags);
final RegistryAccess.Frozen frozenWorldgenRegistries = RegistryDataLoader.load(resourceManager, worldGenLayer, RegistryDataLoader.WORLDGEN_REGISTRIES);
layers = layers.replaceFrom(RegistryLayer.WORLDGEN, frozenWorldgenRegistries);
REGISTRY_ACCESS = layers.compositeAccess().freeze();
final ReloadableServerResources reloadableServerResources = ReloadableServerResources.loadResources(
resourceManager,
layers,
pendingTags,
FeatureFlags.VANILLA_SET,
Commands.CommandSelection.DEDICATED,
0,
MoreExecutors.directExecutor(),
MoreExecutors.directExecutor()
).join();
reloadableServerResources.updateStaticRegistryTags();
EXPERIMENTAL_TAGS = TagCollector.grabExperimental(resourceManager);
}
private Main() {
}
public static void main(final String[] args) {
LOGGER.info("Running API generators...");
generate(Paths.get(args[0]), Generators.API);
// LOGGER.info("Running Server generators...");
// generate(Paths.get(args[1]), Generators.SERVER);
}
private static void generate(Path output, SourceGenerator[] generators) {
try {
if (Files.exists(output)) {
PathUtils.deleteDirectory(output);
}
Files.createDirectories(output);
for (final SourceGenerator generator : generators) {
generator.writeToFile(output);
}
LOGGER.info("Files written to {}", output.toAbsolutePath());
} catch (final Exception ex) {
throw new RuntimeException(ex);
}
}
}
@@ -1,207 +0,0 @@
package io.papermc.generator.types;
import com.google.common.collect.Sets;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import io.papermc.generator.Main;
import io.papermc.generator.utils.Annotations;
import io.papermc.generator.utils.CollectingContext;
import io.papermc.generator.utils.Formatting;
import io.papermc.generator.utils.Javadocs;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.lang.model.SourceVersion;
import net.kyori.adventure.key.Key;
import net.minecraft.core.Holder;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.registries.VanillaRegistries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.flag.FeatureElement;
import net.minecraft.world.flag.FeatureFlags;
import org.bukkit.MinecraftExperimental;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier;
import static com.squareup.javapoet.TypeSpec.classBuilder;
import static io.papermc.generator.utils.Annotations.EXPERIMENTAL_API_ANNOTATION;
import static io.papermc.generator.utils.Annotations.experimentalAnnotations;
import static java.util.Objects.requireNonNull;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
@DefaultQualifier(NonNull.class)
public class GeneratedKeyType<T, A> extends SimpleGenerator {
private static final Map<ResourceKey<? extends Registry<?>>, RegistrySetBuilder.RegistryBootstrap<?>> VANILLA_REGISTRY_ENTRIES = VanillaRegistries.BUILDER.entries.stream()
.collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap));
private static final Map<ResourceKey<? extends Registry<?>>, RegistrySetBuilder.RegistryBootstrap<?>> EXPERIMENTAL_REGISTRY_ENTRIES = Map.of(); // Update for Experimental API
private static final Map<RegistryKey<?>, String> REGISTRY_KEY_FIELD_NAMES;
static {
final Map<RegistryKey<?>, String> map = new HashMap<>();
try {
for (final Field field : RegistryKey.class.getFields()) {
if (!Modifier.isStatic(field.getModifiers()) || !Modifier.isFinal(field.getModifiers()) || field.getType() != RegistryKey.class) {
continue;
}
map.put((RegistryKey<?>) field.get(null), field.getName());
}
REGISTRY_KEY_FIELD_NAMES = Map.copyOf(map);
} catch (final ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
private static final String CREATE_JAVADOC = """
Creates a key for {@link $T} in the registry {@code $L}.
@param key the value's key in the registry
@return a new typed key
""";
private final Class<A> apiType;
private final ResourceKey<? extends Registry<T>> registryKey;
private final RegistryKey<A> apiRegistryKey;
private final boolean publicCreateKeyMethod;
public GeneratedKeyType(final String keysClassName, final Class<A> apiType, final String pkg, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> apiRegistryKey, final boolean publicCreateKeyMethod) {
super(keysClassName, pkg);
this.apiType = apiType;
this.registryKey = registryKey;
this.apiRegistryKey = apiRegistryKey;
this.publicCreateKeyMethod = publicCreateKeyMethod;
}
private MethodSpec.Builder createMethod(final TypeName returnType) {
final TypeName keyType = TypeName.get(Key.class);
final ParameterSpec keyParam = ParameterSpec.builder(keyType, "key", FINAL).build();
final MethodSpec.Builder create = MethodSpec.methodBuilder("create")
.addModifiers(this.publicCreateKeyMethod ? PUBLIC : PRIVATE, STATIC)
.addParameter(keyParam)
.addCode("return $T.create($T.$L, $N);", TypedKey.class, RegistryKey.class, requireNonNull(REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey), "Missing field for " + this.apiRegistryKey), keyParam)
.returns(returnType);
if (this.publicCreateKeyMethod) {
create.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO remove once not experimental
create.addJavadoc(CREATE_JAVADOC, this.apiType, this.registryKey.location().toString());
}
return create;
}
private TypeSpec.Builder keyHolderType() {
return classBuilder(this.className)
.addModifiers(PUBLIC, FINAL)
.addJavadoc(Javadocs.getVersionDependentClassHeader("{@link $T#$L}"), RegistryKey.class, REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey))
.addAnnotations(Annotations.CLASS_HEADER)
.addMethod(MethodSpec.constructorBuilder()
.addModifiers(PRIVATE)
.build()
);
}
@Deprecated
private static final Map<String, String> JUKEBOX_SONG_NAMES = Map.of(
"5", "FIVE",
"11", "ELEVEN",
"13", "THIRTEEN"
);
@Override
protected TypeSpec getTypeSpec() {
final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType);
final TypeSpec.Builder typeBuilder = this.keyHolderType();
final MethodSpec.Builder createMethod = this.createMethod(typedKey);
final Registry<T> registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey);
final Set<ResourceKey<T>> experimental = this.collectExperimentalKeys(registry);
boolean allExperimental = true;
for (final Holder.Reference<T> reference : registry.listElements().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).toList()) {
final ResourceKey<T> key = reference.key();
final String keyPath = key.location().getPath();
String fieldName = Formatting.formatKeyAsField(keyPath);
if (!SourceVersion.isIdentifier(fieldName) && this.registryKey.equals(Registries.JUKEBOX_SONG) && JUKEBOX_SONG_NAMES.containsKey(fieldName)) {
fieldName = JUKEBOX_SONG_NAMES.get(fieldName);
}
final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
.initializer("$N(key($S))", createMethod.build(), keyPath)
.addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), key.location().toString());
if (experimental.contains(key)) {
fieldBuilder.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API
} else {
allExperimental = false;
}
typeBuilder.addField(fieldBuilder.build());
}
if (allExperimental) {
typeBuilder.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API
createMethod.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API
} else {
typeBuilder.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO experimental API
}
return typeBuilder.addMethod(createMethod.build()).build();
}
// todo at some point this should be per feature data pack not all merged
private Set<ResourceKey<T>> collectExperimentalKeys(final Registry<T> registry) {
if (FeatureElement.FILTERED_REGISTRIES.contains(registry.key())) {
return this.collectExperimentalKeysBuiltIn(registry);
} else {
return this.collectExperimentalKeysDataDriven(registry);
}
}
private Set<ResourceKey<T>> collectExperimentalKeysBuiltIn(final Registry<T> registry) {
final HolderLookup.RegistryLookup<T> filteredLookup = registry.filterElements(v -> {
return v instanceof final FeatureElement featureElement && FeatureFlags.isExperimental(featureElement.requiredFeatures()); // Update for Experimental API
});
return filteredLookup.listElementIds().collect(Collectors.toUnmodifiableSet());
}
@SuppressWarnings("unchecked")
private Set<ResourceKey<T>> collectExperimentalKeysDataDriven(final Registry<T> registry) {
final RegistrySetBuilder.@Nullable RegistryBootstrap<T> experimentalBootstrap = (RegistrySetBuilder.RegistryBootstrap<T>) EXPERIMENTAL_REGISTRY_ENTRIES.get(this.registryKey);
if (experimentalBootstrap == null) {
return Collections.emptySet();
}
final Set<ResourceKey<T>> experimental = Collections.newSetFromMap(new IdentityHashMap<>());
final CollectingContext<T> experimentalCollector = new CollectingContext<>(experimental, registry);
experimentalBootstrap.run(experimentalCollector);
final RegistrySetBuilder.@Nullable RegistryBootstrap<T> vanillaBootstrap = (RegistrySetBuilder.RegistryBootstrap<T>) VANILLA_REGISTRY_ENTRIES.get(this.registryKey);
if (vanillaBootstrap != null) {
final Set<ResourceKey<T>> vanilla = Collections.newSetFromMap(new IdentityHashMap<>());
final CollectingContext<T> vanillaCollector = new CollectingContext<>(vanilla, registry);
vanillaBootstrap.run(vanillaCollector);
return Sets.difference(experimental, vanilla);
}
return experimental;
}
@Override
protected JavaFile.Builder file(final JavaFile.Builder builder) {
return builder
.addStaticImport(Key.class, "key");
}
}
@@ -1,138 +0,0 @@
package io.papermc.generator.types;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import io.papermc.generator.Main;
import io.papermc.generator.utils.Annotations;
import io.papermc.generator.utils.Formatting;
import io.papermc.generator.utils.Javadocs;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.tag.TagKey;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import net.kyori.adventure.key.Key;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import org.bukkit.MinecraftExperimental;
import static com.squareup.javapoet.TypeSpec.classBuilder;
import static io.papermc.generator.utils.Annotations.EXPERIMENTAL_API_ANNOTATION;
import static io.papermc.generator.utils.Annotations.experimentalAnnotations;
import static java.util.Objects.requireNonNull;
import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
public class GeneratedTagKeyType<T, A> extends SimpleGenerator {
private static final Map<RegistryKey<?>, String> REGISTRY_KEY_FIELD_NAMES;
static {
final Map<RegistryKey<?>, String> map = new HashMap<>();
try {
for (final Field field : RegistryKey.class.getFields()) {
if (!Modifier.isStatic(field.getModifiers()) || !Modifier.isFinal(field.getModifiers()) || field.getType() != RegistryKey.class) {
continue;
}
map.put((RegistryKey<?>) field.get(null), field.getName());
}
REGISTRY_KEY_FIELD_NAMES = Map.copyOf(map);
} catch (final ReflectiveOperationException ex) {
throw new RuntimeException(ex);
}
}
private static final String CREATE_JAVADOC = """
Creates a tag key for {@link $T} in the registry {@code $L}.
@param key the tag key's key
@return a new tag key
""";
private final Class<A> apiType;
private final ResourceKey<? extends Registry<T>> registryKey;
private final RegistryKey<A> apiRegistryKey;
private final boolean publicCreateKeyMethod;
public GeneratedTagKeyType(final String keysClassName, final Class<A> apiType, final String pkg, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> apiRegistryKey, final boolean publicCreateKeyMethod) {
super(keysClassName, pkg);
this.apiType = apiType;
this.registryKey = registryKey;
this.apiRegistryKey = apiRegistryKey;
this.publicCreateKeyMethod = publicCreateKeyMethod;
}
private MethodSpec.Builder createMethod(final TypeName returnType) {
final TypeName keyType = TypeName.get(Key.class);
final ParameterSpec keyParam = ParameterSpec.builder(keyType, "key", FINAL).build();
final MethodSpec.Builder create = MethodSpec.methodBuilder("create")
.addModifiers(this.publicCreateKeyMethod ? PUBLIC : PRIVATE, STATIC)
.addParameter(keyParam)
.addCode("return $T.create($T.$L, $N);", TagKey.class, RegistryKey.class, requireNonNull(REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey), "Missing field for " + this.apiRegistryKey), keyParam)
.returns(returnType);
if (this.publicCreateKeyMethod) {
create.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO remove once not experimental
create.addJavadoc(CREATE_JAVADOC, this.apiType, this.registryKey.location().toString());
}
return create;
}
private TypeSpec.Builder keyHolderType() {
return classBuilder(this.className)
.addModifiers(PUBLIC, FINAL)
.addJavadoc(Javadocs.getVersionDependentClassHeader("{@link $T#$L}"), RegistryKey.class, REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey))
.addAnnotations(Annotations.CLASS_HEADER)
.addMethod(MethodSpec.constructorBuilder()
.addModifiers(PRIVATE)
.build()
);
}
@Override
protected TypeSpec getTypeSpec() {
final TypeName tagKey = ParameterizedTypeName.get(TagKey.class, this.apiType);
final TypeSpec.Builder typeBuilder = this.keyHolderType();
final MethodSpec.Builder createMethod = this.createMethod(tagKey);
final Registry<T> registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey);
final AtomicBoolean allExperimental = new AtomicBoolean(true);
registry.listTagIds().sorted(Formatting.alphabeticKeyOrder(nmsTagKey -> nmsTagKey.location().getPath())).forEach(nmsTagKey -> {
final String fieldName = Formatting.formatKeyAsField(nmsTagKey.location().getPath());
final FieldSpec.Builder fieldBuilder = FieldSpec.builder(tagKey, fieldName, PUBLIC, STATIC, FINAL)
.initializer("$N(key($S))", createMethod.build(), nmsTagKey.location().getPath())
.addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), "#" + nmsTagKey.location());
final String featureFlagName = Main.EXPERIMENTAL_TAGS.get(nmsTagKey);
if (featureFlagName != null) {
fieldBuilder.addAnnotations(experimentalAnnotations(MinecraftExperimental.Requires.valueOf(featureFlagName.toUpperCase(Locale.ENGLISH)))); // Update for Experimental API
} else {
allExperimental.set(false);
}
typeBuilder.addField(fieldBuilder.build());
});
if (allExperimental.get()) {
typeBuilder.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API
createMethod.addAnnotations(experimentalAnnotations(null)); // Update for Experimental API
} else {
typeBuilder.addAnnotation(EXPERIMENTAL_API_ANNOTATION); // TODO experimental API
}
return typeBuilder.addMethod(createMethod.build()).build();
}
@Override
protected JavaFile.Builder file(final JavaFile.Builder builder) {
return builder
.addStaticImport(Key.class, "key");
}
}
@@ -1,65 +0,0 @@
package io.papermc.generator.utils;
import com.squareup.javapoet.AnnotationSpec;
import java.util.ArrayList;
import java.util.List;
import io.papermc.paper.generated.GeneratedFrom;
import net.minecraft.SharedConstants;
import org.bukkit.MinecraftExperimental;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.NullMarked;
public final class Annotations {
public static List<AnnotationSpec> experimentalAnnotations(final MinecraftExperimental.@Nullable Requires requiredFeatureFlag) {
final List<AnnotationSpec> annotationSpecs = new ArrayList<>();
annotationSpecs.add(AnnotationSpec.builder(ApiStatus.Experimental.class).build());
if (requiredFeatureFlag != null) {
annotationSpecs.add(AnnotationSpec.builder(MinecraftExperimental.class)
.addMember("value", "$T.$L", MinecraftExperimental.Requires.class, requiredFeatureFlag.name())
.build());
} else {
annotationSpecs.add(AnnotationSpec.builder(MinecraftExperimental.class).build());
}
return annotationSpecs;
}
public static AnnotationSpec deprecatedVersioned(final @Nullable String version, final boolean forRemoval) {
final AnnotationSpec.Builder annotationSpec = AnnotationSpec.builder(Deprecated.class);
if (forRemoval) {
annotationSpec.addMember("forRemoval", "$L", true);
}
if (version != null) {
annotationSpec.addMember("since", "$S", version);
}
return annotationSpec.build();
}
public static AnnotationSpec scheduledRemoval(final @Nullable String version) {
return AnnotationSpec.builder(ApiStatus.ScheduledForRemoval.class)
.addMember("inVersion", "$S", version)
.build();
}
@ApiStatus.Experimental
public static final AnnotationSpec EXPERIMENTAL_API_ANNOTATION = AnnotationSpec.builder(ApiStatus.Experimental.class).build();
public static final AnnotationSpec NULL_MARKED = AnnotationSpec.builder(NullMarked.class).build();
private static final AnnotationSpec SUPPRESS_WARNINGS = AnnotationSpec.builder(SuppressWarnings.class)
.addMember("value", "$S", "unused")
.addMember("value", "$S", "SpellCheckingInspection")
.build();
private static final AnnotationSpec GENERATED_FROM = AnnotationSpec.builder(GeneratedFrom.class)
.addMember("value", "$S", SharedConstants.getCurrentVersion().getName())
.build();
public static final Iterable<AnnotationSpec> CLASS_HEADER = List.of(
SUPPRESS_WARNINGS,
GENERATED_FROM,
NULL_MARKED
);
private Annotations() {
}
}
@@ -1,59 +0,0 @@
package io.papermc.generator.utils;
import java.util.Optional;
import org.apache.commons.lang3.math.NumberUtils;
import java.util.Comparator;
import java.util.Locale;
import java.util.OptionalInt;
import java.util.function.Function;
import java.util.regex.Pattern;
public final class Formatting {
private static final Pattern ILLEGAL_FIELD_CHARACTERS = Pattern.compile("[.-/]");
public static String formatKeyAsField(String path) {
return ILLEGAL_FIELD_CHARACTERS.matcher(path.toUpperCase(Locale.ROOT)).replaceAll("_");
}
public static Optional<String> formatTagKey(String tagDir, String resourcePath) {
int tagsIndex = resourcePath.indexOf(tagDir);
int dotIndex = resourcePath.lastIndexOf('.');
if (tagsIndex == -1 || dotIndex == -1) {
return Optional.empty();
}
return Optional.of(resourcePath.substring(tagsIndex + tagDir.length() + 1, dotIndex)); // namespace/tags/registry_key/[tag_key].json
}
public static Comparator<String> ALPHABETIC_KEY_ORDER = alphabeticKeyOrder(path -> path);
public static <T> Comparator<T> alphabeticKeyOrder(Function<T, String> mapper) {
return (o1, o2) -> {
String path1 = mapper.apply(o1);
String path2 = mapper.apply(o2);
OptionalInt trailingInt1 = tryParseTrailingInt(path1);
OptionalInt trailingInt2 = tryParseTrailingInt(path2);
if (trailingInt1.isPresent() && trailingInt2.isPresent()) {
return Integer.compare(trailingInt1.getAsInt(), trailingInt2.getAsInt());
}
return path1.compareTo(path2);
};
}
private static OptionalInt tryParseTrailingInt(String path) {
int delimiterIndex = path.lastIndexOf('_');
if (delimiterIndex != -1) {
String score = path.substring(delimiterIndex + 1);
if (NumberUtils.isDigits(score)) {
return OptionalInt.of(Integer.parseInt(score));
}
}
return OptionalInt.empty();
}
private Formatting() {
}
}
@@ -1,27 +0,0 @@
package io.papermc.generator.utils;
public final class Javadocs {
public static String getVersionDependentClassHeader(String headerIdentifier) {
return """
Vanilla keys for %s.
@apiNote The fields provided here are a direct representation of
what is available from the vanilla game source. They may be
changed (including removals) on any Minecraft version
bump, so cross-version compatibility is not provided on the
same level as it is on most of the other API.
""".formatted(headerIdentifier);
}
public static String getVersionDependentField(String headerIdentifier) {
return """
%s
@apiNote This field is version-dependant and may be removed in future Minecraft versions
""".formatted(headerIdentifier);
}
private Javadocs() {
}
}
@@ -1,79 +0,0 @@
package io.papermc.generator.utils;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.mojang.logging.LogUtils;
import io.papermc.generator.Main;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.packs.PackResources;
import net.minecraft.server.packs.PackType;
import net.minecraft.server.packs.repository.BuiltInPackSource;
import net.minecraft.server.packs.resources.MultiPackResourceManager;
import net.minecraft.tags.TagKey;
import org.slf4j.Logger;
// collect all the tags by grabbing the json from the data-packs
// another (probably) way is to hook into the data generator like the typed keys generator
public final class TagCollector {
private static final Logger LOGGER = LogUtils.getLogger();
public static Map<TagKey<?>, String> grabExperimental(final MultiPackResourceManager resourceManager) {
Map<TagKey<?>, String> result = new IdentityHashMap<>();
// collect all vanilla tags
Multimap<ResourceKey<? extends Registry<?>>, String> vanillaTags = HashMultimap.create();
PackResources vanillaPack = resourceManager.listPacks()
.filter(packResources -> packResources.packId().equals(BuiltInPackSource.VANILLA_ID))
.findFirst()
.orElseThrow();
collectFromPack(vanillaPack, (entry, path) -> vanillaTags.put(entry.key(), path));
// then distinct with other data-pack tags to know for sure newly created tags and so experimental one
resourceManager.listPacks().forEach(pack -> {
String packId = pack.packId();
if (packId.equals(BuiltInPackSource.VANILLA_ID)) return;
collectFromPack(pack, (entry, path) -> {
if (vanillaTags.get(entry.key()).contains(path)) {
return;
}
result.put(entry.value().listTagIds()
.filter(tagKey -> tagKey.location().getPath().equals(path))
.findFirst()
.orElseThrow(), packId);
});
});
return Collections.unmodifiableMap(result);
}
private static void collectFromPack(PackResources pack, BiConsumer<RegistryAccess.RegistryEntry<?>, String> output) {
Set<String> namespaces = pack.getNamespaces(PackType.SERVER_DATA);
for (String namespace : namespaces) {
Main.REGISTRY_ACCESS.registries().forEach(entry -> {
// this is probably expensive but can't find another way around and data-pack loader has similar logic
// the issue is that registry key can have parent/key (and custom folder too) but tag key can also have parent/key so parsing become a mess
// without having at least one of the two values
String tagDir = Registries.tagsDirPath(entry.key());
pack.listResources(PackType.SERVER_DATA, namespace, tagDir, (id, supplier) -> {
Formatting.formatTagKey(tagDir, id.getPath()).ifPresentOrElse(path -> output.accept(entry, path), () -> {
LOGGER.warn("Unable to parse the path: {}/{}/{}.json in the data-pack {} into a tag key", namespace, tagDir, id.getPath(), pack.packId());
});
});
});
}
}
private TagCollector() {
}
}
+18 -19
View File
@@ -9,9 +9,9 @@ java {
withJavadocJar()
}
val annotationsVersion = "24.1.0"
val annotationsVersion = "26.0.1"
val bungeeCordChatVersion = "1.20-R0.2"
val adventureVersion = "4.17.0"
val adventureVersion = "4.18.0"
val slf4jVersion = "2.0.9"
val log4jVersion = "2.17.1"
@@ -68,9 +68,6 @@ dependencies {
apiAndDocs("net.kyori:adventure-text-serializer-plain")
apiAndDocs("net.kyori:adventure-text-logger-slf4j")
implementation("org.ow2.asm:asm:9.7.1")
implementation("org.ow2.asm:asm-commons:9.7.1")
api("org.apache.maven:maven-resolver-provider:3.9.6") // make API dependency for Paper Plugins
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
@@ -96,16 +93,16 @@ dependencies {
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
val generatedApiPath: java.nio.file.Path = rootProject.projectDir.toPath().resolve("paper-api-generator/generated")
val generatedDir: java.nio.file.Path = layout.projectDirectory.dir("src/generated/java").asFile.toPath()
idea {
module {
generatedSourceDirs.add(generatedApiPath.toFile())
generatedSourceDirs.add(generatedDir.toFile())
}
}
sourceSets {
main {
java {
srcDir(generatedApiPath)
srcDir(generatedDir)
}
}
}
@@ -179,7 +176,7 @@ tasks.withType<Javadoc> {
"https://guava.dev/releases/33.3.1-jre/api/docs/",
"https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
"https://javadoc.io/doc/org.jetbrains/annotations/$annotationsVersion/",
"https://javadoc.io/doc/org.joml/joml/1.10.8/index.html",
"https://javadoc.io/doc/org.joml/joml/1.10.8/",
"https://www.javadoc.io/doc/com.google.code.gson/gson/2.11.0",
"https://jspecify.dev/docs/api/",
"https://jd.advntr.dev/api/$adventureVersion/",
@@ -231,21 +228,23 @@ tasks.compileTestJava {
options.compilerArgs.add("-parameters")
}
val scanJar = tasks.register("scanJarForBadCalls", io.papermc.paperweight.tasks.ScanJarForBadCalls::class) {
val scanJarForBadCalls by tasks.registering(io.papermc.paperweight.tasks.ScanJarForBadCalls::class) {
badAnnotations.add("Lio/papermc/paper/annotation/DoNotUse;")
jarToScan.set(tasks.jar.flatMap { it.archiveFile })
classpath.from(configurations.compileClasspath)
}
tasks.check {
dependsOn(scanJar)
dependsOn(scanJarForBadCalls)
}
val scanJarForOldGeneratedCode = tasks.register("scanJarForOldGeneratedCode", io.papermc.paperweight.tasks.ScanJarForOldGeneratedCode::class) {
mcVersion.set(providers.gradleProperty("mcVersion"))
annotation.set("Lio/papermc/paper/generated/GeneratedFrom;")
jarToScan.set(tasks.jar.flatMap { it.archiveFile })
classpath.from(configurations.compileClasspath)
}
tasks.check {
dependsOn(scanJarForOldGeneratedCode)
if (providers.gradleProperty("updatingMinecraft").getOrElse("false").toBoolean()) {
val scanJarForOldGeneratedCode by tasks.registering(io.papermc.paperweight.tasks.ScanJarForOldGeneratedCode::class) {
mcVersion.set(providers.gradleProperty("mcVersion"))
annotation.set("Lio/papermc/paper/generated/GeneratedFrom;")
jarToScan.set(tasks.jar.flatMap { it.archiveFile })
classpath.from(configurations.compileClasspath)
}
tasks.check {
dependsOn(scanJarForOldGeneratedCode)
}
}
@@ -66,8 +66,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
public interface VanillaGoal<T extends Mob> extends Goal<T> {
GoalKey<AbstractHorse> RANDOM_STAND = create("random_stand", AbstractHorse.class);
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.attribute.Attribute;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class AttributeKeys {
/**
* {@code minecraft:armor}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.block.banner.PatternType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class BannerPatternKeys {
/**
* {@code minecraft:base}
@@ -332,12 +330,11 @@ public final class BannerPatternKeys {
}
/**
* Creates a key for {@link PatternType} in the registry {@code minecraft:banner_pattern}.
* Creates a typed key for {@link PatternType} in the registry {@code minecraft:banner_pattern}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<PatternType> create(final Key key) {
return TypedKey.create(RegistryKey.BANNER_PATTERN, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.block.Biome;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class BiomeKeys {
/**
* {@code minecraft:badlands}
@@ -486,12 +484,11 @@ public final class BiomeKeys {
}
/**
* Creates a key for {@link Biome} in the registry {@code minecraft:worldgen/biome}.
* Creates a typed key for {@link Biome} in the registry {@code minecraft:worldgen/biome}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<Biome> create(final Key key) {
return TypedKey.create(RegistryKey.BIOME, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.block.BlockType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class BlockTypeKeys {
/**
* {@code minecraft:acacia_button}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.Cat;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class CatVariantKeys {
/**
* {@code minecraft:all_black}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.damage.DamageType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class DamageTypeKeys {
/**
* {@code minecraft:arrow}
@@ -374,12 +372,11 @@ public final class DamageTypeKeys {
}
/**
* Creates a key for {@link DamageType} in the registry {@code minecraft:damage_type}.
* Creates a typed key for {@link DamageType} in the registry {@code minecraft:damage_type}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<DamageType> create(final Key key) {
return TypedKey.create(RegistryKey.DAMAGE_TYPE, key);
}
@@ -0,0 +1,503 @@
package io.papermc.paper.registry.keys;
import static net.kyori.adventure.key.Key.key;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.generated.GeneratedFrom;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#DATA_COMPONENT_TYPE}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
* changed (including removals) on any Minecraft version
* bump, so cross-version compatibility is not provided on the
* same level as it is on most of the other API.
*/
@SuppressWarnings({
"unused",
"SpellCheckingInspection"
})
@NullMarked
@GeneratedFrom("1.21.4")
public final class DataComponentTypeKeys {
/**
* {@code minecraft:attribute_modifiers}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> ATTRIBUTE_MODIFIERS = create(key("attribute_modifiers"));
/**
* {@code minecraft:banner_patterns}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> BANNER_PATTERNS = create(key("banner_patterns"));
/**
* {@code minecraft:base_color}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> BASE_COLOR = create(key("base_color"));
/**
* {@code minecraft:bees}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> BEES = create(key("bees"));
/**
* {@code minecraft:block_entity_data}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> BLOCK_ENTITY_DATA = create(key("block_entity_data"));
/**
* {@code minecraft:block_state}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> BLOCK_STATE = create(key("block_state"));
/**
* {@code minecraft:bucket_entity_data}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> BUCKET_ENTITY_DATA = create(key("bucket_entity_data"));
/**
* {@code minecraft:bundle_contents}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> BUNDLE_CONTENTS = create(key("bundle_contents"));
/**
* {@code minecraft:can_break}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CAN_BREAK = create(key("can_break"));
/**
* {@code minecraft:can_place_on}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CAN_PLACE_ON = create(key("can_place_on"));
/**
* {@code minecraft:charged_projectiles}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CHARGED_PROJECTILES = create(key("charged_projectiles"));
/**
* {@code minecraft:consumable}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CONSUMABLE = create(key("consumable"));
/**
* {@code minecraft:container}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CONTAINER = create(key("container"));
/**
* {@code minecraft:container_loot}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CONTAINER_LOOT = create(key("container_loot"));
/**
* {@code minecraft:creative_slot_lock}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CREATIVE_SLOT_LOCK = create(key("creative_slot_lock"));
/**
* {@code minecraft:custom_data}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CUSTOM_DATA = create(key("custom_data"));
/**
* {@code minecraft:custom_model_data}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CUSTOM_MODEL_DATA = create(key("custom_model_data"));
/**
* {@code minecraft:custom_name}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> CUSTOM_NAME = create(key("custom_name"));
/**
* {@code minecraft:damage}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> DAMAGE = create(key("damage"));
/**
* {@code minecraft:damage_resistant}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> DAMAGE_RESISTANT = create(key("damage_resistant"));
/**
* {@code minecraft:death_protection}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> DEATH_PROTECTION = create(key("death_protection"));
/**
* {@code minecraft:debug_stick_state}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> DEBUG_STICK_STATE = create(key("debug_stick_state"));
/**
* {@code minecraft:dyed_color}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> DYED_COLOR = create(key("dyed_color"));
/**
* {@code minecraft:enchantable}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> ENCHANTABLE = create(key("enchantable"));
/**
* {@code minecraft:enchantment_glint_override}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> ENCHANTMENT_GLINT_OVERRIDE = create(key("enchantment_glint_override"));
/**
* {@code minecraft:enchantments}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> ENCHANTMENTS = create(key("enchantments"));
/**
* {@code minecraft:entity_data}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> ENTITY_DATA = create(key("entity_data"));
/**
* {@code minecraft:equippable}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> EQUIPPABLE = create(key("equippable"));
/**
* {@code minecraft:firework_explosion}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> FIREWORK_EXPLOSION = create(key("firework_explosion"));
/**
* {@code minecraft:fireworks}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> FIREWORKS = create(key("fireworks"));
/**
* {@code minecraft:food}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> FOOD = create(key("food"));
/**
* {@code minecraft:glider}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> GLIDER = create(key("glider"));
/**
* {@code minecraft:hide_additional_tooltip}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> HIDE_ADDITIONAL_TOOLTIP = create(key("hide_additional_tooltip"));
/**
* {@code minecraft:hide_tooltip}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> HIDE_TOOLTIP = create(key("hide_tooltip"));
/**
* {@code minecraft:instrument}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> INSTRUMENT = create(key("instrument"));
/**
* {@code minecraft:intangible_projectile}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> INTANGIBLE_PROJECTILE = create(key("intangible_projectile"));
/**
* {@code minecraft:item_model}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> ITEM_MODEL = create(key("item_model"));
/**
* {@code minecraft:item_name}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> ITEM_NAME = create(key("item_name"));
/**
* {@code minecraft:jukebox_playable}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> JUKEBOX_PLAYABLE = create(key("jukebox_playable"));
/**
* {@code minecraft:lock}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> LOCK = create(key("lock"));
/**
* {@code minecraft:lodestone_tracker}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> LODESTONE_TRACKER = create(key("lodestone_tracker"));
/**
* {@code minecraft:lore}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> LORE = create(key("lore"));
/**
* {@code minecraft:map_color}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> MAP_COLOR = create(key("map_color"));
/**
* {@code minecraft:map_decorations}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> MAP_DECORATIONS = create(key("map_decorations"));
/**
* {@code minecraft:map_id}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> MAP_ID = create(key("map_id"));
/**
* {@code minecraft:map_post_processing}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> MAP_POST_PROCESSING = create(key("map_post_processing"));
/**
* {@code minecraft:max_damage}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> MAX_DAMAGE = create(key("max_damage"));
/**
* {@code minecraft:max_stack_size}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> MAX_STACK_SIZE = create(key("max_stack_size"));
/**
* {@code minecraft:note_block_sound}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> NOTE_BLOCK_SOUND = create(key("note_block_sound"));
/**
* {@code minecraft:ominous_bottle_amplifier}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> OMINOUS_BOTTLE_AMPLIFIER = create(key("ominous_bottle_amplifier"));
/**
* {@code minecraft:pot_decorations}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> POT_DECORATIONS = create(key("pot_decorations"));
/**
* {@code minecraft:potion_contents}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> POTION_CONTENTS = create(key("potion_contents"));
/**
* {@code minecraft:profile}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> PROFILE = create(key("profile"));
/**
* {@code minecraft:rarity}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> RARITY = create(key("rarity"));
/**
* {@code minecraft:recipes}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> RECIPES = create(key("recipes"));
/**
* {@code minecraft:repair_cost}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> REPAIR_COST = create(key("repair_cost"));
/**
* {@code minecraft:repairable}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> REPAIRABLE = create(key("repairable"));
/**
* {@code minecraft:stored_enchantments}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> STORED_ENCHANTMENTS = create(key("stored_enchantments"));
/**
* {@code minecraft:suspicious_stew_effects}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> SUSPICIOUS_STEW_EFFECTS = create(key("suspicious_stew_effects"));
/**
* {@code minecraft:tool}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> TOOL = create(key("tool"));
/**
* {@code minecraft:tooltip_style}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> TOOLTIP_STYLE = create(key("tooltip_style"));
/**
* {@code minecraft:trim}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> TRIM = create(key("trim"));
/**
* {@code minecraft:unbreakable}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> UNBREAKABLE = create(key("unbreakable"));
/**
* {@code minecraft:use_cooldown}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> USE_COOLDOWN = create(key("use_cooldown"));
/**
* {@code minecraft:use_remainder}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> USE_REMAINDER = create(key("use_remainder"));
/**
* {@code minecraft:writable_book_content}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> WRITABLE_BOOK_CONTENT = create(key("writable_book_content"));
/**
* {@code minecraft:written_book_content}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TypedKey<DataComponentType> WRITTEN_BOOK_CONTENT = create(key("written_book_content"));
private DataComponentTypeKeys() {
}
private static TypedKey<DataComponentType> create(final Key key) {
return TypedKey.create(RegistryKey.DATA_COMPONENT_TYPE, key);
}
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.enchantments.Enchantment;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class EnchantmentKeys {
/**
* {@code minecraft:aqua_affinity}
@@ -325,12 +323,11 @@ public final class EnchantmentKeys {
}
/**
* Creates a key for {@link Enchantment} in the registry {@code minecraft:enchantment}.
* Creates a typed key for {@link Enchantment} in the registry {@code minecraft:enchantment}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<Enchantment> create(final Key key) {
return TypedKey.create(RegistryKey.ENCHANTMENT, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.Fluid;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class FluidKeys {
/**
* {@code minecraft:empty}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.Frog;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class FrogVariantKeys {
/**
* {@code minecraft:cold}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.GameEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class GameEventKeys {
/**
* {@code minecraft:block_activate}
@@ -451,12 +449,11 @@ public final class GameEventKeys {
}
/**
* Creates a key for {@link GameEvent} in the registry {@code minecraft:game_event}.
* Creates a typed key for {@link GameEvent} in the registry {@code minecraft:game_event}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<GameEvent> create(final Key key) {
return TypedKey.create(RegistryKey.GAME_EVENT, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.MusicInstrument;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class InstrumentKeys {
/**
* {@code minecraft:admire_goat_horn}
@@ -87,12 +85,11 @@ public final class InstrumentKeys {
}
/**
* Creates a key for {@link MusicInstrument} in the registry {@code minecraft:instrument}.
* Creates a typed key for {@link MusicInstrument} in the registry {@code minecraft:instrument}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<MusicInstrument> create(final Key key) {
return TypedKey.create(RegistryKey.INSTRUMENT, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.inventory.ItemType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class ItemTypeKeys {
/**
* {@code minecraft:acacia_boat}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.JukeboxSong;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class JukeboxSongKeys {
/**
* {@code minecraft:11}
@@ -164,12 +162,11 @@ public final class JukeboxSongKeys {
}
/**
* Creates a key for {@link JukeboxSong} in the registry {@code minecraft:jukebox_song}.
* Creates a typed key for {@link JukeboxSong} in the registry {@code minecraft:jukebox_song}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<JukeboxSong> create(final Key key) {
return TypedKey.create(RegistryKey.JUKEBOX_SONG, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.map.MapCursor;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class MapDecorationTypeKeys {
/**
* {@code minecraft:banner_black}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.inventory.MenuType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class MenuTypeKeys {
/**
* {@code minecraft:anvil}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class MobEffectKeys {
/**
* {@code minecraft:absorption}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.Art;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class PaintingVariantKeys {
/**
* {@code minecraft:alban}
@@ -381,12 +379,11 @@ public final class PaintingVariantKeys {
}
/**
* Creates a key for {@link Art} in the registry {@code minecraft:painting_variant}.
* Creates a typed key for {@link Art} in the registry {@code minecraft:painting_variant}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<Art> create(final Key key) {
return TypedKey.create(RegistryKey.PAINTING_VARIANT, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.Sound;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class SoundEventKeys {
/**
* {@code minecraft:ambient.basalt_deltas.additions}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.generator.structure.Structure;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class StructureKeys {
/**
* {@code minecraft:ancient_city}
@@ -269,12 +267,11 @@ public final class StructureKeys {
}
/**
* Creates a key for {@link Structure} in the registry {@code minecraft:worldgen/structure}.
* Creates a typed key for {@link Structure} in the registry {@code minecraft:worldgen/structure}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<Structure> create(final Key key) {
return TypedKey.create(RegistryKey.STRUCTURE, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.generator.structure.StructureType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class StructureTypeKeys {
/**
* {@code minecraft:buried_treasure}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.inventory.meta.trim.TrimMaterial;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class TrimMaterialKeys {
/**
* {@code minecraft:amethyst}
@@ -108,12 +106,11 @@ public final class TrimMaterialKeys {
}
/**
* Creates a key for {@link TrimMaterial} in the registry {@code minecraft:trim_material}.
* Creates a typed key for {@link TrimMaterial} in the registry {@code minecraft:trim_material}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<TrimMaterial> create(final Key key) {
return TypedKey.create(RegistryKey.TRIM_MATERIAL, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.inventory.meta.trim.TrimPattern;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class TrimPatternKeys {
/**
* {@code minecraft:bolt}
@@ -157,12 +155,11 @@ public final class TrimPatternKeys {
}
/**
* Creates a key for {@link TrimPattern} in the registry {@code minecraft:trim_pattern}.
* Creates a typed key for {@link TrimPattern} in the registry {@code minecraft:trim_pattern}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<TrimPattern> create(final Key key) {
return TypedKey.create(RegistryKey.TRIM_PATTERN, key);
}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.Villager;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class VillagerProfessionKeys {
/**
* {@code minecraft:armorer}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.Villager;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class VillagerTypeKeys {
/**
* {@code minecraft:desert}
@@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.TypedKey;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.Wolf;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
@@ -23,9 +22,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@ApiStatus.Experimental
@GeneratedFrom("1.21.4")
public final class WolfVariantKeys {
/**
* {@code minecraft:ashen}
@@ -94,12 +92,11 @@ public final class WolfVariantKeys {
}
/**
* Creates a key for {@link Wolf.Variant} in the registry {@code minecraft:wolf_variant}.
* Creates a typed key for {@link Wolf.Variant} in the registry {@code minecraft:wolf_variant}.
*
* @param key the value's key in the registry
* @return a new typed key
*/
@ApiStatus.Experimental
public static TypedKey<Wolf.Variant> create(final Key key) {
return TypedKey.create(RegistryKey.WOLF_VARIANT, key);
}
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#BANNER_PATTERN}.
* Vanilla tag keys for {@link RegistryKey#BANNER_PATTERN}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class BannerPatternTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#BIOME}.
* Vanilla tag keys for {@link RegistryKey#BIOME}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class BiomeTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#BLOCK}.
* Vanilla tag keys for {@link RegistryKey#BLOCK}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class BlockTypeTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#CAT_VARIANT}.
* Vanilla tag keys for {@link RegistryKey#CAT_VARIANT}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class CatVariantTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#DAMAGE_TYPE}.
* Vanilla tag keys for {@link RegistryKey#DAMAGE_TYPE}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class DamageTypeTagKeys {
/**
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#ENCHANTMENT}.
* Vanilla tag keys for {@link RegistryKey#ENCHANTMENT}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -24,8 +24,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class EnchantmentTagKeys {
/**
@@ -0,0 +1,288 @@
package io.papermc.paper.registry.keys.tags;
import static net.kyori.adventure.key.Key.key;
import io.papermc.paper.generated.GeneratedFrom;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.tag.TagKey;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla tag keys for {@link RegistryKey#ENTITY_TYPE}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
* changed (including removals) on any Minecraft version
* bump, so cross-version compatibility is not provided on the
* same level as it is on most of the other API.
*/
@SuppressWarnings({
"unused",
"SpellCheckingInspection"
})
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class EntityTypeTagKeys {
/**
* {@code #minecraft:aquatic}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> AQUATIC = create(key("aquatic"));
/**
* {@code #minecraft:arrows}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> ARROWS = create(key("arrows"));
/**
* {@code #minecraft:arthropod}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> ARTHROPOD = create(key("arthropod"));
/**
* {@code #minecraft:axolotl_always_hostiles}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> AXOLOTL_ALWAYS_HOSTILES = create(key("axolotl_always_hostiles"));
/**
* {@code #minecraft:axolotl_hunt_targets}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> AXOLOTL_HUNT_TARGETS = create(key("axolotl_hunt_targets"));
/**
* {@code #minecraft:beehive_inhabitors}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> BEEHIVE_INHABITORS = create(key("beehive_inhabitors"));
/**
* {@code #minecraft:boat}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> BOAT = create(key("boat"));
/**
* {@code #minecraft:can_breathe_under_water}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> CAN_BREATHE_UNDER_WATER = create(key("can_breathe_under_water"));
/**
* {@code #minecraft:can_turn_in_boats}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> CAN_TURN_IN_BOATS = create(key("can_turn_in_boats"));
/**
* {@code #minecraft:deflects_projectiles}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> DEFLECTS_PROJECTILES = create(key("deflects_projectiles"));
/**
* {@code #minecraft:dismounts_underwater}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> DISMOUNTS_UNDERWATER = create(key("dismounts_underwater"));
/**
* {@code #minecraft:fall_damage_immune}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> FALL_DAMAGE_IMMUNE = create(key("fall_damage_immune"));
/**
* {@code #minecraft:freeze_hurts_extra_types}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> FREEZE_HURTS_EXTRA_TYPES = create(key("freeze_hurts_extra_types"));
/**
* {@code #minecraft:freeze_immune_entity_types}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> FREEZE_IMMUNE_ENTITY_TYPES = create(key("freeze_immune_entity_types"));
/**
* {@code #minecraft:frog_food}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> FROG_FOOD = create(key("frog_food"));
/**
* {@code #minecraft:ignores_poison_and_regen}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> IGNORES_POISON_AND_REGEN = create(key("ignores_poison_and_regen"));
/**
* {@code #minecraft:illager}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> ILLAGER = create(key("illager"));
/**
* {@code #minecraft:illager_friends}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> ILLAGER_FRIENDS = create(key("illager_friends"));
/**
* {@code #minecraft:immune_to_infested}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> IMMUNE_TO_INFESTED = create(key("immune_to_infested"));
/**
* {@code #minecraft:immune_to_oozing}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> IMMUNE_TO_OOZING = create(key("immune_to_oozing"));
/**
* {@code #minecraft:impact_projectiles}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> IMPACT_PROJECTILES = create(key("impact_projectiles"));
/**
* {@code #minecraft:inverted_healing_and_harm}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> INVERTED_HEALING_AND_HARM = create(key("inverted_healing_and_harm"));
/**
* {@code #minecraft:no_anger_from_wind_charge}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> NO_ANGER_FROM_WIND_CHARGE = create(key("no_anger_from_wind_charge"));
/**
* {@code #minecraft:non_controlling_rider}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> NON_CONTROLLING_RIDER = create(key("non_controlling_rider"));
/**
* {@code #minecraft:not_scary_for_pufferfish}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> NOT_SCARY_FOR_PUFFERFISH = create(key("not_scary_for_pufferfish"));
/**
* {@code #minecraft:powder_snow_walkable_mobs}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> POWDER_SNOW_WALKABLE_MOBS = create(key("powder_snow_walkable_mobs"));
/**
* {@code #minecraft:raiders}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> RAIDERS = create(key("raiders"));
/**
* {@code #minecraft:redirectable_projectile}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> REDIRECTABLE_PROJECTILE = create(key("redirectable_projectile"));
/**
* {@code #minecraft:sensitive_to_bane_of_arthropods}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> SENSITIVE_TO_BANE_OF_ARTHROPODS = create(key("sensitive_to_bane_of_arthropods"));
/**
* {@code #minecraft:sensitive_to_impaling}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> SENSITIVE_TO_IMPALING = create(key("sensitive_to_impaling"));
/**
* {@code #minecraft:sensitive_to_smite}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> SENSITIVE_TO_SMITE = create(key("sensitive_to_smite"));
/**
* {@code #minecraft:skeletons}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> SKELETONS = create(key("skeletons"));
/**
* {@code #minecraft:undead}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> UNDEAD = create(key("undead"));
/**
* {@code #minecraft:wither_friends}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> WITHER_FRIENDS = create(key("wither_friends"));
/**
* {@code #minecraft:zombies}
*
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
*/
public static final TagKey<EntityType> ZOMBIES = create(key("zombies"));
private EntityTypeTagKeys() {
}
/**
* Creates a tag key for {@link EntityType} in the registry {@code minecraft:entity_type}.
*
* @param key the tag key's key
* @return a new tag key
*/
@ApiStatus.Experimental
public static TagKey<EntityType> create(final Key key) {
return TagKey.create(RegistryKey.ENTITY_TYPE, key);
}
}
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#FLUID}.
* Vanilla tag keys for {@link RegistryKey#FLUID}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class FluidTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#GAME_EVENT}.
* Vanilla tag keys for {@link RegistryKey#GAME_EVENT}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class GameEventTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#INSTRUMENT}.
* Vanilla tag keys for {@link RegistryKey#INSTRUMENT}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class InstrumentTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#ITEM}.
* Vanilla tag keys for {@link RegistryKey#ITEM}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class ItemTypeTagKeys {
/**
@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#PAINTING_VARIANT}.
* Vanilla tag keys for {@link RegistryKey#PAINTING_VARIANT}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -23,8 +23,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class PaintingVariantTagKeys {
/**
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Vanilla keys for {@link RegistryKey#STRUCTURE}.
* Vanilla tag keys for {@link RegistryKey#STRUCTURE}.
*
* @apiNote The fields provided here are a direct representation of
* what is available from the vanilla game source. They may be
@@ -24,8 +24,8 @@ import org.jspecify.annotations.NullMarked;
"unused",
"SpellCheckingInspection"
})
@GeneratedFrom("1.21.4")
@NullMarked
@GeneratedFrom("1.21.4")
@ApiStatus.Experimental
public final class StructureTagKeys {
/**
@@ -1,54 +0,0 @@
package com.destroystokyo.paper.event.executor;
import com.destroystokyo.paper.util.SneakyThrow;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@ApiStatus.Internal
@NullMarked
public class MethodHandleEventExecutor implements EventExecutor {
private final Class<? extends Event> eventClass;
private final MethodHandle handle;
private final @Nullable Method method;
public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final MethodHandle handle) {
this.eventClass = eventClass;
this.handle = handle;
this.method = null;
}
public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
this.eventClass = eventClass;
try {
m.setAccessible(true);
this.handle = MethodHandles.lookup().unreflect(m);
} catch (final IllegalAccessException e) {
throw new AssertionError("Unable to set accessible", e);
}
this.method = m;
}
@Override
public void execute(final Listener listener, final Event event) throws EventException {
if (!this.eventClass.isInstance(event)) return;
try {
this.handle.invoke(listener, event);
} catch (final Throwable t) {
SneakyThrow.sneaky(t);
}
}
@Override
public String toString() {
return "MethodHandleEventExecutor['" + this.method + "']";
}
}
@@ -1,51 +0,0 @@
package com.destroystokyo.paper.event.executor;
import com.destroystokyo.paper.util.SneakyThrow;
import com.google.common.base.Preconditions;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@ApiStatus.Internal
@NullMarked
public class StaticMethodHandleEventExecutor implements EventExecutor {
private final Class<? extends Event> eventClass;
private final MethodHandle handle;
private final Method method;
public StaticMethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
Preconditions.checkArgument(eventClass != null, "eventClass is null");
this.eventClass = eventClass;
try {
m.setAccessible(true);
this.handle = MethodHandles.lookup().unreflect(m);
} catch (final IllegalAccessException e) {
throw new AssertionError("Unable to set accessible", e);
}
this.method = m;
}
@Override
public void execute(final Listener listener, final Event event) throws EventException {
if (!this.eventClass.isInstance(event)) return;
try {
this.handle.invoke(event);
} catch (final Throwable throwable) {
SneakyThrow.sneaky(throwable);
}
}
@Override
public String toString() {
return "StaticMethodHandleEventExecutor['" + this.method + "']";
}
}
@@ -1,59 +0,0 @@
package com.destroystokyo.paper.event.executor.asm;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicInteger;
import org.bukkit.plugin.EventExecutor;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.V1_8;
@ApiStatus.Internal
@NullMarked
public final class ASMEventExecutorGenerator {
private static final String EXECUTE_DESCRIPTOR = "(Lorg/bukkit/event/Listener;Lorg/bukkit/event/Event;)V";
public static byte[] generateEventExecutor(final Method m, final String name) {
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[]{Type.getInternalName(EventExecutor.class)});
// Generate constructor
GeneratorAdapter methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null), ACC_PUBLIC, "<init>", "()V");
methodGenerator.loadThis();
methodGenerator.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V", false); // Invoke the super class (Object) constructor
methodGenerator.returnValue();
methodGenerator.endMethod();
// Generate the execute method
methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "execute", EXECUTE_DESCRIPTOR, null, null), ACC_PUBLIC, "execute", EXECUTE_DESCRIPTOR);
methodGenerator.loadArg(0);
methodGenerator.checkCast(Type.getType(m.getDeclaringClass()));
methodGenerator.loadArg(1);
methodGenerator.checkCast(Type.getType(m.getParameterTypes()[0]));
methodGenerator.visitMethodInsn(m.getDeclaringClass().isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, Type.getInternalName(m.getDeclaringClass()), m.getName(), Type.getMethodDescriptor(m), m.getDeclaringClass().isInterface());
// The only purpose of this switch statement is to generate the correct pop instruction, should the event handler method return something other than void.
// Non-void event handlers will be unsupported in a future release.
switch (Type.getType(m.getReturnType()).getSize()) {
// case 0 is omitted because the only type that has size 0 is void - no pop instruction needed.
case 1 -> methodGenerator.pop(); // handles reference types and most primitives
case 2 -> methodGenerator.pop2(); // handles long and double
}
methodGenerator.returnValue();
methodGenerator.endMethod();
writer.visitEnd();
return writer.toByteArray();
}
public static AtomicInteger NEXT_ID = new AtomicInteger(1);
public static String generateName() {
final int id = NEXT_ID.getAndIncrement();
return "com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor" + id;
}
}
@@ -1,35 +0,0 @@
package com.destroystokyo.paper.event.executor.asm;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@ApiStatus.Internal
@NullMarked
public interface ClassDefiner {
/**
* Returns if the defined classes can bypass access checks
*
* @return if classes bypass access checks
*/
default boolean isBypassAccessChecks() {
return false;
}
/**
* Define a class
*
* @param parentLoader the parent classloader
* @param name the name of the class
* @param data the class data to load
* @return the defined class
* @throws ClassFormatError if the class data is invalid
* @throws NullPointerException if any of the arguments are null
*/
Class<?> defineClass(ClassLoader parentLoader, String name, byte[] data);
static ClassDefiner getInstance() {
return SafeClassDefiner.INSTANCE;
}
}
@@ -1,66 +0,0 @@
package com.destroystokyo.paper.event.executor.asm;
import com.google.common.base.Preconditions;
import com.google.common.collect.MapMaker;
import java.util.concurrent.ConcurrentMap;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@ApiStatus.Internal
@NullMarked
public class SafeClassDefiner implements ClassDefiner {
/* default */ static final SafeClassDefiner INSTANCE = new SafeClassDefiner();
private SafeClassDefiner() {
}
private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new MapMaker().weakKeys().makeMap();
@Override
public Class<?> defineClass(final ClassLoader parentLoader, final String name, final byte[] data) {
final GeneratedClassLoader loader = this.loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
synchronized (loader.getClassLoadingLock(name)) {
Preconditions.checkState(!loader.hasClass(name), "%s already defined", name);
final Class<?> c = loader.define(name, data);
assert c.getName().equals(name);
return c;
}
}
private static class GeneratedClassLoader extends ClassLoader {
static {
ClassLoader.registerAsParallelCapable();
}
protected GeneratedClassLoader(final ClassLoader parent) {
super(parent);
}
private Class<?> define(final String name, final byte[] data) {
synchronized (this.getClassLoadingLock(name)) {
assert !this.hasClass(name);
final Class<?> c = this.defineClass(name, data, 0, data.length);
this.resolveClass(c);
return c;
}
}
@Override
public Object getClassLoadingLock(final String name) {
return super.getClassLoadingLock(name);
}
public boolean hasClass(final String name) {
synchronized (this.getClassLoadingLock(name)) {
try {
Class.forName(name);
return true;
} catch (final ClassNotFoundException e) {
return false;
}
}
}
}
}
@@ -5,6 +5,7 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@@ -16,8 +17,10 @@ import static org.bukkit.Material.*;
* Called when the player themselves change their armor items
* <p>
* Not currently called for environmental factors though it <strong>MAY BE IN THE FUTURE</strong>
* @apiNote Use {@link io.papermc.paper.event.entity.EntityEquipmentChangedEvent} for all entity equipment changes
*/
@NullMarked
@ApiStatus.Obsolete(since = "1.21.4")
public class PlayerArmorChangeEvent extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -38,11 +41,27 @@ public class PlayerArmorChangeEvent extends PlayerEvent {
* Gets the type of slot being altered.
*
* @return type of slot being altered
* @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot. Use {@link #getSlot()} instead.
*/
@Deprecated(since = "1.21.4")
public SlotType getSlotType() {
return this.slotType;
}
/**
* Gets the slot being altered.
*
* @return slot being altered
*/
public EquipmentSlot getSlot() {
return switch (this.slotType) {
case HEAD -> EquipmentSlot.HEAD;
case CHEST -> EquipmentSlot.CHEST;
case LEGS -> EquipmentSlot.LEGS;
case FEET -> EquipmentSlot.FEET;
};
}
/**
* Gets the existing item that's being replaced
*
@@ -70,6 +89,10 @@ public class PlayerArmorChangeEvent extends PlayerEvent {
return HANDLER_LIST;
}
/**
* @deprecated {@link SlotType} does not accurately represent what item types are valid in each slot.
*/
@Deprecated(since = "1.21.4")
public enum SlotType {
HEAD(NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET, DRAGON_HEAD, PIGLIN_HEAD),
CHEST(NETHERITE_CHESTPLATE, DIAMOND_CHESTPLATE, GOLDEN_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA),
@@ -11,7 +11,7 @@ import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Represents an event that is called when a player right-clicks an unknown entity.
* Represents an event that is called when a player clicks an unknown entity.
* Useful for plugins dealing with virtual entities (entities that aren't actually spawned on the server).
* <br>
* This event may be called multiple times per interaction with different interaction hands
@@ -304,8 +304,7 @@ public class PaperServerListPingEvent extends ServerListPingEvent implements Can
return new PlayerIterator();
}
@NotNull
protected Object[] getOnlinePlayers() {
protected @NotNull Object @NotNull [] getOnlinePlayers() {
return Bukkit.getOnlinePlayers().toArray();
}
@@ -0,0 +1,39 @@
package io.papermc.paper;
import net.kyori.adventure.util.Services;
import org.bukkit.damage.DamageEffect;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Static bridge to the server internals.
* <p>
* Any and all methods in here are *not* to be called by plugin developers, may change at any time and may generally
* cause issues when called under unexpected circumstances.
*/
@ApiStatus.Internal
@NullMarked
public interface InternalAPIBridge {
/**
* Yields the instance of this API bridge by lazily requesting it from the java service loader API.
*
* @return the instance.
*/
static InternalAPIBridge get() {
class Holder {
public static final InternalAPIBridge INSTANCE = Services.service(InternalAPIBridge.class).orElseThrow();
}
return Holder.INSTANCE;
}
/**
* Creates a damage effect instance for the passed key.
*
* @param key the string key.
* @return the damage effect.
*/
DamageEffect getDamageEffect(String key);
}
@@ -10,5 +10,10 @@ import org.jetbrains.annotations.ApiStatus;
*/
@ApiStatus.Internal
public enum CommandRegistrationFlag {
/**
* @deprecated This is the default behavior now.
*/
@Deprecated(since = "1.21.4")
FLATTEN_ALIASES
}
@@ -1,5 +1,7 @@
package io.papermc.paper.command.brigadier;
import com.mojang.brigadier.RedirectModifier;
import com.mojang.brigadier.tree.CommandNode;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
@@ -48,4 +50,24 @@ public interface CommandSourceStack {
* @return entity that executes this command
*/
@Nullable Entity getExecutor();
/**
* Creates a new CommandSourceStack object with a different location for redirecting commands to other nodes.
*
* @param location The location to create a new CommandSourceStack object with
* @return The newly created CommandSourceStack
* @see #getLocation()
* @see com.mojang.brigadier.builder.ArgumentBuilder#fork(CommandNode, RedirectModifier)
*/
CommandSourceStack withLocation(Location location);
/**
* Creates a new CommandSourceStack object with a different executor for redirecting commands to other nodes.
*
* @param executor The executing entity to create a new CommandSourceStack object with
* @return The newly created CommandSourceStack
* @see #getExecutor()
* @see com.mojang.brigadier.builder.ArgumentBuilder#fork(CommandNode, RedirectModifier)
*/
CommandSourceStack withExecutor(Entity executor);
}
@@ -113,6 +113,7 @@ public interface Commands extends Registrar {
* <p>Commands have certain overriding behavior:
* <ul>
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
* <li>The main command/namespaced label will override already existing commands</li>
* </ul>
*
@@ -129,6 +130,7 @@ public interface Commands extends Registrar {
* <p>Commands have certain overriding behavior:
* <ul>
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
* <li>The main command/namespaced label will override already existing commands</li>
* </ul>
*
@@ -146,6 +148,7 @@ public interface Commands extends Registrar {
* <p>Commands have certain overriding behavior:
* <ul>
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
* <li>The main command/namespaced label will override already existing commands</li>
* </ul>
*
@@ -163,6 +166,7 @@ public interface Commands extends Registrar {
* <p>Commands have certain overriding behavior:
* <ul>
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
* <li>The main command/namespaced label will override already existing commands</li>
* </ul>
*
@@ -179,6 +183,7 @@ public interface Commands extends Registrar {
* <p>Commands have certain overriding behavior:
* <ul>
* <li>Aliases will not override already existing commands (excluding namespaced ones)</li>
* <li>Aliases are <b>not</b> Brigadier redirects, they just copy the command to a different label</li>
* <li>The main command/namespaced label will override already existing commands</li>
* </ul>
*
@@ -7,6 +7,7 @@ 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.FinePositionResolver;
import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver;
import io.papermc.paper.command.brigadier.argument.resolvers.RotationResolver;
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;
@@ -123,6 +124,15 @@ public final class ArgumentTypes {
return provider().finePosition(centerIntegers);
}
/**
* A rotation argument.
*
* @return rotation argument
*/
public static ArgumentType<RotationResolver> rotation() {
return provider().rotation();
}
/**
* A blockstate argument which will provide rich parsing for specifying
* the specific block variant and then the block entity NBT if applicable.
@@ -7,6 +7,7 @@ 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.FinePositionResolver;
import io.papermc.paper.command.brigadier.argument.resolvers.PlayerProfileListResolver;
import io.papermc.paper.command.brigadier.argument.resolvers.RotationResolver;
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;
@@ -57,6 +58,8 @@ interface VanillaArgumentProvider {
ArgumentType<FinePositionResolver> finePosition(boolean centerIntegers);
ArgumentType<RotationResolver> rotation();
ArgumentType<BlockState> blockState();
ArgumentType<ItemStack> itemStack();
@@ -0,0 +1,16 @@
package io.papermc.paper.command.brigadier.argument.resolvers;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.math.Rotation;
import org.jetbrains.annotations.ApiStatus;
/**
* An {@link ArgumentResolver} that's capable of resolving
* a rotation argument value using a {@link CommandSourceStack}.
*
* @see io.papermc.paper.command.brigadier.argument.ArgumentTypes#rotation()
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface RotationResolver extends ArgumentResolver<Rotation> {
}
@@ -63,21 +63,76 @@ import static java.util.Objects.requireNonNull;
@ApiStatus.Experimental
public final class DataComponentTypes {
// Start generate - DataComponentTypes
// @GeneratedFrom 1.21.4
/**
* Controls the maximum stacking size of this item.
* <br>
* Values greater than 1 are mutually exclusive with the {@link #MAX_DAMAGE} component.
* Holds attribute modifiers applied to any item,
* if not set, has an implicit default value based on the item type's
* default attributes (e.g. attack damage for weapons).
*/
public static final DataComponentType.Valued<@IntRange(from = 1, to = 99) Integer> MAX_STACK_SIZE = valued("max_stack_size");
public static final DataComponentType.Valued<ItemAttributeModifiers> ATTRIBUTE_MODIFIERS = valued("attribute_modifiers");
/**
* Controls the maximum amount of damage than an item can take,
* if not present, the item cannot be damaged.
* <br>
* Mutually exclusive with the {@link #MAX_STACK_SIZE} component greater than 1.
* Stores the additional patterns applied to a Banner or Shield.
*/
public static final DataComponentType.Valued<BannerPatternLayers> BANNER_PATTERNS = valued("banner_patterns");
/**
* Stores the base color for a Shield.
*/
public static final DataComponentType.Valued<DyeColor> BASE_COLOR = valued("base_color");
/**
* Holds block state properties to apply when placing a block.
*/
public static final DataComponentType.Valued<BlockItemDataProperties> BLOCK_DATA = valued("block_state");
/**
* Holds all items stored inside a Bundle.
* If removed, items cannot be added to the Bundle.
*/
public static final DataComponentType.Valued<BundleContents> BUNDLE_CONTENTS = valued("bundle_contents");
/**
* Controls which blocks a player in Adventure mode can break with this item.
*/
public static final DataComponentType.Valued<ItemAdventurePredicate> CAN_BREAK = valued("can_break");
/**
* Controls which blocks a player in Adventure mode can place on with this item.
*/
public static final DataComponentType.Valued<ItemAdventurePredicate> CAN_PLACE_ON = valued("can_place_on");
/**
* Holds all projectiles that have been loaded into a Crossbow.
* If not present, the Crossbow is not charged.
*/
public static final DataComponentType.Valued<ChargedProjectiles> CHARGED_PROJECTILES = valued("charged_projectiles");
public static final DataComponentType.Valued<Consumable> CONSUMABLE = valued("consumable");
/**
* Holds the contents of container blocks (Chests, Shulker Boxes) in item form.
*/
public static final DataComponentType.Valued<ItemContainerContents> CONTAINER = valued("container");
/**
* Holds the unresolved loot table and seed of a container-like block.
*/
public static final DataComponentType.Valued<SeededContainerLoot> CONTAINER_LOOT = valued("container_loot");
/**
* Controls the minecraft:custom_model_data property in the item model.
*/
public static final DataComponentType.Valued<CustomModelData> CUSTOM_MODEL_DATA = valued("custom_model_data");
/**
* Custom name override for an item (as set by renaming with an Anvil).
*
* @see #DAMAGE
* @see #ITEM_NAME
*/
public static final DataComponentType.Valued<@Positive Integer> MAX_DAMAGE = valued("max_damage");
public static final DataComponentType.Valued<Component> CUSTOM_NAME = valued("custom_name");
/**
* The amount of durability removed from an item,
* for damageable items (with the {@link #MAX_DAMAGE} component), has an implicit default value of: {@code 0}.
@@ -85,16 +140,80 @@ public final class DataComponentTypes {
* @see #MAX_DAMAGE
*/
public static final DataComponentType.Valued<@NonNegative Integer> DAMAGE = valued("damage");
/**
* If set, the item will not lose any durability when used.
* If present, this item will not take damage from the specified damage types.
*/
public static final DataComponentType.Valued<Unbreakable> UNBREAKABLE = valued("unbreakable");
public static final DataComponentType.Valued<DamageResistant> DAMAGE_RESISTANT = valued("damage_resistant");
public static final DataComponentType.Valued<DeathProtection> DEATH_PROTECTION = valued("death_protection");
/**
* Custom name override for an item (as set by renaming with an Anvil).
* Represents a color applied to a dyeable item (in the {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#DYEABLE} item tag).
*/
public static final DataComponentType.Valued<DyedItemColor> DYED_COLOR = valued("dyed_color");
public static final DataComponentType.Valued<Enchantable> ENCHANTABLE = valued("enchantable");
/**
* Overrides the enchantment glint effect on an item.
* If not present, default behaviour is used.
*/
public static final DataComponentType.Valued<Boolean> ENCHANTMENT_GLINT_OVERRIDE = valued("enchantment_glint_override");
/**
* Controls the enchantments on an item.
* <br>
* If not present on a non-enchantment book, this item will not work in an anvil.
*
* @see #ITEM_NAME
* @see #STORED_ENCHANTMENTS
*/
public static final DataComponentType.Valued<Component> CUSTOM_NAME = valued("custom_name");
public static final DataComponentType.Valued<ItemEnchantments> ENCHANTMENTS = valued("enchantments");
public static final DataComponentType.Valued<Equippable> EQUIPPABLE = valued("equippable");
/**
* Stores the explosion crafted in a Firework Star.
*/
public static final DataComponentType.Valued<FireworkEffect> FIREWORK_EXPLOSION = valued("firework_explosion");
/**
* Stores all explosions crafted into a Firework Rocket, as well as flight duration.
*/
public static final DataComponentType.Valued<Fireworks> FIREWORKS = valued("fireworks");
/**
* Controls potential food benefits gained when consuming the item the component is applied on.
* Requires the {@link #CONSUMABLE} component to allow consumption in the first place.
*/
public static final DataComponentType.Valued<FoodProperties> FOOD = valued("food");
public static final DataComponentType.NonValued GLIDER = unvalued("glider");
/**
* If set, disables 'additional' tooltip part which comes from the item type
* (e.g. content of a shulker).
*/
public static final DataComponentType.NonValued HIDE_ADDITIONAL_TOOLTIP = unvalued("hide_additional_tooltip");
/**
* If set, it will completely hide whole item tooltip (that includes item name).
*/
public static final DataComponentType.NonValued HIDE_TOOLTIP = unvalued("hide_tooltip");
/**
* Holds the instrument type used by a Goat Horn.
*/
public static final DataComponentType.Valued<MusicInstrument> INSTRUMENT = valued("instrument");
/**
* Marks that a projectile item would be intangible when fired
* (i.e. can only be picked up by a creative mode player).
*/
public static final DataComponentType.NonValued INTANGIBLE_PROJECTILE = unvalued("intangible_projectile");
public static final DataComponentType.Valued<Key> ITEM_MODEL = valued("item_model");
/**
* When present, replaces default item name with contained chat component.
* <p>
@@ -109,91 +228,100 @@ public final class DataComponentTypes {
* @see #CUSTOM_NAME
*/
public static final DataComponentType.Valued<Component> ITEM_NAME = valued("item_name");
public static final DataComponentType.Valued<Key> ITEM_MODEL = valued("item_model");
public static final DataComponentType.Valued<JukeboxPlayable> JUKEBOX_PLAYABLE = valued("jukebox_playable");
/**
* If present, specifies that the Compass is a Lodestone Compass.
*/
public static final DataComponentType.Valued<LodestoneTracker> LODESTONE_TRACKER = valued("lodestone_tracker");
/**
* Additional lines to include in an item's tooltip.
*/
public static final DataComponentType.Valued<ItemLore> LORE = valued("lore");
/**
* Represents the tint of the decorations on the {@link org.bukkit.inventory.ItemType#FILLED_MAP} item.
*/
public static final DataComponentType.Valued<MapItemColor> MAP_COLOR = valued("map_color");
/**
* Holds a list of markers to be placed on a {@link org.bukkit.inventory.ItemType#FILLED_MAP} (used for Explorer Maps).
*/
public static final DataComponentType.Valued<MapDecorations> MAP_DECORATIONS = valued("map_decorations");
/**
* References the shared map state holding map contents and markers for a {@link org.bukkit.inventory.ItemType#FILLED_MAP}.
*/
public static final DataComponentType.Valued<MapId> MAP_ID = valued("map_id");
/**
* Internal map item state used in the map crafting recipe.
*/
public static final DataComponentType.Valued<MapPostProcessing> MAP_POST_PROCESSING = valued("map_post_processing");
/**
* Controls the maximum amount of damage than an item can take,
* if not present, the item cannot be damaged.
* <br>
* Mutually exclusive with the {@link #MAX_STACK_SIZE} component greater than 1.
*
* @see #DAMAGE
*/
public static final DataComponentType.Valued<@Positive Integer> MAX_DAMAGE = valued("max_damage");
/**
* Controls the maximum stacking size of this item.
* <br>
* Values greater than 1 are mutually exclusive with the {@link #MAX_DAMAGE} component.
*/
public static final DataComponentType.Valued<Integer> MAX_STACK_SIZE = valued("max_stack_size");
/**
* Controls the sound played by a Player Head when placed on a Note Block.
*/
public static final DataComponentType.Valued<Key> NOTE_BLOCK_SOUND = valued("note_block_sound");
/**
* Controls the amplifier amount for an Ominous Bottle's Bad Omen effect.
*/
public static final DataComponentType.Valued<OminousBottleAmplifier> OMINOUS_BOTTLE_AMPLIFIER = valued("ominous_bottle_amplifier");
/**
* Stores the Sherds applied to each side of a Decorated Pot.
*/
public static final DataComponentType.Valued<PotDecorations> POT_DECORATIONS = valued("pot_decorations");
/**
* Holds the contents of a potion (Potion, Splash Potion, Lingering Potion),
* or potion applied to a Tipped Arrow.
*/
public static final DataComponentType.Valued<PotionContents> POTION_CONTENTS = valued("potion_contents");
/**
* Controls the skin displayed on a Player Head.
*/
public static final DataComponentType.Valued<ResolvableProfile> PROFILE = valued("profile");
/**
* Controls the color of the item name.
*/
public static final DataComponentType.Valued<ItemRarity> RARITY = valued("rarity");
/**
* Controls the enchantments on an item.
* <br>
* If not present on a non-enchantment book, this item will not work in an anvil.
*
* @see #STORED_ENCHANTMENTS
* List of recipes that should be unlocked when using the Knowledge Book item.
*/
public static final DataComponentType.Valued<ItemEnchantments> ENCHANTMENTS = valued("enchantments");
/**
* Controls which blocks a player in Adventure mode can place on with this item.
*/
public static final DataComponentType.Valued<ItemAdventurePredicate> CAN_PLACE_ON = valued("can_place_on");
/**
* Controls which blocks a player in Adventure mode can break with this item.
*/
public static final DataComponentType.Valued<ItemAdventurePredicate> CAN_BREAK = valued("can_break");
/**
* Holds attribute modifiers applied to any item,
* if not set, has an implicit default value based on the item type's
* default attributes (e.g. attack damage for weapons).
*/
public static final DataComponentType.Valued<ItemAttributeModifiers> ATTRIBUTE_MODIFIERS = valued("attribute_modifiers");
/**
* Controls the minecraft:custom_model_data property in the item model.
*/
public static final DataComponentType.Valued<CustomModelData> CUSTOM_MODEL_DATA = valued("custom_model_data");
/**
* If set, disables 'additional' tooltip part which comes from the item type
* (e.g. content of a shulker).
*/
public static final DataComponentType.NonValued HIDE_ADDITIONAL_TOOLTIP = unvalued("hide_additional_tooltip");
/**
* If set, it will completely hide whole item tooltip (that includes item name).
*/
public static final DataComponentType.NonValued HIDE_TOOLTIP = unvalued("hide_tooltip");
public static final DataComponentType.Valued<List<Key>> RECIPES = valued("recipes");
/**
* The additional experience cost required to modify an item in an Anvil.
* If not present, has an implicit default value of: {@code 0}.
*/
public static final DataComponentType.Valued<@NonNegative Integer> REPAIR_COST = valued("repair_cost");
// /**
// * Causes an item to not be pickable in the creative menu, currently not very useful.
// */
// public static final DataComponentType.NonValued CREATIVE_SLOT_LOCK = unvalued("creative_slot_lock");
/**
* Overrides the enchantment glint effect on an item.
* If not present, default behaviour is used.
*/
public static final DataComponentType.Valued<Boolean> ENCHANTMENT_GLINT_OVERRIDE = valued("enchantment_glint_override");
/**
* Marks that a projectile item would be intangible when fired
* (i.e. can only be picked up by a creative mode player).
*/
public static final DataComponentType.NonValued INTANGIBLE_PROJECTILE = unvalued("intangible_projectile");
/**
* Controls potential food benefits gained when consuming the item the component is applied on.
* Requires the {@link #CONSUMABLE} component to allow consumption in the first place.
*/
public static final DataComponentType.Valued<FoodProperties> FOOD = valued("food");
public static final DataComponentType.Valued<Consumable> CONSUMABLE = valued("consumable");
public static final DataComponentType.Valued<UseRemainder> USE_REMAINDER = valued("use_remainder");
public static final DataComponentType.Valued<UseCooldown> USE_COOLDOWN = valued("use_cooldown");
/**
* If present, this item will not take damage from the specified damage types.
*/
public static final DataComponentType.Valued<DamageResistant> DAMAGE_RESISTANT = valued("damage_resistant");
/**
* Controls the behavior of the item as a tool.
*/
public static final DataComponentType.Valued<Tool> TOOL = valued("tool");
public static final DataComponentType.Valued<Enchantable> ENCHANTABLE = valued("enchantable");
public static final DataComponentType.Valued<Equippable> EQUIPPABLE = valued("equippable");
public static final DataComponentType.Valued<Repairable> REPAIRABLE = valued("repairable");
public static final DataComponentType.NonValued GLIDER = unvalued("glider");
public static final DataComponentType.Valued<Key> TOOLTIP_STYLE = valued("tooltip_style");
public static final DataComponentType.Valued<DeathProtection> DEATH_PROTECTION = valued("death_protection");
/**
* Stores list of enchantments and their levels for an Enchanted Book.
* Unlike {@link #ENCHANTMENTS}, the effects provided by enchantments
@@ -208,114 +336,51 @@ public final class DataComponentTypes {
* @see #ENCHANTMENTS
*/
public static final DataComponentType.Valued<ItemEnchantments> STORED_ENCHANTMENTS = valued("stored_enchantments");
/**
* Represents a color applied to a dyeable item (in the {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#DYEABLE} item tag).
*/
public static final DataComponentType.Valued<DyedItemColor> DYED_COLOR = valued("dyed_color");
/**
* Represents the tint of the decorations on the {@link org.bukkit.inventory.ItemType#FILLED_MAP} item.
*/
public static final DataComponentType.Valued<MapItemColor> MAP_COLOR = valued("map_color");
/**
* References the shared map state holding map contents and markers for a {@link org.bukkit.inventory.ItemType#FILLED_MAP}.
*/
public static final DataComponentType.Valued<MapId> MAP_ID = valued("map_id");
/**
* Holds a list of markers to be placed on a {@link org.bukkit.inventory.ItemType#FILLED_MAP} (used for Explorer Maps).
*/
public static final DataComponentType.Valued<MapDecorations> MAP_DECORATIONS = valued("map_decorations");
/**
* Internal map item state used in the map crafting recipe.
*/
public static final DataComponentType.Valued<MapPostProcessing> MAP_POST_PROCESSING = valued("map_post_processing");
/**
* Holds all projectiles that have been loaded into a Crossbow.
* If not present, the Crossbow is not charged.
*/
public static final DataComponentType.Valued<ChargedProjectiles> CHARGED_PROJECTILES = valued("charged_projectiles");
/**
* Holds all items stored inside a Bundle.
* If removed, items cannot be added to the Bundle.
*/
public static final DataComponentType.Valued<BundleContents> BUNDLE_CONTENTS = valued("bundle_contents");
/**
* Holds the contents of a potion (Potion, Splash Potion, Lingering Potion),
* or potion applied to a Tipped Arrow.
*/
public static final DataComponentType.Valued<PotionContents> POTION_CONTENTS = valued("potion_contents");
/**
* Holds the effects that will be applied when consuming Suspicious Stew.
*/
public static final DataComponentType.Valued<SuspiciousStewEffects> SUSPICIOUS_STEW_EFFECTS = valued("suspicious_stew_effects");
/**
* Holds the contents in a Book and Quill.
* Controls the behavior of the item as a tool.
*/
public static final DataComponentType.Valued<WritableBookContent> WRITABLE_BOOK_CONTENT = valued("writable_book_content");
/**
* Holds the contents and metadata of a Written Book.
*/
public static final DataComponentType.Valued<WrittenBookContent> WRITTEN_BOOK_CONTENT = valued("written_book_content");
public static final DataComponentType.Valued<Tool> TOOL = valued("tool");
public static final DataComponentType.Valued<Key> TOOLTIP_STYLE = valued("tooltip_style");
/**
* Holds the trims applied to an item in recipes
*/
public static final DataComponentType.Valued<ItemArmorTrim> TRIM = valued("trim");
/**
* If set, the item will not lose any durability when used.
*/
public static final DataComponentType.Valued<Unbreakable> UNBREAKABLE = valued("unbreakable");
public static final DataComponentType.Valued<UseCooldown> USE_COOLDOWN = valued("use_cooldown");
public static final DataComponentType.Valued<UseRemainder> USE_REMAINDER = valued("use_remainder");
/**
* Holds the contents in a Book and Quill.
*/
public static final DataComponentType.Valued<WritableBookContent> WRITABLE_BOOK_CONTENT = valued("writable_book_content");
/**
* Holds the contents and metadata of a Written Book.
*/
public static final DataComponentType.Valued<WrittenBookContent> WRITTEN_BOOK_CONTENT = valued("written_book_content");
// End generate - DataComponentTypes
// /**
// * Causes an item to not be pickable in the creative menu, currently not very useful.
// */
// public static final DataComponentType.NonValued CREATIVE_SLOT_LOCK = unvalued("creative_slot_lock");
// debug_stick_state - Block Property API
// entity_data
// bucket_entity_data
// block_entity_data
/**
* Holds the instrument type used by a Goat Horn.
*/
public static final DataComponentType.Valued<MusicInstrument> INSTRUMENT = valued("instrument");
/**
* Controls the amplifier amount for an Ominous Bottle's Bad Omen effect.
*/
public static final DataComponentType.Valued<OminousBottleAmplifier> OMINOUS_BOTTLE_AMPLIFIER = valued("ominous_bottle_amplifier");
public static final DataComponentType.Valued<JukeboxPlayable> JUKEBOX_PLAYABLE = valued("jukebox_playable");
/**
* List of recipes that should be unlocked when using the Knowledge Book item.
*/
public static final DataComponentType.Valued<List<Key>> RECIPES = valued("recipes");
/**
* If present, specifies that the Compass is a Lodestone Compass.
*/
public static final DataComponentType.Valued<LodestoneTracker> LODESTONE_TRACKER = valued("lodestone_tracker");
/**
* Stores the explosion crafted in a Firework Star.
*/
public static final DataComponentType.Valued<FireworkEffect> FIREWORK_EXPLOSION = valued("firework_explosion");
/**
* Stores all explosions crafted into a Firework Rocket, as well as flight duration.
*/
public static final DataComponentType.Valued<Fireworks> FIREWORKS = valued("fireworks");
/**
* Controls the skin displayed on a Player Head.
*/
public static final DataComponentType.Valued<ResolvableProfile> PROFILE = valued("profile");
/**
* Controls the sound played by a Player Head when placed on a Note Block.
*/
public static final DataComponentType.Valued<Key> NOTE_BLOCK_SOUND = valued("note_block_sound");
/**
* Stores the additional patterns applied to a Banner or Shield.
*/
public static final DataComponentType.Valued<BannerPatternLayers> BANNER_PATTERNS = valued("banner_patterns");
/**
* Stores the base color for a Shield.
*/
public static final DataComponentType.Valued<DyeColor> BASE_COLOR = valued("base_color");
/**
* Stores the Sherds applied to each side of a Decorated Pot.
*/
public static final DataComponentType.Valued<PotDecorations> POT_DECORATIONS = valued("pot_decorations");
/**
* Holds the contents of container blocks (Chests, Shulker Boxes) in item form.
*/
public static final DataComponentType.Valued<ItemContainerContents> CONTAINER = valued("container");
/**
* Holds block state properties to apply when placing a block.
*/
public static final DataComponentType.Valued<BlockItemDataProperties> BLOCK_DATA = valued("block_state");
// bees
// /**
// * Holds the lock state of a container-like block,
@@ -325,10 +390,6 @@ public final class DataComponentTypes {
// * to open this container.
// */
// public static final DataComponentType.Valued<LockCode> LOCK = valued("lock");
/**
* Holds the unresolved loot table and seed of a container-like block.
*/
public static final DataComponentType.Valued<SeededContainerLoot> CONTAINER_LOOT = valued("container_loot");
private static DataComponentType.NonValued unvalued(final String name) {
return (DataComponentType.NonValued) requireNonNull(Registry.DATA_COMPONENT_TYPE.get(NamespacedKey.minecraft(name)), name + " unvalued data component type couldn't be found, this is a bug.");
@@ -21,9 +21,9 @@ public interface DamageResistant {
}
/**
* The types that this damage type is invincible tp.
* The types that this damage type is invincible to.
*
* @return item
* @return the key of the tag holding the respective damage types.
*/
@Contract(value = "-> new", pure = true)
TagKey<DamageType> types();
@@ -21,7 +21,7 @@ public interface ConsumeEffect {
* Creates a consume effect that randomly teleports the entity on consumption.
*
* @param diameter diameter of random teleportation
* @return the effect
* @return the effect instance
*/
@Contract(value = "_ -> new", pure = true)
static TeleportRandomly teleportRandomlyEffect(final float diameter) {
@@ -29,21 +29,21 @@ public interface ConsumeEffect {
}
/**
* Creates a consume effect that gives status effects on consumption.
* Creates a consume effect that removes status effects on consumption.
*
* @param key the sound effect to play
* @return the effect
* @param effects the potion effects to remove
* @return the effect instance
*/
@Contract(value = "_ -> new", pure = true)
static RemoveStatusEffects removeEffects(final RegistryKeySet<PotionEffectType> key) {
return ConsumableTypesBridge.bridge().removeStatusEffects(key);
static RemoveStatusEffects removeEffects(final RegistryKeySet<PotionEffectType> effects) {
return ConsumableTypesBridge.bridge().removeStatusEffects(effects);
}
/**
* Creates a consume effect that plays a sound on consumption.
*
* @param key the sound effect to play
* @return the effect
* @param key the key sound effect to play
* @return the effect instance
*/
@Contract(value = "_ -> new", pure = true)
static PlaySound playSoundConsumeEffect(final Key key) {
@@ -53,7 +53,7 @@ public interface ConsumeEffect {
/**
* Creates a consume effect that clears all status effects.
*
* @return effect instance
* @return the effect instance
*/
@Contract(value = "-> new", pure = true)
static ClearAllStatusEffects clearAllStatusEffects() {
@@ -61,17 +61,20 @@ public interface ConsumeEffect {
}
/**
* Creates a consume effect that gives status effects on consumption.
* Creates a consume effect that gives potion effects on consumption.
*
* @param effects the potion effects to apply
* @param probability the probability of these effects being applied, between 0 and 1 inclusive.
* @return the effect
* @param probability the probability of these effects being applied, between 0 and 1 inclusive
* @return the effect instance
*/
@Contract(value = "_, _ -> new", pure = true)
static ApplyStatusEffects applyStatusEffects(final List<PotionEffect> effects, final float probability) {
return ConsumableTypesBridge.bridge().applyStatusEffects(effects, probability);
}
/**
* Represents a consumable effect that randomly teleports the entity on consumption.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface TeleportRandomly extends ConsumeEffect {
@@ -85,14 +88,14 @@ public interface ConsumeEffect {
}
/**
* Represents a consumable effect that removes status effects on consumption
* Represents a consumable effect that removes status effects on consumption.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface RemoveStatusEffects extends ConsumeEffect {
/**
* Potion effects to remove
* Potion effects to remove.
*
* @return effects
*/
@@ -107,7 +110,7 @@ public interface ConsumeEffect {
interface PlaySound extends ConsumeEffect {
/**
* Sound effect to play in the world
* Sound effect to play in the world.
*
* @return sound effect
*/
@@ -124,16 +127,16 @@ public interface ConsumeEffect {
}
/**
* Represents a consumable effect that applies effects based on a probability on consumption.
* Represents a consumable effect that applies potion effects based on a probability on consumption.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface ApplyStatusEffects extends ConsumeEffect {
/**
* Effect instances to grant
* Potion effect instances to grant.
*
* @return effect
* @return potion effects
*/
List<PotionEffect> effects();
@@ -4,6 +4,8 @@ package io.papermc.paper.datacomponent.item.consumable;
* Represents the hand animation that is used when a player is consuming this item.
*/
public enum ItemUseAnimation {
// Start generate - ItemUseAnimation
// @GeneratedFrom 1.21.4
NONE,
EAT,
DRINK,
@@ -14,5 +16,6 @@ public enum ItemUseAnimation {
SPYGLASS,
TOOT_HORN,
BRUSH,
BUNDLE
BUNDLE;
// End generate - ItemUseAnimation
}
@@ -1,10 +1,8 @@
package io.papermc.paper.datapack;
import java.util.Set;
import net.kyori.adventure.text.Component;
import org.bukkit.FeatureFlag;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;
/**
@@ -12,50 +10,8 @@ import org.jspecify.annotations.NullMarked;
* won't be updated as datapacks are updated.
*/
@NullMarked
public interface Datapack {
/**
* Gets the name/id of this datapack.
*
* @return the name of the pack
*/
@Contract(pure = true)
String getName();
/**
* Gets the title component of this datapack.
*
* @return the title
*/
Component getTitle();
/**
* Gets the description component of this datapack.
*
* @return the description
*/
Component getDescription();
/**
* Gets if this datapack is required to be enabled.
*
* @return true if the pack is required
*/
boolean isRequired();
/**
* Gets the compatibility status of this pack.
*
* @return the compatibility of the pack
*/
Compatibility getCompatibility();
/**
* Gets the set of required features for this datapack.
*
* @return the set of required features
*/
@Unmodifiable Set<FeatureFlag> getRequiredFeatures();
@ApiStatus.NonExtendable
public interface Datapack extends DiscoveredDatapack {
/**
* Gets the enabled state of this pack.
@@ -74,13 +30,6 @@ public interface Datapack {
*/
void setEnabled(boolean enabled);
/**
* Gets the source for this datapack.
*
* @return the pack source
*/
DatapackSource getSource();
/**
* Computes the component vanilla Minecraft uses
* to display this datapack. Includes the {@link #getSource()},
@@ -96,4 +45,11 @@ public interface Datapack {
TOO_NEW,
COMPATIBLE,
}
/**
* Position of the pack in the load order.
*/
enum Position {
TOP, BOTTOM
}
}
@@ -0,0 +1,205 @@
package io.papermc.paper.datapack;
import io.papermc.paper.plugin.configuration.PluginMeta;
import io.papermc.paper.plugin.lifecycle.event.registrar.Registrar;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Path;
import java.util.Map;
import java.util.function.Consumer;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* The registrar for datapacks. The event for this registrar
* is called anytime the game tries to discover datapacks at any of the
* configured locations. This means that if a datapack should stay available to the server,
* it must always be discovered whenever this event fires.
* <p>
* An example of a plugin loading a datapack from within its own jar is below,
* assuming the datapack is included under {@code resources/pack} folder:
* <pre>{@code
* public class YourPluginBootstrap implements PluginBootstrap {
* @Override
* public void bootstrap(BootstrapContext context) {
* final LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager();
* manager.registerEventHandler(LifecycleEvents.DATAPACK_DISCOVERY, event -> {
* DatapackRegistrar registrar = event.registrar();
* try {
* final URI uri = Objects.requireNonNull(
* YourPluginBootstrap.class.getResource("/pack")
* ).toURI();
* registrar.discoverPack(uri, "packId");
* } catch (final URISyntaxException | IOException e) {
* throw new RuntimeException(e);
* }
* });
* }
* }
* }</pre>
*
* @see io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#DATAPACK_DISCOVERY
*/
@ApiStatus.NonExtendable
@ApiStatus.Experimental
@NullMarked
public interface DatapackRegistrar extends Registrar {
/**
* Checks if a datapack with the specified name has been discovered.
*
* @param name the name of the pack
* @return true if the pack has been discovered
* @see Datapack#getName()
*/
@Contract(pure = true)
boolean hasPackDiscovered(String name);
/**
* Gets a discovered datapack by its name.
*
* @param name the name of the pack
* @return the datapack
* @throws java.util.NoSuchElementException if the pack is not discovered
* @see Datapack#getName()
*/
@Contract(pure = true)
DiscoveredDatapack getDiscoveredPack(String name);
/**
* Removes a discovered datapack by its name.
*
* @param name the name of the pack
* @return true if the pack was removed
* @see Datapack#getName()
*/
@Contract(mutates = "this")
boolean removeDiscoveredPack(String name);
/**
* Gets all discovered datapacks.
*
* @return an unmodifiable map of discovered packs
*/
@Contract(pure = true)
@Unmodifiable Map<String, DiscoveredDatapack> getDiscoveredPacks();
/**
* Discovers a datapack at the specified {@link URI} with the id.
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
*
* @param uri the location of the pack
* @param id a unique id (will be combined with plugin for the datapacks name)
* @return the discovered datapack (or null if it failed)
* @throws IOException if any IO error occurs
*/
default @Nullable DiscoveredDatapack discoverPack(final URI uri, final String id) throws IOException {
return this.discoverPack(uri, id, c -> {});
}
/**
* Discovers a datapack at the specified {@link URI} with the id.
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
*
* @param uri the location of the pack
* @param id a unique id (will be combined with plugin for the datapacks name)
* @param configurer a configurer for extra options
* @return the discovered datapack (or null if it failed)
* @throws IOException if any IO error occurs
*/
@Nullable DiscoveredDatapack discoverPack(URI uri, String id, Consumer<Configurer> configurer) throws IOException;
/**
* Discovers a datapack at the specified {@link Path} with the id.
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
*
* @param path the location of the pack
* @param id a unique id (will be combined with plugin for the datapacks name)
* @return the discovered datapack (or null if it failed)
* @throws IOException if any IO error occurs
*/
default @Nullable DiscoveredDatapack discoverPack(final Path path, final String id) throws IOException {
return this.discoverPack(path, id, c -> {});
}
/**
* Discovers a datapack at the specified {@link Path} with the id.
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
*
* @param path the location of the pack
* @param id a unique id (will be combined with plugin for the datapacks name)
* @param configurer a configurer for extra options
* @return the discovered datapack (or null if it failed)
* @throws IOException if any IO error occurs
*/
@Nullable DiscoveredDatapack discoverPack(Path path, String id, Consumer<Configurer> configurer) throws IOException;
/**
* Discovers a datapack at the specified {@link URI} with the id.
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
*
* @param pluginMeta the plugin which will be the "owner" of this datapack
* @param uri the location of the pack
* @param id a unique id (will be combined with plugin for the datapacks name)
* @param configurer a configurer for extra options
* @return the discovered datapack (or null if it failed)
* @throws IOException if any IO error occurs
*/
@Nullable DiscoveredDatapack discoverPack(PluginMeta pluginMeta, URI uri, String id, Consumer<Configurer> configurer) throws IOException;
/**
* Discovers a datapack at the specified {@link Path} with the id.
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
*
* @param pluginMeta the plugin which will be the "owner" of this datapack
* @param path the location of the pack
* @param id a unique id (will be combined with plugin for the datapacks name)
* @param configurer a configurer for extra options
* @return the discovered datapack (or null if it failed)
* @throws IOException if any IO error occurs
*/
@Nullable DiscoveredDatapack discoverPack(PluginMeta pluginMeta, Path path, String id, Consumer<Configurer> configurer) throws IOException;
/**
* Configures additional, optional, details about a datapack.
*/
@ApiStatus.NonExtendable
@ApiStatus.Experimental
interface Configurer {
/**
* Changes the title of the datapack from the default which
* is just the "id" in the {@code registerPack} methods.
*
* @param title the new title
* @return the configurer for chaining
*/
@Contract(value = "_ -> this", mutates = "this")
Configurer title(Component title);
/**
* Sets whether this pack is going to be automatically enabled on server starts even if previously disabled.
* Defaults to false.
*
* @param autoEnableOnServerStart true to ensure the pack is enabled on server starts.
* @return the configurer for chaining
*/
@Contract(value = "_ -> this", mutates = "this")
Configurer autoEnableOnServerStart(boolean autoEnableOnServerStart);
/**
* Configures the position in the
* load order of this datapack.
*
* @param fixed won't move around in the load order as packs are added/removed
* @param position try to insert at the top of the order or bottom
* @return the configurer for chaining
*/
@Contract(value = "_, _ -> this", mutates = "this")
Configurer position(boolean fixed, Datapack.Position position);
}
}
@@ -13,6 +13,7 @@ public sealed interface DatapackSource permits DatapackSourceImpl {
DatapackSource FEATURE = create("feature");
DatapackSource WORLD = create("world");
DatapackSource SERVER = create("server");
DatapackSource PLUGIN = create("plugin");
private static DatapackSource create(final String name) {
return new DatapackSourceImpl(name);
@@ -0,0 +1,74 @@
package io.papermc.paper.datapack;
import java.util.Set;
import net.kyori.adventure.text.Component;
import org.bukkit.FeatureFlag;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;
/**
* Represents a snapshot of a datapack that the server has found by
* searching available sources. It may or may not be enabled and isn't
* guaranteed to be available. This object won't be
* updated as datapacks are updated.
* @see DatapackRegistrar
*/
@NullMarked
@ApiStatus.NonExtendable
public interface DiscoveredDatapack {
/**
* Gets the name/id of this datapack.
*
* @return the name of the pack
*/
@Contract(pure = true)
String getName();
/**
* Gets the title component of this datapack.
*
* @return the title
*/
Component getTitle();
/**
* Gets the description component of this datapack.
*
* @return the description
*/
Component getDescription();
/**
* Gets if this datapack is required.
* <p>
* A "required" datapack will always be enabled on server startup, even if previously disabled.
*
* @return true if the pack is required
*/
boolean isRequired();
/**
* Gets the compatibility status of this pack.
*
* @return the compatibility of the pack
*/
Datapack.Compatibility getCompatibility();
/**
* Gets the set of required features for this datapack.
*
* @return the set of required features
*/
@Unmodifiable
Set<FeatureFlag> getRequiredFeatures();
/**
* Gets the source for this datapack.
*
* @return the pack source
*/
DatapackSource getSource();
}
@@ -0,0 +1,38 @@
package io.papermc.paper.entity;
import org.bukkit.UnsafeValues;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
/**
* Represents flags for entity serialization.
*
* @see UnsafeValues#serializeEntity(Entity, EntitySerializationFlag... serializationFlags)
* @since 1.21.4
*/
public enum EntitySerializationFlag {
/**
* Serialize entities that wouldn't be serialized normally
* (e.g. dead, despawned, non-persistent, etc.).
*
* @see Entity#isValid()
* @see Entity#isPersistent()
*/
FORCE,
/**
* Serialize misc non-saveable entities like lighting bolts, fishing bobbers, etc.
* <br>Note: players require a separate flag: {@link #PLAYER}.
*/
MISC,
/**
* Include passengers in the serialized data.
*/
PASSENGERS,
/**
* Allow serializing {@link Player}s.
* <p>Note: deserializing player data will always fail.
*/
PLAYER
}
@@ -0,0 +1,39 @@
package io.papermc.paper.entity;
import java.util.Collection;
import org.bukkit.entity.Item;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;
/**
* A result type used by {@link org.bukkit.entity.Player#give(ItemStack...)} and its overloads.
*/
@NullMarked
public interface PlayerGiveResult {
/**
* A collection of itemstacks that were not added to the player's inventory as they did not fit.
* The collection is derived from the collections of items to add by creating copies of each stack that was not
* fully added to the inventory and assigning the non-added count as their amount.
* <p>
* Itemstacks found here *may* also be found as item entities in the {@link #drops()} collection, as the
* give logic may have dropped them.
*
* @return the unmodifiable collection of itemstacks that are leftover as they could not be added. Each element is a
* copy of the input stack they are derived from.
*/
@Unmodifiable
Collection<ItemStack> leftovers();
/**
* A collection of item entities dropped as a result of this call to {@link org.bukkit.entity.Player#give(ItemStack...)}.
* The item entities contained here are not guaranteed to match the {@link #leftovers()} as plugins may cancel the
* spawning of item entities.
*
* @return the unmodifiable collection of dropped item entities.
*/
@Unmodifiable
Collection<Item> drops();
}
@@ -12,10 +12,10 @@ import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a player uses sheers on a block.
* Called when a player uses shears on a block.
* <p>
* This event is <b>not</b> called when breaking blocks with shears but instead only when a
* player uses the sheer item on a block to garner drops from said block and/or change its state.
* This event is <b>not</b> called when a player breaks blocks with shears, but rather when a
* player uses the shears on a block to collect drops from it and/or modify its state.
* <p>
* Examples include shearing a pumpkin to turn it into a carved pumpkin or shearing a beehive to get honeycomb.
*/
@@ -0,0 +1,103 @@
package io.papermc.paper.event.entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when an entity attempts to perform a smash attack.
*/
@NullMarked
public class EntityAttemptSmashAttackEvent extends EntityEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final LivingEntity target;
private final ItemStack weapon;
private final boolean originalResult;
private Result result = Result.DEFAULT;
@ApiStatus.Internal
public EntityAttemptSmashAttackEvent(
final LivingEntity attacker,
final LivingEntity target,
final ItemStack weapon,
final boolean originalResult
) {
super(attacker);
this.target = target;
this.weapon = weapon;
this.originalResult = originalResult;
}
/**
* Yields the target of the attempted smash attack.
*
* @return the target entity
*/
public LivingEntity getTarget() {
return target;
}
/**
* Yields a copy of the itemstack used in the smash attack attempt.
*
* @return the itemstack
*/
public ItemStack getWeapon() {
return weapon.clone();
}
/**
* Yields the original result the server computed.
*
* @return {@code true} if this attempt would have been successful by vanilla's logic, {@code false} otherwise.
*/
public boolean getOriginalResult() {
return originalResult;
}
/**
* Yields the effective result of this event.
* The result may take one of three values:
*
* <ul>
* <li>{@link Result#ALLOW}: The attempt will succeed.</li>
* <li>{@link Result#DENY}: The attempt will fail.</li>
* <li>{@link Result#DEFAULT}: The attempt will succeed if {@link #getOriginalResult()} is {@code true} and fail otherwise.</li>
* </ul>
*
* @return the result.
*/
public Result getResult() {
return this.result;
}
/**
* Configures a new result for this event.
* The passes result may take one of three values:
*
* <ul>
* <li>{@link Result#ALLOW}: The attempt will succeed.</li>
* <li>{@link Result#DENY}: The attempt will fail.</li>
* <li>{@link Result#DEFAULT}: The attempt will succeed if {@link #getOriginalResult()} is {@code true} and fail otherwise.</li>
* </ul>
*
* @param result the new result of the event.
*/
public void setResult(final Result result) {
this.result = result;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -0,0 +1,75 @@
package io.papermc.paper.event.entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* An event that is triggered when an entity receives a potion effect instantly
* or when the potion effect is applied on each tick (e.g. every 25 ticks for Poison level 1).
* <p>
* For example, this event may be called when an entity regenerates health
* or takes poison damage as a result of a potion effect.
*/
@NullMarked
public class EntityEffectTickEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final PotionEffectType type;
private final int amplifier;
private boolean cancelled;
@ApiStatus.Internal
public EntityEffectTickEvent(final LivingEntity entity, final PotionEffectType type, final int amplifier) {
super(entity);
this.type = type;
this.amplifier = amplifier;
}
@Override
public LivingEntity getEntity() {
return (LivingEntity) super.getEntity();
}
/**
* Gets the type of the potion effect associated with this event.
*
* @return the {@link PotionEffectType} of the effect
*/
public PotionEffectType getType() {
return type;
}
/**
* Gets the amplifier level of the potion effect associated with this event.
*
* @return the amplifier level of the potion effect
*/
public int getAmplifier() {
return amplifier;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -0,0 +1,89 @@
package io.papermc.paper.event.entity;
import java.util.Collections;
import java.util.Map;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;
/**
* Called whenever a change to an entity's equipment has been detected. This event is called after effects from
* attribute modifiers and enchantments have been updated.
* <p>
* Examples of actions that can trigger this event:
* <ul>
* <li>An entity being added to a world.</li>
* <li>A player logging in.</li>
* <li>The durability of an equipment item changing.</li>
* <li>A dispenser equipping an item onto an entity.</li>
* <li>An entity picking up an armor or weapon item from the ground.</li>
* <li>A player changing their equipped armor.</li>
* <li>A player changes their currently held item.</li>
* </ul>
*/
@NullMarked
public class EntityEquipmentChangedEvent extends EntityEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Map<EquipmentSlot, EquipmentChange> equipmentChanges;
@ApiStatus.Internal
public EntityEquipmentChangedEvent(final LivingEntity entity, final Map<EquipmentSlot, EquipmentChange> equipmentChanges) {
super(entity);
this.equipmentChanges = equipmentChanges;
}
@Override
public LivingEntity getEntity() {
return (LivingEntity) this.entity;
}
/**
* Gets a map of changed slots to their respective equipment changes.
*
* @return the equipment changes map
*/
public @Unmodifiable Map<EquipmentSlot, EquipmentChange> getEquipmentChanges() {
return Collections.unmodifiableMap(this.equipmentChanges);
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
/**
* Represents a change in equipment for a single equipment slot.
*/
@ApiStatus.NonExtendable
public interface EquipmentChange {
/**
* Gets the existing item that is being replaced.
*
* @return the existing item
*/
@Contract(pure = true, value = "-> new")
ItemStack oldItem();
/**
* Gets the new item that is replacing the existing item.
*
* @return the new item
*/
@Contract(pure = true, value = "-> new")
ItemStack newItem();
}
}
@@ -0,0 +1,74 @@
package io.papermc.paper.event.executor;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import java.io.IOException;
import java.io.InputStream;
import java.lang.constant.ConstantDescs;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Objects;
@ApiStatus.Internal
@NullMarked
public final class EventExecutorFactory {
private static final byte[] TEMPLATE_CLASS_BYTES;
static {
try (final InputStream is = EventExecutorFactory.class.getResourceAsStream("MethodHandleEventExecutorTemplate.class")) {
TEMPLATE_CLASS_BYTES = Objects.requireNonNull(is, "template class is missing").readAllBytes();
} catch (IOException e) {
throw new AssertionError(e);
}
}
private EventExecutorFactory() {
}
/**
* {@return an {@link EventExecutor} implemented by a hidden class calling a method handle}
*
* @param method the method to be invoked by the created event executor
* @param eventClass the class of the event to handle
*/
public static EventExecutor create(final Method method, final Class<? extends Event> eventClass) {
final List<?> classData = List.of(method, eventClass);
try {
final MethodHandles.Lookup newClass = MethodHandles.lookup().defineHiddenClassWithClassData(TEMPLATE_CLASS_BYTES, classData, true);
return newClass.lookupClass().asSubclass(EventExecutor.class).getDeclaredConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
}
}
record ClassData(Method method, MethodHandle methodHandle, Class<? extends Event> eventClass) {
}
/**
* Extracts the class data and creates an adjusted MethodHandle directly usable by the lookup class.
* The logic is kept here to minimize memory usage per created class.
*/
static ClassData classData(final MethodHandles.Lookup lookup) {
try {
final Method method = MethodHandles.classDataAt(lookup, ConstantDescs.DEFAULT_NAME, Method.class, 0);
MethodHandle mh = lookup.unreflect(method);
if (Modifier.isStatic(method.getModifiers())) {
mh = MethodHandles.dropArguments(mh, 0, Listener.class);
}
mh = mh.asType(MethodType.methodType(void.class, Listener.class, Event.class));
final Class<?> eventClass = MethodHandles.classDataAt(lookup, ConstantDescs.DEFAULT_NAME, Class.class, 1);
return new ClassData(method, mh, eventClass.asSubclass(Event.class));
} catch (ReflectiveOperationException e) {
throw new AssertionError(e);
}
}
}
@@ -0,0 +1,56 @@
package io.papermc.paper.event.executor;
import com.destroystokyo.paper.util.SneakyThrow;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
/**
* This class is designed to be used as hidden class template.
* Initializing the class directly will fail due to missing {@code classData}.
* Instead, {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClassWithClassData(byte[], Object, boolean, MethodHandles.Lookup.ClassOption...)}
* must be used, with the {@code classData} object being a list consisting of two elements:
* <ol>
* <li>A {@link Method} representing the event handler method</li>
* <li>A {@link Class} representing the event type</li>
* </ol>
* The method must take {@link Event} or a subtype of it as its single parameter.
* If the method is non-static, it also needs to reside in a class implementing {@link Listener}.
*/
@SuppressWarnings("unused")
@ApiStatus.Internal
@NullMarked
class MethodHandleEventExecutorTemplate implements EventExecutor {
private static final Method METHOD;
private static final MethodHandle HANDLE;
private static final Class<? extends Event> EVENT_CLASS;
static {
final MethodHandles.Lookup lookup = MethodHandles.lookup();
final EventExecutorFactory.ClassData classData = EventExecutorFactory.classData(lookup);
METHOD = classData.method();
HANDLE = classData.methodHandle();
EVENT_CLASS = classData.eventClass();
}
@Override
public void execute(final Listener listener, final Event event) throws EventException {
if (!EVENT_CLASS.isInstance(event)) return;
try {
HANDLE.invokeExact(listener, event);
} catch (Throwable t) {
SneakyThrow.sneaky(t);
}
}
@Override
public String toString() {
return "MethodHandleEventExecutorTemplate['" + METHOD + "']";
}
}
@@ -0,0 +1,46 @@
package io.papermc.paper.event.player;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called when a player is marked as loaded.
* <p>
* This either happens when the player notifies the server after loading the world (closing the downloading terrain screen)
* or when the player has not done so for 60 ticks after joining the server or respawning.
*/
@NullMarked
public class PlayerClientLoadedWorldEvent extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final boolean timeout;
@ApiStatus.Internal
public PlayerClientLoadedWorldEvent(final Player who, final boolean timeout) {
super(who);
this.timeout = timeout;
}
/**
* True if the event was triggered because the server has not been notified by the player
* for 60 ticks after the player joined the server or respawned.
*
* @return true if the event was triggered because of a timeout
*/
public boolean isTimeout() {
return timeout;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}
@@ -0,0 +1,34 @@
package io.papermc.paper.math;
import org.jspecify.annotations.NullMarked;
/**
* Represents a rotation with specified pitch and yaw values.
*/
@NullMarked
public interface Rotation {
/**
* Creates a new rotation with the specified yaw and pitch values.
*
* @param yaw the yaw component of the rotation, measured in degrees
* @param pitch the pitch component of the rotation, measured in degrees
* @return a new {@code Rotation} instance with the specified yaw and pitch
*/
static Rotation rotation(float yaw, float pitch) {
return new RotationImpl(yaw, pitch);
}
/**
* Retrieves the pitch component of the rotation, measured in degrees.
*
* @return the pitch value in degrees
*/
float pitch();
/**
* Retrieves the yaw component of the rotation, measured in degrees.
*
* @return the yaw value in degrees
*/
float yaw();
}
@@ -0,0 +1,4 @@
package io.papermc.paper.math;
record RotationImpl(float yaw, float pitch) implements Rotation {
}
@@ -1,10 +1,12 @@
package io.papermc.paper.plugin.lifecycle.event.types;
import io.papermc.paper.command.brigadier.Commands;
import io.papermc.paper.datapack.DatapackRegistrar;
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 io.papermc.paper.plugin.lifecycle.event.registrar.RegistrarEvent;
import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.ApiStatus;
@@ -32,6 +34,14 @@ public final class LifecycleEvents {
*/
public static final TagEventTypeProvider TAGS = LifecycleEventTypeProvider.provider().tagProvider();
/**
* This event is for informing the server about any available datapacks from other sources such as inside a plugin's jar. You
* can register a handler for this event only in {@link io.papermc.paper.plugin.bootstrap.PluginBootstrap#bootstrap(BootstrapContext)}.
* @see DatapackRegistrar an example of a datapack being discovered
*/
public static final LifecycleEventType.Prioritizable<BootstrapContext, RegistrarEvent<DatapackRegistrar>> DATAPACK_DISCOVERY = bootstrapPrioritized("datapack_discovery");
//<editor-fold desc="helper methods" defaultstate="collapsed">
@ApiStatus.Internal
static <E extends LifecycleEvent> LifecycleEventType.Monitorable<Plugin, E> plugin(final String name) {
@@ -0,0 +1,112 @@
package io.papermc.paper.raytracing;
import java.util.function.Predicate;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.util.Vector;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NullMarked;
/**
* A builder for configuring a raytrace with a starting location
* and direction.
*/
@NullMarked
public interface PositionedRayTraceConfigurationBuilder {
/**
* Sets the starting location.
*
* @param start the new starting location
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder start(Location start);
/**
* Sets the direction.
*
* @param direction the new direction
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder direction(Vector direction);
/**
* Sets the maximum distance.
*
* @param maxDistance the new maxDistance
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder maxDistance(@NonNegative double maxDistance);
/**
* Sets the FluidCollisionMode when looking for block collisions.
* <p>
* If collisions with passable blocks are ignored, fluid collisions are
* ignored as well regardless of the fluid collision mode.
*
* @param fluidCollisionMode the new FluidCollisionMode
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder fluidCollisionMode(FluidCollisionMode fluidCollisionMode);
/**
* Sets whether the raytrace should ignore passable blocks when looking for
* block collisions.
* <p>
* If collisions with passable blocks are ignored, fluid collisions are
* ignored as well regardless of the fluid collision mode.
* <p>
* 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.
*
* @param ignorePassableBlocks if the raytrace should ignore passable blocks
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder ignorePassableBlocks(boolean ignorePassableBlocks);
/**
* Sets the size of the raytrace when looking for entity collisions.
*
* @param raySize the new raytrace size
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder raySize(@NonNegative double raySize);
/**
* Sets the current entity filter when looking for entity collisions.
*
* @param entityFilter predicate for entities the ray can potentially collide with
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder entityFilter(Predicate<? super Entity> entityFilter);
/**
* Sets the current block filter when looking for block collisions.
*
* @param blockFilter predicate for blocks the ray can potentially collide with
* @return a reference to this object
*/
@Contract(value = "_ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder blockFilter(Predicate<? super Block> blockFilter);
/**
* Sets the targets for the rayTrace.
*
* @param first the first target
* @param others the other targets
* @return a reference to this object
*/
@Contract(value = "_, _ -> this", mutates = "this")
PositionedRayTraceConfigurationBuilder targets(RayTraceTarget first, RayTraceTarget... others);
}
@@ -0,0 +1,9 @@
package io.papermc.paper.raytracing;
/**
* List of Targets a builder can target.
*/
public enum RayTraceTarget {
ENTITY,
BLOCK
}
@@ -1,6 +1,7 @@
package io.papermc.paper.registry;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.registry.tag.TagKey;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import net.kyori.adventure.key.Keyed;
@@ -209,7 +210,6 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
* @param key the key of the typed key.
* @return the constructed typed key.
*/
@ApiStatus.Experimental
default TypedKey<T> typedKey(final Key key) {
return TypedKey.create(this, key);
}
@@ -220,8 +220,29 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
* @param key the string representation of the key that will be passed to {@link Key#key(String)}.
* @return the constructed typed key.
*/
@ApiStatus.Experimental
default TypedKey<T> typedKey(final @KeyPattern String key) {
default TypedKey<T> typedKey(@KeyPattern final String key) {
return TypedKey.create(this, key);
}
/**
* Constructs a new {@link TagKey} for this registry given the tag key's key.
*
* @param key the key of the typed key.
* @return the constructed tag key.
*/
@ApiStatus.Experimental
default TagKey<T> tagKey(final Key key) {
return TagKey.create(this, key);
}
/**
* Constructs a new {@link TagKey} for this registry given the tag key's key.
*
* @param key the string representation of the key that will be passed to {@link Key#key(String)}.
* @return the constructed tag key.
*/
@ApiStatus.Experimental
default TagKey<T> tagKey(@KeyPattern final String key) {
return TagKey.create(this, key);
}
}
@@ -11,7 +11,6 @@ import org.jspecify.annotations.NullMarked;
*
* @param <T> the value type for the registry
*/
@ApiStatus.Experimental
@NullMarked
public sealed interface TypedKey<T> extends Key permits TypedKeyImpl {
@@ -39,7 +38,6 @@ public sealed interface TypedKey<T> extends Key permits TypedKeyImpl {
* @param <T> value type
* @return a new key for the value key and registry key
*/
@ApiStatus.Experimental
static <T> TypedKey<T> create(final RegistryKey<T> registryKey, final Key key) {
return new TypedKeyImpl<>(key, registryKey);
}
@@ -53,8 +51,7 @@ public sealed interface TypedKey<T> extends Key permits TypedKeyImpl {
* @return a new key for the value key and registry key
* @see Key#key(String)
*/
@ApiStatus.Experimental
static <T> TypedKey<T> create(final RegistryKey<T> registryKey, final @KeyPattern String key) {
static <T> TypedKey<T> create(final RegistryKey<T> registryKey, @KeyPattern final String key) {
return create(registryKey, Key.key(key));
}
}
@@ -0,0 +1,65 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import net.kyori.adventure.key.Key;
import org.bukkit.block.banner.PatternType;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link PatternType} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface BannerPatternRegistryEntry {
/**
* Provides the asset id of the pattern type, which is the location of the sprite to use.
*
* @return the asset id.
*/
Key assetId();
/**
* Provides the translation key for displaying the pattern inside the banner's tooltip.
*
* @return the translation key.
*/
String translationKey();
/**
* A mutable builder for the {@link BannerPatternRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #assetId(Key)}</li>
* <li>{@link #translationKey(String)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends BannerPatternRegistryEntry, RegistryBuilder<PatternType> {
/**
* Sets the asset id of the pattern type, which is the location of the sprite to use.
*
* @param assetId the asset id.
* @return this builder instance.
* @see BannerPatternRegistryEntry#assetId()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder assetId(Key assetId);
/**
* Sets the translation key for displaying the pattern inside the banner's tooltip.
*
* @param translationKey the translation key.
* @return this builder instance.
* @see BannerPatternRegistryEntry#translationKey()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder translationKey(String translationKey);
}
}
@@ -0,0 +1,120 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import org.bukkit.damage.DamageEffect;
import org.bukkit.damage.DamageScaling;
import org.bukkit.damage.DamageType;
import org.bukkit.damage.DeathMessageType;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link DamageType} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface DamageTypeRegistryEntry {
/**
* Provides part of the death message translation key. (death.attack.&lt;message_id&gt;)
* <p>
* <strong>Note</strong> The translation key is only used if
* {@link #deathMessageType()} is {@link DeathMessageType#DEFAULT}
*
* @return part of the translation key
*/
String messageId();
/**
* Provides the amount of hunger exhaustion caused by this damage type.
*
* @return the exhaustion
*/
float exhaustion();
/**
* Provides the {@link DamageScaling} for this damage type.
*
* @return the damage scaling
*/
DamageScaling damageScaling();
/**
* Provides the {@link DamageEffect} for this damage type.
*
* @return the damage effect
*/
DamageEffect damageEffect();
/**
* Provides the {@link DeathMessageType} for this damage type.
*
* @return the death message type
*/
DeathMessageType deathMessageType();
/**
* A mutable builder for the {@link DamageTypeRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #messageId(String)}</li>
* <li>{@link #exhaustion(float)}</li>
* <li>{@link #damageScaling(DamageScaling)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends DamageTypeRegistryEntry, RegistryBuilder<DamageType> {
/**
* Sets part of the death message translation key.
*
* @return this builder instance.
* @see DamageTypeRegistryEntry#messageId()
* @see DamageType#getTranslationKey()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder messageId(String messageId);
/**
* Sets the amount of hunger exhaustion caused by this damage type.
*
* @return this builder instance.
* @see DamageTypeRegistryEntry#exhaustion()
* @see DamageType#getExhaustion()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder exhaustion(float exhaustion);
/**
* Sets the {@link DamageScaling} for this damage type.
*
* @return this builder instance.
* @see DamageTypeRegistryEntry#damageScaling()
* @see DamageType#getDamageScaling()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder damageScaling(DamageScaling scaling);
/**
* Sets the {@link DamageEffect} for this damage type.
*
* @return this builder instance.
* @see DamageTypeRegistryEntry#damageEffect()
* @see DamageType#getDamageEffect()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder damageEffect(DamageEffect effect);
/**
* Sets the {@link DeathMessageType} for this damage type.
*
* @return this builder instance.
* @see DamageTypeRegistryEntry#deathMessageType()
* @see DamageType#getDeathMessageType()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder deathMessageType(DeathMessageType deathMessageType);
}
}
@@ -0,0 +1,22 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilderFactory;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.function.Consumer;
import org.bukkit.Art;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
@ApiStatus.NonExtendable
public interface InlinedRegistryBuilderProvider {
static InlinedRegistryBuilderProvider instance() {
class Holder {
static final Optional<InlinedRegistryBuilderProvider> INSTANCE = ServiceLoader.load(InlinedRegistryBuilderProvider.class).findFirst();
}
return Holder.INSTANCE.orElseThrow();
}
Art createPaintingVariant(Consumer<RegistryBuilderFactory<Art, ? extends PaintingVariantRegistryEntry.Builder>> value);
}
Loaded 100 of 1086 files, more files were not shown because too many files have changed in this diff. Show more