Compare commits

...
259 Commits
Author SHA1 Message Date
retrooper f46ec64e60 update: 2.8.0 release 2025-05-15 14:33:04 +02:00
retrooper f0d7a8e84d patch: fix tropical fish pattern mappings 2025-05-15 14:12:49 +02:00
retrooper ac4fac85ed Merge pull request #1220 from Loyisa/2.0
fix: minecraft:air isn't empty in <1.11
2025-05-14 23:49:46 +02:00
retrooper 8f274e0695 Merge pull request #1224 from Bram1903/fix/legacy-item-damage
Fixed: ItemStack#getDamageValue & ItemStack#setDamageValue
2025-05-14 13:03:45 +02:00
Bram cd0892ffe4 Fixed: ItemStack#getDamageValue & ItemStack#setDamageValue on version 1.12.2 and below 2025-05-11 20:42:43 +02:00
Loyisa f9398b58f7 fix: minecraft:air isn't empty in 1.8 2025-05-06 18:43:51 +08:00
booky10 9c9f5cf41d Fix missing saddle EquipmentSlotGroup 2025-05-03 17:50:21 +02:00
retrooper 5983395561 chore: update adventure to 4.21.0 (for 1.21.5 support) 2025-05-01 13:35:53 +02:00
retrooper 686bb4fd3f Merge pull request #1216 from Axionize/fix/teleport-flags
Fix Setting RelativeFlags
2025-05-01 13:31:24 +02:00
retrooper ff4ac7eefc Merge pull request #1162 from Rubenicos/fix/field-lookup
Fix recursive field lookup
2025-04-30 21:04:16 +02:00
retrooper 20b52fbcd9 Merge pull request #1212 from Beaness/patch-1
Add missing copy fields to spawn player wrapper
2025-04-30 21:01:33 +02:00
Axionize 424fd149e7 Fix setting relativeflags 2025-04-30 14:24:34 -04:00
Beanes e372f4f30a Add missing copy fields to spawn player wrapper 2025-04-28 21:11:59 +02:00
retrooper b520a2ea99 Merge pull request #1205 from booky10/feat/versioned-itemstacks
Add version and registry context to ItemStacks
2025-04-28 17:51:48 +02:00
booky10 4e4174b7d3 Add version and registry context to ItemStacks
As logic related to ItemStack has changed quite a lot throughout the versions, this now adds a version (and registry) field to ItemStacks
These fields are populated by packetevents automatically when reading ItemStacks

Using this new version, this properly updates the ItemStack api methods to how vanilla handles stuff now
Additionally, this should fix issues related to modern handling of item amounts breaking legacy negative stack sizes
(E.g. see https://github.com/retrooper/packetevents/pull/1192 and https://github.com/retrooper/packetevents/pull/1062)
2025-04-19 04:54:21 +02:00
booky10 0931f7c9e7 Merge remote-tracking branch 'upstream/2.0' into 2.0 2025-04-18 23:33:58 +02:00
booky10 4faf97cdb4 Increase bytebuf capacity when writing zero-byte-suffix for chunk data
See https://github.com/retrooper/packetevents/issues/1202#issuecomment-2816226784 for more info

Fixes #1202
2025-04-18 23:33:30 +02:00
booky 71fa7be70d Merge pull request #1158 from spring-dependency-management/spring-dependency-management-patch-1
Check classes before copying from last
2025-04-18 23:16:33 +02:00
booky a7cb0ce6bf Merge pull request #1177 from Axionize/refactor/eliminate-static-ProtocolManager-USERS-&-CHANNELS-use
Eliminate usage of static ProtocolManager fields which should be accessed on an instance basis
2025-04-18 20:03:04 +02:00
booky10 8fa1b820d4 Don't iterate over all channels when disconnecting a channel without a UUID 2025-04-18 19:09:01 +02:00
booky10 05f42bc9d5 Mark internal fields/methods as internal 2025-04-18 19:08:14 +02:00
booky10 b635dcbe54 Merge branch '2.0' into refactor/eliminate-static-ProtocolManager-USERS-&-CHANNELS-use 2025-04-18 19:01:42 +02:00
booky10 a1def4170c Check if last wrapper is an instance of this wrapper when copying 2025-04-18 18:59:02 +02:00
booky 53f1fc495b Merge pull request #1191 from Axionize/feat/runtime-obselete-annotation
Add new RuntimeObsolete annotation used for checking if a field is obsolete at runtime via reflection
2025-04-18 18:55:37 +02:00
booky10 17086d3017 Add registry #getByNameOrThrow/#getByIdOrThrow api 2025-04-18 18:30:56 +02:00
booky10 d604e9d6af Fix nbt encoding/decoding of MappedEntitySet tags 2025-04-18 18:25:56 +02:00
booky 76aba6fb8d Merge pull request #1159 from spring-dependency-management/spring-dependency-management-patch-2
Add getWrapperClass() to packet type
2025-04-18 18:04:37 +02:00
booky10 5e8ad3e6e2 Add missing wrapper class for structure block packet 2025-04-18 18:00:58 +02:00
booky10 2f780a22a0 Merge branch '2.0' into spring-dependency-management-patch-2 2025-04-18 17:57:47 +02:00
booky 7549b22604 Merge pull request #1192 from ManInMyVan/fix/itemstack-type-getter
make itemstack type getter always return type
2025-04-18 17:48:32 +02:00
booky 8083725b96 Merge pull request #1197 from Luuzzi/2.0
fixed a floating-point issue in .nbt files
2025-04-18 15:31:21 +02:00
booky 3e624ebde5 Merge pull request #1203 from Bram1903/fix/NullDisconnectLog
[Fix] Disconnected `null` due to invalid packet console log
2025-04-18 15:11:19 +02:00
booky 16f031c585 Merge pull request #1204 from MachineBreaker/patch-1
Remove server version check for SelectBundleItem selectedItemIndex check
2025-04-18 13:56:27 +02:00
MachineBreaker 32f7d0b68b Actually remove the version check since its useless 2025-04-18 07:35:36 -04:00
MachineBreaker 8a3a418d05 Use correct server version for SelectBundleItem selectedItemIndex check 2025-04-18 07:33:54 -04:00
Bram 3a76049868 Fixed: Disconnected null due to invalid packet 2025-04-18 13:06:57 +02:00
booky10 e7495c2e85 Remove ingredient from TrimMaterial for 1.21.5 2025-04-14 18:54:45 +02:00
booky10 a2726516b3 Fix 1.21.5 player chat message writing 2025-04-14 18:50:36 +02:00
booky10 bf57fef29c Remove template item from TrimPattern for 1.21.5 2025-04-14 18:06:43 +02:00
retrooper a9679cd5b2 Merge pull request #1199 from bridgelol/patch-1
chore: bump adventure to 4.20.0
2025-04-12 14:39:52 +02:00
Bridge 8e3eba761d chore: bump adventure to 4.20.0 2025-04-12 14:02:04 +02:00
retrooper b4ef9b90b9 patch: slight change to project description 2025-04-12 09:35:39 +02:00
Luuzzi b2ccbe0bed fixed a floating-point issue in .nbt files 2025-04-11 09:49:35 +03:00
ManInMyVan 1913c6603e make itemstack type getter always return type 2025-04-07 17:25:52 -06:00
Axionize 9eafaaab7d Add new RuntimeObsolete annotation used for checking if a field is obsolete at runtime via reflection 2025-04-07 18:05:40 -04:00
booky e672aa2b92 Merge pull request #1190 from retrooper/revert-1180-fix/fix-goat-horn-cooldown
Revert "Fix Goat Horn Cooldown"
2025-04-07 23:02:46 +02:00
retrooper 1ba1ec17fa Revert "Fix Goat Horn Cooldown" 2025-04-07 18:02:46 +02:00
booky10 288b0a5bed Fix instrument component for versions older than 1.21.5 2025-04-07 15:40:56 +02:00
booky10 2bc4056c9c Don't use MappedEntity instance for extracting TypesBuilderData when defining in registry
Fixes https://github.com/retrooper/packetevents/issues/1187
2025-04-07 15:28:31 +02:00
retrooper 1c0b85a689 Merge pull request #1180 from Axionize/fix/fix-goat-horn-cooldown
Fix Goat Horn Cooldown
2025-04-06 13:59:41 +02:00
retrooper 51e2538ea4 patch: slight changing of messaging 2025-04-06 13:36:12 +02:00
booky10 47645e4ea0 Fix backwards compatibility packet wrapper creation in chunk reader 2025-04-05 18:25:40 +02:00
booky10 5aa121db9a Update entity types to 1.21.5
Fixes https://github.com/retrooper/packetevents/issues/1186
2025-04-05 14:06:32 +02:00
spring-dependency-management c32300cd04 rebase on 1.21.5 2025-04-05 02:01:15 +01:00
retrooper 0d9b183ea1 feat: support earlier access of player object (as soon as JOIN_GAME packet) on spigot 2025-04-04 23:16:42 +02:00
retrooper a215fd9b4d add .kotlin from buildSrc to gitignore 2025-04-04 21:00:30 +02:00
retrooper 2ffb9335b3 Merge pull request #1174 from booky10/feat/1.21.5-support
1.21.5 support
2025-04-04 20:57:35 +02:00
retrooper d9ddf4e598 feat: bump version up to 2.8.0-SNAPSHOT 2025-04-04 20:52:14 +02:00
retrooper eb3b9593be patch: add missing copyright statement 2025-04-04 20:31:42 +02:00
booky e49b989025 Merge pull request #1139 from ytnoos/fix-wrappers
Fixed some wrappers
2025-04-01 14:37:40 +02:00
booky fdd7947728 Merge pull request #1171 from Axionize/fix/mark-embedded-channels-as-fake
Mark embedded channels as fake
2025-04-01 14:28:45 +02:00
booky cc4b69acf5 Merge pull request #1166 from ManInMyVan/fix/trial-spawner-requiresCorrectTool
fix trial spawner requiresCorrectTool
2025-04-01 14:27:37 +02:00
booky 3139282035 Merge pull request #1176 from ManInMyVan/fix/sus-gravel-sand-requiresCorrectTool
fix suspicious gravel and sand requiresCorrectTool
2025-04-01 14:26:38 +02:00
booky10 9a721c79d5 Don't write entity type tags below 1.14 2025-03-31 18:55:24 +02:00
booky10 5c4ccc544c Fix a lot of random registry issues 2025-03-31 18:47:52 +02:00
booky10 751b93c51f Setup registry registration check
Validates that all registry entries have been defined
2025-03-31 18:16:20 +02:00
booky10 1a0c9da630 Add more command argument type mappings 2025-03-31 18:02:45 +02:00
booky10 383a680a70 Fix legacy support for attributes 2025-03-31 17:47:40 +02:00
booky10 83e600c301 Fix Chunk_v1_9 writing on proxy 2025-03-31 17:41:25 +02:00
booky10 f69eb78aa4 Small legacy palette improvements 2025-03-31 17:41:11 +02:00
booky10 c046bd5a9d Use correct server version when reading/writing Chunk_v1_9
Fixes errors on proxies
2025-03-31 17:32:42 +02:00
booky10 8740a5ed0f Don't skip prefix of zero-bytes if it doesn't exist
Thanks ViaVersion!
2025-03-31 17:19:09 +02:00
booky10 9e89b0a5c7 Fix WrapperPlayServerTeams 1.21.5 reading 2025-03-31 17:15:07 +02:00
booky10 5b45f3c634 Fix entity data type names 2025-03-31 17:02:12 +02:00
booky10 a95250f4f7 Save bits per entry in data palette
If the amount of bits gets changed while constructing the palette, the storage would have the wrong length of data
Instead, be safe and get the amount of bits from the palette after its construction
2025-03-31 16:55:44 +02:00
booky10 fb31dab995 Small chunk palette cleanup
Also adds back proper resizing to block state list palettes
2025-03-31 16:32:18 +02:00
booky10 d3aba54f69 Handle 1.21.5 broken mojang zero byte suffix
See https://bugs.mojang.com/browse/MC-296121
2025-03-31 16:31:32 +02:00
booky10 e823e17f69 Fix hover event text reading 2025-03-31 15:40:02 +02:00
booky10 98e46dd38a Add remaining components types for 1.21.5 2025-03-31 15:08:43 +02:00
booky10 405caec719 Merge branch '2.0' into feat/1.21.5-support 2025-03-31 13:59:01 +02:00
booky10 c32b1b90b1 Default model type of chicken/cow/pig variants to normal 2025-03-31 13:58:10 +02:00
booky 2272315d83 Merge pull request #1181 from AoElite/conversion-fix
Keep block property order to fix conversions
2025-03-31 07:32:54 +02:00
AoElite dfd8eccf87 add a basic test for material conversions 2025-03-31 00:32:32 -04:00
AoElite b826fbc197 block data property order needs to be preserved 2025-03-31 00:32:27 -04:00
booky10 878c7a96d6 Update adventure nbt serializer to 1.21.5 2025-03-30 23:06:31 +02:00
booky10 3a1474c5a6 Add per-version adventure serializers
Required for changes done to click/hover events in 1.21.5
2025-03-30 22:45:40 +02:00
booky10 0f94fc8216 Fix unbreakable item component legacy handling 2025-03-30 21:50:41 +02:00
booky10 445893d664 Fix ItemEquippable reading for 1.21.5 2025-03-30 21:46:30 +02:00
booky10 e8cc99fa0d Add can_destroy_blocks_in_creative field to tool item component for 1.21.5 2025-03-30 21:45:51 +02:00
booky10 9948837294 Ensure base components get fully read 2025-03-30 21:40:38 +02:00
booky10 3e0191aa17 Remove chunk data palette length prefix for 1.21.5 2025-03-30 21:23:17 +02:00
booky10 8a3ee34e28 Small cleanup for chunk palette resizing 2025-03-30 21:10:45 +02:00
booky10 ae317c535b Merge remote-tracking branch 'origin/feat/1.21.5-support' into feat/1.21.5-support 2025-03-30 20:07:13 +02:00
booky10 2949af533f Refactor chunk data reading/writing
This deprecates NetStreamInput/NetStreamOutput as they just duplicate PacketWrapper api and do not carry as much context as a PacketWrapper, which is required for proper proxy support

This is a pretty big change to how chunk reading/writing currently works and should therefore be tested on a lot of versions
2025-03-30 20:05:20 +02:00
retrooper e90f377c61 patch: imports of certain test files were removed by ide (for some odd reason) 2025-03-30 19:26:12 +02:00
retrooper 088ded2190 patch: add forgotten copyright statements 2025-03-30 19:20:26 +02:00
Axionize 93a6e3f5ed Fix Goat Horn Cooldown
Cooldown Length: 7.0 seconds
Resource Group: minecraft:goat_horn
Encoded String: QOAAAAETbWluZWNyYWZ0OmdvYXRfaG9ybg==

See: https://github.com/retrooper/packetevents/pull/1180#issuecomment-2764633510
2025-03-30 12:37:35 -04:00
booky10 63a6b158eb Verify reader index change when reading length-prefixed item component patches 2025-03-30 16:25:52 +02:00
booky10 c471b691f7 Update smithing trim slot display to 1.21.5 2025-03-30 16:14:23 +02:00
booky10 b2c4bb8928 Add new test block related block entity types for 1.21.5 2025-03-30 15:53:48 +02:00
booky10 253d5f968e Merge branch '2.0' into feat/1.21.5-support 2025-03-30 14:47:46 +02:00
booky10andAxionize 533274fd45 Fix WrappedBlockState stringification
Co-authored-by: Axionize <154778082+axionize@users.noreply.github.com>

Closes #1179
2025-03-30 14:45:24 +02:00
booky10 4a35ebf7eb Bump fabric loom, parchment mappings and fabric loader 2025-03-30 05:21:26 +02:00
booky10 9dd45ffc48 Update gradle wrapper to v8.13 2025-03-30 05:16:36 +02:00
booky10 1e8bee4179 Fix workflow distribution config
This should've errored long ago, adopt is already gone since summer 2021
2025-03-30 05:08:53 +02:00
booky10 b367e1da91 Fix static mapped entity constructors 2025-03-30 05:03:41 +02:00
booky10 2808e35234 Add equipOnInteract field to equippable component 2025-03-30 04:59:41 +02:00
booky10 df7b69249b Correctly implement "EitherHolder" 2025-03-30 04:52:49 +02:00
booky10 6650ee5d64 Update tooltip show flag in remaining components 2025-03-30 04:23:03 +02:00
booky10 c75e137bd0 Add type parameter to EntityData
Yes, this is a compile-time breaking change
2025-03-30 04:15:31 +02:00
booky10 57d00aaa4e Update entity data serializers to 1.21.5 2025-03-30 04:11:11 +02:00
booky10 e8a95aeb8e Update wolf variant encoding to 1.21.5 2025-03-30 03:51:18 +02:00
booky10 2fcdce578d Fix wolf variant default registry 2025-03-30 03:46:09 +02:00
booky10 ac729a30e3 Implement cat variant registry 2025-03-30 03:43:34 +02:00
booky10 2b626d38b1 Fully implement pig, frog, cow and chicken variant registries 2025-03-30 03:41:02 +02:00
booky10 a5d3633088 Implement wolf sound variant registry 2025-03-30 03:17:05 +02:00
booky10 c79cea2b42 Add registry synchronization todos 2025-03-30 01:54:00 +01:00
booky10 9c4e438099 Add new 1.21.5 particle types 2025-03-30 01:51:19 +01:00
booky10 7572eeb5ca Add more new item components 2025-03-30 01:49:46 +01:00
booky10 b78f8369f4 Implement basic component matcher support for adventure predicate item component 2025-03-30 01:30:30 +01:00
booky10 881898d788 Add potion duration scale item component 2025-03-30 00:48:20 +01:00
booky10 c355dbf1fc Add blocks attack item component 2025-03-30 00:47:48 +01:00
booky10 17262757ce Add weapon component 2025-03-30 00:30:19 +01:00
booky10 e890fcd7e5 Add new tooltip display component 2025-03-30 00:23:25 +01:00
booky10 90ff84471f Update unbreakable data component 2025-03-30 00:12:26 +01:00
booky10 963643bdeb Update creative inventory item packet to 1.21.5 2025-03-30 00:00:30 +01:00
booky10 12c2c307eb Implement length-prefixed item data component serialization 2025-03-29 23:57:46 +01:00
booky10 a4fefad9e6 Refactor item stack serialization to separate class 2025-03-29 23:15:29 +01:00
booky10 9bb7b6e458 Update WrapperPlayClientClickWindow to 1.21.5 2025-03-29 22:44:27 +01:00
booky10 18ed3fb529 Add initial HashedStack structure 2025-03-29 22:44:21 +01:00
booky10 6c70181d77 Implement support for new heightmap encoding in 1.21.5 2025-03-29 22:16:19 +01:00
booky10 ed848d93d3 Add WrapperPlayServerTestInstanceBlockStatus 2025-03-29 21:58:22 +01:00
booky10 db30205fa6 Add WrapperPlayClientSetStructureBlock 2025-03-29 21:54:08 +01:00
booky10 d33cb38f15 Add new 1.21.5 block state properties 2025-03-29 21:38:04 +01:00
booky10 1371809b37 Update sound events to 1.21.5 2025-03-29 21:29:37 +01:00
booky10 3a24bed6fb Update item tags for 1.21.5 2025-03-29 21:24:52 +01:00
booky10 ab5f4ee049 Update block tags for 1.21.5 2025-03-29 21:24:48 +01:00
booky10 da8bdd9384 Add new 1.21.5 state type constants 2025-03-29 21:16:57 +01:00
booky10 7e398fe45a Add new 1.21.5 item type constants 2025-03-29 21:16:53 +01:00
booky10 1f6314a262 Update item type base components 2025-03-29 21:10:17 +01:00
booky10 2c238c251e Update block state mappings 2025-03-29 21:10:09 +01:00
booky10 0018d60f9c Merge branch '2.0' into feat/1.21.5-support 2025-03-29 20:36:56 +01:00
booky10andAmmo f9670a71b1 Update last seen messages to 1.21.5
Co-authored-by: Ammo <ammo@slne.dev>
2025-03-29 20:36:32 +01:00
booky10 bede82c866 Add some more javadoc comments regarding new 1.21.5 additions 2025-03-29 20:35:20 +01:00
Ammo d5cca6490f feat: Update clientbound player team packet to use enums for name tag visibility and collision rule 2025-03-29 20:31:12 +01:00
Ammo 8f920cd6cc feat: Validate selectedItemIndex in WrapperPlayClientSelectBundleItem 2025-03-29 20:26:39 +01:00
Ammo 06eb3f4b90 chore: Update Minecraft version to 1.21.5 in gradle.properties of fabric to have access to nms classes 2025-03-29 20:24:53 +01:00
booky10 e57002768b Finish WrapperPlayClientTestInstanceBlockAction 2025-03-29 20:23:39 +01:00
booky10 a85de1cef2 Small chat message read/write cleanup 2025-03-29 20:23:33 +01:00
Axionize 39d45d8d1f Remove usage of direct external/public static references to ProtocolManager.CHANNELS and ProtocolManager.USERS
Fields will remain accessible for backwards compatibility in the unlikely case of a developer meddling these values in their own code.

All usage of both these fields is now wrapped in interface methods which can be overwritten by other ProtocolManagers.
2025-03-29 03:56:34 -04:00
retrooper 1bb6268a62 feat: add support for 1.21.5 in chat message packet 2025-03-28 20:46:53 +01:00
retrooper 4c87f3fce1 feat: set test block wrapper added 2025-03-28 20:12:49 +01:00
retrooper 86358c3fe9 Merge pull request #1148 from booky10/feat/lazy-loaded-registries
Registry cleanup and lazy-loaded block state mappings
2025-03-28 19:33:33 +01:00
ManInMyVan 34846df85b fix suspicious gravel and sand requiresCorrectTool 2025-03-27 20:19:04 -06:00
booky10 5b214e4187 Add 1.21.5 resource_selector command argument parser 2025-03-25 21:03:35 +01:00
booky10 5280f26e00 Setup 1.21.5 packet ids 2025-03-25 21:00:31 +01:00
booky10 8226aed28e Add 1.21.5 client and server version constants 2025-03-25 20:39:05 +01:00
Axionize ec4496f837 Add EmbeddedChannel as a FakeChannel name
- This prevents Carpet mod players from not fully existing/being invisible
- EmbeddedChannel is a standard netty channel used to mock/simulate a netty channel, and isn't used for actual player connections on any platform
2025-03-23 03:54:36 -04:00
booky10 91730fdb46 Add javadoc to User#getConnectionState
See https://github.com/retrooper/packetevents/issues/1170
2025-03-19 20:18:19 +01:00
ytnoos c892a15c5a Fixed write for 1.7 WrapperPlayClientTabComplete 2025-03-16 14:15:39 +01:00
ytnoos 2fc6613df0 Added WrapperPlayClientEditBook setters 2025-03-16 14:15:11 +01:00
ytnoos cf0a3115f0 Merge remote-tracking branch 'upstream/2.0' into fix-wrappers 2025-03-16 14:12:42 +01:00
ManInMyVan 513b970c4d fix trial spawner requiresCorrectTool 2025-03-14 11:59:52 -06:00
Rubén 2b03bbce7c Fix recursive field lookup 2025-03-08 12:14:06 -06:00
spring-dependency-management 319568d92a oops 2025-03-06 19:10:27 +00:00
spring-dependency-management f666047ae5 Some missing oops 2025-03-06 16:56:13 +00:00
spring-dependency-management e86beec90f add interface 2025-03-06 16:55:55 +00:00
spring-dependency-management 3d416fc961 Add getWrapperClass() to packet type 2025-03-06 16:47:50 +00:00
spring-dependency-management 2cd2f5d7f9 Check classes before copying 2025-03-06 15:35:31 +00:00
booky10 688e32d9a6 Merge branch '2.0' into feat/lazy-loaded-registries 2025-03-02 19:01:45 +01:00
booky ef49276809 Merge pull request #1155 from booky10/fix/bungee-injection-v2
Support bungee's new combined compressor
2025-03-02 19:00:13 +01:00
booky a3116dc2a6 Merge pull request #1149 from Axionize/fix/fabric-call-user-login-event
Fire UserJoinEvent() on Fabric
2025-03-02 18:57:54 +01:00
booky 3fda55bc39 Merge pull request #1134 from Axionize/fix/painting-registry-id-mappigns
Make PE painting IDs consistent
2025-03-02 18:54:59 +01:00
booky f78294afb4 Merge pull request #1140 from ytnoos/exceptiong-handling
Improved exception handling
2025-03-02 18:47:42 +01:00
booky 0a30904217 Merge pull request #1138 from ytnoos/propagate-exception
Propagate exception while reading NBT
2025-03-02 18:42:10 +01:00
booky 8a1506ee53 Merge pull request #1135 from Axionize/feat/cache-values-of-direction-for-fast-int-to-enum
Add new methods to Direction Enum and optimize by caching values array
2025-03-02 18:39:25 +01:00
booky10 795798de41 Read any number tag as enchantment level
Previously, packetevents would have only parsed shorts as the enchantment level
2025-03-02 18:30:56 +01:00
booky10 fed7c147d8 Support bungee's new combined compressor
See: https://github.com/SpigotMC/BungeeCord/commit/774a6fd68c8fbbb99b6bbe8c0060820f8c3b059e

Bungee combined both the frame encoder and the compressor, which makes handling compression a lot easier
This should still support both the old and the new compression setup
2025-03-02 03:39:00 +01:00
booky10 5cdb80c002 Account for null in-flight connection in velocity
Fixes https://github.com/retrooper/packetevents/issues/1142
2025-02-28 22:46:29 +01:00
booky10 57add57796 Try to do less server version lookups
Every call to do a server version lookup will return an invalid value for proxy servers
2025-02-28 22:45:18 +01:00
Axionize f7a72713e1 Fire UserJoinEvent() on Fabric 2025-02-28 15:27:55 -05:00
booky10 2c0a5346f4 Fix error when trying to load mappings for invalid mapping version 2025-02-28 20:47:15 +01:00
booky10 3627cd4d5a Reset reader index before resetting writer index
The writer index can't be smaller than the reader index according to netty buffers
2025-02-28 20:03:48 +01:00
booky10 6f39702af7 Ensure mapping data gets unloaded from all registries via test 2025-02-28 20:01:23 +01:00
booky10 fe316a4368 Small refactor to ClassStructureTest 2025-02-28 19:49:27 +01:00
booky10 e026ef8181 Move anonymous map decoration type class implementation to outer class 2025-02-28 19:39:54 +01:00
booky10 d9e78b71a6 Convert hard-coded villager professions to a registry 2025-02-28 19:36:49 +01:00
booky10 92fc265333 Convert hard-coded score format types to a registry 2025-02-28 19:32:56 +01:00
booky10 d75137fe5f Convert hard-coded villager types to a registry 2025-02-28 17:55:38 +01:00
booky10 3d90acad8e Fix class structure of mapped entity implementations 2025-02-28 17:48:03 +01:00
booky10 dc3c168d84 Implement class structure test
This ensures consistent usage of annotations and common method/field names for registry-related stuff
2025-02-28 17:47:01 +01:00
booky10 8a5d4fc3e0 Use a single buffer for parsing an item component map 2025-02-28 16:35:02 +01:00
booky10 8cbfde0c3f Convert particle types to a registry 2025-02-28 16:26:20 +01:00
booky10 9dc5908c5e Fix mapping file names in remaining registries 2025-02-28 16:17:29 +01:00
booky10 3bdab06db4 Convert sound events to a registry 2025-02-28 16:15:56 +01:00
booky10 e08b5f69bf Convert legacy recipe serializers to a registry 2025-02-28 16:12:22 +01:00
booky10 f6e76b65b6 Convert potions to a registry 2025-02-28 16:08:39 +01:00
booky10 bbf8749f1e Convert position source types to a registry 2025-02-28 16:06:50 +01:00
booky10 d4f7f64fc6 Convert entity types to a registry
Also refactor entity type instance checking logic
2025-02-27 22:53:43 +01:00
booky10 4a9cd4b8aa Convert entity data types to a registry
Also refactor reader/writer handling logic
2025-02-27 21:08:13 +01:00
booky10 83ae030352 Convert state types to a registry 2025-02-27 19:00:54 +01:00
booky10 88b3b00c43 Convert command argument parsers to a registry 2025-02-27 18:51:19 +01:00
booky10 3b9c3632ad Implement new item base components storage format 2025-02-27 18:47:09 +01:00
booky10 e8a8f0d0a3 Implement new mappings storage format for data mappings 2025-02-27 18:37:52 +01:00
booky10 113b4a84c2 Refactor how mappings are stored
These changes were done to split the block state mappings up into multiple files to prevent lazy-loading having to skip over the entire file for modern versions and to align mapping file names with vanilla registry names

Additionally, this also splits item base components into multiple files to prepare for lazy loading them too, as they will probably also constantly grow in size with each new release
2025-02-27 18:27:03 +01:00
booky10 a9a6c11402 Move each mappings file to a separate directory 2025-02-27 16:41:38 +01:00
booky10 2cb427e06d Small refactor for state data cache map 2025-02-24 17:56:17 +01:00
booky10 22bea4e7b0 Ensure loading of WrappedBlockState on all platforms 2025-02-24 17:43:13 +01:00
booky10 6703db2528 Add system property to force eager loading of all block state mappings 2025-02-24 17:41:21 +01:00
booky10 44223018b0 Implement lazy loading of block state mappings 2025-02-24 17:30:34 +01:00
booky10 d7b677c4db Convert block state map-in-map to map-in-array 2025-02-24 15:56:42 +01:00
retrooper e531e434b6 updated velocity to 3.4.0-SNAPSHOT, fixing build errors 2025-02-17 11:33:27 +01:00
booky10 97dcbc606e Fix login packet fields being read in wrong order
Fixes #1086
2025-02-13 16:11:18 +01:00
Axionize 4d55df1569 Add getting method for VALUES array and makes it private 2025-02-13 07:51:17 -05:00
ytnoos a028653207 Invert handshaking state check 2025-02-12 14:36:50 +01:00
Axionize 0d92230183 Add new methods to Direction enum and optimize by caching values array 2025-02-12 08:34:47 -05:00
ytnoos 5c6c41e62f Improved excpetiong handling 2025-02-12 12:51:43 +01:00
ytnoos 88ff380bbd Fixed WrapperPlayClientEditBook for <1.17.1 2025-02-12 12:31:30 +01:00
ytnoos 8dd207ccec Fixed WrapperPlayClientTabComplete for 1.7 2025-02-12 12:24:26 +01:00
ytnoos 73426fb7bf Propagate exception while reading NBT 2025-02-12 12:23:09 +01:00
Axionize 3f13e4374a Make PE painting IDs consistent
Modern Minecraft sends paintings over the network with ids not representing registration order, but rather alphabetical order.

This commit reorders the painting mappings to all be done in alphabetical order so the index IDs match up with vanilla.
2025-02-10 17:48:44 -05:00
retrooper 478a3e56c3 Merge pull request #1128 from booky10/feat/more-packet-user-utils
Add missing send/write/receive packet utils to User
2025-01-31 23:52:31 +01:00
booky10 699594090a Add missing send/write/receive packet utils to User 2025-01-31 12:09:34 +01:00
booky10 2a137b0059 Fix potted eye blossom blocking/solid flags 2025-01-23 15:32:11 +01:00
booky10 81c53d3c4c Mark resin brick wall as "shape exceeds cube" 2025-01-23 15:30:37 +01:00
booky c824f9c835 Merge pull request #1108 from spring-dependency-management/fix-fence
Fix pale oak materials
2025-01-23 14:44:07 +01:00
booky10 e1df40710e Fix incorrect shadow color deserialization/serialization
Previously, packetevents expected shadow color to be serialized as a hex string
Vanilla serializes shadow colors as a single integer instead
2025-01-18 20:13:45 +01:00
booky 6507a73042 Merge pull request #1110 from AoElite/2.0
add method to user to write packets silently
2025-01-12 03:09:12 +01:00
AoElite 6a99936110 add method to user to write packets silently 2025-01-11 21:04:04 -05:00
spring-dependency-management 93441ece77 Fix sapling, hanging sign, button, and moss carpet 2025-01-07 23:56:34 +00:00
spring-dependency-management f5776682ce Fix pale oak hanging sign 2025-01-07 23:49:35 +00:00
spring-dependency-management be264f3d81 Fix pale oak wall sign 2025-01-07 23:48:07 +00:00
spring-dependency-management 8fcef1d834 Fix pale oak sign 2025-01-07 23:46:55 +00:00
spring-dependency-management 8210bb32da Sapling is of type plant, not wood 2025-01-07 23:43:30 +00:00
spring-dependency-management 8b3ddb7b47 Fix pale oak pressure plate 2025-01-07 23:39:02 +00:00
spring-dependency-management dcb3e5e1cd .isShapeExceedsCube(true) for pale oak 2025-01-07 23:35:05 +00:00
retrooper 3d2a872de1 Merge pull request #1105
Keep Alive Version Check from V_1_12 to V_1_12_2
2025-01-06 00:25:07 +01:00
retrooper 61f5158279 patch: version check correction in WrapperPlayServerKeepAlive 2025-01-06 00:21:45 +01:00
scienziato1pazzo ce481cfdb0 fixed keep alive 2025-01-04 00:01:55 +01:00
retrooper 3d5c294f64 update wiki vg link 2024-12-23 20:03:14 +01:00
retrooper 4f0678d782 Merge pull request #1098 from divinepablo/patch-1
Update protocol link
2024-12-23 20:02:07 +01:00
divine 9b1f7a372c Update protocol link
wiki.vg merged with minecraft.wiki
2024-12-23 12:33:31 -05:00
retrooper 9a1ee3d888 update to adventure 4.18.0 2024-12-23 10:34:20 +01:00
retrooper 4f20680d5b Revert "Temporarily revert shadow color support"
This reverts commit 0be838c58f.
2024-12-23 10:20:31 +01:00
retrooper dd5a25eb66 Merge pull request #1097 from HaHaWTH/fix/folia-scheduling 2024-12-23 00:20:29 +01:00
HaHaWTH 3a3f8c498c Use correct scheduler for tasks
In some rare cases, player may be teleported during join and kick will fail
2024-12-22 13:55:28 -08:00
booky f603b49a3e Merge pull request #1053 from Axionize/fix-legacy-grass-and-tallgrass-mappings
Fix legacy mappings for grass and tallgrass variants
2024-12-22 06:34:54 +01:00
booky 52e182e7f0 Merge pull request #1058 from ManInMyVan/player-digging-face-id
add faceid to WrapperPlayClientPlayerDigging
2024-12-22 06:29:59 +01:00
booky10 7cc925120e Add some missing entity type ids for 1.8 through 1.11 2024-12-22 05:57:15 +01:00
booky10 603cb07c27 Fix wrong skeleton entity type id for versions older than 1.11
Fixes #1068
2024-12-22 05:57:14 +01:00
booky 7b5019ba87 Merge pull request #1047 from Axionize/coral-tags
Extend coral plant blocktags
2024-12-22 05:21:26 +01:00
libraryaddictandbooky10 40f6b2fca4 Fix incorrect sound mappings for 1.19.4
Closes #1059

I didn't merge the original PR as it breaks sound mappings for 1.19.3

Co-authored-by: booky10 <boooky10@gmail.com>
2024-12-22 05:15:35 +01:00
booky10 1e50c5d6cb Fix jukebox playable item component reading/writing
Packetevents didn't account for a jukebox song referring to a registry entry and always assumed it was an inlined jukebox song

See https://github.com/GrimAnticheat/Grim/issues/1892
2024-12-18 20:44:44 +01:00
booky10 d46db268f8 Fix damage event packet wrapper not using network synchronized registries 2024-12-16 20:16:59 +01:00
retrooper 8f5b549b84 bump version up to 2.7.1 snapshot 2024-12-10 22:47:54 +01:00
Axionize 770a9cd996 Fix CORAL_PLANTS blocktag and add new ALIVE_CORAL_PLANTS and DEAD_CORAL_PLANTS blocktags 2024-12-07 02:37:53 -05:00
Axionize 6afe377b55 Fix legacy mappings for shortgrass item returning tallgrass 2024-12-07 02:33:57 -05:00
Axionize fad73d2814 Fix legacy mappings for grass and tallgrass variants 2024-12-07 02:33:32 -05:00
ManInMyVan 0666097934 add faceid to WrapperPlayClientPlayerDigging 2024-11-08 16:52:35 -07:00
461 changed files with 2348521 additions and 2137401 deletions

No files matched your search

+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'adopt'
distribution: 'temurin'
cache: 'gradle'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
+3
View File
@@ -123,3 +123,6 @@ run/
.project
.settings/
.classpath
# Build Source Kotlin
/buildSrc/.kotlin/
+3 -3
View File
@@ -1,7 +1,7 @@
<!--suppress HtmlDeprecatedAttribute -->
<div align="center">
<h2><i>packetevents</i></h2>
<h3><i>Precision meets performance—a powerful tool for mastering Minecraft packet manipulation with speed and finesse.</i></h3>
<h2><i>PacketEvents</i></h2>
<h3><i>A powerful networking library for Minecraft packet processing and manipulation.</i></h3>
<a href="https://github.com/retrooper/packetevents/actions"><img src="https://img.shields.io/github/actions/workflow/status/retrooper/packetevents/gradle-publish.yml?style=for-the-badge&logo=github"></a>
<a href="https://discord.gg/DVHxPPxHZc"><img src="https://img.shields.io/discord/721686193061888071?color=5562e9&logo=discord&logoColor=white&style=for-the-badge"></a>
<img src="https://img.shields.io/github/license/retrooper/packetevents?style=for-the-badge&logo=github">
@@ -35,7 +35,7 @@
<i>Here are some projects that we are heavily inspired by, thus we have integrated</i>\
<i>small portions of their code into our work.</i>
[Protocol Documentation for the Minecraft Java Edition](https://wiki.vg/Protocol)\
[Protocol Documentation for the Minecraft Java Edition](https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol)\
[ViaVersion](https://github.com/ViaVersion/ViaVersion)\
[ProtocolSupport](https://github.com/ProtocolSupport/ProtocolSupport)\
[adventure](https://github.com/KyoriPowered/adventure)\
+13 -66
View File
@@ -1,6 +1,6 @@
import com.github.retrooper.compression.strategy.JsonArrayCompressionStrategy
import com.github.retrooper.compression.strategy.JsonObjectCompressionStrategy
import com.github.retrooper.compression.strategy.JsonToNbtStrategy
import com.github.retrooper.compression.strategy.dir.JsonBase64DataDirStrategy
import com.github.retrooper.compression.strategy.dir.JsonRegistryCompressionDirStrategy
import com.github.retrooper.compression.strategy.dir.JsonToNbtDirStrategy
import com.github.retrooper.excludeAdventure
plugins {
@@ -39,76 +39,21 @@ dependencies {
testImplementation(testlibs.slf4j)
testImplementation(testlibs.bundles.junit)
testImplementation(libs.netty)
testImplementation(libs.classgraph)
}
mappingCompression {
mappingDirectory = rootDir.resolve("mappings")
outDirectory = project.layout.buildDirectory.dir("mappings/generated/assets/mappings")
with<JsonToNbtStrategy> {
compress("block/legacy_block_mappings.json")
compress("block/modern_block_mappings.json")
compress("enchantment/enchantment_type_data.json")
compress("item/item_base_components.json")
compress("stats/statistics.json")
compress("world/biome_data.json")
with<JsonToNbtDirStrategy> {
compress("data")
}
with<JsonArrayCompressionStrategy> {
compress("attribute/attribute_mappings.json")
compress("block/block_entity_type_mappings.json")
compress("block/block_type_mappings.json")
compress("chat/chat_type_mappings.json")
compress("command/argument_parser_mappings.json")
compress("damage/damagetype_mappings.json")
compress("enchantment/effect_component_type.json")
compress("entity/entity_data_type_mappings.json")
compress("entity/painting_mappings.json")
compress("entity/wolf_variant_mappings.json")
compress("item/consume_effect_type_mappings.json")
compress("item/equipment_asset_mappings.json")
compress("item/item_banner_pattern_mappings.json")
compress("item/item_component_mappings.json")
compress("item/item_instrument_mappings.json")
compress("item/item_jukebox_song_mappings.json")
compress("item/item_map_decoration_type_mappings.json")
compress("item/item_potion_mappings.json")
compress("item/item_trim_material_mappings.json")
compress("item/item_trim_pattern_mappings.json")
compress("item/recipe_book_category.json")
compress("item/recipe_display_types.json")
compress("item/recipe_serializer_mappings.json")
compress("item/recipe_slot_display_types.json")
compress("particle/particle_type_mappings.json")
compress("sound/sound_mappings.json")
compress("world/biome_mappings.json")
compress("world/world_position_source_mappings.json")
with<JsonBase64DataDirStrategy> {
compress("item_base_components")
}
with<JsonObjectCompressionStrategy> {
compress("enchantment/enchantment_type_mappings.json")
compress("entity/entity_effect_mappings.json")
compress("entity/entity_type_mappings.json")
compress("entity/legacy_entity_type_mappings.json")
compress("item/item_type_mappings.json")
compress("world/dimension_type_mappings.json")
with<JsonRegistryCompressionDirStrategy> {
compress("registries")
}
}
@@ -145,7 +90,9 @@ tasks {
shadowJar {
exclude {
val path = it.path
path.startsWith("net/kyori") && !path.startsWith("net/kyori/adventure/text/serializer") && !path.startsWith("net/kyori/option")
path.startsWith("net/kyori") && !path.startsWith("net/kyori/adventure/text/serializer") && !path.startsWith(
"net/kyori/option"
)
}
}
}
@@ -0,0 +1,28 @@
package com.github.retrooper.packetevents.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.Documented;
/**
* Marks an API element as obsolete and makes this information available
* at runtime via reflection. Use in conjunction with an IDE-recognized
* annotation like @ApiStatus.Obsolete if IDE warnings are also desired.
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD}) // Adjust targets as needed
public @interface RuntimeObsolete {
/**
* Specifies in which version the API became obsolete.
* Should generally match the value in the corresponding @ApiStatus.Obsolete annotation.
*/
String since() default "";
/**
* Optional: Add a reason or replacement suggestion.
*/
String reason() default "";
}
@@ -145,6 +145,9 @@ public abstract class ProtocolPacketEvent extends PacketEvent implements PlayerE
return (T) player;
}
/**
* Gets the connection state this packet has been sent/received in.
*/
public ConnectionState getConnectionState() {
return connectionState;
}
@@ -35,6 +35,8 @@ public interface ChannelInjector {
void setPlayer(Object channel, Object player);
boolean isPlayerSet(Object channel);
boolean isProxy();
default PacketSide getPacketSide() {
@@ -65,7 +65,7 @@ public class InternalPacketListener extends PacketListenerAbstract {
//Map username with channel
synchronized (channel) {
ProtocolManager.CHANNELS.put(profile.getUUID(), channel);
PacketEvents.getAPI().getProtocolManager().setChannel(profile.getUUID(), channel);
}
PacketEvents.getAPI().getLogManager().debug("Mapped player UUID with their channel.");
@@ -19,10 +19,12 @@
package com.github.retrooper.packetevents.manager.player;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.ProtocolPacketEvent;
import com.github.retrooper.packetevents.protocol.ConnectionState;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
public interface PlayerManager {
@@ -34,7 +36,17 @@ public interface PlayerManager {
User getUser(@NotNull Object player);
default ConnectionState getConnectionState(@NotNull Object player) {
/**
* <strong>WARNING</strong>: Usage of this method should be avoided. Please use either
* {@link User#getDecoderState()} or {@link User#getEncoderState()}.<br>
* To access the specific state a packet event was sent/received in, use {@link ProtocolPacketEvent#getConnectionState()}.
* <p>
* Since 1.20.2, the Minecraft protocol allows the decoder/encoder connection states to de-sync.
*
* @throws IllegalStateException if encoder/decoder connection states do not match
*/
@ApiStatus.Obsolete
default ConnectionState getConnectionState(@NotNull Object player) throws IllegalStateException {
return getUser(player).getConnectionState();
}
@@ -33,8 +33,10 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public interface ProtocolManager {
@ApiStatus.Internal
Map<UUID, Object> CHANNELS = new ConcurrentHashMap<>();
// Use SocketAddress because ProtocolLib wraps Channels with NettyChannelProxy class
@ApiStatus.Internal
Map<Object, User> USERS = new ConcurrentHashMap<>();
default Collection<User> getUsers() {
@@ -150,11 +152,13 @@ public interface ProtocolManager {
return USERS.get(pipeline);
}
@ApiStatus.Internal
default User removeUser(Object channel) {
Object pipeline = ChannelHelper.getPipeline(channel);
return USERS.remove(pipeline);
}
@ApiStatus.Internal
default void setUser(Object channel, User user) {
synchronized (channel) {
Object pipeline = ChannelHelper.getPipeline(channel);
@@ -166,4 +170,23 @@ public interface ProtocolManager {
default Object getChannel(UUID uuid) {
return CHANNELS.get(uuid);
}
@ApiStatus.Internal
default void setChannel(UUID uuid, Object channel) {
CHANNELS.put(uuid, channel);
}
@ApiStatus.Internal
default void removeChannel(Object channel) {
CHANNELS.values().remove(channel);
}
@ApiStatus.Internal
default void removeChannelById(UUID uuid) {
CHANNELS.remove(uuid);
}
default boolean hasChannel(Object channel) {
return CHANNELS.containsValue(channel);
}
}
@@ -50,7 +50,7 @@ public enum ServerVersion {
//1.20 and 1.20.1 have the same protocol version. 1.20.3 and 1.20.4 have the same protocol version. 1.20.5 and 1.20.6 have the same protocol version
V_1_20(763), V_1_20_1(763), V_1_20_2(764), V_1_20_3(765), V_1_20_4(765), V_1_20_5(766), V_1_20_6(766),
//1.21 and 1.21.1 have the same protocol version. 1.21.2 and 1.21.3 have the same protocol version
V_1_21(767), V_1_21_1(767), V_1_21_2(768), V_1_21_3(768), V_1_21_4(769),
V_1_21(767), V_1_21_1(767), V_1_21_2(768), V_1_21_3(768), V_1_21_4(769), V_1_21_5(770),
//TODO UPDATE Add server version constant
ERROR(-1, true);
@@ -31,4 +31,6 @@ public interface ByteBufAllocationOperator {
Object compositeBuffer();
Object compositeBuffer(int maxNumComponents);
Object emptyBuffer();
}
@@ -239,6 +239,19 @@ public class ByteBufHelper {
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().resetWriterIndex(buffer);
}
public static Object allocateNewBuffer(Object buffer) {
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().allocateNewBuffer(buffer);
}
public static int getByteSize(int value) {
for (int i = 1; i < 5; ++i) {
if ((value & -1 << i * 7) == 0) {
return i;
}
}
return 5;
}
public static int readVarInt(Object buffer) {
int value = 0;
int length = 0;
@@ -74,6 +74,8 @@ public interface ByteBufOperator {
Object markWriterIndex(Object buffer);
Object resetWriterIndex(Object buffer);
Object allocateNewBuffer(Object buffer);
default float readFloat(Object buffer) {
return Float.intBitsToFloat(readInt(buffer));
}
@@ -52,4 +52,8 @@ public class UnpooledByteBufAllocationHelper {
public static Object compositeBuffer(int maxNumComponents) {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer(maxNumComponents);
}
public static Object emptyBuffer() {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().emptyBuffer();
}
}
@@ -26,8 +26,7 @@ import org.jetbrains.annotations.Nullable;
public final class Attributes {
private static final VersionedRegistry<Attribute> REGISTRY = new VersionedRegistry<>(
"attribute", "attribute/attribute_mappings");
private static final VersionedRegistry<Attribute> REGISTRY = new VersionedRegistry<>("attribute");
private Attributes() {
}
@@ -50,7 +49,7 @@ public final class Attributes {
if (normedName.startsWith(ResourceLocation.VANILLA_NAMESPACE + ":generic.")
|| normedName.startsWith(ResourceLocation.VANILLA_NAMESPACE + ":player.")
|| normedName.startsWith(ResourceLocation.VANILLA_NAMESPACE + ":zombie.")) {
normedName = normedName.substring(name.indexOf('.') + 1);
normedName = normedName.substring(normedName.indexOf('.') + 1);
}
return REGISTRY.getByName(normedName);
}
@@ -22,6 +22,7 @@ import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
public class StaticAttribute extends AbstractMappedEntity implements Attribute {
@@ -31,21 +32,24 @@ public class StaticAttribute extends AbstractMappedEntity implements Attribute {
private final double minValue;
private final double maxValue;
StaticAttribute(
TypesBuilderData data, String legacyPrefix,
@ApiStatus.Internal
public StaticAttribute(
@Nullable TypesBuilderData data, String legacyPrefix,
double defaultValue, double minValue, double maxValue
) {
super(data);
this.defaultValue = defaultValue;
this.minValue = minValue;
this.maxValue = maxValue;
this.legacyName = legacyPrefix == null ? null : new ResourceLocation(
this.legacyName = legacyPrefix == null || data == null ? null : new ResourceLocation(
data.getName().getNamespace(), legacyPrefix + "." + data.getName().getKey());
}
@Override
public ResourceLocation getName(ClientVersion version) {
assert this.data != null; // not marked as nullable in ctor
if (this.data == null) {
throw new UnsupportedOperationException();
}
return version.isNewerThanOrEquals(ClientVersion.V_1_21_2) || this.legacyName == null
? this.data.getName() : this.legacyName;
}
@@ -90,7 +90,7 @@ public class ChatTypeDecoration {
}
NBTCompound styleTag = compound.getCompoundTagOrNull("style");
Style style = styleTag == null ? empty() :
AdventureSerializer.getNBTSerializer().deserializeStyle(styleTag);
AdventureSerializer.serializer(version).nbt().deserializeStyle(styleTag);
return new ChatTypeDecoration(translationKey, params, style);
}
@@ -104,8 +104,8 @@ public class ChatTypeDecoration {
compound.setTag("translation_key", new NBTString(decoration.translationKey));
compound.setTag("parameters", paramsTag);
if (!decoration.style.isEmpty()) {
compound.setTag("style", AdventureSerializer.getNBTSerializer()
.serializeStyle(decoration.style));
compound.setTag("style", AdventureSerializer.serializer(version)
.nbt().serializeStyle(decoration.style));
}
return compound;
}
@@ -31,8 +31,7 @@ import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration
public final class ChatTypes {
private static final VersionedRegistry<ChatType> REGISTRY = new VersionedRegistry<>(
"chat_type", "chat/chat_type_mappings");
private static final VersionedRegistry<ChatType> REGISTRY = new VersionedRegistry<>("chat_type");
private ChatTypes() {
}
@@ -1,5 +1,6 @@
package com.github.retrooper.packetevents.protocol.chat;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.io.DataOutput;
@@ -86,12 +87,23 @@ public class LastSeenMessages {
}
public static class Update {
private final int offset;
private final BitSet acknowledged;
private final byte checksum;
/**
* Checksum has been added with 1.21.5
*/
@ApiStatus.Obsolete
public Update(int offset, BitSet acknowledged) {
this(offset, acknowledged, (byte) 0);
}
public Update(int offset, BitSet acknowledged, byte checksum) {
this.offset = offset;
this.acknowledged = acknowledged;
this.checksum = checksum;
}
public int getOffset() {
@@ -101,5 +113,12 @@ public class LastSeenMessages {
public BitSet getAcknowledged() {
return acknowledged;
}
/**
* Added with 1.21.5
*/
public byte getChecksum() {
return this.checksum;
}
}
}
@@ -19,58 +19,54 @@
package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class Parsers {
public final class Parsers {
private static final List<Parser> ALL_PARSERS = new ArrayList<>(); // support for old methods
private static final Map<String, Parser> PARSER_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, Parser>> PARSER_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("command/argument_parser_mappings");
private static final VersionedRegistry<Parser> REGISTRY = new VersionedRegistry<>("argument_type");
private Parsers() {
}
@ApiStatus.Internal
public static Parser define(String key) {
return define(key, null, null);
}
@ApiStatus.Internal
public static Parser define(String key, @Nullable Reader reader, @Nullable Writer writer) {
TypesBuilderData data = TYPES_BUILDER.define(key);
Parser parser = new Parser(data, reader, writer);
ALL_PARSERS.add(parser);
MappingHelper.registerMapping(TYPES_BUILDER, PARSER_MAP, PARSER_ID_MAP, parser);
return parser;
return REGISTRY.define(key, data -> new Parser(data, reader, writer));
}
// with key
public static Parser getByName(String name) {
return PARSER_MAP.get(name);
return REGISTRY.getByName(name);
}
public static Parser getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, Parser> idMap = PARSER_ID_MAP.get((byte) index);
return idMap.get(id);
return REGISTRY.getById(version, id);
}
public static List<Parser> getParsers() {
return Collections.unmodifiableList(ALL_PARSERS);
return new ArrayList<>(REGISTRY.getEntries());
}
public static VersionedRegistry<Parser> getRegistry() {
return REGISTRY;
}
public static final Parser BRIGADIER_BOOL = define("brigadier:bool", null, null);
@@ -152,8 +148,8 @@ public class Parsers {
public static final Parser STYLE = define("style", null, null);
public static final Parser MESSAGE = define("message", null, null);
public static final Parser NBT_COMPOUND_TAG = define("nbt_compound_tag", null, null);
@Deprecated
public static final Parser NBT = NBT_COMPOUND_TAG;
@ApiStatus.Obsolete
public static final Parser NBT = define("nbt", null, null);
public static final Parser NBT_TAG = define("nbt_tag", null, null);
public static final Parser NBT_PATH = define("nbt_path", null, null);
public static final Parser OBJECTIVE = define("objective", null, null);
@@ -214,8 +210,16 @@ public class Parsers {
public static final Parser LOOT_MODIFIER = define("loot_modifier", null, null);
public static final Parser UUID = define("uuid", null, null);
/**
* Added with 1.21.5
*/
public static final Parser RESOURCE_SELECTOR = define("resource_selector",
wrapper -> Collections.singletonList(wrapper.readIdentifier()),
(wrapper, value) -> wrapper.writeIdentifier((ResourceLocation) value.get(0))
);
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
@FunctionalInterface
@@ -224,9 +228,8 @@ public class Parsers {
@FunctionalInterface
public interface Writer extends BiConsumer<PacketWrapper<?>, List<Object>> {}
public static final class Parser implements MappedEntity {
public static final class Parser extends AbstractMappedEntity {
private final TypesBuilderData data;
private final Reader reader;
private final Writer writer;
@@ -239,8 +242,9 @@ public class Parsers {
);
}
private Parser(TypesBuilderData data, @Nullable Reader reader, Writer writer) {
this.data = data;
@ApiStatus.Internal
public Parser(@Nullable TypesBuilderData data, @Nullable Reader reader, @Nullable Writer writer) {
super(data);
this.reader = reader;
this.writer = writer;
}
@@ -257,24 +261,5 @@ public class Parsers {
this.writer.accept(wrapper, properties);
}
}
@Override
public ResourceLocation getName() {
return this.data.getName();
}
@Override
public int getId(ClientVersion version) {
int index = TYPES_BUILDER.getDataIndex(version);
return this.data.getData()[index];
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Parser) {
return this.getName().equals(((Parser) obj).getName());
}
return false;
}
}
}
@@ -20,6 +20,7 @@ package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
@@ -39,6 +40,7 @@ public class StaticChatType extends AbstractMappedEntity implements ChatType {
this(null, chatDecoration, null, narrationDecoration, null);
}
@ApiStatus.Internal
public StaticChatType(
@Nullable TypesBuilderData data,
ChatTypeDecoration chatDecoration,
@@ -56,6 +58,7 @@ public class StaticChatType extends AbstractMappedEntity implements ChatType {
this(null, chatDecoration, overlayDecoration, narrationDecoration, narrationPriority);
}
@ApiStatus.Internal
public StaticChatType(
@Nullable TypesBuilderData data,
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration,
@@ -10,7 +10,6 @@ import org.jetbrains.annotations.Nullable;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
//We'll extend ChatMessage_v1_16 for now, hopefully no breaking changes in the future
public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
int index;
byte[] signature;
@@ -0,0 +1,49 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.chat.message;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.time.Instant;
import java.util.UUID;
//We'll extend ChatMessage_v1_19_3 for now, hopefully no breaking changes in the future
public class ChatMessage_v1_21_5 extends ChatMessage_v1_19_3 {
int globalIndex;
public ChatMessage_v1_21_5(int globalIndex, UUID senderUUID, int index, byte[] signature, String plainContent,
Instant timestamp, long salt, LastSeenMessages.Packed lastSeenMessagesPacked, @Nullable Component unsignedChatContent,
FilterMask filterMask, ChatType.Bound chatFormatting) {
super(senderUUID, index, signature, plainContent, timestamp, salt, lastSeenMessagesPacked, unsignedChatContent, filterMask, chatFormatting);
this.globalIndex = globalIndex;
}
public int getGlobalIndex() {
return this.globalIndex;
}
public void setGlobalIndex(int globalIndex) {
this.globalIndex = globalIndex;
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.chat.message.reader.impl;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_21_5;
import com.github.retrooper.packetevents.protocol.chat.message.reader.ChatMessageProcessor;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import java.time.Instant;
import java.util.UUID;
public class ChatMessageProcessor_v1_21_5 implements ChatMessageProcessor {
@Override
public ChatMessage readChatMessage(@NotNull PacketWrapper<?> wrapper) {
int globalIndex = wrapper.readVarInt();
UUID senderUUID = wrapper.readUUID();
int index = wrapper.readVarInt();
byte[] signature = wrapper.readOptional((w) -> w.readBytes(256));
String plainContent = wrapper.readString(256);
Instant timestamp = wrapper.readTimestamp();
long salt = wrapper.readLong();
LastSeenMessages.Packed lastSeenMessagesPacked = wrapper.readLastSeenMessagesPacked();
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
FilterMask filterMask = wrapper.readFilterMask();
ChatType.Bound chatType = wrapper.readChatTypeBoundNetwork();
return new ChatMessage_v1_21_5(globalIndex, senderUUID, index, signature, plainContent, timestamp, salt, lastSeenMessagesPacked, unsignedChatContent, filterMask, chatType);
}
@Override
public void writeChatMessage(@NotNull PacketWrapper<?> wrapper, @NotNull ChatMessage data) {
ChatMessage_v1_21_5 newData = (ChatMessage_v1_21_5) data;
wrapper.writeVarInt(newData.getGlobalIndex());
wrapper.writeUUID(newData.getSenderUUID());
wrapper.writeVarInt(newData.getIndex());
wrapper.writeOptional(newData.getSignature(), PacketWrapper::writeBytes);
wrapper.writeString(newData.getPlainContent());
wrapper.writeTimestamp(newData.getTimestamp());
wrapper.writeLong(newData.getSalt());
wrapper.writeLastSeenMessagesPacked(newData.getLastSeenMessagesPacked());
wrapper.writeOptional(newData.getUnsignedChatContent().orElse(null), PacketWrapper::writeComponent);
wrapper.writeFilterMask(newData.getFilterMask());
wrapper.writeChatTypeBoundNetwork(newData.getChatFormatting());
}
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.color;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.util.RGBLike;
import org.jetbrains.annotations.NotNull;
@@ -54,6 +55,8 @@ public enum DyeColor implements RGBLike {
BLACK(new Color(0x1d1d21), new Color(0x0), new Color(0x1e1b1b), 29);
private static final DyeColor[] COLORS = values();
private final Color textureDiffuseColor;
private final Color textColor;
@@ -70,6 +73,14 @@ public enum DyeColor implements RGBLike {
this.mapColorId = mapColorId;
}
public static DyeColor read(PacketWrapper<?> wrapper) {
return wrapper.readEnum(COLORS);
}
public static void write(PacketWrapper<?> wrapper, DyeColor color) {
wrapper.writeEnum(color);
}
public @NotNull Color color() {
return this.textureDiffuseColor;
}
@@ -100,4 +111,4 @@ public enum DyeColor implements RGBLike {
public int mapColorId() {
return this.mapColorId;
}
}
}
@@ -31,6 +31,10 @@ public class ComponentPredicate implements Predicate<IComponentMap> {
private List<ComponentValue<?>> requiredComponents;
public ComponentPredicate() {
this(new ArrayList<>());
}
public ComponentPredicate(List<ComponentValue<?>> requiredComponents) {
this.requiredComponents = requiredComponents;
}
@@ -19,6 +19,30 @@
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.protocol.component.builtin.AxolotlVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.CatCollarComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.CatVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.ChickenVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.CowVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.FoxVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.FrogVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.HorseVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.LlamaVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.MooshroomVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.PaintingVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.ParrotVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.PigVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.RabbitVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.SalmonSizeComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.SheepColorComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.ShulkerColorComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.TropicalFishBaseColorComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.TropicalFishPatternColorComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.TropicalFishPatternComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.VillagerVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.WolfCollarComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.WolfSoundVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.WolfVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ArmorTrim;
import com.github.retrooper.packetevents.protocol.component.builtin.item.BannerLayers;
import com.github.retrooper.packetevents.protocol.component.builtin.item.BundleContents;
@@ -31,6 +55,8 @@ import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAdv
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAttributeModifiers;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBees;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBlockStateProperties;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBlocksAttacks;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBreakSound;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemConsumable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerContents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerLoot;
@@ -42,6 +68,7 @@ import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnc
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEquippable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemFireworks;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemInstrument;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemJukeboxPlayable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLock;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLore;
@@ -49,20 +76,27 @@ import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemMap
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemMapPostProcessingState;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemModel;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemPotionContents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemPotionDurationScale;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemProfile;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemProvidesBannerPatterns;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemProvidesTrimMaterial;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRarity;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRecipes;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRepairable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemTool;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemTooltipDisplay;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemTooltipStyle;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemUnbreakable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemUseCooldown;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemUseRemainder;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemWeapon;
import com.github.retrooper.packetevents.protocol.component.builtin.item.LodestoneTracker;
import com.github.retrooper.packetevents.protocol.component.builtin.item.PotDecorations;
import com.github.retrooper.packetevents.protocol.component.builtin.item.SuspiciousStewEffects;
import com.github.retrooper.packetevents.protocol.component.builtin.item.WritableBookContent;
import com.github.retrooper.packetevents.protocol.component.builtin.item.WrittenBookContent;
import com.github.retrooper.packetevents.protocol.item.instrument.Instrument;
import com.github.retrooper.packetevents.protocol.mapper.MaybeMappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
@@ -84,8 +118,7 @@ import java.util.Collection;
*/
public final class ComponentTypes {
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
"data_component_type", "item/item_component_mappings");
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>("data_component_type");
private ComponentTypes() {
}
@@ -122,8 +155,14 @@ public final class ComponentTypes {
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Integer> DAMAGE = define("damage",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Boolean> UNBREAKABLE = define("unbreakable",
PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
public static final ComponentType<ItemUnbreakable> UNBREAKABLE_MODERN = define("unbreakable",
ItemUnbreakable::read, ItemUnbreakable::write);
/**
* Changed in 1.21.5
*/
@Deprecated
public static final ComponentType<Boolean> UNBREAKABLE = UNBREAKABLE_MODERN.legacyMap(
ItemUnbreakable::isShowInTooltip, ItemUnbreakable::new);
public static final ComponentType<Component> CUSTOM_NAME = define("custom_name",
PacketWrapper::readComponent, PacketWrapper::writeComponent);
public static final ComponentType<Component> ITEM_NAME = define("item_name",
@@ -148,8 +187,16 @@ public final class ComponentTypes {
@Deprecated
public static final ComponentType<Integer> CUSTOM_MODEL_DATA = CUSTOM_MODEL_DATA_LISTS.legacyMap(
ItemCustomModelData::getLegacyId, ItemCustomModelData::new);
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
public static final ComponentType<Dummy> HIDE_ADDITIONAL_TOOLTIP = define("hide_additional_tooltip",
Dummy::dummyRead, Dummy::dummyWrite);
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
public static final ComponentType<Dummy> HIDE_TOOLTIP = define("hide_tooltip",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<Integer> REPAIR_COST = define("repair_cost",
@@ -204,8 +251,12 @@ public final class ComponentTypes {
PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final ComponentType<NBTCompound> BLOCK_ENTITY_DATA = define("block_entity_data",
PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final ComponentType<Instrument> INSTRUMENT = define("instrument",
Instrument::read, Instrument::write);
public static final ComponentType<ItemInstrument> ITEM_INSTRUMENT = define("instrument",
ItemInstrument::read, ItemInstrument::write);
@Deprecated
public static final ComponentType<Instrument> INSTRUMENT = ITEM_INSTRUMENT.legacyMap(
inst -> inst.getInstrument().getValue(),
inst -> new ItemInstrument(new MaybeMappedEntity<>(inst)));
public static final ComponentType<Integer> OMINOUS_BOTTLE_AMPLIFIER = define("ominous_bottle_amplifier",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<ItemRecipes> RECIPES = define("recipes",
@@ -265,6 +316,162 @@ public final class ComponentTypes {
public static final ComponentType<ItemTooltipStyle> TOOLTIP_STYLE = define("tooltip_style",
ItemTooltipStyle::read, ItemTooltipStyle::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ItemTooltipDisplay> TOOLTIP_DISPLAY = define("tooltip_display",
ItemTooltipDisplay::read, ItemTooltipDisplay::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ItemWeapon> WEAPON = define("weapon",
ItemWeapon::read, ItemWeapon::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ItemBlocksAttacks> BLOCKS_ATTACKS = define("blocks_attacks",
ItemBlocksAttacks::read, ItemBlocksAttacks::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ItemPotionDurationScale> POTION_DURATION_SCALE = define("potion_duration_scale",
ItemPotionDurationScale::read, ItemPotionDurationScale::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ItemProvidesTrimMaterial> PROVIDES_TRIM_MATERIAL = define("provides_trim_material",
ItemProvidesTrimMaterial::read, ItemProvidesTrimMaterial::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ItemProvidesBannerPatterns> PROVIDES_BANNER_PATTERNS = define("provides_banner_patterns",
ItemProvidesBannerPatterns::read, ItemProvidesBannerPatterns::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ItemBreakSound> BREAK_SOUND = define("break_sound",
ItemBreakSound::read, ItemBreakSound::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<VillagerVariantComponent> VILLAGER_VARIANT = define("villager/variant",
VillagerVariantComponent::read, VillagerVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<WolfVariantComponent> WOLF_VARIANT = define("wolf/variant",
WolfVariantComponent::read, WolfVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<WolfSoundVariantComponent> WOLF_SOUND_VARIANT = define("wolf/sound_variant",
WolfSoundVariantComponent::read, WolfSoundVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<WolfCollarComponent> WOLF_COLLAR = define("wolf/collar",
WolfCollarComponent::read, WolfCollarComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<FoxVariantComponent> FOX_VARIANT = define("fox/variant",
FoxVariantComponent::read, FoxVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<SalmonSizeComponent> SALMON_SIZE = define("salmon/size",
SalmonSizeComponent::read, SalmonSizeComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ParrotVariantComponent> PARROT_VARIANT = define("parrot/variant",
ParrotVariantComponent::read, ParrotVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<TropicalFishPatternComponent> TROPICAL_FISH_PATTERN = define("tropical_fish/pattern",
TropicalFishPatternComponent::read, TropicalFishPatternComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<TropicalFishBaseColorComponent> TROPICAL_FISH_BASE_COLOR = define("tropical_fish/base_color",
TropicalFishBaseColorComponent::read, TropicalFishBaseColorComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<TropicalFishPatternColorComponent> TROPICAL_FISH_PATTERN_COLOR = define("tropical_fish/pattern_color",
TropicalFishPatternColorComponent::read, TropicalFishPatternColorComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<MooshroomVariantComponent> MOOSHROOM_VARIANT = define("mooshroom/variant",
MooshroomVariantComponent::read, MooshroomVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<RabbitVariantComponent> RABBIT_VARIANT = define("rabbit/variant",
RabbitVariantComponent::read, RabbitVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<PigVariantComponent> PIG_VARIANT = define("pig/variant",
PigVariantComponent::read, PigVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<CowVariantComponent> COW_VARIANT = define("cow/variant",
CowVariantComponent::read, CowVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ChickenVariantComponent> CHICKEN_VARIANT = define("chicken/variant",
ChickenVariantComponent::read, ChickenVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<FrogVariantComponent> FROG_VARIANT = define("frog/variant",
FrogVariantComponent::read, FrogVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<HorseVariantComponent> HORSE_VARIANT = define("horse/variant",
HorseVariantComponent::read, HorseVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<PaintingVariantComponent> PAINTING_VARIANT = define("painting/variant",
PaintingVariantComponent::read, PaintingVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<LlamaVariantComponent> LLAMA_VARIANT = define("llama/variant",
LlamaVariantComponent::read, LlamaVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<AxolotlVariantComponent> AXOLOTL_VARIANT = define("axolotl/variant",
AxolotlVariantComponent::read, AxolotlVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<CatVariantComponent> CAT_VARIANT = define("cat/variant",
CatVariantComponent::read, CatVariantComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<CatCollarComponent> CAT_COLLAR = define("cat/collar",
CatCollarComponent::read, CatCollarComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<SheepColorComponent> SHEEP_COLOR = define("sheep/color",
SheepColorComponent::read, SheepColorComponent::write);
/**
* Added with 1.21.5
*/
public static final ComponentType<ShulkerColorComponent> SHULKER_COLOR = define("shulker/color",
ShulkerColorComponent::read, ShulkerColorComponent::write);
/**
* Returns an immutable view of the component types.
*
@@ -32,8 +32,7 @@ import org.jetbrains.annotations.Nullable;
*/
public final class EnchantEffectComponentTypes {
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
"enchantment_effect_component_type", "enchantment/effect_component_type");
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>("enchantment_effect_component_type");
private EnchantEffectComponentTypes() {
}
@@ -0,0 +1,57 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public final class HashedComponentPatchMap {
private final Map<ComponentType<?>, Integer> addedComponents;
private final Set<ComponentType<?>> removedComponents;
public HashedComponentPatchMap(Map<ComponentType<?>, Integer> addedComponents, Set<ComponentType<?>> removedComponents) {
this.addedComponents = addedComponents;
this.removedComponents = removedComponents;
}
public static HashedComponentPatchMap read(PacketWrapper<?> wrapper) {
Map<ComponentType<?>, Integer> addedComponents = wrapper.readMap(ew ->
ew.readMappedEntity(ComponentTypes.getRegistry()), PacketWrapper::readInt);
Set<ComponentType<?>> removedComponents = wrapper.readCollection(HashSet::new, ew ->
ew.readMappedEntity(ComponentTypes.getRegistry()));
return new HashedComponentPatchMap(addedComponents, removedComponents);
}
public static void write(PacketWrapper<?> wrapper, HashedComponentPatchMap map) {
wrapper.writeMap(map.addedComponents, PacketWrapper::writeMappedEntity, PacketWrapper::writeInt);
wrapper.writeCollection(map.removedComponents, PacketWrapper::writeMappedEntity);
}
public Map<ComponentType<?>, Integer> getAddedComponents() {
return this.addedComponents;
}
public Set<ComponentType<?>> getRemovedComponents() {
return this.removedComponents;
}
}
@@ -25,6 +25,7 @@ import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
@@ -36,6 +37,7 @@ public class StaticComponentType<T> extends AbstractMappedEntity implements Comp
private final @Nullable Decoder<T> decoder;
private final @Nullable Encoder<T> encoder;
@ApiStatus.Internal
public StaticComponentType(
@Nullable TypesBuilderData data,
@Nullable Reader<T> reader,
@@ -44,6 +46,7 @@ public class StaticComponentType<T> extends AbstractMappedEntity implements Comp
this(data, reader, writer, null, null);
}
@ApiStatus.Internal
public StaticComponentType(
@Nullable TypesBuilderData data,
@Nullable Decoder<T> decoder,
@@ -52,6 +55,7 @@ public class StaticComponentType<T> extends AbstractMappedEntity implements Comp
this(data, null, null, decoder, encoder);
}
@ApiStatus.Internal
public StaticComponentType(
@Nullable TypesBuilderData data,
@Nullable Reader<T> reader,
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.axolotl.AxolotlVariant;
import com.github.retrooper.packetevents.protocol.entity.axolotl.AxolotlVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class AxolotlVariantComponent {
private AxolotlVariant variant;
public AxolotlVariantComponent(AxolotlVariant variant) {
this.variant = variant;
}
public static AxolotlVariantComponent read(PacketWrapper<?> wrapper) {
AxolotlVariant type = wrapper.readMappedEntity(AxolotlVariants.getRegistry());
return new AxolotlVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, AxolotlVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public AxolotlVariant getVariant() {
return this.variant;
}
public void setVariant(AxolotlVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof AxolotlVariantComponent)) return false;
AxolotlVariantComponent that = (AxolotlVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class CatCollarComponent {
private DyeColor color;
public CatCollarComponent(DyeColor color) {
this.color = color;
}
public static CatCollarComponent read(PacketWrapper<?> wrapper) {
DyeColor type = DyeColor.read(wrapper);
return new CatCollarComponent(type);
}
public static void write(PacketWrapper<?> wrapper, CatCollarComponent component) {
DyeColor.write(wrapper, component.color);
}
public DyeColor getDyeColor() {
return this.color;
}
public void setDyeColor(DyeColor color) {
this.color = color;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CatCollarComponent)) return false;
CatCollarComponent that = (CatCollarComponent) obj;
return this.color.equals(that.color);
}
@Override
public int hashCode() {
return Objects.hashCode(this.color);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.cat.CatVariant;
import com.github.retrooper.packetevents.protocol.entity.cat.CatVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class CatVariantComponent {
private CatVariant variant;
public CatVariantComponent(CatVariant variant) {
this.variant = variant;
}
public static CatVariantComponent read(PacketWrapper<?> wrapper) {
CatVariant type = wrapper.readMappedEntity(CatVariants.getRegistry());
return new CatVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, CatVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public CatVariant getVariant() {
return this.variant;
}
public void setVariant(CatVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CatVariantComponent)) return false;
CatVariantComponent that = (CatVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,65 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.chicken.ChickenVariant;
import com.github.retrooper.packetevents.protocol.entity.chicken.ChickenVariants;
import com.github.retrooper.packetevents.protocol.mapper.MaybeMappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ChickenVariantComponent {
private MaybeMappedEntity<ChickenVariant> variant;
public ChickenVariantComponent(MaybeMappedEntity<ChickenVariant> variant) {
this.variant = variant;
}
public static ChickenVariantComponent read(PacketWrapper<?> wrapper) {
MaybeMappedEntity<ChickenVariant> variant = MaybeMappedEntity.read(wrapper,
ChickenVariants.getRegistry(), ChickenVariant::read);
return new ChickenVariantComponent(variant);
}
public static void write(PacketWrapper<?> wrapper, ChickenVariantComponent component) {
MaybeMappedEntity.write(wrapper, component.variant, ChickenVariant::write);
}
public MaybeMappedEntity<ChickenVariant> getVariant() {
return this.variant;
}
public void setVariant(MaybeMappedEntity<ChickenVariant> variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ChickenVariantComponent)) return false;
ChickenVariantComponent that = (ChickenVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.cow.CowVariant;
import com.github.retrooper.packetevents.protocol.entity.cow.CowVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class CowVariantComponent {
private CowVariant variant;
public CowVariantComponent(CowVariant variant) {
this.variant = variant;
}
public static CowVariantComponent read(PacketWrapper<?> wrapper) {
CowVariant type = wrapper.readMappedEntity(CowVariants.getRegistry());
return new CowVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, CowVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public CowVariant getVariant() {
return this.variant;
}
public void setVariant(CowVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CowVariantComponent)) return false;
CowVariantComponent that = (CowVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.fox.FoxVariant;
import com.github.retrooper.packetevents.protocol.entity.fox.FoxVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class FoxVariantComponent {
private FoxVariant variant;
public FoxVariantComponent(FoxVariant variant) {
this.variant = variant;
}
public static FoxVariantComponent read(PacketWrapper<?> wrapper) {
FoxVariant type = wrapper.readMappedEntity(FoxVariants.getRegistry());
return new FoxVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, FoxVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public FoxVariant getVariant() {
return this.variant;
}
public void setVariant(FoxVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof FoxVariantComponent)) return false;
FoxVariantComponent that = (FoxVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.frog.FrogVariant;
import com.github.retrooper.packetevents.protocol.entity.frog.FrogVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class FrogVariantComponent {
private FrogVariant variant;
public FrogVariantComponent(FrogVariant variant) {
this.variant = variant;
}
public static FrogVariantComponent read(PacketWrapper<?> wrapper) {
FrogVariant variant = wrapper.readMappedEntity(FrogVariants.getRegistry());
return new FrogVariantComponent(variant);
}
public static void write(PacketWrapper<?> wrapper, FrogVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public FrogVariant getVariant() {
return this.variant;
}
public void setVariant(FrogVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof FrogVariantComponent)) return false;
FrogVariantComponent that = (FrogVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.horse.HorseVariant;
import com.github.retrooper.packetevents.protocol.entity.horse.HorseVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class HorseVariantComponent {
private HorseVariant variant;
public HorseVariantComponent(HorseVariant variant) {
this.variant = variant;
}
public static HorseVariantComponent read(PacketWrapper<?> wrapper) {
HorseVariant variant = wrapper.readMappedEntity(HorseVariants.getRegistry());
return new HorseVariantComponent(variant);
}
public static void write(PacketWrapper<?> wrapper, HorseVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public HorseVariant getVariant() {
return this.variant;
}
public void setVariant(HorseVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof HorseVariantComponent)) return false;
HorseVariantComponent that = (HorseVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.llama.LlamaVariant;
import com.github.retrooper.packetevents.protocol.entity.llama.LlamaVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class LlamaVariantComponent {
private LlamaVariant variant;
public LlamaVariantComponent(LlamaVariant variant) {
this.variant = variant;
}
public static LlamaVariantComponent read(PacketWrapper<?> wrapper) {
LlamaVariant type = wrapper.readMappedEntity(LlamaVariants.getRegistry());
return new LlamaVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, LlamaVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public LlamaVariant getVariant() {
return this.variant;
}
public void setVariant(LlamaVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LlamaVariantComponent)) return false;
LlamaVariantComponent that = (LlamaVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.mooshroom.MooshroomVariant;
import com.github.retrooper.packetevents.protocol.entity.mooshroom.MooshroomVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class MooshroomVariantComponent {
private MooshroomVariant variant;
public MooshroomVariantComponent(MooshroomVariant variant) {
this.variant = variant;
}
public static MooshroomVariantComponent read(PacketWrapper<?> wrapper) {
MooshroomVariant type = wrapper.readMappedEntity(MooshroomVariants.getRegistry());
return new MooshroomVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, MooshroomVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public MooshroomVariant getVariant() {
return this.variant;
}
public void setVariant(MooshroomVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof MooshroomVariantComponent)) return false;
MooshroomVariantComponent that = (MooshroomVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.world.painting.PaintingVariant;
import com.github.retrooper.packetevents.protocol.world.painting.PaintingVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class PaintingVariantComponent {
private PaintingVariant variant;
public PaintingVariantComponent(PaintingVariant variant) {
this.variant = variant;
}
public static PaintingVariantComponent read(PacketWrapper<?> wrapper) {
PaintingVariant variant = wrapper.readMappedEntity(PaintingVariants.getRegistry());
return new PaintingVariantComponent(variant);
}
public static void write(PacketWrapper<?> wrapper, PaintingVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public PaintingVariant getVariant() {
return this.variant;
}
public void setVariant(PaintingVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PaintingVariantComponent)) return false;
PaintingVariantComponent that = (PaintingVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.parrot.ParrotVariant;
import com.github.retrooper.packetevents.protocol.entity.parrot.ParrotVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ParrotVariantComponent {
private ParrotVariant variant;
public ParrotVariantComponent(ParrotVariant variant) {
this.variant = variant;
}
public static ParrotVariantComponent read(PacketWrapper<?> wrapper) {
ParrotVariant type = wrapper.readMappedEntity(ParrotVariants.getRegistry());
return new ParrotVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, ParrotVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public ParrotVariant getVariant() {
return this.variant;
}
public void setVariant(ParrotVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ParrotVariantComponent)) return false;
ParrotVariantComponent that = (ParrotVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.pig.PigVariant;
import com.github.retrooper.packetevents.protocol.entity.pig.PigVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class PigVariantComponent {
private PigVariant variant;
public PigVariantComponent(PigVariant variant) {
this.variant = variant;
}
public static PigVariantComponent read(PacketWrapper<?> wrapper) {
PigVariant type = wrapper.readMappedEntity(PigVariants.getRegistry());
return new PigVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, PigVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public PigVariant getVariant() {
return this.variant;
}
public void setVariant(PigVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PigVariantComponent)) return false;
PigVariantComponent that = (PigVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.rabbit.RabbitVariant;
import com.github.retrooper.packetevents.protocol.entity.rabbit.RabbitVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class RabbitVariantComponent {
private RabbitVariant variant;
public RabbitVariantComponent(RabbitVariant variant) {
this.variant = variant;
}
public static RabbitVariantComponent read(PacketWrapper<?> wrapper) {
RabbitVariant type = wrapper.readMappedEntity(RabbitVariants.getRegistry());
return new RabbitVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, RabbitVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public RabbitVariant getVariant() {
return this.variant;
}
public void setVariant(RabbitVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof RabbitVariantComponent)) return false;
RabbitVariantComponent that = (RabbitVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.salmon.SalmonVariant;
import com.github.retrooper.packetevents.protocol.entity.salmon.SalmonVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class SalmonSizeComponent {
private SalmonVariant variant;
public SalmonSizeComponent(SalmonVariant variant) {
this.variant = variant;
}
public static SalmonSizeComponent read(PacketWrapper<?> wrapper) {
SalmonVariant type = wrapper.readMappedEntity(SalmonVariants.getRegistry());
return new SalmonSizeComponent(type);
}
public static void write(PacketWrapper<?> wrapper, SalmonSizeComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public SalmonVariant getVariant() {
return this.variant;
}
public void setVariant(SalmonVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SalmonSizeComponent)) return false;
SalmonSizeComponent that = (SalmonSizeComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class SheepColorComponent {
private DyeColor color;
public SheepColorComponent(DyeColor color) {
this.color = color;
}
public static SheepColorComponent read(PacketWrapper<?> wrapper) {
DyeColor type = DyeColor.read(wrapper);
return new SheepColorComponent(type);
}
public static void write(PacketWrapper<?> wrapper, SheepColorComponent component) {
DyeColor.write(wrapper, component.color);
}
public DyeColor getDyeColor() {
return this.color;
}
public void setDyeColor(DyeColor color) {
this.color = color;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SheepColorComponent)) return false;
SheepColorComponent that = (SheepColorComponent) obj;
return this.color.equals(that.color);
}
@Override
public int hashCode() {
return Objects.hashCode(this.color);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ShulkerColorComponent {
private DyeColor color;
public ShulkerColorComponent(DyeColor color) {
this.color = color;
}
public static ShulkerColorComponent read(PacketWrapper<?> wrapper) {
DyeColor type = DyeColor.read(wrapper);
return new ShulkerColorComponent(type);
}
public static void write(PacketWrapper<?> wrapper, ShulkerColorComponent component) {
DyeColor.write(wrapper, component.color);
}
public DyeColor getDyeColor() {
return this.color;
}
public void setDyeColor(DyeColor color) {
this.color = color;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ShulkerColorComponent)) return false;
ShulkerColorComponent that = (ShulkerColorComponent) obj;
return this.color.equals(that.color);
}
@Override
public int hashCode() {
return Objects.hashCode(this.color);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class TropicalFishBaseColorComponent {
private DyeColor color;
public TropicalFishBaseColorComponent(DyeColor color) {
this.color = color;
}
public static TropicalFishBaseColorComponent read(PacketWrapper<?> wrapper) {
DyeColor type = DyeColor.read(wrapper);
return new TropicalFishBaseColorComponent(type);
}
public static void write(PacketWrapper<?> wrapper, TropicalFishBaseColorComponent component) {
DyeColor.write(wrapper, component.color);
}
public DyeColor getDyeColor() {
return this.color;
}
public void setDyeColor(DyeColor color) {
this.color = color;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof TropicalFishBaseColorComponent)) return false;
TropicalFishBaseColorComponent that = (TropicalFishBaseColorComponent) obj;
return this.color.equals(that.color);
}
@Override
public int hashCode() {
return Objects.hashCode(this.color);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class TropicalFishPatternColorComponent {
private DyeColor color;
public TropicalFishPatternColorComponent(DyeColor color) {
this.color = color;
}
public static TropicalFishPatternColorComponent read(PacketWrapper<?> wrapper) {
DyeColor type = DyeColor.read(wrapper);
return new TropicalFishPatternColorComponent(type);
}
public static void write(PacketWrapper<?> wrapper, TropicalFishPatternColorComponent component) {
DyeColor.write(wrapper, component.color);
}
public DyeColor getDyeColor() {
return this.color;
}
public void setDyeColor(DyeColor color) {
this.color = color;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof TropicalFishPatternColorComponent)) return false;
TropicalFishPatternColorComponent that = (TropicalFishPatternColorComponent) obj;
return this.color.equals(that.color);
}
@Override
public int hashCode() {
return Objects.hashCode(this.color);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.tropicalfish.TropicalFishPattern;
import com.github.retrooper.packetevents.protocol.entity.tropicalfish.TropicalFishPatterns;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class TropicalFishPatternComponent {
private TropicalFishPattern variant;
public TropicalFishPatternComponent(TropicalFishPattern variant) {
this.variant = variant;
}
public static TropicalFishPatternComponent read(PacketWrapper<?> wrapper) {
TropicalFishPattern type = wrapper.readMappedEntity(TropicalFishPatterns.getRegistry());
return new TropicalFishPatternComponent(type);
}
public static void write(PacketWrapper<?> wrapper, TropicalFishPatternComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public TropicalFishPattern getVariant() {
return this.variant;
}
public void setVariant(TropicalFishPattern variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof TropicalFishPatternComponent)) return false;
TropicalFishPatternComponent that = (TropicalFishPatternComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerType;
import com.github.retrooper.packetevents.protocol.entity.villager.type.VillagerTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class VillagerVariantComponent {
private VillagerType villagerType;
public VillagerVariantComponent(VillagerType villagerType) {
this.villagerType = villagerType;
}
public static VillagerVariantComponent read(PacketWrapper<?> wrapper) {
VillagerType type = wrapper.readMappedEntity(VillagerTypes.getRegistry());
return new VillagerVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, VillagerVariantComponent component) {
wrapper.writeMappedEntity(component.villagerType);
}
public VillagerType getVillagerType() {
return this.villagerType;
}
public void setVillagerType(VillagerType villagerType) {
this.villagerType = villagerType;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof VillagerVariantComponent)) return false;
VillagerVariantComponent that = (VillagerVariantComponent) obj;
return this.villagerType.equals(that.villagerType);
}
@Override
public int hashCode() {
return Objects.hashCode(this.villagerType);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class WolfCollarComponent {
private DyeColor color;
public WolfCollarComponent(DyeColor color) {
this.color = color;
}
public static WolfCollarComponent read(PacketWrapper<?> wrapper) {
DyeColor type = DyeColor.read(wrapper);
return new WolfCollarComponent(type);
}
public static void write(PacketWrapper<?> wrapper, WolfCollarComponent component) {
DyeColor.write(wrapper, component.color);
}
public DyeColor getDyeColor() {
return this.color;
}
public void setDyeColor(DyeColor color) {
this.color = color;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof WolfCollarComponent)) return false;
WolfCollarComponent that = (WolfCollarComponent) obj;
return this.color.equals(that.color);
}
@Override
public int hashCode() {
return Objects.hashCode(this.color);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfSoundVariant;
import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfSoundVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class WolfSoundVariantComponent {
private WolfSoundVariant soundVariant;
public WolfSoundVariantComponent(WolfSoundVariant soundVariant) {
this.soundVariant = soundVariant;
}
public static WolfSoundVariantComponent read(PacketWrapper<?> wrapper) {
WolfSoundVariant type = wrapper.readMappedEntity(WolfSoundVariants.getRegistry());
return new WolfSoundVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, WolfSoundVariantComponent component) {
wrapper.writeMappedEntity(component.soundVariant);
}
public WolfSoundVariant getSoundVariant() {
return this.soundVariant;
}
public void setSoundVariant(WolfSoundVariant soundVariant) {
this.soundVariant = soundVariant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof WolfSoundVariantComponent)) return false;
WolfSoundVariantComponent that = (WolfSoundVariantComponent) obj;
return this.soundVariant.equals(that.soundVariant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.soundVariant);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfVariant;
import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfVariants;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class WolfVariantComponent {
private WolfVariant variant;
public WolfVariantComponent(WolfVariant variant) {
this.variant = variant;
}
public static WolfVariantComponent read(PacketWrapper<?> wrapper) {
WolfVariant type = wrapper.readMappedEntity(WolfVariants.getRegistry());
return new WolfVariantComponent(type);
}
public static void write(PacketWrapper<?> wrapper, WolfVariantComponent component) {
wrapper.writeMappedEntity(component.variant);
}
public WolfVariant getVariant() {
return this.variant;
}
public void setVariant(WolfVariant variant) {
this.variant = variant;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof WolfVariantComponent)) return false;
WolfVariantComponent that = (WolfVariantComponent) obj;
return this.variant.equals(that.variant);
}
@Override
public int hashCode() {
return Objects.hashCode(this.variant);
}
}
@@ -18,9 +18,11 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.trimmaterial.TrimMaterial;
import com.github.retrooper.packetevents.protocol.item.trimpattern.TrimPattern;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.Objects;
@@ -28,8 +30,20 @@ public class ArmorTrim {
private TrimMaterial material;
private TrimPattern pattern;
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
private boolean showInTooltip;
public ArmorTrim(TrimMaterial material, TrimPattern pattern) {
this(material, pattern, true);
}
/**
* {@link #showInTooltip} has been removed in 1.21.5
*/
@ApiStatus.Obsolete
public ArmorTrim(TrimMaterial material, TrimPattern pattern, boolean showInTooltip) {
this.material = material;
this.pattern = pattern;
@@ -39,14 +53,16 @@ public class ArmorTrim {
public static ArmorTrim read(PacketWrapper<?> wrapper) {
TrimMaterial material = TrimMaterial.read(wrapper);
TrimPattern pattern = TrimPattern.read(wrapper);
boolean showInTooltip = wrapper.readBoolean();
boolean showInTooltip = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5) || wrapper.readBoolean();
return new ArmorTrim(material, pattern, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ArmorTrim trim) {
TrimMaterial.write(wrapper, trim.material);
TrimPattern.write(wrapper, trim.pattern);
wrapper.writeBoolean(trim.showInTooltip);
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(trim.showInTooltip);
}
}
public TrimMaterial getMaterial() {
@@ -65,10 +81,18 @@ public class ArmorTrim {
this.pattern = pattern;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public boolean isShowInTooltip() {
return this.showInTooltip;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@@ -81,13 +81,13 @@ public class BannerLayers {
public static Layer read(PacketWrapper<?> wrapper) {
BannerPattern pattern = wrapper.readMappedEntityOrDirect(
BannerPatterns.getRegistry(), BannerPattern::readDirect);
DyeColor color = wrapper.readEnum(DyeColor.values());
DyeColor color = DyeColor.read(wrapper);
return new Layer(pattern, color);
}
public static void write(PacketWrapper<?> wrapper, Layer layer) {
wrapper.writeMappedEntityOrDirect(layer.pattern, BannerPattern::writeDirect);
wrapper.writeEnum(layer.color);
DyeColor.write(wrapper, layer.color);
}
public BannerPattern getPattern() {
@@ -18,23 +18,37 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.component.predicates.ComponentMatchers;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
// why do I have to implement this mess, I just want to deserialize items
public class ItemAdventurePredicate {
private List<BlockPredicate> predicates;
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
private boolean showInTooltip;
public ItemAdventurePredicate(List<BlockPredicate> predicates) {
this(predicates, true);
}
/**
* {@link #showInTooltip} has been removed in 1.21.5
*/
@ApiStatus.Obsolete
public ItemAdventurePredicate(List<BlockPredicate> predicates, boolean showInTooltip) {
this.predicates = predicates;
this.showInTooltip = showInTooltip;
@@ -42,13 +56,15 @@ public class ItemAdventurePredicate {
public static ItemAdventurePredicate read(PacketWrapper<?> wrapper) {
List<BlockPredicate> predicates = wrapper.readList(BlockPredicate::read);
boolean showInTooltip = wrapper.readBoolean();
boolean showInTooltip = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5) || wrapper.readBoolean();
return new ItemAdventurePredicate(predicates, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemAdventurePredicate predicate) {
wrapper.writeList(predicate.predicates, BlockPredicate::write);
wrapper.writeBoolean(predicate.showInTooltip);
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(predicate.showInTooltip);
}
}
public void addPredicate(BlockPredicate predicate) {
@@ -63,10 +79,18 @@ public class ItemAdventurePredicate {
this.predicates = predicates;
}
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
public boolean isShowInTooltip() {
return this.showInTooltip;
}
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@@ -90,15 +114,29 @@ public class ItemAdventurePredicate {
private @Nullable MappedEntitySet<StateType.Mapped> blocks;
private @Nullable List<PropertyMatcher> properties;
private @Nullable NBTCompound nbt;
/**
* Added with 1.21.5
*/
private ComponentMatchers matchers;
public BlockPredicate(
@Nullable MappedEntitySet<StateType.Mapped> blocks,
@Nullable List<PropertyMatcher> properties,
@Nullable NBTCompound nbt
) {
this(blocks, properties, nbt, new ComponentMatchers());
}
public BlockPredicate(
@Nullable MappedEntitySet<StateType.Mapped> blocks,
@Nullable List<PropertyMatcher> properties,
@Nullable NBTCompound nbt,
ComponentMatchers matchers
) {
this.blocks = blocks;
this.properties = properties;
this.nbt = nbt;
this.matchers = matchers;
}
public static BlockPredicate read(PacketWrapper<?> wrapper) {
@@ -107,7 +145,9 @@ public class ItemAdventurePredicate {
List<PropertyMatcher> properties = wrapper.readOptional(
ew -> wrapper.readList(PropertyMatcher::read));
NBTCompound nbt = wrapper.readOptional(PacketWrapper::readNBT);
return new BlockPredicate(blocks, properties, nbt);
ComponentMatchers matchers = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)
? ComponentMatchers.read(wrapper) : new ComponentMatchers();
return new BlockPredicate(blocks, properties, nbt, matchers);
}
public static void write(PacketWrapper<?> wrapper, BlockPredicate predicate) {
@@ -115,6 +155,9 @@ public class ItemAdventurePredicate {
wrapper.writeOptional(predicate.properties,
(ew, val) -> ew.writeList(val, PropertyMatcher::write));
wrapper.writeOptional(predicate.nbt, PacketWrapper::writeNBT);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
ComponentMatchers.write(wrapper, predicate.matchers);
}
}
public @Nullable MappedEntitySet<StateType.Mapped> getBlocks() {
@@ -148,6 +191,20 @@ public class ItemAdventurePredicate {
this.nbt = nbt;
}
/**
* Added with 1.21.5
*/
public ComponentMatchers getMatchers() {
return this.matchers;
}
/**
* Added with 1.21.5
*/
public void setMatchers(ComponentMatchers matchers) {
this.matchers = matchers;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -155,12 +212,13 @@ public class ItemAdventurePredicate {
BlockPredicate that = (BlockPredicate) obj;
if (!Objects.equals(this.blocks, that.blocks)) return false;
if (!Objects.equals(this.properties, that.properties)) return false;
return Objects.equals(this.nbt, that.nbt);
if (!Objects.equals(this.nbt, that.nbt)) return false;
return this.matchers.equals(that.matchers);
}
@Override
public int hashCode() {
return Objects.hash(this.blocks, this.properties, this.nbt);
return Objects.hash(this.blocks, this.properties, this.nbt, this.matchers);
}
}
@@ -37,6 +37,11 @@ public class ItemAttributeModifiers {
public static final ItemAttributeModifiers EMPTY = new ItemAttributeModifiers(
Collections.emptyList(), true) {
@Override
public void setModifiers(List<ModifierEntry> modifiers) {
throw new UnsupportedOperationException();
}
@Override
public void setShowInTooltip(boolean showInTooltip) {
throw new UnsupportedOperationException();
@@ -44,8 +49,20 @@ public class ItemAttributeModifiers {
};
private List<ModifierEntry> modifiers;
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
private boolean showInTooltip;
public ItemAttributeModifiers(List<ModifierEntry> modifiers) {
this(modifiers, true);
}
/**
* {@link #showInTooltip} has been removed in 1.21.5
*/
@ApiStatus.Obsolete
public ItemAttributeModifiers(List<ModifierEntry> modifiers, boolean showInTooltip) {
this.modifiers = modifiers;
this.showInTooltip = showInTooltip;
@@ -53,13 +70,15 @@ public class ItemAttributeModifiers {
public static ItemAttributeModifiers read(PacketWrapper<?> wrapper) {
List<ModifierEntry> modifiers = wrapper.readList(ModifierEntry::read);
boolean showInTooltip = wrapper.readBoolean();
boolean showInTooltip = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5) || wrapper.readBoolean();
return new ItemAttributeModifiers(modifiers, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemAttributeModifiers modifiers) {
wrapper.writeList(modifiers.modifiers, ModifierEntry::write);
wrapper.writeBoolean(modifiers.showInTooltip);
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(modifiers.showInTooltip);
}
}
public void addModifier(ModifierEntry modifier) {
@@ -74,10 +93,18 @@ public class ItemAttributeModifiers {
this.modifiers = modifiers;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public boolean isShowInTooltip() {
return this.showInTooltip;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@@ -294,7 +321,12 @@ public class ItemAttributeModifiers {
CHEST("chest"),
HEAD("head"),
ARMOR("armor"),
BODY("body");
BODY("body"),
/**
* Added with 1.21.5
*/
SADDLE("saddle"),
;
public static final Index<String, EquipmentSlotGroup> ID_INDEX = Index.create(
EquipmentSlotGroup.class, EquipmentSlotGroup::getId);
@@ -0,0 +1,294 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.protocol.world.damagetype.DamageType;
import com.github.retrooper.packetevents.protocol.world.damagetype.DamageTypes;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public class ItemBlocksAttacks {
private float blockDelaySeconds;
private float disableCooldownScale;
private List<DamageReduction> damageReductions;
private ItemDamageFunction itemDamage;
private @Nullable ResourceLocation bypassedBy;
private @Nullable Sound blockSound;
private @Nullable Sound disableSound;
public ItemBlocksAttacks(
float blockDelaySeconds, float disableCooldownScale, List<DamageReduction> damageReductions,
ItemDamageFunction itemDamage, @Nullable ResourceLocation bypassedBy,
@Nullable Sound blockSound, @Nullable Sound disableSound
) {
this.blockDelaySeconds = blockDelaySeconds;
this.disableCooldownScale = disableCooldownScale;
this.damageReductions = damageReductions;
this.itemDamage = itemDamage;
this.bypassedBy = bypassedBy;
this.blockSound = blockSound;
this.disableSound = disableSound;
}
public static ItemBlocksAttacks read(PacketWrapper<?> wrapper) {
float blockDelaySeconds = wrapper.readFloat();
float disableCooldownScale = wrapper.readFloat();
List<DamageReduction> damageReductions = wrapper.readList(DamageReduction::read);
ItemDamageFunction itemDamage = ItemDamageFunction.read(wrapper);
ResourceLocation bypassedBy = wrapper.readOptional(PacketWrapper::readIdentifier);
Sound blockSound = wrapper.readOptional(Sound::read);
Sound disableSound = wrapper.readOptional(Sound::read);
return new ItemBlocksAttacks(
blockDelaySeconds, disableCooldownScale, damageReductions,
itemDamage, bypassedBy, blockSound, disableSound);
}
public static void write(PacketWrapper<?> wrapper, ItemBlocksAttacks attack) {
wrapper.writeFloat(attack.blockDelaySeconds);
wrapper.writeFloat(attack.disableCooldownScale);
wrapper.writeList(attack.damageReductions, DamageReduction::write);
ItemDamageFunction.write(wrapper, attack.itemDamage);
wrapper.writeOptional(attack.bypassedBy, PacketWrapper::writeIdentifier);
wrapper.writeOptional(attack.blockSound, Sound::write);
wrapper.writeOptional(attack.disableSound, Sound::write);
}
public float getBlockDelaySeconds() {
return this.blockDelaySeconds;
}
public void setBlockDelaySeconds(float blockDelaySeconds) {
this.blockDelaySeconds = blockDelaySeconds;
}
public float getDisableCooldownScale() {
return this.disableCooldownScale;
}
public void setDisableCooldownScale(float disableCooldownScale) {
this.disableCooldownScale = disableCooldownScale;
}
public List<DamageReduction> getDamageReductions() {
return this.damageReductions;
}
public void setDamageReductions(List<DamageReduction> damageReductions) {
this.damageReductions = damageReductions;
}
public ItemDamageFunction getItemDamage() {
return this.itemDamage;
}
public void setItemDamage(ItemDamageFunction itemDamage) {
this.itemDamage = itemDamage;
}
public @Nullable ResourceLocation getBypassedBy() {
return this.bypassedBy;
}
public void setBypassedBy(@Nullable ResourceLocation bypassedBy) {
this.bypassedBy = bypassedBy;
}
public @Nullable Sound getBlockSound() {
return this.blockSound;
}
public void setBlockSound(@Nullable Sound blockSound) {
this.blockSound = blockSound;
}
public @Nullable Sound getDisableSound() {
return this.disableSound;
}
public void setDisableSound(@Nullable Sound disableSound) {
this.disableSound = disableSound;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemBlocksAttacks)) return false;
ItemBlocksAttacks that = (ItemBlocksAttacks) obj;
if (Float.compare(that.blockDelaySeconds, this.blockDelaySeconds) != 0) return false;
if (Float.compare(that.disableCooldownScale, this.disableCooldownScale) != 0) return false;
if (!this.damageReductions.equals(that.damageReductions)) return false;
if (!this.itemDamage.equals(that.itemDamage)) return false;
if (!Objects.equals(this.bypassedBy, that.bypassedBy)) return false;
if (!Objects.equals(this.blockSound, that.blockSound)) return false;
return Objects.equals(this.disableSound, that.disableSound);
}
@Override
public int hashCode() {
return Objects.hash(this.blockDelaySeconds, this.disableCooldownScale, this.damageReductions, this.itemDamage, this.bypassedBy, this.blockSound, this.disableSound);
}
public static final class DamageReduction {
private float horizontalBlockingAngle;
private @Nullable MappedEntitySet<DamageType> type;
private float base;
private float factor;
public DamageReduction(float horizontalBlockingAngle, @Nullable MappedEntitySet<DamageType> type, float base, float factor) {
this.horizontalBlockingAngle = horizontalBlockingAngle;
this.type = type;
this.base = base;
this.factor = factor;
}
public static DamageReduction read(PacketWrapper<?> wrapper) {
float horizontalBlockingAngle = wrapper.readFloat();
MappedEntitySet<DamageType> type = wrapper.readOptional(ew ->
MappedEntitySet.read(ew, DamageTypes.getRegistry()));
float base = wrapper.readFloat();
float factor = wrapper.readFloat();
return new DamageReduction(horizontalBlockingAngle, type, base, factor);
}
public static void write(PacketWrapper<?> wrapper, DamageReduction reduction) {
wrapper.writeFloat(reduction.horizontalBlockingAngle);
wrapper.writeOptional(reduction.type, MappedEntitySet::write);
wrapper.writeFloat(reduction.base);
wrapper.writeFloat(reduction.factor);
}
public float getHorizontalBlockingAngle() {
return this.horizontalBlockingAngle;
}
public void setHorizontalBlockingAngle(float horizontalBlockingAngle) {
this.horizontalBlockingAngle = horizontalBlockingAngle;
}
public @Nullable MappedEntitySet<DamageType> getType() {
return this.type;
}
public void setType(@Nullable MappedEntitySet<DamageType> type) {
this.type = type;
}
public float getBase() {
return this.base;
}
public void setBase(float base) {
this.base = base;
}
public float getFactor() {
return this.factor;
}
public void setFactor(float factor) {
this.factor = factor;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof DamageReduction)) return false;
DamageReduction that = (DamageReduction) obj;
if (Float.compare(that.horizontalBlockingAngle, this.horizontalBlockingAngle) != 0) return false;
if (Float.compare(that.base, this.base) != 0) return false;
if (Float.compare(that.factor, this.factor) != 0) return false;
return Objects.equals(this.type, that.type);
}
@Override
public int hashCode() {
return Objects.hash(this.horizontalBlockingAngle, this.type, this.base, this.factor);
}
}
public static final class ItemDamageFunction {
private float threshold;
private float base;
private float factor;
public ItemDamageFunction(float threshold, float base, float factor) {
this.threshold = threshold;
this.base = base;
this.factor = factor;
}
public static ItemDamageFunction read(PacketWrapper<?> wrapper) {
float threshold = wrapper.readFloat();
float base = wrapper.readFloat();
float factor = wrapper.readFloat();
return new ItemDamageFunction(threshold, base, factor);
}
public static void write(PacketWrapper<?> wrapper, ItemDamageFunction function) {
wrapper.writeFloat(function.threshold);
wrapper.writeFloat(function.base);
wrapper.writeFloat(function.factor);
}
public float getThreshold() {
return this.threshold;
}
public void setThreshold(float threshold) {
this.threshold = threshold;
}
public float getBase() {
return this.base;
}
public void setBase(float base) {
this.base = base;
}
public float getFactor() {
return this.factor;
}
public void setFactor(float factor) {
this.factor = factor;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemDamageFunction)) return false;
ItemDamageFunction that = (ItemDamageFunction) obj;
if (Float.compare(that.threshold, this.threshold) != 0) return false;
if (Float.compare(that.base, this.base) != 0) return false;
return Float.compare(that.factor, this.factor) == 0;
}
@Override
public int hashCode() {
return Objects.hash(this.threshold, this.base, this.factor);
}
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemBreakSound {
private Sound sound;
public ItemBreakSound(Sound sound) {
this.sound = sound;
}
public static ItemBreakSound read(PacketWrapper<?> wrapper) {
Sound sound = Sound.read(wrapper);
return new ItemBreakSound(sound);
}
public static void write(PacketWrapper<?> wrapper, ItemBreakSound sound) {
Sound.write(wrapper, sound.sound);
}
public Sound getSound() {
return this.sound;
}
public void setSound(Sound sound) {
this.sound = sound;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemBreakSound)) return false;
ItemBreakSound that = (ItemBreakSound) obj;
return this.sound.equals(that.sound);
}
@Override
public int hashCode() {
return Objects.hashCode(this.sound);
}
}
@@ -18,15 +18,29 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.Objects;
public class ItemDyeColor {
private int rgb;
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
private boolean showInTooltip;
public ItemDyeColor(int rgb) {
this(rgb, true);
}
/**
* {@link #showInTooltip} has been removed in 1.21.5
*/
@ApiStatus.Obsolete
public ItemDyeColor(int rgb, boolean showInTooltip) {
this.rgb = rgb;
this.showInTooltip = showInTooltip;
@@ -34,13 +48,15 @@ public class ItemDyeColor {
public static ItemDyeColor read(PacketWrapper<?> wrapper) {
int rgb = wrapper.readInt();
boolean showInTooltip = wrapper.readBoolean();
boolean showInTooltip = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5) || wrapper.readBoolean();
return new ItemDyeColor(rgb, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemDyeColor color) {
wrapper.writeInt(color.rgb);
wrapper.writeBoolean(color.showInTooltip);
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(color.showInTooltip);
}
}
public int getRgb() {
@@ -51,10 +67,18 @@ public class ItemDyeColor {
this.rgb = rgb;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public boolean isShowInTooltip() {
return this.showInTooltip;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@@ -18,10 +18,12 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentType;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.Collections;
import java.util.Iterator;
@@ -32,6 +34,11 @@ public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Int
public static final ItemEnchantments EMPTY = new ItemEnchantments(
Collections.emptyMap(), true) {
@Override
public void setEnchantments(Map<EnchantmentType, Integer> enchantments) {
throw new UnsupportedOperationException();
}
@Override
public void setShowInTooltip(boolean showInTooltip) {
throw new UnsupportedOperationException();
@@ -39,8 +46,20 @@ public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Int
};
private Map<EnchantmentType, Integer> enchantments;
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
private boolean showInTooltip;
public ItemEnchantments(Map<EnchantmentType, Integer> enchantments) {
this(enchantments, true);
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public ItemEnchantments(Map<EnchantmentType, Integer> enchantments, boolean showInTooltip) {
this.enchantments = Collections.unmodifiableMap(enchantments);
this.showInTooltip = showInTooltip;
@@ -51,7 +70,7 @@ public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Int
ew -> wrapper.readMappedEntity(EnchantmentTypes.getRegistry()),
PacketWrapper::readVarInt
);
boolean showInTooltip = wrapper.readBoolean();
boolean showInTooltip = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5) || wrapper.readBoolean();
return new ItemEnchantments(enchantments, showInTooltip);
}
@@ -61,7 +80,9 @@ public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Int
(ew, enchantment) -> ew.writeVarInt(enchantment.getId(version)),
PacketWrapper::writeVarInt
);
wrapper.writeBoolean(enchantments.isShowInTooltip());
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(enchantments.isShowInTooltip());
}
}
public int getEnchantmentLevel(EnchantmentType enchantment) {
@@ -92,10 +113,18 @@ public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Int
this.enchantments = enchantments;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public boolean isShowInTooltip() {
return this.showInTooltip;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
@@ -25,6 +26,7 @@ import com.github.retrooper.packetevents.protocol.player.EquipmentSlot;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
@@ -39,7 +41,9 @@ public class ItemEquippable {
private boolean dispensable;
private boolean swappable;
private boolean damageOnHurt;
private boolean equipOnInteract;
@ApiStatus.Obsolete
public ItemEquippable(
EquipmentSlot slot,
Sound equipSound,
@@ -49,6 +53,21 @@ public class ItemEquippable {
boolean dispensable,
boolean swappable,
boolean damageOnHurt
) {
this(slot, equipSound, assetId, cameraOverlay, allowedEntities,
dispensable, swappable, damageOnHurt, false);
}
public ItemEquippable(
EquipmentSlot slot,
Sound equipSound,
@Nullable ResourceLocation assetId,
@Nullable ResourceLocation cameraOverlay,
@Nullable MappedEntitySet<EntityType> allowedEntities,
boolean dispensable,
boolean swappable,
boolean damageOnHurt,
boolean equipOnInteract
) {
this.slot = slot;
this.equipSound = equipSound;
@@ -58,20 +77,22 @@ public class ItemEquippable {
this.dispensable = dispensable;
this.swappable = swappable;
this.damageOnHurt = damageOnHurt;
this.equipOnInteract = equipOnInteract;
}
public static ItemEquippable read(PacketWrapper<?> wrapper) {
EquipmentSlot slot = wrapper.readEnum(EquipmentSlot.values());
Sound equipSound = Sound.read(wrapper);
ResourceLocation model = wrapper.readOptional(PacketWrapper::readIdentifier);
ResourceLocation assetId = wrapper.readOptional(PacketWrapper::readIdentifier);
ResourceLocation cameraOverlay = wrapper.readOptional(PacketWrapper::readIdentifier);
MappedEntitySet<EntityType> allowedEntities = wrapper.readOptional(
ew -> MappedEntitySet.read(ew, EntityTypes::getById));
boolean dispensable = wrapper.readBoolean();
boolean swappable = wrapper.readBoolean();
boolean damageOnHurt = wrapper.readBoolean();
return new ItemEquippable(slot, equipSound, model,
cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt);
boolean equipOnInteract = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5) && wrapper.readBoolean();
return new ItemEquippable(slot, equipSound, assetId,
cameraOverlay, allowedEntities, dispensable, swappable, damageOnHurt, equipOnInteract);
}
public static void write(PacketWrapper<?> wrapper, ItemEquippable equippable) {
@@ -83,6 +104,9 @@ public class ItemEquippable {
wrapper.writeBoolean(equippable.dispensable);
wrapper.writeBoolean(equippable.swappable);
wrapper.writeBoolean(equippable.damageOnHurt);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(equippable.equipOnInteract);
}
}
public EquipmentSlot getSlot() {
@@ -149,6 +173,20 @@ public class ItemEquippable {
this.damageOnHurt = damageOnHurt;
}
/**
* Added with 1.21.5
*/
public boolean isEquipOnInteract() {
return this.equipOnInteract;
}
/**
* Added with 1.21.5
*/
public void setEquipOnInteract(boolean equipOnInteract) {
this.equipOnInteract = equipOnInteract;
}
@Deprecated
public @Nullable ResourceLocation getModel() {
return this.assetId;
@@ -171,16 +209,17 @@ public class ItemEquippable {
if (!Objects.equals(this.equipSound, that.equipSound)) return false;
if (!Objects.equals(this.assetId, that.assetId)) return false;
if (!Objects.equals(this.cameraOverlay, that.cameraOverlay)) return false;
return Objects.equals(this.allowedEntities, that.allowedEntities);
if (!Objects.equals(this.allowedEntities, that.allowedEntities)) return false;
return Objects.equals(this.equipOnInteract, that.equipOnInteract);
}
@Override
public int hashCode() {
return Objects.hash(this.slot, this.equipSound, this.assetId, this.cameraOverlay, this.allowedEntities, this.dispensable, this.swappable, this.damageOnHurt);
return Objects.hash(this.slot, this.equipSound, this.assetId, this.cameraOverlay, this.allowedEntities, this.dispensable, this.swappable, this.damageOnHurt, this.equipOnInteract);
}
@Override
public String toString() {
return "ItemEquippable{slot=" + this.slot + ", equipSound=" + this.equipSound + ", model=" + this.assetId + ", cameraOverlay=" + this.cameraOverlay + ", allowedEntities=" + this.allowedEntities + ", dispensable=" + this.dispensable + ", swappable=" + this.swappable + ", damageOnHurt=" + this.damageOnHurt + '}';
return "ItemEquippable{slot=" + this.slot + ", equipSound=" + this.equipSound + ", assetId=" + this.assetId + ", cameraOverlay=" + this.cameraOverlay + ", allowedEntities=" + this.allowedEntities + ", dispensable=" + this.dispensable + ", swappable=" + this.swappable + ", damageOnHurt=" + this.damageOnHurt + ", equipOnInteract=" + this.equipOnInteract + '}';
}
}
@@ -0,0 +1,74 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.instrument.Instrument;
import com.github.retrooper.packetevents.protocol.item.instrument.Instruments;
import com.github.retrooper.packetevents.protocol.mapper.MaybeMappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemInstrument {
private MaybeMappedEntity<Instrument> instrument;
public ItemInstrument(MaybeMappedEntity<Instrument> instrument) {
this.instrument = instrument;
}
public static ItemInstrument read(PacketWrapper<?> wrapper) {
MaybeMappedEntity<Instrument> instrument;
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
instrument = MaybeMappedEntity.read(wrapper, Instruments.getRegistry(), Instrument::read);
} else {
instrument = new MaybeMappedEntity<>(Instrument.read(wrapper));
}
return new ItemInstrument(instrument);
}
public static void write(PacketWrapper<?> wrapper, ItemInstrument instrument) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
MaybeMappedEntity.write(wrapper, instrument.instrument, Instrument::write);
} else {
Instrument.write(wrapper, instrument.instrument.getValueOrThrow());
}
}
public MaybeMappedEntity<Instrument> getInstrument() {
return this.instrument;
}
public void setInstrument(MaybeMappedEntity<Instrument> instrument) {
this.instrument = instrument;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemInstrument)) return false;
ItemInstrument that = (ItemInstrument) obj;
return this.instrument.equals(that.instrument);
}
@Override
public int hashCode() {
return Objects.hashCode(this.instrument);
}
}
@@ -18,20 +18,35 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.jukebox.IJukeboxSong;
import com.github.retrooper.packetevents.protocol.item.jukebox.JukeboxSong;
import com.github.retrooper.packetevents.protocol.item.jukebox.JukeboxSongs;
import com.github.retrooper.packetevents.protocol.mapper.MaybeMappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class ItemJukeboxPlayable {
private @Nullable IJukeboxSong song;
private @Nullable ResourceLocation songKey;
private MaybeMappedEntity<IJukeboxSong> song;
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
private boolean showInTooltip;
public ItemJukeboxPlayable(MaybeMappedEntity<IJukeboxSong> song) {
this(song, true);
}
/**
* {@link #showInTooltip} has been removed in 1.21.5
*/
@ApiStatus.Obsolete
public ItemJukeboxPlayable(
@Nullable JukeboxSong song,
@Nullable ResourceLocation songKey,
@@ -40,85 +55,99 @@ public class ItemJukeboxPlayable {
this((IJukeboxSong) song, songKey, showInTooltip);
}
/**
* use {@link #ItemJukeboxPlayable(MaybeMappedEntity, boolean)}
*/
@Deprecated
public ItemJukeboxPlayable(
@Nullable IJukeboxSong song,
@Nullable ResourceLocation songKey,
boolean showInTooltip
) {
if ((song == null) == (songKey == null)) {
throw new IllegalStateException("Illegal state of both song and "
+ "song key combined: " + song + " / " + songKey);
}
this(new MaybeMappedEntity<>(song, songKey), showInTooltip);
}
/**
* {@link #showInTooltip} has been removed in 1.21.5
*/
@ApiStatus.Obsolete
public ItemJukeboxPlayable(
MaybeMappedEntity<IJukeboxSong> song,
boolean showInTooltip
) {
this.song = song;
this.songKey = songKey;
this.showInTooltip = showInTooltip;
}
public static ItemJukeboxPlayable read(PacketWrapper<?> wrapper) {
IJukeboxSong song;
ResourceLocation songKey;
if (wrapper.readBoolean()) {
song = IJukeboxSong.read(wrapper);
songKey = null;
} else {
song = null;
songKey = wrapper.readIdentifier();
}
boolean showInTooltip = wrapper.readBoolean();
return new ItemJukeboxPlayable(song, songKey, showInTooltip);
MaybeMappedEntity<IJukeboxSong> song = MaybeMappedEntity.read(wrapper, JukeboxSongs.getRegistry(), IJukeboxSong::read);
boolean showInTooltip = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5) || wrapper.readBoolean();
return new ItemJukeboxPlayable(song, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemJukeboxPlayable jukeboxPlayable) {
if (jukeboxPlayable.song != null) {
wrapper.writeBoolean(true);
IJukeboxSong.write(wrapper, jukeboxPlayable.song);
} else {
assert jukeboxPlayable.songKey != null;
wrapper.writeBoolean(false);
wrapper.writeIdentifier(jukeboxPlayable.songKey);
MaybeMappedEntity.write(wrapper, jukeboxPlayable.song, IJukeboxSong::write);
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(jukeboxPlayable.showInTooltip);
}
wrapper.writeBoolean(jukeboxPlayable.showInTooltip);
}
public @Nullable IJukeboxSong getJukeboxSong() {
public MaybeMappedEntity<IJukeboxSong> getSongHolder() {
return this.song;
}
public void setSongHolder(MaybeMappedEntity<IJukeboxSong> songHolder) {
this.song = songHolder;
}
public @Nullable IJukeboxSong getJukeboxSong() {
return this.song.getValue();
}
public void setJukeboxSong(@Nullable IJukeboxSong song) {
this.song = new MaybeMappedEntity<>(song);
}
public void setJukeboxSong(@Nullable JukeboxSong song) {
this.song = song;
this.songKey = null;
this.setJukeboxSong((IJukeboxSong) song);
}
@Deprecated
public @Nullable JukeboxSong getSong() {
if (this.song == null) {
IJukeboxSong song = this.getJukeboxSong();
if (song == null) {
return null;
} else if (this.song instanceof JukeboxSong) {
return (JukeboxSong) this.song;
} else if (song instanceof JukeboxSong) {
return (JukeboxSong) song;
}
return (JukeboxSong) this.song.copy(null);
return (JukeboxSong) song.copy(null);
}
@Deprecated
public void setSong(JukeboxSong song) {
this.song = song;
this.songKey = null;
this.setJukeboxSong((IJukeboxSong) song);
}
public @Nullable ResourceLocation getSongKey() {
return this.songKey;
return this.song.getName();
}
public void setSongKey(ResourceLocation songKey) {
this.song = null;
this.songKey = songKey;
this.song = new MaybeMappedEntity<>(songKey);
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public boolean isShowInTooltip() {
return this.showInTooltip;
}
/**
* Removed in 1.21.5
*/
@ApiStatus.Obsolete
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@@ -130,11 +159,11 @@ public class ItemJukeboxPlayable {
ItemJukeboxPlayable that = (ItemJukeboxPlayable) obj;
if (this.showInTooltip != that.showInTooltip) return false;
if (!Objects.equals(this.song, that.song)) return false;
return Objects.equals(this.songKey, that.songKey);
return Objects.equals(this.song, that.song);
}
@Override
public int hashCode() {
return Objects.hash(this.song, this.songKey, this.showInTooltip);
return Objects.hash(this.song, this.song, this.showInTooltip);
}
}
@@ -0,0 +1,61 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemPotionDurationScale {
private float scale;
public ItemPotionDurationScale(float scale) {
this.scale = scale;
}
public static ItemPotionDurationScale read(PacketWrapper<?> wrapper) {
float scale = wrapper.readFloat();
return new ItemPotionDurationScale(scale);
}
public static void write(PacketWrapper<?> wrapper, ItemPotionDurationScale scale) {
wrapper.writeFloat(scale.scale);
}
public float getScale() {
return this.scale;
}
public void setScale(float scale) {
this.scale = scale;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemPotionDurationScale)) return false;
ItemPotionDurationScale that = (ItemPotionDurationScale) obj;
return Float.compare(that.scale, this.scale) == 0;
}
@Override
public int hashCode() {
return Objects.hashCode(this.scale);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemProvidesBannerPatterns {
private ResourceLocation tagKey;
public ItemProvidesBannerPatterns(ResourceLocation tagKey) {
this.tagKey = tagKey;
}
public static ItemProvidesBannerPatterns read(PacketWrapper<?> wrapper) {
ResourceLocation tagKey = wrapper.readIdentifier();
return new ItemProvidesBannerPatterns(tagKey);
}
public static void write(PacketWrapper<?> wrapper, ItemProvidesBannerPatterns patterns) {
wrapper.writeIdentifier(patterns.tagKey);
}
public ResourceLocation getTagKey() {
return this.tagKey;
}
public void setTagKey(ResourceLocation tagKey) {
this.tagKey = tagKey;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemProvidesBannerPatterns)) return false;
ItemProvidesBannerPatterns that = (ItemProvidesBannerPatterns) obj;
return this.tagKey.equals(that.tagKey);
}
@Override
public int hashCode() {
return Objects.hashCode(this.tagKey);
}
}
@@ -0,0 +1,64 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.trimmaterial.TrimMaterial;
import com.github.retrooper.packetevents.protocol.item.trimmaterial.TrimMaterials;
import com.github.retrooper.packetevents.protocol.mapper.MaybeMappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemProvidesTrimMaterial {
private MaybeMappedEntity<TrimMaterial> material;
public ItemProvidesTrimMaterial(MaybeMappedEntity<TrimMaterial> material) {
this.material = material;
}
public static ItemProvidesTrimMaterial read(PacketWrapper<?> wrapper) {
MaybeMappedEntity<TrimMaterial> material = MaybeMappedEntity.read(wrapper, TrimMaterials.getRegistry(), TrimMaterial::read);
return new ItemProvidesTrimMaterial(material);
}
public static void write(PacketWrapper<?> wrapper, ItemProvidesTrimMaterial material) {
MaybeMappedEntity.write(wrapper, material.material, TrimMaterial::write);
}
public MaybeMappedEntity<TrimMaterial> getMaterial() {
return this.material;
}
public void setMaterial(MaybeMappedEntity<TrimMaterial> material) {
this.material = material;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemProvidesTrimMaterial)) return false;
ItemProvidesTrimMaterial that = (ItemProvidesTrimMaterial) obj;
return this.material.equals(that.material);
}
@Override
public int hashCode() {
return Objects.hashCode(this.material);
}
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
@@ -32,24 +33,37 @@ public class ItemTool {
private List<Rule> rules;
private float defaultMiningSpeed;
private int damagePerBlock;
/**
* Added with 1.21.5
*/
private boolean canDestroyBlocksInCreative;
public ItemTool(List<Rule> rules, float defaultMiningSpeed, int damagePerBlock) {
this(rules, defaultMiningSpeed, damagePerBlock, true);
}
public ItemTool(List<Rule> rules, float defaultMiningSpeed, int damagePerBlock, boolean canDestroyBlocksInCreative) {
this.rules = rules;
this.defaultMiningSpeed = defaultMiningSpeed;
this.damagePerBlock = damagePerBlock;
this.canDestroyBlocksInCreative = canDestroyBlocksInCreative;
}
public static ItemTool read(PacketWrapper<?> wrapper) {
List<Rule> rules = wrapper.readList(Rule::read);
float defaultMiningSpeed = wrapper.readFloat();
int damagePerBlock = wrapper.readVarInt();
return new ItemTool(rules, defaultMiningSpeed, damagePerBlock);
boolean canDestroyBlocksInCreative = wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5) || wrapper.readBoolean();
return new ItemTool(rules, defaultMiningSpeed, damagePerBlock, canDestroyBlocksInCreative);
}
public static void write(PacketWrapper<?> wrapper, ItemTool tool) {
wrapper.writeList(tool.rules, Rule::write);
wrapper.writeFloat(tool.defaultMiningSpeed);
wrapper.writeVarInt(tool.damagePerBlock);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(tool.canDestroyBlocksInCreative);
}
}
public void addRule(Rule rule) {
@@ -80,6 +94,20 @@ public class ItemTool {
this.damagePerBlock = damagePerBlock;
}
/**
* Added with 1.21.5
*/
public boolean isCanDestroyBlocksInCreative() {
return this.canDestroyBlocksInCreative;
}
/**
* Added with 1.21.5
*/
public void setCanDestroyBlocksInCreative(boolean canDestroyBlocksInCreative) {
this.canDestroyBlocksInCreative = canDestroyBlocksInCreative;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -87,12 +115,13 @@ public class ItemTool {
ItemTool itemTool = (ItemTool) obj;
if (Float.compare(itemTool.defaultMiningSpeed, this.defaultMiningSpeed) != 0) return false;
if (this.damagePerBlock != itemTool.damagePerBlock) return false;
return this.rules.equals(itemTool.rules);
if (!this.rules.equals(itemTool.rules)) return false;
return this.canDestroyBlocksInCreative == itemTool.canDestroyBlocksInCreative;
}
@Override
public int hashCode() {
return Objects.hash(this.rules, this.defaultMiningSpeed, this.damagePerBlock);
return Objects.hash(this.rules, this.defaultMiningSpeed, this.damagePerBlock, this.canDestroyBlocksInCreative);
}
public static class Rule {
@@ -0,0 +1,79 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.component.ComponentType;
import com.github.retrooper.packetevents.protocol.component.ComponentTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
public class ItemTooltipDisplay {
private boolean hideTooltip;
private Set<ComponentType<?>> hiddenComponents;
public ItemTooltipDisplay(boolean hideTooltip, Set<ComponentType<?>> hiddenComponents) {
this.hideTooltip = hideTooltip;
this.hiddenComponents = hiddenComponents;
}
public static ItemTooltipDisplay read(PacketWrapper<?> wrapper) {
boolean hideTooltip = wrapper.readBoolean();
Set<ComponentType<?>> hiddenComponents = wrapper.readCollection(LinkedHashSet::new,
ew -> ew.readMappedEntity(ComponentTypes.getRegistry()));
return new ItemTooltipDisplay(hideTooltip, hiddenComponents);
}
public static void write(PacketWrapper<?> wrapper, ItemTooltipDisplay tooltipDisplay) {
wrapper.writeBoolean(tooltipDisplay.hideTooltip);
wrapper.writeCollection(tooltipDisplay.hiddenComponents, PacketWrapper::writeMappedEntity);
}
public boolean isHideTooltip() {
return this.hideTooltip;
}
public void setHideTooltip(boolean hideTooltip) {
this.hideTooltip = hideTooltip;
}
public Set<ComponentType<?>> getHiddenComponents() {
return this.hiddenComponents;
}
public void setHiddenComponents(Set<ComponentType<?>> hiddenComponents) {
this.hiddenComponents = hiddenComponents;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemTooltipDisplay)) return false;
ItemTooltipDisplay that = (ItemTooltipDisplay) obj;
if (this.hideTooltip != that.hideTooltip) return false;
return this.hiddenComponents.equals(that.hiddenComponents);
}
@Override
public int hashCode() {
return Objects.hash(this.hideTooltip, this.hiddenComponents);
}
}
@@ -0,0 +1,88 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.Objects;
public class ItemUnbreakable {
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
private boolean showInTooltip;
public ItemUnbreakable() {
this(true);
}
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
public ItemUnbreakable(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
public static ItemUnbreakable read(PacketWrapper<?> wrapper) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
return new ItemUnbreakable();
}
boolean showInTooltip = wrapper.readBoolean();
return new ItemUnbreakable(showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemUnbreakable value) {
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_5)) {
wrapper.writeBoolean(value.showInTooltip);
}
}
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
public boolean isShowInTooltip() {
return this.showInTooltip;
}
/**
* Removed with 1.21.5
*/
@ApiStatus.Obsolete
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemUnbreakable)) return false;
ItemUnbreakable that = (ItemUnbreakable) obj;
return this.showInTooltip == that.showInTooltip;
}
@Override
public int hashCode() {
return Objects.hashCode(this.showInTooltip);
}
}
@@ -0,0 +1,74 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemWeapon {
private int itemDamagePerAttack;
private float disableBlockingForSeconds;
public ItemWeapon(int itemDamagePerAttack, float disableBlockingForSeconds) {
this.itemDamagePerAttack = itemDamagePerAttack;
this.disableBlockingForSeconds = disableBlockingForSeconds;
}
public static ItemWeapon read(PacketWrapper<?> wrapper) {
int itemDamagePerAttack = wrapper.readVarInt();
float disableBlockingForSeconds = wrapper.readFloat();
return new ItemWeapon(itemDamagePerAttack, disableBlockingForSeconds);
}
public static void write(PacketWrapper<?> wrapper, ItemWeapon weapon) {
wrapper.writeVarInt(weapon.itemDamagePerAttack);
wrapper.writeFloat(weapon.disableBlockingForSeconds);
}
public int getItemDamagePerAttack() {
return this.itemDamagePerAttack;
}
public void setItemDamagePerAttack(int itemDamagePerAttack) {
this.itemDamagePerAttack = itemDamagePerAttack;
}
public float getDisableBlockingForSeconds() {
return this.disableBlockingForSeconds;
}
public void setDisableBlockingForSeconds(float disableBlockingForSeconds) {
this.disableBlockingForSeconds = disableBlockingForSeconds;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ItemWeapon)) return false;
ItemWeapon that = (ItemWeapon) obj;
if (this.itemDamagePerAttack != that.itemDamagePerAttack) return false;
return Float.compare(that.disableBlockingForSeconds, this.disableBlockingForSeconds) == 0;
}
@Override
public int hashCode() {
return Objects.hash(this.itemDamagePerAttack, this.disableBlockingForSeconds);
}
}
@@ -0,0 +1,81 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.predicates;
import com.github.retrooper.packetevents.protocol.component.ComponentPredicate;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class ComponentMatchers {
private ComponentPredicate components;
private List<TypedComponentPredicate<?>> predicates;
public ComponentMatchers() {
this(new ComponentPredicate(), new ArrayList<>());
}
public ComponentMatchers(ComponentPredicate components, List<TypedComponentPredicate<?>> predicates) {
this.components = components;
this.predicates = predicates;
}
public static ComponentMatchers read(PacketWrapper<?> wrapper) {
ComponentPredicate components = ComponentPredicate.read(wrapper);
List<TypedComponentPredicate<?>> predicates = wrapper.readList(TypedComponentPredicate::read);
return new ComponentMatchers(components, predicates);
}
public static void write(PacketWrapper<?> wrapper, ComponentMatchers matchers) {
ComponentPredicate.write(wrapper, matchers.components);
wrapper.writeList(matchers.predicates, TypedComponentPredicate::write);
}
public ComponentPredicate getComponents() {
return this.components;
}
public void setComponents(ComponentPredicate components) {
this.components = components;
}
public List<TypedComponentPredicate<?>> getPredicates() {
return this.predicates;
}
public void setPredicates(List<TypedComponentPredicate<?>> predicates) {
this.predicates = predicates;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ComponentMatchers)) return false;
ComponentMatchers that = (ComponentMatchers) obj;
if (!this.components.equals(that.components)) return false;
return this.predicates.equals(that.predicates);
}
@Override
public int hashCode() {
return Objects.hash(this.components, this.predicates);
}
}
@@ -0,0 +1,29 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.predicates;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface ComponentPredicateType<T extends IComponentPredicate> extends MappedEntity {
T read(PacketWrapper<?> wrapper);
void write(PacketWrapper<?> wrapper, T predicate);
}
@@ -0,0 +1,96 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.predicates;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* This implementation is experimental and not done yet. As I don't expect
* component predicates to be used in packetevents at all, it is currently not
* read from/to NBT; if you want/need this though, feel free to mention it
* via GitHub/Discord - or open a PR!
*/
public final class ComponentPredicateTypes {
private static final VersionedRegistry<ComponentPredicateType<?>> REGISTRY =
new VersionedRegistry<>("data_component_predicate_type");
private ComponentPredicateTypes() {
}
@ApiStatus.Internal
public static <T extends IComponentPredicate> ComponentPredicateType<T> define(
String key, PacketWrapper.Reader<T> reader, PacketWrapper.Writer<T> writer) {
return REGISTRY.define(key, data ->
new StaticComponentPredicateType<>(data, reader, writer));
}
public static VersionedRegistry<ComponentPredicateType<?>> getRegistry() {
return REGISTRY;
}
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> DAMAGE =
define("damage", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> ENCHANTMENTS =
define("enchantments", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> STORED_ENCHANTMENTS =
define("stored_enchantments", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> POTION_CONTENTS =
define("potion_contents", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> CUSTOM_DATA =
define("custom_data", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> CONTAINER =
define("container", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> BUNDLE_CONTENTS =
define("bundle_contents", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> FIREWORK_EXPLOSION =
define("firework_explosion", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> FIREWORKS =
define("fireworks", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> WRITABLE_BOOK_CONTENT =
define("writable_book_content", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> WRITTEN_BOOK_CONTENT =
define("written_book_content", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> ATTRIBUTE_MODIFIERS =
define("attribute_modifiers", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> TRIM =
define("trim", NbtComponentPredicate::read, NbtComponentPredicate::write);
@ApiStatus.Experimental
public static final ComponentPredicateType<NbtComponentPredicate> JUKEBOX_PLAYABLE =
define("jukebox_playable", NbtComponentPredicate::read, NbtComponentPredicate::write);
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,22 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.predicates;
public interface IComponentPredicate {
}
@@ -0,0 +1,60 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.predicates;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.Objects;
@ApiStatus.Experimental
public class NbtComponentPredicate implements IComponentPredicate {
private final NBT tag;
public NbtComponentPredicate(NBT tag) {
this.tag = tag;
}
public static NbtComponentPredicate read(PacketWrapper<?> wrapper) {
NBT tag = wrapper.readNBTRaw();
return new NbtComponentPredicate(tag);
}
public static void write(PacketWrapper<?> wrapper, NbtComponentPredicate predicate) {
wrapper.writeNBTRaw(predicate.tag);
}
public NBT getTag() {
return this.tag;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NbtComponentPredicate)) return false;
NbtComponentPredicate that = (NbtComponentPredicate) obj;
return this.tag.equals(that.tag);
}
@Override
public int hashCode() {
return Objects.hashCode(this.tag);
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.predicates;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
public class StaticComponentPredicateType<T extends IComponentPredicate> extends AbstractMappedEntity implements ComponentPredicateType<T> {
private final PacketWrapper.Reader<T> reader;
private final PacketWrapper.Writer<T> writer;
public StaticComponentPredicateType(PacketWrapper.Reader<T> reader, PacketWrapper.Writer<T> writer) {
this(null, reader, writer);
}
@ApiStatus.Internal
public StaticComponentPredicateType(
@Nullable TypesBuilderData data,
PacketWrapper.Reader<T> reader,
PacketWrapper.Writer<T> writer
) {
super(data);
this.reader = reader;
this.writer = writer;
}
@Override
public T read(PacketWrapper<?> wrapper) {
return this.reader.apply(wrapper);
}
@Override
public void write(PacketWrapper<?> wrapper, T predicate) {
this.writer.accept(wrapper, predicate);
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.predicates;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class TypedComponentPredicate<T extends IComponentPredicate> {
private final ComponentPredicateType<T> type;
private final T predicate;
public TypedComponentPredicate(ComponentPredicateType<T> type, T predicate) {
this.type = type;
this.predicate = predicate;
}
@SuppressWarnings("unchecked")
public static TypedComponentPredicate<?> read(PacketWrapper<?> wrapper) {
ComponentPredicateType<?> type = wrapper.readMappedEntity(ComponentPredicateTypes.getRegistry());
IComponentPredicate predicate = type.read(wrapper);
return new TypedComponentPredicate<>((ComponentPredicateType<IComponentPredicate>) type, predicate);
}
public static <T extends IComponentPredicate> void write(PacketWrapper<?> wrapper, TypedComponentPredicate<T> predicate) {
wrapper.writeMappedEntity(predicate.type);
predicate.type.write(wrapper, predicate.predicate);
}
public ComponentPredicateType<T> getType() {
return this.type;
}
public T getPredicate() {
return this.predicate;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof TypedComponentPredicate)) return false;
TypedComponentPredicate<?> that = (TypedComponentPredicate<?>) obj;
if (!this.type.equals(that.type)) return false;
return this.predicate.equals(that.predicate);
}
@Override
public int hashCode() {
return Objects.hash(this.type, this.predicate);
}
}
@@ -0,0 +1,24 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.axolotl;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
public interface AxolotlVariant extends MappedEntity {
}
@@ -0,0 +1,50 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.axolotl;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
public final class AxolotlVariants {
private static final VersionedRegistry<AxolotlVariant> REGISTRY =
new VersionedRegistry<>("axolotl_variant");
private AxolotlVariants() {
}
@ApiStatus.Internal
public static AxolotlVariant define(String name) {
return REGISTRY.define(name, StaticAxolotlVariant::new);
}
public static VersionedRegistry<AxolotlVariant> getRegistry() {
return REGISTRY;
}
public static final AxolotlVariant LUCY = define("lucy");
public static final AxolotlVariant WILD = define("wild");
public static final AxolotlVariant GOLD = define("gold");
public static final AxolotlVariant CYAN = define("cyan");
public static final AxolotlVariant BLUE = define("blue");
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,32 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.axolotl;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
public class StaticAxolotlVariant extends AbstractMappedEntity implements AxolotlVariant {
@ApiStatus.Internal
public StaticAxolotlVariant(@Nullable TypesBuilderData data) {
super(data);
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.cat;
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
import com.github.retrooper.packetevents.protocol.mapper.DeepComparableEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
public interface CatVariant extends MappedEntity, CopyableEntity<CatVariant>, DeepComparableEntity {
ResourceLocation getAssetId();
static CatVariant read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntity(CatVariants.getRegistry());
}
static void write(PacketWrapper<?> wrapper, CatVariant variant) {
wrapper.writeMappedEntity(variant);
}
static CatVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
return new StaticCatVariant(data, assetId);
}
static NBT encode(CatVariant variant, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("asset_id", new NBTString(variant.getAssetId().toString()));
return compound;
}
}
@@ -0,0 +1,59 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.cat;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
public final class CatVariants {
private static final VersionedRegistry<CatVariant> REGISTRY =
new VersionedRegistry<>("cat_variant");
private CatVariants() {
}
@ApiStatus.Internal
public static CatVariant define(String name) {
ResourceLocation assetId = new ResourceLocation("entity/cat/" + name);
return REGISTRY.define(name, data ->
new StaticCatVariant(data, assetId));
}
public static VersionedRegistry<CatVariant> getRegistry() {
return REGISTRY;
}
public static final CatVariant ALL_BLACK = define("all_black");
public static final CatVariant BLACK = define("black");
public static final CatVariant BRITISH_SHORTHAIR = define("british_shorthair");
public static final CatVariant CALICO = define("calico");
public static final CatVariant JELLIE = define("jellie");
public static final CatVariant PERSIAN = define("persian");
public static final CatVariant RAGDOLL = define("ragdoll");
public static final CatVariant RED = define("red");
public static final CatVariant SIAMESE = define("siamese");
public static final CatVariant TABBY = define("tabby");
public static final CatVariant WHITE = define("white");
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,65 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.cat;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class StaticCatVariant extends AbstractMappedEntity implements CatVariant {
private final ResourceLocation assetId;
public StaticCatVariant(ResourceLocation assetId) {
this(null, assetId);
}
@ApiStatus.Internal
public StaticCatVariant(@Nullable TypesBuilderData data, ResourceLocation assetId) {
super(data);
this.assetId = assetId;
}
@Override
public CatVariant copy(@Nullable TypesBuilderData newData) {
return new StaticCatVariant(newData, this.assetId);
}
@Override
public ResourceLocation getAssetId() {
return this.assetId;
}
@Override
public boolean deepEquals(Object obj) {
if (!(obj instanceof StaticCatVariant)) return false;
if (!super.equals(obj)) return false;
StaticCatVariant that = (StaticCatVariant) obj;
return this.assetId.equals(that.assetId);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.assetId);
}
}
@@ -0,0 +1,87 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.chicken;
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
import com.github.retrooper.packetevents.protocol.mapper.DeepComparableEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.util.Index;
import org.jetbrains.annotations.Nullable;
public interface ChickenVariant extends MappedEntity, CopyableEntity<ChickenVariant>, DeepComparableEntity {
ModelType getModelType();
ResourceLocation getAssetId();
static ChickenVariant read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntity(ChickenVariants.getRegistry());
}
static void write(PacketWrapper<?> wrapper, ChickenVariant variant) {
wrapper.writeMappedEntity(variant);
}
static ChickenVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
String modelTypeString = compound.getStringTagValueOrNull("model");
ModelType modelType = modelTypeString != null ? ModelType.getByName(modelTypeString) : ModelType.NORMAL;
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
return new StaticChickenVariant(data, modelType, assetId);
}
static NBT encode(ChickenVariant variant, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("model", new NBTString(variant.getModelType().getName()));
compound.setTag("asset_id", new NBTString(variant.getAssetId().toString()));
return compound;
}
enum ModelType {
NORMAL("normal"),
COLD("cold"),
;
private static final Index<String, ModelType> NAME_INDEX = Index.create(
ModelType.class, ModelType::getName);
private final String name;
ModelType(String name) {
this.name = name;
}
public static ModelType getByName(String name) {
return AdventureIndexUtil.indexValueOrThrow(NAME_INDEX, name);
}
public String getName() {
return this.name;
}
}
}
@@ -0,0 +1,52 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.chicken;
import com.github.retrooper.packetevents.protocol.entity.chicken.ChickenVariant.ModelType;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
public final class ChickenVariants {
private static final VersionedRegistry<ChickenVariant> REGISTRY =
new VersionedRegistry<>("chicken_variant");
private ChickenVariants() {
}
@ApiStatus.Internal
public static ChickenVariant define(String name, ModelType modelType, String texture) {
ResourceLocation assetId = new ResourceLocation("entity/chicken/" + texture);
return REGISTRY.define(name, data ->
new StaticChickenVariant(data, modelType, assetId));
}
public static VersionedRegistry<ChickenVariant> getRegistry() {
return REGISTRY;
}
public static final ChickenVariant COLD = define("cold", ModelType.COLD, "cold_chicken");
public static final ChickenVariant TEMPERATE = define("temperate", ModelType.NORMAL, "temperate_chicken");
public static final ChickenVariant WARM = define("warm", ModelType.NORMAL, "warm_chicken");
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,73 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.chicken;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class StaticChickenVariant extends AbstractMappedEntity implements ChickenVariant {
private final ModelType modelType;
private final ResourceLocation assetId;
public StaticChickenVariant(ModelType modelType, ResourceLocation assetId) {
this(null, modelType, assetId);
}
@ApiStatus.Internal
public StaticChickenVariant(@Nullable TypesBuilderData data, ModelType modelType, ResourceLocation assetId) {
super(data);
this.modelType = modelType;
this.assetId = assetId;
}
@Override
public ChickenVariant copy(@Nullable TypesBuilderData newData) {
return new StaticChickenVariant(newData, this.modelType, this.assetId);
}
@Override
public ModelType getModelType() {
return this.modelType;
}
@Override
public ResourceLocation getAssetId() {
return this.assetId;
}
@Override
public boolean deepEquals(Object obj) {
if (!(obj instanceof StaticChickenVariant)) return false;
if (!super.equals(obj)) return false;
StaticChickenVariant that = (StaticChickenVariant) obj;
if (!this.modelType.equals(that.modelType)) return false;
return this.assetId.equals(that.assetId);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.modelType, this.assetId);
}
}
@@ -0,0 +1,88 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.cow;
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
import com.github.retrooper.packetevents.protocol.mapper.DeepComparableEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.util.Index;
import org.jetbrains.annotations.Nullable;
public interface CowVariant extends MappedEntity, CopyableEntity<CowVariant>, DeepComparableEntity {
ModelType getModelType();
ResourceLocation getAssetId();
static CowVariant read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntity(CowVariants.getRegistry());
}
static void write(PacketWrapper<?> wrapper, CowVariant variant) {
wrapper.writeMappedEntity(variant);
}
static CowVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
String modelTypeString = compound.getStringTagValueOrNull("model");
ModelType modelType = modelTypeString != null ? ModelType.getByName(modelTypeString) : ModelType.NORMAL;
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
return new StaticCowVariant(data, modelType, assetId);
}
static NBT encode(CowVariant variant, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("model", new NBTString(variant.getModelType().getName()));
compound.setTag("asset_id", new NBTString(variant.getAssetId().toString()));
return compound;
}
enum ModelType {
NORMAL("normal"),
COLD("cold"),
WARM("warm"),
;
private static final Index<String, ModelType> NAME_INDEX = Index.create(
ModelType.class, ModelType::getName);
private final String name;
ModelType(String name) {
this.name = name;
}
public static ModelType getByName(String name) {
return AdventureIndexUtil.indexValueOrThrow(NAME_INDEX, name);
}
public String getName() {
return this.name;
}
}
}
@@ -0,0 +1,52 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.cow;
import com.github.retrooper.packetevents.protocol.entity.cow.CowVariant.ModelType;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
public final class CowVariants {
private static final VersionedRegistry<CowVariant> REGISTRY =
new VersionedRegistry<>("cow_variant");
private CowVariants() {
}
@ApiStatus.Internal
public static CowVariant define(String name, ModelType modelType, String texture) {
ResourceLocation assetId = new ResourceLocation("entity/cow/" + texture);
return REGISTRY.define(name, data ->
new StaticCowVariant(data, modelType, assetId));
}
public static VersionedRegistry<CowVariant> getRegistry() {
return REGISTRY;
}
public static final CowVariant COLD = define("cold", ModelType.COLD, "cold_cow");
public static final CowVariant TEMPERATE = define("temperate", ModelType.NORMAL, "temperate_cow");
public static final CowVariant WARM = define("warm", ModelType.WARM, "warm_cow");
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,73 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.cow;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class StaticCowVariant extends AbstractMappedEntity implements CowVariant {
private final ModelType modelType;
private final ResourceLocation assetId;
public StaticCowVariant(ModelType modelType, ResourceLocation assetId) {
this(null, modelType, assetId);
}
@ApiStatus.Internal
public StaticCowVariant(@Nullable TypesBuilderData data, ModelType modelType, ResourceLocation assetId) {
super(data);
this.modelType = modelType;
this.assetId = assetId;
}
@Override
public CowVariant copy(@Nullable TypesBuilderData newData) {
return new StaticCowVariant(newData, this.modelType, this.assetId);
}
@Override
public ModelType getModelType() {
return this.modelType;
}
@Override
public ResourceLocation getAssetId() {
return this.assetId;
}
@Override
public boolean deepEquals(Object obj) {
if (!(obj instanceof StaticCowVariant)) return false;
if (!super.equals(obj)) return false;
StaticCowVariant that = (StaticCowVariant) obj;
if (!this.modelType.equals(that.modelType)) return false;
return this.assetId.equals(that.assetId);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.modelType, this.assetId);
}
}
@@ -18,38 +18,39 @@
package com.github.retrooper.packetevents.protocol.entity.data;
public class EntityData {
private int index;
private EntityDataType<?> type;
private Object value;
public class EntityData<T> {
public EntityData(int index, EntityDataType<?> type, Object value) {
private int index;
private EntityDataType<T> type;
private T value;
public EntityData(int index, EntityDataType<T> type, T value) {
this.index = index;
this.type = type;
this.value = value;
}
public int getIndex() {
return index;
return this.index;
}
public void setIndex(int index) {
this.index = index;
}
public EntityDataType<?> getType() {
return type;
public EntityDataType<T> getType() {
return this.type;
}
public void setType(EntityDataType<?> type) {
public void setType(EntityDataType<T> type) {
this.type = type;
}
public Object getValue() {
return value;
public T getValue() {
return this.value;
}
public void setValue(Object value) {
public void setValue(T value) {
this.value = value;
}
}
}
@@ -18,39 +18,46 @@
package com.github.retrooper.packetevents.protocol.entity.data;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class EntityDataType<T> {
private final String name;
private final int[] ids;
private final Function<PacketWrapper<?>, T> dataDeserializer;
private final BiConsumer<PacketWrapper<?>, Object> dataSerializer;
public class EntityDataType<T> extends AbstractMappedEntity {
public EntityDataType(String name, int[] ids, Function<PacketWrapper<?>, T> dataDeserializer, BiConsumer<PacketWrapper<?>, Object> dataSerializer) {
this.name = name;
this.ids = ids;
this.dataDeserializer = dataDeserializer;
this.dataSerializer = dataSerializer;
private final PacketWrapper.Reader<? extends T> reader;
private final PacketWrapper.Writer<T> writer;
@ApiStatus.Internal
public EntityDataType(
@Nullable TypesBuilderData data,
PacketWrapper.Reader<? extends T> reader,
PacketWrapper.Writer<T> writer
) {
super(data);
this.reader = reader;
this.writer = writer;
}
public String getName() {
return name;
public T read(PacketWrapper<?> wrapper) {
return this.reader.apply(wrapper);
}
public int getId(ClientVersion version) {
int index = EntityDataTypes.TYPES_BUILDER.getDataIndex(version);
return ids[index];
public void write(PacketWrapper<?> wrapper, T serializer) {
this.writer.accept(wrapper, serializer);
}
@Deprecated
public Function<PacketWrapper<?>, T> getDataDeserializer() {
return dataDeserializer;
return this.reader::apply;
}
public BiConsumer<PacketWrapper<?>, Object> getDataSerializer() {
return dataSerializer;
@Deprecated
public BiConsumer<PacketWrapper<?>, T> getDataSerializer() {
return this.writer;
}
}
@@ -18,43 +18,46 @@
package com.github.retrooper.packetevents.protocol.entity.data;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
import com.github.retrooper.packetevents.protocol.entity.cat.CatVariant;
import com.github.retrooper.packetevents.protocol.entity.chicken.ChickenVariant;
import com.github.retrooper.packetevents.protocol.entity.cow.CowVariant;
import com.github.retrooper.packetevents.protocol.entity.frog.FrogVariant;
import com.github.retrooper.packetevents.protocol.entity.pig.PigVariant;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
import com.github.retrooper.packetevents.protocol.entity.sniffer.SnifferState;
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfSoundVariant;
import com.github.retrooper.packetevents.protocol.entity.wolfvariant.WolfVariant;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.particle.Particle;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
import com.github.retrooper.packetevents.protocol.world.painting.PaintingVariant;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Quaternion4f;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class EntityDataTypes {
//1.7 -> 1.18 block_position is just 3 ints, not serialized with a long
//short was removed in 1.9+
//boolean was added in 1.9
//nbt was added in 1.12
public final class EntityDataTypes {
private static final Map<String, EntityDataType<?>> ENTITY_DATA_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, EntityDataType<?>>> ENTITY_DATA_TYPE_ID_MAP = new HashMap<>();
protected static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_data_type_mappings");
private static final VersionedRegistry<EntityDataType<?>> REGISTRY = new VersionedRegistry<>("entity_data_serializer");
public static final EntityDataType<Byte> BYTE = define("byte", PacketWrapper::readByte, PacketWrapper::writeByte);
// short was removed in 1.9+
public static final EntityDataType<Short> SHORT = define("short", PacketWrapper::readShort, PacketWrapper::writeShort);
public static final EntityDataType<Integer> INT = define("int", wrapper -> {
@@ -77,10 +80,16 @@ public class EntityDataTypes {
public static final EntityDataType<String> STRING = define("string", PacketWrapper::readString, PacketWrapper::writeString);
/**
* @deprecated use {@link #ADV_COMPONENT} instead
*/
@Deprecated
public static final EntityDataType<String> COMPONENT = define("component", PacketWrapper::readComponentJSON, PacketWrapper::writeComponentJSON);
public static final EntityDataType<Component> ADV_COMPONENT = define("component", PacketWrapper::readComponent, PacketWrapper::writeComponent);
/**
* @deprecated use {@link #OPTIONAL_ADV_COMPONENT} instead
*/
@Deprecated
public static final EntityDataType<Optional<String>> OPTIONAL_COMPONENT = define("optional_component", readOptionalComponentJSONDeserializer(), writeOptionalComponentJSONSerializer());
public static final EntityDataType<Optional<Component>> OPTIONAL_ADV_COMPONENT = define("optional_component", readOptionalComponentDeserializer(), writeOptionalComponentSerializer());
@@ -91,6 +100,7 @@ public class EntityDataTypes {
(PacketWrapper<?> wrapper) -> Optional.of(wrapper.readItemStack()),
(PacketWrapper<?> wrapper, Optional<ItemStack> value) -> wrapper.writeItemStack(value.orElse(null)));
// boolean was added in 1.9
public static final EntityDataType<Boolean> BOOLEAN = define("boolean", PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
public static final EntityDataType<Vector3f> ROTATION = define("rotation",
@@ -101,6 +111,7 @@ public class EntityDataTypes {
wrapper.writeFloat(value.z);
});
// 1.7 -> 1.18 block_position is just 3 ints, not serialized with a long
public static final EntityDataType<Vector3i> BLOCK_POSITION = define("block_position", (PacketWrapper<?> wrapper) -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
return wrapper.readBlockPosition();
@@ -139,6 +150,7 @@ public class EntityDataTypes {
public static final EntityDataType<Integer> OPTIONAL_BLOCK_STATE = define("optional_block_state", readIntDeserializer(), writeIntSerializer());
// nbt was added in 1.12
public static final EntityDataType<NBTCompound> NBT = define("nbt", PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final EntityDataType<Particle<?>> PARTICLE = define("particle", Particle::read, Particle::write);
@@ -157,9 +169,23 @@ public class EntityDataTypes {
return EntityPose.getById(wrapper.getServerVersion().toClientVersion(), id);
}, (PacketWrapper<?> wrapper, EntityPose value) -> wrapper.writeVarInt(value.getId(wrapper.getServerVersion().toClientVersion())));
public static final EntityDataType<Integer> CAT_VARIANT = define("cat_variant_type", readIntDeserializer(), writeIntSerializer());
/**
* @deprecated use {@link #TYPED_CAT_VARIANT} instead
*/
@Deprecated
public static final EntityDataType<Integer> CAT_VARIANT =
define("cat_variant_type", readIntDeserializer(), writeIntSerializer());
public static final EntityDataType<CatVariant> TYPED_CAT_VARIANT =
define("cat_variant_type", CatVariant::read, CatVariant::write);
public static final EntityDataType<Integer> FROG_VARIANT = define("frog_variant_type", readIntDeserializer(), writeIntSerializer());
/**
* @deprecated use {@link #TYPED_FROG_VARIANT} instead
*/
@Deprecated
public static final EntityDataType<Integer> FROG_VARIANT =
define("frog_variant_type", readIntDeserializer(), writeIntSerializer());
public static final EntityDataType<FrogVariant> TYPED_FROG_VARIANT =
define("frog_variant_type", FrogVariant::read, FrogVariant::write);
public static final EntityDataType<Optional<WorldBlockPosition>> OPTIONAL_GLOBAL_POSITION = define("optional_global_position",
(PacketWrapper<?> wrapper) -> Optional.ofNullable(wrapper.readOptional(w -> new WorldBlockPosition(new ResourceLocation(w.readString(32767)), w.readBlockPosition()))),
@@ -168,7 +194,14 @@ public class EntityDataTypes {
w.writeBlockPosition(globalPos.getBlockPosition());
}));
public static final EntityDataType<Integer> PAINTING_VARIANT_TYPE = define("painting_variant_type", readIntDeserializer(), writeIntSerializer());
/**
* @deprecated use {@link #PAINTING_VARIANT} instead
*/
@Deprecated
public static final EntityDataType<Integer> PAINTING_VARIANT_TYPE =
define("painting_variant_type", readIntDeserializer(), writeIntSerializer());
public static final EntityDataType<PaintingVariant> PAINTING_VARIANT =
define("painting_variant_type", PaintingVariant::read, PaintingVariant::write);
public static final EntityDataType<SnifferState> SNIFFER_STATE = define("sniffer_state", (PacketWrapper<?> wrapper) -> {
int id = wrapper.readVarInt();
@@ -192,185 +225,143 @@ public class EntityDataTypes {
wrapper.writeFloat(value.getW());
});
// Added in 1.20.5
/**
* Added with 1.20.5
*/
public static final EntityDataType<ArmadilloState> ARMADILLO_STATE = define("armadillo_state",
(PacketWrapper<?> wrapper) -> ArmadilloState.values()[wrapper.readVarInt()],
(PacketWrapper<?> wrapper, ArmadilloState value) -> wrapper.writeVarInt(value.ordinal())
);
/**
* Added with 1.20.5
*/
public static final EntityDataType<List<Particle<?>>> PARTICLES = define("particles",
wrapper -> wrapper.readList(Particle::read),
(wrapper, particles) -> wrapper.writeList(particles, Particle::write)
);
/**
* Added with 1.20.5
*
* @deprecated use {@link #TYPED_WOLF_VARIANT} instead
*/
@Deprecated
public static final EntityDataType<Integer> WOLF_VARIANT =
define("wolf_variant_type", readIntDeserializer(), writeIntSerializer());
/**
* Added with 1.20.5
*/
public static final EntityDataType<WolfVariant> TYPED_WOLF_VARIANT =
define("wolf_variant_type", WolfVariant::read, WolfVariant::write);
/**
* Added with 1.21.5
*/
public static final EntityDataType<CowVariant> COW_VARIANT =
define("cow_variant_type", CowVariant::read, CowVariant::write);
/**
* Added with 1.21.5
*/
public static final EntityDataType<WolfSoundVariant> WOLF_SOUND_VARIANT =
define("wolf_sound_variant_type", WolfSoundVariant::read, WolfSoundVariant::write);
/**
* Added with 1.21.5
*/
public static final EntityDataType<PigVariant> PIG_VARIANT =
define("pig_variant_type", PigVariant::read, PigVariant::write);
/**
* Added with 1.21.5
*/
public static final EntityDataType<ChickenVariant> CHICKEN_VARIANT =
define("chicken_variant_type", ChickenVariant::read, ChickenVariant::write);
private EntityDataTypes() {
}
public static VersionedRegistry<EntityDataType<?>> getRegistry() {
return REGISTRY;
}
/**
* Returns an immutable view of the entity-data types.
*
* @return Entity-Data Types
*/
public static Collection<EntityDataType<?>> values() {
return Collections.unmodifiableCollection(ENTITY_DATA_TYPE_MAP.values());
return REGISTRY.getEntries();
}
public static EntityDataType<?> getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, EntityDataType<?>> typeIdMap = ENTITY_DATA_TYPE_ID_MAP.get((byte) index);
return typeIdMap.get(id);
return REGISTRY.getById(version, id);
}
public static EntityDataType<?> getByName(String name) {
return ENTITY_DATA_TYPE_MAP.get(name);
return REGISTRY.getByName(name);
}
public static <T> EntityDataType<T> define(String name, Function<PacketWrapper<?>, T> deserializer, BiConsumer<PacketWrapper<?>, T> serializer) {
TypesBuilderData data = TYPES_BUILDER.define(name);
EntityDataType<T> type = new EntityDataType<>(name, data.getData(), deserializer,
(BiConsumer<PacketWrapper<?>, Object>) serializer);
ENTITY_DATA_TYPE_MAP.put(type.getName(), type);
for (ClientVersion version : TYPES_BUILDER.getVersions()) {
int index = TYPES_BUILDER.getDataIndex(version);
if (index == -1) continue;
Map<Integer, EntityDataType<?>> typeIdMap = ENTITY_DATA_TYPE_ID_MAP
.computeIfAbsent((byte) index, k -> new HashMap<>());
typeIdMap.put(type.getId(version), type);
}
return type;
@ApiStatus.Internal
public static <T, Z extends T> EntityDataType<Z> define(
String name, PacketWrapper.Reader<Z> reader, PacketWrapper.Writer<T> writer
) {
return REGISTRY.define(name, data -> new EntityDataType<>(data, reader, writer::accept));
}
private static <T> Function<PacketWrapper<?>, T> readIntDeserializer() {
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
return (PacketWrapper<?> wrapper) -> (T) ((Object) wrapper.readVarInt());
} else {
return (PacketWrapper<?> wrapper) -> (T) ((Object) wrapper.readInt());
}
private static PacketWrapper.Reader<Integer> readIntDeserializer() {
return wrapper -> wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9) ?
wrapper.readVarInt() : wrapper.readInt();
}
private static <T> BiConsumer<PacketWrapper<?>, T> writeIntSerializer() {
return (PacketWrapper<?> wrapper, T value) -> {
int output = 0;
if (value instanceof Byte) {
output = ((Byte) value).intValue();
} else if (value instanceof Short) {
output = ((Short) value).intValue();
} else if (value instanceof Integer) {
output = (Integer) value;
} else if (value instanceof Long) {
output = ((Long) value).intValue();
}
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
wrapper.writeVarInt(output);
private static PacketWrapper.Writer<Number> writeIntSerializer() {
return (wrapper, value) -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
wrapper.writeVarInt(value.intValue());
} else {
wrapper.writeInt(output);
wrapper.writeInt(value.intValue());
}
};
}
@Deprecated
private static Function<PacketWrapper<?>, Optional<String>> readOptionalComponentJSONDeserializer() {
return (PacketWrapper<?> wrapper) -> {
if (wrapper.readBoolean()) {
return Optional.of(wrapper.readComponentJSON());
} else {
return Optional.empty();
}
};
private static PacketWrapper.Reader<Optional<String>> readOptionalComponentJSONDeserializer() {
return wrapper -> wrapper.readJavaOptional(PacketWrapper::readComponentJSON);
}
@Deprecated
private static BiConsumer<PacketWrapper<?>, Optional<String>> writeOptionalComponentJSONSerializer() {
return (PacketWrapper<?> wrapper, Optional<String> value) -> {
if (value != null && value.isPresent()) {
wrapper.writeBoolean(true);
wrapper.writeComponentJSON(value.get());
} else {
wrapper.writeBoolean(false);
private static PacketWrapper.Writer<Optional<String>> writeOptionalComponentJSONSerializer() {
return (wrapper, value) -> wrapper.writeJavaOptional(value, PacketWrapper::writeComponentJSON);
}
private static PacketWrapper.Reader<Optional<Component>> readOptionalComponentDeserializer() {
return wrapper -> wrapper.readJavaOptional(PacketWrapper::readComponent);
}
private static PacketWrapper.Writer<Optional<Component>> writeOptionalComponentSerializer() {
return (wrapper, value) -> wrapper.writeJavaOptional(value, PacketWrapper::writeComponent);
}
private static PacketWrapper.Reader<Optional<Vector3i>> readOptionalBlockPositionDeserializer() {
return wrapper -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
return wrapper.readJavaOptional(PacketWrapper::readBlockPosition);
}
return wrapper.readJavaOptional(ew ->
new Vector3i(ew.readInt(), ew.readInt(), ew.readInt()));
};
}
private static Function<PacketWrapper<?>, Optional<Component>> readOptionalComponentDeserializer() {
return (PacketWrapper<?> wrapper) -> {
if (wrapper.readBoolean()) {
return Optional.of(wrapper.readComponent());
private static PacketWrapper.Writer<Optional<Vector3i>> writeOptionalBlockPositionSerializer() {
return (wrapper, value) -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
wrapper.writeJavaOptional(value, PacketWrapper::writeBlockPosition);
} else {
return Optional.empty();
wrapper.writeJavaOptional(value, (ew, valuee) -> {
wrapper.writeInt(valuee.getX());
wrapper.writeInt(valuee.getY());
wrapper.writeInt(valuee.getZ());
});
}
};
}
private static BiConsumer<PacketWrapper<?>, Optional<Component>> writeOptionalComponentSerializer() {
return (PacketWrapper<?> wrapper, Optional<Component> value) -> {
if (value != null && value.isPresent()) {
wrapper.writeBoolean(true);
wrapper.writeComponent(value.get());
} else {
wrapper.writeBoolean(false);
}
};
}
private static <T> Function<PacketWrapper<?>, T> readOptionalBlockPositionDeserializer() {
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
return (PacketWrapper<?> wrapper) -> {
if (wrapper.readBoolean()) {
return (T) Optional.of(wrapper.readBlockPosition());
} else {
return (T) Optional.empty();
}
};
} else {
return (PacketWrapper<?> wrapper) -> {
if (wrapper.readBoolean()) {
int x = wrapper.readInt();
int y = wrapper.readInt();
int z = wrapper.readInt();
return (T) Optional.of(new Vector3i(x, y, z));
} else {
return (T) Optional.empty();
}
};
}
}
private static <T> BiConsumer<PacketWrapper<?>, T> writeOptionalBlockPositionSerializer() {
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) {
return (PacketWrapper<?> wrapper, T value) -> {
if (value instanceof Optional) {
Optional<?> optional = (Optional<?>) value;
if (optional.isPresent()) {
wrapper.writeBoolean(true);
wrapper.writeBlockPosition((Vector3i) optional.get());
} else {
wrapper.writeBoolean(false);
}
} else {
wrapper.writeBoolean(false);
}
};
} else {
return (PacketWrapper<?> wrapper, T value) -> {
if (value instanceof Optional) {
Optional<?> optional = (Optional<?>) value;
if (optional.isPresent()) {
wrapper.writeBoolean(true);
Vector3i position = (Vector3i) optional.get();
wrapper.writeInt(position.getX());
wrapper.writeInt(position.getY());
wrapper.writeInt(position.getZ());
} else {
wrapper.writeBoolean(false);
}
} else {
wrapper.writeBoolean(false);
}
};
}
}
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
}
@@ -19,7 +19,7 @@ public interface EntityMetadataProvider {
* @param version The protocol version of the format we expect the metadata to be in.
* @return Metadata (list of entity data)
*/
List<EntityData> entityData(ClientVersion version);
List<EntityData<?>> entityData(ClientVersion version);
/**
* Similar to {@link #entityData(ClientVersion)} but does not provide a protocol version.
@@ -29,7 +29,7 @@ public interface EntityMetadataProvider {
* @deprecated Does not specify format of metadata, therefore not advised to use this. It will assume the current latest version.
*/
@Deprecated
default List<EntityData> entityData() {
default List<EntityData<?>> entityData() {
return entityData(ClientVersion.getLatest());
}
}
@@ -0,0 +1,24 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.fox;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
public interface FoxVariant extends MappedEntity {
}
@@ -0,0 +1,47 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.fox;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
public final class FoxVariants {
private static final VersionedRegistry<FoxVariant> REGISTRY =
new VersionedRegistry<>("fox_variant");
private FoxVariants() {
}
@ApiStatus.Internal
public static FoxVariant define(String name) {
return REGISTRY.define(name, StaticFoxVariant::new);
}
public static VersionedRegistry<FoxVariant> getRegistry() {
return REGISTRY;
}
public static final FoxVariant RED = define("red");
public static final FoxVariant SNOW = define("snow");
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,32 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.fox;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
public class StaticFoxVariant extends AbstractMappedEntity implements FoxVariant {
@ApiStatus.Internal
public StaticFoxVariant(@Nullable TypesBuilderData data) {
super(data);
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.frog;
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
import com.github.retrooper.packetevents.protocol.mapper.DeepComparableEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
public interface FrogVariant extends MappedEntity, CopyableEntity<FrogVariant>, DeepComparableEntity {
ResourceLocation getAssetId();
static FrogVariant read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntity(FrogVariants.getRegistry());
}
static void write(PacketWrapper<?> wrapper, FrogVariant variant) {
wrapper.writeMappedEntity(variant);
}
static FrogVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
return new StaticFrogVariant(data, assetId);
}
static NBT encode(FrogVariant variant, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("asset_id", new NBTString(variant.getAssetId().toString()));
return compound;
}
}
Loaded 100 of 461 files, more files were not shown because too many files have changed in this diff. Show more