Compare commits

...
749 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
retrooper ab8faf358c 2.5.0 Release 2024-09-20 22:07:20 +02:00
retrooper 243ce3c5dd Merge pull request #990 from Elikill58/2.0
Add wrapper for BossBar packet
2024-09-20 21:57:25 +02:00
retrooper d4762195f9 adhere to packetevents' convention of capitalizing UUID in setters & getters 2024-09-20 21:53:46 +02:00
retrooper 121e1615b6 remove awkward comment break in PEVersion#toStringWithoutSnapshot docs 2024-09-20 21:49:46 +02:00
retrooper 350d33ae6f Merge remote-tracking branch 'origin/2.0' into 2.0 2024-09-20 21:47:15 +02:00
retrooper d4f7bced86 bstats metrics do not collect snapshot & commit, solely version is captured. 2024-09-20 21:46:18 +02:00
retrooper 8037e659a8 Merge pull request #1000 from booky10/fix/particle-data-again
Revert some fixes for particle data decoding/encoding
2024-09-20 21:12:04 +02:00
retrooper 28c7849252 Merge pull request #999 from booky10/fix/bungee-injection
Rework bungee injector to allow for packet cancellation
2024-09-20 21:07:09 +02:00
retrooper cb277bf16a Merge pull request #995 from booky10/fix/packet-sending-race-condition
Synchronize packet encoding
2024-09-20 21:04:50 +02:00
booky10 0612e1e188 Revert some fixes for particle data decoding/encoding
Mojang's codecs are confusing
2024-09-20 20:30:08 +02:00
booky10 7a9f83129e Fix incorrect list recycling usage 2024-09-20 20:11:05 +02:00
booky10 a17e5f13a7 Rework bungee injector to allow for packet cancellation 2024-09-20 20:04:29 +02:00
retrooper 02a565bf39 Merge pull request #996 from booky10/fix/bungee-injection
Fix support for new bungee compression
2024-09-20 19:44:01 +02:00
booky10 f1d7d5ac81 Merge pull request #992 from galacticwarrior9/add-biomeeffects-getters 2024-09-18 08:33:30 +02:00
retrooper a1663f5a03 Merge pull request #994 from booky10/fix/pre-1.20.5-registry-data-limit
Remove nbt reading limit in registry-data packet for pre 1.20.5
2024-09-17 23:22:28 +02:00
booky10 909492cfae Fix support for new bungee compression 2024-09-17 16:39:46 +02:00
booky10 a3b4cc21f5 Synchronize packet encoding
Resolves concurrency issues which may happen when sending the same packet wrapper to different players, concurrently

This is not a perfect solution, but the alternative would be refactoring the packetwrapper to be based on buffers passed during encoding as parameters, which would be too much effort and would require breaking changes
2024-09-17 16:29:30 +02:00
booky10 402ebd729e Remove nbt reading limit in registry-data packet for pre 1.20.5 2024-09-17 16:21:49 +02:00
galacticwarrior9 349b5dc110 Add missing getters to BiomeEffects 2024-09-17 13:43:07 +01:00
Elikill58 c778cc3368 Convert list to EnumSet 2024-09-16 23:03:43 +02:00
Elikill58 26e5aab84e Rename divison to overlay 2024-09-16 19:54:01 +02:00
Elikill58 79da4e1bc4 Convert flags 2024-09-16 19:50:29 +02:00
Elikill58 51b550ca5e Use adventure's enum 2024-09-16 11:29:37 +02:00
Elikill58 2877b74c42 Remove own config... 2024-09-15 19:54:08 +02:00
Elikill58 c67d1a86c5 Fix missing import 2024-09-15 19:41:28 +02:00
Elikill58 5cf9b34fd2 Add wrapper for BossBar packet 2024-09-15 19:24:59 +02:00
retrooper 99acbe4960 Merge pull request #980 from booky10/fix/javadoc-links
Update javadoc overview links
2024-09-02 22:27:53 +02:00
booky10 2bf64b6107 Update javadoc overview links 2024-09-02 22:26:07 +02:00
retrooper 4e86af8754 Add Javadocs URL 2024-09-02 22:22:44 +02:00
retrooper 6bf639f18a Update links to documentation. 2024-09-02 22:11:34 +02:00
retrooper 9a7bb17459 Merge pull request #978 from AoElite/2.0
fixed runAtFixedRate not using ticks when running on folia
2024-09-01 22:38:57 +02:00
AoElite 6b84c683ee fixed runAtFixedRate not using ticks when running on folia 2024-09-01 16:33:12 -04: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
booky10 dc015dc457 Merge pull request #935 from rafi67000/gradleUpdate
Gradle, and shadow update
2024-08-29 22:34:52 +02:00
booky10 fd7bc84cd5 Merge pull request #972 from booky10/fix/workaround-spigot-item-conversion-issues
Use global synchronized registries as fallback
2024-08-29 17:46:19 +02:00
booky10 9fd5b3b912 Use global synchronized registries as fallback for spigot and fabric
Works around issues where plugins convert items to bukkit items, which doesn't preserve registry holder context, e.g. https://github.com/nulli0n/ExcellentEnchants-spigot/blob/8623159ca61b60e1d3cae22c77a99e82b15b9d5f/Core/src/main/java/su/nightexpress/excellentenchants/hook/impl/PacketEventsHook.java
2024-08-29 12:49:12 +02:00
rafi67000 a2d259af58 Update to Gradle 8.10 2024-08-27 20:29:28 +02:00
rafi67000 6cc21a6d98 Merge branch 'retrooper:2.0' into gradleUpdate 2024-08-27 20:13:20 +02:00
retrooper e105770dde Merge pull request #967 from KermanIsPretty/fix/join-game-data-codec-1.7
Fix 1.8< clients not having Reduced Debug Info.
2024-08-27 12:28:49 +02:00
booky10 68b7ee51dc Merge pull request #968 from ManInMyVan/tuff-walls
tuff walls exceed cube
2024-08-26 19:50:22 +02:00
ManInMyVan a4a375f411 tuff walls exceed cube 2024-08-26 11:19:35 -06:00
KermanIsPretty ae6b3d18a4 Fix 1.8< clients not having reducedDebugInfo. 2024-08-25 15:50:02 -05:00
booky10 8763b0e77f Merge pull request #966 from ManInMyVan/fix-inconsistency
Fix inconsistency in StateTypes
2024-08-25 10:55:44 +02:00
ManInMyVan 2440b64981 Fix inconsistency in StateTypes 2024-08-25 01:02:36 -06:00
retrooper ebe73587fe Merge pull request #959 from AoElite/2.0
API for checking if packetevents is terminated
2024-08-22 17:34:43 +02:00
AoElite 5b87ac4f61 unnecessary fix 2024-08-21 08:56:58 -04:00
AoElite d9a3f33199 implement for test 2024-08-21 08:29:16 -04:00
AoElite 9f44834514 don't forget netty one 2024-08-20 21:04:03 -04:00
AoElite 314d4a2813 option to kick on join if terminated & added API for checking if terminated 2024-08-20 21:02:39 -04:00
retrooper 97fee0c898 Merge pull request #956 from booky10/fix/particle-data-decoding-1.20.4
Fix particle data decoding and encoding for <1.20.5
2024-08-21 00:19:56 +02:00
booky10 bdc96a88cd Merge branch '2.0' into fix/particle-data-decoding-1.20.4 2024-08-20 19:33:29 +02:00
retrooper af1691e6e5 Merge pull request #957 from booky10/fix/bungeecord-resolving
Fix bungeecord artifact not resolving
2024-08-20 19:03:40 +02:00
booky10 e4058f7f15 Fix bungeecord artifact not resolving 2024-08-20 18:06:55 +02:00
booky10 7f0c922e10 Fix particle data decoding and encoding for <1.20.5 2024-08-20 17:57:54 +02:00
retrooper 453793eb60 Merge pull request #955 from booky10/fix/item-adventure-predicate-component-reading
Read item adventure predicate nbt and property matchers as optionals
2024-08-20 17:37:45 +02:00
booky10 015e7a4647 Read item adventure predicate nbt and property matchers as optionals 2024-08-20 16:59:17 +02:00
retrooper 45c0c580f7 Merge pull request #954 from booky10/fix/1.19-issues
Fix some 1.19 issues related to registries
2024-08-20 15:39:11 +02:00
booky10 1c12a868c8 Fix chattype decoding and encoding for 1.19 2024-08-20 15:20:54 +02:00
booky10 a3f22320d5 Fix error when handling empty legacy registries 2024-08-20 15:10:57 +02:00
retrooper f4bb1dd8fc kick players even if user is null & they throw an exception, kick user for exceptions also in encoder. 2024-08-18 07:11:01 +02:00
retrooper 5203b3a376 Merge pull request #943 from ManInMyVan/static-getByName
Make BlockTags::getByName static
2024-08-17 20:22:28 +02:00
retrooper fe66d743a9 Merge pull request #949 from booky10/fix/1.16.5-errors
Fix some errors related to old minecraft versions
2024-08-17 20:01:13 +02:00
retrooper 1d1cf84c60 Merge pull request #950 from booky10/fix/dynamic-registry-elements-equality
Don't do deep equals checks for dynamic registry entries
2024-08-17 19:57:02 +02:00
booky10 1c81aab994 Don't do deep equals checks for dynamic registry entries 2024-08-17 19:12:52 +02:00
booky10 52559f6fc8 Fix binary tag holder for adventure <4.10.0 2024-08-17 17:55:29 +02:00
booky10 06cc25bf23 Add workaround to make DimensionType#getId work for 1.16.2 to 1.18.2 2024-08-17 17:49:32 +02:00
booky10 86cf0d51ed Replace usages of translation fallback in ComponentSerializerImpl 2024-08-17 17:36:25 +02:00
booky10 5fbb052d6f Fix wrong recipe serializer definition key 2024-08-17 17:36:09 +02:00
booky10 b7021fcd1f Fix support for adventure <4.10
Replaces Index#valueToKey usages with alternative
Fixes error on join in 1.16.5
2024-08-17 17:22:22 +02:00
booky10 64db7f13c6 Fix support for adventure <4.11
Replaces Index#valueOrThrow usages with copied implementation
Fixes error on join in 1.16.5
2024-08-17 17:05:41 +02:00
retrooper 20c9fdf634 Merge pull request #947 from booky10/fix/dimension-type-npes
Handle null values correctly in StaticDimensionType#equals
2024-08-17 17:03:29 +02:00
booky10 a71035a157 Handle null values correctly in StaticDimensionType#equals 2024-08-17 16:19:56 +02:00
ManInMyVan b0002102e3 Make BlockTags::getByName static 2024-08-15 19:29:07 -06:00
retrooper a3e65cfcbe Merge pull request #939 from rexlManu/2.0
(Velocity) Avoid user if channel cannot be found
2024-08-14 09:35:48 +02:00
Emmanuel Lampe edd9c5ce3d Merge branch 'retrooper:2.0' into 2.0 2024-08-14 05:22:04 +02:00
retrooper e918e6b10a Merge remote-tracking branch 'origin/2.0' into 2.0 2024-08-13 21:04:18 +02:00
retrooper f6c309fd18 add copyright notice to Metrics 2024-08-13 21:03:20 +02:00
retrooper 322a99dbc4 final change in README 2024-08-13 17:50:54 +02:00
retrooper 6793dee0bc More fixes to README 2024-08-13 17:46:39 +02:00
retrooper d33751dbb0 fix BUILD STATUS in README 2024-08-13 17:41:26 +02:00
retrooper fa67de16a1 fixed issues in README 2024-08-13 17:40:10 +02:00
retrooper 57fc21f411 patch readme 2024-08-13 17:37:27 +02:00
retrooper 9999ee3b4a updated README for packetevents 2024-08-13 17:32:03 +02:00
retrooper 4a90cadeb1 Merge pull request #933 from booky10/fix/bungee-server-nullability
Account for null servers in bungee
2024-08-12 18:49:59 +02:00
retrooper 048903f33f Merge pull request #934 from booky10/fix/translation-fallback-adventure
Fix compatibility with adventure versions older than 4.13.0
2024-08-12 18:48:09 +02:00
retrooper 3fa5eaf2a3 Merge pull request #932 from booky10/fix/dimension-type-mappings
Fix dimension type mappings
2024-08-12 18:47:01 +02:00
rafi67000 93bd6d5ac9 Update wrapper 2024-08-12 17:24:04 +02:00
rafi67000 aa5535615c A little tweak... 2024-08-12 17:22:15 +02:00
booky10 9ccd85178d Fix compatibility with adventure versions older than 4.13.0
Translation fallback methods didn't exist before
2024-08-12 17:11:16 +02:00
rafi67000 14fd279c06 Update and switch to maintained shadow fork 2024-08-12 17:07:20 +02:00
rafi67000 6df845324b Update gradle to 8.9 2024-08-12 17:06:59 +02:00
booky10 c3f233ca61 Account for null servers in bungee 2024-08-12 16:47:52 +02:00
booky10 ed4f018b34 Fix dimension type mappings 2024-08-12 16:44:09 +02:00
retrooper ef4bc1c02e github sponsors added as funding option 2024-08-12 09:32:44 +02:00
retrooper ca725b68a5 fix: NPE error in DimensionType#decode 2024-08-12 09:09:02 +02:00
booky10 40f7463e93 Merge pull request #927 from AoElite/2.0
Fix sound exception on 1.21
2024-08-12 00:57:46 +02:00
AoElite 7778768c30 tweak 2024-08-11 18:55:09 -04:00
AoElite 6a6be44ab2 fix sound exception on 1.21 2024-08-11 15:57:12 -04:00
Abhigya fe67c23ad4 Merge pull request #926 from AoElite/2.0
Release item buffer regardless of exception
2024-08-11 23:45:40 +05:30
AoElite c09348d4f7 release item buffer regardless of exception 2024-08-11 13:55:17 -04:00
retrooper e04cd2108f Merge pull request #919 from libraryaddict/patch-2
Fix #916 via removing explicit type call of nbt get
2024-08-10 17:18:35 +02:00
retrooper 39f0dee9f1 Merge pull request #912 from booky10/feat/1.21.1-server-version
Add 1.21.1 version support
2024-08-10 17:16:20 +02:00
libraryaddict 9b9ae8d36c Fix #916 2024-08-10 22:47:03 +12:00
retrooper fc934195de Merge pull request #866 from booky10/feat/network-synced-registries
Network synced registries
2024-08-09 07:49:14 +02:00
retrooper 6c4db8029b chore: bump up version to 2.5.0-SNAPSHOT 2024-08-09 07:46:25 +02:00
retrooper c4ce7b7a87 packetevents version represented as string only provides snapshotCommit if it is a snapshot, not for stable releases. 2024-08-09 07:44:31 +02:00
booky10 b751c63625 Add 1.21.1 version support 2024-08-08 16:44:16 +02:00
retrooper 31ac149b42 Merge pull request #909 from booky10/feat/peversion-build-timestamp
Add build timestamp to PEVersions class
2024-08-06 19:08:17 +02:00
booky10 2f45e9e469 Add equality methods for all dynamic registry value classes 2024-08-06 17:55:27 +02:00
booky10 7b152ff264 Don't store exact copies of vanilla registry elements 2024-08-06 17:25:55 +02:00
booky10 e9eb441a1c Implement caching on bungee platform 2024-08-06 17:19:23 +02:00
booky10 55c1093783 Fix biome and enchantment type definitions on bungee 2024-08-06 17:17:05 +02:00
booky10 963ec4e978 Revert some debug changes which weren't meant to be pushed 2024-08-06 17:09:53 +02:00
booky10 26c30f46e7 Implement key-based registry caching and velocity proxy per-server caching
Bungee isn't finished yet
2024-08-06 17:06:55 +02:00
booky10 c2cdafb17f Add system property to force disable caching 2024-08-06 16:09:38 +02:00
booky10 22060a9889 Actually make caching work by not decoding registries when not needed 2024-08-06 16:08:55 +02:00
booky10 e1a54099a4 Add build timestamp to PEVersions class 2024-08-06 15:24:28 +02:00
retrooper 3fa6a0f69a fix: wrong tag name used in ParticleDustData 2024-08-05 22:48:26 +02:00
retrooper 676cb6c3ce feature: cache legacy registries 2024-08-05 22:34:54 +02:00
retrooper a3063f0bcb feature: cache registries globally on non-proxy servers
Each kind of registry has a VersionedRegistry. This VersionedRegistry now contains a SimpleRegistry as a cache. If the cache is not null, it will be used globally. This makes the usage of registries convenient for PacketEvents users as they no longer need to access them within each user instance. If the plugin is on proxy, we shall store all registries for each user. If the plugin is not on proxy, we shall only store the dimension type registry for each user and globally cache the rest.
2024-08-05 22:17:53 +02:00
retrooper c1520401b6 deletion: remove hard-coded 1.21 enchantment type mappings (as temporary fix) 2024-08-05 22:07:57 +02:00
booky10 d988d0c684 Fix backwards compatibility for dimension type codec 2024-08-04 23:00:46 +02:00
booky10 e2283d6f4e Fix backwards compatibility for encoding trim patterns 2024-08-04 22:39:25 +02:00
booky10 ea56cfde04 Add backwards compatibility support for chat types 2024-08-04 22:34:44 +02:00
booky10 16733e587e Add full legacy data support for biomes 2024-08-04 21:58:28 +02:00
booky10 b247807f0f Fix biome mapping test 2024-08-04 20:30:26 +02:00
booky10 679aea8181 Add even more biome mappings 2024-08-04 18:47:30 +02:00
booky10 f0d499a008 Add more biome mappings 2024-08-04 18:41:22 +02:00
booky10 b5320f2ae7 Fix data reading for biomes and enchantment types 2024-08-04 18:24:52 +02:00
retrooper 0fd0821a93 Merge pull request #907 from booky10/fix/fire-legacy-mappings
Map legacy block ids for fire block
2024-08-04 18:17:59 +02:00
booky10 c7c1b9da17 Map legacy block ids for fire block 2024-08-04 18:15:03 +02:00
retrooper d67d307788 Merge pull request #906 from booky10/fix/component-equality
Fix some component equality checking issues
2024-08-04 18:10:45 +02:00
booky10 c057f18914 Merge branch '2.0' into feat/network-synced-registries 2024-08-04 18:05:46 +02:00
booky10 7a5b425dbb Merge pull request #1 from libraryaddict/feat/network-synced-registries
Feat/network synced registries
2024-08-04 18:01:20 +02:00
booky10 9b22739977 Remove setters from jukebox song interface 2024-08-04 17:56:03 +02:00
booky10 12e0869e0a Fix JukeboxSongs#values javadoc 2024-08-04 17:55:22 +02:00
booky10 0039ab8704 Resolve small backwards compatibility issues 2024-08-04 17:55:12 +02:00
retrooper 7da389db14 feature: 1.21 enchantment mappings (ordered alphabetically) 2024-08-04 16:14:17 +02:00
libraryaddict 1f85797768 Merge pull request #1 from packetevents/2.0
Feature: Create Damage Event wrapper using new Damage Types
2024-08-04 23:49:55 +12:00
retrooper 3c55703718 feature: damage event wrapper using new damage types 2024-08-04 10:50:28 +02:00
booky10 e3734c2d94 Fix some component equality checking issues 2024-08-01 22:41:22 +02:00
Emmanuel Lampe afc571e331 fix(velocity): check for fake connections 2024-08-01 09:59:47 +02:00
libraryaddict 4549d07a6c IJukeboxSong 2024-07-31 17:36:11 +12:00
libraryaddict acc220729b Rename JukeboxSong and StaticJukeboxSong 2024-07-31 01:45:15 +12:00
libraryaddict b27f64c3b1 Missing license disclaimer thingy 2024-07-30 21:17:32 +12:00
libraryaddict 1f7a09a561 Current WIP, adds damage types and jukebox 2024-07-30 21:14:15 +12:00
retrooper f0b15c3f94 Merge pull request #900 from booky10/fix/number-issues-adventure-nbt-serializer
Allow item hover event count to be specified as any number
2024-07-27 11:32:31 +02:00
booky10 cc03d3029d Allow item hover event count to be specified as any number
Fixes compatibility with vanilla codec, as vanilla allows any number to be decoded within DFU
2024-07-23 17:57:46 +02:00
retrooper ef2d24c5ff Merge pull request #894 from booky10/fix/chunk-codec-issues
Fix chunk codec issues
2024-07-23 13:58:58 +02:00
retrooper 6a69d1bcb4 Generics usage in ProtocolPacketEvent for platform-dependent player 2024-07-22 18:50:35 +02:00
retrooper ea1e11d690 Merge pull request #874 from Bram1903/fix/LatestFabricSupport
Fabric 1.21 Support
2024-07-22 11:32:47 +02:00
retrooper 65b51fa6f5 Update javadocs link. 2024-07-19 17:27:25 +02:00
retrooper dae31cedf6 Fix fabric injection, packet listeners now work. 2024-07-19 17:21:32 +02:00
retrooper 6179f997c9 Update fabric version 2024-07-19 16:42:50 +02:00
retrooper 8cb083c29a Correction in PacketListenerPriority documentation, MONITOR should be avoided when modifying. 2024-07-19 13:21:57 +02:00
retrooper 7dd2434ea9 Modification of PacketEvents settings is now marked as internal API behavior. Generally, you are not advised to change the settings.
Unnecessary static in PacketEventsAPI fixed.
2024-07-19 13:17:34 +02:00
booky10 66ca952a1d Add getter/setter for light data in Chunk_v1_9 packet
Would otherwise be impossible to send new chunk layers for 1.9 to 1.13
2024-07-18 19:57:10 +02:00
booky10 d6fef1180f Don't read sky data in overworld dimension for 1.14 to 1.15.2
Sky data in overworld was only present before 1.14
2024-07-18 18:48:13 +02:00
booky10 32451165ba Don't allow usage of singleton palette before 1.18 2024-07-18 18:47:28 +02:00
Bram 2c806b2d4e Removed: foojay-resolver in favor of the foojay-resolver-convention 2024-07-14 11:17:40 +02:00
Bram a8dadfdfff Merge branch 'refs/heads/2.0' into fix/LatestFabricSupport
# Conflicts:
#	settings.gradle.kts
2024-07-14 11:16:32 +02:00
booky10 4524b4289c Merge pull request #883 from booky10/fix/1.21-item-attribute-modifiers-component
Fix reading/writing of item attribute modifier component in 1.21
2024-07-12 23:18:36 +02:00
retrooper 67010e8f11 Merge pull request #885 from booky10/feat/javadoc-publishing
Implement automatic javadoc publishing
2024-07-12 16:39:42 +02:00
retrooper 245ee7699a Merge pull request #890 from booky10/fix/null-material-types
Fix missing material types for vault and heavy core
2024-07-12 16:38:11 +02:00
booky10 25dfb3c5b9 Fix missing material types for vault and heavy core 2024-07-12 16:36:57 +02:00
booky10 52709f279b Update javadoc links 2024-07-11 17:43:23 +02:00
booky10 13d6437638 Remove javadoc pages deployment
Will be handled in different repo, see https://github.com/packetevents/packetevents.github.io
2024-07-11 16:51:46 +02:00
booky10 7a3505070e Restrict javadoc deployment for tag pushes 2024-07-11 01:27:31 +02:00
booky10 7d79603d08 Move api javadoc to pages root 2024-07-11 00:57:37 +02:00
booky10 7890a8ae97 Add javadoc overview 2024-07-11 00:55:54 +02:00
booky10 c73e149f43 Fix spigot javadoc jar generation 2024-07-11 00:24:13 +02:00
booky10 2f72766aac Fix wrong action name 2024-07-10 23:50:33 +02:00
booky10 43d915d09c Add id-token permission to javadoc extraction job 2024-07-10 23:49:47 +02:00
booky10 3444b07f6a Try if github pages upload action works 2024-07-10 23:46:23 +02:00
booky10 3cfb1c5b3e Add initial javadoc upload workflow
Designed to not work yet, just testing if it outputs correct stuff as act is broken for me
2024-07-10 23:15:39 +02:00
booky10 150736b170 Update github build workflow actions 2024-07-10 23:11:20 +02:00
booky10 1f325a36d6 Enable javadoc jar generation 2024-07-10 23:10:56 +02:00
booky10 bdc8f6ef82 Use jvm 21 for kotlin jvm toolchain in buildscript 2024-07-10 23:10:44 +02:00
booky10 d365e4b949 Add foojay resolver convention plugin
Allows automatic download of specified java toolchain jvm version
2024-07-10 23:10:25 +02:00
booky10 4f4a3ba87b Update gradle wrapper to v8.8 2024-07-10 23:06:44 +02:00
retrooper 7ceeaa5f3f Merge pull request #872 from ShadowOfHeaven-Me/2.0
Optimized the EventManager
2024-07-10 21:07:52 +02:00
retrooper 6f968275c1 Merge pull request #882 from KoutaChan/fix-pallet-shift
Fix: Palette index calculation error
2024-07-10 18:29:41 +02:00
booky10 245b7a0d2a Fix reading/writing of item attribute modifier component in 1.21 2024-07-10 16:29:36 +02:00
KoutaChan 13b1007c1c Fix: pallet bit 2024-07-10 23:26:15 +09:00
KoutaChan c164908aac Fix: bit shift error 2024-07-10 23:22:40 +09:00
KoutaChan 1dd28f124a Fix: Palette index calculation error 2024-07-10 23:02:53 +09:00
retrooper 149483ef21 Merge pull request #881 from booky10/fix/version-hash-publishing
Don't specify version hash in published maven pom
2024-07-10 15:49:32 +02:00
booky10 0a689564ce Don't specify version hash in published maven pom 2024-07-10 15:44:33 +02:00
retrooper facc6bc074 Merge pull request #877 from booky10/feat/versioning-commit-hash
Add current commit hash to project version
2024-07-09 22:57:14 +02:00
booky10 41224c9faf Fix snapshot commit for release versions 2024-07-09 22:54:15 +02:00
retrooper 14548f5679 Even more clarity, now LGTM 2024-07-09 22:47:50 +02:00
retrooper d31d0b2487 Correction and clarity to the PEVersion#snapshotCommit method documentation 2024-07-09 22:43:38 +02:00
retrooper 1366872acb Merge pull request #870 from AbhigyaKrishna/mappings-reading-optimization
Mappings reading optimization
2024-07-09 11:41:11 +02:00
retrooper 40fcd23d87 More clarity on the deprecation reason in PEVersion#asArray 2024-07-09 11:31:48 +02:00
retrooper ba7d09ee91 Correction in the documentation of PEVersion: Accuracy in the content and grammar whilst ensuring clarity. 2024-07-09 11:19:08 +02:00
booky10 b0fa4eb3b7 Don't include snapshot commit hash in file name 2024-07-09 01:54:40 +02:00
Bram a8bf163355 Fix: Left behind old shadow plugin convention 2024-07-08 19:00:31 +02:00
booky10 f81730c689 Add snapshot commit api to PEVersion 2024-07-08 15:18:07 +02:00
booky10 a830fe8b63 Adjust PEVersionTask regex to allow any commit hash length 2024-07-08 04:18:25 +02:00
booky10 05c116271e Add current commit hash to project version
Only added when version is a snapshot version
Disables itself if no git directory is found
2024-07-08 04:09:31 +02:00
booky10 a08f89813e Allow chat type decoration parameters to be defined directly 2024-07-08 03:47:39 +02:00
booky10 87fa35dea0 Fix enchantment registry not being able to be replaced
Caused by directly referencing static registry
2024-07-08 03:45:32 +02:00
booky10 4ed644313a Allow enchantment definition slots to be defined directly 2024-07-08 03:43:34 +02:00
booky10 9fdd1615bd Merge branch '2.0' into feat/network-synced-registries 2024-07-08 03:25:15 +02:00
booky10 4ab220f189 Make TrimMaterial override armor materials optional 2024-07-08 03:25:00 +02:00
booky10 adef187685 Fix MappedEntitySet codec 2024-07-08 03:24:21 +02:00
booky10 0e5a443e9b Fix various issues encountered on login 2024-07-08 03:01:45 +02:00
booky10 4961ad6e8d Add biome registry handling to SynchronizedRegistriesHandler
Seems like I forgot to add it there
2024-07-08 02:44:32 +02:00
booky10 e056f1ca0a Implement synchronized painting variant registries 2024-07-08 02:43:58 +02:00
retrooper 9d43fd7a35 Stop re-encoding by default on BungeeCord 2024-07-07 23:56:29 +02:00
AbhigyaKrishna 45bafb37fe feat: HashedByteArray -> BinaryNBTCompound 2024-07-05 22:52:16 +05:30
AbhigyaKrishna 3554f3c6ac feat: Read compound tags in binary format to save memory 2024-07-05 22:42:32 +05:30
AbhigyaKrishna 10d4cf4a9d feat: fabric adventure dependency fix 2024-07-05 20:17:04 +05:30
retrooper 7a1621aa37 Final correction for bungee injector. 2024-07-05 14:11:57 +02:00
retrooper 22a5e67c69 Another correction, but probably obsolete 2024-07-05 13:56:33 +02:00
retrooper 8737ba218a Correct decompress decode method on Bungee. Reflection error. 2024-07-05 13:51:47 +02:00
Bram 98e0a35f0c Removed: Unused Mod Properties in the Fabric module gradle.properties 2024-07-05 10:01:21 +02:00
Bram 21500f3cab Fixed: Another issue in the PacketEventsInjectorMixin 2024-07-04 23:58:13 +02:00
Bram 750d87937a Switched: johnrengelman shadow to googler's shadowjar for Java 21 support (See https://github.com/johnrengelman/shadow/issues/908) 2024-07-04 23:55:25 +02:00
Bram f78ffc9a5c Fixed: PacketEventsInjectorMixin 2024-07-04 23:33:10 +02:00
Bram 48b789d268 Added: foojay-resolver (fixes issues with the latest Fabric Loom dependency
Re-added: Parchment (mixed something up)
Fixed: Compile issue with removed class import
2024-07-04 23:29:29 +02:00
ShadowOfHeaven a765347cba Added a class description 2024-07-04 23:02:54 +02:00
ShadowOfHeaven 21fe4c920d Just a little sneak of my name there 2024-07-04 22:55:05 +02:00
Bram d35505b83a Updated: Fabric Loom 0.11-SNAPSHOT -> 1.7.2
Updated: Gradle Wrapper 8.5 -> 8.7 (Required by Fabric Loom)
Removed: parchmentmc (Fabric Loom provides native support for Parchment mappings as of version 0.9)
Changed: Fabric Dependency id from fabric -> fabric-api (see: https://fabricmc.net/2022/11/24/1193.html)
2024-07-04 21:36:50 +02:00
ShadowOfHeaven 930d1370ce Removed the User value association system. Another PR will be made 2024-07-04 09:45:25 +02:00
ShadowOfHeaven 4f01b9b2d6 Added a User value association system 2024-07-04 00:35:46 +02:00
ShadowOfHeaven 79ae548463 Optimized the EventManager v2 2024-07-03 19:59:41 +02:00
booky10 08120db4b4 Add small biome mapping test 2024-07-03 18:18:38 +02:00
booky10 11d2d979cc Fix biome mapping not being compressed and shadowed 2024-07-03 18:18:26 +02:00
booky10 3822609afe Implement most particle data codecs
Theoretically required for full support of biome data serialization
2024-07-03 18:15:25 +02:00
booky10 dd057ca20f Finish biome effects implementation 2024-07-03 15:16:32 +02:00
ShadowOfHeaven 42403c9f51 Optimized the EventManager 2024-07-03 00:37:35 +02:00
AbhigyaKrishna 9eb6b11fe0 fix: Statistics not being cached 2024-07-03 02:27:32 +05:30
booky10 8c02988330 Save dimension type as reference while decoding
Reference gets resolved when calling the getter, this allows legacy version registries to be swapped before resolving the new dimension type
2024-07-02 18:58:12 +02:00
AbhigyaKrishna fd7223a259 fix: Statistics reading 2024-07-02 15:37:16 +05:30
AbhigyaKrishna b22560852f chores: Update licence 2024-07-02 15:30:06 +05:30
AbhigyaKrishna 3498720e8c feat: Change SequentialNBTReader class design to resemble reader 2024-07-02 15:24:46 +05:30
AbhigyaKrishna 457aed221b fix: NBTEnd not being read when there is no data 2024-07-02 14:39:24 +05:30
AbhigyaKrishna d6fb68d8e7 chores: Update licence 2024-07-02 03:32:50 +05:30
AbhigyaKrishna 0e6c15eb8b feat: Diff load order 2024-07-02 03:30:00 +05:30
AbhigyaKrishna 485124bfef feat: change diff tags order
'removals' tags now come before 'additions' tag
Order: removals, additions, changes
2024-07-02 03:27:53 +05:30
AbhigyaKrishna 3517d1fd00 feat: Refactor SequentialNBTReader 2024-07-02 03:07:38 +05:30
AbhigyaKrishna 7d80f08e1c fix: nbt reading 2024-07-02 03:04:31 +05:30
AbhigyaKrishna ff0af88299 chores: Removed debug statements 2024-07-02 02:16:25 +05:30
booky10 ba08959d39 Add wolf_variant registry and start with biome registry
Biome registry is required for wolf variant registry to fully work
2024-07-01 22:41:13 +02:00
AbhigyaKrishna 050aab96f7 fix: SequentialNBTReader parsing 2024-07-02 02:11:00 +05:30
booky10 afcdfae5a1 Fix version being ignored in User#getMinWorldHeight 2024-07-01 21:13:46 +02:00
booky10 8908cce24f Implement enchantment effect component types 2024-07-01 21:08:49 +02:00
booky10 31447cb6cf Fix test errors 2024-07-01 20:21:02 +02:00
booky10 884ab800f5 Start working on enchantment registry 2024-07-01 19:11:32 +02:00
booky10 6e87103114 Move everything related to registries from InternalPacketListener to new class 2024-07-01 16:24:55 +02:00
booky10 c3b8c213d3 Implement trim_material as a synchronized registry 2024-07-01 16:22:14 +02:00
booky10 33f50a0eb9 Implement trim_pattern as a synchronized registry 2024-07-01 16:12:32 +02:00
booky10 3f309bc92d Migrate usages of chat types to new registry 2024-07-01 16:04:33 +02:00
booky10 8315b8d335 Implement chat_type as a synchronized registry 2024-07-01 15:59:15 +02:00
booky10 902c99aca2 Revert some now useless changes to MappedEntity#getId 2024-07-01 15:41:52 +02:00
booky10 f4fc20a1c8 Revert formatting changes in ChunkReader_v1_7 2024-07-01 15:36:50 +02:00
booky10 0690c45558 Add quality methods to StaticDimensionType 2024-07-01 15:35:11 +02:00
booky10 699fd9ac02 Finish migrating Dimension to DimensionType 2024-07-01 15:32:08 +02:00
booky10 b01db5ca2a Work on creating registries of sent registries 2024-07-01 12:39:13 +02:00
booky10 4fdc9c67ad Finish encode of DimensionType 2024-07-01 12:38:56 +02:00
AbhigyaKrishna 395ed0d58e fix: version mapper initialization 2024-07-01 10:03:17 +05:30
AbhigyaKrishna bcad08260c feat: Implement sequential reading for all mappings 2024-07-01 09:55:34 +05:30
AbhigyaKrishna 06be6d52b2 feat: Implement closeable on sequential reader 2024-07-01 09:55:05 +05:30
AbhigyaKrishna 7ec896b8b0 feat: Updated block mappings for easier access to v2 mapping deserializer 2024-07-01 09:37:39 +05:30
AbhigyaKrishna 2717a94db5 feat: Implement sequential reader in type builder 2024-07-01 09:08:19 +05:30
AbhigyaKrishna 2ea20e3d19 feat: Bump Compression Task version 2024-07-01 09:07:43 +05:30
AbhigyaKrishna 94d939ba67 feat: Changes to mappings format 2024-07-01 08:13:25 +05:30
AbhigyaKrishna 620af0aec0 feat: SequentialNBTReader 2024-07-01 07:15:07 +05:30
AbhigyaKrishna 2299d82b92 feat: Improved NBTSerializer class 2024-07-01 05:56:54 +05:30
AbhigyaKrishna 25dbe61f64 feat: NBTLimiter class rewrite
Rewritten NBTLimiter class with better approach for better extendability
2024-07-01 05:53:41 +05:30
retrooper ecd183156a * Bump version up to 2.4.1-SNAPSHOT
* Marked SpigotReflectionUtil.getEntityById as internal
2024-07-01 00:20:35 +02:00
booky10 3f0cb7e799 Start working on dimension type registry 2024-06-30 23:33:40 +02:00
retrooper 3400877958 Release of 2.4.0 2024-06-30 22:56:57 +02:00
booky10 7b209c9733 Revert changes to Dimension 2024-06-30 22:37:10 +02:00
booky10 dfd490afc8 Merge branch '2.0' into feat/network-synced-registries 2024-06-30 22:34:34 +02:00
retrooper b5a2c0ac29 Merge pull request #865 from cswhite2000/2.0
Switch EventManager listenerSet to CopyOnWriteArraySet
2024-06-30 09:40:48 +02:00
Christopher White c43dd6425a Switch EventManager listenerSet to CopyOnWriteArraySet 2024-06-29 23:21:34 -07:00
retrooper 8b643ae238 Small change of updater messages. 2024-06-30 08:07:55 +02:00
retrooper b07461340e Corrected latest chat type mappings to represent 1.20 2024-06-30 07:59:44 +02:00
retrooper 4cec8fe549 Correct the chat type mappings, temporarily assume that the 1.20.1 is referring to 1.20.2? 2024-06-30 07:56:23 +02:00
booky10 55ea059640 Merge pull request #864 from booky10/fix/sound-mappings-1.21
Fix missing/renamed sounds for 1.21
2024-06-30 05:09:09 +02:00
booky10 5429e80f66 Fix missing/renamed sounds for 1.21 2024-06-30 04:01:06 +02:00
retrooper 16c71fad14 Start working on WolfVariant in EntityMetadata packet. 2024-06-29 00:47:38 +02:00
retrooper d27a97c322 Bump version up to 2.4.0-SNAPSHOT! 2024-06-29 00:46:38 +02:00
retrooper 59ccfa89db Trying out PacketWrapper#writeVarInt optimization, written by Steinborn. 2024-06-29 00:26:55 +02:00
retrooper b6f25939be Correction in javadocs for SpigotConversionUtil 2024-06-29 00:10:23 +02:00
retrooper d19406edf4 Merge pull request #858 from Bram1903/chore/BlockDataMethodCleanup
Removed: Unnecessary 1.7.10 version check and improved JavaDocs
2024-06-29 00:04:29 +02:00
retrooper 0702ff3716 Merge pull request #852 from AbhigyaKrishna/2.0
feat: chat type mappings update
2024-06-29 00:00:22 +02:00
Bram 4577c5a948 Removed: Unnecessary 1.7.10 version check
Added: JavaDocs to SpigotConversionUtil#fromBukkitMaterialData and #toBukkitMaterialData
2024-06-28 16:32:11 +02:00
booky10 d073f716f9 Merge pull request #855 from dawon/bugfix/fix-new-potion-effects
Fix new potion effects
2024-06-27 23:56:06 +02:00
Jakub Zacek 5051c31bea Fix new potion effects 2024-06-27 23:48:47 +02:00
retrooper eb2d91745a Merge pull request #854 from booky10/fix/bungee-compat
Fix more bungee compatibility issues
2024-06-27 21:46:47 +02:00
booky10 9d40bc506e Disable debug mode in bungee plugin 2024-06-27 21:07:29 +02:00
booky10 0fa3be1ce2 Extract channel from player on login
Caused by login success being sent after the PostLoginEvent gets fired
2024-06-27 20:59:28 +02:00
booky10 acecdb57f4 Skip bungeecord query handler handler 2024-06-27 20:58:00 +02:00
retrooper 33d3a72d4d Fix bungee packetevents injector. 2024-06-27 20:18:10 +02:00
retrooper 2ce1fc1e79 Final change to this all 2024-06-27 19:08:56 +02:00
retrooper 63b9e27ebf More changes to the bungee pipeline injector? 2024-06-27 19:04:55 +02:00
retrooper 8093481f08 Last changes to the bungee pipeline injector? 2024-06-27 18:51:35 +02:00
AbhigyaKrishna 629871fcb5 fix: type naming 2024-06-27 21:15:13 +05:30
AbhigyaKrishna d2d9135c45 feat: chat type mappings update 2024-06-27 21:11:15 +05:30
retrooper bf5c3e90b3 Merge pull request #851 from booky10/fix/dimtype-reg-via-velocity
Fix errors on velocity when via is installed on backends
2024-06-27 16:58:01 +02:00
retrooper d100fd54de Delete .travis.yml
We no longer use Travis CI. The Jenkins builds are working again,
2024-06-27 16:54:46 +02:00
retrooper c8137956f1 Merge pull request #799 from booky10/fix/recipe-packet
Fix recipe packet writing/reading
2024-06-27 16:53:18 +02:00
booky10 e7739bac22 Remove MCProtocolLib credits from rewritten classes 2024-06-27 16:36:15 +02:00
booky10 5c9cfcb25d Merge branch '2.0' into fix/recipe-packet 2024-06-27 16:35:08 +02:00
booky10 4364d7a646 Check for dimension type registry name without vanilla namespace 2024-06-27 16:31:57 +02:00
booky10 0ba826f578 Work around missing dimension type registry causing join errors 2024-06-27 16:29:57 +02:00
booky10 92564a3a09 More WIP changes to networked registries 2024-06-27 16:10:20 +02:00
retrooper 3e21b7d384 Merge pull request #836 from ManInMyVan/#693
Add #693
2024-06-27 16:10:20 +02:00
retrooper b934d7361d Merge pull request #844 from booky10/fix/item-hover-component
Support reading components in show_item hover events
2024-06-27 15:55:59 +02:00
booky10 172cfceed7 WIP starting network synchronized registries 2024-06-25 20:47:01 +02:00
retrooper 4047bafc6a Merge pull request #848 from booky10/feat/itemstack-builder-utils
Add utility methods to ItemStack builder
2024-06-24 17:13:36 +02:00
booky10 27de28476e Add utility methods to ItemStack builder
Allows easier modification of components and nbt data
2024-06-24 15:01:29 +02:00
retrooper e5dfb84a53 Update DefaultNBTSerializer 2024-06-24 00:15:50 +02:00
retrooper 2b3c77b6b8 Update DefaultNBTSerializer to have limit for LONG_ARRAY 2024-06-24 00:15:31 +02:00
retrooper 16294ccc63 Merge pull request #847 from Bram1903/fix/NettyVersionResolving
Fix: Netty Version not being properly converted to an PEVersion
2024-06-23 23:56:50 +02:00
Bram 9ae2cd0538 Fix: Netty Version not being properly converted to an PEVersion due to not using semantic versioning 2024-06-23 23:44:13 +02:00
retrooper 30492a7b1f chores: Format the multi-line comment appropriately and clarify references to the generated PEVersions class 2024-06-23 12:10:29 +02:00
AbhigyaKrishna ecce9d8c4e chores: Added default comment to the generated file 2024-06-23 15:32:23 +05:30
AbhigyaKrishna 448f7be2ae fix: include generateVersionFile task in task graph 2024-06-23 02:49:43 +05:30
Abhigya 4e3c45bc7e Merge pull request #819 from Bram1903/feat/GlobalVersioning
Feat: Global Versioning
2024-06-23 00:46:09 +05:30
AbhigyaKrishna ccd3fd4b7b chores: following some code design 2024-06-22 21:35:47 +05:30
Bram 5003d578c7 Fix: toArray being mend to be called asArray 2024-06-22 17:18:15 +02:00
AbhigyaKrishna 881a66740f feat: Removed version resolution from manifest 2024-06-22 15:39:14 +05:30
AbhigyaKrishna c9ae98814c Merge branch 'feat/GlobalVersioning' of github.com:Bram1903/packetevents into Bram1903-feat/GlobalVersioning 2024-06-22 15:36:43 +05:30
AbhigyaKrishna ee2c562c9e feat: PEVersions file generation 2024-06-22 15:33:36 +05:30
Bram cbd38ea581 Reverted: Previously changed comparison method 2024-06-22 11:08:08 +02:00
Bram 983b27d071 Added: Old toArray method and marked it as deprecated to prevent breaking changes 2024-06-22 10:39:03 +02:00
Bram b2a827e97b Merge branch 'refs/heads/2.0' into feat/GlobalVersioning 2024-06-22 10:31:59 +02:00
AbhigyaKrishna a709e5f746 fix: Velocity adventure issue 2024-06-22 08:13:58 +05:30
AbhigyaKrishna c1f482dd35 feat: MappingCompression task to depend on mapping files 2024-06-22 08:13:31 +05:30
booky10 269ca7ad43 Fix support for adventure <4.17.0 2024-06-22 04:17:14 +02:00
booky10 594f8cdc6e Fix show item hover support for <1.20.3 2024-06-22 04:14:20 +02:00
booky10 187041bd47 Support reading components in show_item hover events 2024-06-22 03:29:55 +02:00
booky10 68eb537b66 Merge pull request #843 from booky10/fix/light-data-1.17-newer
Fix light data throwing errors for 1.17+
2024-06-22 01:56:48 +02:00
AbhigyaKrishna b18884a5b3 fix: manifest implementation version should be in shadowJar 2024-06-22 05:19:26 +05:30
AbhigyaKrishna 061d1c25e8 fix: Version comparison 2024-06-22 04:57:11 +05:30
booky10 b1a881bfab Fix light data throwing errors for 1.17+ 2024-06-22 01:26:48 +02:00
AbhigyaKrishna e68dbe4155 chore: method design pattern 2024-06-22 04:56:39 +05:30
AbhigyaKrishna 60e33ef0a3 Merge branch 'feat/GlobalVersioning' of github.com:Bram1903/packetevents into Bram1903-feat/GlobalVersioning 2024-06-22 04:12:04 +05:30
AbhigyaKrishna eac72687cb Merge branch 'Bram1903-feat/NativeFoliaSupport' into 2.0-pe 2024-06-22 04:03:03 +05:30
AbhigyaKrishna d205d83f61 chore: Property access from a global final isFolia variable
Accessing a global final variable is better than having a copy in every class
2024-06-22 04:01:03 +05:30
AbhigyaKrishna 61969bf9df chore: Work directory set to rootDir
Work directory now set to rootDir for easier navigation
2024-06-22 03:45:46 +05:30
AbhigyaKrishna ed9ff0c5da Merge branch 'feat/NativeFoliaSupport' of https://github.com/Bram1903/packetevents into Bram1903-feat/NativeFoliaSupport 2024-06-22 03:34:20 +05:30
Abhigya 371ec62571 Merge pull request #842 from AbhigyaKrishna/2.0
fix: Fixes NoSuchMethodError for GsonComponentSerializer on version 1.16.5
2024-06-22 03:19:31 +05:30
AbhigyaKrishna 4eaf000dea fix: Fixes NoSuchMethodError for GsonComponentSerializer on version 1.16.5
Fixed NoSuchMethodError in GsonComponentSerializer due to older version of abstract classes in version 1.16.5

Ticket: #832
2024-06-22 03:16:19 +05:30
retrooper 97ca0007fc Merge remote-tracking branch 'origin/2.0' into 2.0 2024-06-21 22:44:45 +02:00
retrooper ece10d66c1 Undo something I removed, sorry! 2024-06-21 22:44:30 +02:00
booky10 420a658b0a Merge pull request #835 from libraryaddict/2.0
Divide Color's int rgb by 255 when using for particle colors
2024-06-21 22:21:53 +02:00
booky10 48fbb745e0 Merge branch '2.0' into fix/recipe-packet 2024-06-21 22:15:42 +02:00
retrooper 24d78ef500 Merge remote-tracking branch 'origin/2.0' into 2.0 2024-06-21 22:13:05 +02:00
retrooper a1123cdf67 Fix Paper entity lookup code. 2024-06-21 22:12:33 +02:00
booky10 cd3d3b17b1 Merge pull request #760 from ShadowOfHeaven-Me/WrapperPlayServerMapData-added
Added the missing WrapperPlayServerMapData
2024-06-21 21:44:37 +02:00
booky10 1f2de8a566 Merge pull request #715 from LeeGodSRC/feat/update-light
Added WrapperPlayServerUpdateLight and LightData
2024-06-21 21:32:25 +02:00
LeeGodSRC 74f4d65356 fix: Suggested changes for chunk packets by booky10 2024-06-22 03:16:11 +08:00
retrooper 2be8692661 Fix attempt for conversion between packetevents and bukkit itemstacks. 2024-06-21 13:32:43 +02:00
retrooper 5021eebd55 Final fix for bungee injector. 2024-06-21 13:26:37 +02:00
retrooper 124e59ba70 Another fix for bungee injector. 2024-06-21 13:12:42 +02:00
retrooper 301adfb28f Fix paper entity lookup 2024-06-21 13:06:38 +02:00
retrooper 8d80725cf7 Does this fix the Bungee injector 2024-06-21 12:56:16 +02:00
retrooper 7aa429988b Fixing the BungeeCord injector and the server version detection. (Part 2) 2024-06-21 12:40:43 +02:00
Bram 1cbd15e797 Merge branch 'refs/heads/2.0' into feat/NativeFoliaSupport 2024-06-21 09:11:09 +02:00
Bram 802c707902 Merge branch 'refs/heads/2.0' into feat/GlobalVersioning 2024-06-21 09:10:36 +02:00
retrooper 17d5e3f711 Merge remote-tracking branch 'origin/2.0' into 2.0 2024-06-21 08:05:39 +02:00
retrooper 7a342a8c21 Fixing the BungeeCord injector and the server version detection. 2024-06-21 08:04:53 +02:00
retrooper a4e9a2cd06 Merge pull request #800 from booky10/fix/various-packet-wrapper-issues
Fix various packet wrapper issues
2024-06-21 00:13:02 +02:00
retrooper 4abc4a7403 Update copy method argument in WrapperPlayServerWorldBorderWarningReach (compilation error) 2024-06-21 00:12:38 +02:00
retrooper 2a364895cf Correct constructor naming 2024-06-21 00:07:52 +02:00
retrooper ff56e81136 Correct packet wrapper naming 2024-06-21 00:06:08 +02:00
retrooper 371fcff23a Merge pull request #691 from ytnoos/reencode-fix
Fix re-encode for new bytebufs that were bigger than the received one
2024-06-21 00:03:05 +02:00
retrooper abe5b9f75a Merge pull request #827 from dawon/bugfix/fix-missing-body-slot
Fix missing Equipment body slot
2024-06-20 23:53:44 +02:00
retrooper 2c36b5ad9f Variable naming issue fixed 2024-06-20 23:48:42 +02:00
retrooper 0436b8cb6a Account for client version in EquipmentSlot enum. 2024-06-20 23:42:24 +02:00
retrooper 2fb967ec04 Merge pull request #732 from booky10/dev/1.21
1.21 update
2024-06-20 21:39:43 +02:00
retrooper aafc45d70d No more chat type handling 2024-06-20 21:32:12 +02:00
retrooper 3e25fa641c Minor documentation error fixed 2024-06-18 22:07:15 +02:00
retrooper 3f3c6ba2e1 * ChatMessage_v1_19_1.ChatTypeBoundNetwork relocated to ChatType.Bound (with backwards compatibility)
* ChatMessage_v1_19_1#getChatType -> getChatFormatting
* ChatMessage_v1_19_3#getChatType -> getChatFormatting
* WrapperPlayServerDisguisedChat#getChatType -> getChatFormatting
* ChatTypeDecoration#decorate implemented
2024-06-18 22:03:14 +02:00
retrooper 3175ef85c4 Merge pull request #690 from ytnoos/nbt-limiter
Added NBT, ByteBuf, MessageSignature read limits
2024-06-17 21:40:28 +02:00
retrooper e876b1c95f First effort to network-synchronized registries regarding chat, but please look at TODOs. 2024-06-17 07:09:52 +02:00
retrooper be2094a21f Merge pull request #828 from booky10/fix/block-entity-data-wrapper
Fix block entity data packet wrapper
2024-06-17 06:42:23 +02:00
ManInMyVan 95fdebfb08 Add #693 2024-06-16 12:29:56 -06:00
booky10 5662c7ea9c Fix name of attribute modifiers being unused 2024-06-16 19:48:12 +02:00
booky10 b8587a2487 Support reading int/byte/long arrays when parsing translation arguments
Fixes #801
2024-06-16 16:40:39 +02:00
booky10 1411fd09b9 Fix invalid WrappedBlockState mappings index 2024-06-16 16:28:08 +02:00
booky10 604a48e2dd Make mappings compression task depend on changes to mappings input files 2024-06-16 16:24:14 +02:00
booky10 f091ab69bc Support reading string translation arguments 2024-06-16 16:23:42 +02:00
libraryaddict e22db21f72 Fix particledata color, divide Color's rgb's int by 255f 2024-06-16 21:27:10 +12:00
retrooper 24000fd837 Merge branch '2.0' into dev/1.21 2024-06-16 08:38:32 +02:00
retrooper 87275458bb Merge pull request #833 from booky10/fix/velocity-version-detection
Fix velocity version failing to be detected
2024-06-16 06:58:18 +02:00
booky10 faac9cd83d Mirror changes by user in name/uuid attribute modifier on change 2024-06-16 05:22:03 +02:00
booky10 887a9fa959 Look up private constructor of ResourceLocation
Was made private in 1.21, should normally now be constructed using static methods
2024-06-16 05:07:07 +02:00
booky10 d716309e34 Fix initialization of PacketType 2024-06-16 05:05:05 +02:00
booky10 92603a382b Update attribute modifier encoding
Not perfect but idk how to solve this any better
2024-06-16 04:54:48 +02:00
booky10 88c788f654 Update item type mappings
Something was re-ordered in 24w19a
2024-06-16 04:46:24 +02:00
booky10 bdb429a0b4 Implement jukebox_playable component added with 24w21a 2024-06-16 04:45:21 +02:00
booky10 0c2e09bc7b Implement wrappers for new packets added in 24w21a
Adds wrappers for minecraft:custom_report_details and minecraft:server_links
2024-06-16 04:32:16 +02:00
booky10 131a66220f Add new packet types added with 24w21a 2024-06-16 04:19:16 +02:00
booky10 7e2c6726e0 Merge branch '2.0' into dev/1.21 2024-06-16 04:09:17 +02:00
LeeGodSRC 882e7b57f9 fix: Suggested changes for chunk packets 2024-06-15 21:00:54 +08:00
LeeGodSRC 990a19585f Merge remote-tracking branch 'upstream/2.0' into feat/update-light 2024-06-15 21:00:49 +08:00
booky10 c2f7c92ed4 Fix ClientVersion#getById 2024-06-15 02:32:30 +02:00
booky10 08b420ffb4 Reverse iteration over velocity ProtocolVersion
Newest get chosen first now
2024-06-15 02:32:17 +02:00
booky10 d9a821e44e Fix velocity version failing to detect 2024-06-14 14:17:16 +02:00
Bram 2e39d61d53 Bumped Travis to use Java 21 2024-06-12 09:37:15 +02:00
Bram bb9bd91970 Fixed: Merge Conflicts 2024-06-12 09:30:25 +02:00
Bram a789d9ec83 Merge branch 'refs/heads/2.0' into feat/NativeFoliaSupport
# Conflicts:
#	velocity/build.gradle.kts
2024-06-12 09:28:28 +02:00
Bram 524cf896c3 Fixed: Breaking change by removing an old constructor method.
The method has been marked as deprecated.
2024-06-12 09:25:34 +02:00
Bram 5190d71bc8 Merge branch 'refs/heads/2.0' into feat/GlobalVersioning 2024-06-12 09:20:31 +02:00
retrooper 29dd1cdc03 Merge pull request #794 from IssueDescription/2.0
Add mojang mapped jar support
2024-06-11 23:04:24 +02:00
retrooper cbe517e994 Add shadowJar block 2024-06-11 22:56:54 +02:00
retrooper 5175ed9733 Add mojang mapping attribute 2024-06-11 22:54:43 +02:00
retrooper 26ddcfde2a Merge branch '2.0' of https://github.com/retrooper/packetevents into fork/IssueDescription/2.0 2024-06-11 22:39:35 +02:00
retrooper e17eb7987f Undo BuildScript changes to fix conflict 2024-06-11 22:38:35 +02:00
retrooper 6cc2ac81df Fix package location of ServerPlayer on remapped paper 2024-06-11 19:20:32 +02:00
AbhigyaKrishna 12d16144c0 Merge remote-tracking branch 'pe/2.0' into 2.0-pe 2024-06-11 02:29:38 +05:30
AbhigyaKrishna f4fc034d51 Publication group and artifact naming changes 2024-06-11 02:27:16 +05:30
booky10 42c6df480c Fix block entity data packet wrapper 2024-06-10 20:38:20 +02:00
Jakub Zacek c591335dd4 Fix missing Equipment body slot 2024-06-10 20:34:58 +02:00
retrooper d93e01cca1 Update .travis.yml JDK to 17 2024-06-10 20:30:16 +02:00
retrooper b666a1a62c Update .travis.yml to JDK 17 2024-06-10 20:25:28 +02:00
retrooper fcdac76ba9 Rename travis.yml to .travis.yml 2024-06-10 18:19:58 +02:00
retrooper 3e33d38518 Create travis.yml 2024-06-10 18:17:52 +02:00
AbhigyaKrishna 46dd4be1d3 Publishing group and module group are now consistent
We are probably going to change the naming convention of module and group in future update but this should work for now
2024-06-10 20:14:16 +05:30
AbhigyaKrishna 809517f04b Maven publication pom now have better structure 2024-06-10 03:42:17 +05:30
AbhigyaKrishna f53e73ed9a Try fixing publication dependency resolution 2024-06-09 23:54:47 +05:30
AbhigyaKrishna a7e1852af4 compileOnly -> shadow configuration for pom generation 2024-06-09 01:54:20 +05:30
AbhigyaKrishna 95ac9d8633 Maven Publication for shadow configuration 2024-06-09 01:45:14 +05:30
Bram 8034de3ec3 Improved: JavaDocs 2024-06-08 10:36:28 +02:00
Bram ee6aac43d4 Added: Overload constructor which defaults snapshot to false
Removed: Cloneable interface, and simply returns a new object with the same values.
Added: Getters for the class field (Using Java record naming conventions)
2024-06-08 10:28:14 +02:00
Bram 2fef51f3d4 Rewrote: PEVersion, now implementing Comparable and Cloneable 2024-06-08 00:24:44 +02:00
Bram f27ead56c7 Fixed: Making Gradle not use the cache when just changing version number. 2024-06-07 19:26:35 +02:00
Bram 317853fd8e Merge branch 'refs/heads/2.0' into feat/GlobalVersioning 2024-06-07 19:14:15 +02:00
Bram db8a4184f8 Merge branch 'refs/heads/2.0' into feat/NativeFoliaSupport
# Conflicts:
#	spigot/build.gradle.kts
2024-06-07 19:12:43 +02:00
AbhigyaKrishna 95543c7033 Publication for patch module 2024-06-07 05:03:38 +05:30
AbhigyaKrishna 306f1598e0 Publish configuration 2024-06-07 04:30:02 +05:30
Abhigya 5a26451880 Merge pull request #823 from AbhigyaKrishna/2.0
Publication consistency
2024-06-07 02:50:21 +05:30
AbhigyaKrishna 9384187f06 Publication consistency for with older convention 2024-06-07 02:49:32 +05:30
AbhigyaKrishna 5e414bae58 Revert "Patch for group name"
This reverts commit 990dfc279f.
2024-06-07 02:48:55 +05:30
retrooper 990dfc279f Patch for group name 2024-06-06 23:06:13 +02:00
retrooper 27ec0876cb Publishing patch 2024-06-06 22:50:58 +02:00
retrooper c3853614c5 Merge pull request #814 from AbhigyaKrishna/library-patching
Library patching
2024-06-06 22:36:05 +02:00
_ShadowOfHeaven_ 67855eda8a Merge pull request #1 from booky10/fix/map-data-wrapper-version-compat
Fix map data wrapper version compat
2024-06-06 21:57:17 +02:00
retrooper e2ed78e81d Merge pull request #822 from RaynLegends/2.0
Fix: WrapperPlayServerChunkDataBulk not initialized correctly when instantiated multiple times
2024-06-06 18:26:15 +02:00
RaynLegends 80ae2de524 Fix: WrapperPlayServerChunkDataBulk not initialized correctly when instantiated multiple times
Fixes retrooper/packetevents#821
2024-06-06 11:46:52 +02:00
AbhigyaKrishna af3c440526 Backward compatibility to AdventureNBTSerializer 2024-06-06 10:23:42 +05:30
Bram 8bac60f2db Fixed: Documentation typo 2024-06-05 11:17:48 +02:00
Bram 6d0d1df82e Improved: Version parsing from the manifest implementation by moving it to its own method 2024-06-05 11:10:13 +02:00
Bram 44eba1fbdc Fixed: Unit Tests failing because of not being able to access the jar manifest. 2024-06-05 09:44:10 +02:00
Bram 7ca7eaa346 Improved: Global Versioning 2024-06-05 09:30:44 +02:00
ytnoos fb93dde220 upstream 2024-06-04 21:11:18 +02:00
Abhigya 4f9f58f76f Merge pull request #811 from joshuaprince/fix-map-decoration
Fix map ItemStack decoding for rotation key
2024-06-04 21:00:20 +05:30
Abhigya 4c2ee57f8d Merge pull request #817 from booky10/fix/joingame-respawn-screen
Fix enforcesSecureChat not being read on login packet
2024-06-04 20:52:46 +05:30
booky10 345db7d3f6 Add recipe serializer mappings compression to new mappings task 2024-06-04 14:25:12 +02:00
booky10 ab6df11274 Merge branch '2.0' into fix/recipe-packet 2024-06-04 14:21:45 +02:00
booky10 71ed30e2a9 Fix enforcesSecureChat not being read 2024-06-04 08:53:18 +02:00
AbhigyaKrishna cbfccafce7 Unregister debug listener 2024-06-03 22:57:43 +05:30
AbhigyaKrishna 2888afa999 Update to publish configuration which now includes shadow publication 2024-06-03 22:56:57 +05:30
AbhigyaKrishna 9c4d7cb933 Adventure version resolution fix 2024-06-03 22:54:25 +05:30
AbhigyaKrishna baec4bdd00 MIT Licence 2024-06-03 22:54:11 +05:30
AbhigyaKrishna a00ae8f52c Fix argument parsing 2024-06-03 21:31:36 +05:30
AbhigyaKrishna b973820c59 Shadow configuration for patch module and gson inclusion 2024-06-03 21:08:42 +05:30
AbhigyaKrishna 5fbf597d20 Removed gradle daemon as we are having issues 2024-06-03 21:08:04 +05:30
AbhigyaKrishna cc8bb89ee5 TranslatableArgument patch 2024-06-03 20:51:27 +05:30
AbhigyaKrishna 1f0792f854 Patch ShowItemSerializer and ShowEntitySerializer 2024-06-03 19:51:58 +05:30
AbhigyaKrishna 6b7ebc2162 adventure version bump 2024-06-03 19:47:47 +05:30
AbhigyaKrishna 596a961b05 Rollback constants 2024-06-03 19:30:52 +05:30
AbhigyaKrishna 9586d8da29 Changed adventure library configuration 2024-06-03 17:33:42 +05:30
AbhigyaKrishna 8391c11a7f Parent build function to not include patch module jar 2024-06-03 17:32:52 +05:30
AbhigyaKrishna 51de60ab4f Gradle script update 2024-06-03 16:46:48 +05:30
AbhigyaKrishna 5d14703492 Removed legacy fixes and updated Adventure serializer 2024-06-03 16:46:20 +05:30
AbhigyaKrishna d3968b15db Grouping change for adventure bundle 2024-06-03 16:45:48 +05:30
AbhigyaKrishna 990cc38b67 Configuration update to conventions 2024-06-03 16:45:12 +05:30
AbhigyaKrishna df0d135a72 GsonComponentSerializer patch 2024-06-03 15:57:14 +05:30
AbhigyaKrishna 18ac4937b6 Adventure gson serializer patches 2024-06-03 15:35:43 +05:30
AbhigyaKrishna 531cef241a Configuration changes 2024-06-03 15:35:18 +05:30
AbhigyaKrishna e5353800e7 Patch module 2024-06-03 15:34:52 +05:30
AbhigyaKrishna 21dfaceb22 Custom library patching toolchain 2024-06-03 15:29:31 +05:30
Bram c13454a255 Removed: Unnecessary null initializer 2024-06-02 19:21:50 +02:00
Bram 4f4f5f0578 Fixed: Build workflow by updating the Java version 2024-06-02 14:38:44 +02:00
Bram 02544cd0f5 Greatly improved the TaskWrapper readability 2024-06-02 13:38:27 +02:00
Bram 3ed09a3834 Updated the old FoliaCompatUtil to prevent reflections where possible 2024-06-02 13:08:56 +02:00
Bram 28749faa44 Renamed: serverInitEventClass -> regionizedServerInitEventClass
Added: Documentation on why we are still using reflections for the runTaskOnInit method
2024-06-02 12:59:17 +02:00
Bram 2dbbdcc5d4 Reworked: RegionScheduler to use the RegionScheduler class provided by Paper instead of using reflections 2024-06-02 12:56:44 +02:00
Bram 291266c4bd Reworked: GlobalRegionScheduler to use the GlobalRegionScheduler class provided by Paper instead of using reflections 2024-06-02 12:54:14 +02:00
Bram 411693611a Reworked: EntityScheduler to use the EntityScheduler class provided by Paper instead of using reflections
Fixed: Some AsyncScheduler methods still re-getting the bukkit scheduler
2024-06-02 12:51:17 +02:00
Bram 98c36ff39f Reworked: AsyncScheduler to use the AsyncScheduler class provided by Paper instead of using reflections 2024-06-02 12:42:04 +02:00
Bram 1e69b33d4f Reworked: TaskWrapper to use the ScheduledTask instead of using reflections to access the class 2024-06-02 12:38:58 +02:00
Bram ae2c6cdc4b Added: Proper run paper/velocity tasks 2024-06-02 12:08:14 +02:00
Bram 3104885fb5 Switched: spigot-api -> paper-api 2024-06-02 11:59:13 +02:00
Joshua Prince 081868571b Fix map ItemStack decoding for rotation key
Fixes https://github.com/retrooper/packetevents/issues/810
2024-06-01 16:50:53 -07:00
retrooper 6a3b18aff9 Merge pull request #807 from Bram1903/patch/bStatsSettingRemoval
Removed: bStats Configuration Option
2024-06-01 23:53:03 +02:00
Bram c4caba57bd Merge branch 'refs/heads/2.0' into patch/bStatsSettingRemoval 2024-06-01 23:35:22 +02:00
retrooper c9f3eb32aa Merge pull request #790 from AbhigyaKrishna/gradle-kotlin-dsl
Gradle build chain rework with kotlin DSL
2024-06-01 23:32:55 +02:00
Bram 1dad678f98 Fixed: Saying "removing" instead of "disabling" 2024-05-31 14:11:05 +02:00
Bram 4f579f59c3 Removed: bStats Setting
Deprecated: PacketEventsSettings#bStats
Deprecated: PacketEventsSettings#isbStatsEnabled
2024-05-31 11:56:53 +02:00
retrooper 3352f25ede Merge pull request #805 from booky10/fix/legacy-attributes
Add legacy names for armor and luck attribute
2024-05-30 19:51:06 +02:00
booky10 0378141ac4 Add legacy names for armor and luck attribute
Wasn't present previously because mojang doesn't include them in their attribute rename patch
2024-05-30 17:35:24 +02:00
booky10 9dbb877455 Fix sound effect packet wrapper for <1.9 2024-05-29 20:37:43 +02:00
booky10 ee382176c5 Add missing ResourceLocation#hashCode 2024-05-29 20:27:29 +02:00
booky10 b3d9c1f10f Refactor tags packet wrapper
Also fix support for versions <1.17
2024-05-29 20:25:00 +02:00
booky10 a51ce059e5 Fix serialization of command argument nodes for <1.19 2024-05-29 19:03:53 +02:00
booky10 126bf406ce Add legacy command argument type parsers 2024-05-29 19:02:54 +02:00
booky10 b476d51910 Fix missing seed in entity sound packet wrapper 2024-05-29 17:56:52 +02:00
booky10 02e9f7f901 Fix nbt_compound_tag command argument parser 2024-05-28 22:02:34 +02:00
booky10 0cf411c4de Fix recipe packet writing/reading 2024-05-28 21:17:21 +02:00
booky10 37e2317a5f Fix various packet wrapper constructors 2024-05-28 17:12:22 +02:00
retrooper 415550b354 Merge pull request #789 from MemencioPerez/2.0
Clear the buffer if the packet send event is canceled in Velocity and BungeeCord
2024-05-26 19:14:36 +02:00
retrooper 3b5099f940 NPC#changeSkin properly re-spawns the player on all versions 2024-05-26 14:58:12 +02:00
retrooper 34605f3d72 Fix NPC#despawnAll not emptying channels after usage. 2024-05-26 13:17:39 +02:00
retrooper 8e5eab8bd1 Addition to ByteBufAllocationOperator, new methods declared for further control 2024-05-25 18:19:15 +02:00
retrooper 8cde415712 Merge pull request #795 from booky10/fix/item-stack-enchantments
Fix more issues with ItemStack enchantment components
2024-05-21 20:19:20 +02:00
booky10 c5189d2788 Fix more issues with ItemStack enchantment components
Caused by every item having a default enchantments component set with an empty value
2024-05-21 20:18:01 +02:00
issueDescription e550924b38 Add mojang mapped jar support 2024-05-21 16:48:51 +01:00
AbhigyaKrishna 27d7495f65 Spigot version bump 2024-05-21 01:22:01 +05:30
AbhigyaKrishna 7477483f15 Merge branch 'refs/heads/2.0' into gradle-kotlin-dsl
# Conflicts:
#	spigot/build.gradle
2024-05-21 01:03:25 +05:30
Abhigya 7e064f453a Merge pull request #783 from booky10/fix/spigot-particle-conversions
Fix spigot particle conversion
2024-05-21 00:56:33 +05:30
AbhigyaKrishna f7e58de863 Revert "Update gradle publish github workflow"
This reverts commit 7a135fe0f5.
2024-05-21 00:15:25 +05:30
AbhigyaKrishna 7a135fe0f5 Update gradle publish github workflow
Removed unwanted github workflow tasks
2024-05-21 00:05:24 +05:30
AbhigyaKrishna 8336f1c0ab Misc changes 2024-05-21 00:01:23 +05:30
AbhigyaKrishna 2648f8538d Mapping compression task in kotlin
Rewritten mapping compression task in kotlin
2024-05-20 22:36:26 +05:30
AbhigyaKrishna 6893216ed2 Root project build cycle and javadoc
* Added global jar out task to root project build
* Configured javadoc task to not log warnings
2024-05-19 14:41:22 +05:30
AbhigyaKrishna b6f944ad57 Minor changes and patches to build cycle 2024-05-19 14:25:01 +05:30
Memencio 969f032607 Clear the buffer if the packet send event is canceled in BungeeCord 2024-05-18 19:26:12 -04:00
AbhigyaKrishna daed712bf7 Version catalog for buildSrc
Included version catalog for buildSrc
2024-05-19 04:21:38 +05:30
AbhigyaKrishna 835952a7d2 Gradle convention plugin
Using gradle convention plugin strategy for managing common gradle scripts
2024-05-19 04:08:45 +05:30
AbhigyaKrishna d272f8d19e Gradle kotlin dsl migration
Migrated gradle dsl from groovy to kotlin for easier maintainability
2024-05-19 03:35:45 +05:30
Memencio 8cb8ad7388 Clear the buffer if the packet send event is canceled in Velocity 2024-05-18 16:47:59 -04:00
AbhigyaKrishna 6793fcb928 Versions Catalog
Implementation of version catalog for managing dependencies
2024-05-19 00:18:14 +05:30
retrooper 86ea24d3ee Merge pull request #787 from booky10/fix/paper-1.8-cache-chunk-maps-unload-packet
Account for zero chunk data on unload chunk packet
2024-05-18 18:36:30 +02:00
booky10 69f9c4f500 Account for zero chunk data on unload chunk packet
Sent by Paper 1.8 if cache-chunk-maps is enabled in the paper config
2024-05-18 16:58:59 +02:00
retrooper 3d869f7dfc Merge pull request #786 from booky10/feat/spawn-entity-head-yaw
Add head-yaw methods to spawn entity packet wrapper
2024-05-18 15:35:39 +02:00
booky10 92d716d78e Add head-yaw methods to spawn entity packet wrapper 2024-05-18 15:22:21 +02:00
booky10 8a7f086fdf Fix spigot particle conversion
Fixes #775
2024-05-17 15:23:10 +02:00
booky10 58f6a77287 Implement direct chattype reading 2024-05-15 17:31:46 +02:00
booky10 04110da6f1 Implement direct painting variant reading 2024-05-15 16:54:09 +02:00
booky10 81e5a50b8a Add yaw and pitch to use item packet wrapper 2024-05-15 16:41:05 +02:00
retrooper dfb6787322 Merge pull request #774 from booky10/fix/various-invalid-registry-id-getters
Fix invalid registry ids in various registries
2024-05-12 19:25:55 +02:00
booky10 6b03502307 Fix invalid registry id getting in various registries 2024-05-12 19:22:40 +02:00
retrooper 499d2eea6c Fix CRAFT_PARTICLE_PARTICLES_FIELD being null exception 2024-05-12 17:02:50 +02:00
retrooper fdf1942553 Merge pull request #761 from MemencioPerez/2.0
Fix Encryption Response packet wrapper write method for server versions between 1.19 and 1.19.2
2024-05-11 18:33:03 +02:00
retrooper 9e9b9abb14 Merge pull request #769 from booky10/fix/decorated-pots
Fix pot decorations causing NPEs
2024-05-11 17:08:44 +02:00
booky10 92397b2e4a Fix pot decorations causing NPEs
Now wraps null values in optionals
2024-05-11 17:01:30 +02:00
retrooper 154b789b48 Merge pull request #767 from ItzZisker/2.0
fixed entity id assign bug
2024-05-11 12:01:31 +02:00
ItzZisker 0cee676a69 fixed entity id assign bug 2024-05-11 05:36:35 +03:30
retrooper 387f4661e8 Add ICHUNKPROVIDER class to spigot reflection util 2024-05-10 23:42:37 +02:00
retrooper c261e1d467 Addition of some methods and classes and constructors in SpigotReflectionUtil 2024-05-10 22:32:21 +02:00
booky10 b43a76e682 Initial logic for reading CustomData from non-compounds, WIP 2024-05-10 18:15:49 +02:00
booky10 6efb6f59b1 Update FoodProperties for 1.21 2024-05-10 18:10:26 +02:00
booky10 9f27a49358 Fix flag parsing for <1.13 2024-05-10 18:00:09 +02:00
booky10 5001b21e7a Fix version compatibility for map data packet wrapper 2024-05-10 18:00:07 +02:00
retrooper 24446c61e0 Merge pull request #765 from booky10/fix/particle-mappings-typo
Fix typo in particle mappings for 1.12.2
2024-05-10 17:35:52 +02:00
booky10 d03ed48409 Fix typo in particle mappings for 1.12.2 2024-05-10 17:28:01 +02:00
booky10 840153bc98 Update WrapperPlayServerProjectilePower for 1.21 2024-05-10 16:01:54 +02:00
booky10 f3ee112a4e Merge branch '2.0' into dev/1.21 2024-05-10 15:52:41 +02:00
retrooper 1634eed6e7 Merge pull request #763 from AbhigyaKrishna/2.0
StateValue Map caching
2024-05-10 00:05:35 +02:00
retrooper 6e7dbf13e3 Typo fix 2024-05-10 00:04:09 +02:00
AbhigyaKrishna d60c661d3d StateValue Map caching
Caching and reusing StateValue data map for saving memory
2024-05-10 02:55:30 +05:30
Memencio cd0f1bb241 Fix Encryption Response packet wrapper write method for server versions between 1.19 and 1.19.2 2024-05-09 16:36:04 -04:00
retrooper dd46140147 Implement immutable views on the values within registries 2024-05-09 19:26:58 +02:00
retrooper 337d35f1d8 ReflectionObject#readObjectArray implemented 2024-05-09 18:38:32 +02:00
retrooper 6ad2d61dd3 WrapperPlayServerSoundEffect fixed for 1.8-1.9.4 2024-05-09 18:36:36 +02:00
retrooper 1d6e737611 Bump version up to 2.3.0-SNAPSHOT 2024-05-09 00:41:13 +02:00
_ShadowOfHeaven_ 01e161d37e Added the missing WrapperPlayServerMapData 2024-05-07 23:47:00 +02:00
booky10 bbb3e47a50 Add new attributes for 1.21 2024-05-03 19:27:46 +02:00
booky10 09ab2ff82b Revert legacy itemtypes being changed 2024-05-03 16:24:55 +02:00
booky10 a59a8e116c Update all itemtypes for 1.21 2024-05-03 16:17:47 +02:00
booky10 9adfa831bf Update block and item tags for 1.21 2024-05-03 16:13:56 +02:00
booky10 3a4daec265 Add item type mappings for 1.21 2024-05-03 16:13:47 +02:00
booky10 de87ca203e Implement painting variant registry 2024-05-03 16:07:04 +02:00
booky10 9957cb3de9 Add 1.21 banner patterns 2024-05-03 15:57:17 +02:00
booky10 2ac60d7055 Add 1.21 version constants 2024-05-03 15:55:07 +02:00
leegod 87c2ca3c07 feat: Added getter and setter for LightData in WrapperPlayServerChunkData
chore: Added packet transformation for pre 1.18 (where light data and chunk data are sent separately)
2024-04-16 16:39:26 +08:00
leegod 1f1b1aabd1 feat: Added WrapperPlayServerUpdateLight
chore: Moved away LightData values from WrapperPlayServerChunkData
2024-04-16 16:27:53 +08:00
ytnoos e2865ce4be Fix re-encode for new bytebufs that were bigger than the received one 2024-03-02 10:47:52 +01:00
ytnoos f53f182090 MessageSignature limits 2024-03-02 10:34:35 +01:00
ytnoos 2ec7771a8a ByteBufInputStream limits 2024-03-02 10:32:17 +01:00
ytnoos 75320ef583 implemented NBT read limits following vanilla values 2024-03-02 10:29:02 +01:00
538 changed files with 257274 additions and 33840 deletions

No files matched your search

+1 -3
View File
@@ -1,5 +1,3 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: retrooper
custom: ['https://paypal.me/retrooperdev']
github: [retrooper]
+21 -12
View File
@@ -8,16 +8,19 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v3
- name: Validate gradle wrapper
uses: gradle/actions/wrapper-validation@v3
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '17'
java-version: '21'
distribution: 'adopt'
cache: 'gradle'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
@@ -25,37 +28,43 @@ jobs:
run: chmod +x gradlew && ./gradlew build
- name: Upload build artifacts api
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: api-build
path: api/build/libs
- name: Upload build artifacts spigot
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: spigot-build
path: spigot/build/libs
- name: Upload build artifacts netty-common
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: netty-common-build
path: netty-common/build/libs
- name: Upload build artifacts bungeecord
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: bungeecord-build
path: bungeecord/build/libs
- name: Upload build artifacts velocity
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: velocity-build
path: velocity/build/libs
- name: Upload build artifacts fabric
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: fabric-build
path: fabric/build/libs
path: fabric/build/libs
- name: Upload build artifacts sponge
uses: actions/upload-artifact@v4
with:
name: sponge-build
path: sponge/build/libs
+31 -22
View File
@@ -1,33 +1,42 @@
# packetevents
<!--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>
<h3>Resources</h3>
[![](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://github.com/retrooper/packetevents/blob/2.0/LICENSE) [![](https://github.com/retrooper/packetevents/actions/workflows/build.yml/badge.svg)](https://github.com/retrooper/packetevents/actions) [![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white)](https://discord.gg/prqzNg9tRU)
- [Read documentation](https://docs.packetevents.com/)
- [Getting Started](https://docs.packetevents.com/getting-started)
- [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)
- [SpigotMC](https://www.spigotmc.org/resources/packetevents-api.80279/)
- [Development Builds](https://ci.codemc.io/job/retrooper/job/packetevents)
- [Statistics](https://bstats.org/plugin/bukkit/packetevents/11327)
PacketEvents is a fast and efficient multi-platform packet processing library. Our packet wrappers are easy to use with multi-version support. With our API you can write code that runs on Spigot, BungeeCord, Velocity, and Fabric! Switch to PacketEvents today by joining \
our [Discord Server](https://discord.me/packetevents) for help.
<h3>Sponsors</h3>
### Links
* [Find release builds on Modrinth](https://modrinth.com/plugin/packetevents)
* [Find development builds on Jenkins](https://ci.codemc.io/job/retrooper/job/packetevents)
* [View documentation on our JavaDocs Page](https://packetevents.github.io/javadocs)
<i>Thanks to the following sponsors for supporting this project:</i>
### Setup
[How to Setup PacketEvents](https://github.com/retrooper/packetevents/wiki/Depending-on-pre%E2%80%90built-PacketEvents)
<a href="https://pebblehost.com"><img src="https://pebblehost.com/src/img/logos/main-old.png" width=150><br>
### Examples / How to use PacketEvents
[Example repository](https://github.com/retrooper/packetevents-example)
<a href="https://www.ej-technologies.com"><img src="https://www.ej-technologies.com/images/product_banners/jprofiler_small.png"><br>
### Sponsorships
[![](https://www.ej-technologies.com/images/product_banners/jprofiler_small.png)](https://www.ej-technologies.com/products/jprofiler/overview.html)
<a href="https://github.com/radstevee"><img src="https://github.com/radstevee.png" width="50px" alt="radstevee"/></a><br>
### Statistics
PacketEvents optionally collects statistics using [bStats](https://bstats.org/)\
Check out our [bStats page](https://bstats.org/plugin/bukkit/packetevents/11327)
<h3>Credits</h3>
### Credit to these projects
[wiki.vg/Protocol](https://wiki.vg/Protocol)\
[netty](https://github.com/netty/netty)\
[gson](https://github.com/google/gson)\
[adventure](https://github.com/KyoriPowered/adventure)\
<i>Here are some projects that we are heavily inspired by, thus we have integrated</i>\
<i>small portions of their code into our work.</i>
[Protocol Documentation for the Minecraft Java Edition](https://wiki.vg/Protocol)\
[ViaVersion](https://github.com/ViaVersion/ViaVersion)\
[ProtocolSupport](https://github.com/ProtocolSupport/ProtocolSupport)\
[adventure](https://github.com/KyoriPowered/adventure)\
[MCProtocolLib](https://github.com/GeyserMC/MCProtocolLib/)
-60
View File
@@ -1,60 +0,0 @@
import com.github.retrooper.MappingCompressionTask
// papermc repo + disableAutoTargetJvm needed for mockbukkit
repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
java {
disableAutoTargetJvm()
sourceSets {
main {
resources {
srcDirs += ["$buildDir.canonicalPath/mappings/generated"]
}
}
test {
resources {
srcDirs += ["$buildDir.canonicalPath/mappings/generated"]
}
}
}
}
dependencies {
compileOnly(adventureDependencies)
testImplementation(adventureDependencies)
testImplementation(project(":netty-common"))
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.9.0")
testImplementation("org.slf4j:slf4j-simple:2.0.7")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.0")
}
test {
useJUnitPlatform()
}
task generateMapping(type: MappingCompressionTask) {
mappingsDir = rootDir.toPath().resolve("mappings")
outDir = project.buildDir.toPath().resolve("mappings/generated/assets/mappings")
outputs.upToDateWhen {
def gen_modified = project.buildDir.toPath().resolve("mappings/generated/assets/mappings").toFile().lastModified()
def list = []
project.rootProject.projectDir.toPath().resolve("mappings").toFile().eachFileRecurse(groovy.io.FileType.FILES) { file ->
list << file
}
for (File file : list) {
if (file.lastModified() > gen_modified) {
return false
}
}
return true
}
}
tasks.processResources.dependsOn(generateMapping)
+159
View File
@@ -0,0 +1,159 @@
import com.github.retrooper.compression.strategy.JsonArrayCompressionStrategy
import com.github.retrooper.compression.strategy.JsonObjectCompressionStrategy
import com.github.retrooper.compression.strategy.JsonToNbtStrategy
import com.github.retrooper.excludeAdventure
plugins {
packetevents.`shadow-conventions`
packetevents.`library-conventions`
`mapping-compression`
`pe-version`
}
// papermc repo + disableAutoTargetJvm needed for mockbukkit
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
java {
withJavadocJar()
}
dependencies {
compileOnlyApi(libs.bundles.adventure)
compileOnlyApi(libs.bundles.adventure.serializers)
implementation(libs.adventure.api)
api(project(":patch:adventure-text-serializer-gson", "shadow")) {
excludeAdventure()
}
api(libs.adventure.text.serializer.legacy) {
excludeAdventure()
}
compileOnly(libs.gson)
testImplementation(libs.bundles.adventure)
testImplementation(project(":patch:adventure-text-serializer-gson"))
testImplementation(libs.adventure.text.serializer.legacy)
testImplementation(project(":netty-common"))
testImplementation(testlibs.mockbukkit)
testImplementation(testlibs.slf4j)
testImplementation(testlibs.bundles.junit)
testImplementation(libs.netty)
}
mappingCompression {
mappingDirectory = rootDir.resolve("mappings")
outDirectory = project.layout.buildDirectory.dir("mappings/generated/assets/mappings")
with<JsonToNbtStrategy> {
compress("block/legacy_block_mappings.json")
compress("block/modern_block_mappings.json")
compress("enchantment/enchantment_type_data.json")
compress("item/item_base_components.json")
compress("stats/statistics.json")
compress("world/biome_data.json")
}
with<JsonArrayCompressionStrategy> {
compress("attribute/attribute_mappings.json")
compress("block/block_entity_type_mappings.json")
compress("block/block_type_mappings.json")
compress("chat/chat_type_mappings.json")
compress("command/argument_parser_mappings.json")
compress("damage/damagetype_mappings.json")
compress("enchantment/effect_component_type.json")
compress("entity/entity_data_type_mappings.json")
compress("entity/painting_mappings.json")
compress("entity/wolf_variant_mappings.json")
compress("item/consume_effect_type_mappings.json")
compress("item/item_armor_material_mappings.json")
compress("item/item_banner_pattern_mappings.json")
compress("item/item_component_mappings.json")
compress("item/item_instrument_mappings.json")
compress("item/item_jukebox_song_mappings.json")
compress("item/item_map_decoration_type_mappings.json")
compress("item/item_potion_mappings.json")
compress("item/item_trim_material_mappings.json")
compress("item/item_trim_pattern_mappings.json")
compress("item/recipe_book_category.json")
compress("item/recipe_display_types.json")
compress("item/recipe_serializer_mappings.json")
compress("item/recipe_slot_display_types.json")
compress("particle/particle_type_mappings.json")
compress("sound/sound_mappings.json")
compress("world/biome_mappings.json")
compress("world/world_position_source_mappings.json")
}
with<JsonObjectCompressionStrategy> {
compress("enchantment/enchantment_type_mappings.json")
compress("entity/entity_effect_mappings.json")
compress("entity/entity_type_mappings.json")
compress("entity/legacy_entity_type_mappings.json")
compress("item/item_type_mappings.json")
compress("world/dimension_type_mappings.json")
}
}
tasks {
assemble {
setDependsOn(dependsOn.filterNot { it == "shadowNoAdventure" })
}
javadoc {
mustRunAfter(generateVersionsFile)
}
sourcesJar {
mustRunAfter(generateVersionsFile)
}
withType<JavaCompile> {
dependsOn(generateVersionsFile)
}
processResources {
dependsOn(compressMappings)
from(project.layout.buildDirectory.dir("mappings/generated").get())
}
generateVersionsFile {
packageName = "com.github.retrooper.packetevents.util"
}
test {
useJUnitPlatform()
}
shadowJar {
exclude {
val path = it.path
path.startsWith("net/kyori") && !path.startsWith("net/kyori/adventure/text/serializer") && !path.startsWith("net/kyori/option")
}
}
}
publishing {
publications {
named<MavenPublication>("shadow") {
artifact(tasks["javadocJar"])
}
}
}
@@ -27,33 +27,34 @@ import com.github.retrooper.packetevents.netty.NettyManager;
import com.github.retrooper.packetevents.settings.PacketEventsSettings;
import com.github.retrooper.packetevents.util.LogManager;
import com.github.retrooper.packetevents.util.PEVersion;
//Note: The PEVersions class is generated. Refer to PEVersionTask.kt
import com.github.retrooper.packetevents.util.PEVersions;
import com.github.retrooper.packetevents.util.updatechecker.UpdateChecker;
import java.util.logging.Logger;
public abstract class PacketEventsAPI<T> {
private static final EventManager EVENT_MANAGER = new EventManager();
private static final PacketEventsSettings SETTINGS = new PacketEventsSettings();
private static final UpdateChecker UPDATE_CHECKER = new UpdateChecker();
private final Logger LOGGER = Logger.getLogger(PacketEventsAPI.class.getName());
private static final LogManager LOG_MANAGER = new LogManager();
//TODO UPDATE
private static final PEVersion VERSION = new PEVersion(2, 3, 0);
private final EventManager eventManager = new EventManager();
private final PacketEventsSettings settings = new PacketEventsSettings();
private final UpdateChecker updateChecker = new UpdateChecker();
private final LogManager logManager = new LogManager();
private static final Logger LOGGER = Logger.getLogger(PacketEventsAPI.class.getName());
public EventManager getEventManager() {
return EVENT_MANAGER;
return eventManager;
}
public PacketEventsSettings getSettings() {
return SETTINGS;
return settings;
}
public UpdateChecker getUpdateChecker() {
return UPDATE_CHECKER;
return updateChecker;
}
public PEVersion getVersion() {
return VERSION;
//Note: The PEVersions class is generated by the auto-version task. Refer to PEVersionTask.kt
return PEVersions.CURRENT;
}
public Logger getLogger() {
@@ -61,7 +62,7 @@ public abstract class PacketEventsAPI<T> {
}
public LogManager getLogManager() {
return LOG_MANAGER;
return logManager;
}
public abstract void load();
@@ -74,6 +75,8 @@ public abstract class PacketEventsAPI<T> {
public abstract void terminate();
public abstract boolean isTerminated();
public abstract T getPlugin();
public abstract ServerManager getServerManager();
@@ -24,11 +24,35 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Level;
/**
* Class for event managing. Implements both, internal and API methods.
*
* @apiNote It is highly recommended to register the event listeners at server start-up,
* without frequent modifications during runtime, since this class needs to recalculate all of
* its event listeners during any modifications. In other words, it assumes that reads (events fired)
* greatly outnumber writes (listeners modifications). If your case requires frequent listener modifications,
* open a pull request on GitHub and describe your case.
*
* @author retrooper
* @author ShadowOfHeaven (optimization)
*
*/
public class EventManager {
private final Map<PacketListenerPriority, Set<PacketListenerCommon>> listenersMap =
Collections.synchronizedMap(new EnumMap<>(PacketListenerPriority.class));
//Using a ConcurrentHashMap is faster and more secure here, compared to Collections.synchronizedMap(new EnumMap<>(PacketListenerPriority.class))
//This is mainly due to:
//1. On each modification Collections.synchronizedMap synchronizes the whole Map object, while ConcurrentHashMap only it's internal, currently modified Node
//2. ConcurrentHashMap won't fail in a multi-thread environment, while Collections.synchronizedMap is said to have a lot of potential problems,
//being a generalized method for synchronization
private final Map<PacketListenerPriority, Set<PacketListenerCommon>> listenersMap = new ConcurrentHashMap<>();
//Since reads greatly outnumber writes, create an array for the best possible iteration time
//Updated as a whole on writes, no index modifications are allowed
private volatile PacketListenerCommon[] listeners = new PacketListenerCommon[0];
/**
* Call the PacketEvent.
@@ -43,32 +67,43 @@ public class EventManager {
callEvent(event, null);
}
/**
* Call the PacketEvent.
* This method processes the event on all the registered dynamic packet event listeners.
* The {@link PacketListenerPriority#LOWEST} prioritized listeners will be processing first,
* the {@link PacketListenerPriority#MONITOR} will be processing last and can
* be the final decider whether the event has been cancelled or not.
*
* @param event {@link PacketEvent}
* @param postCallListenerAction The action to be ran after all the listeners have finished processing
*/
public void callEvent(PacketEvent event, @Nullable Runnable postCallListenerAction) {
for (PacketListenerPriority priority : PacketListenerPriority.values()) {
Set<PacketListenerCommon> listeners = listenersMap.get(priority);
if (listeners != null) {
for (PacketListenerCommon listener : listeners) {
try {
event.call(listener);
} catch (Exception t) {
// ignore handshake exceptions
if (t.getClass() != InvalidHandshakeException.class) {
PacketEvents.getAPI().getLogger().log(Level.WARNING, "PacketEvents caught an unhandled exception while calling your listener.", t);
}
}
if (postCallListenerAction != null) {
postCallListenerAction.run();
}
for (PacketListenerCommon listener : listeners) {
try {
event.call(listener);
} catch (Exception t) {
// ignore handshake exceptions
if (t.getClass() != InvalidHandshakeException.class) {
PacketEvents.getAPI().getLogger().log(Level.WARNING, "PacketEvents caught an unhandled exception while calling your listener.", t);
}
}
if (postCallListenerAction != null) {
postCallListenerAction.run();
}
}
// For performance reasons, we don't want to re-encode the packet if it's not needed.
if (event instanceof ProtocolPacketEvent && !((ProtocolPacketEvent<?>) event).needsReEncode()) {
((ProtocolPacketEvent<?>) event).setLastUsedWrapper(null);
if (event instanceof ProtocolPacketEvent && !((ProtocolPacketEvent) event).needsReEncode()) {
((ProtocolPacketEvent) event).setLastUsedWrapper(null);
}
}
/**
* Register the dynamic packet event listener.
*
* @param listener {@link PacketListenerCommon}
* @param priority {@link PacketListenerPriority}
*/
public PacketListenerCommon registerListener(PacketListener listener, PacketListenerPriority priority) {
PacketListenerCommon packetListenerAbstract = listener.asAbstract(priority);
return registerListener(packetListenerAbstract);
@@ -80,12 +115,8 @@ public class EventManager {
* @param listener {@link PacketListenerCommon}
*/
public PacketListenerCommon registerListener(PacketListenerCommon listener) {
Set<PacketListenerCommon> listenerSet = listenersMap.get(listener.getPriority());
if (listenerSet == null) {
listenerSet = ConcurrentHashMap.newKeySet();
}
listenerSet.add(listener);
listenersMap.put(listener.getPriority(), listenerSet);
this.registerListenerNoRecalculation(listener);
this.recalculateListeners();
return listener;
}
@@ -96,21 +127,22 @@ public class EventManager {
*/
public PacketListenerCommon[] registerListeners(PacketListenerCommon... listeners) {
for (PacketListenerCommon listener : listeners) {
registerListener(listener);
this.registerListenerNoRecalculation(listener);
}
this.recalculateListeners();
return listeners;
}
public void unregisterListener(PacketListenerCommon listener) {
Set<PacketListenerCommon> listenerSet = listenersMap.get(listener.getPriority());
if (listenerSet == null) return;
listenerSet.remove(listener);
if (this.unregisterListenerNoRecalculation(listener)) this.recalculateListeners();
}
public void unregisterListeners(PacketListenerCommon... listeners) {
boolean modified = false;
for (PacketListenerCommon listener : listeners) {
unregisterListener(listener);
modified |= this.unregisterListenerNoRecalculation(listener);//OR - at least one of these needs to be true to return true, meaning the boolean will permanently stay true if once set so
}
if (modified) this.recalculateListeners();
}
@@ -118,6 +150,36 @@ public class EventManager {
* Unregister all dynamic packet event listeners.
*/
public void unregisterAllListeners() {
listenersMap.clear();
this.listenersMap.clear();
synchronized (this) {//like booky10 said, the synchronization is necessary here
this.listeners = new PacketListenerCommon[0];
}
}
//Needs to be synchronized in order to avoid race conditions (for example where the 'listeners' variable
//is overridden by its non-up-to-date value, simply because it finished a bit later than the most recent update)
private void recalculateListeners() {
synchronized (this) {
List<PacketListenerCommon> list = new ArrayList<>();
//adds from LOWEST to MONITOR, so in the correct order
for (PacketListenerPriority priority : PacketListenerPriority.values()) {
Set<PacketListenerCommon> set = this.listenersMap.get(priority);
if (set != null) list.addAll(set);
}
this.listeners = list.toArray(new PacketListenerCommon[0]);
}
}
//Internal registration methods, specifically separated for lesser overhead when registering an array of Listeners
private void registerListenerNoRecalculation(PacketListenerCommon listener) {
Set<PacketListenerCommon> listenerSet = this.listenersMap.computeIfAbsent(listener.getPriority(), p -> new CopyOnWriteArraySet<>());
listenerSet.add(listener);
}
//Returns true if the listener was removed, so a modification occurred
private boolean unregisterListenerNoRecalculation(PacketListenerCommon listener) {
Set<PacketListenerCommon> listenerSet = this.listenersMap.get(listener.getPriority());
return listenerSet != null && listenerSet.remove(listener);
}
}
@@ -30,8 +30,7 @@ package com.github.retrooper.packetevents.event;
*/
public enum PacketListenerPriority {
/**
* Listener is of very low importance.
* This listener will be ran first.
* This listener will be run first and has little say in the outcome of events.
*/
LOWEST,
@@ -41,8 +40,11 @@ public enum PacketListenerPriority {
LOW,
/**
* Default listener priority.
* Listener is neither important nor unimportant and may run normally.
* The normal listener priority.
* If possible, always pick this.
* It allows other projects to easily overturn your decisions.
* Moreover, it is pretty bold to assume that your project should
* always have the final say.
*/
NORMAL,
@@ -52,13 +54,13 @@ public enum PacketListenerPriority {
HIGH,
/**
* Listener is of critical importance and wants to decide the cancellation of an event.
* Listener is of critical importance. Use this to decide the final state of packets.
*/
HIGHEST,
/**
* Listener is purely trying to decide the cancellation of an event.
* This listener should be ran last.
* Only use this priority if you want to perform logic based on the outcome of an event.
* Please do not modify packets in this stage.
*/
MONITOR;
@@ -18,7 +18,6 @@
package com.github.retrooper.packetevents.event;
import com.github.retrooper.packetevents.event.simple.*;
import com.github.retrooper.packetevents.exception.PacketProcessException;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
@@ -26,7 +25,7 @@ import com.github.retrooper.packetevents.protocol.PacketSide;
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
import com.github.retrooper.packetevents.protocol.player.User;
public class PacketReceiveEvent extends ProtocolPacketEvent<Object> {
public class PacketReceiveEvent extends ProtocolPacketEvent {
protected PacketReceiveEvent(Object channel, User user, Object player, Object rawByteBuf,
boolean autoProtocolTranslation) throws PacketProcessException {
super(PacketSide.CLIENT, channel, user, player, rawByteBuf, autoProtocolTranslation);
@@ -29,7 +29,7 @@ import com.github.retrooper.packetevents.protocol.player.User;
import java.util.ArrayList;
import java.util.List;
public class PacketSendEvent extends ProtocolPacketEvent<Object> {
public class PacketSendEvent extends ProtocolPacketEvent {
private List<Runnable> tasksAfterSend = null;
protected PacketSendEvent(Object channel, User user, Object player, Object rawByteBuf,
@@ -24,11 +24,11 @@ package com.github.retrooper.packetevents.event;
* @author retrooper
* @since 1.6.9
*/
public interface PlayerEvent<T> {
public interface PlayerEvent {
/**
* Associated player.
*
* @return Player.
*/
T getPlayer();
<T> T getPlayer();
}
@@ -36,14 +36,15 @@ 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;
public abstract class ProtocolPacketEvent<T> extends PacketEvent implements PlayerEvent<T>, CancellableEvent, UserEvent {
public abstract class ProtocolPacketEvent extends PacketEvent implements PlayerEvent, CancellableEvent, UserEvent {
private final Object channel;
private final ConnectionState connectionState;
private final User user;
private final T player;
private final Object player;
private Object byteBuf;
private final int packetID;
private final PacketTypeCommon packetType;
@@ -55,7 +56,7 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
private boolean needsReEncode = PacketEvents.getAPI().getSettings().reEncodeByDefault();
public ProtocolPacketEvent(PacketSide packetSide, Object channel,
User user, T player, Object byteBuf,
User user, Object player, Object byteBuf,
boolean autoProtocolTranslation) throws PacketProcessException {
this.channel = channel;
this.user = user;
@@ -92,7 +93,7 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
}
public ProtocolPacketEvent(int packetID, PacketTypeCommon packetType, ServerVersion serverVersion, Object channel,
User user, T player, Object byteBuf) {
User user, Object player, Object byteBuf) {
this.channel = channel;
this.user = user;
this.player = player;
@@ -123,8 +124,15 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
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
@@ -133,8 +141,8 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
}
@Override
public T getPlayer() {
return player;
public <T> T getPlayer() {
return (T) player;
}
public ConnectionState getConnectionState() {
@@ -213,7 +221,7 @@ public abstract class ProtocolPacketEvent<T> extends PacketEvent implements Play
}
@Override
public ProtocolPacketEvent<?> clone() {
public ProtocolPacketEvent clone() {
return this instanceof PacketReceiveEvent ? ((PacketReceiveEvent) this).clone()
: ((PacketSendEvent) this).clone();
}
@@ -20,7 +20,7 @@ package com.github.retrooper.packetevents.event;
import com.github.retrooper.packetevents.protocol.player.User;
public class UserLoginEvent extends PacketEvent implements CallableEvent, UserEvent, PlayerEvent<Object> {
public class UserLoginEvent extends PacketEvent implements CallableEvent, UserEvent, PlayerEvent {
private final User user;
private final Object player;
@@ -35,8 +35,8 @@ public class UserLoginEvent extends PacketEvent implements CallableEvent, UserEv
}
@Override
public Object getPlayer() {
return player;
public <T> T getPlayer() {
return (T) player;
}
@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;
}
}
@@ -26,31 +26,20 @@ import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.manager.protocol.ProtocolManager;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.ConnectionState;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
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.resources.ResourceLocation;
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.configuration.server.WrapperConfigServerRegistryData.RegistryElement;
import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake;
import com.github.retrooper.packetevents.wrapper.login.server.WrapperLoginServerLoginSuccess;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerJoinGame;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
import java.net.InetSocketAddress;
import java.util.List;
public class InternalPacketListener extends PacketListenerAbstract {
private static final ResourceLocation DIMENSION_TYPE_REGISTRY_KEY =
ResourceLocation.minecraft("dimension_type");
public InternalPacketListener() {
this(PacketListenerPriority.LOWEST);
}
@@ -92,70 +81,37 @@ public class InternalPacketListener extends PacketListenerAbstract {
}
}
// The server sends dimension information in configuration phase >= 1.20.2
// The server sends dimension information in configuration phase, since 1.20.2
else if (event.getPacketType() == PacketType.Configuration.Server.REGISTRY_DATA) {
WrapperConfigServerRegistryData registryData = new WrapperConfigServerRegistryData(event);
WrapperConfigServerRegistryData packet = new WrapperConfigServerRegistryData(event);
// Store world data
NBTCompound registryDataTag = registryData.getRegistryData();
NBTList<NBTCompound> list = null;
if (registryDataTag != null) { // <1.20.5
list = registryDataTag
.getCompoundTagOrNull(DIMENSION_TYPE_REGISTRY_KEY.toString())
.getCompoundListTagOrNull("value");
} else if (DIMENSION_TYPE_REGISTRY_KEY.equals(registryData.getRegistryKey())) { // >=1.20.5
// remap to legacy format
list = new NBTList<>(NBTType.COMPOUND);
List<RegistryElement> elements = registryData.getElements();
if (elements != null) {
int i = 0;
for (RegistryElement element : elements) {
NBTCompound tag = new NBTCompound();
tag.setTag("name", new NBTString(element.getId().toString()));
tag.setTag("id", new NBTInt(i++));
if (element.getData() != null) { // may be null because of known packs not being sent
tag.setTag("element", element.getData());
}
list.addTag(tag);
}
}
if (packet.getElements() != null) { // 1.20.2 to 1.20.5
SynchronizedRegistriesHandler.handleRegistry(user, packet.getServerVersion().toClientVersion(),
packet.getRegistryKey(), packet.getElements());
}
if (list != null) {
user.setWorldNBT(list);
if (packet.getRegistryData() != null) { // since 1.20.5
SynchronizedRegistriesHandler.handleLegacyRegistries(user, packet.getServerVersion()
.toClientVersion(), packet.getRegistryData());
}
}
// The server sends dimension information in login packet for >= 1.17 and < 1.20.2
// The server sends registry info in login packet for 1.16 to 1.20.1
else if (event.getPacketType() == PacketType.Play.Server.JOIN_GAME) {
WrapperPlayServerJoinGame joinGame = new WrapperPlayServerJoinGame(event);
user.setEntityId(joinGame.getEntityId());
user.setDimension(joinGame.getDimension());
if (event.getServerVersion().isOlderThanOrEquals(ServerVersion.V_1_16_5)) {
return; // Fixed world height, no tags are sent to the client
if (joinGame.getDimensionCodec() != null) { // 1.16 to 1.20.1
SynchronizedRegistriesHandler.handleLegacyRegistries(user, joinGame.getServerVersion().toClientVersion(),
joinGame.getDimensionCodec());
}
// Store world data
NBTCompound dimensionCodec = joinGame.getDimensionCodec();
if (dimensionCodec != null) {
NBTList<NBTCompound> list = dimensionCodec
.getCompoundTagOrNull(DIMENSION_TYPE_REGISTRY_KEY.toString())
.getCompoundListTagOrNull("value");
user.setWorldNBT(list);
}
// Update world height
user.switchDimensionType(joinGame.getServerVersion(), joinGame.getDimension());
user.setDimensionType(joinGame.getDimensionType());
}
// Respawn is used to switch dimensions
else if (event.getPacketType() == PacketType.Play.Server.RESPAWN) {
WrapperPlayServerRespawn respawn = new WrapperPlayServerRespawn(event);
user.setDimension(respawn.getDimension());
if (event.getServerVersion().isOlderThanOrEquals(ServerVersion.V_1_16_5)) {
return; // Fixed world height, no tags are sent to the client
}
user.switchDimensionType(respawn.getServerVersion(), respawn.getDimension());
WrapperPlayServerRespawn packet = new WrapperPlayServerRespawn(event);
user.setDimensionType(packet.getDimensionType());
} else if (event.getPacketType() == PacketType.Play.Server.CONFIGURATION_START) {
user.setEncoderState(ConnectionState.CONFIGURATION);
} else if (event.getPacketType() == PacketType.Configuration.Server.CONFIGURATION_END) {
@@ -167,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) {
@@ -104,10 +104,13 @@ public interface ProtocolManager {
PacketWrapper<?>[] wrappers = PacketTransformationUtil.transform(wrapper);
Object[] buffers = new Object[wrappers.length];
for (int i = 0; i < wrappers.length; i++) {
wrappers[i].prepareForSend(channel, outgoing);
buffers[i] = wrappers[i].buffer;
// Fix race condition when sending packets to multiple people (due to when the buffer is freed)
wrappers[i].buffer = null;
PacketWrapper<?> wrappper = wrappers[i];
synchronized (wrappper.bufferLock) {
wrappper.prepareForSend(channel, outgoing);
buffers[i] = wrappper.buffer;
// Fix race condition when sending packets to multiple people (due to when the buffer is freed)
wrappper.buffer = null;
}
}
return buffers;
}
@@ -18,6 +18,10 @@
package com.github.retrooper.packetevents.manager.server;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.player.User;
import org.jetbrains.annotations.Nullable;
public interface ServerManager {
/**
* Get the server version.
@@ -34,4 +38,20 @@ public interface ServerManager {
default SystemOS getOS() {
return SystemOS.getOS();
}
/**
* Gets a platform-specific network-synchronized-registries cache key.
* <p>
* This tells packetevents, if a registry should be cached or read again. On
* backend servers with global registries, this may be a constant value. On
* proxy servers with per-server registries, this may be a value which depends
* on the current server the {@link User} is on.
*
* @param user the {@link User} for which the registry gets read
* @param version the version the packet is for
* @return some value or null for no caching at all
*/
default @Nullable Object getRegistryCacheKey(User user, ClientVersion version) {
return null; // no caching
}
}
@@ -49,6 +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. 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);
@@ -24,8 +24,11 @@ public interface ByteBufAllocationOperator {
Object copiedBuffer(byte[] bytes);
Object buffer();
Object buffer(int initialCapacity);
Object directBuffer();
Object directBuffer(int initialCapacity);
Object compositeBuffer();
Object compositeBuffer(int maxNumComponents);
}
@@ -103,6 +103,14 @@ public class ByteBufHelper {
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeShort(buffer, value);
}
public static int readMedium(Object buffer) {
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().readMedium(buffer);
}
public static void writeMedium(Object buffer, int value) {
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeMedium(buffer, value);
}
public static int readInt(Object buffer) {
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().readInt(buffer);
}
@@ -42,27 +42,27 @@ public class ByteBufInputStream extends InputStream implements DataInput {
this(buffer, ByteBufHelper.readableBytes(buffer), releaseOnClose);
}
public ByteBufInputStream(Object buffer, int length, boolean releaseOnClose) {
public ByteBufInputStream(Object buffer, int maxLength, boolean releaseOnClose) {
this.lineBuf = new StringBuilder();
if (buffer == null) {
throw new NullPointerException("buffer");
} else if (length < 0) {
} else if (maxLength < 0) {
if (releaseOnClose) {
ByteBufHelper.release(buffer);
}
throw new IllegalArgumentException("length: " + length);
} else if (length > ByteBufHelper.readableBytes(buffer)) {
throw new IllegalArgumentException("maxLength: " + maxLength);
} else if (ByteBufHelper.readableBytes(buffer) > maxLength) {
if (releaseOnClose) {
ByteBufHelper.release(buffer);
}
throw new IndexOutOfBoundsException("Too many bytes to be read - Needs " + length + ", maximum is " + ByteBufHelper.readableBytes(buffer));
throw new IndexOutOfBoundsException("Too many bytes to be read - Found " + ByteBufHelper.readableBytes(buffer) + ", maximum is " + maxLength);
} else {
this.releaseOnClose = releaseOnClose;
this.buffer = buffer;
this.startIndex = ByteBufHelper.readerIndex(buffer);
this.endIndex = this.startIndex + length;
this.endIndex = this.startIndex + ByteBufHelper.readableBytes(buffer);
ByteBufHelper.markReaderIndex(buffer);
}
}
@@ -35,12 +35,14 @@ public interface ByteBufOperator {
byte readByte(Object buffer);
short readShort(Object buffer);
int readMedium(Object buffer);
int readInt(Object buffer);
long readUnsignedInt(Object buffer);
long readLong(Object buffer);
void writeByte(Object buffer, int value);
void writeShort(Object buffer, int value);
void writeMedium(Object buffer, int value);
void writeInt(Object buffer, int value);
void writeLong(Object buffer, long value);
@@ -40,4 +40,16 @@ public class UnpooledByteBufAllocationHelper {
public static Object compositeBuffer() {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer();
}
public static Object buffer(int initialCapacity) {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().buffer(initialCapacity);
}
public static Object directBuffer(int initialCapacity) {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().directBuffer(initialCapacity);
}
public static Object compositeBuffer(int maxNumComponents) {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer(maxNumComponents);
}
}
@@ -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,87 +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");
// Added in 1.20.5
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("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;
}
}
@@ -18,8 +18,150 @@
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;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.util.Index;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
public interface ChatType extends MappedEntity {
import java.util.Objects;
import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow;
public interface ChatType extends MappedEntity, CopyableEntity<ChatType>, DeepComparableEntity {
@UnknownNullability("only nullable for 1.19")
ChatTypeDecoration getChatDecoration();
@ApiStatus.Obsolete(since = "1.19.1")
@Nullable ChatTypeDecoration getOverlayDecoration();
@UnknownNullability("only nullable for 1.19")
ChatTypeDecoration getNarrationDecoration();
@ApiStatus.Obsolete(since = "1.19.1")
@Nullable NarrationPriority getNarrationPriority();
static ChatType readDirect(PacketWrapper<?> wrapper) {
ChatTypeDecoration chatDecoration = ChatTypeDecoration.read(wrapper);
ChatTypeDecoration narrationDecoration = ChatTypeDecoration.read(wrapper);
return new StaticChatType(chatDecoration, narrationDecoration);
}
static void writeDirect(PacketWrapper<?> wrapper, ChatType chatType) {
ChatTypeDecoration.write(wrapper, chatType.getChatDecoration());
ChatTypeDecoration.write(wrapper, chatType.getNarrationDecoration());
}
static ChatType decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
// everything is nullable in 1.19, even the chat format!
NBTCompound compound = (NBTCompound) nbt;
NBTCompound chatTag = compound.getCompoundTagOrNull("chat");
NBTCompound narrationTag = compound.getCompoundTagOrNull("narration");
ChatTypeDecoration overlay = null;
NarrationPriority narrationPriority = null;
if (version.isOlderThan(ClientVersion.V_1_19_1)) {
NBTCompound overlayTag = compound.getCompoundTagOrNull("overlay");
if (overlayTag != null) {
// why is this nullable? why is this wrapped? There is no reason to wrap this...
overlayTag = overlayTag.getCompoundTagOrNull("description");
if (overlayTag != null) {
overlay = ChatTypeDecoration.decode(overlayTag, version);
}
}
if (chatTag != null) {
chatTag = chatTag.getCompoundTagOrNull("description");
}
if (narrationTag != null) {
// the priority is the ONLY value which isn't nullable!
narrationPriority = indexValueOrThrow(NarrationPriority.ID_INDEX,
narrationTag.getStringTagValueOrThrow("priority"));
narrationTag = narrationTag.getCompoundTagOrNull("description");
}
} else {
// ensure this isn't null in everything but 1.19
Objects.requireNonNull(chatTag, "NBT chat does not exist");
Objects.requireNonNull(narrationTag, "NBT narration does not exist");
}
ChatTypeDecoration chat = chatTag == null ? null : ChatTypeDecoration.decode(chatTag, version);
ChatTypeDecoration narration = narrationTag == null ? null : ChatTypeDecoration.decode(narrationTag, version);
return new StaticChatType(data, chat, overlay, narration, narrationPriority);
}
static NBT encode(ChatType chatType, ClientVersion version) {
NBTCompound compound = new NBTCompound();
NBT chatTag = chatType.getChatDecoration() == null ? null :
ChatTypeDecoration.encode(chatType.getChatDecoration(), version);
NBT narrationTag = chatType.getNarrationDecoration() == null ? null :
ChatTypeDecoration.encode(chatType.getNarrationDecoration(), version);
if (version.isOlderThan(ClientVersion.V_1_19_1)) {
ChatTypeDecoration overlayDeco = chatType.getOverlayDecoration();
if (overlayDeco != null) {
NBTCompound overlayCompound = new NBTCompound();
overlayCompound.setTag("description",
ChatTypeDecoration.encode(overlayDeco, version));
compound.setTag("overlay", overlayCompound);
}
if (narrationTag != null) {
NBTCompound narrationCompound = new NBTCompound();
narrationCompound.setTag("description", narrationTag);
if (chatType.getNarrationPriority() != null) {
narrationCompound.setTag("priority", new NBTString(chatType.getNarrationPriority().getId()));
}
narrationTag = narrationCompound;
}
if (chatTag != null) {
NBTCompound chatCompound = new NBTCompound();
chatCompound.setTag("description", chatTag);
chatTag = chatCompound;
}
}
if (chatTag != null) {
compound.setTag("chat", chatTag);
}
if (narrationTag != null) {
compound.setTag("narration", narrationTag);
}
return compound;
}
class Bound extends ChatMessage_v1_19_1.ChatTypeBoundNetwork {
public Bound(ChatType type, Component name, @Nullable Component targetName) {
super(type, name, targetName);
}
}
@ApiStatus.Obsolete(since = "1.19.1")
enum NarrationPriority {
CHAT("chat"),
SYSTEM("system");
public static final Index<String, NarrationPriority> ID_INDEX = Index.create(
NarrationPriority.class, NarrationPriority::getId);
private final String id;
NarrationPriority(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
}
}
@@ -0,0 +1,195 @@
/*
* 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.chat;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.util.Index;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.Parameter.CONTENT;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.Parameter.SENDER;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.Parameter.TARGET;
import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow;
import static java.util.Arrays.asList;
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
import static net.kyori.adventure.text.format.Style.empty;
import static net.kyori.adventure.text.format.Style.style;
import static net.kyori.adventure.text.format.TextDecoration.ITALIC;
public class ChatTypeDecoration {
private final String translationKey;
private final List<Parameter> parameters;
private final Style style;
public ChatTypeDecoration(String translationKey, List<Parameter> parameters, Style style) {
this.translationKey = translationKey;
this.parameters = Collections.unmodifiableList(new ArrayList<>(parameters));
this.style = style;
}
public static ChatTypeDecoration read(PacketWrapper<?> wrapper) {
String translationKey = wrapper.readString();
List<Parameter> parameters = wrapper.readList(ew -> ew.readEnum(Parameter.values()));
Style style = wrapper.readStyle();
return new ChatTypeDecoration(translationKey, parameters, style);
}
public static void write(PacketWrapper<?> wrapper, ChatTypeDecoration decoration) {
wrapper.writeString(decoration.translationKey);
wrapper.writeList(decoration.parameters, PacketWrapper::writeEnum);
wrapper.writeStyle(decoration.style);
}
public static ChatTypeDecoration decode(NBT nbt, ClientVersion version) {
NBTCompound compound = (NBTCompound) nbt;
String translationKey = compound.getStringTagValueOrThrow("translation_key");
NBT paramsTag = compound.getTagOrThrow("parameters");
List<Parameter> params;
if (paramsTag instanceof NBTList<?>) {
params = new ArrayList<>();
NBTList<?> paramsTagList = (NBTList<?>) paramsTag;
for (NBT paramTag : paramsTagList.getTags()) {
String paramId = ((NBTString) paramTag).getValue();
params.add(indexValueOrThrow(Parameter.ID_INDEX, paramId));
}
} else {
String paramId = ((NBTString) paramsTag).getValue();
params = Collections.singletonList(indexValueOrThrow(Parameter.ID_INDEX, paramId));
}
NBTCompound styleTag = compound.getCompoundTagOrNull("style");
Style style = styleTag == null ? empty() :
AdventureSerializer.getNBTSerializer().deserializeStyle(styleTag);
return new ChatTypeDecoration(translationKey, params, style);
}
public static NBT encode(ChatTypeDecoration decoration, ClientVersion version) {
NBTList<NBTString> paramsTag = NBTList.createStringList();
for (Parameter param : decoration.parameters) {
paramsTag.addTag(new NBTString(param.getId()));
}
NBTCompound compound = new NBTCompound();
compound.setTag("translation_key", new NBTString(decoration.translationKey));
compound.setTag("parameters", paramsTag);
if (!decoration.style.isEmpty()) {
compound.setTag("style", AdventureSerializer.getNBTSerializer()
.serializeStyle(decoration.style));
}
return compound;
}
public static ChatTypeDecoration withSender(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(SENDER, CONTENT), empty());
}
public static ChatTypeDecoration incomingDirectMessage(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(SENDER, CONTENT),
style(GRAY, ITALIC));
}
public static ChatTypeDecoration outgoingDirectMessage(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(TARGET, CONTENT),
style(GRAY, ITALIC));
}
public static ChatTypeDecoration teamMessage(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(TARGET, SENDER, CONTENT), empty());
}
public Component decorate(Component component, ChatType.Bound chatType) {
ComponentLike[] components = new ComponentLike[this.parameters.size()];
for (int i = 0; i < components.length; i++) {
Parameter parameter = this.parameters.get(i);
components[i] = parameter.selector.apply(component, chatType);
}
return Component.translatable(this.translationKey, null, this.style, components);
}
public String getTranslationKey() {
return this.translationKey;
}
public List<Parameter> getParameters() {
return this.parameters;
}
public Style getStyle() {
return this.style;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ChatTypeDecoration)) return false;
ChatTypeDecoration that = (ChatTypeDecoration) obj;
if (!this.translationKey.equals(that.translationKey)) return false;
if (!this.parameters.equals(that.parameters)) return false;
return this.style.equals(that.style);
}
@Override
public int hashCode() {
return Objects.hash(this.translationKey, this.parameters, this.style);
}
public enum Parameter {
SENDER("sender", (component, type) -> type.getName()),
TARGET("target", (component, type) -> type.getTargetName() != null
? type.getTargetName() : Component.empty()),
CONTENT("content", (component, type) -> component);
public static final Index<String, Parameter> ID_INDEX = Index.create(
Parameter.class, Parameter::getId);
private final String id;
private final BiFunction<Component, ChatType.Bound, Component> selector;
Parameter(String id, BiFunction<Component, ChatType.Bound, Component> selector) {
this.id = id;
this.selector = selector;
}
public String getId() {
return this.id;
}
@Deprecated
public static @Nullable Parameter valueByName(String id) {
return ID_INDEX.value(id);
}
}
}
@@ -19,54 +19,68 @@
package com.github.retrooper.packetevents.protocol.chat;
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 java.util.HashMap;
import java.util.Map;
import java.util.Collection;
public class ChatTypes {
private static final Map<String, ChatType> CHAT_TYPE_MAP = new HashMap<>();
//Key - mappings version, value - map with chat type ids and chat types
private static final Map<Byte, Map<Integer, ChatType>> CHAT_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("chat/chat_type_mappings");
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.incomingDirectMessage;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.outgoingDirectMessage;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.teamMessage;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.withSender;
public static ChatType define(String key) {
TypesBuilderData data = TYPES_BUILDER.define(key);
ChatType chatType = new ChatType() {
@Override
public ResourceLocation getName() {
return data.getName();
}
public final class ChatTypes {
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
};
MappingHelper.registerMapping(TYPES_BUILDER, CHAT_TYPE_MAP, CHAT_TYPE_ID_MAP, chatType);
return chatType;
private static final VersionedRegistry<ChatType> REGISTRY = new VersionedRegistry<>(
"chat_type", "chat/chat_type_mappings");
private ChatTypes() {
}
@ApiStatus.Internal
public static ChatType define(String key) {
return define(key, withSender("chat.type.text"));
}
@ApiStatus.Internal
public static ChatType define(String key, ChatTypeDecoration chatDeco) {
return define(key, chatDeco, withSender("chat.type.text.narrate"));
}
@ApiStatus.Internal
public static ChatType define(String key, ChatTypeDecoration chatDeco, ChatTypeDecoration narrationDeco) {
return REGISTRY.define(key, data ->
new StaticChatType(data, chatDeco, narrationDeco));
}
public static VersionedRegistry<ChatType> getRegistry() {
return REGISTRY;
}
//with minecraft:key
public static ChatType getByName(String name) {
return CHAT_TYPE_MAP.get(name);
return REGISTRY.getByName(name);
}
public static ChatType getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
return CHAT_TYPE_ID_MAP.get((byte) index).get(id);
return REGISTRY.getById(version, id);
}
public static final ChatType CHAT = define("chat");
public static final ChatType SAY_COMMAND = define("say_command");
public static final ChatType MSG_COMMAND_INCOMING = define("msg_command_incoming");
public static final ChatType MSG_COMMAND_OUTGOING = define("msg_command_outgoing");
public static final ChatType TEAM_MSG_COMMAND_INCOMING = define("team_msg_command_incoming");
public static final ChatType TEAM_MSG_COMMAND_OUTGOING = define("team_msg_command_outgoing");
public static final ChatType EMOTE_COMMAND = define("emote_command");
public static final ChatType SAY_COMMAND = define("say_command",
withSender("chat.type.announcement"));
public static final ChatType MSG_COMMAND_INCOMING = define("msg_command_incoming",
incomingDirectMessage("commands.message.display.incoming"));
public static final ChatType MSG_COMMAND_OUTGOING = define("msg_command_outgoing",
outgoingDirectMessage("commands.message.display.outgoing"));
public static final ChatType TEAM_MSG_COMMAND_INCOMING = define("team_msg_command_incoming",
teamMessage("chat.type.team.text"));
public static final ChatType TEAM_MSG_COMMAND_OUTGOING = define("team_msg_command_outgoing",
teamMessage("chat.type.team.sent"));
public static final ChatType EMOTE_COMMAND = define("emote_command",
withSender("chat.type.emote"),
withSender("chat.type.emote"));
// added by CraftBukkit for a few versions
public static final ChatType RAW = define("raw");
@Deprecated
@@ -78,7 +92,16 @@ public class ChatTypes {
@Deprecated
public static final ChatType TEAM_MSG_COMMAND = define("team_msg_command");
/**
* Returns an immutable view of the chat types.
*
* @return Chat Types
*/
public static Collection<ChatType> values() {
return REGISTRY.getEntries();
}
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
}
@@ -16,9 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.chat.Parsers.Parser;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
@@ -26,20 +27,33 @@ import java.util.List;
import java.util.Optional;
public class Node {
private byte flags;
private List<Integer> children;
private int redirectNodeIndex;
private Optional<String> name;
private Optional<Integer> parserID;
private Optional<Parser> parser;
private Optional<List<Object>> properties;
private Optional<ResourceLocation> suggestionsType;
public Node(byte flags, List<Integer> children, int redirectNodeIndex, @Nullable String name, @Nullable Integer parserID, @Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType) {
public Node(
byte flags, List<Integer> children, int redirectNodeIndex, @Nullable String name,
@Nullable Integer parserID, @Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType
) {
this(flags, children, redirectNodeIndex, name, parserID == null ? null : Parsers.getById(
PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), parserID),
properties, suggestionsType);
}
public Node(
byte flags, List<Integer> children, int redirectNodeIndex, @Nullable String name, @Nullable Parser parser,
@Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType
) {
this.flags = flags;
this.children = children;
this.redirectNodeIndex = redirectNodeIndex;
this.name = Optional.ofNullable(name);
this.parserID = Optional.ofNullable(parserID);
this.parser = Optional.ofNullable(parser);
this.properties = Optional.ofNullable(properties);
this.suggestionsType = Optional.ofNullable(suggestionsType);
}
@@ -76,12 +90,22 @@ public class Node {
this.name = name;
}
public Optional<Parser> getParser() {
return this.parser;
}
public void setParser(Optional<Parser> parser) {
this.parser = parser;
}
public Optional<Integer> getParserID() {
return parserID;
return this.parser.map(parser -> parser.getId(PacketEvents.getAPI()
.getServerManager().getVersion().toClientVersion()));
}
public void setParserID(Optional<Integer> parserID) {
this.parserID = parserID;
this.parser = parserID.map(id -> Parsers.getById(PacketEvents.getAPI()
.getServerManager().getVersion().toClientVersion(), id));
}
public Optional<List<Object>> getProperties() {
@@ -151,7 +151,9 @@ public class Parsers {
public static final Parser COMPONENT = define("component", null, null);
public static final Parser STYLE = define("style", null, null);
public static final Parser MESSAGE = define("message", null, null);
public static final Parser NBT = define("nbt", null, null);
public static final Parser NBT_COMPOUND_TAG = define("nbt_compound_tag", null, null);
@Deprecated
public static final Parser NBT = NBT_COMPOUND_TAG;
public static final Parser NBT_TAG = define("nbt_tag", null, null);
public static final Parser NBT_PATH = define("nbt_path", null, null);
public static final Parser OBJECTIVE = define("objective", null, null);
@@ -170,10 +172,13 @@ public class Parsers {
public static final Parser ITEM_SLOT = define("item_slot", null, null);
public static final Parser ITEM_SLOTS = define("item_slots", null, null);
public static final Parser RESOURCE_LOCATION = define("resource_location", null, null);
public static final Parser MOB_EFFECT = define("mob_effect", null, null);
public static final Parser FUNCTION = define("function", null, null);
public static final Parser ENTITY_ANCHOR = define("entity_anchor", null, null);
public static final Parser INT_RANGE = define("int_range", null, null);
public static final Parser FLOAT_RANGE = define("float_range", null, null);
public static final Parser ITEM_ENCHANTMENT = define("item_enchantment", null, null);
public static final Parser ENTITY_SUMMON = define("entity_summon", null, null);
public static final Parser DIMENSION = define("dimension", null, null);
public static final Parser GAMEMODE = define("gamemode", null, null);
public static final Parser TIME = define("time",
@@ -2,9 +2,9 @@ package com.github.retrooper.packetevents.protocol.chat;
public class SignedCommandArgument {
private String argument;
private byte[] signature;
private MessageSignature signature;
public SignedCommandArgument(String argument, byte[] signature) {
public SignedCommandArgument(String argument, MessageSignature signature) {
this.argument = argument;
this.signature = signature;
}
@@ -17,11 +17,11 @@ public class SignedCommandArgument {
this.argument = argument;
}
public byte[] getSignature() {
public MessageSignature getSignature() {
return signature;
}
public void setSignature(byte[] signature) {
public void setSignature(MessageSignature signature) {
this.signature = signature;
}
}
@@ -0,0 +1,120 @@
/*
* 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.chat;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import java.util.Objects;
public class StaticChatType extends AbstractMappedEntity implements ChatType {
private final @UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration;
private final @Nullable ChatTypeDecoration overlayDecoration;
private final @UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration;
private final @Nullable NarrationPriority narrationPriority;
public StaticChatType(
ChatTypeDecoration chatDecoration,
ChatTypeDecoration narrationDecoration
) {
this(null, chatDecoration, null, narrationDecoration, null);
}
public StaticChatType(
@Nullable TypesBuilderData data,
ChatTypeDecoration chatDecoration,
ChatTypeDecoration narrationDecoration
) {
this(data, chatDecoration, null, narrationDecoration, null);
}
public StaticChatType(
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration,
@Nullable ChatTypeDecoration overlayDecoration,
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration,
@Nullable NarrationPriority narrationPriority
) {
this(null, chatDecoration, overlayDecoration, narrationDecoration, narrationPriority);
}
public StaticChatType(
@Nullable TypesBuilderData data,
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration chatDecoration,
@Nullable ChatTypeDecoration overlayDecoration,
@UnknownNullability("only nullable for 1.19") ChatTypeDecoration narrationDecoration,
@Nullable NarrationPriority narrationPriority
) {
super(data);
this.chatDecoration = chatDecoration;
this.overlayDecoration = overlayDecoration;
this.narrationDecoration = narrationDecoration;
this.narrationPriority = narrationPriority;
}
@Override
public ChatType copy(@Nullable TypesBuilderData newData) {
return new StaticChatType(newData, this.chatDecoration,
this.overlayDecoration, this.narrationDecoration, this.narrationPriority);
}
@Override
public @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getChatDecoration() {
return this.chatDecoration;
}
@Override
public @Nullable ChatTypeDecoration getOverlayDecoration() {
return this.overlayDecoration;
}
@Override
public @UnknownNullability("only nullable for 1.19") ChatTypeDecoration getNarrationDecoration() {
return this.narrationDecoration;
}
@Override
public @Nullable NarrationPriority getNarrationPriority() {
return this.narrationPriority;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticChatType)) return false;
if (!super.equals(obj)) return false;
StaticChatType that = (StaticChatType) obj;
if (!Objects.equals(this.chatDecoration, that.chatDecoration)) return false;
if (!Objects.equals(this.overlayDecoration, that.overlayDecoration)) return false;
if (!Objects.equals(this.narrationDecoration, that.narrationDecoration)) return false;
return this.narrationPriority == that.narrationPriority;
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.chatDecoration, this.overlayDecoration, this.narrationDecoration, this.narrationPriority);
}
@Override
public String toString() {
return "StaticChatType{chatDecoration=" + this.chatDecoration + ", overlayDecoration=" + this.overlayDecoration + ", narrationDecoration=" + this.narrationDecoration + ", narrationPriority=" + this.narrationPriority + '}';
}
}
@@ -30,7 +30,7 @@ import java.util.UUID;
public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
private String plainContent;
private @Nullable Component unsignedChatContent;
private ChatTypeBoundNetwork chatType;
private ChatType.Bound chatFormatting;
private byte @Nullable [] previousSignature;
private byte[] signature;
private Instant timestamp;
@@ -40,15 +40,15 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
public ChatMessage_v1_19_1(String plainContent, Component decoratedChatContent,
@Nullable Component unsignedChatContent,
UUID senderUUID, ChatTypeBoundNetwork chatType,
UUID senderUUID, ChatType.Bound chatFormatting,
byte @Nullable [] previousSignature, byte[] signature,
Instant timestamp, long salt,
LastSeenMessages lastSeenMessages,
FilterMask filterMask) {
super(decoratedChatContent, chatType.getType(), senderUUID);
super(decoratedChatContent, chatFormatting.getType(), senderUUID);
this.plainContent = plainContent;
this.unsignedChatContent = unsignedChatContent;
this.chatType = chatType;
this.chatFormatting = chatFormatting;
this.previousSignature = previousSignature;
this.signature = signature;
this.timestamp = timestamp;
@@ -79,20 +79,38 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
@Override
public ChatType getType() {
return chatType.getType();
return chatFormatting.getType();
}
@Override
public void setType(ChatType type) {
chatType.setType(type);
chatFormatting.setType(type);
}
public ChatTypeBoundNetwork getChatType() {
return chatType;
public ChatType.Bound getChatFormatting() {
return chatFormatting;
}
public void setChatType(ChatTypeBoundNetwork type) {
this.chatType = type;
public void setChatFormatting(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
/**
* Retrieves the chat formatting. Please refer to {@link ChatMessage_v1_19_1#getChatFormatting}
* @return chat formatting which contains the actual chat type.
*/
@Deprecated
public ChatType.Bound getChatType() {
return chatFormatting;
}
/**
* Sets the chat formatting. Please refer to {@link ChatMessage_v1_19_1#setChatFormatting}
* @param chatFormatting formatting which contains the actual chat type.
*/
@Deprecated
public void setChatType(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
public byte @Nullable [] getPreviousSignature() {
@@ -143,6 +161,10 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
this.filterMask = filterMask;
}
/**
* Please refer to {@link com.github.retrooper.packetevents.protocol.chat.ChatType.Bound}
*/
@Deprecated
public static class ChatTypeBoundNetwork {
private ChatType type;
private Component name;
@@ -1,5 +1,6 @@
package com.github.retrooper.packetevents.protocol.chat.message;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
@@ -19,10 +20,10 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
LastSeenMessages.Packed lastSeenMessagesPacked;
@Nullable Component unsignedChatContent;
FilterMask filterMask;
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType;
ChatType.Bound chatFormatting;
public ChatMessage_v1_19_3(UUID senderUUID, int index, byte[] signature, String plainContent, Instant timestamp, long salt, LastSeenMessages.Packed lastSeenMessagesPacked, @Nullable Component unsignedChatContent, FilterMask filterMask, ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType) {
super(Component.text(plainContent), chatType.getType(), senderUUID);
public ChatMessage_v1_19_3(UUID senderUUID, int index, byte[] signature, String plainContent, Instant timestamp, long salt, LastSeenMessages.Packed lastSeenMessagesPacked, @Nullable Component unsignedChatContent, FilterMask filterMask, ChatType.Bound chatFormatting) {
super(Component.text(plainContent), chatFormatting.getType(), senderUUID);
this.index = index;
this.signature = signature;
this.plainContent = plainContent;
@@ -31,7 +32,7 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
this.lastSeenMessagesPacked = lastSeenMessagesPacked;
this.unsignedChatContent = unsignedChatContent;
this.filterMask = filterMask;
this.chatType = chatType;
this.chatFormatting = chatFormatting;
}
public int getIndex() {
@@ -109,11 +110,30 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
this.filterMask = filterMask;
}
public ChatMessage_v1_19_1.ChatTypeBoundNetwork getChatType() {
return chatType;
public ChatType.Bound getChatFormatting() {
return chatFormatting;
}
public void setChatType(ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType) {
this.chatType = chatType;
public void setChatFormatting(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
/**
* Retrieves the chat formatting. Please refer to {@link ChatMessage_v1_19_3#getChatFormatting}
* @return chat formatting which contains the actual chat type.
*/
@Deprecated
public ChatType.Bound getChatType() {
return chatFormatting;
}
/**
* Sets the chat formatting. Please refer to {@link ChatMessage_v1_19_3#setChatFormatting}
* @param chatFormatting formatting which contains the actual chat type.
*/
@Deprecated
public void setChatType(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
}
@@ -31,14 +31,13 @@ public class ChatMessageProcessorLegacy implements ChatMessageProcessor {
@Override
public ChatMessage readChatMessage(@NotNull PacketWrapper<?> wrapper) {
Component chatContent = wrapper.readComponent();
int id = wrapper.readByte();
ChatType type = ChatTypes.getById(wrapper.getServerVersion().toClientVersion(), id);
ChatType type = wrapper.readMappedEntity(ChatTypes.getRegistry());
return new ChatMessageLegacy(chatContent, type);
}
@Override
public void writeChatMessage(@NotNull PacketWrapper<?> wrapper, @NotNull ChatMessage data) {
wrapper.writeComponent(data.getChatContent());
wrapper.writeByte(data.getType().getId(wrapper.getServerVersion().toClientVersion()));
wrapper.writeMappedEntity(data.getType());
}
}
@@ -33,8 +33,7 @@ public class ChatMessageProcessor_v1_16 implements ChatMessageProcessor {
@Override
public ChatMessage readChatMessage(@NotNull PacketWrapper<?> wrapper) {
Component chatContent = wrapper.readComponent();
int id = wrapper.readByte();
ChatType type = ChatTypes.getById(wrapper.getServerVersion().toClientVersion(), id);
ChatType type = wrapper.readMappedEntity(ChatTypes.getRegistry());
UUID senderUUID = wrapper.readUUID();
return new ChatMessage_v1_16(chatContent, type, senderUUID);
}
@@ -42,7 +41,7 @@ public class ChatMessageProcessor_v1_16 implements ChatMessageProcessor {
@Override
public void writeChatMessage(@NotNull PacketWrapper<?> wrapper, @NotNull ChatMessage data) {
wrapper.writeComponent(data.getChatContent());
wrapper.writeByte(data.getType().getId(wrapper.getServerVersion().toClientVersion()));
wrapper.writeMappedEntity(data.getType());
wrapper.writeUUID(((ChatMessage_v1_16) data).getSenderUUID());
}
}
@@ -36,8 +36,7 @@ public class ChatMessageProcessor_v1_19 implements ChatMessageProcessor {
public ChatMessage readChatMessage(@NotNull PacketWrapper<?> wrapper) {
Component chatContent = wrapper.readComponent();
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
int id = wrapper.readVarInt();
ChatType type = ChatTypes.getById(wrapper.getServerVersion().toClientVersion(), id);
ChatType type = wrapper.readMappedEntity(ChatTypes.getRegistry());
UUID senderUUID = wrapper.readUUID();
Component senderDisplayName = wrapper.readComponent();
@Nullable Component teamName = wrapper.readOptional(PacketWrapper::readComponent);
@@ -53,7 +52,7 @@ public class ChatMessageProcessor_v1_19 implements ChatMessageProcessor {
ChatMessage_v1_19 newData = (ChatMessage_v1_19) data;
wrapper.writeComponent(newData.getChatContent());
wrapper.writeOptional(newData.getUnsignedChatContent(), PacketWrapper::writeComponent);
wrapper.writeVarInt(newData.getType().getId(wrapper.getServerVersion().toClientVersion()));
wrapper.writeMappedEntity(newData.getType());
wrapper.writeUUID(newData.getSenderUUID());
wrapper.writeComponent(newData.getSenderDisplayName());
wrapper.writeOptional(newData.getTeamName(), PacketWrapper::writeComponent);
@@ -50,8 +50,8 @@ public class ChatMessageProcessor_v1_19_1 implements ChatMessageProcessor {
LastSeenMessages lastSeenMessages = wrapper.readLastSeenMessages();
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
FilterMask filterMask = wrapper.readFilterMask();
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType = wrapper.readChatTypeBoundNetwork();
return new ChatMessage_v1_19_1(plainContent, chatContent, unsignedChatContent, senderUUID, chatType,
ChatType.Bound chatFormatting = wrapper.readChatTypeBoundNetwork();
return new ChatMessage_v1_19_1(plainContent, chatContent, unsignedChatContent, senderUUID, chatFormatting,
previousSignature, signature, timestamp, salt, lastSeenMessages, filterMask);
}
@@ -68,6 +68,6 @@ public class ChatMessageProcessor_v1_19_1 implements ChatMessageProcessor {
wrapper.writeLastSeenMessages(newData.getLastSeenMessages());
wrapper.writeOptional(newData.getUnsignedChatContent(), PacketWrapper::writeComponent);
wrapper.writeFilterMask(newData.getFilterMask());
wrapper.writeChatTypeBoundNetwork(newData.getChatType());
wrapper.writeChatTypeBoundNetwork(newData.getChatFormatting());
}
}
@@ -1,5 +1,6 @@
package com.github.retrooper.packetevents.protocol.chat.message.reader.impl;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage;
@@ -25,7 +26,7 @@ public class ChatMessageProcessor_v1_19_3 implements ChatMessageProcessor {
LastSeenMessages.Packed lastSeenMessagesPacked = wrapper.readLastSeenMessagesPacked();
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
FilterMask filterMask = wrapper.readFilterMask();
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType = wrapper.readChatTypeBoundNetwork();
ChatType.Bound chatType = wrapper.readChatTypeBoundNetwork();
return new ChatMessage_v1_19_3(senderUUID, index, signature, plainContent, timestamp, salt, lastSeenMessagesPacked, unsignedChatContent, filterMask, chatType);
}
@@ -42,6 +43,6 @@ public class ChatMessageProcessor_v1_19_3 implements ChatMessageProcessor {
wrapper.writeLastSeenMessagesPacked(newData.getLastSeenMessagesPacked());
wrapper.writeOptional(newData.getUnsignedChatContent().orElse(null), PacketWrapper::writeComponent);
wrapper.writeFilterMask(newData.getFilterMask());
wrapper.writeChatTypeBoundNetwork(newData.getChatType());
wrapper.writeChatTypeBoundNetwork(newData.getChatFormatting());
}
}
@@ -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;
}
}
}
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
@@ -88,4 +89,22 @@ public class ComponentPredicate implements Predicate<IComponentMap> {
public void setRequiredComponents(List<ComponentValue<?>> requiredComponents) {
this.requiredComponents = requiredComponents;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ComponentPredicate)) return false;
ComponentPredicate that = (ComponentPredicate) obj;
return this.requiredComponents.equals(that.requiredComponents);
}
@Override
public int hashCode() {
return Objects.hashCode(this.requiredComponents);
}
@Override
public String toString() {
return "ComponentPredicate{requiredComponents=" + this.requiredComponents + '}';
}
}
@@ -19,6 +19,8 @@
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface ComponentType<T> extends MappedEntity {
@@ -26,4 +28,18 @@ public interface ComponentType<T> extends MappedEntity {
T read(PacketWrapper<?> wrapper);
void write(PacketWrapper<?> wrapper, T content);
T decode(NBT nbt, ClientVersion version);
NBT encode(T value, ClientVersion version);
interface Decoder<T> {
T decode(NBT nbt, ClientVersion version);
}
interface Encoder<T> {
NBT encode(T value, ClientVersion version);
}
}
@@ -23,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.component.builtin.item.ArmorTr
import com.github.retrooper.packetevents.protocol.component.builtin.item.BannerLayers;
import com.github.retrooper.packetevents.protocol.component.builtin.item.BundleContents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ChargedProjectiles;
import com.github.retrooper.packetevents.protocol.component.builtin.item.CustomData;
import com.github.retrooper.packetevents.protocol.component.builtin.item.DebugStickState;
import com.github.retrooper.packetevents.protocol.component.builtin.item.FireworkExplosion;
import com.github.retrooper.packetevents.protocol.component.builtin.item.FoodProperties;
@@ -30,20 +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;
@@ -54,85 +66,55 @@ import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Dummy;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Reader;
import com.github.retrooper.packetevents.wrapper.PacketWrapper.Writer;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.Collection;
public class ComponentTypes {
/**
* Contains all item data component types.
*
* @see EnchantEffectComponentTypes
*/
public final class ComponentTypes {
private static final Map<String, ComponentType<?>> COMPONENT_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, ComponentType<?>>> COMPONENT_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_component_mappings");
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
"data_component_type", "item/item_component_mappings");
private ComponentTypes() {
}
@ApiStatus.Internal
public static <T> ComponentType<T> define(String key) {
return define(key, null, null);
}
@ApiStatus.Internal
public static <T> ComponentType<T> define(String key, @Nullable Reader<T> reader, @Nullable Writer<T> writer) {
TypesBuilderData data = TYPES_BUILDER.define(key);
ComponentType<T> type = new ComponentType<T>() {
@Override
public T read(PacketWrapper<?> wrapper) {
return reader == null ? null : reader.apply(wrapper);
}
@Override
public void write(PacketWrapper<?> wrapper, T content) {
if (writer != null) {
writer.accept(wrapper, content);
}
}
@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 ComponentType<?>) {
return this.getName().equals(((ComponentType<?>) obj).getName());
}
return false;
}
@Override
public String toString() {
return "Component[" + this.getName() + "]";
}
};
MappingHelper.registerMapping(TYPES_BUILDER, COMPONENT_TYPE_MAP, COMPONENT_TYPE_ID_MAP, type);
return type;
return REGISTRY.define(key, data -> new StaticComponentType<>(data, reader, writer));
}
public static VersionedRegistry<ComponentType<?>> getRegistry() {
return REGISTRY;
}
// with key
public static ComponentType<?> getByName(String name) {
return COMPONENT_TYPE_MAP.get(name);
return REGISTRY.getByName(name);
}
public static ComponentType<?> getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, ComponentType<?>> idMap = COMPONENT_TYPE_ID_MAP.get((byte) index);
return idMap.get(id);
return REGISTRY.getById(version, id);
}
// item component types
public static final ComponentType<NBTCompound> CUSTOM_DATA = define("custom_data",
PacketWrapper::readNBT, PacketWrapper::writeNBT);
// mojang wraps their "persistent" codec as a stream codec just here,
// so packetevents has to handle nbt strings
CustomData::read, CustomData::write);
public static final ComponentType<Integer> MAX_STACK_SIZE = define("max_stack_size",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Integer> MAX_DAMAGE = define("max_damage",
@@ -173,6 +155,10 @@ public 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",
@@ -244,13 +230,44 @@ public class ComponentTypes {
public static final ComponentType<ItemContainerLoot> CONTAINER_LOOT = define("container_loot",
ItemContainerLoot::read, ItemContainerLoot::write);
static {
TYPES_BUILDER.unloadFileMappings();
// added in 1.21
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.
*
* @return Component Types
*/
public static Collection<ComponentType<?>> values() {
return REGISTRY.getEntries();
}
@FunctionalInterface
public interface Reader<T> extends Function<PacketWrapper<?>, T> {}
@FunctionalInterface
public interface Writer<T> extends BiConsumer<PacketWrapper<?>, T> {}
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,120 @@
/*
* 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;
import com.github.retrooper.packetevents.protocol.component.ComponentType.Decoder;
import com.github.retrooper.packetevents.protocol.component.ComponentType.Encoder;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
/**
* Contains all enchantment effect component types.
*
* @see ComponentTypes
*/
public final class EnchantEffectComponentTypes {
private static final VersionedRegistry<ComponentType<?>> REGISTRY = new VersionedRegistry<>(
"enchantment_effect_component_type", "enchantment/effect_component_type");
private EnchantEffectComponentTypes() {
}
@ApiStatus.Internal
public static <T> ComponentType<T> define(String key) {
return define(key, null, null);
}
@ApiStatus.Internal
public static <T> ComponentType<T> define(String key, @Nullable Decoder<T> reader, @Nullable Encoder<T> writer) {
return REGISTRY.define(key, data -> new StaticComponentType<>(data, reader, writer));
}
public static VersionedRegistry<ComponentType<?>> getRegistry() {
return REGISTRY;
}
// just pass everything through for now
public static ComponentType<NBT> DAMAGE_PROTECTION = define("damage_protection",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> DAMAGE_IMMUNITY = define("damage_immunity",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> DAMAGE = define("damage",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> SMASH_DAMAGE_PER_FALLEN_BLOCK = define("smash_damage_per_fallen_block",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> KNOCKBACK = define("knockback",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> ARMOR_EFFECTIVENESS = define("armor_effectiveness",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> POST_ATTACK = define("post_attack",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> HIT_BLOCK = define("hit_block",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> ITEM_DAMAGE = define("item_damage",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> ATTRIBUTES = define("attributes",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> EQUIPMENT_DROPS = define("equipment_drops",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> LOCATION_CHANGED = define("location_changed",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> TICK = define("tick",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> AMMO_USE = define("ammo_use",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> PROJECTILE_PIERCING = define("projectile_piercing",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> PROJECTILE_SPAWNED = define("projectile_spawned",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> PROJECTILE_SPREAD = define("projectile_spread",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> PROJECTILE_COUNT = define("projectile_count",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> TRIDENT_RETURN_ACCELERATION = define("trident_return_acceleration",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> FISHING_TIME_REDUCTION = define("fishing_time_reduction",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> FISHING_LUCK_BONUS = define("fishing_luck_bonus",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> BLOCK_EXPERIENCE = define("block_experience",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> MOB_EXPERIENCE = define("mob_experience",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> REPAIR_WITH_XP = define("repair_with_xp",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> CROSSBOW_CHARGE_TIME = define("crossbow_charge_time",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> CROSSBOW_CHARGING_SOUNDS = define("crossbow_charging_sounds",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> TRIDENT_SOUND = define("trident_sound",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> PREVENT_EQUIPMENT_DROP = define("prevent_equipment_drop",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> PREVENT_ARMOR_CHANGE = define("prevent_armor_change",
(nbt, version) -> nbt, (val, version) -> val);
public static ComponentType<NBT> TRIDENT_SPIN_ATTACK_STRENGTH = define("trident_spin_attack_strength",
(nbt, version) -> nbt, (val, version) -> val);
static {
REGISTRY.unloadMappings();
}
}
@@ -18,13 +18,44 @@
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.mappings.IRegistry;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Optional;
public interface IComponentMap {
@SuppressWarnings("unchecked") // safe in this case
static StaticComponentMap decode(NBT nbt, ClientVersion version, IRegistry<? extends ComponentType<?>> registry) {
NBTCompound compound = (NBTCompound) nbt;
StaticComponentMap.Builder components = StaticComponentMap.builder();
for (Map.Entry<String, NBT> entry : compound.getTags().entrySet()) {
ComponentType<?> type = registry.getByName(entry.getKey());
if (type == null) {
throw new IllegalStateException("Unknown component type named " + entry.getKey() + " encountered");
}
Object value = type.decode(entry.getValue(), version);
components.set((ComponentType<? super Object>) type, value);
}
return components.build();
}
@SuppressWarnings("unchecked") // safe in this case
static NBT encode(StaticComponentMap components, ClientVersion version) {
NBTCompound compound = new NBTCompound();
for (Map.Entry<ComponentType<?>, ?> entry : components.getDelegate().entrySet()) {
String key = entry.getKey().getName().toString();
NBT value = ((ComponentType<? super Object>) entry.getKey()).encode(entry.getValue(), version);
compound.setTag(key, value);
}
return compound;
}
default <T> Optional<T> getOptional(ComponentType<T> type) {
return Optional.ofNullable(this.get(type));
}
@@ -96,6 +96,20 @@ public class PatchableComponentMap implements IComponentMap {
return this.patches;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof PatchableComponentMap)) return false;
PatchableComponentMap that = (PatchableComponentMap) obj;
if (!this.base.equals(that.base)) return false;
return this.patches.equals(that.patches);
}
@Override
public int hashCode() {
return Objects.hash(this.base, this.patches);
}
@Override
public String toString() {
return "PatchableComponentMap{base=" + this.base + ", patches=" + this.patches + '}';
@@ -22,16 +22,20 @@ 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;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
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)
@@ -82,6 +86,24 @@ public class StaticComponentMap implements IComponentMap {
return this.empty;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticComponentMap)) return false;
StaticComponentMap that = (StaticComponentMap) obj;
return this.delegate.equals(that.delegate);
}
@Override
public int hashCode() {
return Objects.hashCode(this.delegate);
}
@Override
public String toString() {
return "Components" + this.delegate;
}
public static class Builder {
private final Map<ComponentType<?>, Object> map = new HashMap<>();
@@ -93,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());
}
@@ -0,0 +1,94 @@
/*
* 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;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
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 StaticComponentType<T> extends AbstractMappedEntity implements ComponentType<T> {
private final @Nullable Reader<T> reader;
private final @Nullable Writer<T> writer;
private final @Nullable Decoder<T> decoder;
private final @Nullable Encoder<T> encoder;
public StaticComponentType(
@Nullable TypesBuilderData data,
@Nullable Reader<T> reader,
@Nullable Writer<T> writer
) {
this(data, reader, writer, null, null);
}
public StaticComponentType(
@Nullable TypesBuilderData data,
@Nullable Decoder<T> decoder,
@Nullable Encoder<T> encoder
) {
this(data, null, null, decoder, encoder);
}
public StaticComponentType(
@Nullable TypesBuilderData data,
@Nullable Reader<T> reader,
@Nullable Writer<T> writer,
@Nullable Decoder<T> decoder,
@Nullable Encoder<T> encoder
) {
super(data);
this.reader = reader;
this.writer = writer;
this.decoder = decoder;
this.encoder = encoder;
}
@Override
public T read(PacketWrapper<?> wrapper) {
return this.reader != null ? this.reader.apply(wrapper) : null;
}
@Override
public void write(PacketWrapper<?> wrapper, T content) {
if (this.writer != null) {
this.writer.accept(wrapper, content);
}
}
@Override
public T decode(NBT nbt, ClientVersion version) {
if (this.decoder != null) {
return this.decoder.decode(nbt, version);
}
throw new UnsupportedOperationException();
}
@Override
public NBT encode(T value, ClientVersion version) {
if (this.encoder != null) {
return this.encoder.encode(value, version);
}
throw new UnsupportedOperationException();
}
}
@@ -87,4 +87,9 @@ public class ArmorTrim {
public int hashCode() {
return Objects.hash(this.material, this.pattern, this.showInTooltip);
}
@Override
public String toString() {
return "ArmorTrim{material=" + this.material + ", pattern=" + this.pattern + ", showInTooltip=" + this.showInTooltip + '}';
}
}
@@ -80,7 +80,7 @@ public class BannerLayers {
public static Layer read(PacketWrapper<?> wrapper) {
BannerPattern pattern = wrapper.readMappedEntityOrDirect(
BannerPatterns::getById, BannerPattern::readDirect);
BannerPatterns.getRegistry(), BannerPattern::readDirect);
DyeColor color = wrapper.readEnum(DyeColor.values());
return new Layer(pattern, color);
}
@@ -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.component.builtin.item;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class CustomData {
private CustomData() {
}
public static NBTCompound read(PacketWrapper<?> wrapper) {
NBT nbt = wrapper.readNBTRaw();
if (nbt instanceof NBTCompound) {
return (NBTCompound) nbt;
}
if (nbt instanceof NBTString) {
// TODO: parse nbt string
}
throw new UnsupportedOperationException("Unsupported custom data nbt type: " + nbt.getType());
}
public static void write(PacketWrapper<?> wrapper, NBTCompound compound) {
wrapper.writeNBT(compound);
}
}
@@ -18,9 +18,14 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
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;
@@ -31,30 +36,68 @@ public class FoodProperties {
private boolean canAlwaysEat;
private float eatSeconds;
private List<PossibleEffect> effects;
private @Nullable ItemStack usingConvertsTo;
public FoodProperties(int nutrition, float saturation, boolean canAlwaysEat, float eatSeconds, List<PossibleEffect> effects) {
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
) {
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
) {
this.nutrition = nutrition;
this.saturation = saturation;
this.canAlwaysEat = canAlwaysEat;
this.eatSeconds = eatSeconds;
this.effects = effects;
this.usingConvertsTo = usingConvertsTo;
}
public static FoodProperties read(PacketWrapper<?> wrapper) {
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();
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);
return new FoodProperties(nutrition, saturation, canAlwaysEat, eatSeconds, effects, usingConvertsTo);
}
public static void write(PacketWrapper<?> wrapper, FoodProperties props) {
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().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);
}
}
public int getNutrition() {
@@ -81,26 +124,62 @@ 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;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -110,14 +189,19 @@ public class FoodProperties {
if (Float.compare(that.saturation, this.saturation) != 0) return false;
if (this.canAlwaysEat != that.canAlwaysEat) return false;
if (Float.compare(that.eatSeconds, this.eatSeconds) != 0) return false;
return this.effects.equals(that.effects);
if (!this.effects.equals(that.effects)) return false;
return Objects.equals(this.usingConvertsTo, that.usingConvertsTo);
}
@Override
public int hashCode() {
return Objects.hash(this.nutrition, this.saturation, this.canAlwaysEat, this.eatSeconds, this.effects);
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;
@@ -104,8 +104,9 @@ public class ItemAdventurePredicate {
public static BlockPredicate read(PacketWrapper<?> wrapper) {
MappedEntitySet<StateType.Mapped> blocks = wrapper.readOptional(
ew -> MappedEntitySet.read(ew, StateTypes::getMappedById));
List<PropertyMatcher> properties = wrapper.readList(PropertyMatcher::read);
NBTCompound nbt = wrapper.readNBT();
List<PropertyMatcher> properties = wrapper.readOptional(
ew -> wrapper.readList(PropertyMatcher::read));
NBTCompound nbt = wrapper.readOptional(PacketWrapper::readNBT);
return new BlockPredicate(blocks, properties, nbt);
}
@@ -18,10 +18,15 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
import com.github.retrooper.packetevents.protocol.attribute.AttributeOperation;
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes.PropertyModifier;
import net.kyori.adventure.util.Index;
import org.jetbrains.annotations.ApiStatus;
import java.util.Collections;
import java.util.List;
@@ -168,11 +173,16 @@ public class ItemAttributeModifiers {
public static class Modifier {
private UUID id;
private String name;
private UUID id; // removed in 1.21
private String name; // ResourceLocation since 1.21
private double value;
private AttributeOperation operation;
public Modifier(ResourceLocation name, double value, AttributeOperation operation) {
this(PropertyModifier.generateSemiUniqueId(name), name.toString(), value, operation);
}
@ApiStatus.Obsolete
public Modifier(UUID id, String name, double value, AttributeOperation operation) {
this.id = id;
this.name = name;
@@ -181,32 +191,56 @@ public class ItemAttributeModifiers {
}
public static Modifier read(PacketWrapper<?> wrapper) {
UUID id = wrapper.readUUID();
String name = wrapper.readString();
UUID id;
String name;
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
ResourceLocation nameKey = wrapper.readIdentifier();
name = nameKey.toString();
id = PropertyModifier.generateSemiUniqueId(nameKey);
} else {
id = wrapper.readUUID();
name = wrapper.readString();
}
double value = wrapper.readDouble();
AttributeOperation operation = wrapper.readEnum(AttributeOperation.values());
return new Modifier(id, name, value, operation);
}
public static void write(PacketWrapper<?> wrapper, Modifier modifier) {
wrapper.writeUUID(modifier.id);
wrapper.writeString(modifier.name);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
wrapper.writeIdentifier(new ResourceLocation(modifier.name));
} else {
wrapper.writeUUID(modifier.id);
wrapper.writeString(modifier.name);
}
wrapper.writeDouble(modifier.value);
wrapper.writeEnum(modifier.operation);
}
public ResourceLocation getNameKey() {
return new ResourceLocation(this.name);
}
public void setNameKey(ResourceLocation nameKey) {
this.name = nameKey.toString();
}
@ApiStatus.Obsolete
public UUID getId() {
return this.id;
}
@ApiStatus.Obsolete
public void setId(UUID id) {
this.id = id;
}
@ApiStatus.Obsolete
public String getName() {
return this.name;
}
@ApiStatus.Obsolete
public void setName(String name) {
this.name = name;
}
@@ -250,15 +284,29 @@ public class ItemAttributeModifiers {
}
public enum EquipmentSlotGroup {
ANY,
MAINHAND,
OFFHAND,
HAND,
FEET,
LEGS,
CHEST,
HEAD,
ARMOR,
BODY,
ANY("any"),
MAINHAND("mainhand"),
OFFHAND("offhand"),
HAND("hand"),
FEET("feet"),
LEGS("legs"),
CHEST("chest"),
HEAD("head"),
ARMOR("armor"),
BODY("body");
public static final Index<String, EquipmentSlotGroup> ID_INDEX = Index.create(
EquipmentSlotGroup.class, EquipmentSlotGroup::getId);
private final String id;
EquipmentSlotGroup(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
}
}
@@ -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 + '}';
}
}
@@ -47,9 +47,8 @@ public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Int
}
public static ItemEnchantments read(PacketWrapper<?> wrapper) {
ClientVersion version = wrapper.getServerVersion().toClientVersion();
Map<EnchantmentType, Integer> enchantments = wrapper.readMap(
ew -> EnchantmentTypes.getById(version, ew.readVarInt()),
ew -> wrapper.readMappedEntity(EnchantmentTypes.getRegistry()),
PacketWrapper::readVarInt
);
boolean showInTooltip = wrapper.readBoolean();
@@ -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,140 @@
/*
* 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.jukebox.IJukeboxSong;
import com.github.retrooper.packetevents.protocol.item.jukebox.JukeboxSong;
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 ItemJukeboxPlayable {
private @Nullable IJukeboxSong song;
private @Nullable ResourceLocation songKey;
private boolean showInTooltip;
public ItemJukeboxPlayable(
@Nullable JukeboxSong song,
@Nullable ResourceLocation songKey,
boolean showInTooltip
) {
this((IJukeboxSong) song, songKey, showInTooltip);
}
public ItemJukeboxPlayable(
@Nullable IJukeboxSong song,
@Nullable ResourceLocation songKey,
boolean showInTooltip
) {
if ((song == null) == (songKey == null)) {
throw new IllegalStateException("Illegal state of both song and "
+ "song key combined: " + song + " / " + songKey);
}
this.song = song;
this.songKey = songKey;
this.showInTooltip = showInTooltip;
}
public static ItemJukeboxPlayable read(PacketWrapper<?> wrapper) {
IJukeboxSong song;
ResourceLocation songKey;
if (wrapper.readBoolean()) {
song = IJukeboxSong.read(wrapper);
songKey = null;
} else {
song = null;
songKey = wrapper.readIdentifier();
}
boolean showInTooltip = wrapper.readBoolean();
return new ItemJukeboxPlayable(song, songKey, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemJukeboxPlayable jukeboxPlayable) {
if (jukeboxPlayable.song != null) {
wrapper.writeBoolean(true);
IJukeboxSong.write(wrapper, jukeboxPlayable.song);
} else {
assert jukeboxPlayable.songKey != null;
wrapper.writeBoolean(false);
wrapper.writeIdentifier(jukeboxPlayable.songKey);
}
wrapper.writeBoolean(jukeboxPlayable.showInTooltip);
}
public @Nullable IJukeboxSong getJukeboxSong() {
return this.song;
}
public void setJukeboxSong(@Nullable JukeboxSong song) {
this.song = song;
this.songKey = null;
}
@Deprecated
public @Nullable JukeboxSong getSong() {
if (this.song == null) {
return null;
} else if (this.song instanceof JukeboxSong) {
return (JukeboxSong) this.song;
}
return (JukeboxSong) this.song.copy(null);
}
@Deprecated
public void setSong(JukeboxSong song) {
this.song = song;
this.songKey = null;
}
public @Nullable ResourceLocation getSongKey() {
return this.songKey;
}
public void setSongKey(ResourceLocation songKey) {
this.song = null;
this.songKey = songKey;
}
public boolean isShowInTooltip() {
return this.showInTooltip;
}
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemJukeboxPlayable)) return false;
ItemJukeboxPlayable that = (ItemJukeboxPlayable) obj;
if (this.showInTooltip != that.showInTooltip) return false;
if (!Objects.equals(this.song, that.song)) return false;
return Objects.equals(this.songKey, that.songKey);
}
@Override
public int hashCode() {
return Objects.hash(this.song, this.songKey, this.showInTooltip);
}
}
@@ -122,7 +122,7 @@ public class ItemMapDecorations {
compound.setTag("type", new NBTString(decoration.type.getName().toString()));
compound.setTag("x", new NBTDouble(decoration.x));
compound.setTag("z", new NBTDouble(decoration.z));
compound.setTag("float", new NBTFloat(decoration.rotation));
compound.setTag("rotation", new NBTFloat(decoration.rotation));
}
public MapDecorationType getType() {
@@ -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 + '}';
}
}
@@ -27,6 +27,7 @@ import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
public class PotDecorations {
@@ -36,8 +37,13 @@ public class PotDecorations {
private @Nullable ItemType right;
private @Nullable ItemType front;
private PotDecorations(Queue<ItemType> items) {
this(items.poll(), items.poll(), items.poll(), items.poll());
private PotDecorations(Queue<Optional<ItemType>> items) {
this(
items.isEmpty() ? null : items.remove().orElse(null),
items.isEmpty() ? null : items.remove().orElse(null),
items.isEmpty() ? null : items.remove().orElse(null),
items.isEmpty() ? null : items.remove().orElse(null)
);
}
public PotDecorations(
@@ -52,23 +58,28 @@ public class PotDecorations {
this.front = front;
}
private List<ItemType> asList() {
return Arrays.asList(this.back, this.left, this.right, this.front);
private List<Optional<ItemType>> asList() {
return Arrays.asList(
Optional.ofNullable(this.back),
Optional.ofNullable(this.left),
Optional.ofNullable(this.right),
Optional.ofNullable(this.front)
);
}
private static @Nullable ItemType readItem(PacketWrapper<?> wrapper) {
private static Optional<ItemType> readItem(PacketWrapper<?> wrapper) {
ItemType type = wrapper.readMappedEntity(ItemTypes::getById);
return type == ItemTypes.BRICK ? null : type;
return type == ItemTypes.BRICK ? Optional.empty() : Optional.of(type);
}
public static PotDecorations read(PacketWrapper<?> wrapper) {
Queue<ItemType> items = wrapper.<ItemType, Queue<ItemType>>readCollection(
ArrayDeque::new, PotDecorations::readItem);
Queue<Optional<ItemType>> items = wrapper.<Optional<ItemType>, Queue<Optional<ItemType>>>
readCollection(ArrayDeque::new, PotDecorations::readItem);
return new PotDecorations(items);
}
private static void writeItem(PacketWrapper<?> wrapper, @Nullable ItemType type) {
wrapper.writeMappedEntity(type == null ? ItemTypes.BRICK : type);
private static void writeItem(PacketWrapper<?> wrapper, Optional<ItemType> type) {
wrapper.writeMappedEntity(type.orElse(ItemTypes.BRICK));
}
public static void write(PacketWrapper<?> wrapper, PotDecorations decorations) {
@@ -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 + '}';
}
}
@@ -39,11 +39,7 @@ import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
@@ -210,6 +206,14 @@ public class EntityDataTypes {
public static final EntityDataType<Integer> WOLF_VARIANT =
define("wolf_variant_type", readIntDeserializer(), writeIntSerializer());
/**
* Returns an immutable view of the entity-data types.
* @return Entity-Data Types
*/
public static Collection<EntityDataType<?>> values() {
return Collections.unmodifiableCollection(ENTITY_DATA_TYPE_MAP.values());
}
public static EntityDataType<?> getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, EntityDataType<?>> typeIdMap = ENTITY_DATA_TYPE_ID_MAP.get((byte) index);
@@ -24,6 +24,8 @@ import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -153,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);
@@ -297,6 +305,39 @@ 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() {
return Collections.unmodifiableCollection(ENTITY_TYPE_MAP.values());
}
static {
TYPES_BUILDER.unloadFileMappings();
LEGACY_TYPES_BUILDER.unloadFileMappings();
@@ -20,6 +20,8 @@ package com.github.retrooper.packetevents.protocol.entity.villager.type;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -62,4 +64,12 @@ public class VillagerTypes {
public static final VillagerType SNOW = define(4, "minecraft:snow");
public static final VillagerType SWAMP = define(5, "minecraft:swamp");
public static final VillagerType TAIGA = define(6, "minecraft:taiga");
/**
* Returns an immutable view of the villager types.
* @return Villager Types
*/
public static Collection<VillagerType> values() {
return Collections.unmodifiableCollection(VILLAGER_TYPE_MAP.values());
}
}
@@ -0,0 +1,106 @@
/*
* 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.wolfvariant;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.world.biome.Biome;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class StaticWolfVariant extends AbstractMappedEntity implements WolfVariant {
private final ResourceLocation wildTexture;
private final ResourceLocation tameTexture;
private final ResourceLocation angryTexture;
private final MappedEntitySet<Biome> biomes;
public StaticWolfVariant(
ResourceLocation wildTexture,
ResourceLocation tameTexture,
ResourceLocation angryTexture,
MappedEntitySet<Biome> biomes
) {
this(null, wildTexture, tameTexture, angryTexture, biomes);
}
public StaticWolfVariant(
@Nullable TypesBuilderData data,
ResourceLocation wildTexture,
ResourceLocation tameTexture,
ResourceLocation angryTexture,
MappedEntitySet<Biome> biomes
) {
super(data);
this.wildTexture = wildTexture;
this.tameTexture = tameTexture;
this.angryTexture = angryTexture;
this.biomes = biomes;
}
@Override
public WolfVariant copy(@Nullable TypesBuilderData newData) {
return new StaticWolfVariant(newData, this.wildTexture, this.tameTexture, this.angryTexture, this.biomes);
}
@Override
public ResourceLocation getWildTexture() {
return this.wildTexture;
}
@Override
public ResourceLocation getTameTexture() {
return this.tameTexture;
}
@Override
public ResourceLocation getAngryTexture() {
return this.angryTexture;
}
@Override
public MappedEntitySet<Biome> getBiomes() {
return this.biomes;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticWolfVariant)) return false;
if (!super.equals(obj)) return false;
StaticWolfVariant that = (StaticWolfVariant) obj;
if (!this.wildTexture.equals(that.wildTexture)) return false;
if (!this.tameTexture.equals(that.tameTexture)) return false;
if (!this.angryTexture.equals(that.angryTexture)) return false;
return this.biomes.equals(that.biomes);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.wildTexture, this.tameTexture, this.angryTexture, this.biomes);
}
@Override
public String toString() {
return "StaticWolfVariant{wildTexture=" + this.wildTexture + ", tameTexture=" + this.tameTexture + ", angryTexture=" + this.angryTexture + ", biomes=" + this.biomes + '}';
}
}
@@ -0,0 +1,63 @@
/*
* 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.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;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.biome.Biome;
import com.github.retrooper.packetevents.protocol.world.biome.Biomes;
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>, DeepComparableEntity {
ResourceLocation getWildTexture();
ResourceLocation getTameTexture();
ResourceLocation getAngryTexture();
MappedEntitySet<Biome> getBiomes();
static WolfVariant decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
ResourceLocation wildTexture = new ResourceLocation(compound.getStringTagValueOrThrow("wild_texture"));
ResourceLocation tameTexture = new ResourceLocation(compound.getStringTagValueOrThrow("tame_texture"));
ResourceLocation angryTexture = new ResourceLocation(compound.getStringTagValueOrThrow("angry_texture"));
MappedEntitySet<Biome> biomes = MappedEntitySet.decode(
compound.getTagOrThrow("biomes"), version, Biomes.getRegistry());
return new StaticWolfVariant(data, wildTexture, tameTexture, angryTexture, biomes);
}
static NBT encode(WolfVariant variant, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("wild_texture", new NBTString(variant.getWildTexture().toString()));
compound.setTag("tame_texture", new NBTString(variant.getTameTexture().toString()));
compound.setTag("angry_texture", new NBTString(variant.getAngryTexture().toString()));
compound.setTag("biomes", MappedEntitySet.encode(variant.getBiomes(), version));
return compound;
}
}
@@ -0,0 +1,88 @@
/*
* 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.wolfvariant;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.world.biome.Biome;
import com.github.retrooper.packetevents.protocol.world.biome.Biomes;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
import java.util.Arrays;
public final class WolfVariants {
private static final VersionedRegistry<WolfVariant> REGISTRY = new VersionedRegistry<>(
"wolf_variant", "entity/wolf_variant_mappings");
private WolfVariants() {
}
@ApiStatus.Internal
public static WolfVariant define(String key, MappedEntitySet<Biome> biomes) {
return define(key, "wolf_" + key, biomes);
}
@ApiStatus.Internal
public static WolfVariant define(String key, String assetId, MappedEntitySet<Biome> biomes) {
return define(key, ResourceLocation.minecraft("entity/wolf/" + assetId),
ResourceLocation.minecraft("entity/wolf/" + assetId + "_tame"),
ResourceLocation.minecraft("entity/wolf/" + assetId + "_angry"), biomes);
}
@ApiStatus.Internal
public static WolfVariant define(
String key,
ResourceLocation wildTexture,
ResourceLocation tameTexture,
ResourceLocation angryTexture,
MappedEntitySet<Biome> biomes
) {
return REGISTRY.define(key, data -> new StaticWolfVariant(
data, wildTexture, tameTexture, angryTexture, biomes));
}
public static VersionedRegistry<WolfVariant> getRegistry() {
return REGISTRY;
}
public static final WolfVariant PALE = define("pale", "wolf",
new MappedEntitySet<>(Arrays.asList(Biomes.TAIGA)));
public static final WolfVariant SPOTTED = define("spotted",
new MappedEntitySet<>(ResourceLocation.minecraft("is_savanna")));
public static final WolfVariant SNOWY = define("snowy",
new MappedEntitySet<>(Arrays.asList(Biomes.GROVE)));
public static final WolfVariant BLACK = define("black",
new MappedEntitySet<>(Arrays.asList(Biomes.OLD_GROWTH_PINE_TAIGA)));
public static final WolfVariant ASHEN = define("ashen",
new MappedEntitySet<>(Arrays.asList(Biomes.SNOWY_TAIGA)));
public static final WolfVariant RUSTY = define("rusty",
new MappedEntitySet<>(ResourceLocation.minecraft("is_jungle")));
public static final WolfVariant WOODS = define("woods",
new MappedEntitySet<>(Arrays.asList(Biomes.FOREST)));
public static final WolfVariant CHESTNUT = define("chestnut",
new MappedEntitySet<>(Arrays.asList(Biomes.OLD_GROWTH_SPRUCE_TAIGA)));
public static final WolfVariant STRIPED = define("striped",
new MappedEntitySet<>(ResourceLocation.minecraft("is_badlands")));
static {
REGISTRY.unloadMappings();
}
}
@@ -21,19 +21,23 @@ package com.github.retrooper.packetevents.protocol.item;
import com.github.retrooper.packetevents.protocol.component.ComponentType;
import com.github.retrooper.packetevents.protocol.component.ComponentTypes;
import com.github.retrooper.packetevents.protocol.component.PatchableComponentMap;
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
import com.github.retrooper.packetevents.protocol.item.enchantment.Enchantment;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentType;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
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.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
import com.github.retrooper.packetevents.protocol.nbt.NBTShort;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -80,6 +84,54 @@ public class ItemStack {
updateCachedEmptyStatus();
}
public static ItemStack decode(NBT nbt, ClientVersion version) {
if (nbt instanceof NBTString) {
ResourceLocation itemName = new ResourceLocation(((NBTString) nbt).getValue());
return ItemStack.builder().type(ItemTypes.getByName(itemName.toString())).build();
}
NBTCompound compound = (NBTCompound) nbt;
ItemStack.Builder builder = ItemStack.builder();
ResourceLocation itemName = Optional.ofNullable(compound.getStringTagValueOrNull("id")).map(Optional::of)
.orElseGet(() -> Optional.ofNullable(compound.getStringTagValueOrNull("item")))
.map(ResourceLocation::new).orElseThrow(() -> new IllegalArgumentException(
"No item type specified: " + compound.getTags().keySet()));
builder.type(ItemTypes.getByName(itemName.toString()));
builder.nbt(compound.getCompoundTagOrNull("tag"));
Optional.ofNullable(compound.getNumberTagOrNull("Count")).map(Optional::of)
.orElseGet(() -> Optional.ofNullable(compound.getNumberTagOrNull("count")))
.map(NBTNumber::getAsInt).ifPresent(builder::amount);
// TODO components
return builder.build();
}
public static NBT encodeForParticle(ItemStack itemStack, ClientVersion version) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
boolean simple = itemStack.isEmpty()
|| itemStack.components == null
|| itemStack.components.getPatches().isEmpty();
if (simple) {
return new NBTString(itemStack.type.getName().toString());
}
}
NBTCompound compound = new NBTCompound();
compound.setTag("id", new NBTString(itemStack.type.getName().toString()));
if (version.isOlderThan(ClientVersion.V_1_20_5)) {
compound.setTag("Count", new NBTInt(itemStack.amount));
if (itemStack.nbt != null) {
compound.setTag("tag", itemStack.nbt);
}
}
// TODO components
return compound;
}
public int getMaxStackSize() {
return this.getComponentOr(MAX_STACK_SIZE,
// fallback to legacy specified max stack size
@@ -273,17 +325,15 @@ public class ItemStack {
}
// check for components
Optional<ItemEnchantments> optEnchantments = this.getComponent(ENCHANTMENTS);
Optional<ItemEnchantments> optStoredEnchantments = this.getComponent(STORED_ENCHANTMENTS);
if (optEnchantments.isPresent() || optStoredEnchantments.isPresent()) {
ItemEnchantments enchantments = optEnchantments.orElse(ItemEnchantments.EMPTY);
ItemEnchantments storedEnchantments = optStoredEnchantments.orElse(ItemEnchantments.EMPTY);
ItemEnchantments enchantmentsComp = this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY);
ItemEnchantments storedEnchantmentsComp = this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY);
if (!enchantmentsComp.isEmpty() || !storedEnchantmentsComp.isEmpty()) {
List<Enchantment> enchantmentsList = new ArrayList<>(
enchantments.getEnchantmentCount() + storedEnchantments.getEnchantmentCount());
for (Map.Entry<EnchantmentType, Integer> enchantment : enchantments) {
enchantmentsComp.getEnchantmentCount() + storedEnchantmentsComp.getEnchantmentCount());
for (Map.Entry<EnchantmentType, Integer> enchantment : enchantmentsComp) {
enchantmentsList.add(new Enchantment(enchantment.getKey(), enchantment.getValue()));
}
for (Map.Entry<EnchantmentType, Integer> enchantment : storedEnchantments) {
for (Map.Entry<EnchantmentType, Integer> enchantment : storedEnchantmentsComp) {
enchantmentsList.add(new Enchantment(enchantment.getKey(), enchantment.getValue()));
}
return enchantmentsList;
@@ -320,16 +370,16 @@ public class ItemStack {
}
// check for components
Optional<ItemEnchantments> optEnchantments = this.getComponent(ENCHANTMENTS);
if (optEnchantments.isPresent()) {
int level = optEnchantments.get().getEnchantmentLevel(enchantment);
ItemEnchantments enchantmentsComp = this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY);
if (!enchantmentsComp.isEmpty()) {
int level = enchantmentsComp.getEnchantmentLevel(enchantment);
if (level > 0) {
return level;
}
}
Optional<ItemEnchantments> optStoredEnchantments = this.getComponent(STORED_ENCHANTMENTS);
if (optStoredEnchantments.isPresent()) {
int level = optStoredEnchantments.get().getEnchantmentLevel(enchantment);
ItemEnchantments storedEnchantmentsComp = this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY);
if (!storedEnchantmentsComp.isEmpty()) {
int level = storedEnchantmentsComp.getEnchantmentLevel(enchantment);
if (level > 0) {
return level;
}
@@ -462,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) + "]";
}
}
@@ -496,11 +546,28 @@ public class ItemStack {
return this;
}
public Builder nbt(String key, NBT tag) {
if (this.nbt == null) {
this.nbt = new NBTCompound();
}
this.nbt.setTag(key, tag);
return this;
}
public Builder components(@Nullable PatchableComponentMap components) {
this.components = components;
return this;
}
public <T> Builder component(ComponentType<T> type, @Nullable T value) {
if (this.components == null) {
this.components = new PatchableComponentMap(this.type == null
? StaticComponentMap.SHARED_ITEM_COMPONENTS : this.type.getComponents());
}
this.components.set(type, value);
return this;
}
public Builder legacyData(int legacyData) {
this.legacyData = legacyData;
return this;
@@ -43,7 +43,7 @@ public class ArmorMaterials {
@Override
public int getId(ClientVersion version) {
return TYPES_BUILDER.getDataIndex(version);
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
@@ -18,11 +18,19 @@
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;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
public interface BannerPattern extends MappedEntity {
public interface BannerPattern extends MappedEntity, CopyableEntity<BannerPattern>, DeepComparableEntity {
ResourceLocation getAssetId();
@@ -38,4 +46,18 @@ public interface BannerPattern extends MappedEntity {
wrapper.writeIdentifier(pattern.getAssetId());
wrapper.writeString(pattern.getTranslationKey());
}
static BannerPattern decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
ResourceLocation assetId = new ResourceLocation(compound.getStringTagValueOrThrow("asset_id"));
String translationKey = compound.getStringTagValueOrThrow("translation_key");
return new StaticBannerPattern(data, assetId, translationKey);
}
static NBT encode(BannerPattern bannerPattern, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("asset_id", new NBTString(bannerPattern.getAssetId().toString()));
compound.setTag("translation_key", new NBTString(bannerPattern.getTranslationKey()));
return compound;
}
}
@@ -20,69 +20,42 @@ package com.github.retrooper.packetevents.protocol.item.banner;
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 java.util.HashMap;
import java.util.Map;
import java.util.Collection;
public class BannerPatterns {
public final class BannerPatterns {
private static final Map<String, BannerPattern> PATTERN_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, BannerPattern>> PATTERN_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_banner_pattern_mappings");
private static final VersionedRegistry<BannerPattern> REGISTRY = new VersionedRegistry<>(
"banner_pattern", "item/item_banner_pattern_mappings");
private BannerPatterns() {
}
@ApiStatus.Internal
public static BannerPattern define(String key) {
ResourceLocation assetId = ResourceLocation.minecraft(key);
String translationKey = "block.minecraft.banner." + key;
return define(key, assetId, translationKey);
}
@ApiStatus.Internal
public static BannerPattern define(String key, ResourceLocation assetId, String translationKey) {
TypesBuilderData data = TYPES_BUILDER.define(key);
BannerPattern pattern = new BannerPattern() {
@Override
public ResourceLocation getAssetId() {
return assetId;
}
@Override
public String getTranslationKey() {
return translationKey;
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return TYPES_BUILDER.getDataIndex(version);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BannerPattern) {
return getName().equals(((BannerPattern) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, PATTERN_TYPE_MAP, PATTERN_TYPE_ID_MAP, pattern);
return pattern;
return REGISTRY.define(key, data ->
new StaticBannerPattern(data, assetId, translationKey));
}
public static VersionedRegistry<BannerPattern> getRegistry() {
return REGISTRY;
}
// with key
public static BannerPattern getByName(String name) {
return PATTERN_TYPE_MAP.get(name);
return REGISTRY.getByName(name);
}
public static BannerPattern getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, BannerPattern> idMap = PATTERN_TYPE_ID_MAP.get((byte) index);
return idMap.get(id);
return REGISTRY.getById(version, id);
}
public static final BannerPattern SQUARE_BOTTOM_LEFT = define("square_bottom_left");
@@ -127,7 +100,20 @@ public class BannerPatterns {
public static final BannerPattern PIGLIN = define("piglin");
public static final BannerPattern DIAGONAL_LEFT = define("diagonal_left");
// Added with 1.21
public static final BannerPattern FLOW = define("flow");
public static final BannerPattern GUSTER = define("guster");
/**
* Returns an immutable view of the banner patterns.
*
* @return Banner Patterns
*/
public static Collection<BannerPattern> values() {
return REGISTRY.getEntries();
}
static {
TYPES_BUILDER.unloadFileMappings();
REGISTRY.unloadMappings();
}
}
@@ -18,21 +18,33 @@
package com.github.retrooper.packetevents.protocol.item.banner;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class StaticBannerPattern implements BannerPattern {
public class StaticBannerPattern extends AbstractMappedEntity implements BannerPattern {
private final ResourceLocation assetId;
private final String translationKey;
public StaticBannerPattern(ResourceLocation assetId, String translationKey) {
this(null, assetId, translationKey);
}
public StaticBannerPattern(@Nullable TypesBuilderData data, ResourceLocation assetId, String translationKey) {
super(data);
this.assetId = assetId;
this.translationKey = translationKey;
}
@Override
public BannerPattern copy(@Nullable TypesBuilderData newData) {
return new StaticBannerPattern(newData, this.assetId, this.translationKey);
}
@Override
public ResourceLocation getAssetId() {
return this.assetId;
@@ -44,31 +56,22 @@ public class StaticBannerPattern implements BannerPattern {
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
}
@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 StaticBannerPattern)) return false;
if (!super.equals(obj)) return false;
StaticBannerPattern that = (StaticBannerPattern) obj;
if (!this.assetId.equals(that.assetId)) return false;
return this.translationKey.equals(that.translationKey);
}
@Override
public int hashCode() {
return Objects.hash(this.assetId, this.translationKey);
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.assetId, this.translationKey);
}
@Override
public String toString() {
return "StaticBannerPattern{assetId=" + this.assetId + ", translationKey='" + 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;
}
}
@@ -0,0 +1,78 @@
/*
* 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.enchantment;
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.player.ClientVersion;
import java.util.Objects;
public final class EnchantmentCost {
private final int base;
private final int perLevelAboveFirst;
public EnchantmentCost(int base, int perLevelAboveFirst) {
this.base = base;
this.perLevelAboveFirst = perLevelAboveFirst;
}
public static EnchantmentCost decode(NBT nbt, ClientVersion version) {
NBTCompound compound = (NBTCompound) nbt;
int base = compound.getNumberTagOrThrow("base").getAsInt();
int perLevelAboveFirst = compound.getNumberTagOrThrow("per_level_above_first").getAsInt();
return new EnchantmentCost(base, perLevelAboveFirst);
}
public static NBT encode(EnchantmentCost cost, ClientVersion version) {
NBTCompound compound = new NBTCompound();
compound.setTag("base", new NBTInt(cost.base));
compound.setTag("per_level_above_first", new NBTInt(cost.perLevelAboveFirst));
return compound;
}
public int getBase() {
return this.base;
}
public int getPerLevelAboveFirst() {
return this.perLevelAboveFirst;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof EnchantmentCost)) return false;
EnchantmentCost that = (EnchantmentCost) obj;
if (this.base != that.base) return false;
return this.perLevelAboveFirst == that.perLevelAboveFirst;
}
@Override
public int hashCode() {
return Objects.hash(this.base, this.perLevelAboveFirst);
}
@Override
public String toString() {
return "EnchantmentCost{base=" + this.base + ", perLevelAboveFirst=" + this.perLevelAboveFirst + '}';
}
}
@@ -0,0 +1,175 @@
/*
* 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.enchantment;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAttributeModifiers.EquipmentSlotGroup;
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.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.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import static com.github.retrooper.packetevents.util.adventure.AdventureIndexUtil.indexValueOrThrow;
public final class EnchantmentDefinition {
private final MappedEntitySet<ItemType> supportedItems;
private final Optional<MappedEntitySet<ItemType>> primaryItems;
private final int weight;
private final int maxLevel;
private final EnchantmentCost minCost;
private final EnchantmentCost maxCost;
private final int anvilCost;
private final List<EquipmentSlotGroup> slots;
public EnchantmentDefinition(
MappedEntitySet<ItemType> supportedItems,
Optional<MappedEntitySet<ItemType>> primaryItems,
int weight, int maxLevel,
EnchantmentCost minCost, EnchantmentCost maxCost,
int anvilCost, List<EquipmentSlotGroup> slots
) {
this.supportedItems = supportedItems;
this.primaryItems = primaryItems;
this.weight = weight;
this.maxLevel = maxLevel;
this.minCost = minCost;
this.maxCost = maxCost;
this.anvilCost = anvilCost;
this.slots = slots;
}
public static EnchantmentDefinition decode(NBT nbt, ClientVersion version) {
NBTCompound compound = (NBTCompound) nbt;
MappedEntitySet<ItemType> supportedItems = MappedEntitySet.decode(
compound.getTagOrThrow("supported_items"), version, ItemTypes.getRegistry());
Optional<MappedEntitySet<ItemType>> primaryItems = Optional.ofNullable(compound.getTagOrNull("primary_items"))
.map(items -> MappedEntitySet.decode(items, version, ItemTypes.getRegistry()));
int weight = compound.getNumberTagOrThrow("weight").getAsInt();
int maxLevel = compound.getNumberTagOrThrow("max_level").getAsInt();
EnchantmentCost minCost = EnchantmentCost.decode(compound.getTagOrThrow("min_cost"), version);
EnchantmentCost maxCost = EnchantmentCost.decode(compound.getTagOrThrow("max_cost"), version);
int anvilCost = compound.getNumberTagOrThrow("anvil_cost").getAsInt();
NBT slotsTag = compound.getTagOrThrow("slots");
List<EquipmentSlotGroup> slots;
if (slotsTag instanceof NBTList<?>) {
NBTList<?> slotsTagList = (NBTList<?>) slotsTag;
slots = new ArrayList<>(slotsTagList.size());
for (NBT tag : slotsTagList.getTags()) {
String slotGroupId = ((NBTString) tag).getValue();
slots.add(indexValueOrThrow(EquipmentSlotGroup.ID_INDEX, slotGroupId));
}
} else {
String slotGroupId = ((NBTString) slotsTag).getValue();
EquipmentSlotGroup slotGroup = indexValueOrThrow(EquipmentSlotGroup.ID_INDEX, slotGroupId);
slots = Collections.singletonList(slotGroup);
}
return new EnchantmentDefinition(supportedItems, primaryItems, weight,
maxLevel, minCost, maxCost, anvilCost, slots);
}
public static NBT encode(EnchantmentDefinition definition, ClientVersion version) {
NBTList<NBTString> slotsTag = NBTList.createStringList();
for (EquipmentSlotGroup slot : definition.slots) {
slotsTag.addTag(new NBTString(slot.getId()));
}
NBTCompound compound = new NBTCompound();
compound.setTag("supported_items", MappedEntitySet.encode(
definition.supportedItems, version));
definition.primaryItems.ifPresent(set -> compound.setTag(
"primary_items", MappedEntitySet.encode(set, version)));
compound.setTag("weight", new NBTInt(definition.weight));
compound.setTag("max_level", new NBTInt(definition.maxLevel));
compound.setTag("min_cost", EnchantmentCost.encode(definition.minCost, version));
compound.setTag("max_cost", EnchantmentCost.encode(definition.maxCost, version));
compound.setTag("anvil_cost", new NBTInt(definition.anvilCost));
compound.setTag("slots", slotsTag);
return compound;
}
public MappedEntitySet<ItemType> getSupportedItems() {
return this.supportedItems;
}
public Optional<MappedEntitySet<ItemType>> getPrimaryItems() {
return this.primaryItems;
}
public int getWeight() {
return this.weight;
}
public int getMaxLevel() {
return this.maxLevel;
}
public EnchantmentCost getMinCost() {
return this.minCost;
}
public EnchantmentCost getMaxCost() {
return this.maxCost;
}
public int getAnvilCost() {
return this.anvilCost;
}
public List<EquipmentSlotGroup> getSlots() {
return this.slots;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof EnchantmentDefinition)) return false;
EnchantmentDefinition that = (EnchantmentDefinition) obj;
if (this.weight != that.weight) return false;
if (this.maxLevel != that.maxLevel) return false;
if (this.anvilCost != that.anvilCost) return false;
if (!this.supportedItems.equals(that.supportedItems)) return false;
if (!this.primaryItems.equals(that.primaryItems)) return false;
if (!this.minCost.equals(that.minCost)) return false;
if (!this.maxCost.equals(that.maxCost)) return false;
return this.slots.equals(that.slots);
}
@Override
public int hashCode() {
return Objects.hash(this.supportedItems, this.primaryItems, this.weight, this.maxLevel, this.minCost, this.maxCost, this.anvilCost, this.slots);
}
@Override
public String toString() {
return "EnchantmentDefinition{supportedItems=" + this.supportedItems + ", primaryItems=" + this.primaryItems + ", weight=" + this.weight + ", maxLevel=" + this.maxLevel + ", minCost=" + this.minCost + ", maxCost=" + this.maxCost + ", anvilCost=" + this.anvilCost + ", slots=" + this.slots + '}';
}
}
@@ -18,7 +18,57 @@
package com.github.retrooper.packetevents.protocol.item.enchantment.type;
import com.github.retrooper.packetevents.protocol.component.EnchantEffectComponentTypes;
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;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
public interface EnchantmentType extends MappedEntity {
import java.util.Optional;
public interface EnchantmentType extends MappedEntity, CopyableEntity<EnchantmentType>, DeepComparableEntity {
Component getDescription();
EnchantmentDefinition getDefinition();
MappedEntitySet<EnchantmentType> getExclusiveSet();
StaticComponentMap getEffects();
static EnchantmentType decode(NBT nbt, ClientVersion version, @Nullable TypesBuilderData data) {
NBTCompound compound = (NBTCompound) nbt;
Component description = AdventureSerializer.fromNbt(compound.getTagOrThrow("description"));
EnchantmentDefinition definition = EnchantmentDefinition.decode(compound, version);
MappedEntitySet<EnchantmentType> exclusiveSet = Optional.ofNullable(compound.getTagOrNull("exclusive_set"))
.map(tag -> MappedEntitySet.decode(tag, version, EnchantmentTypes.getRegistry()))
.orElseGet(MappedEntitySet::createEmpty);
StaticComponentMap effects = Optional.ofNullable(compound.getTagOrNull("effects"))
.map(tag -> IComponentMap.decode(tag, version,
EnchantEffectComponentTypes.getRegistry()))
.orElse(StaticComponentMap.EMPTY);
return new StaticEnchantmentType(data, description, definition, exclusiveSet, effects);
}
static NBT encode(EnchantmentType type, ClientVersion version) {
NBTCompound compound = (NBTCompound) EnchantmentDefinition.encode(type.getDefinition(), version);
compound.setTag("description", AdventureSerializer.toNbt(type.getDescription()));
if (!type.getExclusiveSet().isEmpty()) {
compound.setTag("exclusive_set", MappedEntitySet.encode(type.getExclusiveSet(), version));
}
if (!type.getEffects().isEmpty()) {
compound.setTag("effects", IComponentMap.encode(type.getEffects(), version));
}
return compound;
}
}
@@ -18,17 +18,21 @@
package com.github.retrooper.packetevents.protocol.item.enchantment.type;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.serializer.SequentialNBTReader;
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.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class EnchantmentTypes {
public final class EnchantmentTypes {
private static final Map<String, String> STRING_UPDATER = new HashMap<>();
@@ -37,47 +41,50 @@ public class EnchantmentTypes {
STRING_UPDATER.put("minecraft:sweeping", "minecraft:sweeping_edge");
}
private static final Map<String, EnchantmentType> ENCHANTMENT_TYPE_MAPPINGS = new HashMap<>();
private static final Map<Byte, Map<Integer, EnchantmentType>> ENCHANTMENT_TYPE_ID_MAPPINGS = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("enchantment/enchantment_type_mappings");
// load data from file, enchantment types are too complex to define in code here
private static final Map<ResourceLocation, NBTCompound> ENCHANTMENT_DATA;
public static EnchantmentType define(String key) {
TypesBuilderData data = TYPES_BUILDER.define(key);
EnchantmentType enchantmentType = new EnchantmentType() {
@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 EnchantmentType) {
return getName() == ((EnchantmentType) obj).getName();
static {
ENCHANTMENT_DATA = new HashMap<>();
try (SequentialNBTReader.Compound dataTag = MappingHelper.decompress("mappings/enchantment/enchantment_type_data")) {
while (dataTag.hasNext()) {
Map.Entry<String, NBT> entry = dataTag.next();
if (entry.getKey().equals("version")) {
continue; // skip version field
}
return false;
ResourceLocation enchantKey = new ResourceLocation(entry.getKey());
ENCHANTMENT_DATA.put(enchantKey, ((SequentialNBTReader.Compound) entry.getValue()).readFully());
}
};
MappingHelper.registerMapping(TYPES_BUILDER, ENCHANTMENT_TYPE_MAPPINGS, ENCHANTMENT_TYPE_ID_MAPPINGS, enchantmentType);
return enchantmentType;
} catch (IOException exception) {
throw new RuntimeException("Error while reading enchantment type data", exception);
}
}
@Nullable
public static EnchantmentType getByName(String name) {
private static final VersionedRegistry<EnchantmentType> REGISTRY = new VersionedRegistry<>(
"enchantment", "enchantment/enchantment_type_mappings");
@ApiStatus.Internal
public static EnchantmentType define(String key) {
return REGISTRY.define(key, data -> {
NBTCompound dataTag = ENCHANTMENT_DATA.get(data.getName());
if (dataTag == null) {
throw new IllegalArgumentException("Can't define enchantment " + data.getName() + ", no data found");
}
return EnchantmentType.decode(dataTag, ClientVersion.getLatest(), data);
});
}
public static VersionedRegistry<EnchantmentType> getRegistry() {
return REGISTRY;
}
public static @Nullable EnchantmentType getByName(String name) {
String fixedName = STRING_UPDATER.getOrDefault(name, name);
return ENCHANTMENT_TYPE_MAPPINGS.get(fixedName);
return REGISTRY.getByName(fixedName);
}
@Nullable
public static EnchantmentType getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, EnchantmentType> typeIdMap = ENCHANTMENT_TYPE_ID_MAPPINGS.get((byte) index);
return typeIdMap.get(id);
public static @Nullable EnchantmentType getById(ClientVersion version, int id) {
return REGISTRY.getById(version, id);
}
public static final EnchantmentType ALL_DAMAGE_PROTECTION = define("protection");
@@ -126,6 +133,7 @@ public class EnchantmentTypes {
public static final EnchantmentType WIND_BURST = define("wind_burst");
static {
TYPES_BUILDER.unloadFileMappings();
ENCHANTMENT_DATA.clear();
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,108 @@
/*
* 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.enchantment.type;
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
import com.github.retrooper.packetevents.protocol.item.enchantment.EnchantmentDefinition;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
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 StaticEnchantmentType extends AbstractMappedEntity implements EnchantmentType {
private final Component description;
private final EnchantmentDefinition definition;
private final MappedEntitySet<EnchantmentType> exclusiveSet;
private final StaticComponentMap effects;
public StaticEnchantmentType(
Component description,
EnchantmentDefinition definition,
MappedEntitySet<EnchantmentType> exclusiveSet,
StaticComponentMap effects
) {
this(null, description, definition, exclusiveSet, effects);
}
public StaticEnchantmentType(
@Nullable TypesBuilderData data,
Component description,
EnchantmentDefinition definition,
MappedEntitySet<EnchantmentType> exclusiveSet,
StaticComponentMap effects
) {
super(data);
this.description = description;
this.definition = definition;
this.exclusiveSet = exclusiveSet;
this.effects = effects;
}
@Override
public EnchantmentType copy(@Nullable TypesBuilderData newData) {
return new StaticEnchantmentType(newData, this.description,
this.definition, this.exclusiveSet, this.effects);
}
@Override
public Component getDescription() {
return this.description;
}
@Override
public EnchantmentDefinition getDefinition() {
return this.definition;
}
@Override
public MappedEntitySet<EnchantmentType> getExclusiveSet() {
return this.exclusiveSet;
}
@Override
public StaticComponentMap getEffects() {
return this.effects;
}
@Override
public boolean deepEquals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticEnchantmentType)) return false;
if (!super.equals(obj)) return false;
StaticEnchantmentType that = (StaticEnchantmentType) obj;
if (!this.description.equals(that.description)) return false;
if (!this.definition.equals(that.definition)) return false;
if (!this.exclusiveSet.equals(that.exclusiveSet)) return false;
return this.effects.equals(that.effects);
}
@Override
public int deepHashCode() {
return Objects.hash(super.hashCode(), this.description, this.definition, this.exclusiveSet, this.effects);
}
@Override
public String toString() {
return "StaticEnchantmentType{description=" + this.description + ", definition=" + this.definition + ", exclusiveSet=" + this.exclusiveSet + ", effects=" + 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);
}
}
Loaded 100 of 538 files, more files were not shown because too many files have changed in this diff. Show more