Compare commits

...
232 Commits
Author SHA1 Message Date
retrooper 476c61ed47 bump version up to 2.7.0 release 2024-12-10 21:34:52 +01:00
retrooper 4b6bfbc08b Merge pull request #1085 from booky10/workaround/revert-shadow-color-support
Temporarily revert shadow color support
2024-12-10 20:52:44 +01:00
booky10 0be838c58f Temporarily revert shadow color support
Will be un-reverted when adventure v4.18.0 gets released
2024-12-10 20:32:19 +01:00
booky10 d6c81f32cd Fix shadow color adventure support check 2024-12-04 18:03:46 +01:00
booky10 5d2104dd91 Merge pull request #1076 from mfnalex/feat/fix-npe-nbtinterpret
fix NPE for nbtInterpret
2024-12-04 18:00:55 +01:00
retrooper 969ce9d6a3 Merge pull request #1081 from Tecnio/2.0
bugfix: Added input validation for window click
2024-12-04 16:37:18 +01:00
Tecnio 55b456cb95 bugfix: Added input validation for window click 2024-12-04 18:34:40 +03:00
booky10 062ffc18f9 Merge pull request #1078 from AoElite/biomefix
fix npe if music tag isn't present on older versions
2024-12-04 12:32:42 +01:00
AoElite 95cbd40655 fix npe if music tag isn't present on older versions 2024-12-04 05:38:55 -05:00
retrooper 70d94137dd Merge pull request #1049 from booky10/feat/1.21.4-support
1.21.4 support
2024-12-03 22:50:55 +01:00
mfnalex bbea70d1db fix NPE for nbtInterpret 2024-12-03 20:23:31 +01:00
booky10 b5e5b752a4 Bump fabric version info 2024-12-03 18:42:39 +01:00
retrooper 28b4dd8e08 bump version up to 2.7.0 SNAPSHOT 2024-12-03 18:33:07 +01:00
retrooper 1ae92a8b9d correction to comments mistakenly referring to 1.21.5 2024-12-03 17:57:29 +01:00
booky10 00bbea33f6 Bump fabric minecraft version to 1.21.4-rc3 2024-12-02 23:10:59 +01:00
booky10 3fd3c397a6 Rename attribute constants to remove "type" prefix 2024-12-02 22:56:33 +01:00
booky10 f1f95a0aac Fix name of equipment asset mapping file reference 2024-12-02 22:20:25 +01:00
booky10 6e90a3e376 Update serverbound packet type mappings 2024-12-02 22:05:26 +01:00
booky10 41d51453a5 Update mappings for all changed registries 2024-12-02 22:01:06 +01:00
booky10andBeanes c74f8b2559 Add precision loss fix while writing, not while reading
This fixes *slightly* incorrect velocity values being provided in the wrapper, while still writing the correct short value

Co-authored-by: Beanes <sikyserver@gmail.com>
2024-12-02 21:45:35 +01:00
booky10 be2eb6a8ce Update generated block tags and item tags 2024-12-02 21:40:45 +01:00
Beanesandbooky10 9819db60cd Work around loss of precision when unpacking entity velocity
Solution was discussed on discord (https://discord.com/channels/721686193061888071/721686193515003966/1313231483225378946)

Closes #1074

Co-authored-by: booky10 <boooky10@gmail.com>
2024-12-02 21:26:55 +01:00
booky10 2a86e0d355 Update trim material structure to 1.21.4 2024-12-02 21:05:12 +01:00
booky10 4a209a342e Update biome music nbt structure to 1.21.4 2024-12-02 20:46:22 +01:00
booky10 33e5b58e3b Update custom model data component to 1.21.4 2024-12-02 20:21:21 +01:00
booky10 fd11bd24a9 Add new player loaded packet type and wrapper 2024-11-30 12:48:06 +01:00
booky10 8c1f14de57 Add wrappers for new pick item packets 2024-11-30 12:46:27 +01:00
booky10 bc615355c8 Add 1.21.4 serverbound packet type constants 2024-11-30 12:42:02 +01:00
booky10 28730806f9 Small javadoc notice for ParticleTrailData duration 2024-11-29 15:23:31 +01:00
booky10 4ec975fcd1 Update block state properties to 1.21.4 2024-11-29 15:20:55 +01:00
booky10 b6ce588e10 Add new item consumable use animation 2024-11-29 15:17:13 +01:00
booky10 a1510b5f6d Update equippable item component 2024-11-29 15:15:58 +01:00
booky10 913d527a64 Mark creaking transient entity type as obsolete 2024-11-29 15:13:51 +01:00
booky10 a1e250b521 Add new sound constants 2024-11-29 15:13:18 +01:00
booky10 887c107216 Add resin trim material constant 2024-11-29 15:12:15 +01:00
booky10 b6fb699a27 Add onground flag to WrapperPlayClientVehicleMove 2024-11-29 15:09:19 +01:00
booky10 575aa4619c Add initial support for shadow colors in component styles 2024-11-29 15:07:06 +01:00
booky10 3f787c0e35 Update particle types to 1.21.4 2024-11-29 14:41:37 +01:00
retrooper a0fc7f6978 Merge pull request #1065 from rafi67000/missingServerVersion
Add missing ServerVersion.V_1_9_1
2024-11-25 17:32:54 +01:00
rafi67000 2cd069ea72 Add missing ServerVersion.V_1_9_1 2024-11-24 22:13:00 +01:00
retrooper d4b4b24e3c WrapperPlayServerResourcePackSend#setPrompt added 2024-11-17 16:35:30 +01:00
retrooper dca7daec04 Merge pull request #1044 from ShreyasAyyengar/2.0
fix: NPC objects to have unique server team names.
2024-11-14 19:43:35 +01:00
booky10 b686eb467f Fix javadoc warnings 2024-11-13 15:16:01 +01:00
booky10 d1f0618c0e Merge branch '2.0' into feat/1.21.4-support 2024-11-13 14:28:59 +01:00
Shreyas Ayyengar ce06511b52 fix: initial team name not longer than 16 characters. 2024-11-11 14:41:56 -08:00
Shreyas Ayyengar a2b0c0f28e fix: truncate team name for versions older than V_1_18 2024-11-10 10:13:20 -08:00
retrooper da71044fc4 rename BlockFace#getHorizontalId to adhere to naming convention 2024-11-08 14:47:41 +01:00
booky10 4167c949fe Merge pull request #1048 from Axionize/blockface-get-horizontal
add getHorizontalID
2024-11-07 16:02:57 +01:00
booky10 6f490a7e93 Merge pull request #1057 from booky10/fix/potion-contents-component
Fix potion contents item component for 1.21.2/1.21.3
2024-11-07 16:01:51 +01:00
booky10 b14dfc710a Fix potion contents item component for 1.21.2/1.21.3 2024-11-06 23:36:07 +01:00
You 1877bae091 add getHorizontalID 2024-11-04 22:27:29 -05:00
retrooper 4cf7069254 Bump version up to 2.6.1-SNAPSHOT 2024-11-03 21:31:26 +01:00
retrooper d4c89ebff0 Final javadoc update 2024-11-03 20:35:26 +01:00
retrooper f58005a412 Update javadoc overview 2024-11-03 20:34:07 +01:00
retrooper 382931f4f8 Merge pull request #1050 from booky10/fix/sponge-artifact-upload
Fix sponge artifacts not getting uploaded
2024-11-03 20:32:44 +01:00
booky10 7be5b84b5d Fix sponge artifacts not getting uploaded 2024-11-03 20:31:53 +01:00
retrooper 0db35d3bd7 Stable release of 2.6.0 2024-11-03 20:22:12 +01:00
booky10 6e2da40aa5 Update block and item tags for 24w44a 2024-11-03 18:37:18 +01:00
booky10 dae7c2e90b Update item types for 24w44a 2024-11-03 18:37:11 +01:00
booky10 04db0ba88d Update state types for 24w44a 2024-11-03 18:37:06 +01:00
retrooper 9680bc77b3 relocate bstats in shadowNoAdventure task. 2024-11-02 22:53:43 +01:00
retrooper 85c0d3d9d3 Merge pull request #1018 from AbhigyaKrishna/2.0
Introduce a jar task to build without adventure dependencies
2024-11-02 22:46:38 +01:00
booky10 b348af9581 Update WrapperPlayServerHeldItemChange to 24w44a 2024-10-30 15:23:16 +01:00
booky10 aedb43b487 Update WrapperPlayServerPlayerInfoUpdate to 24w44a 2024-10-30 15:21:07 +01:00
booky10 3b86806d8e Update WrapperPlayServerParticle to 24w44a 2024-10-30 15:17:18 +01:00
booky10 c4cc09d8e0 Add 1.21.4 version constants 2024-10-30 15:14:51 +01:00
Shreyas Ayyengar 1a3b2471b3 refactor: add get/set for teamName 2024-10-28 11:19:55 -07:00
ShreyasAyyengar 3a004572c1 fix: NPC objects to have unique server team names. 2024-10-29 01:59:16 +08:00
retrooper feabf561c5 Merge pull request #1043 from booky10/fix/block-state-mapping-indexes
Fix block state mapping indexes
2024-10-28 17:16:12 +01:00
retrooper 5247ccd129 Add support for 1.16.1 join game codec (fix error) 2024-10-28 17:03:05 +01:00
booky10 c77390b86c Implement more dynamic wrapped block state mapping indexes 2024-10-28 15:52:11 +01:00
booky10 8ecad1f93e Introduce static field for legacy mapping index 2024-10-28 15:41:26 +01:00
booky10 dae82c4d65 Fix legacy mapping index being broken 2024-10-28 15:40:17 +01:00
booky10 8f8cc8ac43 Removed left over debug code from fabric module refactor 2024-10-28 14:46:50 +01:00
retrooper f66626ae74 Merge pull request #1042 from booky10/fix/bstats-shadow-issues
Include relocated bstats classes in published shadow jar
2024-10-28 14:43:30 +01:00
booky10 4ffcbcad91 Include relocated bstats classes in published shadow jar
This moves bstats dependencies to a separate gradle dependency configuration, which is always shadowed and used in compile classpath
2024-10-28 14:41:31 +01:00
booky10 fc31b7de7b Merge pull request #1032 from booky10/fix/fabric-module
Fabric module refactor
2024-10-27 05:09:00 +01:00
booky10 c24f2d7849 Re-add deprecated FabricPacketEventsBuilder for some backwards compatibility 2024-10-27 03:04:21 +01:00
booky10 b316f54fd8 Simplify platform-specific pre launch entrypoint handler logic 2024-10-27 02:58:42 +01:00
booky10 2fda301027 Load packetevents api instance on prelaunch 2024-10-27 02:57:56 +01:00
booky10 9e6f3fbb2a Fix channel to user association in fabric module 2024-10-27 02:50:01 +02:00
booky10 980d306100 Bump fabric loom to v1.8.11 2024-10-27 01:46:15 +02:00
booky10 9d4a44b403 Merge branch '2.0' into fix/fabric-module 2024-10-27 01:46:04 +02:00
booky10 52d92e6c1a Merge pull request #975 from booky10/feat/1.21.2-update
1.21.2/1.21.3 update
2024-10-27 01:43:19 +02:00
booky10 0a96edb1bb Merge pull request #1034 from booky10/fix/slime-paper-support
Fix support for unsafe entity id getter on AdvancedSlimePaper
2024-10-27 01:37:04 +02:00
booky10 3ced349018 Merge pull request #1028 from Bram1903/feat/bStatsUpdate
[Feat] bStats Sponge Support
2024-10-27 00:49:16 +02:00
booky10 9649c99f90 Merge branch '2.0' into feat/bStatsUpdate 2024-10-27 00:49:01 +02:00
booky10 0b587d398d Merge pull request #1022 from rafi67000/gradleUpdate
Update gradle
2024-10-27 00:47:50 +02:00
booky10 47eaa1d1ca Add accesswidener to fabric.mod.json 2024-10-27 00:38:52 +02:00
booky10 cbd170729d Bump version up to 2.6.0-SNAPSHOT 2024-10-27 00:30:45 +02:00
rafi67000 6997bb4615 Revert "Update loom"
This reverts commit 76ea2aa665.
2024-10-25 19:55:17 +02:00
rafi67000 dc6db3cfaa Revert "Update SpongeGradle"
This reverts commit 72c337a68c.
2024-10-25 19:53:14 +02:00
rafi67000 72c337a68c Update SpongeGradle 2024-10-25 19:51:21 +02:00
rafi67000 a9d0389adf Merge pull request #13 from retrooper/2.0
Sponge
2024-10-25 19:48:42 +02:00
rafi67000 76ea2aa665 Update loom 2024-10-25 19:40:45 +02:00
booky10 672700afc5 Add 1.21.3 server version
Thanks mojang for fixing the salmon!
2024-10-23 18:14:45 +02:00
retrooper d8a44fe8b6 Merge pull request #1037 from booky10/fix/javadoc-link
Fix javadoc link in readme
2024-10-23 07:08:37 +02:00
booky10 2a777092d2 Fix javadoc link in readme 2024-10-23 01:14:01 +02:00
booky10 083a060371 Fix legacy attribute naming "remapping" 2024-10-22 18:18:56 +02:00
booky10 b1b5dee5f0 Fix NPE when copying WrapperPlayServerChunkData below 1.18 2024-10-22 18:14:23 +02:00
booky10 05dfea6da2 Fix classloading loop in SynchronizedRegistriesHandler 2024-10-22 18:07:27 +02:00
booky10 208d6911f0 Expose packet side in channel injector 2024-10-22 01:10:20 +02:00
booky10 07ca508df1 Change default value of legacy lookup to true 2024-10-21 21:53:48 +02:00
booky10 40ab1419c5 Fix support for unsafe entity id getter on AdvancedSlimePaper 2024-10-21 21:43:28 +02:00
booky10 cb48134548 Remove TODOs, tests were successful 2024-10-21 19:27:37 +02:00
booky10 ce287ad7db Fix writing packets on fabric client side 2024-10-21 19:20:55 +02:00
booky10 be1e743571 Invert protocol manager send/receive methods if in client environment 2024-10-21 18:34:03 +02:00
booky10 a57b911fd2 Skip injection of fabric channels on the wrong side 2024-10-21 18:10:16 +02:00
booky10 a3b7fc8908 Refactor handshake handling to support non-inet socket addresses 2024-10-21 17:58:46 +02:00
booky10 85717a84b7 Associate player instance with player connection channel
The behaviour of the fabric platform is a bit different here, as the player instance gets re-created on respawn
2024-10-21 03:55:57 +02:00
booky10 6a8e96382e Add method for creating packetevents instance 2024-10-21 03:31:35 +02:00
booky10 52b6cb6a71 Fix writing of WrapperPlayClientCraftRecipeRequest 2024-10-21 02:31:49 +02:00
booky10 eda7d9273f Fix serialization of SingleInputOptionDisplay 2024-10-21 02:31:48 +02:00
booky10 9391b16f50 Fix missing sealevel write in login packet 2024-10-21 02:31:47 +02:00
booky10 bd499550d8 Reuse entity position sync EntityPositionData in more places for 1.21.2 2024-10-21 02:31:46 +02:00
booky10 dd6eb173a0 Fix ENTITY_POSITION_SYNC packet id 2024-10-21 02:31:45 +02:00
booky10 78c994987f Update client settings packet wrapper to 1.21.2
Also refactors it's logic into a common class, as it was previously split in config and play state packets
2024-10-21 02:31:45 +02:00
booky10 d11a0bade5 Add tip and creaking block state properties for 1.21.2 2024-10-21 01:36:03 +02:00
booky10 e54035a683 Work around classloading loop only present on fabric 2024-10-21 01:32:17 +02:00
booky10 5ef51406eb Refactor clientbound and serverbound packet handling for same behaviour 2024-10-21 01:32:05 +02:00
booky10 9843e9fd68 Fix refcount issues with PacketEncoder 2024-10-21 01:32:04 +02:00
booky10 f3bdcbec83 Fix PacketDecoder handling of serverbound packets 2024-10-21 01:32:03 +02:00
booky10 a5d3cf5957 Fix wrong packetencoder side 2024-10-21 01:32:03 +02:00
booky10 aa87cf8032 Fix fabric logger level remapping 2024-10-21 01:32:02 +02:00
booky10 07137ddb26 Call correct packet events depending on packet side 2024-10-21 01:32:01 +02:00
booky10 92076e8559 Move fabric mod metadata to common sourceset 2024-10-21 01:32:00 +02:00
booky10 5356a011ec Refactor fabric network handlers
This removes compression handling from encoder, as vanilla compression setup does not interfere with packetevents
This also refactors the packet encoder to be based directly on the ChannelOutboundHandlerAdapter, instead of the MessageToByteEncoder

Requires testing - there could be a retain missing in the PacketEncoder
2024-10-20 06:03:00 +02:00
booky10 b72502b8a1 Implement support for fabric client again 2024-10-20 06:02:59 +02:00
booky10 20bee30f69 Refactor fabric packetevents builder to work on both server and client 2024-10-20 06:02:59 +02:00
booky10 4f29b8a2c9 Split fabric client and server sources 2024-10-20 06:02:58 +02:00
booky10 ef867acc36 Fix fabric mod icon 2024-10-20 06:02:58 +02:00
booky10 da37c4320e Remove fabric api dependency
It's not used by packetevents, there is no need to depend on it
2024-10-20 06:02:57 +02:00
booky10 6b2d3cbc7e Small cleanup of WrapperPlayServerExplosion
Didn't think I would have updated this already, but its already up-to-date! Yay!
2024-10-20 04:46:26 +02:00
booky10 397310df8b Update WrapperPlayServerDeclareRecipes to 1.21.2 2024-10-20 04:42:45 +02:00
booky10 04d444cc30 Update WrapperPlayServerEntityTeleport to 1.21.2 2024-10-20 03:32:36 +02:00
booky10 eb68151a73 Update WrapperPlayServerPlayerPositionAndLook to 1.21.2 2024-10-20 03:04:59 +02:00
booky10 a2fcc30fbb Update WrapperPlayServerCraftRecipeResponse to 1.21.2 2024-10-20 02:33:24 +02:00
booky10 6cdc535cbc Update WrapperPlayServerTimeUpdate to 1.21.2 2024-10-20 02:26:08 +02:00
booky10 095550e041 Update WrapperPlayClientCraftRecipeRequest to 1.21.2 2024-10-20 02:18:42 +02:00
booky10 3b4a0609e3 Update WrapperPlayClientSetDisplayedRecipe to 1.21.2 2024-10-20 02:08:17 +02:00
booky10 54fe6b0dbd Add player input packet wrapper 2024-10-20 02:05:12 +02:00
booky10 ff2b73e9b1 Update WrapperLoginServerLoginSuccess to 1.21.2 2024-10-20 01:51:30 +02:00
booky10 bb3630840d Update particle network and nbt serialization to 1.21.2 2024-10-20 01:39:21 +02:00
booky10 555aed78f3 Fix items without any overrides missing their default base components 2024-10-20 01:10:11 +02:00
booky10 1ed52f3f4e Fix versioned item type base components 2024-10-20 00:03:03 +02:00
booky10 72a44648cd Fix removed music disc tag causing tests to fail 2024-10-19 23:57:48 +02:00
booky10 2db8e75a66 Update sound registry to 1.21.2 2024-10-19 05:48:18 +02:00
booky10 e9064c4e87 Implement new trail and block crumble particles 2024-10-19 05:44:21 +02:00
booky10 680cbbf932 Fix item component mappings 2024-10-19 05:25:31 +02:00
booky10 7285af4481 Update damage type registry 2024-10-19 05:17:00 +02:00
booky10 bd4f5c2ecf Add 1.21.2 state type mappings 2024-10-19 05:14:10 +02:00
booky10 dd94a9a677 Refactor block entity types to registries 2024-10-19 05:13:24 +02:00
booky10 341c70f6dd Add creaking heart block entity type 2024-10-19 05:10:59 +02:00
booky10 41a8a47060 Add pale garden biome 2024-10-19 05:09:53 +02:00
booky10 881ad034a6 Refactor attributes to include default, minimum and maximum values
Also adds utility for calculating final attribute value
Additionally, strips "category" prefix for 1.21.2+
And adds the new attribute for 1.21.2
2024-10-19 05:02:06 +02:00
booky10 4a1c86cba3 Update block and item tags 2024-10-19 02:54:52 +02:00
booky10 56c9b73bcb Add new entity types for 1.21.2 2024-10-19 02:42:56 +02:00
booky10 93bac071ac Add new item types for 1.21.2 2024-10-19 02:34:29 +02:00
booky10 f88c9f027d Implement new item components for 1.21.2 2024-10-19 02:29:02 +02:00
booky10 1cb2219dbb Update FoodProperties serialization to 1.21.2 2024-10-19 02:09:40 +02:00
booky10 e00d5822f2 Fix serialization of ItemRecipes component type 2024-10-19 02:04:20 +02:00
booky10 f64846f339 Add initial logic for loading item base components from file 2024-10-19 01:58:42 +02:00
booky10 fd2480abbc Add item base component data for 1.20.5 to 1.21.2 2024-10-19 01:08:21 +02:00
booky10 4d820eef6d Add new state types for 1.21.2 2024-10-18 23:54:18 +02:00
booky10 6bddd197db Add block state mappings for 1.21.2 2024-10-18 23:54:07 +02:00
booky10 8439ca103c Fix modern block state mapping indices 2024-10-18 23:26:57 +02:00
booky10 60e546b075 Mark current recipe wrappers as obsolete 2024-10-18 18:11:21 +02:00
booky10 cfc0e5b260 Finish implementing serialization of new recipe data 2024-10-18 18:08:39 +02:00
booky10 3c11278949 Implement WrapperPlayServerRecipeBookSettings 2024-10-18 17:31:05 +02:00
booky10 8bde89d4ee Implement WrapperPlayServerRecipeBookRemove 2024-10-18 03:19:21 +02:00
booky10 a5ebc356ad Start implementing WrapperPlayServerRecipeBookAdd
Recipe display types are too much work for now, I'll do them later

Also, mojang has removed the ability for custom item recipes... for whatever reason?
2024-10-18 03:16:24 +02:00
booky10 aeb37c0a28 Implement WrapperPlayServerPlayerRotation 2024-10-18 02:37:58 +02:00
booky10 85106c8e59 Implement WrapperPlayServerEntityPositionSync 2024-10-18 02:36:42 +02:00
booky10 06d350bb1e Update packet mappings to rc1 2024-10-18 02:31:26 +02:00
booky10 a612ffeba1 Use mapped entity registry reading when reading modern ItemStacks 2024-10-18 02:12:52 +02:00
booky10 651051f136 Merge branch '2.0' into feat/1.21.2-update 2024-10-18 02:10:02 +02:00
Bram 3000d76272 Removed: Old bStats classes 2024-10-17 11:34:53 +02:00
retrooper e136327742 Update README text 2024-10-16 23:30:05 +02:00
Bram e1a22373d6 Re-added: Old Metric classes to prevent breaking changes, but marked the classes as deprecated 2024-10-15 16:10:57 +02:00
Bram b7f4375599 Fixed: Coding convention issue 2024-10-15 15:55:18 +02:00
Bram bf97a66dd7 Changed: Position of the plugin started message to outside the class constructor into the actual initiation event 2024-10-15 15:45:44 +02:00
Bram 9077e346f2 Removed: Internal bStats classes
Added: bStats as gradle dependency
Added: Sponge bStats Support
Changed: Velocity bStats initialisation, due to a reworked approach in a recent bStats update
Changed: Sponge Gradle Plugin version being specified in the build.gradle.kts rather than in the libs.versions.toml
2024-10-15 15:43:09 +02:00
retrooper 0031d6aae3 Merge pull request #670 from SamB440/feat/sponge
(WIP) Sponge support
2024-10-13 23:03:35 +02:00
SamB440 cec46d111b Don't store the ServerPlayer 2024-10-13 21:30:18 +01:00
SamB440 ef151757db Don't include non-nbt adventure 2024-10-13 21:30:18 +01:00
SamB440 fef29a0697 Update to new build logic 2024-10-13 21:30:17 +01:00
SamB440 b58b71a5b1 Fix ViaVersion compatibility (as via fixed injector) 2024-10-13 21:30:17 +01:00
SamB440 8a4fc799e4 Update to JDK 21 and support latest Sponge API 2024-10-13 21:30:17 +01:00
SamB440 979fc09e13 Sponge support 2024-10-13 21:30:17 +01:00
rafi67000 13fa3504bf Remove unused and deprecated import 2024-10-08 17:41:09 +02:00
rafi67000 adbaa5cfbc Update test libraries 2024-10-08 17:30:40 +02:00
rafi67000 1881336a14 Update runTask 2024-10-08 17:15:51 +02:00
rafi67000 100d02904e Update shadow 2024-10-08 17:15:45 +02:00
rafi67000 be8e15e087 Update gradle to 8.10.2 2024-10-08 17:15:38 +02:00
retrooper 487bcc3461 Merge pull request #1021 from booky10/fix/food-properties
Fix order of reading fields in food properties
2024-10-06 16:53:21 +02:00
booky10 1f86c651b8 Fix order of reading fields in food properties 2024-10-06 13:39:10 +02:00
AbhigyaKrishna 388001447f feat: jar task to produce jars without adventure 2024-10-04 17:17:59 +05:30
AbhigyaKrishna 13c59e2b5e refactor: make jar names consistent 2024-10-04 17:17:21 +05:30
AbhigyaKrishna 5c236bb4ed feat: configure javadoc plugin 2024-10-04 17:16:52 +05:30
booky10 fea6e90f12 Merge pull request #1015 from ManInMyVan/missing-breaks
add breaks in WrapperHandshakingClientHandshake::setNextConnectionState
2024-09-29 23:52:40 +02:00
ManInMyVan fb098bd169 add breaks in WrapperHandshakingClientHandshake::setNextConnectionState 2024-09-29 15:46:01 -06:00
booky10 612b2bb6cc Merge pull request #1014 from ManInMyVan/fix/legacy-rail-mappings
fix legacy rail mappings
2024-09-29 04:00:06 +02:00
ManInMyVan a145c10e5d fix detector rail id 2024-09-28 19:54:23 -06:00
ManInMyVan cb57f4fd6a fix legacy rail mappings 2024-09-28 17:43:31 -06:00
retrooper ed28da338a Merge pull request #1006 from booky10/fix/viaversion-map-deco-errors
Fix errors with viaversion and map decorations
2024-09-24 18:16:54 +02:00
retrooper 0d86b3b297 Merge pull request #1004 from booky10/fix/workaround-paper-library-loading-problems
Force usage of plugin classloader to lookup classes of other plugins
2024-09-24 18:16:22 +02:00
booky10 90bd1841f0 Revert unused import 2024-09-23 18:45:52 +02:00
booky10 be24877913 Merge pull request #1003 from booky10/fix/registry-element-equality
Fix registry element equality check
2024-09-23 18:43:57 +02:00
retrooper 7218c365e3 Merge pull request #1009 from booky10/fix/nbt-component-booleans
Allow any numbers when reading nbt booleans
2024-09-23 18:21:03 +02:00
booky10 33dd09362a Allow any numbers when reading nbt booleans
Vanilla accepts every number type and so should packetevents
2024-09-23 17:36:16 +02:00
booky10 4aae57075a Merge pull request #1005 from booky10/fix/more-bungee-injector-issues 2024-09-23 09:58:09 +02:00
booky10 d90240641e Convert MapDecorationTypes to proper registry 2024-09-21 16:50:01 +02:00
booky10 a5871befe6 Norm registry key input strings 2024-09-21 16:47:08 +02:00
booky10 fa56d226f3 Add ResourceLocation#normString utility
This prepends the vanilla key namespace to the specified input key, if no other namespace has been specified
2024-09-21 16:45:58 +02:00
booky10 a5ff4a9ad8 Only print component map patches for ItemStack#toString 2024-09-21 16:42:53 +02:00
booky10 d61c690075 Release buffers after recompression 2024-09-21 16:26:01 +02:00
booky10 873589bd7f Clear recyclable out list after usage 2024-09-21 16:25:47 +02:00
booky10 032f2ff228 Use proper logging for bungee instead of stdout 2024-09-21 16:25:19 +02:00
booky10 0c733b31a7 Force usage of plugin classloader to lookup classes of other plugins
Works around issues caused by some plugins loading packetevents through the library loader, which doesn't know about the classloader of plugins
2024-09-21 16:00:20 +02:00
booky10 2baaf18db6 Fix missing DeepComparableEntity interface
Caused by me just cherry-picking some commits from another branch
2024-09-21 15:26:53 +02:00
booky10 4d7314e2d8 Check for deep equals before using vanilla registry element
Could potentially solve #962, although I can't reproduce that issue

This may be caused by two different changes to packetevents:
1. We did a little memory optimization so only elements different to the vanilly registry get stored
2. We fixed an issue where some elements would not equal the "same" vanilla element

This could cause every custom element to just never be registered, so we now do explicit deep-equals checks before saving the vanilla element instead
2024-09-21 15:21:02 +02:00
booky10 f1f4ffe6b2 Implement DeepComparableEntity for all dynamic registry entries 2024-09-21 15:21:01 +02:00
retrooper 2fac9dc516 Bump version up to 2.5.1-SNAPSHOT 2024-09-20 23:37:15 +02:00
booky10 1260aa1de5 Add some transformations for slot changes 2024-08-30 22:53:19 +02:00
booky10 bdccde4040 Fix compile issue with StaticConsumeEffectType 2024-08-30 21:44:45 +02:00
booky10 7cdb95116a Implement all new components 2024-08-30 21:21:06 +02:00
booky10 c9d42f8e8e Check for deep equals before using vanilla registry element
Could potentially solve #962, although I can't reproduce that issue

This may be caused by two different changes to packetevents:
1. We did a little memory optimization so only elements different to the vanilly registry get stored
2. We fixed an issue where some elements would not equal the "same" vanilla element

This could cause every custom element to just never be registered, so we now do explicit deep-equals checks before saving the vanilla element instead
2024-08-30 20:34:37 +02:00
booky10 1e738f038f Implement DeepComparableEntity for all dynamic registry entries 2024-08-30 20:31:32 +02:00
booky10 57fb06ca5f Implement dynamic instrument registry 2024-08-30 20:28:59 +02:00
booky10 83d925ead0 Implement most 1.21.2 packet wrapper changes 2024-08-30 20:14:00 +02:00
booky10 ce1baaad7a Setup new 1.21.2 packet types 2024-08-30 20:13:52 +02:00
booky10 a370f6e7b7 Setup 1.21.2 server version and client version constants 2024-08-30 20:13:42 +02:00
319 changed files with 408993 additions and 5202 deletions

No files matched your search

+6
View File
@@ -62,3 +62,9 @@ jobs:
with:
name: fabric-build
path: fabric/build/libs
- name: Upload build artifacts sponge
uses: actions/upload-artifact@v4
with:
name: sponge-build
path: sponge/build/libs
+2 -3
View File
@@ -1,19 +1,18 @@
<!--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>
<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">
<a href="https://bstats.org/plugin/bukkit/packetevents/11327"><img src="https://img.shields.io/bstats/servers/11327?style=for-the-badge"></a>
<a href="https://github.com/retrooper/packetevents/releases"><img src="https://img.shields.io/github/downloads/retrooper/packetevents/total.svg?style=for-the-badge&logo=github"></a>
</div>
PacketEvents is emerging as a strong contender in the realm of Minecraft packet processing libraries. Designed to simplify packet manipulation while delivering high performance, this powerful tool aims to demystify the complexities of projects utilizing packets. Imbued with versatility, PacketEvents supports various platforms such as Spigot, BungeeCord, Velocity, and Fabric.
<h3>Resources</h3>
- [Read documentation](https://docs.packetevents.com/)
- [Getting Started](https://docs.packetevents.com/getting-started)
- [JavaDocs](javadocs.packetevents.com)
- [JavaDocs](https://javadocs.packetevents.com)
- [Releases](https://github.com/retrooper/packetevents/releases/)
- [GitHub](https://github.com/retrooper/packetevents/releases/)
- [Modrinth](https://modrinth.com/plugin/packetevents)
+12 -5
View File
@@ -38,6 +38,7 @@ dependencies {
testImplementation(testlibs.mockbukkit)
testImplementation(testlibs.slf4j)
testImplementation(testlibs.bundles.junit)
testImplementation(libs.netty)
}
mappingCompression {
@@ -50,6 +51,8 @@ mappingCompression {
compress("enchantment/enchantment_type_data.json")
compress("item/item_base_components.json")
compress("stats/statistics.json")
compress("world/biome_data.json")
@@ -73,7 +76,8 @@ mappingCompression {
compress("entity/painting_mappings.json")
compress("entity/wolf_variant_mappings.json")
compress("item/item_armor_material_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")
@@ -82,7 +86,10 @@ mappingCompression {
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")
@@ -106,11 +113,11 @@ mappingCompression {
}
tasks {
assemble {
setDependsOn(dependsOn.filterNot { it == "shadowNoAdventure" })
}
javadoc {
setDestinationDir(file("${project.layout.buildDirectory.asFile.get()}/docs/javadoc"))
options {
(this as CoreJavadocOptions).addBooleanOption("Xdoclint:none", true)
}
mustRunAfter(generateVersionsFile)
}
@@ -36,6 +36,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
@@ -123,8 +124,15 @@ public abstract class ProtocolPacketEvent extends PacketEvent implements PlayerE
return channel;
}
public SocketAddress getAddress() {
return ChannelHelper.remoteAddress(this.channel);
}
/**
* <strong>WARNING:</strong> This doesn't support local addresses or unix sockets.
*/
public InetSocketAddress getSocketAddress() {
return (InetSocketAddress) ChannelHelper.remoteAddress(channel);
return (InetSocketAddress) this.getAddress();
}
@Override
@@ -18,9 +18,11 @@
package com.github.retrooper.packetevents.injector;
import com.github.retrooper.packetevents.protocol.PacketSide;
import com.github.retrooper.packetevents.protocol.player.User;
public interface ChannelInjector {
default boolean isServerBound() {
return true;
}
@@ -34,4 +36,8 @@ public interface ChannelInjector {
void setPlayer(Object channel, Object player);
boolean isProxy();
default PacketSide getPacketSide() {
return PacketSide.SERVER;
}
}
@@ -30,6 +30,7 @@ import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.util.LogManager;
import com.github.retrooper.packetevents.util.mappings.SynchronizedRegistriesHandler;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerRegistryData;
import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake;
@@ -37,8 +38,6 @@ import com.github.retrooper.packetevents.wrapper.login.server.WrapperLoginServer
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerJoinGame;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
import java.net.InetSocketAddress;
public class InternalPacketListener extends PacketListenerAbstract {
public InternalPacketListener() {
@@ -124,16 +123,18 @@ public class InternalPacketListener extends PacketListenerAbstract {
public void onPacketReceive(PacketReceiveEvent event) {
User user = event.getUser();
if (event.getPacketType() == PacketType.Handshaking.Client.HANDSHAKE) {
Object channel = event.getChannel();
InetSocketAddress address = event.getSocketAddress();
WrapperHandshakingClientHandshake handshake = new WrapperHandshakingClientHandshake(event);
ConnectionState nextState = handshake.getNextConnectionState();
ClientVersion clientVersion = handshake.getClientVersion();
//Update client version for this event call(and user)
WrapperHandshakingClientHandshake packet = new WrapperHandshakingClientHandshake(event);
ClientVersion clientVersion = packet.getClientVersion();
ConnectionState state = packet.getNextConnectionState();
LogManager logger = PacketEvents.getAPI().getLogManager();
if (logger.isDebug()) {
logger.debug("Processed handshake for " + event.getAddress() + ": "
+ state.name() + " / " + packet.getClientVersion().getReleaseName());
}
user.setClientVersion(clientVersion);
PacketEvents.getAPI().getLogManager().debug("Processed " + address.getHostString() + ":" + address.getPort() + "'s client version. Client Version: " + clientVersion.getReleaseName());
//Transition into LOGIN or STATUS connection state immediately, to remain in sync with vanilla
user.setConnectionState(nextState);
user.setConnectionState(state);
} else if (event.getPacketType() == PacketType.Login.Client.LOGIN_SUCCESS_ACK) {
user.setDecoderState(ConnectionState.CONFIGURATION);
} else if (event.getPacketType() == PacketType.Play.Client.CONFIGURATION_ACK) {
@@ -34,7 +34,7 @@ public enum ServerVersion {
//TODO Rename to MinecraftVersion?
V_1_7_10(5),
V_1_8(47), V_1_8_3(47), V_1_8_8(47),
V_1_9(107), V_1_9_2(109), V_1_9_4(110),
V_1_9(107), V_1_9_1(108), V_1_9_2(109), V_1_9_4(110),
//1.10 and 1.10.1 are redundant
V_1_10(210), V_1_10_1(210), V_1_10_2(210),
V_1_11(315), V_1_11_2(316),
@@ -49,8 +49,8 @@ public enum ServerVersion {
V_1_19(759), V_1_19_1(760), V_1_19_2(760), V_1_19_3(761), V_1_19_4(762),
//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
V_1_21(767), V_1_21_1(767),
//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),
//TODO UPDATE Add server version constant
ERROR(-1, true);
@@ -18,7 +18,35 @@
package com.github.retrooper.packetevents.protocol.attribute;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.MathUtil;
public interface Attribute extends MappedEntity {
@Override
default ResourceLocation getName() {
return this.getName(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
}
ResourceLocation getName(ClientVersion version);
default double sanitizeValue(double value) {
return this.sanitizeValue(value, PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
}
default double sanitizeValue(double value, ClientVersion version) {
if (!Double.isNaN(value)) {
return MathUtil.clamp(value, this.getMinValue(), this.getMaxValue());
}
return this.getMinValue();
}
double getDefaultValue();
double getMinValue();
double getMaxValue();
}
@@ -20,98 +20,338 @@ package com.github.retrooper.packetevents.protocol.attribute;
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 org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public final class Attributes {
public class Attributes {
private static final VersionedRegistry<Attribute> REGISTRY = new VersionedRegistry<>(
"attribute", "attribute/attribute_mappings");
private static final Map<String, Attribute> ATTRIBUTE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, Attribute>> ATTRIBUTE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("attribute/attribute_mappings");
public static Attribute define(String key) {
TypesBuilderData data = TYPES_BUILDER.define(key);
Attribute attribute = new Attribute() {
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Attribute) {
return this.getName().equals(((Attribute) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, ATTRIBUTE_MAP, ATTRIBUTE_ID_MAP, attribute);
return attribute;
private Attributes() {
}
private static Attribute define(
String key, @Nullable String legacyPrefix,
double def, double min, double max
) {
return REGISTRY.define(key, data ->
new StaticAttribute(data, legacyPrefix, def, min, max));
}
public static VersionedRegistry<Attribute> getRegistry() {
return REGISTRY;
}
// with minecraft:key
public static Attribute getByName(String name) {
return ATTRIBUTE_MAP.get(name);
// "remapping" to support < 1.21.2
String normedName = ResourceLocation.normString(name);
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);
}
return REGISTRY.getByName(normedName);
}
public static Attribute getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, Attribute> idMap = ATTRIBUTE_ID_MAP.get((byte) index);
return idMap.get(id);
return REGISTRY.getById(version, id);
}
public static final Attribute GENERIC_ARMOR = define("generic.armor");
public static final Attribute GENERIC_ARMOR_TOUGHNESS = define("generic.armor_toughness");
public static final Attribute GENERIC_ATTACK_DAMAGE = define("generic.attack_damage");
public static final Attribute GENERIC_ATTACK_KNOCKBACK = define("generic.attack_knockback");
public static final Attribute GENERIC_ATTACK_SPEED = define("generic.attack_speed");
public static final Attribute GENERIC_FLYING_SPEED = define("generic.flying_speed");
public static final Attribute GENERIC_FOLLOW_RANGE = define("generic.follow_range");
@ApiStatus.Obsolete // renamed in 1.20.5
public static final Attribute HORSE_JUMP_STRENGTH = define("horse.jump_strength");
public static final Attribute GENERIC_KNOCKBACK_RESISTANCE = define("generic.knockback_resistance");
public static final Attribute GENERIC_LUCK = define("generic.luck");
public static final Attribute GENERIC_MAX_HEALTH = define("generic.max_health");
public static final Attribute GENERIC_MOVEMENT_SPEED = define("generic.movement_speed");
public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = define("zombie.spawn_reinforcements");
public static final Attribute ARMOR = define("armor",
"generic", 0d, 0d, 30d);
public static final Attribute ARMOR_TOUGHNESS = define("armor_toughness",
"generic", 0d, 0d, 20d);
public static final Attribute ATTACK_DAMAGE = define("attack_damage",
"generic", 2d, 0d, 2048d);
public static final Attribute ATTACK_KNOCKBACK = define("attack_knockback",
"generic", 0d, 0d, 5d);
public static final Attribute ATTACK_SPEED = define("attack_speed",
"generic", 4d, 0d, 1024d);
public static final Attribute FLYING_SPEED = define("flying_speed",
"generic", 0.4d, 0d, 1024d);
public static final Attribute FOLLOW_RANGE = define("follow_range",
"generic", 32d, 0d, 2048d);
public static final Attribute KNOCKBACK_RESISTANCE = define("knockback_resistance",
"generic", 0d, 0d, 1d);
public static final Attribute LUCK = define("luck",
"generic", 0d, -1024d, 1024d);
public static final Attribute MAX_HEALTH = define("max_health",
"generic", 20d, 1d, 1024d);
public static final Attribute MOVEMENT_SPEED = define("movement_speed",
"generic", 0.7d, 0d, 1024d);
public static final Attribute SPAWN_REINFORCEMENTS = define("spawn_reinforcements",
"zombie", 0d, 0d, 1d);
// Added in 1.20.2
public static final Attribute GENERIC_MAX_ABSORPTION = define("generic.max_absorption");
/**
* Added with 1.20.2
*/
public static final Attribute MAX_ABSORPTION = define("max_absorption",
"generic", 0d, 0d, 2048d);
// Added in 1.20.5
public static final Attribute PLAYER_BLOCK_BREAK_SPEED = define("player.block_break_speed");
public static final Attribute PLAYER_BLOCK_INTERACTION_RANGE = define("player.block_interaction_range");
public static final Attribute PLAYER_ENTITY_INTERACTION_RANGE = define("player.entity_interaction_range");
public static final Attribute GENERIC_FALL_DAMAGE_MULTIPLIER = define("generic.fall_damage_multiplier");
public static final Attribute GENERIC_GRAVITY = define("generic.gravity");
public static final Attribute GENERIC_JUMP_STRENGTH = define("generic.jump_strength");
public static final Attribute GENERIC_SAFE_FALL_DISTANCE = define("generic.safe_fall_distance");
public static final Attribute GENERIC_SCALE = define("generic.scale");
public static final Attribute GENERIC_STEP_HEIGHT = define("generic.step_height");
/**
* Added with 1.20.5
*/
public static final Attribute BLOCK_BREAK_SPEED = define("block_break_speed",
"player", 1d, 0d, 1024d);
/**
* Added with 1.20.5
*/
public static final Attribute BLOCK_INTERACTION_RANGE = define("block_interaction_range",
"player", 4.5d, 0d, 64d);
/**
* Added with 1.20.5
*/
public static final Attribute ENTITY_INTERACTION_RANGE = define("entity_interaction_range",
"player", 3d, 0d, 64d);
/**
* Added with 1.20.5
*/
public static final Attribute FALL_DAMAGE_MULTIPLIER = define("fall_damage_multiplier",
"generic", 1d, 0d, 100d);
/**
* Added with 1.20.5
*/
public static final Attribute GRAVITY = define("gravity",
"generic", 0.08d, -1d, 1d);
/**
* Added with 1.20.5
*/
public static final Attribute JUMP_STRENGTH = define("jump_strength",
"generic", 0.42d, 0d, 32d);
/**
* Added with 1.20.5
*/
public static final Attribute SAFE_FALL_DISTANCE = define("safe_fall_distance",
"generic", 3d, 0d, 1024d);
/**
* Added with 1.20.5
*/
public static final Attribute SCALE = define("scale",
"generic", 1d, 1d / 16d, 16d);
/**
* Added with 1.20.5
*/
public static final Attribute STEP_HEIGHT = define("step_height",
"generic", 0.6d, 0d, 10d);
// Added in 1.21
public static final Attribute GENERIC_BURNING_TIME = define("generic.burning_time");
public static final Attribute GENERIC_EXPLOSION_KNOCKBACK_RESISTANCE = define("generic.explosion_knockback_resistance");
public static final Attribute PLAYER_MINING_EFFICIENCY = define("player.mining_efficiency");
public static final Attribute GENERIC_MOVEMENT_EFFICIENCY = define("generic.movement_efficiency");
public static final Attribute GENERIC_OXYGEN_BONUS = define("generic.oxygen_bonus");
public static final Attribute PLAYER_SNEAKING_SPEED = define("player.sneaking_speed");
public static final Attribute PLAYER_SUBMERGED_MINING_SPEED = define("player.submerged_mining_speed");
public static final Attribute PLAYER_SWEEPING_DAMAGE_RATIO = define("player.sweeping_damage_ratio");
public static final Attribute GENERIC_WATER_MOVEMENT_EFFICIENCY = define("generic.water_movement_efficiency");
/**
* Added with 1.21
*/
public static final Attribute BURNING_TIME = define("burning_time",
"generic", 0d, 1d, 1024d);
/**
* Added with 1.21
*/
public static final Attribute EXPLOSION_KNOCKBACK_RESISTANCE = define("explosion_knockback_resistance",
"generic", 0d, 0d, 1d);
/**
* Added with 1.21
*/
public static final Attribute MINING_EFFICIENCY = define("mining_efficiency",
"player", 0d, 0d, 1024d);
/**
* Added with 1.21
*/
public static final Attribute MOVEMENT_EFFICIENCY = define("movement_efficiency",
"generic", 0d, 0d, 1d);
/**
* Added with 1.21
*/
public static final Attribute OXYGEN_BONUS = define("oxygen_bonus",
"generic", 0d, 0d, 1024d);
/**
* Added with 1.21
*/
public static final Attribute SNEAKING_SPEED = define("sneaking_speed",
"player", 0.3d, 0d, 1d);
/**
* Added with 1.21
*/
public static final Attribute SUBMERGED_MINING_SPEED = define("submerged_mining_speed",
"player", 0.2d, 0d, 20d);
/**
* Added with 1.21
*/
public static final Attribute SWEEPING_DAMAGE_RATIO = define("sweeping_damage_ratio",
"player", 0d, 0d, 1d);
/**
* Added with 1.21
*/
public static final Attribute WATER_MOVEMENT_EFFICIENCY = define("water_movement_efficiency",
"generic", 0d, 0d, 1d);
/**
* Added with 1.21.2
*/
public static final Attribute TEMPT_RANGE = define("tempt_range",
null, 10d, 0d, 2048d);
/**
* This attribute has been renamed in 1.20.5 to {@link #JUMP_STRENGTH}
*/
@ApiStatus.Obsolete
public static final Attribute HORSE_JUMP_STRENGTH = define("horse.jump_strength",
null, 0.7d, 0d, 2d);
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_ARMOR = ARMOR;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_ARMOR_TOUGHNESS = ARMOR_TOUGHNESS;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_ATTACK_DAMAGE = ATTACK_DAMAGE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_ATTACK_KNOCKBACK = ATTACK_KNOCKBACK;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_ATTACK_SPEED = ATTACK_SPEED;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_FLYING_SPEED = FLYING_SPEED;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_FOLLOW_RANGE = FOLLOW_RANGE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_KNOCKBACK_RESISTANCE = KNOCKBACK_RESISTANCE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_LUCK = LUCK;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_MAX_HEALTH = MAX_HEALTH;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_MOVEMENT_SPEED = MOVEMENT_SPEED;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = SPAWN_REINFORCEMENTS;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_MAX_ABSORPTION = MAX_ABSORPTION;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute PLAYER_BLOCK_BREAK_SPEED = BLOCK_BREAK_SPEED;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute PLAYER_BLOCK_INTERACTION_RANGE = BLOCK_INTERACTION_RANGE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute PLAYER_ENTITY_INTERACTION_RANGE = ENTITY_INTERACTION_RANGE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_FALL_DAMAGE_MULTIPLIER = FALL_DAMAGE_MULTIPLIER;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_GRAVITY = GRAVITY;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_JUMP_STRENGTH = JUMP_STRENGTH;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_SAFE_FALL_DISTANCE = SAFE_FALL_DISTANCE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_SCALE = SCALE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_STEP_HEIGHT = STEP_HEIGHT;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_BURNING_TIME = BURNING_TIME;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_EXPLOSION_KNOCKBACK_RESISTANCE = EXPLOSION_KNOCKBACK_RESISTANCE;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute PLAYER_MINING_EFFICIENCY = MINING_EFFICIENCY;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_MOVEMENT_EFFICIENCY = MOVEMENT_EFFICIENCY;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_OXYGEN_BONUS = OXYGEN_BONUS;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute PLAYER_SNEAKING_SPEED = SNEAKING_SPEED;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute PLAYER_SUBMERGED_MINING_SPEED = SUBMERGED_MINING_SPEED;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute PLAYER_SWEEPING_DAMAGE_RATIO = SWEEPING_DAMAGE_RATIO;
/**
* All attribute "type" prefixes were removed with 1.21.2
*/
@Deprecated
public static final Attribute GENERIC_WATER_MOVEMENT_EFFICIENCY = WATER_MOVEMENT_EFFICIENCY;
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.attribute;
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.Nullable;
public class StaticAttribute extends AbstractMappedEntity implements Attribute {
private final @Nullable ResourceLocation legacyName;
private final double defaultValue;
private final double minValue;
private final double maxValue;
StaticAttribute(
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(
data.getName().getNamespace(), legacyPrefix + "." + data.getName().getKey());
}
@Override
public ResourceLocation getName(ClientVersion version) {
assert this.data != null; // not marked as nullable in ctor
return version.isNewerThanOrEquals(ClientVersion.V_1_21_2) || this.legacyName == null
? this.data.getName() : this.legacyName;
}
@Override
public double getDefaultValue() {
return this.defaultValue;
}
@Override
public double getMinValue() {
return this.minValue;
}
@Override
public double getMaxValue() {
return this.maxValue;
}
}
@@ -20,6 +20,7 @@ package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_1;
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;
@@ -37,7 +38,7 @@ import java.util.Objects;
import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow;
public interface ChatType extends MappedEntity, CopyableEntity<ChatType> {
public interface ChatType extends MappedEntity, CopyableEntity<ChatType>, DeepComparableEntity {
@UnknownNullability("only nullable for 1.19")
ChatTypeDecoration getChatDecoration();
@@ -96,6 +96,7 @@ public class StaticChatType extends AbstractMappedEntity implements ChatType {
return this.narrationPriority;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticChatType)) return false;
@@ -107,6 +108,7 @@ public class StaticChatType extends AbstractMappedEntity implements ChatType {
return this.narrationPriority == that.narrationPriority;
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.chatDecoration, this.overlayDecoration, this.narrationDecoration, this.narrationPriority);
}
@@ -0,0 +1,146 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.color;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.MathUtil;
import org.jetbrains.annotations.Range;
public final class AlphaColor extends Color {
public static final AlphaColor WHITE = new AlphaColor(0xFFFFFFFF);
private final int alpha;
public AlphaColor(
@Range(from = 0L, to = 255L) int red,
@Range(from = 0L, to = 255L) int green,
@Range(from = 0L, to = 255L) int blue
) {
this(255, red, green, blue);
}
public AlphaColor(
@Range(from = 0L, to = 255L) int alpha,
@Range(from = 0L, to = 255L) int red,
@Range(from = 0L, to = 255L) int green,
@Range(from = 0L, to = 255L) int blue
) {
super(red, green, blue);
this.alpha = alpha;
}
public AlphaColor(
@Range(from = 0L, to = 1L) float red,
@Range(from = 0L, to = 1L) float green,
@Range(from = 0L, to = 1L) float blue
) {
this(1f, red, green, blue);
}
public AlphaColor(
@Range(from = 0L, to = 1L) float alpha,
@Range(from = 0L, to = 1L) float red,
@Range(from = 0L, to = 1L) float green,
@Range(from = 0L, to = 1L) float blue
) {
super(red, green, blue);
this.alpha = MathUtil.floor(alpha * 255f);
}
public AlphaColor(int rgb) {
this((rgb >> 24) & BIT_MASK,
(rgb >> 16) & BIT_MASK,
(rgb >> 8) & BIT_MASK,
rgb & BIT_MASK);
}
public static AlphaColor decode(NBT nbt, ClientVersion version) {
if (nbt instanceof NBTNumber) {
return new AlphaColor(((NBTNumber) nbt).getAsInt());
}
NBTList<?> list = (NBTList<?>) nbt;
float red = ((NBTNumber) list.getTag(0)).getAsFloat();
float green = ((NBTNumber) list.getTag(1)).getAsFloat();
float blue = ((NBTNumber) list.getTag(2)).getAsFloat();
float alpha = ((NBTNumber) list.getTag(3)).getAsFloat();
return new AlphaColor(alpha, red, green, blue);
}
public static NBT encode(AlphaColor color, ClientVersion version) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_2)) {
return new NBTInt(color.asRGB());
}
NBTList<NBTFloat> list = new NBTList<>(NBTType.FLOAT, 4);
list.addTag(new NBTFloat(color.red));
list.addTag(new NBTFloat(color.green));
list.addTag(new NBTFloat(color.blue));
list.addTag(new NBTFloat(color.alpha));
return list;
}
public AlphaColor withAlpha(@Range(from = 0L, to = 255L) int alpha) {
return new AlphaColor(alpha, this.red, this.green, this.blue);
}
@Override
public AlphaColor withRed(@Range(from = 0L, to = 255L) int red) {
return new AlphaColor(this.alpha, red, this.green, this.blue);
}
@Override
public AlphaColor withGreen(@Range(from = 0L, to = 255L) int green) {
return new AlphaColor(this.alpha, this.red, green, this.blue);
}
@Override
public AlphaColor withBlue(@Range(from = 0L, to = 255L) int blue) {
return new AlphaColor(this.alpha, this.red, this.green, blue);
}
@Override
public int asRGB() {
return (this.alpha << 24) | (this.red << 16) | (this.green << 8) | this.blue;
}
public @Range(from = 0L, to = 255L) int alpha() {
return this.alpha;
}
@Override
public @Range(from = 0L, to = 255L) int red() {
return this.red;
}
@Override
public @Range(from = 0L, to = 255L) int green() {
return this.green;
}
@Override
public @Range(from = 0L, to = 255L) int blue() {
return this.blue;
}
}
@@ -18,15 +18,24 @@
package com.github.retrooper.packetevents.protocol.color;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.MathUtil;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.util.RGBLike;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;
public final class Color implements RGBLike {
public class Color implements RGBLike {
private static final int BIT_MASK = 0xFF;
protected static final int BIT_MASK = 0xFF;
private final int red, green, blue;
protected final int red, green, blue;
public Color(@Range(from = 0L, to = 255L) int red, @Range(from = 0L, to = 255L) int green, @Range(from = 0L, to = 255L) int blue) {
this.red = red;
@@ -34,10 +43,50 @@ public final class Color implements RGBLike {
this.blue = blue;
}
public Color(
@Range(from = 0L, to = 1L) float red,
@Range(from = 0L, to = 1L) float green,
@Range(from = 0L, to = 1L) float blue
) {
this(MathUtil.floor(red * 255f),
MathUtil.floor(green * 255f),
MathUtil.floor(blue * 255f));
}
public Color(int rgb) {
this((rgb >> 16) & BIT_MASK, (rgb >> 8) & BIT_MASK, rgb & BIT_MASK);
}
public static Color read(PacketWrapper<?> wrapper) {
return new Color(wrapper.readInt());
}
public static void write(PacketWrapper<?> wrapper, Color color) {
wrapper.writeInt(color.asRGB());
}
public static Color decode(NBT nbt, ClientVersion version) {
if (nbt instanceof NBTNumber) {
return new Color(((NBTNumber) nbt).getAsInt());
}
NBTList<?> list = (NBTList<?>) nbt;
float red = ((NBTNumber) list.getTag(0)).getAsFloat();
float green = ((NBTNumber) list.getTag(1)).getAsFloat();
float blue = ((NBTNumber) list.getTag(2)).getAsFloat();
return new Color(red, green, blue);
}
public static NBT encode(Color color, ClientVersion version) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_2)) {
return new NBTInt(color.asRGB());
}
NBTList<NBTFloat> list = new NBTList<>(NBTType.FLOAT, 3);
list.addTag(new NBTFloat(color.red));
list.addTag(new NBTFloat(color.green));
list.addTag(new NBTFloat(color.blue));
return list;
}
public @NotNull Color withRed(@Range(from = 0L, to = 255L) int red) {
return new Color(red, green, blue);
}
@@ -51,9 +100,7 @@ public final class Color implements RGBLike {
}
public int asRGB() {
int rgb = red;
rgb = (rgb << 8) + green;
return (rgb << 8) + blue;
return (this.red << 16) | (this.green << 8) | this.blue;
}
@Override
@@ -70,4 +117,4 @@ public final class Color implements RGBLike {
public @Range(from = 0L, to = 255L) int blue() {
return blue;
}
}
}
@@ -22,6 +22,9 @@ import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.function.Function;
public interface ComponentType<T> extends MappedEntity {
@@ -33,6 +36,9 @@ public interface ComponentType<T> extends MappedEntity {
NBT encode(T value, ClientVersion version);
@ApiStatus.Internal
<Z> ComponentType<Z> legacyMap(Function<T, Z> mapper, Function<Z, T> unmapper);
interface Decoder<T> {
T decode(NBT nbt, ClientVersion version);
@@ -31,21 +31,32 @@ 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.ItemConsumable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerContents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerLoot;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemCustomModelData;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemDamageResistant;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemDeathProtection;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemDyeColor;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantable;
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.ItemJukeboxPlayable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLock;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLore;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemMapDecorations;
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.ItemProfile;
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.ItemTooltipStyle;
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.LodestoneTracker;
import com.github.retrooper.packetevents.protocol.component.builtin.item.PotDecorations;
import com.github.retrooper.packetevents.protocol.component.builtin.item.SuspiciousStewEffects;
@@ -129,8 +140,14 @@ public final class ComponentTypes {
ItemAdventurePredicate::read, ItemAdventurePredicate::write);
public static final ComponentType<ItemAttributeModifiers> ATTRIBUTE_MODIFIERS = define("attribute_modifiers",
ItemAttributeModifiers::read, ItemAttributeModifiers::write);
public static final ComponentType<Integer> CUSTOM_MODEL_DATA = define("custom_model_data",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<ItemCustomModelData> CUSTOM_MODEL_DATA_LISTS = define("custom_model_data",
ItemCustomModelData::read, ItemCustomModelData::write);
/**
* Rewritten in 1.21.4
*/
@Deprecated
public static final ComponentType<Integer> CUSTOM_MODEL_DATA = CUSTOM_MODEL_DATA_LISTS.legacyMap(
ItemCustomModelData::getLegacyId, ItemCustomModelData::new);
public static final ComponentType<Dummy> HIDE_ADDITIONAL_TOOLTIP = define("hide_additional_tooltip",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<Dummy> HIDE_TOOLTIP = define("hide_tooltip",
@@ -145,6 +162,10 @@ public final class ComponentTypes {
Dummy::dummyReadNbt, Dummy::dummyWriteNbt);
public static final ComponentType<FoodProperties> FOOD = define("food",
FoodProperties::read, FoodProperties::write);
/**
* Has been migrated to #DAMAGE_RESISTANT with 1.21.2.
*/
@ApiStatus.Obsolete
public static final ComponentType<Dummy> FIRE_RESISTANT = define("fire_resistant",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<ItemTool> TOOL = define("tool",
@@ -220,6 +241,30 @@ public final class ComponentTypes {
public static final ComponentType<ItemJukeboxPlayable> JUKEBOX_PLAYABLE = define("jukebox_playable",
ItemJukeboxPlayable::read, ItemJukeboxPlayable::write);
// added in 1.21.2
public static final ComponentType<ItemConsumable> CONSUMABLE = define("consumable",
ItemConsumable::read, ItemConsumable::write);
public static final ComponentType<ItemUseRemainder> USE_REMAINDER = define("use_remainder",
ItemUseRemainder::read, ItemUseRemainder::write);
public static final ComponentType<ItemUseCooldown> USE_COOLDOWN = define("use_cooldown",
ItemUseCooldown::read, ItemUseCooldown::write);
public static final ComponentType<ItemEnchantable> ENCHANTABLE = define("enchantable",
ItemEnchantable::read, ItemEnchantable::write);
public static final ComponentType<ItemRepairable> REPAIRABLE = define("repairable",
ItemRepairable::read, ItemRepairable::write);
public static final ComponentType<ItemModel> ITEM_MODEL = define("item_model",
ItemModel::read, ItemModel::write);
public static final ComponentType<ItemDamageResistant> DAMAGE_RESISTANT = define("damage_resistant",
ItemDamageResistant::read, ItemDamageResistant::write);
public static final ComponentType<ItemEquippable> EQUIPPABLE = define("equippable",
ItemEquippable::read, ItemEquippable::write);
public static final ComponentType<Dummy> GLIDER = define("glider",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<ItemDeathProtection> DEATH_PROTECTION = define("death_protection",
ItemDeathProtection::read, ItemDeathProtection::write);
public static final ComponentType<ItemTooltipStyle> TOOLTIP_STYLE = define("tooltip_style",
ItemTooltipStyle::read, ItemTooltipStyle::write);
/**
* Returns an immutable view of the component types.
*
@@ -22,6 +22,7 @@ import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAtt
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLore;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRarity;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -33,6 +34,8 @@ import java.util.Optional;
public class StaticComponentMap implements IComponentMap {
public static final StaticComponentMap EMPTY = new StaticComponentMap(Collections.emptyMap());
@ApiStatus.Obsolete
public static final StaticComponentMap SHARED_ITEM_COMPONENTS = builder()
.set(ComponentTypes.MAX_STACK_SIZE, 64)
.set(ComponentTypes.LORE, ItemLore.EMPTY)
@@ -98,7 +101,7 @@ public class StaticComponentMap implements IComponentMap {
@Override
public String toString() {
return "StaticComponentMap{empty=" + this.empty + ", delegate=" + this.delegate + '}';
return "Components" + this.delegate;
}
public static class Builder {
@@ -112,6 +115,10 @@ public class StaticComponentMap implements IComponentMap {
return new StaticComponentMap(this.map);
}
public Builder setAll(StaticComponentMap.Builder map) {
return this.setAll(map.map);
}
public Builder setAll(StaticComponentMap map) {
return this.setAll(map.getDelegate());
}
@@ -27,6 +27,8 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
import org.jetbrains.annotations.Nullable;
import java.util.function.Function;
public class StaticComponentType<T> extends AbstractMappedEntity implements ComponentType<T> {
private final @Nullable Reader<T> reader;
@@ -91,4 +93,13 @@ public class StaticComponentType<T> extends AbstractMappedEntity implements Comp
}
throw new UnsupportedOperationException();
}
@Override
public <Z> ComponentType<Z> legacyMap(Function<T, Z> mapper, Function<Z, T> unmapper) {
Reader<Z> reader = this.reader != null ? wrapper -> mapper.apply(this.reader.apply(wrapper)) : null;
Writer<Z> writer = this.writer != null ? (wrapper, value) -> this.writer.accept(wrapper, unmapper.apply(value)) : null;
Decoder<Z> decoder = this.decoder != null ? (nbt, version) -> mapper.apply(this.decoder.decode(nbt, version)) : null;
Encoder<Z> encoder = this.encoder != null ? (value, version) -> this.encoder.encode(unmapper.apply(value), version) : null;
return new StaticComponentType<>(this.data, reader, writer, decoder, encoder);
}
}
@@ -22,8 +22,10 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -36,6 +38,17 @@ public class FoodProperties {
private List<PossibleEffect> effects;
private @Nullable ItemStack usingConvertsTo;
public FoodProperties(
int nutrition, float saturation, boolean canAlwaysEat
) {
this(nutrition, saturation, canAlwaysEat, 1.6f, Collections.emptyList());
}
/**
* <code>eatSeconds</code> and <code>effects</code>
* have been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public FoodProperties(
int nutrition, float saturation, boolean canAlwaysEat,
float eatSeconds, List<PossibleEffect> effects
@@ -43,6 +56,11 @@ public class FoodProperties {
this(nutrition, saturation, canAlwaysEat, eatSeconds, effects, null);
}
/**
* <code>eatSeconds</code>, <code>effects</code> and <code>usingConvertsTo</code>
* have been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public FoodProperties(
int nutrition, float saturation, boolean canAlwaysEat, float eatSeconds,
List<PossibleEffect> effects, @Nullable ItemStack usingConvertsTo
@@ -59,10 +77,13 @@ public class FoodProperties {
int nutrition = wrapper.readVarInt();
float saturation = wrapper.readFloat();
boolean canAlwaysEat = wrapper.readBoolean();
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
return new FoodProperties(nutrition, saturation, canAlwaysEat);
}
float eatSeconds = wrapper.readFloat();
List<PossibleEffect> effects = wrapper.readList(PossibleEffect::read);
ItemStack usingConvertsTo = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)
? wrapper.readOptional(PacketWrapper::readItemStack) : null;
List<PossibleEffect> effects = wrapper.readList(PossibleEffect::read);
return new FoodProperties(nutrition, saturation, canAlwaysEat, eatSeconds, effects, usingConvertsTo);
}
@@ -70,10 +91,12 @@ public class FoodProperties {
wrapper.writeVarInt(props.nutrition);
wrapper.writeFloat(props.saturation);
wrapper.writeBoolean(props.canAlwaysEat);
wrapper.writeFloat(props.eatSeconds);
wrapper.writeList(props.effects, PossibleEffect::write);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
wrapper.writeOptional(props.usingConvertsTo, PacketWrapper::writeItemStack);
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_2)) {
wrapper.writeFloat(props.eatSeconds);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
wrapper.writeOptional(props.usingConvertsTo, PacketWrapper::writeItemStack);
}
wrapper.writeList(props.effects, PossibleEffect::write);
}
}
@@ -101,30 +124,58 @@ public class FoodProperties {
this.canAlwaysEat = canAlwaysEat;
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public float getEatSeconds() {
return this.eatSeconds;
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public void setEatSeconds(float eatSeconds) {
this.eatSeconds = eatSeconds;
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public void addEffect(PossibleEffect effect) {
this.effects.add(effect);
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public List<PossibleEffect> getEffects() {
return this.effects;
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public void setEffects(List<PossibleEffect> effects) {
this.effects = effects;
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public @Nullable ItemStack getUsingConvertsTo() {
return this.usingConvertsTo;
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public void setUsingConvertsTo(@Nullable ItemStack usingConvertsTo) {
this.usingConvertsTo = usingConvertsTo;
}
@@ -147,6 +198,10 @@ public class FoodProperties {
return Objects.hash(this.nutrition, this.saturation, this.canAlwaysEat, this.eatSeconds, this.effects, this.usingConvertsTo);
}
/**
* Has been moved to {@link ItemConsumable} in 1.21.2
*/
@ApiStatus.Obsolete
public static class PossibleEffect {
private PotionEffect effect;
@@ -0,0 +1,144 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.consumables.ConsumeEffect;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ItemConsumable {
private float consumeSeconds;
private Animation animation;
private Sound sound;
private boolean consumeParticles;
private List<ConsumeEffect<?>> effects;
public ItemConsumable(
float consumeSeconds, Animation animation, Sound sound,
boolean consumeParticles, List<ConsumeEffect<?>> effects
) {
this.consumeSeconds = consumeSeconds;
this.animation = animation;
this.sound = sound;
this.consumeParticles = consumeParticles;
this.effects = effects;
}
public static ItemConsumable read(PacketWrapper<?> wrapper) {
float consumeSeconds = wrapper.readFloat();
Animation animation = wrapper.readEnum(Animation.values());
Sound sound = Sound.read(wrapper);
boolean consumeParticles = wrapper.readBoolean();
List<ConsumeEffect<?>> effects = wrapper.readList(ConsumeEffect::readFull);
return new ItemConsumable(consumeSeconds, animation, sound, consumeParticles, effects);
}
public static void write(PacketWrapper<?> wrapper, ItemConsumable consumable) {
wrapper.writeFloat(consumable.consumeSeconds);
wrapper.writeEnum(consumable.animation);
Sound.write(wrapper, consumable.sound);
wrapper.writeBoolean(consumable.consumeParticles);
wrapper.writeList(consumable.effects, ConsumeEffect::writeFull);
}
public float getConsumeSeconds() {
return this.consumeSeconds;
}
public void setConsumeSeconds(float consumeSeconds) {
this.consumeSeconds = consumeSeconds;
}
public Animation getAnimation() {
return this.animation;
}
public void setAnimation(Animation animation) {
this.animation = animation;
}
public Sound getSound() {
return this.sound;
}
public void setSound(Sound sound) {
this.sound = sound;
}
public boolean isConsumeParticles() {
return this.consumeParticles;
}
public void setConsumeParticles(boolean consumeParticles) {
this.consumeParticles = consumeParticles;
}
public List<ConsumeEffect<?>> getEffects() {
return this.effects;
}
public void setEffects(List<ConsumeEffect<?>> effects) {
this.effects = effects;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemConsumable)) return false;
ItemConsumable that = (ItemConsumable) obj;
if (Float.compare(that.consumeSeconds, this.consumeSeconds) != 0) return false;
if (this.consumeParticles != that.consumeParticles) return false;
if (this.animation != that.animation) return false;
if (!this.sound.equals(that.sound)) return false;
return this.effects.equals(that.effects);
}
@Override
public int hashCode() {
return Objects.hash(this.consumeSeconds, this.animation, this.sound, this.consumeParticles, this.effects);
}
@Override
public String toString() {
return "ItemConsumable{consumeSeconds=" + this.consumeSeconds + ", animation=" + this.animation + ", sound=" + this.sound + ", consumeParticles=" + this.consumeParticles + ", effects=" + this.effects + '}';
}
public enum Animation {
NONE,
EAT,
DRINK,
BLOCK,
BOW,
SPEAR,
CROSSBOW,
SPYGLASS,
TOOT_HORN,
BRUSH,
/**
* Added with 1.21.4
*/
BUNDLE,
;
}
}
@@ -0,0 +1,134 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.color.Color;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.List;
/**
* Custom model data was completely rewritten with 1.21.4.
* <p>
* Before 1.21.4, this used to be a single integer.<br/>
* With 1.21.4, this is now a holder of many elements.
* <p>
* If possible, use {@link com.github.retrooper.packetevents.protocol.component.ComponentTypes#ITEM_MODEL}
* instead for specifying which model an item should have.
* <p>
* When working with legacy versions, the first element in the {@link #floats}
* will represent the legacy single integer, just like Mojang is handling this.
*/
public class ItemCustomModelData {
private List<Float> floats;
private List<Boolean> flags;
private List<String> strings;
private List<Color> colors;
public ItemCustomModelData(List<Float> floats, List<Boolean> flags, List<String> strings, List<Color> colors) {
this.floats = floats;
this.flags = flags;
this.strings = strings;
this.colors = colors;
}
public ItemCustomModelData(int legacyId) {
this.floats = new ArrayList<>(1);
this.flags = new ArrayList<>(0);
this.strings = new ArrayList<>(0);
this.colors = new ArrayList<>(0);
this.setLegacyId(legacyId);
}
public static ItemCustomModelData read(PacketWrapper<?> wrapper) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_4)) {
return new ItemCustomModelData(
wrapper.readList(PacketWrapper::readFloat),
wrapper.readList(PacketWrapper::readBoolean),
wrapper.readList(PacketWrapper::readString),
wrapper.readList(Color::read));
} else {
return new ItemCustomModelData(wrapper.readVarInt());
}
}
public static void write(PacketWrapper<?> wrapper, ItemCustomModelData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_4)) {
wrapper.writeList(data.floats, PacketWrapper::writeFloat);
wrapper.writeList(data.flags, PacketWrapper::writeBoolean);
wrapper.writeList(data.strings, PacketWrapper::writeString);
wrapper.writeList(data.colors, Color::write);
} else {
wrapper.writeVarInt(data.getLegacyId());
}
}
public List<Float> getFloats() {
return this.floats;
}
public void setFloats(List<Float> floats) {
this.floats = floats;
}
public List<Boolean> getFlags() {
return this.flags;
}
public void setFlags(List<Boolean> flags) {
this.flags = flags;
}
public List<String> getStrings() {
return this.strings;
}
public void setStrings(List<String> strings) {
this.strings = strings;
}
public List<Color> getColors() {
return this.colors;
}
public void setColors(List<Color> colors) {
this.colors = colors;
}
@ApiStatus.Obsolete
public int getLegacyId() {
if (!this.floats.isEmpty()) {
return this.floats.get(0).intValue();
}
return 0;
}
@ApiStatus.Obsolete
public void setLegacyId(int legacyId) {
if (this.flags.isEmpty()) {
this.floats.add((float) legacyId);
} else {
this.floats.set(0, (float) legacyId);
}
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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 ItemDamageResistant {
private ResourceLocation typesTagKey;
public ItemDamageResistant(ResourceLocation typesTagKey) {
this.typesTagKey = typesTagKey;
}
public static ItemDamageResistant read(PacketWrapper<?> wrapper) {
return new ItemDamageResistant(wrapper.readIdentifier());
}
public static void write(PacketWrapper<?> wrapper, ItemDamageResistant resistant) {
wrapper.writeIdentifier(resistant.typesTagKey);
}
public ResourceLocation getTypesTagKey() {
return this.typesTagKey;
}
public void setTypesTagKey(ResourceLocation typesTagKey) {
this.typesTagKey = typesTagKey;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemDamageResistant)) return false;
ItemDamageResistant that = (ItemDamageResistant) obj;
return this.typesTagKey.equals(that.typesTagKey);
}
@Override
public int hashCode() {
return Objects.hashCode(this.typesTagKey);
}
@Override
public String toString() {
return "ItemDamageResistant{typesTagKey=" + this.typesTagKey + '}';
}
}
@@ -0,0 +1,69 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.consumables.ConsumeEffect;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ItemDeathProtection {
private List<ConsumeEffect<?>> deathEffects;
public ItemDeathProtection(List<ConsumeEffect<?>> deathEffects) {
this.deathEffects = deathEffects;
}
public static ItemDeathProtection read(PacketWrapper<?> wrapper) {
List<ConsumeEffect<?>> deathEffects = wrapper.readList(ConsumeEffect::readFull);
return new ItemDeathProtection(deathEffects);
}
public static void write(PacketWrapper<?> wrapper, ItemDeathProtection deathProtection) {
wrapper.writeList(deathProtection.deathEffects, ConsumeEffect::writeFull);
}
public List<ConsumeEffect<?>> getDeathEffects() {
return this.deathEffects;
}
public void setDeathEffects(List<ConsumeEffect<?>> deathEffects) {
this.deathEffects = deathEffects;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemDeathProtection)) return false;
ItemDeathProtection that = (ItemDeathProtection) obj;
return this.deathEffects.equals(that.deathEffects);
}
@Override
public int hashCode() {
return Objects.hashCode(this.deathEffects);
}
@Override
public String toString() {
return "ItemDeathProtection{deathEffects=" + this.deathEffects + '}';
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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 ItemEnchantable {
private int value;
public ItemEnchantable(int value) {
this.value = value;
}
public static ItemEnchantable read(PacketWrapper<?> wrapper) {
int value = wrapper.readVarInt();
return new ItemEnchantable(value);
}
public static void write(PacketWrapper<?> wrapper, ItemEnchantable enchantable) {
wrapper.writeVarInt(enchantable.value);
}
public int getValue() {
return this.value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemEnchantable)) return false;
ItemEnchantable that = (ItemEnchantable) obj;
return this.value == that.value;
}
@Override
public int hashCode() {
return Objects.hashCode(this.value);
}
@Override
public String toString() {
return "ItemEnchantable{value=" + this.value + '}';
}
}
@@ -0,0 +1,186 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
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.Nullable;
import java.util.Objects;
public class ItemEquippable {
private EquipmentSlot slot;
private Sound equipSound;
private @Nullable ResourceLocation assetId;
private @Nullable ResourceLocation cameraOverlay;
private @Nullable MappedEntitySet<EntityType> allowedEntities;
private boolean dispensable;
private boolean swappable;
private boolean damageOnHurt;
public ItemEquippable(
EquipmentSlot slot,
Sound equipSound,
@Nullable ResourceLocation assetId,
@Nullable ResourceLocation cameraOverlay,
@Nullable MappedEntitySet<EntityType> allowedEntities,
boolean dispensable,
boolean swappable,
boolean damageOnHurt
) {
this.slot = slot;
this.equipSound = equipSound;
this.assetId = assetId;
this.cameraOverlay = cameraOverlay;
this.allowedEntities = allowedEntities;
this.dispensable = dispensable;
this.swappable = swappable;
this.damageOnHurt = damageOnHurt;
}
public static ItemEquippable read(PacketWrapper<?> wrapper) {
EquipmentSlot slot = wrapper.readEnum(EquipmentSlot.values());
Sound equipSound = Sound.read(wrapper);
ResourceLocation model = 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);
}
public static void write(PacketWrapper<?> wrapper, ItemEquippable equippable) {
wrapper.writeEnum(equippable.slot);
Sound.write(wrapper, equippable.equipSound);
wrapper.writeOptional(equippable.assetId, PacketWrapper::writeIdentifier);
wrapper.writeOptional(equippable.cameraOverlay, PacketWrapper::writeIdentifier);
wrapper.writeOptional(equippable.allowedEntities, MappedEntitySet::write);
wrapper.writeBoolean(equippable.dispensable);
wrapper.writeBoolean(equippable.swappable);
wrapper.writeBoolean(equippable.damageOnHurt);
}
public EquipmentSlot getSlot() {
return this.slot;
}
public void setSlot(EquipmentSlot slot) {
this.slot = slot;
}
public Sound getEquipSound() {
return this.equipSound;
}
public void setEquipSound(Sound equipSound) {
this.equipSound = equipSound;
}
public @Nullable ResourceLocation getAssetId() {
return this.assetId;
}
public void setAssetId(@Nullable ResourceLocation assetId) {
this.assetId = assetId;
}
public @Nullable ResourceLocation getCameraOverlay() {
return this.cameraOverlay;
}
public void setCameraOverlay(@Nullable ResourceLocation cameraOverlay) {
this.cameraOverlay = cameraOverlay;
}
public @Nullable MappedEntitySet<EntityType> getAllowedEntities() {
return this.allowedEntities;
}
public void setAllowedEntities(@Nullable MappedEntitySet<EntityType> allowedEntities) {
this.allowedEntities = allowedEntities;
}
public boolean isDispensable() {
return this.dispensable;
}
public void setDispensable(boolean dispensable) {
this.dispensable = dispensable;
}
public boolean isSwappable() {
return this.swappable;
}
public void setSwappable(boolean swappable) {
this.swappable = swappable;
}
public boolean isDamageOnHurt() {
return this.damageOnHurt;
}
public void setDamageOnHurt(boolean damageOnHurt) {
this.damageOnHurt = damageOnHurt;
}
@Deprecated
public @Nullable ResourceLocation getModel() {
return this.assetId;
}
@Deprecated
public void setModel(@Nullable ResourceLocation assetId) {
this.assetId = assetId;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemEquippable)) return false;
ItemEquippable that = (ItemEquippable) obj;
if (this.dispensable != that.dispensable) return false;
if (this.swappable != that.swappable) return false;
if (this.damageOnHurt != that.damageOnHurt) return false;
if (this.slot != that.slot) return false;
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);
}
@Override
public int hashCode() {
return Objects.hash(this.slot, this.equipSound, this.assetId, this.cameraOverlay, this.allowedEntities, this.dispensable, this.swappable, this.damageOnHurt);
}
@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 + '}';
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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 ItemModel {
private ResourceLocation modelLocation;
public ItemModel(ResourceLocation modelLocation) {
this.modelLocation = modelLocation;
}
public static ItemModel read(PacketWrapper<?> wrapper) {
return new ItemModel(wrapper.readIdentifier());
}
public static void write(PacketWrapper<?> wrapper, ItemModel model) {
wrapper.writeIdentifier(model.modelLocation);
}
public ResourceLocation getModelLocation() {
return this.modelLocation;
}
public void setModelLocation(ResourceLocation modelLocation) {
this.modelLocation = modelLocation;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemModel)) return false;
ItemModel itemModel = (ItemModel) obj;
return this.modelLocation.equals(itemModel.modelLocation);
}
@Override
public int hashCode() {
return Objects.hashCode(this.modelLocation);
}
@Override
public String toString() {
return "ItemModel{modelLocation=" + this.modelLocation + '}';
}
}
@@ -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.potion.Potion;
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
import com.github.retrooper.packetevents.protocol.potion.Potions;
@@ -32,28 +33,44 @@ public class ItemPotionContents {
private @Nullable Potion potion;
private @Nullable Integer customColor;
private List<PotionEffect> customEffects;
private @Nullable String customName;
public ItemPotionContents(
@Nullable Potion potion,
@Nullable Integer customColor,
List<PotionEffect> customEffects
) {
this(potion, customColor, customEffects, null);
}
public ItemPotionContents(
@Nullable Potion potion,
@Nullable Integer customColor,
List<PotionEffect> customEffects,
@Nullable String customName
) {
this.potion = potion;
this.customColor = customColor;
this.customEffects = customEffects;
this.customName = customName;
}
public static ItemPotionContents read(PacketWrapper<?> wrapper) {
Potion potionId = wrapper.readOptional(ew -> ew.readMappedEntity(Potions::getById));
Integer customColor = wrapper.readOptional(PacketWrapper::readInt);
List<PotionEffect> customEffects = wrapper.readList(PotionEffect::read);
return new ItemPotionContents(potionId, customColor, customEffects);
String customName = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)
? wrapper.readOptional(PacketWrapper::readString) : null;
return new ItemPotionContents(potionId, customColor, customEffects, customName);
}
public static void write(PacketWrapper<?> wrapper, ItemPotionContents contents) {
wrapper.writeOptional(contents.potion, PacketWrapper::writeMappedEntity);
wrapper.writeOptional(contents.customColor, PacketWrapper::writeInt);
wrapper.writeList(contents.customEffects, PotionEffect::write);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
wrapper.writeOptional(contents.customName, PacketWrapper::writeString);
}
}
public @Nullable Potion getPotion() {
@@ -84,6 +101,14 @@ public class ItemPotionContents {
this.customEffects = customEffects;
}
public @Nullable String getCustomName() {
return this.customName;
}
public void setCustomName(@Nullable String customName) {
this.customName = customName;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -91,11 +116,12 @@ public class ItemPotionContents {
ItemPotionContents that = (ItemPotionContents) obj;
if (!Objects.equals(this.potion, that.potion)) return false;
if (!Objects.equals(this.customColor, that.customColor)) return false;
return this.customEffects.equals(that.customEffects);
if (!this.customEffects.equals(that.customEffects)) return false;
return Objects.equals(this.customName, that.customName);
}
@Override
public int hashCode() {
return Objects.hash(this.potion, this.customColor, this.customEffects);
return Objects.hash(this.potion, this.customColor, this.customEffects, this.customName);
}
}
@@ -18,9 +18,12 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -33,12 +36,21 @@ public class ItemRecipes {
}
public static ItemRecipes read(PacketWrapper<?> wrapper) {
List<ResourceLocation> recipes = wrapper.readList(PacketWrapper::readIdentifier);
return new ItemRecipes(recipes);
NBTList<?> recipes = (NBTList<?>) wrapper.readNBTRaw();
List<ResourceLocation> recipeKeys = new ArrayList<>(recipes.size());
for (int i = 0; i < recipes.size(); i++) {
NBTString tag = (NBTString) recipes.getTag(i);
recipeKeys.add(new ResourceLocation(tag.getValue()));
}
return new ItemRecipes(recipeKeys);
}
public static void write(PacketWrapper<?> wrapper, ItemRecipes recipes) {
wrapper.writeList(recipes.recipes, PacketWrapper::writeIdentifier);
NBTList<NBTString> recipesTag = NBTList.createStringList();
for (ResourceLocation recipeKey : recipes.recipes) {
recipesTag.addTag(new NBTString(recipeKey.toString()));
}
wrapper.writeNBTRaw(recipesTag);
}
public void addRecipe(ResourceLocation recipeKey) {
@@ -0,0 +1,70 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemRepairable {
private MappedEntitySet<ItemType> items;
public ItemRepairable(MappedEntitySet<ItemType> items) {
this.items = items;
}
public static ItemRepairable read(PacketWrapper<?> wrapper) {
MappedEntitySet<ItemType> items = MappedEntitySet.read(wrapper, ItemTypes.getRegistry());
return new ItemRepairable(items);
}
public static void write(PacketWrapper<?> wrapper, ItemRepairable repairable) {
MappedEntitySet.write(wrapper, repairable.items);
}
public MappedEntitySet<ItemType> getItems() {
return this.items;
}
public void setItems(MappedEntitySet<ItemType> items) {
this.items = items;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemRepairable)) return false;
ItemRepairable that = (ItemRepairable) obj;
return this.items.equals(that.items);
}
@Override
public int hashCode() {
return Objects.hashCode(this.items);
}
@Override
public String toString() {
return "ItemRepairable{items=" + this.items + '}';
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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 ItemTooltipStyle {
private ResourceLocation tooltipLoc;
public ItemTooltipStyle(ResourceLocation tooltipLoc) {
this.tooltipLoc = tooltipLoc;
}
public static ItemTooltipStyle read(PacketWrapper<?> wrapper) {
return new ItemTooltipStyle(wrapper.readIdentifier());
}
public static void write(PacketWrapper<?> wrapper, ItemTooltipStyle style) {
wrapper.writeIdentifier(style.tooltipLoc);
}
public ResourceLocation getTooltipLoc() {
return this.tooltipLoc;
}
public void setTooltipLoc(ResourceLocation tooltipLoc) {
this.tooltipLoc = tooltipLoc;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemTooltipStyle)) return false;
ItemTooltipStyle that = (ItemTooltipStyle) obj;
return this.tooltipLoc.equals(that.tooltipLoc);
}
@Override
public int hashCode() {
return Objects.hashCode(this.tooltipLoc);
}
@Override
public String toString() {
return "ItemTooltipStyle{tooltipLoc=" + this.tooltipLoc + '}';
}
}
@@ -0,0 +1,101 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.ItemStack;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetCooldown;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.Optional;
public class ItemUseCooldown {
private float seconds;
private Optional<ResourceLocation> cooldownGroup;
public ItemUseCooldown(float seconds, @Nullable ResourceLocation cooldownGroup) {
this(seconds, Optional.ofNullable(cooldownGroup));
}
public ItemUseCooldown(float seconds, Optional<ResourceLocation> cooldownGroup) {
this.seconds = seconds;
this.cooldownGroup = cooldownGroup;
}
public static ItemUseCooldown read(PacketWrapper<?> wrapper) {
float seconds = wrapper.readFloat();
ResourceLocation cooldownGroup = wrapper.readOptional(PacketWrapper::readIdentifier);
return new ItemUseCooldown(seconds, cooldownGroup);
}
public static void write(PacketWrapper<?> wrapper, ItemUseCooldown cooldown) {
wrapper.writeFloat(cooldown.seconds);
wrapper.writeOptional(cooldown.cooldownGroup.orElse(null), PacketWrapper::writeIdentifier);
}
public WrapperPlayServerSetCooldown buildWrapper(ItemStack fallbackStack) {
return this.buildWrapper(fallbackStack.getType());
}
public WrapperPlayServerSetCooldown buildWrapper(ItemType fallbackItem) {
int ticks = (int) (this.seconds * 20f);
return this.cooldownGroup
.map(resourceLocation -> new WrapperPlayServerSetCooldown(resourceLocation, ticks))
.orElseGet(() -> new WrapperPlayServerSetCooldown(fallbackItem, ticks));
}
public float getSeconds() {
return this.seconds;
}
public void setSeconds(float seconds) {
this.seconds = seconds;
}
public Optional<ResourceLocation> getCooldownGroup() {
return this.cooldownGroup;
}
public void setCooldownGroup(Optional<ResourceLocation> cooldownGroup) {
this.cooldownGroup = cooldownGroup;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemUseCooldown)) return false;
ItemUseCooldown that = (ItemUseCooldown) obj;
if (Float.compare(that.seconds, this.seconds) != 0) return false;
return this.cooldownGroup.equals(that.cooldownGroup);
}
@Override
public int hashCode() {
return Objects.hash(this.seconds, this.cooldownGroup);
}
@Override
public String toString() {
return "ItemUseCooldown{seconds=" + this.seconds + ", cooldownGroup=" + this.cooldownGroup + '}';
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.ItemStack;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemUseRemainder {
private ItemStack target;
public ItemUseRemainder(ItemStack target) {
this.target = target;
}
public static ItemUseRemainder read(PacketWrapper<?> wrapper) {
ItemStack target = wrapper.readItemStack();
return new ItemUseRemainder(target);
}
public static void write(PacketWrapper<?> wrapper, ItemUseRemainder remainder) {
wrapper.writeItemStack(remainder.target);
}
public ItemStack getTarget() {
return this.target;
}
public void setTarget(ItemStack target) {
this.target = target;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemUseRemainder)) return false;
ItemUseRemainder that = (ItemUseRemainder) obj;
return this.target.equals(that.target);
}
@Override
public int hashCode() {
return Objects.hashCode(this.target);
}
@Override
public String toString() {
return "ItemUseRemainder{target=" + this.target + '}';
}
}
@@ -0,0 +1,109 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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;
// Created by booky10 in packetevents (02:12 21.10.2024)
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityPositionSync;
import java.util.Objects;
public final class EntityPositionData {
private Vector3d position;
private Vector3d deltaMovement;
private float yaw;
private float pitch;
public EntityPositionData(Vector3d position, Vector3d deltaMovement, float yaw, float pitch) {
this.position = position;
this.deltaMovement = deltaMovement;
this.yaw = yaw;
this.pitch = pitch;
}
public static EntityPositionData read(PacketWrapper<?> wrapper) {
Vector3d position = Vector3d.read(wrapper);
Vector3d deltaMovement = Vector3d.read(wrapper);
float yaw = wrapper.readFloat();
float pitch = wrapper.readFloat();
return new EntityPositionData(position, deltaMovement, yaw, pitch);
}
public static void write(PacketWrapper<?> wrapper, EntityPositionData positionData) {
Vector3d.write(wrapper, positionData.position);
Vector3d.write(wrapper, positionData.deltaMovement);
wrapper.writeFloat(positionData.yaw);
wrapper.writeFloat(positionData.pitch);
}
public Vector3d getPosition() {
return this.position;
}
public void setPosition(Vector3d position) {
this.position = position;
}
public Vector3d getDeltaMovement() {
return this.deltaMovement;
}
public void setDeltaMovement(Vector3d deltaMovement) {
this.deltaMovement = deltaMovement;
}
public float getYaw() {
return this.yaw;
}
public void setYaw(float yaw) {
this.yaw = yaw;
}
public float getPitch() {
return this.pitch;
}
public void setPitch(float pitch) {
this.pitch = pitch;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof EntityPositionData)) return false;
EntityPositionData that = (EntityPositionData) obj;
if (Float.compare(that.yaw, this.yaw) != 0) return false;
if (Float.compare(that.pitch, this.pitch) != 0) return false;
if (!this.position.equals(that.position)) return false;
return this.deltaMovement.equals(that.deltaMovement);
}
@Override
public int hashCode() {
return Objects.hash(this.position, this.deltaMovement, this.yaw, this.pitch);
}
@Override
public String toString() {
return "EntityPositionData{position=" + this.position + ", deltaMovement=" + this.deltaMovement + ", yaw=" + this.yaw + ", pitch=" + this.pitch + '}';
}
}
@@ -22,9 +22,14 @@ import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class EntityTypes {
private static final Map<String, EntityType> ENTITY_TYPE_MAP = new HashMap<>();
@@ -151,7 +156,13 @@ public class EntityTypes {
public static final EntityType BAT = define("bat", ABSTRACT_AMBIENT);
public static final EntityType BEE = define("bee", ABSTRACT_INSENTIENT);
public static final EntityType BLAZE = define("blaze", ABSTRACT_MONSTER);
/**
* <strong>WARNING:</strong> Does not exist itself anymore since 1.21.2
*/
public static final EntityType BOAT = define("boat", ENTITY);
/**
* <strong>WARNING:</strong> Does not exist itself anymore since 1.21.2
*/
public static final EntityType CHEST_BOAT = define("chest_boat", BOAT);
public static final EntityType CAT = define("cat", ABSTRACT_TAMEABLE_ANIMAL);
public static final EntityType CAMEL = define("camel", ABSTRACT_HORSE);
@@ -295,8 +306,37 @@ public class EntityTypes {
public static final EntityType BREEZE_WIND_CHARGE = define("breeze_wind_charge", ABSTRACT_WIND_CHARGE);
public static final EntityType OMINOUS_ITEM_SPAWNER = define("ominous_item_spawner", ENTITY);
// added with 1.21.2
public static final EntityType ACACIA_BOAT = define("acacia_boat", BOAT);
public static final EntityType ACACIA_CHEST_BOAT = define("acacia_chest_boat", CHEST_BOAT);
public static final EntityType BAMBOO_CHEST_RAFT = define("bamboo_chest_raft", CHEST_BOAT);
public static final EntityType BAMBOO_RAFT = define("bamboo_raft", BOAT);
public static final EntityType BIRCH_BOAT = define("birch_boat", BOAT);
public static final EntityType BIRCH_CHEST_BOAT = define("birch_chest_boat", CHEST_BOAT);
public static final EntityType CHERRY_BOAT = define("cherry_boat", BOAT);
public static final EntityType CHERRY_CHEST_BOAT = define("cherry_chest_boat", CHEST_BOAT);
public static final EntityType CREAKING = define("creaking", ABSTRACT_MONSTER);
/**
* Removed with 1.21.4
*/
@ApiStatus.Obsolete
public static final EntityType CREAKING_TRANSIENT = define("creaking_transient", CREAKING);
public static final EntityType DARK_OAK_BOAT = define("dark_oak_boat", BOAT);
public static final EntityType DARK_OAK_CHEST_BOAT = define("dark_oak_chest_boat", CHEST_BOAT);
public static final EntityType JUNGLE_BOAT = define("jungle_boat", BOAT);
public static final EntityType JUNGLE_CHEST_BOAT = define("jungle_chest_boat", CHEST_BOAT);
public static final EntityType MANGROVE_BOAT = define("mangrove_boat", BOAT);
public static final EntityType MANGROVE_CHEST_BOAT = define("mangrove_chest_boat", CHEST_BOAT);
public static final EntityType OAK_BOAT = define("oak_boat", BOAT);
public static final EntityType OAK_CHEST_BOAT = define("oak_chest_boat", CHEST_BOAT);
public static final EntityType PALE_OAK_BOAT = define("pale_oak_boat", BOAT);
public static final EntityType PALE_OAK_CHEST_BOAT = define("pale_oak_chest_boat", CHEST_BOAT);
public static final EntityType SPRUCE_BOAT = define("spruce_boat", BOAT);
public static final EntityType SPRUCE_CHEST_BOAT = define("spruce_chest_boat", CHEST_BOAT);
/**
* Returns an immutable view of the entity types.
*
* @return Entity Types
*/
public static Collection<EntityType> values() {
@@ -82,6 +82,7 @@ public class StaticWolfVariant extends AbstractMappedEntity implements WolfVaria
return this.biomes;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticWolfVariant)) return false;
@@ -93,6 +94,7 @@ public class StaticWolfVariant extends AbstractMappedEntity implements WolfVaria
return this.biomes.equals(that.biomes);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.wildTexture, this.tameTexture, this.angryTexture, this.biomes);
}
@@ -19,6 +19,7 @@
package com.github.retrooper.packetevents.protocol.entity.wolfvariant;
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.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
@@ -31,7 +32,7 @@ import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
public interface WolfVariant extends MappedEntity, CopyableEntity<WolfVariant> {
public interface WolfVariant extends MappedEntity, CopyableEntity<WolfVariant>, DeepComparableEntity {
ResourceLocation getWildTexture();
@@ -512,7 +512,7 @@ public class ItemStack {
int maxAmount = getType().getMaxAmount();
return "ItemStack[type=" + identifier + ", amount=" + amount + "/" + maxAmount
+ ", nbt tag names: " + (nbt != null ? nbt.getTagNames() : "[null]")
+ ", legacyData=" + legacyData + ", components=" + components + "]";
+ ", legacyData=" + legacyData + ", components=" + (components != null ? components.getPatches() : null) + "]";
}
}
@@ -19,54 +19,47 @@
package com.github.retrooper.packetevents.protocol.item.armormaterial;
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 java.util.HashMap;
import java.util.Map;
public class ArmorMaterials {
/**
* This is named "equipment asset" in vanilla since 1.21.4,
* before this was also called "armor material" in vanilla.
*/
public final class ArmorMaterials {
private static final Map<String, ArmorMaterial> MATERIAL_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, ArmorMaterial>> MATERIAL_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_armor_material_mappings");
// this isn't great, but it works
private static final Map<String, String> DFU = new HashMap<>();
public static ArmorMaterial define(String key) {
TypesBuilderData data = TYPES_BUILDER.define(key);
ArmorMaterial instrument = new ArmorMaterial() {
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ArmorMaterial) {
return getName().equals(((ArmorMaterial) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, MATERIAL_MAP, MATERIAL_ID_MAP, instrument);
return instrument;
static {
DFU.put("turtle", "minecraft:turtle_scute");
DFU.put("minecraft:turtle", "minecraft:turtle_scute");
DFU.put("armadillo", "minecraft:armadillo_scute");
DFU.put("minecraft:armadillo", "minecraft:armadillo_scute");
}
private static final VersionedRegistry<ArmorMaterial> REGISTRY = new VersionedRegistry<>(
"equipment_asset", "item/equipment_asset_mappings");
private ArmorMaterials() {
}
private static ArmorMaterial define(String name) {
return REGISTRY.define(name, StaticArmorMaterial::new);
}
public static VersionedRegistry<ArmorMaterial> getRegistry() {
return REGISTRY;
}
// with key
public static ArmorMaterial getByName(String name) {
return MATERIAL_MAP.get(name);
return REGISTRY.getByName(DFU.getOrDefault(name, name));
}
public static ArmorMaterial getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, ArmorMaterial> idMap = MATERIAL_ID_MAP.get((byte) index);
return idMap.get(id);
return REGISTRY.getById(version, id);
}
public static final ArmorMaterial LEATHER = define("leather");
@@ -75,16 +68,105 @@ public class ArmorMaterials {
public static final ArmorMaterial GOLD = define("gold");
public static final ArmorMaterial DIAMOND = define("diamond");
// Added with 1.13
public static final ArmorMaterial TURTLE = define("turtle");
/**
* Renamed from {@link #TURTLE} in 1.21.4
*/
public static final ArmorMaterial TURTLE_SCUTE = define("turtle_scute");
/**
* Added with 1.13, renamed to {@link #TURTLE_SCUTE} in 1.21.4
*/
@Deprecated
public static final ArmorMaterial TURTLE = TURTLE_SCUTE;
// Added with 1.16
/**
* Added with 1.16
*/
public static final ArmorMaterial NETHERITE = define("netherite");
// Added with 1.20.5
public static final ArmorMaterial ARMADILLO = define("armadillo");
/**
* Renamed from {@link #ARMADILLO} in 1.21.4
*/
public static final ArmorMaterial ARMADILLO_SCUTE = define("armadillo_scute");
/**
* Added with 1.20.5, renamed to {@link #ARMADILLO_SCUTE} in 1.21.4
*/
@Deprecated
public static final ArmorMaterial ARMADILLO = ARMADILLO_SCUTE;
/**
* Added with 1.21.4
*/
public static final ArmorMaterial ELYTRA = define("elytra");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial WHITE_CARPET = define("white_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial ORANGE_CARPET = define("orange_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial MAGENTA_CARPET = define("magenta_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial LIGHT_BLUE_CARPET = define("light_blue_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial YELLOW_CARPET = define("yellow_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial LIME_CARPET = define("lime_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial PINK_CARPET = define("pink_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial GRAY_CARPET = define("gray_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial LIGHT_GRAY_CARPET = define("light_gray_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial CYAN_CARPET = define("cyan_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial PURPLE_CARPET = define("purple_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial BLUE_CARPET = define("blue_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial BROWN_CARPET = define("brown_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial GREEN_CARPET = define("green_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial RED_CARPET = define("red_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial BLACK_CARPET = define("black_carpet");
/**
* Added with 1.21.4
*/
public static final ArmorMaterial TRADER_LLAMA = define("trader_llama");
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,30 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.armormaterial;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
public class StaticArmorMaterial extends AbstractMappedEntity implements ArmorMaterial {
public StaticArmorMaterial(@Nullable TypesBuilderData data) {
super(data);
}
}
@@ -19,6 +19,7 @@
package com.github.retrooper.packetevents.protocol.item.banner;
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;
@@ -29,7 +30,7 @@ import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
public interface BannerPattern extends MappedEntity, CopyableEntity<BannerPattern> {
public interface BannerPattern extends MappedEntity, CopyableEntity<BannerPattern>, DeepComparableEntity {
ResourceLocation getAssetId();
@@ -55,6 +55,7 @@ public class StaticBannerPattern extends AbstractMappedEntity implements BannerP
return this.translationKey;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticBannerPattern)) return false;
@@ -64,6 +65,7 @@ public class StaticBannerPattern extends AbstractMappedEntity implements BannerP
return this.translationKey.equals(that.translationKey);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.assetId, this.translationKey);
}
@@ -0,0 +1,45 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public abstract class ConsumeEffect<T extends ConsumeEffect<?>> {
protected final ConsumeEffectType<T> type;
protected ConsumeEffect(ConsumeEffectType<T> type) {
this.type = type;
}
public static ConsumeEffect<?> readFull(PacketWrapper<?> wrapper) {
ConsumeEffectType<?> type = wrapper.readMappedEntity(ConsumeEffectTypes.getRegistry());
return type.read(wrapper);
}
@SuppressWarnings("unchecked") // I hate generics
public static <T extends ConsumeEffect<?>> void writeFull(PacketWrapper<?> wrapper, ConsumeEffect<T> effect) {
wrapper.writeMappedEntity(effect.getType());
((ConsumeEffectType<ConsumeEffect<?>>) effect.getType()).write(wrapper, effect);
}
public ConsumeEffectType<T> getType() {
return this.type;
}
}
@@ -0,0 +1,29 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface ConsumeEffectType<T extends ConsumeEffect<?>> extends MappedEntity {
T read(PacketWrapper<?> wrapper);
void write(PacketWrapper<?> wrapper, T effect);
}
@@ -0,0 +1,64 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables;
import com.github.retrooper.packetevents.protocol.item.consumables.builtin.ApplyEffectsConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.builtin.ClearAllEffectsConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.builtin.PlaySoundConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.builtin.RemoveEffectsConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.builtin.TeleportRandomlyConsumeEffect;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
import org.jetbrains.annotations.ApiStatus;
public final class ConsumeEffectTypes {
private static final VersionedRegistry<ConsumeEffectType<?>> REGISTRY = new VersionedRegistry<>(
"consume_effect_type", "item/consume_effect_type_mappings");
private ConsumeEffectTypes() {
}
@ApiStatus.Internal
public static <T extends ConsumeEffect<?>> ConsumeEffectType<T> define(
String name, Reader<T> reader, Writer<T> writer) {
return REGISTRY.define(name, data ->
new StaticConsumeEffectType<>(data, reader, writer));
}
public static final ConsumeEffectType<ApplyEffectsConsumeEffect> APPLY_EFFECTS = define(
"apply_effects", ApplyEffectsConsumeEffect::read, ApplyEffectsConsumeEffect::write);
public static final ConsumeEffectType<RemoveEffectsConsumeEffect> REMOVE_EFFECTS = define(
"remove_effects", RemoveEffectsConsumeEffect::read, RemoveEffectsConsumeEffect::write);
public static final ConsumeEffectType<ClearAllEffectsConsumeEffect> CLEAR_ALL_EFFECTS = define(
"clear_all_effects", ClearAllEffectsConsumeEffect::read, ClearAllEffectsConsumeEffect::write);
public static final ConsumeEffectType<TeleportRandomlyConsumeEffect> TELEPORT_RANDOMLY = define(
"teleport_randomly", TeleportRandomlyConsumeEffect::read, TeleportRandomlyConsumeEffect::write);
public static final ConsumeEffectType<PlaySoundConsumeEffect> PLAY_SOUND = define(
"play_sound", PlaySoundConsumeEffect::read, PlaySoundConsumeEffect::write);
public static VersionedRegistry<ConsumeEffectType<?>> getRegistry() {
return REGISTRY;
}
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,52 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
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.Nullable;
public class StaticConsumeEffectType<T extends ConsumeEffect<?>> extends AbstractMappedEntity implements ConsumeEffectType<T> {
private final Reader<T> reader;
private final Writer<T> writer;
public StaticConsumeEffectType(
@Nullable TypesBuilderData data,
Reader<T> reader,
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 effect) {
this.writer.accept(wrapper, effect);
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables.builtin;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffectTypes;
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
public class ApplyEffectsConsumeEffect extends ConsumeEffect<ApplyEffectsConsumeEffect> {
private final List<PotionEffect> effects;
private final float probability;
public ApplyEffectsConsumeEffect(List<PotionEffect> effects, float probability) {
super(ConsumeEffectTypes.APPLY_EFFECTS);
this.effects = effects;
this.probability = probability;
}
public static ApplyEffectsConsumeEffect read(PacketWrapper<?> wrapper) {
List<PotionEffect> effects = wrapper.readList(PotionEffect::read);
float probability = wrapper.readFloat();
return new ApplyEffectsConsumeEffect(effects, probability);
}
public static void write(PacketWrapper<?> wrapper, ApplyEffectsConsumeEffect effect) {
wrapper.writeList(effect.effects, PotionEffect::write);
wrapper.writeFloat(effect.probability);
}
public List<PotionEffect> getEffects() {
return this.effects;
}
public float getProbability() {
return this.probability;
}
}
@@ -0,0 +1,41 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables.builtin;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffectType;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffectTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class ClearAllEffectsConsumeEffect extends ConsumeEffect<ClearAllEffectsConsumeEffect> {
public static final ClearAllEffectsConsumeEffect INSTANCE = new ClearAllEffectsConsumeEffect();
private ClearAllEffectsConsumeEffect() {
super(ConsumeEffectTypes.CLEAR_ALL_EFFECTS);
}
public static ClearAllEffectsConsumeEffect read(PacketWrapper<?> ignoredWrapper) {
return INSTANCE;
}
public static void write(PacketWrapper<?> ignoredWrapper, ClearAllEffectsConsumeEffect ignoredEffect) {
// NO-OP
}
}
@@ -0,0 +1,47 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables.builtin;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffectTypes;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class PlaySoundConsumeEffect extends ConsumeEffect<PlaySoundConsumeEffect> {
private final Sound sound;
public PlaySoundConsumeEffect(Sound sound) {
super(ConsumeEffectTypes.PLAY_SOUND);
this.sound = sound;
}
public static PlaySoundConsumeEffect read(PacketWrapper<?> wrapper) {
Sound sound = Sound.read(wrapper);
return new PlaySoundConsumeEffect(sound);
}
public static void write(PacketWrapper<?> wrapper, PlaySoundConsumeEffect effect) {
Sound.write(wrapper, effect.sound);
}
public Sound getSound() {
return this.sound;
}
}
@@ -0,0 +1,49 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables.builtin;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffectTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.potion.PotionType;
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class RemoveEffectsConsumeEffect extends ConsumeEffect<RemoveEffectsConsumeEffect> {
private final MappedEntitySet<PotionType> effects;
public RemoveEffectsConsumeEffect(MappedEntitySet<PotionType> effects) {
super(ConsumeEffectTypes.REMOVE_EFFECTS);
this.effects = effects;
}
public static RemoveEffectsConsumeEffect read(PacketWrapper<?> wrapper) {
MappedEntitySet<PotionType> effects = MappedEntitySet.read(wrapper, PotionTypes::getById);
return new RemoveEffectsConsumeEffect(effects);
}
public static void write(PacketWrapper<?> wrapper, RemoveEffectsConsumeEffect effect) {
MappedEntitySet.write(wrapper, effect.effects);
}
public MappedEntitySet<PotionType> getEffects() {
return this.effects;
}
}
@@ -0,0 +1,46 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.consumables.builtin;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffect;
import com.github.retrooper.packetevents.protocol.item.consumables.ConsumeEffectTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class TeleportRandomlyConsumeEffect extends ConsumeEffect<TeleportRandomlyConsumeEffect> {
private final float diameter;
public TeleportRandomlyConsumeEffect(float diameter) {
super(ConsumeEffectTypes.TELEPORT_RANDOMLY);
this.diameter = diameter;
}
public static TeleportRandomlyConsumeEffect read(PacketWrapper<?> wrapper) {
float diameter = wrapper.readFloat();
return new TeleportRandomlyConsumeEffect(diameter);
}
public static void write(PacketWrapper<?> wrapper, TeleportRandomlyConsumeEffect effect) {
wrapper.writeFloat(effect.diameter);
}
public float getDiameter() {
return this.diameter;
}
}
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.component.IComponentMap;
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
import com.github.retrooper.packetevents.protocol.item.enchantment.EnchantmentDefinition;
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.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
@@ -35,7 +36,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public interface EnchantmentType extends MappedEntity, CopyableEntity<EnchantmentType> {
public interface EnchantmentType extends MappedEntity, CopyableEntity<EnchantmentType>, DeepComparableEntity {
Component getDescription();
@@ -84,6 +84,7 @@ public class StaticEnchantmentType extends AbstractMappedEntity implements Encha
return this.effects;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticEnchantmentType)) return false;
@@ -95,6 +96,7 @@ public class StaticEnchantmentType extends AbstractMappedEntity implements Encha
return this.effects.equals(that.effects);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.description, this.definition, this.exclusiveSet, this.effects);
}
@@ -18,27 +18,51 @@
package com.github.retrooper.packetevents.protocol.item.instrument;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
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.NBTFloat;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.util.MathUtil;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
public interface Instrument extends MappedEntity {
public interface Instrument extends MappedEntity, CopyableEntity<Instrument>, DeepComparableEntity {
Sound getSound();
int getUseDuration();
float getUseSeconds();
/**
* Use duration measured in ticks
*/
default int getUseDuration() {
return MathUtil.floor(this.getUseSeconds() * 20);
}
float getRange();
Component getDescription();
static Instrument read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntityOrDirect(Instruments::getById, Instrument::readDirect);
return wrapper.readMappedEntityOrDirect(Instruments.getRegistry(), Instrument::readDirect);
}
static Instrument readDirect(PacketWrapper<?> wrapper) {
Sound sound = Sound.read(wrapper);
int useDuration = wrapper.readVarInt();
float useSeconds = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)
? wrapper.readFloat() : wrapper.readVarInt() * 20f;
float range = wrapper.readFloat();
return new StaticInstrument(sound, useDuration, range);
Component description = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)
? wrapper.readComponent() : Component.empty();
return new StaticInstrument(sound, useSeconds, range, description);
}
static void write(PacketWrapper<?> wrapper, Instrument instrument) {
@@ -47,7 +71,32 @@ public interface Instrument extends MappedEntity {
static void writeDirect(PacketWrapper<?> wrapper, Instrument instrument) {
Sound.write(wrapper, instrument.getSound());
wrapper.writeVarInt(instrument.getUseDuration());
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
wrapper.writeFloat(instrument.getUseSeconds());
} else {
wrapper.writeVarInt(instrument.getUseDuration());
}
wrapper.writeFloat(instrument.getRange());
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
wrapper.writeComponent(instrument.getDescription());
}
}
static Instrument decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
Sound sound = Sound.decode(compound.getTagOrThrow("sound_event"), version);
float useSeconds = compound.getNumberTagOrThrow("use_duration").getAsFloat();
float range = compound.getNumberTagOrThrow("range").getAsFloat();
Component description = AdventureSerializer.fromNbt(compound.getTagOrThrow("description"));
return new StaticInstrument(data, sound, useSeconds, range, description);
}
static NBT encode(Instrument instrument, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("sound_event", Sound.encode(instrument.getSound(), version));
compound.setTag("use_duration", new NBTFloat(instrument.getUseSeconds()));
compound.setTag("range", new NBTFloat(instrument.getRange()));
compound.setTag("description", AdventureSerializer.toNbt(instrument.getDescription()));
return compound;
}
}
@@ -21,74 +21,40 @@ package com.github.retrooper.packetevents.protocol.item.instrument;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.protocol.sound.Sounds;
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 net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import java.util.HashMap;
import java.util.Map;
public final class Instruments {
public class Instruments {
private static final VersionedRegistry<Instrument> REGISTRY = new VersionedRegistry<>(
"instrument", "item/item_instrument_mappings");
private static final Map<String, Instrument> INSTRUMENT_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, Instrument>> INSTRUMENT_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_instrument_mappings");
private Instruments() {
}
public static Instrument define(String key, Sound sound) {
// vanilla defaults for goat horns
return define(key, sound, 140, 256f);
return define(key, sound, 20 * 7, 256f);
}
@ApiStatus.Internal
public static Instrument define(String key, Sound sound, int useDuration, float range) {
TypesBuilderData data = TYPES_BUILDER.define(key);
Instrument instrument = new Instrument() {
@Override
public Sound getSound() {
return sound;
}
@Override
public int getUseDuration() {
return useDuration;
}
@Override
public float getRange() {
return range;
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Instrument) {
return getName().equals(((Instrument) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, INSTRUMENT_MAP, INSTRUMENT_ID_MAP, instrument);
return instrument;
return REGISTRY.define(key, data -> new StaticInstrument(
data, sound, useDuration, range,
Component.translatable("instrument.minecraft." + key)));
}
public static VersionedRegistry<Instrument> getRegistry() {
return REGISTRY;
}
// with key
public static Instrument getByName(String name) {
return INSTRUMENT_MAP.get(name);
return REGISTRY.getByName(name);
}
public static Instrument getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, Instrument> idMap = INSTRUMENT_ID_MAP.get((byte) index);
return idMap.get(id);
return REGISTRY.getById(version, id);
}
public static final Instrument PONDER_GOAT_HORN = define("ponder_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_0);
@@ -101,6 +67,6 @@ public class Instruments {
public static final Instrument DREAM_GOAT_HORN = define("dream_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_7);
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
}
@@ -18,22 +18,41 @@
package com.github.retrooper.packetevents.protocol.item.instrument;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class StaticInstrument implements Instrument {
public class StaticInstrument extends AbstractMappedEntity implements Instrument {
private final Sound sound;
private final int useDuration;
private final float useSeconds;
private final float range;
private final Component description;
@Deprecated // useDuration changed from ticks to seconds in 1.21.2
public StaticInstrument(Sound sound, int useDuration, float range) {
this(sound, useDuration * 20f, range, Component.empty());
}
public StaticInstrument(Sound sound, float useSeconds, float range, Component description) {
this(null, sound, useSeconds, range, description);
}
public StaticInstrument(@Nullable TypesBuilderData data, Sound sound, float useSeconds, float range, Component description) {
super(data);
this.sound = sound;
this.useDuration = useDuration;
this.useSeconds = useSeconds;
this.range = range;
this.description = description;
}
@Override
public Instrument copy(@Nullable TypesBuilderData newData) {
return new StaticInstrument(newData, this.sound, this.useSeconds, this.range, this.description);
}
@Override
@@ -42,8 +61,8 @@ public class StaticInstrument implements Instrument {
}
@Override
public int getUseDuration() {
return this.useDuration;
public float getUseSeconds() {
return this.useSeconds;
}
@Override
@@ -52,32 +71,24 @@ public class StaticInstrument implements Instrument {
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
public Component getDescription() {
return this.description;
}
@Override
public int getId(ClientVersion version) {
throw new UnsupportedOperationException();
}
@Override
public boolean isRegistered() {
return false;
}
@Override
public boolean equals(Object obj) {
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticInstrument)) return false;
if (!super.equals(obj)) return false;
StaticInstrument that = (StaticInstrument) obj;
if (this.useDuration != that.useDuration) return false;
if (this.useSeconds != that.useSeconds) return false;
if (Float.compare(that.range, this.range) != 0) return false;
return this.sound.equals(that.sound);
if (!this.sound.equals(that.sound)) return false;
return this.description.equals(that.description);
}
@Override
public int hashCode() {
return Objects.hash(this.sound, this.useDuration, this.range);
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.sound, this.useSeconds, this.range, this.description);
}
}
@@ -19,6 +19,7 @@
package com.github.retrooper.packetevents.protocol.item.jukebox;
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;
@@ -32,7 +33,8 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
public interface IJukeboxSong extends MappedEntity, CopyableEntity<IJukeboxSong> {
public interface IJukeboxSong extends MappedEntity, CopyableEntity<IJukeboxSong>, DeepComparableEntity {
Sound getSound();
Component getDescription();
@@ -101,6 +101,7 @@ public class JukeboxSong extends AbstractMappedEntity implements IJukeboxSong {
this.comparatorOutput = comparatorOutput;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof JukeboxSong)) return false;
@@ -112,6 +113,7 @@ public class JukeboxSong extends AbstractMappedEntity implements IJukeboxSong {
return this.description.equals(that.description);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.sound, this.description, this.lengthInSeconds, this.comparatorOutput);
}
@@ -20,24 +20,17 @@ package com.github.retrooper.packetevents.protocol.item.mapdecoration;
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 org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static com.github.retrooper.packetevents.resources.ResourceLocation.minecraft;
public class MapDecorationTypes {
private static final Map<String, MapDecorationType> DECORATION_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, MapDecorationType>> DECORATION_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_map_decoration_type_mappings");
private static final VersionedRegistry<MapDecorationType> REGISTRY =
new VersionedRegistry<>("map_decoration_type", "item/item_map_decoration_type_mappings");
public static MapDecorationType define(String key, boolean showOnItemFrame, boolean trackCount) {
return define(key, minecraft(key), showOnItemFrame, trackCount);
@@ -65,8 +58,7 @@ public class MapDecorationTypes {
boolean showOnItemFrame, int mapColor,
boolean explorationMapElement, boolean trackCount
) {
TypesBuilderData data = TYPES_BUILDER.define(key);
MapDecorationType potionType = new MapDecorationType() {
return REGISTRY.define(key, data -> new MapDecorationType() {
@Override
public ResourceLocation getAssetId() {
return assetId;
@@ -99,7 +91,7 @@ public class MapDecorationTypes {
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
return data.getId(version);
}
@Override
@@ -109,23 +101,19 @@ public class MapDecorationTypes {
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, DECORATION_TYPE_MAP, DECORATION_TYPE_ID_MAP, potionType);
return potionType;
});
}
public static @Nullable MapDecorationType getByName(String name) {
return DECORATION_TYPE_MAP.get(name);
return REGISTRY.getByName(name);
}
public static @Nullable MapDecorationType getById(int id, ClientVersion version) {
return getById(version, id);
return REGISTRY.getById(version, id);
}
public static @Nullable MapDecorationType getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, MapDecorationType> idMap = DECORATION_TYPE_ID_MAP.get((byte) index);
return idMap.get(id);
return REGISTRY.getById(version, id);
}
// color constants used by vanilla
@@ -209,13 +197,14 @@ public class MapDecorationTypes {
/**
* Returns an immutable view of the map decoration types.
*
* @return Map Decoration Types
*/
public static Collection<MapDecorationType> values() {
return Collections.unmodifiableCollection(DECORATION_TYPE_MAP.values());
return REGISTRY.getEntries();
}
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
}
@@ -36,6 +36,21 @@ public class StaticTrimMaterial extends AbstractMappedEntity implements TrimMate
private final Map<ArmorMaterial, String> overrideArmorMaterials;
private final Component description;
public StaticTrimMaterial(
String assetName, ItemType ingredient,
Map<ArmorMaterial, String> overrideArmorMaterials, Component description
) {
this(null, assetName, ingredient, FALLBACK_ITEM_MODEL_INDEX, overrideArmorMaterials, description);
}
public StaticTrimMaterial(
@Nullable TypesBuilderData data,
String assetName, ItemType ingredient,
Map<ArmorMaterial, String> overrideArmorMaterials, Component description
) {
this(data, assetName, ingredient, FALLBACK_ITEM_MODEL_INDEX, overrideArmorMaterials, description);
}
public StaticTrimMaterial(
String assetName, ItemType ingredient, float itemModelIndex,
Map<ArmorMaterial, String> overrideArmorMaterials, Component description
@@ -87,6 +102,7 @@ public class StaticTrimMaterial extends AbstractMappedEntity implements TrimMate
return this.description;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticTrimMaterial)) return false;
@@ -99,6 +115,7 @@ public class StaticTrimMaterial extends AbstractMappedEntity implements TrimMate
return this.description.equals(that.description);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.assetName, this.ingredient, this.itemModelIndex, this.overrideArmorMaterials, this.description);
}
@@ -18,11 +18,13 @@
package com.github.retrooper.packetevents.protocol.item.trimmaterial;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMaterial;
import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMaterials;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
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;
@@ -33,18 +35,25 @@ import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public interface TrimMaterial extends MappedEntity, CopyableEntity<TrimMaterial> {
public interface TrimMaterial extends MappedEntity, CopyableEntity<TrimMaterial>, DeepComparableEntity {
float FALLBACK_ITEM_MODEL_INDEX = 0f;
String getAssetName();
ItemType getIngredient();
/**
* Removed in 1.21.4
*/
@ApiStatus.Obsolete
float getItemModelIndex();
default @Nullable String getArmorMaterialOverride(ArmorMaterial armorMaterial) {
@@ -62,7 +71,8 @@ public interface TrimMaterial extends MappedEntity, CopyableEntity<TrimMaterial>
static TrimMaterial readDirect(PacketWrapper<?> wrapper) {
String assetName = wrapper.readString();
ItemType ingredient = wrapper.readMappedEntity(ItemTypes::getById);
float itemModelIndex = wrapper.readFloat();
float itemModelIndex = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_4)
? FALLBACK_ITEM_MODEL_INDEX : wrapper.readFloat();
Map<ArmorMaterial, String> overrideArmorMaterials = wrapper.readMap(
ew -> ew.readMappedEntity(ArmorMaterials::getById),
PacketWrapper::readString);
@@ -77,7 +87,9 @@ public interface TrimMaterial extends MappedEntity, CopyableEntity<TrimMaterial>
static void writeDirect(PacketWrapper<?> wrapper, TrimMaterial material) {
wrapper.writeString(material.getAssetName());
wrapper.writeMappedEntity(material.getIngredient());
wrapper.writeFloat(material.getItemModelIndex());
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_4)) {
wrapper.writeFloat(material.getItemModelIndex());
}
wrapper.writeMap(material.getOverrideArmorMaterials(),
PacketWrapper::writeMappedEntity, PacketWrapper::writeString);
wrapper.writeComponent(material.getDescription());
@@ -87,7 +99,8 @@ public interface TrimMaterial extends MappedEntity, CopyableEntity<TrimMaterial>
NBTCompound compound = (NBTCompound) nbt;
String assetName = compound.getStringTagValueOrThrow("asset_name");
ItemType ingredient = ItemTypes.getByName(compound.getStringTagValueOrThrow("ingredient"));
float itemModelIndex = compound.getNumberTagOrThrow("item_model_index").getAsFloat();
float itemModelIndex = version.isNewerThanOrEquals(ClientVersion.V_1_21_4)
? FALLBACK_ITEM_MODEL_INDEX : compound.getNumberTagOrThrow("item_model_index").getAsFloat();
NBTCompound overrideArmorMaterialsTag = compound.getCompoundTagOrNull("override_armor_materials");
Map<ArmorMaterial, String> overrideArmorMaterials;
if (overrideArmorMaterialsTag != null) {
@@ -120,7 +133,9 @@ public interface TrimMaterial extends MappedEntity, CopyableEntity<TrimMaterial>
NBTCompound compound = new NBTCompound();
compound.setTag("asset_name", new NBTString(material.getAssetName()));
compound.setTag("ingredient", new NBTString(material.getIngredient().getName().toString()));
compound.setTag("item_model_index", new NBTFloat(material.getItemModelIndex()));
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_4)) {
compound.setTag("item_model_index", new NBTFloat(material.getItemModelIndex()));
}
if (overrideArmorMaterialsTag != null) {
compound.setTag("override_armor_materials", overrideArmorMaterialsTag);
}
@@ -90,6 +90,9 @@ public final class TrimMaterials {
public static final TrimMaterial QUARTZ = define("quartz", ItemTypes.QUARTZ, 0.1f, 0xE3D4C4);
public static final TrimMaterial REDSTONE = define("redstone", ItemTypes.REDSTONE, 0.4f, 0x971607);
// added with 1.21.4
public static final TrimMaterial RESIN = define("resin", ItemTypes.RESIN_BRICK, 0.11f, 0xFC7812);
/**
* Returns an immutable view of the trim materials.
*
@@ -79,6 +79,7 @@ public class StaticTrimPattern extends AbstractMappedEntity implements TrimPatte
return this.decal;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticTrimPattern)) return false;
@@ -90,6 +91,7 @@ public class StaticTrimPattern extends AbstractMappedEntity implements TrimPatte
return this.description.equals(that.description);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.assetId, this.templateItem, this.description, this.decal);
}
@@ -21,6 +21,7 @@ package com.github.retrooper.packetevents.protocol.item.trimpattern;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
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.NBTByte;
@@ -34,7 +35,7 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
public interface TrimPattern extends MappedEntity, CopyableEntity<TrimPattern> {
public interface TrimPattern extends MappedEntity, CopyableEntity<TrimPattern>, DeepComparableEntity {
ResourceLocation getAssetId();
@@ -18,30 +18,42 @@
package com.github.retrooper.packetevents.protocol.item.type;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes.ItemAttribute;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public interface ItemType extends MappedEntity {
int getMaxAmount();
int getMaxDurability();
boolean isMusicDisc();
default boolean isMusicDisc() {
return this.hasAttribute(ItemAttribute.MUSIC_DISC);
}
ItemType getCraftRemainder();
@Nullable
StateType getPlacedType();
Set<ItemTypes.ItemAttribute> getAttributes();
Set<ItemAttribute> getAttributes();
boolean hasAttribute(ItemTypes.ItemAttribute attribute);
default boolean hasAttribute(ItemAttribute attribute) {
return this.getAttributes().contains(attribute);
}
default StaticComponentMap getComponents() {
return this.getComponents(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
}
default StaticComponentMap getComponents(ClientVersion clientVersion) {
return StaticComponentMap.EMPTY;
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,136 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.item.type;
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes.ItemAttribute;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import java.util.EnumMap;
import java.util.Map;
import java.util.Set;
public class StaticItemType extends AbstractMappedEntity implements ItemType {
private final int maxAmount;
private final int maxDurability;
private final ItemType craftRemainder;
private final @Nullable StateType placedType;
private final Set<ItemAttribute> attributes;
private final Map<ClientVersion, StaticComponentMap> components;
StaticItemType(
TypesBuilderData data,
int maxAmount,
int maxDurability,
ItemType craftRemainder,
@Nullable StateType placedType,
Set<ItemAttribute> attributes
) {
super(data);
this.maxAmount = maxAmount;
this.maxDurability = maxDurability;
this.craftRemainder = craftRemainder;
this.placedType = placedType;
this.attributes = attributes;
this.components = new EnumMap<>(ClientVersion.class);
}
@Override
public int getMaxAmount() {
return this.maxAmount;
}
@Override
public int getMaxDurability() {
return this.maxDurability;
}
@Override
public ItemType getCraftRemainder() {
return this.craftRemainder;
}
@Override
public @Nullable StateType getPlacedType() {
return this.placedType;
}
@Override
public Set<ItemAttribute> getAttributes() {
return this.attributes;
}
@Override
public StaticComponentMap getComponents(ClientVersion version) {
if (!version.isRelease()) {
throw new IllegalArgumentException("Unsupported version for "
+ "getting components of " + this.getName() + ": " + version);
}
return this.components.getOrDefault(version, StaticComponentMap.SHARED_ITEM_COMPONENTS);
}
void setComponents(ClientVersion version, StaticComponentMap components) {
if (this.components.containsKey(version)) {
throw new IllegalStateException("Components are already defined for "
+ this.getName() + " in version " + version);
} else if (!version.isRelease()) {
throw new IllegalArgumentException("Unsupported version for "
+ "setting components of " + this.getName() + ": " + version);
}
this.components.put(version, components);
}
// internal, only used for checking wether
// component definition is present during startup
boolean hasComponents(ClientVersion version) {
return this.components.containsKey(version);
}
// fills holes in the base component mappings
void fillComponents() {
StaticComponentMap lastComponents = null;
for (ClientVersion version : ClientVersion.values()) {
if (!version.isRelease()) {
continue;
}
StaticComponentMap components = this.components.get(version);
if (components == null) {
if (lastComponents != null) {
this.components.put(version, lastComponents);
}
continue;
}
if (lastComponents == null) {
// also fill backwards
for (ClientVersion beforeVersion : ClientVersion.values()) {
if (beforeVersion == version) {
break;
}
this.components.put(beforeVersion, components);
}
}
lastComponents = components;
}
}
}
@@ -76,4 +76,9 @@ public abstract class AbstractMappedEntity implements MappedEntity {
}
return super.hashCode();
}
@Override
public String toString() {
return this.getClass().getSimpleName() + "[" + (this.data == null ? this.hashCode() : this.data.getName()) + ']';
}
}
@@ -0,0 +1,26 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.mapper;
public interface DeepComparableEntity {
boolean deepEquals(Object obj);
int deepHashCode();
}
@@ -207,7 +207,7 @@ public class NBTCompound extends NBT {
}
public boolean getBoolean(String string) {
NBTByte nbtByte = this.getTagOfTypeOrNull(string, NBTByte.class);
NBTNumber nbtByte = this.getTagOfTypeOrNull(string, NBTNumber.class);
// Empty byte tags are considered 0
return nbtByte != null && nbtByte.getAsByte() != 0;
}
@@ -40,6 +40,7 @@ public class NPC {
private NamedTextColor nameColor;
private Component prefixName;
private Component suffixName;
private String teamName;
private int displayPing = 0;
private Location location = new Location(0.0, 0.0, 0.0, 0.0f, 0.0f);
private ItemStack mainHand = null;
@@ -60,6 +61,7 @@ public class NPC {
this.nameColor = nameColor;
this.prefixName = prefixName;
this.suffixName = suffixName;
this.teamName = "npc-" + id;
}
public NPC(UserProfile profile, int entityId, @Nullable Component tabName) {
@@ -273,7 +275,7 @@ public class NPC {
for (Object channel : channels) {
//Destroy team
WrapperPlayServerTeams removeTeam =
new WrapperPlayServerTeams("custom_name_team",
new WrapperPlayServerTeams(teamName,
WrapperPlayServerTeams.TeamMode.REMOVE,
Optional.empty());
PacketEvents.getAPI().getProtocolManager().sendPacket(channel, removeTeam);
@@ -410,6 +412,16 @@ public class NPC {
this.suffixName = nameSuffix;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_18)) {
this.teamName = teamName.substring(0, 16);
} else this.teamName = teamName;
}
@Nullable
public Component getTabName() {
return tabName;
@@ -436,11 +448,11 @@ public class NPC {
}
private WrapperPlayServerTeams generateTeamsData() {
return new WrapperPlayServerTeams("custom_name_team",
return new WrapperPlayServerTeams(teamName,
WrapperPlayServerTeams.TeamMode.CREATE,
Optional.of(
new WrapperPlayServerTeams.ScoreBoardTeamInfo(
Component.text("custom_name_team"),
Component.text(teamName),
prefixName,
suffixName,
WrapperPlayServerTeams.NameTagVisibility.ALWAYS,
@@ -39,6 +39,7 @@ import com.github.retrooper.packetevents.protocol.packettype.clientbound.Clientb
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_20_3;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_20_5;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_21;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_21_2;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_7_10;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_8;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_9;
@@ -64,11 +65,14 @@ import com.github.retrooper.packetevents.protocol.packettype.serverbound.Serverb
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_20_2;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_20_3;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_20_5;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_21_2;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_21_4;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_7_10;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_8;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_9;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.VersionMapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
@@ -103,7 +107,8 @@ public final class PacketType {
ClientVersion.V_1_20_2,
ClientVersion.V_1_20_3,
ClientVersion.V_1_20_5,
ClientVersion.V_1_21);
ClientVersion.V_1_21,
ClientVersion.V_1_21_2);
//TODO UPDATE Update packet type mappings (serverbound pt. 1)
private static final VersionMapper SERVERBOUND_PLAY_VERSION_MAPPER = new VersionMapper(
@@ -124,7 +129,9 @@ public final class PacketType {
ClientVersion.V_1_19_4,
ClientVersion.V_1_20_2,
ClientVersion.V_1_20_3,
ClientVersion.V_1_20_5);
ClientVersion.V_1_20_5,
ClientVersion.V_1_21_2,
ClientVersion.V_1_21_4);
// TODO UPDATE Update packet type mappings (config clientbound pt. 1)
private static final VersionMapper CLIENTBOUND_CONFIG_VERSION_MAPPER = new VersionMapper(
@@ -617,11 +624,19 @@ public final class PacketType {
PLAYER_FLYING,
VEHICLE_MOVE,
STEER_BOAT,
/**
* Removed with 1.21.4
*/
@ApiStatus.Obsolete
PICK_ITEM,
CRAFT_RECIPE_REQUEST,
PLAYER_ABILITIES,
PLAYER_DIGGING,
ENTITY_ACTION,
/**
* Removed with 1.21.2
*/
@ApiStatus.Obsolete
STEER_VEHICLE,
PONG,
RECIPE_BOOK_DATA,
@@ -644,27 +659,78 @@ public final class PacketType {
PLAYER_BLOCK_PLACEMENT,
USE_ITEM,
// Added in 1.19
/**
* Added with 1.19
*/
CHAT_COMMAND,
// Added in 1.19.1
/**
* Added with 1.19.1
*/
CHAT_ACK,
// Added in 1.19.3
/**
* Added with 1.19.3
*/
CHAT_SESSION_UPDATE,
// Added in 1.20.2
/**
* Added with 1.20.2
*/
CHUNK_BATCH_ACK,
/**
* Added with 1.20.2
*/
CONFIGURATION_ACK,
/**
* Added with 1.20.2
*/
DEBUG_PING,
// Added in 1.20.3
/**
* Added with 1.20.3
*/
SLOT_STATE_CHANGE,
// Added in 1.20.5
/**
* Added with 1.20.5
*/
CHAT_COMMAND_UNSIGNED,
/**
* Added with 1.20.5
*/
COOKIE_RESPONSE,
DEBUG_SAMPLE_SUBSCRIPTION;
/**
* Added with 1.20.5
*/
DEBUG_SAMPLE_SUBSCRIPTION,
/**
* Added with 1.21.2
*/
CLIENT_TICK_END,
/**
* Added with 1.21.2
*/
SELECT_BUNDLE_ITEM,
/**
* Added with 1.21.2, based on {@link #STEER_VEHICLE}
*/
PLAYER_INPUT,
/**
* Added with 1.21.4
*/
PICK_ITEM_FROM_BLOCK,
/**
* Added with 1.21.4
*/
PICK_ITEM_FROM_ENTITY,
/**
* Added with 1.21.4
*/
PLAYER_LOADED,
;
private static int INDEX = 0;
private static final Map<Byte, Map<Integer, PacketTypeCommon>> PACKET_TYPE_ID_MAP = new HashMap<>();
@@ -718,6 +784,8 @@ public final class PacketType {
loadPacketIds(ServerboundPacketType_1_20_2.values());
loadPacketIds(ServerboundPacketType_1_20_3.values());
loadPacketIds(ServerboundPacketType_1_20_5.values());
loadPacketIds(ServerboundPacketType_1_21_2.values());
loadPacketIds(ServerboundPacketType_1_21_4.values());
//TODO UPDATE Update packet type mappings (serverbound pt. 2)
}
@@ -812,7 +880,7 @@ public final class PacketType {
DEATH_COMBAT_EVENT,
FACE_PLAYER,
PLAYER_POSITION_AND_LOOK,
UNLOCK_RECIPES,
UNLOCK_RECIPES, // removed in 1.21.2
DESTROY_ENTITIES,
REMOVE_ENTITY_EFFECT,
RESOURCE_PACK_SEND,
@@ -901,7 +969,18 @@ public final class PacketType {
// added in 1.21
CUSTOM_REPORT_DETAILS,
SERVER_LINKS;
SERVER_LINKS,
// added in 1.21.2
MOVE_MINECART,
SET_CURSOR_ITEM,
SET_PLAYER_INVENTORY,
ENTITY_POSITION_SYNC,
PLAYER_ROTATION,
RECIPE_BOOK_ADD,
RECIPE_BOOK_REMOVE,
RECIPE_BOOK_SETTINGS,
;
private static int INDEX = 0;
private static final Map<Byte, Map<Integer, PacketTypeCommon>> PACKET_TYPE_ID_MAP = new HashMap<>();
@@ -972,6 +1051,7 @@ public final class PacketType {
loadPacketIds(ClientboundPacketType_1_20_3.values());
loadPacketIds(ClientboundPacketType_1_20_5.values());
loadPacketIds(ClientboundPacketType_1_21.values());
loadPacketIds(ClientboundPacketType_1_21_2.values());
//TODO UPDATE Update packet type mappings (clientbound pt. 2)
}
}
@@ -0,0 +1,154 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.packettype.clientbound;
public enum ClientboundPacketType_1_21_2 {
BUNDLE,
SPAWN_ENTITY,
SPAWN_EXPERIENCE_ORB,
ENTITY_ANIMATION,
STATISTICS,
ACKNOWLEDGE_BLOCK_CHANGES,
BLOCK_BREAK_ANIMATION,
BLOCK_ENTITY_DATA,
BLOCK_ACTION,
BLOCK_CHANGE,
BOSS_BAR,
SERVER_DIFFICULTY,
CHUNK_BATCH_END,
CHUNK_BATCH_BEGIN,
CHUNK_BIOMES,
CLEAR_TITLES,
TAB_COMPLETE,
DECLARE_COMMANDS,
CLOSE_WINDOW,
WINDOW_ITEMS,
WINDOW_PROPERTY,
SET_SLOT,
COOKIE_REQUEST,
SET_COOLDOWN,
CUSTOM_CHAT_COMPLETIONS,
PLUGIN_MESSAGE,
DAMAGE_EVENT,
DEBUG_SAMPLE,
DELETE_CHAT,
DISCONNECT,
DISGUISED_CHAT,
ENTITY_STATUS,
ENTITY_POSITION_SYNC, // new packet
EXPLOSION,
UNLOAD_CHUNK,
CHANGE_GAME_STATE,
OPEN_HORSE_WINDOW,
HURT_ANIMATION,
INITIALIZE_WORLD_BORDER,
KEEP_ALIVE,
CHUNK_DATA,
EFFECT,
PARTICLE,
UPDATE_LIGHT,
JOIN_GAME,
MAP_DATA,
MERCHANT_OFFERS,
ENTITY_RELATIVE_MOVE,
ENTITY_RELATIVE_MOVE_AND_ROTATION,
MOVE_MINECART, // new packet
ENTITY_ROTATION,
VEHICLE_MOVE,
OPEN_BOOK,
OPEN_WINDOW,
OPEN_SIGN_EDITOR,
PING,
DEBUG_PONG,
CRAFT_RECIPE_RESPONSE,
PLAYER_ABILITIES,
CHAT_MESSAGE,
END_COMBAT_EVENT,
ENTER_COMBAT_EVENT,
DEATH_COMBAT_EVENT,
PLAYER_INFO_REMOVE,
PLAYER_INFO_UPDATE,
FACE_PLAYER,
PLAYER_POSITION_AND_LOOK,
PLAYER_ROTATION, // new packet
RECIPE_BOOK_ADD, // new packet
RECIPE_BOOK_REMOVE, // new packet
RECIPE_BOOK_SETTINGS, // new packet
DESTROY_ENTITIES,
REMOVE_ENTITY_EFFECT,
RESET_SCORE,
RESOURCE_PACK_REMOVE,
RESOURCE_PACK_SEND,
RESPAWN,
ENTITY_HEAD_LOOK,
MULTI_BLOCK_CHANGE,
SELECT_ADVANCEMENTS_TAB,
SERVER_DATA,
ACTION_BAR,
WORLD_BORDER_CENTER,
WORLD_BORDER_LERP_SIZE,
WORLD_BORDER_SIZE,
WORLD_BORDER_WARNING_DELAY,
WORLD_BORDER_WARNING_REACH,
CAMERA,
UPDATE_VIEW_POSITION,
UPDATE_VIEW_DISTANCE,
SET_CURSOR_ITEM, // new packet
SPAWN_POSITION,
DISPLAY_SCOREBOARD,
ENTITY_METADATA,
ATTACH_ENTITY,
ENTITY_VELOCITY,
ENTITY_EQUIPMENT,
SET_EXPERIENCE,
UPDATE_HEALTH,
HELD_ITEM_CHANGE, // moved 0x53 -> 0x63
SCOREBOARD_OBJECTIVE,
SET_PASSENGERS,
SET_PLAYER_INVENTORY, // new packet
TEAMS,
UPDATE_SCORE,
UPDATE_SIMULATION_DISTANCE,
SET_TITLE_SUBTITLE,
TIME_UPDATE,
SET_TITLE_TEXT,
SET_TITLE_TIMES,
ENTITY_SOUND_EFFECT,
SOUND_EFFECT,
CONFIGURATION_START,
STOP_SOUND,
STORE_COOKIE,
SYSTEM_CHAT_MESSAGE,
PLAYER_LIST_HEADER_AND_FOOTER,
NBT_QUERY_RESPONSE,
COLLECT_ITEM,
ENTITY_TELEPORT,
TICKING_STATE,
TICKING_STEP,
TRANSFER,
UPDATE_ADVANCEMENTS,
UPDATE_ATTRIBUTES,
ENTITY_EFFECT,
DECLARE_RECIPES,
TAGS,
PROJECTILE_POWER,
CUSTOM_REPORT_DETAILS,
SERVER_LINKS,
}
@@ -0,0 +1,83 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.packettype.serverbound;
public enum ServerboundPacketType_1_21_2 {
TELEPORT_CONFIRM,
QUERY_BLOCK_NBT,
SELECT_BUNDLE_ITEM, // new packet
SET_DIFFICULTY,
CHAT_ACK,
CHAT_COMMAND_UNSIGNED,
CHAT_COMMAND,
CHAT_MESSAGE,
CHAT_SESSION_UPDATE,
CHUNK_BATCH_ACK,
CLIENT_STATUS,
CLIENT_TICK_END, // new packet
CLIENT_SETTINGS,
TAB_COMPLETE,
CONFIGURATION_ACK,
CLICK_WINDOW_BUTTON,
CLICK_WINDOW,
CLOSE_WINDOW,
SLOT_STATE_CHANGE,
COOKIE_RESPONSE,
PLUGIN_MESSAGE,
DEBUG_SAMPLE_SUBSCRIPTION,
EDIT_BOOK,
QUERY_ENTITY_NBT,
INTERACT_ENTITY,
GENERATE_STRUCTURE,
KEEP_ALIVE,
LOCK_DIFFICULTY,
PLAYER_POSITION,
PLAYER_POSITION_AND_ROTATION,
PLAYER_ROTATION,
PLAYER_FLYING,
VEHICLE_MOVE,
STEER_BOAT,
PICK_ITEM,
DEBUG_PING,
CRAFT_RECIPE_REQUEST,
PLAYER_ABILITIES,
PLAYER_DIGGING,
ENTITY_ACTION,
PLAYER_INPUT, // based on STEER_VEHICLE
PONG,
SET_RECIPE_BOOK_STATE,
SET_DISPLAYED_RECIPE,
NAME_ITEM,
RESOURCE_PACK_STATUS,
ADVANCEMENT_TAB,
SELECT_TRADE,
SET_BEACON_EFFECT,
HELD_ITEM_CHANGE,
UPDATE_COMMAND_BLOCK,
UPDATE_COMMAND_BLOCK_MINECART,
CREATIVE_INVENTORY_ACTION,
UPDATE_JIGSAW_BLOCK,
UPDATE_STRUCTURE_BLOCK,
UPDATE_SIGN,
ANIMATION,
SPECTATE,
PLAYER_BLOCK_PLACEMENT,
USE_ITEM,
}
@@ -0,0 +1,85 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.packettype.serverbound;
public enum ServerboundPacketType_1_21_4 {
TELEPORT_CONFIRM,
QUERY_BLOCK_NBT,
SELECT_BUNDLE_ITEM,
SET_DIFFICULTY,
CHAT_ACK,
CHAT_COMMAND_UNSIGNED,
CHAT_COMMAND,
CHAT_MESSAGE,
CHAT_SESSION_UPDATE,
CHUNK_BATCH_ACK,
CLIENT_STATUS,
CLIENT_TICK_END,
CLIENT_SETTINGS,
TAB_COMPLETE,
CONFIGURATION_ACK,
CLICK_WINDOW_BUTTON,
CLICK_WINDOW,
CLOSE_WINDOW,
SLOT_STATE_CHANGE,
COOKIE_RESPONSE,
PLUGIN_MESSAGE,
DEBUG_SAMPLE_SUBSCRIPTION,
EDIT_BOOK,
QUERY_ENTITY_NBT,
INTERACT_ENTITY,
GENERATE_STRUCTURE,
KEEP_ALIVE,
LOCK_DIFFICULTY,
PLAYER_POSITION,
PLAYER_POSITION_AND_ROTATION,
PLAYER_ROTATION,
PLAYER_FLYING,
VEHICLE_MOVE,
STEER_BOAT,
PICK_ITEM_FROM_BLOCK, // new packet
PICK_ITEM_FROM_ENTITY, // new packet
DEBUG_PING,
CRAFT_RECIPE_REQUEST,
PLAYER_ABILITIES,
PLAYER_DIGGING,
ENTITY_ACTION,
PLAYER_INPUT,
PLAYER_LOADED, // new packet
PONG,
SET_RECIPE_BOOK_STATE,
SET_DISPLAYED_RECIPE,
NAME_ITEM,
RESOURCE_PACK_STATUS,
ADVANCEMENT_TAB,
SELECT_TRADE,
SET_BEACON_EFFECT,
HELD_ITEM_CHANGE,
UPDATE_COMMAND_BLOCK,
UPDATE_COMMAND_BLOCK_MINECART,
CREATIVE_INVENTORY_ACTION,
UPDATE_JIGSAW_BLOCK,
UPDATE_STRUCTURE_BLOCK,
UPDATE_SIGN,
ANIMATION,
SPECTATE,
PLAYER_BLOCK_PLACEMENT,
USE_ITEM,
}
@@ -19,21 +19,21 @@
package com.github.retrooper.packetevents.protocol.particle.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.color.AlphaColor;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import static com.github.retrooper.packetevents.protocol.particle.data.ParticleDustData.decodeColor;
import static com.github.retrooper.packetevents.util.MathUtil.floor;
public class ParticleColorData extends ParticleData {
private int color;
private AlphaColor color;
public ParticleColorData(int color) {
this(new AlphaColor(color));
}
public ParticleColorData(AlphaColor color) {
this.color = color;
}
@@ -44,42 +44,37 @@ public class ParticleColorData extends ParticleData {
public static void write(PacketWrapper<?> wrapper, ParticleColorData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_20_5)) {
wrapper.writeInt(data.color);
wrapper.writeInt(data.color.asRGB());
}
}
public static ParticleColorData decode(NBTCompound compound, ClientVersion version) {
int argb;
AlphaColor argb;
if (version.isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
NBT colorTag = compound.getTagOrThrow("color");
if (colorTag instanceof NBTNumber) {
argb = ((NBTNumber) colorTag).getAsInt();
} else {
float[] color = decodeColor(colorTag);
assert color.length == 4; // required by vanilla protocol
argb = (floor(color[0] * 255f) << 24)
| (floor(color[1] * 255f) << 16)
| (floor(color[2] * 255f) << 8)
| floor(color[3] * 255f);
}
argb = AlphaColor.decode(colorTag, version);
} else {
// no data to decode for <1.20.5
argb = 0xFFFFFFFF;
argb = AlphaColor.WHITE;
}
return new ParticleColorData(argb);
}
public static void encode(ParticleColorData data, ClientVersion version, NBTCompound compound) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
compound.setTag("color", new NBTInt(data.color));
compound.setTag("color", AlphaColor.encode(data.color, version));
}
}
public int getColor() {
return this.color;
return this.color.asRGB();
}
public void setColor(int color) {
this.color = new AlphaColor(color);
}
public void setAlphaColor(AlphaColor color) {
this.color = color;
}
@@ -26,130 +26,84 @@ import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import static com.github.retrooper.packetevents.protocol.particle.data.ParticleDustData.decodeColor;
import static com.github.retrooper.packetevents.protocol.particle.data.ParticleDustData.encodeColor;
public class ParticleDustColorTransitionData extends ParticleData {
//0.01 - 4
private float scale;
private Color start;
private Color end;
//0-1
private float startRed;
private float startGreen;
private float startBlue;
//0-1
private float endRed;
private float endGreen;
private float endBlue;
public ParticleDustColorTransitionData(float scale, float startRed, float startGreen,
float startBlue, float endRed, float endGreen,
float endBlue) {
this.scale = scale;
this.startRed = startRed;
this.startGreen = startGreen;
this.startBlue = startBlue;
this.endRed = endRed;
this.endGreen = endGreen;
this.endBlue = endBlue;
public ParticleDustColorTransitionData(
float scale,
float startRed, float startGreen, float startBlue,
float endRed, float endGreen, float endBlue
) {
this(scale, new Color(startRed, startGreen, startBlue),
new Color(endRed, endGreen, endBlue));
}
public ParticleDustColorTransitionData(float scale, float[] startRGB, float[] endRGB) {
this(scale, startRGB[0], startRGB[1], startRGB[2], endRGB[0], endRGB[1], endRGB[2]);
this(scale, startRGB[0], startRGB[1], startRGB[2],
endRGB[0], endRGB[1], endRGB[2]);
}
public ParticleDustColorTransitionData(float scale, Vector3f startRGB, Vector3f endRGB) {
this(scale, startRGB.getX(), startRGB.getY(), startRGB.getZ(), endRGB.getX(), endRGB.getY(), endRGB.getZ());
this(scale, startRGB.getX(), startRGB.getY(), startRGB.getZ(),
endRGB.getX(), endRGB.getY(), endRGB.getZ());
}
public ParticleDustColorTransitionData(float scale, Color start, Color end) {
this(scale, start.red() / 255f, start.green() / 255f, start.blue() / 255f, end.red() / 255f, end.green() / 255f, end.blue() / 255f);
}
public float getScale() {
return scale;
}
public void setScale(float scale) {
this.scale = scale;
}
public float getStartRed() {
return startRed;
}
public void setStartRed(float startRed) {
this.startRed = startRed;
}
public float getStartGreen() {
return startGreen;
}
public void setStartGreen(float startGreen) {
this.startGreen = startGreen;
}
public float getStartBlue() {
return startBlue;
}
public void setStartBlue(float startBlue) {
this.startBlue = startBlue;
}
public float getEndRed() {
return endRed;
}
public void setEndRed(float endRed) {
this.endRed = endRed;
}
public float getEndGreen() {
return endGreen;
}
public void setEndGreen(float endGreen) {
this.endGreen = endGreen;
}
public float getEndBlue() {
return endBlue;
}
public void setEndBlue(float endBlue) {
this.endBlue = endBlue;
this.start = start;
this.end = end;
}
public static ParticleDustColorTransitionData read(PacketWrapper<?> wrapper) {
float startRed = wrapper.readFloat();
float startGreen = wrapper.readFloat();
float startBlue = wrapper.readFloat();
Color start;
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
start = new Color(wrapper.readInt());
} else {
float startRed = wrapper.readFloat();
float startGreen = wrapper.readFloat();
float startBlue = wrapper.readFloat();
start = new Color(startRed, startGreen, startBlue);
}
float scale = 0f;
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_20_5)) {
scale = wrapper.readFloat();
}
float endRed = wrapper.readFloat();
float endGreen = wrapper.readFloat();
float endBlue = wrapper.readFloat();
Color end;
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
end = new Color(wrapper.readInt());
} else {
float endRed = wrapper.readFloat();
float endGreen = wrapper.readFloat();
float endBlue = wrapper.readFloat();
end = new Color(endRed, endGreen, endBlue);
}
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_20_5)) {
scale = wrapper.readFloat();
}
return new ParticleDustColorTransitionData(scale, startRed, startGreen, startBlue, endRed, endGreen, endBlue);
return new ParticleDustColorTransitionData(scale, start, end);
}
public static void write(PacketWrapper<?> wrapper, ParticleDustColorTransitionData data) {
wrapper.writeFloat(data.getStartRed());
wrapper.writeFloat(data.getStartGreen());
wrapper.writeFloat(data.getStartBlue());
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
wrapper.writeInt(data.getStart().asRGB());
} else {
wrapper.writeFloat(data.getStartRed());
wrapper.writeFloat(data.getStartGreen());
wrapper.writeFloat(data.getStartBlue());
}
if (wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_20_5)) {
wrapper.writeFloat(data.getScale());
}
wrapper.writeFloat(data.getEndRed());
wrapper.writeFloat(data.getEndGreen());
wrapper.writeFloat(data.getEndBlue());
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
wrapper.writeInt(data.getEnd().asRGB());
} else {
wrapper.writeFloat(data.getEndRed());
wrapper.writeFloat(data.getEndGreen());
wrapper.writeFloat(data.getEndBlue());
}
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_20_5)) {
wrapper.writeFloat(data.getScale());
}
@@ -162,8 +116,8 @@ public class ParticleDustColorTransitionData extends ParticleData {
fromColorKey = "fromColor";
toColorKey = "toColor";
}
float[] fromColor = decodeColor(compound.getTagOrThrow(fromColorKey));
float[] toColor = decodeColor(compound.getTagOrThrow(toColorKey));
Color fromColor = Color.decode(compound.getTagOrThrow(fromColorKey), version);
Color toColor = Color.decode(compound.getTagOrThrow(toColorKey), version);
float scale = compound.getNumberTagOrThrow("scale").getAsFloat();
return new ParticleDustColorTransitionData(scale, fromColor, toColor);
}
@@ -175,8 +129,8 @@ public class ParticleDustColorTransitionData extends ParticleData {
fromColorKey = "fromColor";
toColorKey = "toColor";
}
compound.setTag(fromColorKey, encodeColor(null, data.startRed, data.startGreen, data.startBlue));
compound.setTag(toColorKey, encodeColor(null, data.endRed, data.endGreen, data.endBlue));
compound.setTag(fromColorKey, Color.encode(data.start, version));
compound.setTag(toColorKey, Color.encode(data.end, version));
compound.setTag("scale", new NBTFloat(data.scale));
}
@@ -184,4 +138,76 @@ public class ParticleDustColorTransitionData extends ParticleData {
public boolean isEmpty() {
return false;
}
public float getStartRed() {
return this.start.red() / 255f;
}
public void setStartRed(float startRed) {
this.start = new Color(startRed, this.getStartGreen(), this.getStartBlue());
}
public float getStartGreen() {
return this.start.green() / 255f;
}
public void setStartGreen(float startGreen) {
this.start = new Color(this.getStartRed(), startGreen, this.getStartBlue());
}
public float getStartBlue() {
return this.start.blue() / 255f;
}
public void setStartBlue(float startBlue) {
this.start = new Color(this.getStartRed(), this.getStartGreen(), startBlue);
}
public float getEndRed() {
return this.end.red() / 255f;
}
public void setEndRed(float endRed) {
this.end = new Color(endRed, this.getEndGreen(), this.getEndBlue());
}
public float getEndGreen() {
return this.end.green() / 255f;
}
public void setEndGreen(float endGreen) {
this.end = new Color(this.getEndRed(), endGreen, this.getEndBlue());
}
public float getEndBlue() {
return this.end.blue() / 255f;
}
public void setEndBlue(float endBlue) {
this.end = new Color(this.getEndRed(), this.getEndGreen(), endBlue);
}
public float getScale() {
return this.scale;
}
public void setScale(float scale) {
this.scale = scale;
}
public Color getStart() {
return this.start;
}
public void setStart(Color start) {
this.start = start;
}
public Color getEnd() {
return this.end;
}
public void setEnd(Color end) {
this.end = end;
}
}
@@ -18,36 +18,21 @@
package com.github.retrooper.packetevents.protocol.particle.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.color.Color;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTByteArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.nbt.NBTIntArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTLongArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
public class ParticleDustData extends ParticleData {
//0.01 - 4
private float scale;
//0-1
private float red;
private float green;
private float blue;
private Color color;
public ParticleDustData(float scale, float red, float green, float blue) {
this.scale = scale;
this.red = red;
this.green = green;
this.blue = blue;
this(scale, new Color(red, green, blue));
}
public ParticleDustData(float scale, float[] rgb) {
@@ -58,112 +43,48 @@ public class ParticleDustData extends ParticleData {
this(scale, rgb.getX(), rgb.getY(), rgb.getZ());
}
public ParticleDustData(float scale, int red, int green, int blue) {
this(scale, new Color(red, green, blue));
}
public ParticleDustData(float scale, Color color) {
this(scale, color.red() / 255f, color.green() / 255f, color.blue() / 255f);
}
public float getRed() {
return red;
}
public void setRed(float red) {
this.red = red;
}
public float getGreen() {
return green;
}
public void setGreen(float green) {
this.green = green;
}
public float getBlue() {
return blue;
}
public void setBlue(float blue) {
this.blue = blue;
}
public float getScale() {
return scale;
}
public void setScale(float scale) {
this.scale = scale;
this.color = color;
}
public static ParticleDustData read(PacketWrapper<?> wrapper) {
float red = wrapper.readFloat();
float green = wrapper.readFloat();
float blue = wrapper.readFloat();
Color color;
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
color = new Color(wrapper.readInt());
} else {
float red = wrapper.readFloat();
float green = wrapper.readFloat();
float blue = wrapper.readFloat();
color = new Color(red, green, blue);
}
float scale = wrapper.readFloat();
return new ParticleDustData(scale, red, green, blue);
return new ParticleDustData(scale, color);
}
public static void write(PacketWrapper<?> wrapper, ParticleDustData data) {
wrapper.writeFloat(data.getRed());
wrapper.writeFloat(data.getGreen());
wrapper.writeFloat(data.getBlue());
wrapper.writeFloat(data.getScale());
}
@ApiStatus.Internal
public static float[] decodeColor(NBT tag) {
// I hate how nbt works
if (tag instanceof NBTList<?>) {
NBTList<?> colorTagList = (NBTList<?>) tag;
float first = ((NBTNumber) colorTagList.getTag(0)).getAsFloat();
float second = ((NBTNumber) colorTagList.getTag(1)).getAsFloat();
float third = ((NBTNumber) colorTagList.getTag(2)).getAsFloat();
if (colorTagList.size() > 3) {
float fourth = ((NBTNumber) colorTagList.getTag(3)).getAsFloat();
return new float[]{first, second, third, fourth}; // ARGB
}
return new float[]{first, second, third}; // RGB
} else if (tag instanceof NBTByteArray) {
byte[] colors = ((NBTByteArray) tag).getValue();
return colors.length > 3
? new float[]{colors[0], colors[1], colors[2], colors[3]}
: new float[]{colors[0], colors[1], colors[2]};
} else if (tag instanceof NBTIntArray) {
int[] colors = ((NBTIntArray) tag).getValue();
return colors.length > 3
? new float[]{colors[0], colors[1], colors[2], colors[3]}
: new float[]{colors[0], colors[1], colors[2]};
} else if (tag instanceof NBTLongArray) {
long[] colors = ((NBTLongArray) tag).getValue();
return colors.length > 3
? new float[]{colors[0], colors[1], colors[2], colors[3]}
: new float[]{colors[0], colors[1], colors[2]};
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
wrapper.writeInt(data.color.asRGB());
} else {
throw new UnsupportedOperationException("Unsupported color nbt tag: " + tag);
wrapper.writeFloat(data.getRed());
wrapper.writeFloat(data.getGreen());
wrapper.writeFloat(data.getBlue());
}
}
@ApiStatus.Internal
public static NBT encodeColor(@Nullable Float alpha, float red, float green, float blue) {
NBTList<NBTFloat> nbtList = new NBTList<>(NBTType.FLOAT,
alpha == null ? 3 : 4);
if (alpha != null) {
nbtList.addTag(new NBTFloat(alpha));
}
nbtList.addTag(new NBTFloat(red));
nbtList.addTag(new NBTFloat(green));
nbtList.addTag(new NBTFloat(blue));
return nbtList;
wrapper.writeFloat(data.scale);
}
public static ParticleDustData decode(NBTCompound compound, ClientVersion version) {
NBT colorNBT = compound.getTagOrNull("color");
float[] color = decodeColor(colorNBT);
Color color = Color.decode(compound.getTagOrThrow("color"), version);
float scale = compound.getNumberTagOrThrow("scale").getAsFloat();
return new ParticleDustData(scale, color);
}
public static void encode(ParticleDustData data, ClientVersion version, NBTCompound compound) {
compound.setTag("color", encodeColor(null, data.red, data.green, data.blue));
compound.setTag("color", Color.encode(data.color, version));
compound.setTag("scale", new NBTFloat(data.scale));
}
@@ -171,4 +92,44 @@ public class ParticleDustData extends ParticleData {
public boolean isEmpty() {
return false;
}
public float getRed() {
return this.color.red() / 255f;
}
public void setRed(float red) {
this.color = new Color(red, this.getGreen(), this.getBlue());
}
public float getGreen() {
return this.color.green() / 255f;
}
public void setGreen(float green) {
this.color = new Color(this.getRed(), green, this.getBlue());
}
public float getBlue() {
return this.color.blue() / 255f;
}
public void setBlue(float blue) {
this.color = new Color(this.getRed(), this.getGreen(), blue);
}
public float getScale() {
return this.scale;
}
public void setScale(float scale) {
this.scale = scale;
}
public Color getColor() {
return this.color;
}
public void setColor(Color color) {
this.color = color;
}
}
@@ -0,0 +1,118 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.particle.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.color.Color;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class ParticleTrailData extends ParticleData {
private static final int FALLBACK_DURATION = 50 / 2; // use average duration as default
private Vector3d target;
private Color color;
/**
* Added with 1.21.4
*/
private int duration;
public ParticleTrailData(Vector3d target, Color color) {
this(target, color, FALLBACK_DURATION);
}
public ParticleTrailData(Vector3d target, Color color, int duration) {
this.target = target;
this.color = color;
this.duration = duration;
}
public static ParticleTrailData read(PacketWrapper<?> wrapper) {
Vector3d target = Vector3d.read(wrapper);
Color color = new Color(wrapper.readInt());
int duration = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_4)
? wrapper.readVarInt() : FALLBACK_DURATION;
return new ParticleTrailData(target, color, duration);
}
public static void write(PacketWrapper<?> wrapper, ParticleTrailData data) {
Vector3d.write(wrapper, data.target);
wrapper.writeInt(data.color.asRGB());
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_4)) {
wrapper.writeVarInt(data.duration);
}
}
public static ParticleTrailData decode(NBTCompound compound, ClientVersion version) {
Vector3d target = Vector3d.decode(compound.getTagOrThrow("target"), version);
Color color = Color.decode(compound.getTagOrThrow("color"), version);
int duration = FALLBACK_DURATION;
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_4)) {
duration = compound.getNumberTagOrThrow("duration").getAsInt();
}
return new ParticleTrailData(target, color, duration);
}
public static void encode(ParticleTrailData data, ClientVersion version, NBTCompound compound) {
compound.setTag("target", Vector3d.encode(data.target, version));
compound.setTag("color", Color.encode(data.color, version));
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_4)) {
compound.setTag("duration", new NBTInt(data.duration));
}
}
@Override
public boolean isEmpty() {
return false;
}
public Vector3d getTarget() {
return this.target;
}
public void setTarget(Vector3d target) {
this.target = target;
}
public Color getColor() {
return this.color;
}
public void setColor(Color color) {
this.color = color;
}
/**
* Added with 1.21.4
*/
public int getDuration() {
return this.duration;
}
/**
* Added with 1.21.4
*/
public void setDuration(int duration) {
this.duration = duration;
}
}
@@ -27,6 +27,7 @@ import com.github.retrooper.packetevents.protocol.particle.data.ParticleDustData
import com.github.retrooper.packetevents.protocol.particle.data.ParticleItemStackData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleSculkChargeData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleShriekData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleTrailData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleVibrationData;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
@@ -273,6 +274,17 @@ public class ParticleTypes {
public static final ParticleType<ParticleData> RAID_OMEN = define("raid_omen");
public static final ParticleType<ParticleData> TRIAL_OMEN = define("trial_omen");
// added with 1.21.2
public static final ParticleType<ParticleTrailData> TRAIL = define("trail",
ParticleTrailData::read, ParticleTrailData::write,
ParticleTrailData::decode, ParticleTrailData::encode);
public static final ParticleType<ParticleBlockStateData> BLOCK_CRUMBLE = define("block_crumble",
ParticleBlockStateData::read, ParticleBlockStateData::write,
ParticleBlockStateData::decode, ParticleBlockStateData::encode);
// added with 1.21.4
public static final ParticleType<ParticleData> PALE_OAK_LEAVES = define("pale_oak_leaves");
/**
* Returns an immutable view of the particle types.
*
@@ -100,13 +100,18 @@ public enum ClientVersion {
* 1.21 and 1.21.1 have the same protocol version.
*/
V_1_21(767),
/**
* 1.21.2 and 1.21.3 have the same protocol version.
*/
V_1_21_2(768),
V_1_21_4(769),
//TODO UPDATE Add new protocol version field
@Deprecated
LOWER_THAN_SUPPORTED_VERSIONS(V_1_7_10.protocolVersion - 1, true),
//TODO UPDATE Update HIGHER_THAN_SUPPORTED_VERSIONS field
@Deprecated
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_21.protocolVersion + 1, true),
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_21_4.protocolVersion + 1, true),
UNKNOWN(-1, true);
@@ -18,6 +18,12 @@
package com.github.retrooper.packetevents.protocol.recipe;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> Replaced with {@link com.github.retrooper.packetevents.protocol.recipe.category.RecipeBookCategories} since 1.21.2.
*/
@ApiStatus.Obsolete
public enum CookingCategory {
FOOD,
@@ -18,6 +18,12 @@
package com.github.retrooper.packetevents.protocol.recipe;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> Replaced with {@link com.github.retrooper.packetevents.protocol.recipe.category.RecipeBookCategories} since 1.21.2.
*/
@ApiStatus.Obsolete
public enum CraftingCategory {
BUILDING,
@@ -20,7 +20,12 @@ package com.github.retrooper.packetevents.protocol.recipe;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class Ingredient {
private final ItemStack[] options;
@@ -22,7 +22,12 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.recipe.data.RecipeData;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class Recipe<T extends RecipeData> {
private final ResourceLocation key;
@@ -0,0 +1,142 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;
public final class RecipeBookSettings {
private final Map<RecipeBookType, TypeState> states;
public RecipeBookSettings(Map<RecipeBookType, TypeState> states) {
this.states = states;
}
public static RecipeBookSettings read(PacketWrapper<?> wrapper) {
Map<RecipeBookType, TypeState> state = new EnumMap<>(RecipeBookType.class);
for (RecipeBookType bookType : RecipeBookType.values()) {
state.put(bookType, TypeState.read(wrapper));
}
return new RecipeBookSettings(state);
}
public static void write(PacketWrapper<?> wrapper, RecipeBookSettings settings) {
for (RecipeBookType bookType : RecipeBookType.values()) {
TypeState.write(wrapper, settings.getState(bookType));
}
}
public TypeState getState(RecipeBookType type) {
return this.states.computeIfAbsent(type, $ -> new TypeState());
}
public void setState(RecipeBookType type, TypeState state) {
this.states.put(type, state);
}
public Map<RecipeBookType, TypeState> getStates() {
return this.states;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof RecipeBookSettings)) return false;
RecipeBookSettings that = (RecipeBookSettings) obj;
return this.states.equals(that.states);
}
@Override
public int hashCode() {
return Objects.hashCode(this.states);
}
@Override
public String toString() {
return "RecipeBookSettings{states=" + this.states + '}';
}
public static final class TypeState {
private static final boolean DEFAULT_OPEN = false;
private static final boolean DEFAULT_FILTERING = false;
private boolean open;
private boolean filtering;
public TypeState() { // default
this(DEFAULT_OPEN, DEFAULT_FILTERING);
}
public TypeState(boolean open, boolean filtering) {
this.open = open;
this.filtering = filtering;
}
public static TypeState read(PacketWrapper<?> wrapper) {
boolean open = wrapper.readBoolean();
boolean filtering = wrapper.readBoolean();
return new TypeState(open, filtering);
}
public static void write(PacketWrapper<?> wrapper, TypeState state) {
wrapper.writeBoolean(state.open);
wrapper.writeBoolean(state.filtering);
}
public boolean isOpen() {
return this.open;
}
public void setOpen(boolean open) {
this.open = open;
}
public boolean isFiltering() {
return this.filtering;
}
public void setFiltering(boolean filtering) {
this.filtering = filtering;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof TypeState)) return false;
TypeState typeState = (TypeState) obj;
if (this.open != typeState.open) return false;
return this.filtering == typeState.filtering;
}
@Override
public int hashCode() {
return Objects.hash(this.open, this.filtering);
}
@Override
public String toString() {
return "TypeState{open=" + this.open + ", filtering=" + this.filtering + '}';
}
}
}
@@ -0,0 +1,26 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe;
public enum RecipeBookType {
CRAFTING,
FURNACE,
BLAST_FURNACE,
SMOKER,
}
@@ -0,0 +1,135 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.recipe.category.RecipeBookCategories;
import com.github.retrooper.packetevents.protocol.recipe.category.RecipeBookCategory;
import com.github.retrooper.packetevents.protocol.recipe.display.RecipeDisplay;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public final class RecipeDisplayEntry {
private RecipeDisplayId id;
private RecipeDisplay<?> display;
private @Nullable Integer group;
private RecipeBookCategory category;
private @Nullable List<MappedEntitySet<ItemType>> ingredients;
public RecipeDisplayEntry(
RecipeDisplayId id,
RecipeDisplay<?> display,
@Nullable Integer group,
RecipeBookCategory category,
@Nullable List<MappedEntitySet<ItemType>> ingredients
) {
this.id = id;
this.display = display;
this.group = group;
this.category = category;
this.ingredients = ingredients;
}
public static RecipeDisplayEntry read(PacketWrapper<?> wrapper) {
RecipeDisplayId id = RecipeDisplayId.read(wrapper);
RecipeDisplay<?> display = RecipeDisplay.read(wrapper);
Integer group = wrapper.readNullableVarInt();
RecipeBookCategory category = wrapper.readMappedEntity(RecipeBookCategories.getRegistry());
List<MappedEntitySet<ItemType>> ingredients = wrapper.readOptional(ew -> ew.readList(
eww -> MappedEntitySet.read(eww, ItemTypes.getRegistry())));
return new RecipeDisplayEntry(id, display, group, category, ingredients);
}
public static void write(PacketWrapper<?> wrapper, RecipeDisplayEntry entry) {
RecipeDisplayId.write(wrapper, entry.id);
RecipeDisplay.write(wrapper, entry.display);
wrapper.writeNullableVarInt(entry.group);
wrapper.writeMappedEntity(entry.category);
wrapper.writeOptional(entry.ingredients, (ew, list) ->
ew.writeList(list, MappedEntitySet::write));
}
public RecipeDisplayId getId() {
return this.id;
}
public void setId(RecipeDisplayId id) {
this.id = id;
}
public RecipeDisplay<?> getDisplay() {
return this.display;
}
public void setDisplay(RecipeDisplay<?> display) {
this.display = display;
}
public @Nullable Integer getGroup() {
return this.group;
}
public void setGroup(@Nullable Integer group) {
this.group = group;
}
public RecipeBookCategory getCategory() {
return this.category;
}
public void setCategory(RecipeBookCategory category) {
this.category = category;
}
public @Nullable List<MappedEntitySet<ItemType>> getIngredients() {
return this.ingredients;
}
public void setIngredients(@Nullable List<MappedEntitySet<ItemType>> ingredients) {
this.ingredients = ingredients;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof RecipeDisplayEntry)) return false;
RecipeDisplayEntry that = (RecipeDisplayEntry) obj;
if (this.id != that.id) return false;
if (!this.display.equals(that.display)) return false;
if (!Objects.equals(this.group, that.group)) return false;
if (!this.category.equals(that.category)) return false;
return Objects.equals(this.ingredients, that.ingredients);
}
@Override
public int hashCode() {
return Objects.hash(this.id, this.display, this.group, this.category, this.ingredients);
}
@Override
public String toString() {
return "RecipeDisplayEntry{id=" + this.id + ", display=" + this.display + ", group=" + this.group + ", category=" + this.category + ", ingredients=" + this.ingredients + '}';
}
}
@@ -0,0 +1,43 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public final class RecipeDisplayId {
private final int id;
public RecipeDisplayId(int id) {
this.id = id;
}
public static RecipeDisplayId read(PacketWrapper<?> wrapper) {
int id = wrapper.readVarInt();
return new RecipeDisplayId(id);
}
public static void write(PacketWrapper<?> wrapper, RecipeDisplayId id) {
wrapper.writeVarInt(id.id);
}
public int getId() {
return this.id;
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.LinkedHashSet;
import java.util.Set;
public final class RecipePropertySet {
public static final ResourceLocation SMITHING_BASE = ResourceLocation.minecraft("smithing_base");
public static final ResourceLocation SMITHING_TEMPLATE = ResourceLocation.minecraft("smithing_template");
public static final ResourceLocation SMITHING_ADDITION = ResourceLocation.minecraft("smithing_addition");
public static final ResourceLocation FURNACE_INPUT = ResourceLocation.minecraft("furnace_input");
public static final ResourceLocation BLAST_FURNACE_INPUT = ResourceLocation.minecraft("blast_furnace_input");
public static final ResourceLocation SMOKER_INPUT = ResourceLocation.minecraft("smoker_input");
public static final ResourceLocation CAMPFIRE_INPUT = ResourceLocation.minecraft("campfire_input");
private Set<ItemType> items;
public RecipePropertySet(Set<ItemType> items) {
this.items = items;
}
public static RecipePropertySet read(PacketWrapper<?> wrapper) {
LinkedHashSet<ItemType> items = wrapper.readCollection(LinkedHashSet::new,
ew -> ew.readMappedEntity(ItemTypes.getRegistry()));
return new RecipePropertySet(items);
}
public static void write(PacketWrapper<?> wrapper, RecipePropertySet set) {
wrapper.writeCollection(set.items, PacketWrapper::writeMappedEntity);
}
public Set<ItemType> getItems() {
return this.items;
}
public void setItems(Set<ItemType> items) {
this.items = items;
}
}
@@ -21,7 +21,12 @@ package com.github.retrooper.packetevents.protocol.recipe;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.recipe.data.RecipeData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public interface RecipeSerializer<T extends RecipeData> extends MappedEntity {
@Deprecated
@@ -40,6 +40,10 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class RecipeSerializers {
private static final Map<String, RecipeSerializer<?>> PATTERN_TYPE_MAP = new HashMap<>();
@@ -0,0 +1,71 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.recipe.display.slot.SlotDisplay;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
/**
* This is a representation of some strange vanilla concept
* specific to stonecutters.
* <p>
* Seems like a hack to make stonecutters work with their
* rewritten recipe system, but I'm not too sure about what
* this really is for.
*/
public class SingleInputOptionDisplay {
private MappedEntitySet<ItemType> input;
private SlotDisplay<?> optionDisplay;
public SingleInputOptionDisplay(MappedEntitySet<ItemType> input, SlotDisplay<?> optionDisplay) {
this.input = input;
this.optionDisplay = optionDisplay;
}
public static SingleInputOptionDisplay read(PacketWrapper<?> wrapper) {
MappedEntitySet<ItemType> ingredient = MappedEntitySet.read(wrapper, ItemTypes.getRegistry());
SlotDisplay<?> optionDisplay = SlotDisplay.read(wrapper);
return new SingleInputOptionDisplay(ingredient, optionDisplay);
}
public static void write(PacketWrapper<?> wrapper, SingleInputOptionDisplay recipe) {
MappedEntitySet.write(wrapper, recipe.input);
SlotDisplay.write(wrapper, recipe.optionDisplay);
}
public MappedEntitySet<ItemType> getInput() {
return this.input;
}
public void setInput(MappedEntitySet<ItemType> input) {
this.input = input;
}
public SlotDisplay<?> getOptionDisplay() {
return this.optionDisplay;
}
public void setOptionDisplay(SlotDisplay<?> optionDisplay) {
this.optionDisplay = optionDisplay;
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe.category;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
public final class RecipeBookCategories {
private static final VersionedRegistry<RecipeBookCategory> REGISTRY = new VersionedRegistry<>(
"recipe_book_category", "item/recipe_book_category");
private RecipeBookCategories() {
}
private static RecipeBookCategory register(String id) {
return REGISTRY.define(id, StaticRecipeBookCategory::new);
}
public static VersionedRegistry<RecipeBookCategory> getRegistry() {
return REGISTRY;
}
public static final RecipeBookCategory CRAFTING_BUILDING_BLOCKS = register("crafting_building_blocks");
public static final RecipeBookCategory CRAFTING_REDSTONE = register("crafting_redstone");
public static final RecipeBookCategory CRAFTING_EQUIPMENT = register("crafting_equipment");
public static final RecipeBookCategory CRAFTING_MISC = register("crafting_misc");
public static final RecipeBookCategory FURNACE_FOOD = register("furnace_food");
public static final RecipeBookCategory FURNACE_BLOCKS = register("furnace_blocks");
public static final RecipeBookCategory FURNACE_MISC = register("furnace_misc");
public static final RecipeBookCategory BLAST_FURNACE_BLOCKS = register("blast_furnace_blocks");
public static final RecipeBookCategory BLAST_FURNACE_MISC = register("blast_furnace_misc");
public static final RecipeBookCategory SMOKER_FOOD = register("smoker_food");
public static final RecipeBookCategory STONECUTTER = register("stonecutter");
public static final RecipeBookCategory SMITHING = register("smithing");
public static final RecipeBookCategory CAMPFIRE = register("campfire");
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,24 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe.category;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
public interface RecipeBookCategory extends MappedEntity {
}
@@ -0,0 +1,29 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 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.recipe.category;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
public class StaticRecipeBookCategory extends AbstractMappedEntity implements RecipeBookCategory {
public StaticRecipeBookCategory(TypesBuilderData data) {
super(data);
}
}
@@ -23,7 +23,12 @@ import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.recipe.CookingCategory;
import com.github.retrooper.packetevents.protocol.recipe.Ingredient;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class CookedRecipeData implements RecipeData {
private final String group;
@@ -18,5 +18,11 @@
package com.github.retrooper.packetevents.protocol.recipe.data;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public interface RecipeData {
}
@@ -23,7 +23,12 @@ import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.recipe.CraftingCategory;
import com.github.retrooper.packetevents.protocol.recipe.Ingredient;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class ShapedRecipeData implements RecipeData {
private final String group;
@@ -23,7 +23,12 @@ import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.recipe.CraftingCategory;
import com.github.retrooper.packetevents.protocol.recipe.Ingredient;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class ShapelessRecipeData implements RecipeData {
private final String group;
@@ -21,7 +21,12 @@ package com.github.retrooper.packetevents.protocol.recipe.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.recipe.CraftingCategory;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class SimpleRecipeData implements RecipeData {
private final CraftingCategory category;
Loaded 100 of 319 files, more files were not shown because too many files have changed in this diff. Show more