Compare commits

...
171 Commits
Author SHA1 Message Date
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
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
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
290 changed files with 209012 additions and 4819 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)
+11 -4
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,6 +76,7 @@ mappingCompression {
compress("entity/painting_mappings.json")
compress("entity/wolf_variant_mappings.json")
compress("item/consume_effect_type_mappings.json")
compress("item/item_armor_material_mappings.json")
compress("item/item_banner_pattern_mappings.json")
compress("item/item_component_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) {
@@ -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),
//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,122 @@ 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");
public static final Attribute GENERIC_ARMOR = define("armor",
"generic", 0d, 0d, 30d);
public static final Attribute GENERIC_ARMOR_TOUGHNESS = define("armor_toughness",
"generic", 0d, 0d, 20d);
public static final Attribute GENERIC_ATTACK_DAMAGE = define("attack_damage",
"generic", 2d, 0d, 2048d);
public static final Attribute GENERIC_ATTACK_KNOCKBACK = define("attack_knockback",
"generic", 0d, 0d, 5d);
public static final Attribute GENERIC_ATTACK_SPEED = define("attack_speed",
"generic", 4d, 0d, 1024d);
public static final Attribute GENERIC_FLYING_SPEED = define("flying_speed",
"generic", 0.4d, 0d, 1024d);
public static final Attribute GENERIC_FOLLOW_RANGE = define("follow_range",
"generic", 32d, 0d, 2048d);
@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 HORSE_JUMP_STRENGTH = define("horse.jump_strength",
null, 0.7d, 0d, 2d);
public static final Attribute GENERIC_KNOCKBACK_RESISTANCE = define("knockback_resistance",
"generic", 0d, 0d, 1d);
public static final Attribute GENERIC_LUCK = define("luck",
"generic", 0d, -1024d, 1024d);
public static final Attribute GENERIC_MAX_HEALTH = define("max_health",
"generic", 20d, 1d, 1024d);
public static final Attribute GENERIC_MOVEMENT_SPEED = define("movement_speed",
"generic", 0.7d, 0d, 1024d);
public static final Attribute ZOMBIE_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");
public static final Attribute GENERIC_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");
public static final Attribute PLAYER_BLOCK_BREAK_SPEED = define("block_break_speed",
"player", 1d, 0d, 1024d);
public static final Attribute PLAYER_BLOCK_INTERACTION_RANGE = define("block_interaction_range",
"player", 4.5d, 0d, 64d);
public static final Attribute PLAYER_ENTITY_INTERACTION_RANGE = define("entity_interaction_range",
"player", 3d, 0d, 64d);
public static final Attribute GENERIC_FALL_DAMAGE_MULTIPLIER = define("fall_damage_multiplier",
"generic", 1d, 0d, 100d);
public static final Attribute GENERIC_GRAVITY = define("gravity",
"generic", 0.08d, -1d, 1d);
public static final Attribute GENERIC_JUMP_STRENGTH = define("jump_strength",
"generic", 0.42d, 0d, 32d);
public static final Attribute GENERIC_SAFE_FALL_DISTANCE = define("safe_fall_distance",
"generic", 3d, 0d, 1024d);
public static final Attribute GENERIC_SCALE = define("scale",
"generic", 1d, 1d / 16d, 16d);
public static final Attribute GENERIC_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");
public static final Attribute GENERIC_BURNING_TIME = define("burning_time",
"generic", 0d, 1d, 1024d);
public static final Attribute GENERIC_EXPLOSION_KNOCKBACK_RESISTANCE = define("explosion_knockback_resistance",
"generic", 0d, 0d, 1d);
public static final Attribute PLAYER_MINING_EFFICIENCY = define("mining_efficiency",
"player", 0d, 0d, 1024d);
public static final Attribute GENERIC_MOVEMENT_EFFICIENCY = define("movement_efficiency",
"generic", 0d, 0d, 1d);
public static final Attribute GENERIC_OXYGEN_BONUS = define("oxygen_bonus",
"generic", 0d, 0d, 1024d);
public static final Attribute PLAYER_SNEAKING_SPEED = define("sneaking_speed",
"player", 0.3d, 0d, 1d);
public static final Attribute PLAYER_SUBMERGED_MINING_SPEED = define("submerged_mining_speed",
"player", 0.2d, 0d, 20d);
public static final Attribute PLAYER_SWEEPING_DAMAGE_RATIO = define("sweeping_damage_ratio",
"player", 0d, 0d, 1d);
public static final Attribute GENERIC_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);
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,23 @@
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 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 +42,42 @@ 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 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 +91,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 +108,4 @@ public final class Color implements RGBLike {
public @Range(from = 0L, to = 255L) int blue() {
return blue;
}
}
}
@@ -31,21 +31,31 @@ 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.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;
@@ -145,6 +155,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 +234,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());
}
@@ -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,138 @@
/*
* 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,
}
}
@@ -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,176 @@
/*
* 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 model;
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 model,
@Nullable ResourceLocation cameraOverlay,
@Nullable MappedEntitySet<EntityType> allowedEntities,
boolean dispensable,
boolean swappable,
boolean damageOnHurt
) {
this.slot = slot;
this.equipSound = equipSound;
this.model = model;
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.model, 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 getModel() {
return this.model;
}
public void setModel(@Nullable ResourceLocation model) {
this.model = model;
}
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;
}
@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.model, that.model)) 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.model, this.cameraOverlay, this.allowedEntities, this.dispensable, this.swappable, this.damageOnHurt);
}
@Override
public String toString() {
return "ItemEquippable{slot=" + this.slot + ", equipSound=" + this.equipSound + ", model=" + this.model + ", 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,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 + '}';
}
}
@@ -24,7 +24,11 @@ import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
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 +155,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 +305,33 @@ 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);
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,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();
}
}
@@ -87,6 +87,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 +100,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);
}
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMateri
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;
@@ -39,7 +40,7 @@ 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 {
String getAssetName();
@@ -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();
}
@@ -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,6 +65,7 @@ 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_7_10;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_8;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_9;
@@ -103,7 +105,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 +127,8 @@ 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);
// TODO UPDATE Update packet type mappings (config clientbound pt. 1)
private static final VersionMapper CLIENTBOUND_CONFIG_VERSION_MAPPER = new VersionMapper(
@@ -664,7 +668,13 @@ public final class PacketType {
// Added in 1.20.5
CHAT_COMMAND_UNSIGNED,
COOKIE_RESPONSE,
DEBUG_SAMPLE_SUBSCRIPTION;
DEBUG_SAMPLE_SUBSCRIPTION,
// added in 1.21.2
CLIENT_TICK_END,
SELECT_BUNDLE_ITEM,
PLAYER_INPUT, // based on STEER_VEHICLE
;
private static int INDEX = 0;
private static final Map<Byte, Map<Integer, PacketTypeCommon>> PACKET_TYPE_ID_MAP = new HashMap<>();
@@ -718,6 +728,7 @@ 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());
//TODO UPDATE Update packet type mappings (serverbound pt. 2)
}
@@ -812,7 +823,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 +912,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 +994,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,
}
@@ -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,79 @@
/*
* 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.protocol.color.Color;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
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 Vector3d target;
private Color color;
public ParticleTrailData(Vector3d target, Color color) {
this.target = target;
this.color = color;
}
public static ParticleTrailData read(PacketWrapper<?> wrapper) {
Vector3d target = Vector3d.read(wrapper);
Color color = new Color(wrapper.readInt());
return new ParticleTrailData(target, color);
}
public static void write(PacketWrapper<?> wrapper, ParticleTrailData data) {
Vector3d.write(wrapper, data.target);
wrapper.writeInt(data.color.asRGB());
}
public static ParticleTrailData decode(NBTCompound compound, ClientVersion version) {
Vector3d target = Vector3d.decode(compound.getTagOrThrow("target"), version);
Color color = Color.decode(compound.getTagOrThrow("color"), version);
return new ParticleTrailData(target, color);
}
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));
}
@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;
}
}
@@ -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,14 @@ 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);
/**
* Returns an immutable view of the particle types.
*
@@ -100,13 +100,17 @@ 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),
//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_2.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;
@@ -22,8 +22,13 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.recipe.Ingredient;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.UnknownNullability;
/**
* <strong>WARNING:</strong> No longer exists since 1.21.2, network recipe data was rewritten.
*/
@ApiStatus.Obsolete
public class SmithingRecipeData implements RecipeData {
private final @UnknownNullability Ingredient template;
@@ -20,7 +20,12 @@ package com.github.retrooper.packetevents.protocol.recipe.data;
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 SmithingTrimRecipeData implements RecipeData {
private final Ingredient template;
@@ -21,7 +21,12 @@ package com.github.retrooper.packetevents.protocol.recipe.data;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
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 StoneCuttingRecipeData implements RecipeData {
private final String group;
@@ -0,0 +1,138 @@
/*
* 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.display;
import com.github.retrooper.packetevents.protocol.recipe.display.slot.SlotDisplay;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class FurnaceRecipeDisplay extends RecipeDisplay<FurnaceRecipeDisplay> {
private SlotDisplay<?> ingredient;
private SlotDisplay<?> fuel;
private SlotDisplay<?> result;
private SlotDisplay<?> craftingStation;
private int duration;
private float experience;
public FurnaceRecipeDisplay(
SlotDisplay<?> ingredient, SlotDisplay<?> fuel, SlotDisplay<?> result,
SlotDisplay<?> craftingStation, int duration, float experience
) {
super(RecipeDisplayTypes.FURNACE);
this.ingredient = ingredient;
this.fuel = fuel;
this.result = result;
this.craftingStation = craftingStation;
this.duration = duration;
this.experience = experience;
}
public static FurnaceRecipeDisplay read(PacketWrapper<?> wrapper) {
SlotDisplay<?> ingredient = SlotDisplay.read(wrapper);
SlotDisplay<?> fuel = SlotDisplay.read(wrapper);
SlotDisplay<?> result = SlotDisplay.read(wrapper);
SlotDisplay<?> craftingStation = SlotDisplay.read(wrapper);
int duration = wrapper.readVarInt();
float experience = wrapper.readFloat();
return new FurnaceRecipeDisplay(ingredient, fuel, result,
craftingStation, duration, experience);
}
public static void write(PacketWrapper<?> wrapper, FurnaceRecipeDisplay display) {
SlotDisplay.write(wrapper, display.ingredient);
SlotDisplay.write(wrapper, display.fuel);
SlotDisplay.write(wrapper, display.result);
SlotDisplay.write(wrapper, display.craftingStation);
wrapper.writeVarInt(display.duration);
wrapper.writeFloat(display.experience);
}
public SlotDisplay<?> getIngredient() {
return this.ingredient;
}
public void setIngredient(SlotDisplay<?> ingredient) {
this.ingredient = ingredient;
}
public SlotDisplay<?> getFuel() {
return this.fuel;
}
public void setFuel(SlotDisplay<?> fuel) {
this.fuel = fuel;
}
public SlotDisplay<?> getResult() {
return this.result;
}
public void setResult(SlotDisplay<?> result) {
this.result = result;
}
public SlotDisplay<?> getCraftingStation() {
return this.craftingStation;
}
public void setCraftingStation(SlotDisplay<?> craftingStation) {
this.craftingStation = craftingStation;
}
public int getDuration() {
return this.duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public float getExperience() {
return this.experience;
}
public void setExperience(float experience) {
this.experience = experience;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof FurnaceRecipeDisplay)) return false;
FurnaceRecipeDisplay that = (FurnaceRecipeDisplay) obj;
if (this.duration != that.duration) return false;
if (Float.compare(that.experience, this.experience) != 0) return false;
if (!this.ingredient.equals(that.ingredient)) return false;
if (!this.fuel.equals(that.fuel)) return false;
if (!this.result.equals(that.result)) return false;
return this.craftingStation.equals(that.craftingStation);
}
@Override
public int hashCode() {
return Objects.hash(this.ingredient, this.fuel, this.result, this.craftingStation, this.duration, this.experience);
}
@Override
public String toString() {
return "FurnaceRecipeDisplay{ingredient=" + this.ingredient + ", fuel=" + this.fuel + ", result=" + this.result + ", craftingStation=" + this.craftingStation + ", duration=" + this.duration + ", experience=" + this.experience + '}';
}
}
@@ -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.recipe.display;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public abstract class RecipeDisplay<T extends RecipeDisplay<?>> {
protected final RecipeDisplayType<T> type;
public RecipeDisplay(RecipeDisplayType<T> type) {
this.type = type;
}
public static RecipeDisplay<?> read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntity(RecipeDisplayTypes.getRegistry()).read(wrapper);
}
@SuppressWarnings("unchecked")
public static <T extends RecipeDisplay<?>> void write(
PacketWrapper<?> wrapper, T display) {
wrapper.writeMappedEntity(display.getType());
((RecipeDisplayType<T>) display.getType()).write(wrapper, display);
}
public RecipeDisplayType<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.recipe.display;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface RecipeDisplayType<T extends RecipeDisplay<?>> extends MappedEntity {
T read(PacketWrapper<?> wrapper);
void write(PacketWrapper<?> wrapper, T display);
}
@@ -0,0 +1,55 @@
/*
* 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.display;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public final class RecipeDisplayTypes {
private static final VersionedRegistry<RecipeDisplayType<?>> REGISTRY = new VersionedRegistry<>(
"recipe_display", "item/recipe_display_types");
private RecipeDisplayTypes() {
}
private static <T extends RecipeDisplay<?>> RecipeDisplayType<T> register(
String id, PacketWrapper.Reader<T> reader, PacketWrapper.Writer<T> writer) {
return REGISTRY.define(id, data -> new StaticRecipeDisplayType<>(data, reader, writer));
}
public static VersionedRegistry<RecipeDisplayType<?>> getRegistry() {
return REGISTRY;
}
public static final RecipeDisplayType<ShapelessCraftingRecipeDisplay> CRAFTING_SHAPELESS = register(
"crafting_shapeless", ShapelessCraftingRecipeDisplay::read, ShapelessCraftingRecipeDisplay::write);
public static final RecipeDisplayType<ShapedCraftingRecipeDisplay> CRAFTING_SHAPED = register(
"crafting_shaped", ShapedCraftingRecipeDisplay::read, ShapedCraftingRecipeDisplay::write);
public static final RecipeDisplayType<FurnaceRecipeDisplay> FURNACE = register(
"furnace", FurnaceRecipeDisplay::read, FurnaceRecipeDisplay::write);
public static final RecipeDisplayType<StonecutterRecipeDisplay> STONECUTTER = register(
"stonecutter", StonecutterRecipeDisplay::read, StonecutterRecipeDisplay::write);
public static final RecipeDisplayType<SmithingRecipeDisplay> SMITHING = register(
"smithing", SmithingRecipeDisplay::read, SmithingRecipeDisplay::write);
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,127 @@
/*
* 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.display;
import com.github.retrooper.packetevents.protocol.recipe.display.slot.SlotDisplay;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ShapedCraftingRecipeDisplay extends RecipeDisplay<ShapedCraftingRecipeDisplay> {
private int width;
private int height;
private List<SlotDisplay<?>> ingredients;
private SlotDisplay<?> result;
private SlotDisplay<?> craftingStation;
public ShapedCraftingRecipeDisplay(
int width, int height,
List<SlotDisplay<?>> ingredients,
SlotDisplay<?> result,
SlotDisplay<?> craftingStation
) {
super(RecipeDisplayTypes.CRAFTING_SHAPED);
this.width = width;
this.height = height;
this.ingredients = ingredients;
this.result = result;
this.craftingStation = craftingStation;
}
public static ShapedCraftingRecipeDisplay read(PacketWrapper<?> wrapper) {
int width = wrapper.readVarInt();
int height = wrapper.readVarInt();
List<SlotDisplay<?>> ingredients = wrapper.readList(SlotDisplay::read);
SlotDisplay<?> result = SlotDisplay.read(wrapper);
SlotDisplay<?> craftingStation = SlotDisplay.read(wrapper);
return new ShapedCraftingRecipeDisplay(width, height, ingredients, result, craftingStation);
}
public static void write(PacketWrapper<?> wrapper, ShapedCraftingRecipeDisplay display) {
wrapper.writeVarInt(display.width);
wrapper.writeVarInt(display.height);
wrapper.writeList(display.ingredients, SlotDisplay::write);
SlotDisplay.write(wrapper, display.result);
SlotDisplay.write(wrapper, display.craftingStation);
}
public int getWidth() {
return this.width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return this.height;
}
public void setHeight(int height) {
this.height = height;
}
public List<SlotDisplay<?>> getIngredients() {
return this.ingredients;
}
public void setIngredients(List<SlotDisplay<?>> ingredients) {
this.ingredients = ingredients;
}
public SlotDisplay<?> getResult() {
return this.result;
}
public void setResult(SlotDisplay<?> result) {
this.result = result;
}
public SlotDisplay<?> getCraftingStation() {
return this.craftingStation;
}
public void setCraftingStation(SlotDisplay<?> craftingStation) {
this.craftingStation = craftingStation;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ShapedCraftingRecipeDisplay)) return false;
ShapedCraftingRecipeDisplay that = (ShapedCraftingRecipeDisplay) obj;
if (this.width != that.width) return false;
if (this.height != that.height) return false;
if (!this.ingredients.equals(that.ingredients)) return false;
if (!this.result.equals(that.result)) return false;
return this.craftingStation.equals(that.craftingStation);
}
@Override
public int hashCode() {
return Objects.hash(this.width, this.height, this.ingredients, this.result, this.craftingStation);
}
@Override
public String toString() {
return "ShapedCraftingRecipeDisplay{width=" + this.width + ", height=" + this.height + ", ingredients=" + this.ingredients + ", result=" + this.result + ", craftingStation=" + this.craftingStation + '}';
}
}
@@ -0,0 +1,99 @@
/*
* 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.display;
import com.github.retrooper.packetevents.protocol.recipe.display.slot.SlotDisplay;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ShapelessCraftingRecipeDisplay extends RecipeDisplay<ShapelessCraftingRecipeDisplay> {
private List<SlotDisplay<?>> ingredients;
private SlotDisplay<?> result;
private SlotDisplay<?> craftingStation;
public ShapelessCraftingRecipeDisplay(
List<SlotDisplay<?>> ingredients,
SlotDisplay<?> result,
SlotDisplay<?> craftingStation) {
super(RecipeDisplayTypes.CRAFTING_SHAPELESS);
this.ingredients = ingredients;
this.result = result;
this.craftingStation = craftingStation;
}
public static ShapelessCraftingRecipeDisplay read(PacketWrapper<?> wrapper) {
List<SlotDisplay<?>> ingredients = wrapper.readList(SlotDisplay::read);
SlotDisplay<?> result = SlotDisplay.read(wrapper);
SlotDisplay<?> craftingStation = SlotDisplay.read(wrapper);
return new ShapelessCraftingRecipeDisplay(ingredients, result, craftingStation);
}
public static void write(PacketWrapper<?> wrapper, ShapelessCraftingRecipeDisplay display) {
wrapper.writeList(display.ingredients, SlotDisplay::write);
SlotDisplay.write(wrapper, display.result);
SlotDisplay.write(wrapper, display.craftingStation);
}
public List<SlotDisplay<?>> getIngredients() {
return this.ingredients;
}
public void setIngredients(List<SlotDisplay<?>> ingredients) {
this.ingredients = ingredients;
}
public SlotDisplay<?> getResult() {
return this.result;
}
public void setResult(SlotDisplay<?> result) {
this.result = result;
}
public SlotDisplay<?> getCraftingStation() {
return this.craftingStation;
}
public void setCraftingStation(SlotDisplay<?> craftingStation) {
this.craftingStation = craftingStation;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ShapelessCraftingRecipeDisplay)) return false;
ShapelessCraftingRecipeDisplay that = (ShapelessCraftingRecipeDisplay) obj;
if (!this.ingredients.equals(that.ingredients)) return false;
if (!this.result.equals(that.result)) return false;
return this.craftingStation.equals(that.craftingStation);
}
@Override
public int hashCode() {
return Objects.hash(this.ingredients, this.result, this.craftingStation);
}
@Override
public String toString() {
return "ShapelessCraftingRecipeDisplay{ingredients=" + this.ingredients + ", result=" + this.result + ", craftingStation=" + this.craftingStation + '}';
}
}
@@ -0,0 +1,127 @@
/*
* 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.display;
import com.github.retrooper.packetevents.protocol.recipe.display.slot.SlotDisplay;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class SmithingRecipeDisplay extends RecipeDisplay<SmithingRecipeDisplay> {
private SlotDisplay<?> template;
private SlotDisplay<?> base;
private SlotDisplay<?> addition;
private SlotDisplay<?> result;
private SlotDisplay<?> craftingStation;
public SmithingRecipeDisplay(
SlotDisplay<?> template,
SlotDisplay<?> base,
SlotDisplay<?> addition,
SlotDisplay<?> result,
SlotDisplay<?> craftingStation
) {
super(RecipeDisplayTypes.SMITHING);
this.template = template;
this.base = base;
this.addition = addition;
this.result = result;
this.craftingStation = craftingStation;
}
public static SmithingRecipeDisplay read(PacketWrapper<?> wrapper) {
SlotDisplay<?> template = SlotDisplay.read(wrapper);
SlotDisplay<?> base = SlotDisplay.read(wrapper);
SlotDisplay<?> addition = SlotDisplay.read(wrapper);
SlotDisplay<?> result = SlotDisplay.read(wrapper);
SlotDisplay<?> craftingStation = SlotDisplay.read(wrapper);
return new SmithingRecipeDisplay(template, base, addition, result, craftingStation);
}
public static void write(PacketWrapper<?> wrapper, SmithingRecipeDisplay display) {
SlotDisplay.write(wrapper, display.template);
SlotDisplay.write(wrapper, display.base);
SlotDisplay.write(wrapper, display.addition);
SlotDisplay.write(wrapper, display.result);
SlotDisplay.write(wrapper, display.craftingStation);
}
public SlotDisplay<?> getTemplate() {
return this.template;
}
public void setTemplate(SlotDisplay<?> template) {
this.template = template;
}
public SlotDisplay<?> getBase() {
return this.base;
}
public void setBase(SlotDisplay<?> base) {
this.base = base;
}
public SlotDisplay<?> getAddition() {
return this.addition;
}
public void setAddition(SlotDisplay<?> addition) {
this.addition = addition;
}
public SlotDisplay<?> getResult() {
return this.result;
}
public void setResult(SlotDisplay<?> result) {
this.result = result;
}
public SlotDisplay<?> getCraftingStation() {
return this.craftingStation;
}
public void setCraftingStation(SlotDisplay<?> craftingStation) {
this.craftingStation = craftingStation;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof SmithingRecipeDisplay)) return false;
SmithingRecipeDisplay that = (SmithingRecipeDisplay) obj;
if (!this.template.equals(that.template)) return false;
if (!this.base.equals(that.base)) return false;
if (!this.addition.equals(that.addition)) return false;
if (!this.result.equals(that.result)) return false;
return this.craftingStation.equals(that.craftingStation);
}
@Override
public int hashCode() {
return Objects.hash(this.template, this.base, this.addition, this.result, this.craftingStation);
}
@Override
public String toString() {
return "SmithingRecipeDisplay{template=" + this.template + ", base=" + this.base + ", addition=" + this.addition + ", result=" + this.result + ", craftingStation=" + this.craftingStation + '}';
}
}
Loaded 100 of 290 files, more files were not shown because too many files have changed in this diff. Show more