Compare commits

...
Author SHA1 Message Date
copilot-swe-agent[bot]andretrooper e4676a18fe Optimize loop performance by caching size() and using entrySet()
Co-authored-by: retrooper <49798017+retrooper@users.noreply.github.com>
2025-11-08 00:59:09 +00:00
copilot-swe-agent[bot] a5b0758b67 Initial plan 2025-11-08 00:53:13 +00:00
booky 14b162b098 Merge pull request #1380 from Rothes/palette-constructor
Add constructor with data array to ListPalette
2025-11-06 13:21:06 +01:00
Rothes f1e9a6f1e8 Guarantee data array length 2025-11-06 17:53:18 +08:00
retrooper 00c8164201 2.10.2 snapshot 2025-11-04 19:32:53 +01:00
retrooper 206d1e03bb 2.10.1 release 2025-11-04 17:42:44 +01:00
retrooper c180263e3f Merge pull request #1389 from SamB440/sponge-adventure
Validate Sponge Adventure version & fix logging
2025-11-04 13:59:17 +01:00
retrooper 8872c65ba2 Merge pull request #1374 from booky10/fix/particle-types-1-21-9
Fix 1.21.9/1.21.10 particle types
2025-11-04 13:56:53 +01:00
retrooper abe79fb351 I couldn't find a better solution to this. 2025-11-04 13:50:07 +01:00
booky b76a014432 Merge pull request #1382 from TheFaser/fix/fabric-player-head
Fix nbt list unwrapping logic
2025-11-04 12:45:10 +01:00
Rothes c7b9e15cef Verify data length 2025-11-04 04:20:02 +08:00
booky fade6da4e2 Fix missing tag unwrapping 2025-11-03 20:59:34 +01:00
retrooper 86c67bfe52 Merge pull request #1390 from retrooper/revert-1384-2.0
Revert "Check if Velocity anti-bots closed the channel before initializing"
2025-11-02 21:33:52 +01:00
retrooper 6cda366bc2 Revert "Check if Velocity anti-bots closed the channel before initializing" 2025-11-02 21:33:30 +01:00
SamB440 2771c6c5d1 Validate Sponge Adventure version & fix logging 2025-11-01 16:43:28 +00:00
booky 7ba541843b Merge pull request #1387 from Axionize/fix/lp-vector-3
Fix incorrect encoding of LPVector3d
2025-10-30 23:05:56 +01:00
TheFaser 47ac4d5894 simplify NBT list conversion logic 2025-10-30 22:30:17 +05:00
TheFaser 6c424946fe Revert "add support for decoding item profile properties from NBT lists, fix #1377"
This reverts commit 0d030d0ca7.
2025-10-30 22:29:59 +05:00
Axionize b4e5b10299 Fix incorrect mul calculation for LPVector3d 2025-10-30 12:52:32 -04:00
booky efeb9019a6 Merge pull request #1384 from linsaftw/2.0
Check if Velocity anti-bots closed the channel before initializing
2025-10-27 20:31:00 +01:00
linsaftw 5b994a58da Check if Velocity anti-bots closed the channel before initializing 2025-10-27 14:47:57 -03:00
TheFaser 0d030d0ca7 add support for decoding item profile properties from NBT lists, fix #1377 2025-10-27 11:48:08 +05:00
Rothes cff73e9e67 Add constructor with data array to ListPalette 2025-10-26 15:45:44 +08:00
booky10 7225117fea Fix bees component for 1.21.9+
Fixes #1378
2025-10-26 04:46:43 +01:00
booky10 3f44016db1 Merge branch '2.0' into fix/particle-types-1-21-9 2025-10-19 23:33:46 +02:00
retrooper c0dc2c5908 2.10.1 snapshot 2025-10-19 22:38:36 +02:00
booky10 8a0ebb77eb Downgrade buildscript jackson dependency
Our publishing plugin isn't compatible with jackson v2.20.0, which is provided by the run-task plugin
2025-10-19 21:11:01 +02:00
booky10 4ebb0acbfe Implement new spell effect particle data 2025-10-19 18:20:56 +02:00
booky10 b4831c4f09 Add color data to flash particle 2025-10-19 18:04:41 +02:00
booky10 17563f1856 Implement new dragon breath particle data 2025-10-19 17:55:16 +02:00
booky10 486cf4c74d Place sources and javadoc jars in root build directory
This will now allow our actions artifact upload task to pick up these files again, which fixes our automatic javadoc generation
2025-10-19 05:01:24 +02:00
retrooper 0528f0ebc6 2.10.0 release 2025-10-19 01:06:32 +02:00
booky ce43c2ba84 Merge pull request #1370 from TheFaser/2.0
update adventure version and add support object components
2025-10-18 01:38:40 +02:00
booky10 f37bb34cdf Reapply adventure serializer patch and update it
I hate this stupid fucking shit mess, can we just stop shading adventure please?
2025-10-18 01:25:56 +02:00
booky10 3fb60fa2c5 Update adventure patch classes to v4.25.0
I hate this adventure mess we are in
2025-10-18 00:36:55 +02:00
booky10 e59c1a5d3a Revert "Temporarily revert adventure patch"
This reverts commit 3831a7d1f0.
2025-10-18 00:31:55 +02:00
booky10 3831a7d1f0 Temporarily revert adventure patch 2025-10-18 00:30:25 +02:00
booky10 f7aee7c797 Align some lines in patched adventure subproject with real adventure 2025-10-18 00:27:50 +02:00
booky10 68b0a65288 Use ItemProfile nbt codec in adventure nbt serializer 2025-10-18 00:01:22 +02:00
booky10 7633319f2a Add full support for decoding/encoding ItemProfile to/from nbt tags
I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs I hate codecs
2025-10-17 23:52:48 +02:00
booky10 ca8ca25a3f Fix PlayerModelType reading/writing
I didn't expect mojang to use a simple boolean here
2025-10-17 23:39:43 +02:00
booky10 a96657d600 Don't check for version when decoding 2025-10-17 22:25:14 +02:00
booky10 bf664a4314 Merge branch '2.0' into TheFaser/2.0 2025-10-17 22:19:46 +02:00
TheFaser 8dd5bec27f remove double version check for sprite serialization 2025-10-12 19:28:03 +05:00
booky10 e11ae8b2cf Fix SpigotReflectionUtil#recentTPS() trying to read legacy fields 2025-10-09 21:53:15 +02:00
TheFaser c8f070cf7d add backward compatibility 2025-10-08 16:38:45 +05:00
TheFaser cc76a19fe3 add player head texture support 2025-10-08 12:45:58 +05:00
TheFaser d0b4ca57d1 fix hat boolean 2025-10-08 12:45:05 +05:00
TheFaser 18d103d202 add some comments 2025-10-08 12:27:18 +05:00
TheFaser 56241cee40 remove unnecessary atlas reading 2025-10-08 12:00:31 +05:00
TheFaser 061874fa46 add support for serializing and deserializing object components 2025-10-08 02:49:54 +05:00
TheFaser c1d22c98ef update adventure version to 4.25.0 2025-10-08 02:49:03 +05:00
booky 06c7afd21a Merge pull request #1369 from ManInMyVan/feat/wrappedblockstate/hasproperty
add WrappedBlockState#hasProperty(StateValue)
2025-10-07 22:39:35 +02:00
ManInMyVan ecb360eabd add WrappedBlockState#hasProperty(StateValue) 2025-10-07 13:49:50 -06:00
booky10 56941722aa Add minimum support for ItemLock network serialization
Fixes #1129

The problem is that the lock component is serialized using codecs (to nbt) instead of using stream codecs and packetevents doesn't have a great way to parse nbt how vanilla does it yet
Vanilla allows millions of different ways to write nbt (because of user input)
2025-10-07 20:39:56 +02:00
booky 2452d753af Merge pull request #1368 from TheFaser/2.0
fix: resolve NoSuchMethodError in login event with isAllowed() check
2025-10-07 19:03:35 +02:00
TheFaser 2085a725b0 fix: resolve NoSuchMethodError in login event with isAllowed() check 2025-10-07 21:28:51 +05:00
retrooper b67f99e8ea Merge pull request #1361 from booky10/feat/1.21.9-support
1.21.9/1.21.10 support
2025-10-06 12:21:33 +02:00
retrooper eee5dd7fa2 2.10.0 snapshot 2025-10-06 12:18:57 +02:00
retrooper 9c5e2bd4c9 patch: minor corrections to copyright year 2025-10-06 12:12:01 +02:00
booky10 87efd2dcf3 Merge branch '2.0' into feat/1.21.9-support 2025-10-05 20:39:47 +02:00
booky 170e1a9cb5 Merge pull request #1362 from rafi67000/gradleUpdate
Gradle update
2025-10-05 20:37:45 +02:00
booky10 7d4ef278cd Update fastutil in buildSrc 2025-10-05 20:20:12 +02:00
booky10 05c6d3447a Don't force wrapper version in build.gradle.kts 2025-10-05 20:17:19 +02:00
booky10 ef9f8d2000 Change workflow artifact uploading paths 2025-10-05 20:15:07 +02:00
rafi67000 9d192b61ea Update MockBukkit 2025-10-03 20:01:14 +02:00
rafi67000 d4d7e96c15 Update Loom 2025-10-03 20:00:59 +02:00
booky10 918fa83388 Fix player instance not being available for first few play packets
This now pauses packet processing until the player instance has been set, see javadoc comment on the InternalPaperJoinListener for more details
2025-10-02 23:25:26 +02:00
booky10 34f26bb3bd Make fabric support 1.21.9
Also tries to fix inconsistencies in when the player object was set for fabric
2025-10-02 20:13:11 +02:00
booky10 ccbfa6cf00 Mark 1.21.10 as supported 2025-10-02 18:48:37 +02:00
rafi67000 bcb429ec7f Fix workflow 2025-10-02 13:42:47 +02:00
rafi67000 5f38d74cfc Replace deprecated task registration 2025-10-01 18:47:43 +02:00
rafi67000 5111c354c1 Update mod-publish 2025-10-01 18:46:49 +02:00
rafi67000 643b2e9975 Update shadow 2025-10-01 18:46:38 +02:00
rafi67000 d9bc12b05e Update gradle to 9.1.0 2025-10-01 16:53:31 +02:00
booky10 f7e6de8594 Fix a few minor issues 2025-10-01 03:31:18 +02:00
booky10 8275088bda Update ItemProfile component to 1.21.9 2025-10-01 02:01:48 +02:00
booky10 06dd7a5555 Update entity data component to 1.21.9 2025-10-01 01:27:36 +02:00
booky10 4fa6bccaa7 Fix compile issue because of generics 2025-10-01 00:48:27 +02:00
booky10 7df7e3700b Update packet types to 1.21.9 2025-10-01 00:39:30 +02:00
booky10 adf1b2692a Update blocktags/itemtags to 1.21.9 2025-10-01 00:30:45 +02:00
booky10 b57d3364a3 Update block state properties to 1.21.9 2025-10-01 00:21:53 +02:00
booky10 48e67537c1 Update registries to 1.21.9 2025-10-01 00:17:20 +02:00
booky10 fe7455e379 Update entity data serializers 2025-09-30 22:25:39 +02:00
booky10 01e4f20c68 Finish packet wrapper updates 2025-09-30 21:30:47 +02:00
booky10 bf066d6156 Update explosion packet to 1.21.9 2025-09-30 18:29:29 +02:00
booky10 20bf1fd89d Implement debug packet wrappers 2025-09-30 05:32:49 +02:00
booky10 f2a470f943 Start implementing debug subscription network serialization 2025-09-30 02:47:05 +02:00
booky10 845077ff35 Some packet wrapper updates 2025-09-30 01:26:41 +02:00
booky10 ff03e29b3f Implement low/less precision Vec3d 2025-09-30 01:26:27 +02:00
booky10 fad9a4873f Work aroundl warning on paper server startup for now 2025-09-29 18:13:02 +02:00
booky10 ad21d93863 Fix paper runtask 2025-09-29 16:08:21 +02:00
booky10 4d366d06cd Add 1.21.9 server/client version 2025-09-29 13:53:25 +02:00
booky10 197a3c956e Revert breaking changes
- Deprecates PlayerData#getUser()/#setUser(UserProfile) instead of removing it without warning
- Reverts changes to signatures in WrapperPlayClientClickWindow, still tries to keep the fixes made by AO
2025-09-29 04:41:54 +02:00
booky10 f8371c461d Add small editorconfig 2025-09-29 04:30:28 +02:00
booky10 02f0855d3d Add missing sealevel getters/setters to WrapperPlayServerRespawn 2025-09-29 04:30:28 +02:00
booky 22a4085978 Merge pull request #1358 from Jyguy/fix-click-window-wrapper
Fix CLICK_WINDOW wrapper write length
2025-09-29 04:30:21 +02:00
Jyguy acae93e9cf Fix CLICK_WINDOW wrapper write length 2025-09-28 21:09:08 -04:00
booky 803cf8f109 Merge pull request #1357 from Axionize/2.0
Fix Build Issues due to Missing Dependencies and with Gradle 9.0.0
2025-09-27 22:42:16 +02:00
Axionize 4af2de9fee Fix building of bungeecoord due to removal of of Bungeecoord 1.21-R0.1-SNAPSHOT from paper repos 2025-09-27 15:14:28 -04:00
Axionize d916789acb Gradle 9.0.0 support 2025-09-27 14:36:39 -04:00
retrooper 54d120c296 Merge pull request #1333 from Beaness/patch-2 2025-09-20 09:09:38 +02:00
retrooper a84cbbd209 Merge pull request #1347 from AoElite/2.0
Improved getting slots and other improvements
2025-09-19 16:22:31 +02:00
retrooper 295b6f268e Merge pull request #1350 from scienziatopazzo/2.0
fix: remove duplicate setter for userProfile | WrapperPlayServerPlayerInfo
2025-09-19 16:22:11 +02:00
scienziato1pazzo a1e674f61d fix: remove duplicate setter for userProfile 2025-09-19 15:07:11 +02:00
AoElite bf1f896b39 ensure the cause is not null 2025-09-15 00:10:58 -04:00
AoElite eeb2b40138 convert nulls to empties 2025-09-14 23:56:44 -04:00
AoElite 60ff394785 fix more issues 2025-09-14 23:56:41 -04:00
AoElite 149c017099 fix mistake 2025-09-14 23:56:39 -04:00
AoElite 233d6c150c improve compatibility 2025-09-14 20:32:41 -04:00
AoElite 96aa95f9d7 dejankify WrapperPlayClientClickWindow 2025-09-14 20:20:32 -04:00
AoElite 7e1a8a704a improve getSlots backwards compatibility 2025-09-14 19:26:26 -04:00
AoElite cd769921b9 make the reading of slots to be changeable 2025-09-14 19:26:24 -04:00
AoElite 7d33952145 handle show_entity contents better 2025-09-14 19:26:21 -04:00
retrooper 58f1134254 Merge pull request #1341 from AoElite/wrapper-pref
Refactor properties and equipment processing to dedicated method
2025-09-05 13:05:31 +02:00
AoElite 6d1f2830d1 allow property reading to be overridden in update attribute packet wrappers 2025-09-05 06:11:21 -04:00
AoElite d103dd74f9 make the readEquipment method changeable with subclass overrides to allow optional performance optimizations 2025-09-05 04:19:35 -04:00
retrooper cd0f238b97 do not throw stacktrace for handshakes, in particular when the exception is caused by the handshake exception. 2025-08-29 10:34:48 +02:00
retrooper d7a475adfd PacketEvents 2.9.6-SNAPSHOT 2025-08-26 01:39:21 +02:00
retrooper ccfb6b422c PacketEvents 2.9.5 Update 2025-08-26 01:22:29 +02:00
booky10 2c8143ddb0 Add WrappedBlockState utility constructor to WrapperPlayServerBlockChange
Fixes #1325
2025-08-25 23:02:05 +02:00
booky10 f9892c598c Don't try to read direct wolf variant below 1.21
Fixes #1327
2025-08-25 22:59:49 +02:00
booky10andMesterMan03 3eb79fd6d2 Don't encode SingleOptionInputControl entries as strings for now
Packetevents doesn't support mixed nbt lists properly, so adding a string tag to a compound list will cause errors

Fixes #1334

Co-authored-by: MesterMan03 <MesterMan03+github@proton.me>
2025-08-25 22:52:41 +02:00
booky10 8ddceada42 Only error when reading chunk data if we managed to read more than allowed 2025-08-25 22:41:57 +02:00
booky10 a1c355d4c9 Cleanup NBT tag reading/writing 2025-08-25 21:20:40 +02:00
booky10 5c23459e1e Fix Direction Y/Z axis being swapped 2025-08-25 21:04:22 +02:00
booky10 af3dbc928b Mark SpigotChannelInjector encoder/decoder getters as nullable 2025-08-25 18:13:24 +02:00
booky10 bd1bc7f06a Check if the network channel is open instead of Player#isOnline if possible on kick
Player#isOnline() returns whether the player still exists in the internal bukkit player list, not whether the network channel is still active
2025-08-25 18:11:18 +02:00
retrooper 7f16b992eb Merge remote-tracking branch 'origin/2.0' into 2.0 2025-08-19 08:43:23 +02:00
retrooper 460884cbd8 patch: remove paper OfflinePlayer#isConnected reference; use Player#isOnline instead 2025-08-19 08:43:00 +02:00
Beanes 0cc99eadde Always try to fetch netty version 2025-08-18 19:49:27 +02:00
retrooper 24bf010d98 Merge pull request #1308 from Moulberry/fix/nbt-compound-getListOrThrow-NPE 2025-07-29 21:44:59 +02:00
retrooper e74adedf88 Merge pull request #1309 from Moulberry/fix/spigotchannelinjector-isplayerset-npe 2025-07-29 20:58:11 +02:00
Moulberry a34d03f422 Fix NPE in SpigotChannelInjector#isPlayerSet 2025-07-30 01:04:15 +08:00
Moulberry c0a9be3c7d Fix NBTCompound.java getListOrThrow always returning null 2025-07-30 01:01:28 +08:00
retrooper 8f352d9115 Merge pull request #1306 from rafi67000/gradleUpdate
ViaNBT, SpongeGradle, MockBukkit and shadow update
2025-07-22 23:55:39 +02:00
rafi67000 6ca306405c Update sponge plugin 2025-07-22 21:47:44 +02:00
rafi67000 d4190b2fde Update shadow plugin 2025-07-22 21:47:44 +02:00
rafi67000 30ed0bdcf3 Update ViaNBT 2025-07-22 21:47:44 +02:00
rafi67000 c3e2c3ee9e Update MockBukkit 2025-07-22 21:47:44 +02:00
retrooper 155f8520d4 increment packetevents version to 2.9.5-SNAPSHOT 2025-07-22 21:29:33 +02:00
180 changed files with 217122 additions and 911 deletions

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
[*.java]
indent_style = space
indent_size = 4
ij_continuation_indent_size = 8
ij_java_names_count_to_use_import_on_demand = 9999
ij_java_class_count_to_use_import_on_demand = 9999
+10 -10
View File
@@ -10,13 +10,13 @@ jobs:
contents: read
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- name: Validate gradle wrapper
uses: gradle/actions/wrapper-validation@v4
uses: gradle/actions/wrapper-validation@v5
- name: Set up JDK 21
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
@@ -31,40 +31,40 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: api-build
path: api/build/libs
path: build/libs/packetevents-api-*.jar
- name: Upload build artifacts spigot
uses: actions/upload-artifact@v4
with:
name: spigot-build
path: spigot/build/libs
path: build/libs/packetevents-spigot-*.jar
- name: Upload build artifacts netty-common
uses: actions/upload-artifact@v4
with:
name: netty-common-build
path: netty-common/build/libs
path: build/libs/packetevents-netty-common-*.jar
- name: Upload build artifacts bungeecord
uses: actions/upload-artifact@v4
with:
name: bungeecord-build
path: bungeecord/build/libs
path: build/libs/packetevents-bungeecord-*.jar
- name: Upload build artifacts velocity
uses: actions/upload-artifact@v4
with:
name: velocity-build
path: velocity/build/libs
path: build/libs/packetevents-velocity-*.jar
- name: Upload build artifacts fabric
uses: actions/upload-artifact@v4
with:
name: fabric-build
path: fabric/build/libs
path: build/libs/packetevents-fabric-*.jar
- name: Upload build artifacts sponge
uses: actions/upload-artifact@v4
with:
name: sponge-build
path: sponge/build/libs
path: build/libs/packetevents-sponge-*.jar
+87
View File
@@ -1,3 +1,90 @@
!!!!! v2.10.1
# PacketEvents 2.10.1 is finally out! 🎉
This update includes some bug fixes.
# Brief Announcement 📢⚠️
### Visit our website: https://packetevents.com
### Documentation: https://docs.packetevents.com
### JavaDocs: https://javadocs.packetevents.com
## What's Changed (Summary)
* Fixed for certain particle types on 1.21.9 & 1.21.10 Minecraft
* Fixed the bee's component on 1.21.9 & 1.21.10 Minecraft
* Correction of 'mul' calculation in LpVector3d
**View Full Changelog**: https://github.com/retrooper/packetevents/compare/v2.10.0...v2.10.1
## If you want to support PacketEvents, consider sponsoring us on [GitHub Sponsors](https://github.com/sponsors/retrooper)
## Maven/Gradle Dependency
### **Check out**: https://docs.packetevents.com/getting-started
!!!!! v2.10.0
# PacketEvents 2.10.0 is finally out! 🎉
This update includes critical bug fixes & minor additions to the API.
# Brief Announcement 📢⚠️
### We have our very own website: https://packetevents.com
### Documentation: https://docs.packetevents.com
### JavaDocs: https://javadocs.packetevents.com
## What's Changed (Summary)
* Added 1.21.9 & 1.21.10 support
* Various bug fixes (such as TPS reading, PlayerModelType reading/writing, and more)
* Update adventure API
**View Full Changelog**: https://github.com/retrooper/packetevents/compare/v2.9.5...v2.10.0
## If you want to support PacketEvents, consider sponsoring us on [GitHub Sponsors](https://github.com/sponsors/retrooper)
## Maven/Gradle Dependency
### **Check out**: https://docs.packetevents.com/getting-started
!!!!! v2.9.5
# PacketEvents 2.9.5 is out now! 🎉
This update includes critical bug fixes & minor additions to the API.
# Brief Announcement 📢⚠️
### We have our very own website: https://packetevents.com
### Documentation: https://docs.packetevents.com
### JavaDocs: https://javadocs.packetevents.com
## What's Changed (Summary)
* Injector bug fix (for Spigot)
* WolfVariant issue fixed
* Chunk Data error fixed
* NBT tag issues fixed
* Direction Y/Z axis being swapped fixed
* Added WrappedBlockState to constructor of WrapperPlayServerBlockChange
**View Full Changelog**: https://github.com/retrooper/packetevents/compare/v2.9.4...v2.9.5
## If you want to support PacketEvents, consider sponsoring us on [GitHub Sponsors](https://github.com/sponsors/retrooper)
## Maven/Gradle Dependency
### **Check out**: https://docs.packetevents.com/getting-started
!!!!! v2.9.4
# PacketEvents 2.9.4 is out now! 🎉
+1
View File
@@ -36,6 +36,7 @@ dependencies {
testImplementation(libs.adventure.text.serializer.legacy)
testImplementation(project(":netty-common"))
testImplementation(testlibs.mockbukkit)
testImplementation(testlibs.paper.api)
testImplementation(testlibs.slf4j)
testImplementation(testlibs.bundles.junit)
testImplementation(libs.netty)
@@ -76,7 +76,7 @@ public class EventManager {
* 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
* @param postCallListenerAction The action to be run after all the listeners have finished processing
*/
public void callEvent(PacketEvent event, @Nullable Runnable postCallListenerAction) {
for (PacketListenerCommon listener : listeners) {
@@ -84,7 +84,7 @@ public class EventManager {
event.call(listener);
} catch (Exception t) {
// ignore handshake exceptions
if (t.getClass() != InvalidHandshakeException.class) {
if (t.getClass() != InvalidHandshakeException.class && (t.getCause() == null || t.getCause().getClass() != InvalidHandshakeException.class)) {
PacketEvents.getAPI().getLogger().log(Level.WARNING, "PacketEvents caught an unhandled exception while calling your listener.", t);
}
}
@@ -50,8 +50,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), V_1_21_4(769), V_1_21_5(770), V_1_21_6(771), V_1_21_7(772), V_1_21_8(772),
//1.21 and 1.21.1 have the same protocol version. 1.21.2 and 1.21.3 have the same protocol version. 1.21.7 and 1.21.8 have the same protocol version. 1.21.9 and 1.21.10 have the same protocol version
V_1_21(767), V_1_21_1(767), V_1_21_2(768), V_1_21_3(768), V_1_21_4(769), V_1_21_5(770), V_1_21_6(771), V_1_21_7(772), V_1_21_8(772), V_1_21_9(773), V_1_21_10(773),
//TODO UPDATE Add server version constant
ERROR(-1, true);
@@ -103,6 +103,10 @@ public class ByteBufHelper {
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeShort(buffer, value);
}
public static void writeShortLE(Object buffer, int value) {
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeShortLE(buffer, value);
}
public static int readMedium(Object buffer) {
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().readMedium(buffer);
}
@@ -42,6 +42,7 @@ public interface ByteBufOperator {
void writeByte(Object buffer, int value);
void writeShort(Object buffer, int value);
void writeShortLE(Object buffer, int value);
void writeMedium(Object buffer, int value);
void writeInt(Object buffer, int value);
void writeLong(Object buffer, long value);
@@ -33,6 +33,8 @@ import org.jetbrains.annotations.Range;
public class Color implements RGBLike {
public static final Color WHITE = new Color(0xFFFFFFFF);
protected static final int BIT_MASK = 0xFF;
protected final int red, green, blue;
@@ -75,6 +77,11 @@ public class Color implements RGBLike {
wrapper.writeByte(color.blue);
}
public static Color decode(NBT nbt, PacketWrapper<?> wrapper) {
return decode(nbt, wrapper.getServerVersion().toClientVersion());
}
@Deprecated
public static Color decode(NBT nbt, ClientVersion version) {
if (nbt instanceof NBTNumber) {
return new Color(((NBTNumber) nbt).getAsInt());
@@ -86,6 +93,11 @@ public class Color implements RGBLike {
return new Color(red, green, blue);
}
public static NBT encode(PacketWrapper<?> wrapper, Color color) {
return encode(color, wrapper.getServerVersion().toClientVersion());
}
@Deprecated
public static NBT encode(Color color, ClientVersion version) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_2)) {
return new NBTInt(color.asRGB());
@@ -39,6 +39,8 @@ import com.github.retrooper.packetevents.protocol.component.builtin.ShulkerColor
import com.github.retrooper.packetevents.protocol.component.builtin.TropicalFishBaseColorComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.TropicalFishPatternColorComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.TropicalFishPatternComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.TypedBlockEntityData;
import com.github.retrooper.packetevents.protocol.component.builtin.TypedEntityData;
import com.github.retrooper.packetevents.protocol.component.builtin.VillagerVariantComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.WolfCollarComponent;
import com.github.retrooper.packetevents.protocol.component.builtin.WolfSoundVariantComponent;
@@ -245,12 +247,18 @@ public final class ComponentTypes {
ArmorTrim::read, ArmorTrim::write);
public static final ComponentType<DebugStickState> DEBUG_STICK_STATE = define("debug_stick_state",
DebugStickState::read, DebugStickState::write);
public static final ComponentType<NBTCompound> ENTITY_DATA = define("entity_data",
PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final ComponentType<TypedEntityData> TYPED_ENTITY_DATA = define("entity_data",
TypedEntityData::read, TypedEntityData::write);
@Deprecated
public static final ComponentType<NBTCompound> ENTITY_DATA = TYPED_ENTITY_DATA
.legacyMap(TypedEntityData::getCompound, TypedEntityData::new);
public static final ComponentType<NBTCompound> BUCKET_ENTITY_DATA = define("bucket_entity_data",
PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final ComponentType<NBTCompound> BLOCK_ENTITY_DATA = define("block_entity_data",
PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final ComponentType<TypedBlockEntityData> TYPED_BLOCK_ENTITY_DATA = define("block_entity_data",
TypedBlockEntityData::read, TypedBlockEntityData::write);
@Deprecated
public static final ComponentType<NBTCompound> BLOCK_ENTITY_DATA = TYPED_BLOCK_ENTITY_DATA
.legacyMap(TypedBlockEntityData::getCompound, TypedBlockEntityData::new);
public static final ComponentType<ItemInstrument> ITEM_INSTRUMENT = define("instrument",
ItemInstrument::read, ItemInstrument::write);
@Deprecated
@@ -0,0 +1,84 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.world.blockentity.BlockEntityType;
import com.github.retrooper.packetevents.protocol.world.blockentity.BlockEntityTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.Objects;
@NullMarked
public final class TypedBlockEntityData {
private static final BlockEntityType FALLBACK_TYPE = BlockEntityTypes.FURNACE;
/**
* @versions 1.21.9+
*/
private final BlockEntityType type;
private final NBTCompound compound;
public TypedBlockEntityData(NBTCompound compound) {
this(FALLBACK_TYPE, compound);
}
public TypedBlockEntityData(BlockEntityType type, NBTCompound compound) {
this.type = type;
this.compound = compound;
}
public static TypedBlockEntityData read(PacketWrapper<?> wrapper) {
BlockEntityType type = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)
? wrapper.readMappedEntity(BlockEntityTypes.getRegistry()) : FALLBACK_TYPE;
NBTCompound compound = wrapper.readNBT();
return new TypedBlockEntityData(type, compound);
}
public static void write(PacketWrapper<?> wrapper, TypedBlockEntityData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
wrapper.writeMappedEntity(data.type);
}
wrapper.writeNBT(data.compound);
}
public BlockEntityType getType() {
return this.type;
}
public NBTCompound getCompound() {
return this.compound;
}
@Override
public boolean equals(Object obj) {
if (obj == null || this.getClass() != obj.getClass()) return false;
TypedBlockEntityData that = (TypedBlockEntityData) obj;
if (!this.type.equals(that.type)) return false;
return this.compound.equals(that.compound);
}
@Override
public int hashCode() {
return Objects.hash(this.type, this.compound);
}
}
@@ -0,0 +1,84 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.Objects;
@NullMarked
public final class TypedEntityData {
private static final EntityType FALLBACK_TYPE = EntityTypes.PIG;
/**
* @versions 1.21.9+
*/
private final EntityType type;
private final NBTCompound compound;
public TypedEntityData(NBTCompound compound) {
this(FALLBACK_TYPE, compound);
}
public TypedEntityData(EntityType type, NBTCompound compound) {
this.type = type;
this.compound = compound;
}
public static TypedEntityData read(PacketWrapper<?> wrapper) {
EntityType type = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)
? wrapper.readMappedEntity(EntityTypes.getRegistry()) : FALLBACK_TYPE;
NBTCompound compound = wrapper.readNBT();
return new TypedEntityData(type, compound);
}
public static void write(PacketWrapper<?> wrapper, TypedEntityData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
wrapper.writeMappedEntity(data.type);
}
wrapper.writeNBT(data.compound);
}
public EntityType getType() {
return this.type;
}
public NBTCompound getCompound() {
return this.compound;
}
@Override
public boolean equals(Object obj) {
if (obj == null || this.getClass() != obj.getClass()) return false;
TypedEntityData that = (TypedEntityData) obj;
if (!this.type.equals(that.type)) return false;
return this.compound.equals(that.compound);
}
@Override
public int hashCode() {
return Objects.hash(this.type, this.compound);
}
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.component.builtin.TypedEntityData;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
@@ -68,37 +69,50 @@ public class ItemBees {
public static class BeeEntry {
private NBTCompound entityData;
private TypedEntityData entityData;
private int ticksInHive;
private int minTicksInHive;
@Deprecated
public BeeEntry(NBTCompound entityData, int ticksInHive, int minTicksInHive) {
this(new TypedEntityData(entityData), ticksInHive, minTicksInHive);
}
public BeeEntry(TypedEntityData entityData, int ticksInHive, int minTicksInHive) {
this.entityData = entityData;
this.ticksInHive = ticksInHive;
this.minTicksInHive = minTicksInHive;
}
public static BeeEntry read(PacketWrapper<?> wrapper) {
NBTCompound entityData = wrapper.readNBT();
TypedEntityData entityData = TypedEntityData.read(wrapper);
int ticksInHive = wrapper.readVarInt();
int minTicksInHive = wrapper.readVarInt();
return new BeeEntry(entityData, ticksInHive, minTicksInHive);
}
public static void write(PacketWrapper<?> wrapper, BeeEntry bee) {
wrapper.writeNBT(bee.entityData);
TypedEntityData.write(wrapper, bee.entityData);
wrapper.writeVarInt(bee.ticksInHive);
wrapper.writeVarInt(bee.minTicksInHive);
}
public NBTCompound getEntityData() {
public TypedEntityData getTypedEntityData() {
return this.entityData;
}
public void setEntityData(NBTCompound entityData) {
public void setTypedEntityData(TypedEntityData entityData) {
this.entityData = entityData;
}
public NBTCompound getEntityData() {
return this.entityData.getCompound();
}
public void setEntityData(NBTCompound entityData) {
this.entityData = new TypedEntityData(entityData);
}
public int getTicksInHive() {
return this.ticksInHive;
}
@@ -18,46 +18,100 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import java.util.Objects;
@NullMarked
public class ItemLock {
private String code;
private static final String FALLBACK_LOCK_STRING = "packetevents$invalid_lock";
/**
* @versions 1.20.5-1.21.1
*/
@ApiStatus.Obsolete
private String code;
/**
* @versions 1.21.2+
*/
private NBTCompound predicate;
/**
* @versions 1.20.5-1.21.1
*/
@ApiStatus.Obsolete
public ItemLock(String code) {
this.code = code;
this.predicate = new NBTCompound();
}
public ItemLock(NBTCompound predicate) {
this.code = FALLBACK_LOCK_STRING;
this.predicate = predicate;
}
public static ItemLock read(PacketWrapper<?> wrapper) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
return new ItemLock(wrapper.readNBT());
}
NBTString codeTag = (NBTString) wrapper.readNBTRaw();
return new ItemLock(codeTag.getValue());
}
public static void write(PacketWrapper<?> wrapper, ItemLock lock) {
wrapper.writeNBTRaw(new NBTString(lock.code));
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
wrapper.writeNBT(lock.predicate);
} else {
wrapper.writeNBTRaw(new NBTString(lock.code));
}
}
/**
* @versions 1.20.5-1.21.1
*/
@ApiStatus.Obsolete
public String getCode() {
return this.code;
}
/**
* @versions 1.20.5-1.21.1
*/
@ApiStatus.Obsolete
public void setCode(String code) {
this.code = code;
}
/**
* @versions 1.21.2+
*/
public NBTCompound getPredicate() {
return this.predicate;
}
/**
* @versions 1.21.2+
*/
public void setPredicate(NBTCompound predicate) {
this.predicate = predicate;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemLock)) return false;
if (obj == null || this.getClass() != obj.getClass()) return false;
ItemLock itemLock = (ItemLock) obj;
return this.code.equals(itemLock.code);
if (!this.code.equals(itemLock.code)) return false;
return this.predicate.equals(itemLock.predicate);
}
@Override
public int hashCode() {
return Objects.hashCode(this.code);
return Objects.hash(this.code, this.predicate);
}
}
@@ -18,40 +18,146 @@
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
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.PlayerModelType;
import com.github.retrooper.packetevents.protocol.util.NbtCodec;
import com.github.retrooper.packetevents.protocol.util.NbtCodecs;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import net.kyori.adventure.text.object.PlayerHeadObjectContents;
import net.kyori.adventure.text.object.PlayerHeadObjectContents.ProfileProperty;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
public class ItemProfile {
import static net.kyori.adventure.text.object.PlayerHeadObjectContents.property;
@NullMarked
public final class ItemProfile {
private @Nullable String name;
private @Nullable UUID id;
private List<Property> properties;
/**
* @versions 1.21.9+
*/
private SkinPatch skinPatch;
public ItemProfile(
@Nullable String name,
@Nullable UUID id,
List<Property> properties
) {
this(name, id, properties, SkinPatch.EMPTY);
}
public ItemProfile(
@Nullable String name,
@Nullable UUID id,
List<Property> properties,
SkinPatch skinPatch
) {
this.name = name;
this.id = id;
this.properties = properties;
this.skinPatch = skinPatch;
}
public static ItemProfile read(PacketWrapper<?> wrapper) {
String name = wrapper.readOptional(ew -> ew.readString(16));
UUID id = wrapper.readOptional(PacketWrapper::readUUID);
String name;
UUID id;
boolean partial = wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_9) || !wrapper.readBoolean();
if (!partial) {
id = wrapper.readUUID();
name = wrapper.readString(16);
} else {
name = wrapper.readOptional(ew -> ew.readString(16));
id = wrapper.readOptional(PacketWrapper::readUUID);
}
List<Property> properties = wrapper.readList(Property::read);
return new ItemProfile(name, id, properties);
SkinPatch skinPatch = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)
? SkinPatch.read(wrapper) : SkinPatch.EMPTY;
return new ItemProfile(name, id, properties, skinPatch);
}
public static void write(PacketWrapper<?> wrapper, ItemProfile profile) {
wrapper.writeOptional(profile.name, (ew, name) -> ew.writeString(name, 16));
wrapper.writeOptional(profile.id, PacketWrapper::writeUUID);
boolean partial;
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
partial = profile.name == null || profile.id == null;
wrapper.writeBoolean(!partial);
} else {
// always partial profile (which is way simpler, why did they change this?)
partial = true;
}
if (!partial) {
wrapper.writeUUID(profile.id);
wrapper.writeString(profile.name, 16);
} else {
wrapper.writeOptional(profile.name, (ew, name) -> ew.writeString(name, 16));
wrapper.writeOptional(profile.id, PacketWrapper::writeUUID);
}
wrapper.writeList(profile.properties, Property::write);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
SkinPatch.write(wrapper, profile.skinPatch);
}
}
public static ItemProfile decode(NBT nbt, PacketWrapper<?> wrapper) {
if (nbt instanceof NBTString) {
String name = ((NBTString) nbt).getValue();
return new ItemProfile(name, null, new ArrayList<>());
}
NBTCompound compound = (NBTCompound) nbt;
UUID id = compound.getOrNull("id", NbtCodecs.UUID, wrapper);
String name = compound.getStringTagValueOrNull("name");
List<Property> properties = compound.getOrSupply("properties",
Property.PROPERTY_MAP, ArrayList::new, wrapper);
SkinPatch patch = SkinPatch.decode(compound, wrapper);
return new ItemProfile(name, id, properties, patch);
}
public static NBT encode(PacketWrapper<?> wrapper, ItemProfile profile) {
NBTCompound compound = new NBTCompound();
if (profile.id != null) {
compound.set("id", profile.id, NbtCodecs.UUID, wrapper);
}
if (profile.name != null) {
compound.setTag("name", new NBTString(profile.name));
}
if (!profile.properties.isEmpty()) {
compound.set("properties", profile.properties, Property.PROPERTY_MAP, wrapper);
}
SkinPatch.encode(compound, wrapper, profile.skinPatch);
return compound;
}
public static ItemProfile fromAdventure(PlayerHeadObjectContents headContents) {
List<ProfileProperty> advProps = headContents.profileProperties();
List<Property> properties = new ArrayList<>(advProps.size());
for (ProfileProperty property : advProps) {
properties.add(Property.fromAdventure(property));
}
return new ItemProfile(headContents.name(), headContents.id(), properties);
}
public List<ProfileProperty> getAdventureProperties() {
if (this.properties.isEmpty()) {
return Collections.emptyList();
}
List<ProfileProperty> properties = new ArrayList<>(this.properties.size());
for (Property property : this.properties) {
properties.add(property.asAdventure());
}
return Collections.unmodifiableList(properties);
}
public @Nullable String getName() {
@@ -82,6 +188,20 @@ public class ItemProfile {
this.properties = properties;
}
/**
* @versions 1.21.9+
*/
public SkinPatch getSkinPatch() {
return this.skinPatch;
}
/**
* @versions 1.21.9+
*/
public void setSkinPatch(SkinPatch skinPatch) {
this.skinPatch = skinPatch;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -89,16 +209,63 @@ public class ItemProfile {
ItemProfile that = (ItemProfile) obj;
if (!Objects.equals(this.name, that.name)) return false;
if (!Objects.equals(this.id, that.id)) return false;
return this.properties.equals(that.properties);
if (!this.properties.equals(that.properties)) return false;
return this.skinPatch.equals(that.skinPatch);
}
@Override
public int hashCode() {
return Objects.hash(this.name, this.id, this.properties);
return Objects.hash(this.name, this.id, this.properties, this.skinPatch);
}
public static class Property {
public static final NbtCodec<Property> CODEC = new NbtCodec<ItemProfile.Property>() {
@Override
public ItemProfile.Property decode(NBT nbt, PacketWrapper<?> wrapper) {
NBTCompound compound = (NBTCompound) nbt;
String name = compound.getStringTagValueOrThrow("name");
String value = compound.getStringTagValueOrThrow("value");
String signature = compound.getStringTagValueOrNull("signature");
return new ItemProfile.Property(name, value, signature);
}
@Override
public NBT encode(PacketWrapper<?> wrapper, ItemProfile.Property value) {
NBTCompound compound = new NBTCompound();
compound.setTag("name", new NBTString(value.getName()));
compound.setTag("value", new NBTString(value.getValue()));
if (value.getSignature() != null) {
compound.setTag("signature", new NBTString(value.getSignature()));
}
return compound;
}
};
public static final NbtCodec<List<ItemProfile.Property>> PROPERTY_MAP = new NbtCodec<List<ItemProfile.Property>>() {
private final NbtCodec<List<ItemProfile.Property>> propertyList = CODEC.applyList();
@Override
public List<ItemProfile.Property> decode(NBT nbt, PacketWrapper<?> wrapper) {
if (nbt instanceof NBTCompound) {
Map<String, NBT> tags = ((NBTCompound) nbt).getTags();
List<ItemProfile.Property> properties = new ArrayList<>(tags.size());
for (Map.Entry<String, NBT> entry : tags.entrySet()) {
for (String value : NbtCodecs.STRING_LIST.decode(entry.getValue(), wrapper)) {
properties.add(new ItemProfile.Property(entry.getKey(), value, null));
}
}
return properties;
}
return this.propertyList.decode(nbt, wrapper);
}
@Override
public NBT encode(PacketWrapper<?> wrapper, List<ItemProfile.Property> value) {
return this.propertyList.encode(wrapper, value);
}
};
private String name;
private String value;
private @Nullable String signature;
@@ -123,6 +290,14 @@ public class ItemProfile {
(ew, signature) -> ew.writeString(signature, 1024));
}
public static Property fromAdventure(ProfileProperty property) {
return new Property(property.name(), property.value(), property.signature());
}
public ProfileProperty asAdventure() {
return property(this.name, this.value, this.signature);
}
public String getName() {
return this.name;
}
@@ -162,4 +337,95 @@ public class ItemProfile {
return Objects.hash(this.name, this.value, this.signature);
}
}
public static class SkinPatch {
public static final SkinPatch EMPTY = new SkinPatch(null, null, null, null);
private final @Nullable ResourceLocation body;
private final @Nullable ResourceLocation cape;
private final @Nullable ResourceLocation elytra;
private final @Nullable PlayerModelType model;
public SkinPatch(
@Nullable ResourceLocation body,
@Nullable ResourceLocation cape,
@Nullable ResourceLocation elytra,
@Nullable PlayerModelType model
) {
this.body = body;
this.cape = cape;
this.elytra = elytra;
this.model = model;
}
public static SkinPatch read(PacketWrapper<?> wrapper) {
ResourceLocation body = wrapper.readOptional(ResourceLocation::read);
ResourceLocation cape = wrapper.readOptional(ResourceLocation::read);
ResourceLocation elytra = wrapper.readOptional(ResourceLocation::read);
PlayerModelType model = wrapper.readOptional(PlayerModelType::read);
return new SkinPatch(body, cape, elytra, model);
}
public static void write(PacketWrapper<?> wrapper, SkinPatch patch) {
wrapper.writeOptional(patch.body, ResourceLocation::write);
wrapper.writeOptional(patch.cape, ResourceLocation::write);
wrapper.writeOptional(patch.elytra, ResourceLocation::write);
wrapper.writeOptional(patch.model, PlayerModelType::write);
}
public static SkinPatch decode(NBTCompound nbt, PacketWrapper<?> wrapper) {
ResourceLocation body = nbt.getOrNull("texture", ResourceLocation.CODEC, wrapper);
ResourceLocation cape = nbt.getOrNull("cape", ResourceLocation.CODEC, wrapper);
ResourceLocation elytra = nbt.getOrNull("elytra", ResourceLocation.CODEC, wrapper);
PlayerModelType model = nbt.getOrNull("model", PlayerModelType.CODEC, wrapper);
return new SkinPatch(body, cape, elytra, model);
}
public static void encode(NBTCompound compound, PacketWrapper<?> wrapper, SkinPatch patch) {
if (patch.body != null) {
compound.set("texture", patch.body, ResourceLocation.CODEC, wrapper);
}
if (patch.cape != null) {
compound.set("cape", patch.cape, ResourceLocation.CODEC, wrapper);
}
if (patch.elytra != null) {
compound.set("elytra", patch.elytra, ResourceLocation.CODEC, wrapper);
}
if (patch.model != null) {
compound.set("model", patch.model, PlayerModelType.CODEC, wrapper);
}
}
public @Nullable ResourceLocation getBody() {
return this.body;
}
public @Nullable ResourceLocation getCape() {
return this.cape;
}
public @Nullable ResourceLocation getElytra() {
return this.elytra;
}
public @Nullable PlayerModelType getModel() {
return this.model;
}
@Override
public boolean equals(Object obj) {
if (obj == null || this.getClass() != obj.getClass()) return false;
SkinPatch skinPatch = (SkinPatch) obj;
if (!Objects.equals(this.body, skinPatch.body)) return false;
if (!Objects.equals(this.cape, skinPatch.cape)) return false;
if (!Objects.equals(this.elytra, skinPatch.elytra)) return false;
return this.model == skinPatch.model;
}
@Override
public int hashCode() {
return Objects.hash(this.body, this.cape, this.elytra, this.model);
}
}
}
@@ -37,8 +37,9 @@ public class ItemRecipes {
public static ItemRecipes read(PacketWrapper<?> wrapper) {
NBTList<?> recipes = (NBTList<?>) wrapper.readNBTRaw();
List<ResourceLocation> recipeKeys = new ArrayList<>(recipes.size());
for (int i = 0; i < recipes.size(); i++) {
int size = recipes.size();
List<ResourceLocation> recipeKeys = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
NBTString tag = (NBTString) recipes.getTag(i);
recipeKeys.add(new ResourceLocation(tag.getValue()));
}
@@ -0,0 +1,97 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* @versions 1.21.9+
*/
@NullMarked
public interface DebugSubscription<T> extends MappedEntity {
T read(PacketWrapper<?> wrapper);
void write(PacketWrapper<?> wrapper, T value);
final class Event<T> {
private final DebugSubscription<T> subscription;
private final T value;
public Event(DebugSubscription<T> subscription, T value) {
this.subscription = subscription;
this.value = value;
}
public static Event<?> read(PacketWrapper<?> wrapper) {
@SuppressWarnings("unchecked")
DebugSubscription<? super Object> subscription = (DebugSubscription<? super Object>) wrapper.readMappedEntity(DebugSubscriptions.getRegistry());
Object value = subscription.read(wrapper);
return new Event<>(subscription, value);
}
public static <T> void write(PacketWrapper<?> wrapper, Event<T> event) {
wrapper.writeMappedEntity(event.subscription);
event.subscription.write(wrapper, event.value);
}
public DebugSubscription<T> getSubscription() {
return this.subscription;
}
public T getValue() {
return this.value;
}
}
final class Update<T> {
private final DebugSubscription<T> subscription;
private final @Nullable T value;
public Update(DebugSubscription<T> subscription, @Nullable T value) {
this.subscription = subscription;
this.value = value;
}
public static Update<?> read(PacketWrapper<?> wrapper) {
@SuppressWarnings("unchecked")
DebugSubscription<? super Object> subscription = (DebugSubscription<? super Object>) wrapper.readMappedEntity(DebugSubscriptions.getRegistry());
Object value = wrapper.readOptional(subscription::read);
return new Update<>(subscription, value);
}
public static <T> void write(PacketWrapper<?> wrapper, Update<T> event) {
wrapper.writeMappedEntity(event.subscription);
wrapper.writeOptional(event.value, event.subscription::write);
}
public DebugSubscription<T> getSubscription() {
return this.subscription;
}
public @Nullable T getValue() {
return this.value;
}
}
}
@@ -0,0 +1,91 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugBeeInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugBrainDump;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugBreezeInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugEntityBlockIntersection;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugGameEventInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugGameEventListenerInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugGoalInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugHiveInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugNeighborUpdateInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugPathInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugPoiInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugRaidsInfo;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugStructureInfos;
import com.github.retrooper.packetevents.protocol.debug.struct.DebugVillageSections;
import com.github.retrooper.packetevents.protocol.debug.struct.RedstoneOrientation;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugSubscriptions {
private static final VersionedRegistry<DebugSubscription<?>> REGISTRY = new VersionedRegistry<>("debug_subscription");
private DebugSubscriptions() {
}
public static VersionedRegistry<DebugSubscription<?>> getRegistry() {
return REGISTRY;
}
@ApiStatus.Internal
public static <T> DebugSubscription<T> define(String name) {
return define(name, null, null);
}
@ApiStatus.Internal
public static <T> DebugSubscription<T> define(
String name,
PacketWrapper.@Nullable Reader<T> reader,
PacketWrapper.@Nullable Writer<T> writer
) {
return REGISTRY.define(name, data -> new StaticDebugSubscription<>(data, reader, writer));
}
public static final DebugSubscription<?> DEDICATED_SERVER_TICK_TIME = define("dedicated_server_tick_time");
public static final DebugSubscription<DebugBeeInfo> BEES = define("bees", DebugBeeInfo::read, DebugBeeInfo::write);
public static final DebugSubscription<DebugBrainDump> BRAINS = define("brains", DebugBrainDump::read, DebugBrainDump::write);
public static final DebugSubscription<DebugBreezeInfo> BREEZES = define("breezes", DebugBreezeInfo::read, DebugBreezeInfo::write);
public static final DebugSubscription<DebugGoalInfo> GOAL_SELECTORS = define("goal_selectors", DebugGoalInfo::read, DebugGoalInfo::write);
public static final DebugSubscription<DebugPathInfo> ENTITY_PATHS = define("entity_paths", DebugPathInfo::read, DebugPathInfo::write);
public static final DebugSubscription<DebugEntityBlockIntersection> ENTITY_BLOCK_INTERSECTIONS = define("entity_block_intersections", DebugEntityBlockIntersection::read, DebugEntityBlockIntersection::write);
public static final DebugSubscription<DebugHiveInfo> BEE_HIVES = define("bee_hives", DebugHiveInfo::read, DebugHiveInfo::write);
public static final DebugSubscription<DebugPoiInfo> POIS = define("pois", DebugPoiInfo::read, DebugPoiInfo::write);
public static final DebugSubscription<RedstoneOrientation> REDSTONE_WIRE_ORIENTATIONS = define("redstone_wire_orientations", RedstoneOrientation::read, RedstoneOrientation::write);
public static final DebugSubscription<DebugVillageSections> VILLAGE_SECTIONS = define("village_sections", DebugVillageSections::read, DebugVillageSections::write);
public static final DebugSubscription<DebugRaidsInfo> RAIDS = define("raids", DebugRaidsInfo::read, DebugRaidsInfo::write);
public static final DebugSubscription<DebugStructureInfos> STRUCTURES = define("structures", DebugStructureInfos::read, DebugStructureInfos::write);
public static final DebugSubscription<DebugGameEventListenerInfo> GAME_EVENT_LISTENERS = define("game_event_listeners", DebugGameEventListenerInfo::read, DebugGameEventListenerInfo::write);
public static final DebugSubscription<DebugNeighborUpdateInfo> NEIGHBOR_UPDATES = define("neighbor_updates", DebugNeighborUpdateInfo::read, DebugNeighborUpdateInfo::write);
public static final DebugSubscription<DebugGameEventInfo> GAME_EVENTS = define("game_events", DebugGameEventInfo::read, DebugGameEventInfo::write);
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* @versions 1.21.9+
*/
@NullMarked
public class StaticDebugSubscription<T> extends AbstractMappedEntity implements DebugSubscription<T> {
private final PacketWrapper.@Nullable Reader<T> reader;
private final PacketWrapper.@Nullable Writer<T> writer;
@ApiStatus.Internal
public StaticDebugSubscription(
@Nullable TypesBuilderData data,
PacketWrapper.@Nullable Reader<T> reader,
PacketWrapper.@Nullable Writer<T> writer
) {
super(data);
this.reader = reader;
this.writer = writer;
}
@Override
public T read(PacketWrapper<?> wrapper) {
if (this.reader == null) {
throw new IllegalStateException(this + " doesn't support network reading");
}
return this.reader.apply(wrapper);
}
@Override
public void write(PacketWrapper<?> wrapper, T value) {
if (this.writer == null) {
throw new IllegalStateException(this + " doesn't support network writing");
}
this.writer.accept(wrapper, value);
}
}
@@ -0,0 +1,94 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.path;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugNode {
private final Vector3i pos;
private final float walkedDistance;
private final float costMalus;
private final boolean closed;
private final DebugPathType type;
private final float f;
public DebugNode(
Vector3i pos, float walkedDistance, float costMalus,
boolean closed, DebugPathType type, float f
) {
this.pos = pos;
this.walkedDistance = walkedDistance;
this.costMalus = costMalus;
this.closed = closed;
this.type = type;
this.f = f;
}
public static DebugNode read(PacketWrapper<?> wrapper) {
Vector3i pos = new Vector3i(wrapper.readInt(), wrapper.readInt(), wrapper.readInt());
float walkedDistance = wrapper.readFloat();
float costMalus = wrapper.readFloat();
boolean closed = wrapper.readBoolean();
DebugPathType type = wrapper.readEnum(DebugPathType.values());
float f = wrapper.readFloat();
return new DebugNode(pos, walkedDistance, costMalus, closed, type, f);
}
public static void write(PacketWrapper<?> wrapper, DebugNode node) {
wrapper.writeInt(node.pos.x);
wrapper.writeInt(node.pos.y);
wrapper.writeInt(node.pos.z);
wrapper.writeFloat(node.walkedDistance);
wrapper.writeFloat(node.costMalus);
wrapper.writeBoolean(node.closed);
wrapper.writeEnum(node.type);
wrapper.writeFloat(node.f);
}
public Vector3i getPos() {
return this.pos;
}
public float getWalkedDistance() {
return this.walkedDistance;
}
public float getCostMalus() {
return this.costMalus;
}
public boolean isClosed() {
return this.closed;
}
public DebugPathType getType() {
return this.type;
}
public float getF() {
return this.f;
}
}
@@ -0,0 +1,105 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.path;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.List;
import java.util.Set;
/**
* Network structure for representing vanilla pathfinder paths.
*
* @versions 1.21.9+
*/
@NullMarked
public final class DebugPath {
private final boolean reached;
private final int nextNodeIndex;
private final Vector3i target;
private final List<DebugNode> nodes;
private final Set<DebugNode> targetNodes;
private final List<DebugNode> openSet;
private final List<DebugNode> closedSet;
public DebugPath(
boolean reached, int nextNodeIndex, Vector3i target, List<DebugNode> nodes,
Set<DebugNode> targetNodes, List<DebugNode> openSet, List<DebugNode> closedSet
) {
this.reached = reached;
this.nextNodeIndex = nextNodeIndex;
this.target = target;
this.nodes = nodes;
this.targetNodes = targetNodes;
this.openSet = openSet;
this.closedSet = closedSet;
}
public static DebugPath read(PacketWrapper<?> wrapper) {
boolean reached = wrapper.readBoolean();
int nextNodeIndex = wrapper.readInt();
Vector3i target = wrapper.readBlockPosition();
List<DebugNode> nodes = wrapper.readList(DebugNode::read);
Set<DebugNode> targetNodes = wrapper.readSet(DebugNode::read);
List<DebugNode> openSet = wrapper.readList(DebugNode::read);
List<DebugNode> closedSet = wrapper.readList(DebugNode::read);
return new DebugPath(reached, nextNodeIndex, target, nodes, targetNodes, openSet, closedSet);
}
public static void write(PacketWrapper<?> wrapper, DebugPath path) {
wrapper.writeBoolean(path.reached);
wrapper.writeInt(path.nextNodeIndex);
wrapper.writeBlockPosition(path.target);
wrapper.writeList(path.nodes, DebugNode::write);
wrapper.writeSet(path.targetNodes, DebugNode::write);
wrapper.writeList(path.openSet, DebugNode::write);
wrapper.writeList(path.closedSet, DebugNode::write);
}
public boolean isReached() {
return this.reached;
}
public int getNextNodeIndex() {
return this.nextNodeIndex;
}
public Vector3i getTarget() {
return this.target;
}
public List<DebugNode> getNodes() {
return this.nodes;
}
public Set<DebugNode> getTargetNodes() {
return this.targetNodes;
}
public List<DebugNode> getOpenSet() {
return this.openSet;
}
public List<DebugNode> getClosedSet() {
return this.closedSet;
}
}
@@ -0,0 +1,55 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.path;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public enum DebugPathType {
BLOCKED,
OPEN,
WALKABLE,
WALKABLE_DOOR,
TRAPDOOR,
POWDER_SNOW,
DANGER_POWDER_SNOW,
FENCE,
LAVA,
WATER,
WATER_BORDER,
RAIL,
UNPASSABLE_RAIL,
DANGER_FIRE,
DAMAGE_FIRE,
DANGER_OTHER,
DAMAGE_OTHER,
DOOR_OPEN,
DOOR_WOOD_CLOSED,
DOOR_IRON_CLOSED,
BREACH,
LEAVES,
STICKY_HONEY,
COCOA,
DAMAGE_CAUTIOUS,
DANGER_TRAPDOOR,
}
@@ -0,0 +1,26 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.poi;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import org.jspecify.annotations.NullMarked;
@NullMarked
public interface PoiType extends MappedEntity {
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.poi;
import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@NullMarked
public final class PoiTypes {
private static final VersionedRegistry<PoiType> REGISTRY = new VersionedRegistry<>("point_of_interest_type");
private PoiTypes() {
}
public static VersionedRegistry<PoiType> getRegistry() {
return REGISTRY;
}
@ApiStatus.Internal
public static PoiType define(String name) {
return REGISTRY.define(name, StaticPoiType::new);
}
public static final PoiType ARMORER = define("armorer");
public static final PoiType BUTCHER = define("butcher");
public static final PoiType CARTOGRAPHER = define("cartographer");
public static final PoiType CLERIC = define("cleric");
public static final PoiType FARMER = define("farmer");
public static final PoiType FISHERMAN = define("fisherman");
public static final PoiType FLETCHER = define("fletcher");
public static final PoiType LEATHERWORKER = define("leatherworker");
public static final PoiType LIBRARIAN = define("librarian");
public static final PoiType MASON = define("mason");
public static final PoiType SHEPHERD = define("shepherd");
public static final PoiType TOOLSMITH = define("toolsmith");
public static final PoiType WEAPONSMITH = define("weaponsmith");
public static final PoiType HOME = define("home");
public static final PoiType MEETING = define("meeting");
public static final PoiType BEEHIVE = define("beehive");
public static final PoiType BEE_NEST = define("bee_nest");
public static final PoiType NETHER_PORTAL = define("nether_portal");
public static final PoiType LODESTONE = define("lodestone");
public static final PoiType TEST_INSTANCE = define("test_instance");
public static final PoiType LIGHTNING_ROD = define("lightning_rod");
static {
REGISTRY.unloadMappings();
}
}
@@ -0,0 +1,34 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.poi;
import com.github.retrooper.packetevents.protocol.mapper.AbstractMappedEntity;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
@NullMarked
public class StaticPoiType extends AbstractMappedEntity implements PoiType {
@ApiStatus.Internal
public StaticPoiType(@Nullable TypesBuilderData data) {
super(data);
}
}
@@ -0,0 +1,79 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.List;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugBeeInfo {
private final @Nullable Vector3i hivePos;
private final @Nullable Vector3i flowerPos;
private final int travelTicks;
private final List<Vector3i> blacklistedHives;
public DebugBeeInfo(
@Nullable Vector3i hivePos, @Nullable Vector3i flowerPos,
int travelTicks, List<Vector3i> blacklistedHives
) {
this.hivePos = hivePos;
this.flowerPos = flowerPos;
this.travelTicks = travelTicks;
this.blacklistedHives = blacklistedHives;
}
public static DebugBeeInfo read(PacketWrapper<?> wrapper) {
Vector3i hivePos = wrapper.readOptional(PacketWrapper::readBlockPosition);
Vector3i flowerPos = wrapper.readOptional(PacketWrapper::readBlockPosition);
int travelTicks = wrapper.readVarInt();
List<Vector3i> blacklistedHives = wrapper.readList(PacketWrapper::readBlockPosition);
return new DebugBeeInfo(hivePos, flowerPos, travelTicks, blacklistedHives);
}
public static void write(PacketWrapper<?> wrapper, DebugBeeInfo info) {
wrapper.writeOptional(info.hivePos, PacketWrapper::writeBlockPosition);
wrapper.writeOptional(info.flowerPos, PacketWrapper::writeBlockPosition);
wrapper.writeVarInt(info.travelTicks);
wrapper.writeList(info.blacklistedHives, PacketWrapper::writeBlockPosition);
}
public @Nullable Vector3i getHivePos() {
return this.hivePos;
}
public @Nullable Vector3i getFlowerPos() {
return this.flowerPos;
}
public int getTravelTicks() {
return this.travelTicks;
}
public List<Vector3i> getBlacklistedHives() {
return this.blacklistedHives;
}
}
@@ -0,0 +1,164 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.List;
import java.util.Set;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugBrainDump {
private final String name;
private final String profession;
private final int xp;
private final float health;
private final float maxHealth;
private final String inventory;
private final boolean wantsGolem;
private final int angerLevel;
private final List<String> activities;
private final List<String> behaviors;
private final List<String> memories;
private final List<String> gossips;
private final Set<Vector3i> pois;
private final Set<Vector3i> potentialPois;
public DebugBrainDump(
String name, String profession, int xp, float health, float maxHealth,
String inventory, boolean wantsGolem, int angerLevel, List<String> activities,
List<String> behaviors, List<String> memories, List<String> gossips,
Set<Vector3i> pois, Set<Vector3i> potentialPois
) {
this.name = name;
this.profession = profession;
this.xp = xp;
this.health = health;
this.maxHealth = maxHealth;
this.inventory = inventory;
this.wantsGolem = wantsGolem;
this.angerLevel = angerLevel;
this.activities = activities;
this.behaviors = behaviors;
this.memories = memories;
this.gossips = gossips;
this.pois = pois;
this.potentialPois = potentialPois;
}
public static DebugBrainDump read(PacketWrapper<?> wrapper) {
String name = wrapper.readString();
String profession = wrapper.readString();
int xp = wrapper.readInt();
float health = wrapper.readFloat();
float maxHealth = wrapper.readFloat();
String inventory = wrapper.readString();
boolean wantsGolem = wrapper.readBoolean();
int angerLevel = wrapper.readInt();
List<String> activities = wrapper.readList(PacketWrapper::readString);
List<String> behaviors = wrapper.readList(PacketWrapper::readString);
List<String> memories = wrapper.readList(PacketWrapper::readString);
List<String> gossips = wrapper.readList(PacketWrapper::readString);
Set<Vector3i> pois = wrapper.readSet(PacketWrapper::readBlockPosition);
Set<Vector3i> potentialPois = wrapper.readSet(PacketWrapper::readBlockPosition);
return new DebugBrainDump(
name, profession, xp, health, maxHealth, inventory, wantsGolem,
angerLevel, activities, behaviors, memories, gossips, pois, potentialPois
);
}
public static void write(PacketWrapper<?> wrapper, DebugBrainDump info) {
wrapper.writeString(info.name);
wrapper.writeString(info.profession);
wrapper.writeInt(info.xp);
wrapper.writeFloat(info.health);
wrapper.writeFloat(info.maxHealth);
wrapper.writeString(info.inventory);
wrapper.writeBoolean(info.wantsGolem);
wrapper.writeInt(info.angerLevel);
wrapper.writeList(info.activities, PacketWrapper::writeString);
wrapper.writeList(info.behaviors, PacketWrapper::writeString);
wrapper.writeList(info.memories, PacketWrapper::writeString);
wrapper.writeList(info.gossips, PacketWrapper::writeString);
wrapper.writeSet(info.pois, PacketWrapper::writeBlockPosition);
wrapper.writeSet(info.potentialPois, PacketWrapper::writeBlockPosition);
}
public String getName() {
return this.name;
}
public String getProfession() {
return this.profession;
}
public int getXp() {
return this.xp;
}
public float getHealth() {
return this.health;
}
public float getMaxHealth() {
return this.maxHealth;
}
public String getInventory() {
return this.inventory;
}
public boolean isWantsGolem() {
return this.wantsGolem;
}
public int getAngerLevel() {
return this.angerLevel;
}
public List<String> getActivities() {
return this.activities;
}
public List<String> getBehaviors() {
return this.behaviors;
}
public List<String> getMemories() {
return this.memories;
}
public List<String> getGossips() {
return this.gossips;
}
public Set<Vector3i> getPois() {
return this.pois;
}
public Set<Vector3i> getPotentialPois() {
return this.potentialPois;
}
}
@@ -0,0 +1,58 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugBreezeInfo {
private final @Nullable Integer attackTarget;
private final @Nullable Vector3i jumpTarget;
public DebugBreezeInfo(@Nullable Integer attackTarget, @Nullable Vector3i jumpTarget) {
this.attackTarget = attackTarget;
this.jumpTarget = jumpTarget;
}
public static DebugBreezeInfo read(PacketWrapper<?> wrapper) {
Integer attackTarget = wrapper.readOptional(PacketWrapper::readVarInt);
Vector3i jumpTarget = wrapper.readOptional(PacketWrapper::readBlockPosition);
return new DebugBreezeInfo(attackTarget, jumpTarget);
}
public static void write(PacketWrapper<?> wrapper, DebugBreezeInfo info) {
wrapper.writeOptional(info.attackTarget, PacketWrapper::writeVarInt);
wrapper.writeOptional(info.jumpTarget, PacketWrapper::writeBlockPosition);
}
public @Nullable Integer getAttackTarget() {
return this.attackTarget;
}
public @Nullable Vector3i getJumpTarget() {
return this.jumpTarget;
}
}
@@ -0,0 +1,54 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugEntityBlockIntersection {
private final IntersectionType type;
public DebugEntityBlockIntersection(IntersectionType type) {
this.type = type;
}
public static DebugEntityBlockIntersection read(PacketWrapper<?> wrapper) {
IntersectionType type = wrapper.readEnum(IntersectionType.values());
return new DebugEntityBlockIntersection(type);
}
public static void write(PacketWrapper<?> wrapper, DebugEntityBlockIntersection intersection) {
wrapper.writeEnum(intersection.type);
}
public IntersectionType getType() {
return this.type;
}
public enum IntersectionType {
IN_BLOCK,
IN_FLUID,
IN_AIR,
}
}
@@ -0,0 +1,61 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugGameEventInfo {
/**
* Possible values include all keys of the built-in <code>minecraft:game_event</code> registry.
*/
private final ResourceLocation event;
private final Vector3d pos;
public DebugGameEventInfo(ResourceLocation event, Vector3d pos) {
this.event = event;
this.pos = pos;
}
public static DebugGameEventInfo read(PacketWrapper<?> wrapper) {
ResourceLocation event = ResourceLocation.read(wrapper);
Vector3d pos = Vector3d.read(wrapper);
return new DebugGameEventInfo(event, pos);
}
public static void write(PacketWrapper<?> wrapper, DebugGameEventInfo info) {
ResourceLocation.write(wrapper, info.event);
Vector3d.write(wrapper, info.pos);
}
public ResourceLocation getEvent() {
return this.event;
}
public Vector3d getPos() {
return this.pos;
}
}
@@ -0,0 +1,48 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugGameEventListenerInfo {
private final int listenerRadius;
public DebugGameEventListenerInfo(int listenerRadius) {
this.listenerRadius = listenerRadius;
}
public static DebugGameEventListenerInfo read(PacketWrapper<?> wrapper) {
int listenerRadius = wrapper.readVarInt();
return new DebugGameEventListenerInfo(listenerRadius);
}
public static void write(PacketWrapper<?> wrapper, DebugGameEventListenerInfo info) {
wrapper.writeVarInt(info.listenerRadius);
}
public int getListenerRadius() {
return this.listenerRadius;
}
}
@@ -0,0 +1,88 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.List;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugGoalInfo {
private final List<DebugGoal> goals;
public DebugGoalInfo(List<DebugGoal> goals) {
this.goals = goals;
}
public static DebugGoalInfo read(PacketWrapper<?> wrapper) {
List<DebugGoal> goals = wrapper.readList(DebugGoal::read);
return new DebugGoalInfo(goals);
}
public static void write(PacketWrapper<?> wrapper, DebugGoalInfo info) {
wrapper.writeList(info.goals, DebugGoal::write);
}
public List<DebugGoal> getGoals() {
return this.goals;
}
public static final class DebugGoal {
private final int priority;
private final boolean running;
private final String name;
public DebugGoal(int priority, boolean running, String name) {
this.priority = priority;
this.running = running;
this.name = name;
}
public static DebugGoal read(PacketWrapper<?> wrapper) {
int priority = wrapper.readVarInt();
boolean running = wrapper.readBoolean();
String name = wrapper.readString(255);
return new DebugGoal(priority, running, name);
}
public static void write(PacketWrapper<?> wrapper, DebugGoal goal) {
wrapper.writeVarInt(goal.priority);
wrapper.writeBoolean(goal.running);
wrapper.writeString(goal.name, 255);
}
public int getPriority() {
return this.priority;
}
public boolean isRunning() {
return this.running;
}
public String getName() {
return this.name;
}
}
}
@@ -0,0 +1,74 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugHiveInfo {
private final StateType type;
private final int occupantCount;
private final int honeyLevel;
private final boolean sedated;
public DebugHiveInfo(StateType type, int occupantCount, int honeyLevel, boolean sedated) {
this.type = type;
this.occupantCount = occupantCount;
this.honeyLevel = honeyLevel;
this.sedated = sedated;
}
public static DebugHiveInfo read(PacketWrapper<?> wrapper) {
StateType type = wrapper.readMappedEntity(StateTypes.getRegistry()).getStateType();
int occupantCount = wrapper.readVarInt();
int honeyLevel = wrapper.readVarInt();
boolean sedated = wrapper.readBoolean();
return new DebugHiveInfo(type, occupantCount, honeyLevel, sedated);
}
public static void write(PacketWrapper<?> wrapper, DebugHiveInfo info) {
wrapper.writeMappedEntity(info.type.getMapped());
wrapper.writeVarInt(info.occupantCount);
wrapper.writeVarInt(info.honeyLevel);
wrapper.writeBoolean(info.sedated);
}
public StateType getType() {
return this.type;
}
public int getOccupantCount() {
return this.occupantCount;
}
public int getHoneyLevel() {
return this.honeyLevel;
}
public boolean isSedated() {
return this.sedated;
}
}
@@ -0,0 +1,49 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugNeighborUpdateInfo {
private final Vector3i pos;
public DebugNeighborUpdateInfo(Vector3i pos) {
this.pos = pos;
}
public static DebugNeighborUpdateInfo read(PacketWrapper<?> wrapper) {
Vector3i pos = wrapper.readBlockPosition();
return new DebugNeighborUpdateInfo(pos);
}
public static void write(PacketWrapper<?> wrapper, DebugNeighborUpdateInfo info) {
wrapper.writeBlockPosition(info.pos);
}
public Vector3i getPos() {
return this.pos;
}
}
@@ -0,0 +1,57 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.protocol.debug.path.DebugPath;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugPathInfo {
private final DebugPath path;
private final float maxNodeDistance;
public DebugPathInfo(DebugPath path, float maxNodeDistance) {
this.path = path;
this.maxNodeDistance = maxNodeDistance;
}
public static DebugPathInfo read(PacketWrapper<?> wrapper) {
DebugPath path = DebugPath.read(wrapper);
float maxNodeDistance = wrapper.readFloat();
return new DebugPathInfo(path, maxNodeDistance);
}
public static void write(PacketWrapper<?> wrapper, DebugPathInfo info) {
DebugPath.write(wrapper, info.path);
wrapper.writeFloat(info.maxNodeDistance);
}
public DebugPath getPath() {
return this.path;
}
public float getMaxNodeDistance() {
return this.maxNodeDistance;
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.protocol.debug.poi.PoiType;
import com.github.retrooper.packetevents.protocol.debug.poi.PoiTypes;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugPoiInfo {
private final Vector3i pos;
private final PoiType poiType;
private final int freeTicketCount;
public DebugPoiInfo(Vector3i pos, PoiType poiType, int freeTicketCount) {
this.pos = pos;
this.poiType = poiType;
this.freeTicketCount = freeTicketCount;
}
public static DebugPoiInfo read(PacketWrapper<?> wrapper) {
Vector3i pos = wrapper.readBlockPosition();
PoiType poiType = wrapper.readMappedEntity(PoiTypes.getRegistry());
int freeTicketCount = wrapper.readVarInt();
return new DebugPoiInfo(pos,poiType,freeTicketCount);
}
public static void write(PacketWrapper<?> wrapper, DebugPoiInfo info) {
wrapper.writeBlockPosition(info.pos);
wrapper.writeMappedEntity(info.poiType);
wrapper.writeVarInt(info.freeTicketCount);
}
public Vector3i getPos() {
return this.pos;
}
public PoiType getPoiType() {
return this.poiType;
}
public int getFreeTicketCount() {
return this.freeTicketCount;
}
}
@@ -0,0 +1,51 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.List;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugRaidsInfo {
private final List<Vector3i> positions;
public DebugRaidsInfo(List<Vector3i> positions) {
this.positions = positions;
}
public static DebugRaidsInfo read(PacketWrapper<?> wrapper) {
List<Vector3i> positions = wrapper.readList(PacketWrapper::readBlockPosition);
return new DebugRaidsInfo(positions);
}
public static void write(PacketWrapper<?> wrapper, DebugRaidsInfo info) {
wrapper.writeList(info.positions, PacketWrapper::writeBlockPosition);
}
public List<Vector3i> getPositions() {
return this.positions;
}
}
@@ -0,0 +1,111 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.protocol.world.BlockBoundingBox;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.List;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugStructureInfos {
private final List<DebugStructureInfo> infos;
public DebugStructureInfos(List<DebugStructureInfo> infos) {
this.infos = infos;
}
public static DebugStructureInfos read(PacketWrapper<?> wrapper) {
List<DebugStructureInfo> infos = wrapper.readList(DebugStructureInfo::read);
return new DebugStructureInfos(infos);
}
public static void write(PacketWrapper<?> wrapper, DebugStructureInfos infos) {
wrapper.writeList(infos.infos, DebugStructureInfo::write);
}
public List<DebugStructureInfo> getInfos() {
return this.infos;
}
public static final class DebugStructureInfo {
private final BlockBoundingBox boundingBox;
private final List<Piece> pieces;
public DebugStructureInfo(BlockBoundingBox boundingBox, List<Piece> pieces) {
this.boundingBox = boundingBox;
this.pieces = pieces;
}
public static DebugStructureInfo read(PacketWrapper<?> wrapper) {
BlockBoundingBox box = BlockBoundingBox.read(wrapper);
List<Piece> pieces = wrapper.readList(Piece::read);
return new DebugStructureInfo(box, pieces);
}
public static void write(PacketWrapper<?> wrapper, DebugStructureInfo info) {
BlockBoundingBox.write(wrapper, info.boundingBox);
wrapper.writeList(info.pieces, Piece::write);
}
public BlockBoundingBox getBoundingBox() {
return this.boundingBox;
}
public List<Piece> getPieces() {
return this.pieces;
}
public static final class Piece {
private final BlockBoundingBox boundingBox;
private final boolean start;
public Piece(BlockBoundingBox boundingBox, boolean start) {
this.boundingBox = boundingBox;
this.start = start;
}
public static Piece read(PacketWrapper<?> wrapper) {
BlockBoundingBox boundingBox = BlockBoundingBox.read(wrapper);
boolean start = wrapper.readBoolean();
return new Piece(boundingBox, start);
}
public static void write(PacketWrapper<?> wrapper, Piece piece) {
BlockBoundingBox.write(wrapper, piece.boundingBox);
wrapper.writeBoolean(piece.start);
}
public BlockBoundingBox getBoundingBox() {
return this.boundingBox;
}
public boolean isStart() {
return this.start;
}
}
}
}
@@ -0,0 +1,42 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class DebugVillageSections {
public static final DebugVillageSections INSTANCE = new DebugVillageSections();
private DebugVillageSections() {
}
public static DebugVillageSections read(PacketWrapper<?> wrapper) {
return INSTANCE;
}
public static void write(PacketWrapper<?> wrapper, DebugVillageSections sections) {
// NO-OP
}
}
@@ -0,0 +1,48 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.debug.struct;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public final class RedstoneOrientation {
private final int index;
public RedstoneOrientation(int index) {
this.index = index;
}
public static RedstoneOrientation read(PacketWrapper<?> wrapper) {
int index = wrapper.readVarInt();
return new RedstoneOrientation(index);
}
public static void write(PacketWrapper<?> wrapper, RedstoneOrientation orientation) {
wrapper.writeVarInt(orientation.index);
}
public int getIndex() {
return this.index;
}
}
@@ -119,9 +119,6 @@ public class SingleOptionInputControl implements InputControl {
}
public static NBT encode(PacketWrapper<?> wrapper, Entry entry) {
if (entry.display == null && !entry.initial) {
return new NBTString(entry.id);
}
NBTCompound compound = new NBTCompound();
compound.setTag("id", new NBTString(entry.id));
if (entry.display != null) {
@@ -19,10 +19,13 @@
package com.github.retrooper.packetevents.protocol.entity.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemProfile;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
import com.github.retrooper.packetevents.protocol.entity.cat.CatVariant;
import com.github.retrooper.packetevents.protocol.entity.chicken.ChickenVariant;
import com.github.retrooper.packetevents.protocol.entity.cow.CowVariant;
import com.github.retrooper.packetevents.protocol.entity.data.struct.CopperGolemState;
import com.github.retrooper.packetevents.protocol.entity.data.struct.WeatheringCopperState;
import com.github.retrooper.packetevents.protocol.entity.frog.FrogVariant;
import com.github.retrooper.packetevents.protocol.entity.pig.PigVariant;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
@@ -45,12 +48,15 @@ import com.github.retrooper.packetevents.util.mappings.VersionedRegistry;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@NullMarked
public final class EntityDataTypes {
private static final VersionedRegistry<EntityDataType<?>> REGISTRY = new VersionedRegistry<>("entity_data_serializer");
@@ -150,7 +156,10 @@ public final class EntityDataTypes {
public static final EntityDataType<Integer> OPTIONAL_BLOCK_STATE = define("optional_block_state", readIntDeserializer(), writeIntSerializer());
// nbt was added in 1.12
/**
* @versions 1.12-1.21.8
*/
@ApiStatus.Obsolete
public static final EntityDataType<NBTCompound> NBT = define("nbt", PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final EntityDataType<Particle<?>> PARTICLE = define("particle", Particle::read, Particle::write);
@@ -226,52 +235,66 @@ public final class EntityDataTypes {
});
/**
* Added with 1.20.5
* @versions 1.20.5+
*/
public static final EntityDataType<ArmadilloState> ARMADILLO_STATE = define("armadillo_state",
(PacketWrapper<?> wrapper) -> ArmadilloState.values()[wrapper.readVarInt()],
(PacketWrapper<?> wrapper, ArmadilloState value) -> wrapper.writeVarInt(value.ordinal())
);
/**
* Added with 1.20.5
* @versions 1.20.5+
*/
public static final EntityDataType<List<Particle<?>>> PARTICLES = define("particles",
wrapper -> wrapper.readList(Particle::read),
(wrapper, particles) -> wrapper.writeList(particles, Particle::write)
);
/**
* Added with 1.20.5
*
* @versions 1.20.5+
* @deprecated use {@link #TYPED_WOLF_VARIANT} instead
*/
@Deprecated
public static final EntityDataType<Integer> WOLF_VARIANT =
define("wolf_variant_type", readIntDeserializer(), writeIntSerializer());
/**
* Added with 1.20.5
* @versions 1.20.5+
*/
public static final EntityDataType<WolfVariant> TYPED_WOLF_VARIANT =
define("wolf_variant_type", WolfVariant::read, WolfVariant::write);
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final EntityDataType<CowVariant> COW_VARIANT =
define("cow_variant_type", CowVariant::read, CowVariant::write);
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final EntityDataType<WolfSoundVariant> WOLF_SOUND_VARIANT =
define("wolf_sound_variant_type", WolfSoundVariant::read, WolfSoundVariant::write);
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final EntityDataType<PigVariant> PIG_VARIANT =
define("pig_variant_type", PigVariant::read, PigVariant::write);
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final EntityDataType<ChickenVariant> CHICKEN_VARIANT =
define("chicken_variant_type", ChickenVariant::read, ChickenVariant::write);
/**
* @versions 1.21.9+
*/
public static final EntityDataType<CopperGolemState> COPPER_GOLEM_STATE =
define("copper_golem_state", CopperGolemState::read, CopperGolemState::write);
/**
* @versions 1.21.9+
*/
public static final EntityDataType<WeatheringCopperState> WEATHERING_COPPER_STATE =
define("weathering_copper_state", WeatheringCopperState::read, WeatheringCopperState::write);
/**
* @versions 1.21.9+
*/
public static final EntityDataType<ItemProfile> RESOLVABLE_PROFILE =
define("resolvable_profile", ItemProfile::read, ItemProfile::write);
private EntityDataTypes() {
}
@@ -289,11 +312,11 @@ public final class EntityDataTypes {
return REGISTRY.getEntries();
}
public static EntityDataType<?> getById(ClientVersion version, int id) {
public static @Nullable EntityDataType<?> getById(ClientVersion version, int id) {
return REGISTRY.getById(version, id);
}
public static EntityDataType<?> getByName(String name) {
public static @Nullable EntityDataType<?> getByName(String name) {
return REGISTRY.getByName(name);
}
@@ -0,0 +1,46 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.data.struct;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public enum CopperGolemState {
IDLE,
GETTING_ITEM,
GETTING_NO_ITEM,
DROPPING_ITEM,
DROPPING_NO_ITEM,
;
private static final CopperGolemState[] STATES = values();
public static CopperGolemState read(PacketWrapper<?> wrapper){
return wrapper.readEnum(STATES);
}
public static void write(PacketWrapper<?> wrapper, CopperGolemState state) {
wrapper.writeEnum(state);
}
}
@@ -0,0 +1,42 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.entity.data.struct;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
@NullMarked
public enum WeatheringCopperState {
UNAFFECTED,
EXPOSED,
WEATHERED,
OXIDIZED,
;
private static final WeatheringCopperState[] STATES = values();
public static WeatheringCopperState read(PacketWrapper<?> wrapper) {
return wrapper.readEnum(STATES);
}
public static void write(PacketWrapper<?> wrapper, WeatheringCopperState state) {
wrapper.writeEnum(state);
}
}
@@ -97,6 +97,12 @@ public final class EntityTypes {
public static final EntityType PROJECTILE_ABSTRACT = define("projectile_abstract", ENTITY);
public static final EntityType MINECART_ABSTRACT = define("minecart_abstract", ENTITY);
public static final EntityType CHESTED_MINECART_ABSTRACT = define("chested_minecart_abstract", MINECART_ABSTRACT);
/**
* Not spawnable
*
* @versions 1.21.9+
*/
public static final EntityType AVATAR = define("avatar", LIVINGENTITY);
public static final EntityType AREA_EFFECT_CLOUD = define("area_effect_cloud", ENTITY);
public static final EntityType ARMOR_STAND = define("armor_stand", LIVINGENTITY);
public static final EntityType ALLAY = define("allay", ABSTRACT_CREATURE);
@@ -226,7 +232,7 @@ public final class EntityTypes {
public static final EntityType ZOMBIE_HORSE = define("zombie_horse", ABSTRACT_HORSE);
public static final EntityType ZOMBIE_VILLAGER = define("zombie_villager", ZOMBIE);
public static final EntityType ZOMBIFIED_PIGLIN = define("zombified_piglin", ZOMBIE);
public static final EntityType PLAYER = define("player", LIVINGENTITY);
public static final EntityType PLAYER = define("player", AVATAR);
public static final EntityType FISHING_BOBBER = define("fishing_bobber", ENTITY);
public static final EntityType ENDER_SIGNAL = define("ender_signal", ENTITY);
public static final EntityType THROWN_EXP_BOTTLE = define("thrown_exp_bottle", PROJECTILE_ABSTRACT);
@@ -239,67 +245,167 @@ public final class EntityTypes {
public static final EntityType MINECART_TNT = define("minecart_tnt", MINECART_ABSTRACT);
public static final EntityType MINECART_HOPPER = define("minecart_hopper", MINECART_ABSTRACT);
public static final EntityType MINECART_MOB_SPAWNER = define("minecart_mob_spawner", MINECART_ABSTRACT);
// Added in 1.19.4
/**
* @versions 1.19.4+
*/
public static final EntityType DISPLAY = define("display", ENTITY);
/**
* @versions 1.19.4+
*/
public static final EntityType BLOCK_DISPLAY = define("block_display", DISPLAY);
/**
* @versions 1.19.4+
*/
public static final EntityType ITEM_DISPLAY = define("item_display", DISPLAY);
/**
* @versions 1.19.4+
*/
public static final EntityType TEXT_DISPLAY = define("text_display", DISPLAY);
/**
* @versions 1.19.4+
*/
public static final EntityType INTERACTION = define("interaction", DISPLAY);
/**
* @versions 1.19.4+
*/
public static final EntityType SNIFFER = define("sniffer", ABSTRACT_ANIMAL);
// Added in 1.20.3
/**
* @versions 1.20.3+
*/
public static final EntityType BREEZE = define("breeze", ABSTRACT_MONSTER);
/**
* @versions 1.20.3+
*/
public static final EntityType ABSTRACT_WIND_CHARGE = define("abstract_wind_charge", PROJECTILE_ABSTRACT);
/**
* @versions 1.20.3+
*/
public static final EntityType WIND_CHARGE = define("wind_charge", ABSTRACT_WIND_CHARGE);
// Added in 1.20.5
/**
* @versions 1.20.5+
*/
public static final EntityType ARMADILLO = define("armadillo", ABSTRACT_ANIMAL);
/**
* @versions 1.20.5+
*/
public static final EntityType BOGGED = define("bogged", ABSTRACT_SKELETON);
/**
* @versions 1.20.5+
*/
public static final EntityType BREEZE_WIND_CHARGE = define("breeze_wind_charge", ABSTRACT_WIND_CHARGE);
/**
* @versions 1.20.5+
*/
public static final EntityType OMINOUS_ITEM_SPAWNER = define("ominous_item_spawner", ENTITY);
// added with 1.21.2
/**
* @versions 1.21.2+
*/
public static final EntityType ACACIA_BOAT = define("acacia_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType ACACIA_CHEST_BOAT = define("acacia_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType BAMBOO_CHEST_RAFT = define("bamboo_chest_raft", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType BAMBOO_RAFT = define("bamboo_raft", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType BIRCH_BOAT = define("birch_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType BIRCH_CHEST_BOAT = define("birch_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType CHERRY_BOAT = define("cherry_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType CHERRY_CHEST_BOAT = define("cherry_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType CREAKING = define("creaking", ABSTRACT_MONSTER);
/**
* Removed with 1.21.4
* @versions 1.21.2-1.21.3
*/
@ApiStatus.Obsolete
public static final EntityType CREAKING_TRANSIENT = define("creaking_transient", CREAKING);
public static final EntityType DARK_OAK_BOAT = define("dark_oak_boat", BOAT);
public static final EntityType DARK_OAK_CHEST_BOAT = define("dark_oak_chest_boat", CHEST_BOAT);
public static final EntityType JUNGLE_BOAT = define("jungle_boat", BOAT);
public static final EntityType JUNGLE_CHEST_BOAT = define("jungle_chest_boat", CHEST_BOAT);
public static final EntityType MANGROVE_BOAT = define("mangrove_boat", BOAT);
public static final EntityType MANGROVE_CHEST_BOAT = define("mangrove_chest_boat", CHEST_BOAT);
public static final EntityType OAK_BOAT = define("oak_boat", BOAT);
public static final EntityType OAK_CHEST_BOAT = define("oak_chest_boat", CHEST_BOAT);
public static final EntityType PALE_OAK_BOAT = define("pale_oak_boat", BOAT);
public static final EntityType PALE_OAK_CHEST_BOAT = define("pale_oak_chest_boat", CHEST_BOAT);
public static final EntityType SPRUCE_BOAT = define("spruce_boat", BOAT);
public static final EntityType SPRUCE_CHEST_BOAT = define("spruce_chest_boat", CHEST_BOAT);
/**
* Added with 1.21.5
* @versions 1.21.2+
*/
public static final EntityType DARK_OAK_BOAT = define("dark_oak_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType DARK_OAK_CHEST_BOAT = define("dark_oak_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType JUNGLE_BOAT = define("jungle_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType JUNGLE_CHEST_BOAT = define("jungle_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType MANGROVE_BOAT = define("mangrove_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType MANGROVE_CHEST_BOAT = define("mangrove_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType OAK_BOAT = define("oak_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType OAK_CHEST_BOAT = define("oak_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType PALE_OAK_BOAT = define("pale_oak_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType PALE_OAK_CHEST_BOAT = define("pale_oak_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType SPRUCE_BOAT = define("spruce_boat", BOAT);
/**
* @versions 1.21.2+
*/
public static final EntityType SPRUCE_CHEST_BOAT = define("spruce_chest_boat", CHEST_BOAT);
/**
* @versions 1.21.5+
*/
public static final EntityType SPLASH_POTION = define("splash_potion", POTION);
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final EntityType LINGERING_POTION = define("lingering_potion", POTION);
/**
* Added with 1.21.6
* @versions 1.21.6+
*/
public static final EntityType HAPPY_GHAST = define("happy_ghast", ABSTRACT_ANIMAL);
/**
* @versions 1.21.9+
*/
public static final EntityType COPPER_GOLEM = define("copper_golem", ABSTRACT_GOLEM);
/**
* @versions 1.21.9+
*/
public static final EntityType MANNEQUIN = define("mannequin", AVATAR);
/**
* Returns an immutable view of the entity types.
@@ -50,14 +50,16 @@ public interface WolfVariant extends MappedEntity, CopyableEntity<WolfVariant>,
MappedEntitySet<Biome> getBiomes();
static WolfVariant read(PacketWrapper<?> wrapper) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)
|| wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21)) {
return wrapper.readMappedEntity(WolfVariants.getRegistry());
}
return wrapper.readMappedEntityOrDirect(WolfVariants.getRegistry(), WolfVariant::readDirect);
}
static void write(PacketWrapper<?> wrapper, WolfVariant variant) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_5)
|| wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21)) {
wrapper.writeMappedEntity(variant);
} else {
wrapper.writeMappedEntityOrDirect(variant, WolfVariant::writeDirect);
@@ -23,12 +23,9 @@ import com.github.retrooper.packetevents.protocol.component.HashedComponentPatch
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.*;
public final class HashedStack {
@@ -42,33 +39,39 @@ public final class HashedStack {
this.components = components;
}
public static Optional<HashedStack> read(PacketWrapper<?> wrapper) {
if (!wrapper.readBoolean()) {
return Optional.empty();
}
public static Optional<HashedStack> readOptional(PacketWrapper<?> wrapper) {
return Optional.ofNullable(read(wrapper));
}
public static Optional<HashedStack> toOptionalFromItemStack(ItemStack itemStack) {
return Optional.ofNullable(fromItemStack(itemStack));
}
public static @Nullable HashedStack read(PacketWrapper<?> wrapper) {
if (!wrapper.readBoolean()) return null;
ItemType item = wrapper.readMappedEntity(ItemTypes.getRegistry());
int count = wrapper.readVarInt();
HashedComponentPatchMap components = HashedComponentPatchMap.read(wrapper);
return Optional.of(new HashedStack(item, count, components));
return new HashedStack(item, count, components);
}
public static void write(PacketWrapper<?> wrapper, Optional<HashedStack> optStack) {
if (optStack == null || !optStack.isPresent()) {
public static void writeOptional(PacketWrapper<?> wrapper, Optional<HashedStack> stack) {
write(wrapper, stack.orElse(null));
}
public static void write(PacketWrapper<?> wrapper, HashedStack stack) {
if (stack == null) {
wrapper.writeBoolean(false);
} else {
wrapper.writeBoolean(true);
HashedStack stack = optStack.get();
wrapper.writeMappedEntity(stack.item);
wrapper.writeVarInt(stack.count);
HashedComponentPatchMap.write(wrapper, stack.components);
}
}
public static Optional<HashedStack> fromItemStack(ItemStack stack) {
if (stack == null || stack.isEmpty()) {
return Optional.empty();
}
public static HashedStack fromItemStack(ItemStack stack) {
if (stack == null) return null;
// extract component info from item stack
Map<ComponentType<?>, Optional<?>> patches = stack.getComponents().getPatches();
Map<ComponentType<?>, Integer> addedComponents = new HashMap<>(patches.size());
@@ -83,7 +86,7 @@ public final class HashedStack {
}
// construct hashed item stack structure
HashedComponentPatchMap map = new HashedComponentPatchMap(addedComponents, removedComponents);
return Optional.of(new HashedStack(stack.getType(), stack.getAmount(), map));
return new HashedStack(stack.getType(), stack.getAmount(), map);
}
/**
@@ -494,6 +494,10 @@ public final class ItemTypes {
public static final ItemType RED_BED = builder("red_bed").setMaxAmount(1).setPlacedType(StateTypes.RED_BED).build();
public static final ItemType YELLOW_BANNER = builder("yellow_banner").setMaxAmount(16).setPlacedType(StateTypes.YELLOW_BANNER).setAttributes(ItemAttribute.FUEL).build();
public static final ItemType BARREL = builder("barrel").setMaxAmount(64).setPlacedType(StateTypes.BARREL).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.6-1.21.8
*/
@ApiStatus.Obsolete
public static final ItemType CHAIN = builder("chain").setMaxAmount(64).setPlacedType(StateTypes.CHAIN).build();
public static final ItemType DEAD_BRAIN_CORAL_FAN = builder("dead_brain_coral_fan").setMaxAmount(64).setPlacedType(StateTypes.DEAD_BRAIN_CORAL_FAN).build();
public static final ItemType ROTTEN_FLESH = builder("rotten_flesh").setMaxAmount(64).setAttributes(ItemAttribute.EDIBLE).build();
@@ -1552,11 +1556,302 @@ public final class ItemTypes {
* Added with 1.21.6
*/
public static final ItemType MUSIC_DISC_TEARS = builder("music_disc_tears").setMaxAmount(1).setAttributes(ItemAttribute.MUSIC_DISC).build();
/**
* Added with 1.21.7
* @versions 1.21.7+
*/
public static final ItemType MUSIC_DISC_LAVA_CHICKEN = builder("music_disc_lava_chicken").setMaxAmount(1).setAttributes(ItemAttribute.MUSIC_DISC).build();
/**
* @versions 1.21.9+
*/
public static final ItemType ACACIA_SHELF = builder("acacia_shelf").setMaxAmount(64).setPlacedType(StateTypes.ACACIA_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType BAMBOO_SHELF = builder("bamboo_shelf").setMaxAmount(64).setPlacedType(StateTypes.BAMBOO_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType BIRCH_SHELF = builder("birch_shelf").setMaxAmount(64).setPlacedType(StateTypes.BIRCH_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType CHERRY_SHELF = builder("cherry_shelf").setMaxAmount(64).setPlacedType(StateTypes.CHERRY_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType CRIMSON_SHELF = builder("crimson_shelf").setMaxAmount(64).setPlacedType(StateTypes.CRIMSON_SHELF).build();
/**
* @versions 1.21.9+
*/
public static final ItemType DARK_OAK_SHELF = builder("dark_oak_shelf").setMaxAmount(64).setPlacedType(StateTypes.DARK_OAK_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType JUNGLE_SHELF = builder("jungle_shelf").setMaxAmount(64).setPlacedType(StateTypes.JUNGLE_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType MANGROVE_SHELF = builder("mangrove_shelf").setMaxAmount(64).setPlacedType(StateTypes.MANGROVE_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType OAK_SHELF = builder("oak_shelf").setMaxAmount(64).setPlacedType(StateTypes.OAK_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType PALE_OAK_SHELF = builder("pale_oak_shelf").setMaxAmount(64).setPlacedType(StateTypes.PALE_OAK_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType SPRUCE_SHELF = builder("spruce_shelf").setMaxAmount(64).setPlacedType(StateTypes.SPRUCE_SHELF).setAttributes(ItemAttribute.FUEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WARPED_SHELF = builder("warped_shelf").setMaxAmount(64).setPlacedType(StateTypes.WARPED_SHELF).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_TORCH = builder("copper_torch").setMaxAmount(64).setPlacedType(StateTypes.COPPER_TORCH).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_BARS = builder("copper_bars").setMaxAmount(64).setPlacedType(StateTypes.COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType EXPOSED_COPPER_BARS = builder("exposed_copper_bars").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WEATHERED_COPPER_BARS = builder("weathered_copper_bars").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType OXIDIZED_COPPER_BARS = builder("oxidized_copper_bars").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_COPPER_BARS = builder("waxed_copper_bars").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_EXPOSED_COPPER_BARS = builder("waxed_exposed_copper_bars").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_WEATHERED_COPPER_BARS = builder("waxed_weathered_copper_bars").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_OXIDIZED_COPPER_BARS = builder("waxed_oxidized_copper_bars").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_BARS).build();
/**
* @versions 1.21.9+
*/
public static final ItemType IRON_CHAIN = builder("iron_chain").setMaxAmount(64).setPlacedType(StateTypes.IRON_CHAIN).setAttributes(ItemAttribute.IRON_TIER).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_CHAIN = builder("copper_chain").setMaxAmount(64).setPlacedType(StateTypes.COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType EXPOSED_COPPER_CHAIN = builder("exposed_copper_chain").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WEATHERED_COPPER_CHAIN = builder("weathered_copper_chain").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType OXIDIZED_COPPER_CHAIN = builder("oxidized_copper_chain").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_COPPER_CHAIN = builder("waxed_copper_chain").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_EXPOSED_COPPER_CHAIN = builder("waxed_exposed_copper_chain").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_WEATHERED_COPPER_CHAIN = builder("waxed_weathered_copper_chain").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_OXIDIZED_COPPER_CHAIN = builder("waxed_oxidized_copper_chain").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_CHAIN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType EXPOSED_LIGHTNING_ROD = builder("exposed_lightning_rod").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_LIGHTNING_ROD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WEATHERED_LIGHTNING_ROD = builder("weathered_lightning_rod").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_LIGHTNING_ROD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType OXIDIZED_LIGHTNING_ROD = builder("oxidized_lightning_rod").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_LIGHTNING_ROD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_LIGHTNING_ROD = builder("waxed_lightning_rod").setMaxAmount(64).setPlacedType(StateTypes.WAXED_LIGHTNING_ROD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_EXPOSED_LIGHTNING_ROD = builder("waxed_exposed_lightning_rod").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_LIGHTNING_ROD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_WEATHERED_LIGHTNING_ROD = builder("waxed_weathered_lightning_rod").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_LIGHTNING_ROD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_OXIDIZED_LIGHTNING_ROD = builder("waxed_oxidized_lightning_rod").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_LIGHTNING_ROD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_SWORD = builder("copper_sword").setMaxAmount(1).setMaxDurability(190).setAttributes(ItemAttribute.SWORD).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_SHOVEL = builder("copper_shovel").setMaxAmount(1).setMaxDurability(190).setAttributes(ItemAttribute.SHOVEL).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_PICKAXE = builder("copper_pickaxe").setMaxAmount(1).setMaxDurability(190).setAttributes(ItemAttribute.PICKAXE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_AXE = builder("copper_axe").setMaxAmount(1).setMaxDurability(190).setAttributes(ItemAttribute.AXE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_HOE = builder("copper_hoe").setMaxAmount(1).setMaxDurability(190).setAttributes(ItemAttribute.HOE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_HELMET = builder("copper_helmet").setMaxAmount(1).setMaxDurability(121).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_CHESTPLATE = builder("copper_chestplate").setMaxAmount(1).setMaxDurability(176).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_LEGGINGS = builder("copper_leggings").setMaxAmount(1).setMaxDurability(165).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_BOOTS = builder("copper_boots").setMaxAmount(1).setMaxDurability(143).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_GOLEM_SPAWN_EGG = builder("copper_golem_spawn_egg").setMaxAmount(64).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_HORSE_ARMOR = builder("copper_horse_armor").setMaxAmount(1).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_NUGGET = builder("copper_nugget").setMaxAmount(64).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_LANTERN = builder("copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType EXPOSED_COPPER_LANTERN = builder("exposed_copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WEATHERED_COPPER_LANTERN = builder("weathered_copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType OXIDIZED_COPPER_LANTERN = builder("oxidized_copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_COPPER_LANTERN = builder("waxed_copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_EXPOSED_COPPER_LANTERN = builder("waxed_exposed_copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_WEATHERED_COPPER_LANTERN = builder("waxed_weathered_copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_OXIDIZED_COPPER_LANTERN = builder("waxed_oxidized_copper_lantern").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_LANTERN).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_CHEST = builder("copper_chest").setMaxAmount(64).setPlacedType(StateTypes.COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType EXPOSED_COPPER_CHEST = builder("exposed_copper_chest").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WEATHERED_COPPER_CHEST = builder("weathered_copper_chest").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType OXIDIZED_COPPER_CHEST = builder("oxidized_copper_chest").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_COPPER_CHEST = builder("waxed_copper_chest").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_EXPOSED_COPPER_CHEST = builder("waxed_exposed_copper_chest").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_WEATHERED_COPPER_CHEST = builder("waxed_weathered_copper_chest").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_OXIDIZED_COPPER_CHEST = builder("waxed_oxidized_copper_chest").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_CHEST).build();
/**
* @versions 1.21.9+
*/
public static final ItemType COPPER_GOLEM_STATUE = builder("copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.COPPER_GOLEM_STATUE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType EXPOSED_COPPER_GOLEM_STATUE = builder("exposed_copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.EXPOSED_COPPER_GOLEM_STATUE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WEATHERED_COPPER_GOLEM_STATUE = builder("weathered_copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.WEATHERED_COPPER_GOLEM_STATUE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType OXIDIZED_COPPER_GOLEM_STATUE = builder("oxidized_copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.OXIDIZED_COPPER_GOLEM_STATUE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_COPPER_GOLEM_STATUE = builder("waxed_copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.WAXED_COPPER_GOLEM_STATUE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_EXPOSED_COPPER_GOLEM_STATUE = builder("waxed_exposed_copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.WAXED_EXPOSED_COPPER_GOLEM_STATUE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_WEATHERED_COPPER_GOLEM_STATUE = builder("waxed_weathered_copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.WAXED_WEATHERED_COPPER_GOLEM_STATUE).build();
/**
* @versions 1.21.9+
*/
public static final ItemType WAXED_OXIDIZED_COPPER_GOLEM_STATUE = builder("waxed_oxidized_copper_golem_statue").setMaxAmount(64).setPlacedType(StateTypes.WAXED_OXIDIZED_COPPER_GOLEM_STATUE).build();
/**
* @deprecated Burning furnace shows up as a missing texture, removed in 1.9
@@ -1625,8 +1920,8 @@ public final class ItemTypes {
}
// reset to start of buffer
ByteBufHelper.resetReaderIndex(byteBuf);
ByteBufHelper.resetWriterIndex(byteBuf);
ByteBufHelper.readerIndex(byteBuf, 0);
ByteBufHelper.writerIndex(byteBuf, 0);
// empty values are serialized as a single byte (smaller than an empty byte array),
// so just parse byte array tag values
@@ -1636,9 +1931,13 @@ public final class ItemTypes {
ByteBufHelper.writeBytes(byteBuf, bytes);
}
// read from shared buffer
Object compValue = compType.read(wrapper);
components.set((ComponentType<Object>) compType, compValue);
try {
// read from shared buffer
Object compValue = compType.read(wrapper);
components.set((ComponentType<Object>) compType, compValue);
} catch (Throwable throwable) {
throw new IllegalStateException("Failed to read " + compType, throwable);
}
// ensure the entire component value has been read
int wi = ByteBufHelper.writerIndex(byteBuf);
@@ -1686,7 +1985,7 @@ public final class ItemTypes {
ClientVersion[] versions = new ClientVersion[]{
ClientVersion.V_1_20_5, ClientVersion.V_1_21, ClientVersion.V_1_21_2,
ClientVersion.V_1_21_4, ClientVersion.V_1_21_5, ClientVersion.V_1_21_6,
ClientVersion.V_1_21_7,
ClientVersion.V_1_21_7, ClientVersion.V_1_21_9,
};
for (ClientVersion version : versions) {
parseAllComponents(version);
@@ -21,10 +21,12 @@ package com.github.retrooper.packetevents.protocol.mapper;
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;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.Objects;
@NullMarked
public abstract class AbstractMappedEntity implements MappedEntity {
protected final @Nullable TypesBuilderData data;
@@ -31,6 +31,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
public class NBTCompound extends NBT {
@@ -45,6 +46,10 @@ public class NBTCompound extends NBT {
return tags.isEmpty();
}
public boolean contains(String key) {
return this.tags.containsKey(key);
}
public Set<String> getTagNames() {
return Collections.unmodifiableSet(tags.keySet());
}
@@ -241,6 +246,12 @@ public class NBTCompound extends NBT {
return tag != null ? decoder.decode(tag, wrapper) : def;
}
@Contract("_, _, !null, _ -> !null")
public <T> @Nullable T getOrSupply(String key, NbtDecoder<T> decoder, Supplier<@Nullable T> def, PacketWrapper<?> wrapper) {
NBT tag = this.getTagOrNull(key);
return tag != null ? decoder.decode(tag, wrapper) : def.get();
}
public <T> @Nullable T getOrNull(String key, NbtDecoder<T> decoder, PacketWrapper<?> wrapper) {
return this.getOr(key, decoder, null, wrapper);
}
@@ -284,7 +295,7 @@ public class NBTCompound extends NBT {
if (list == null) {
throw new IllegalStateException(MessageFormat.format("NBT {0} does not exist", key));
}
return null;
return list;
}
public <T> void set(String key, T value, NbtEncoder<T> encoder, PacketWrapper<?> wrapper) {
@@ -297,10 +308,11 @@ public class NBTCompound extends NBT {
} else {
// determine list type using first value in list
NBT firstVal = encoder.encode(wrapper, value.get(0));
NBTList<?> list = new NBTList<>(firstVal.getType(), value.size());
int size = value.size();
NBTList<?> list = new NBTList<>(firstVal.getType(), size);
list.addTagUnsafe(firstVal);
// add remaining list entries
for (int i = 1; i < value.size(); i++) {
for (int i = 1; i < size; i++) {
list.addTagUnsafe(encoder.encode(wrapper, value.get(i)));
}
this.setTag(key, list);
@@ -18,11 +18,15 @@
package com.github.retrooper.packetevents.protocol.nbt;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@NullMarked
@ApiStatus.NonExtendable
public interface NBTLimiter {
int DEFAULT_MAX_SIZE = 2097152;
int DEFAULT_MAX_SIZE = Integer.getInteger("packetevents.nbt.default-max-size", 1 << 20); // 2MiB
int DEFAULT_MAX_DEPTH = Integer.getInteger("packetevents.nbt.default-max-depth", 512);
static NBTLimiter noop() {
return new NBTLimiter() {
@@ -35,27 +39,64 @@ public interface NBTLimiter {
public void checkReadability(int length) {
// no-op
}
@Override
public void enterDepth() {
// no-op
}
@Override
public void exitDepth() {
// no-op
}
};
}
static NBTLimiter forBuffer(final @NotNull Object byteBuf) {
static NBTLimiter forBuffer(Object byteBuf) {
return forBuffer(byteBuf, DEFAULT_MAX_SIZE);
}
static NBTLimiter forBuffer(final @NotNull Object byteBuf, final int max) {
static NBTLimiter forBuffer(Object byteBuf, int maxBytes) {
return forBuffer(byteBuf, maxBytes, DEFAULT_MAX_DEPTH);
}
static NBTLimiter forBuffer(Object byteBuf, int maxBytes, int maxDepth) {
return new NBTLimiter() {
private int bytes;
private int depth;
@Override
public void increment(int amount) {
bytes += amount;
if (bytes > max) throw new IllegalArgumentException("NBT size limit reached (" + bytes + "/" + max + ")");
if (amount < 0) {
throw new IllegalArgumentException("Can't increment NBT limiter by negative amount: " + amount);
} else if (this.bytes + amount > maxBytes) {
throw new IllegalArgumentException("NBT size limit reached (" + this.bytes + "/" + maxBytes + ")");
}
this.bytes += amount;
}
@Override
public void checkReadability(int length) {
if (length > ByteBufHelper.readableBytes(byteBuf)) throw new IllegalArgumentException("Length is too large: " + length + ", readable: " + ByteBufHelper.readableBytes(byteBuf));
int readableBytes = ByteBufHelper.readableBytes(byteBuf);
if (length > readableBytes) {
throw new IllegalArgumentException("Can't read more than possible: " + length + " > " + readableBytes);
}
}
@Override
public void enterDepth() {
if (this.depth >= maxDepth) {
throw new IllegalArgumentException("NBT depth limit reached (" + this.depth + "/" + maxDepth + ")");
}
this.depth++;
}
@Override
public void exitDepth() {
if (this.depth <= 0) {
throw new IllegalArgumentException("Can't exit top-level depth");
}
this.depth--;
}
};
}
@@ -64,4 +105,7 @@ public interface NBTLimiter {
void checkReadability(int length);
void enterDepth();
void exitDepth();
}
@@ -53,6 +53,19 @@ public class NBTList<T extends NBT> extends NBT {
return new NBTList<>(NBTType.STRING);
}
public static NBTType<?> getCommonTagType(List<? extends NBT> tags) {
NBTType<?> type = NBTType.END;
for (NBT tag : tags) {
if (type == NBTType.END) {
type = tag.getType();
} else if (type != tag.getType()) {
// there is no common type, fallback to heterogeneous list
return NBTType.COMPOUND;
}
}
return type; // common type found!
}
@Override
@SuppressWarnings("rawtypes")
public NBTType<NBTList> getType() {
@@ -112,6 +125,46 @@ public class NBTList<T extends NBT> extends NBT {
}
}
@SuppressWarnings("unchecked") // checked casts
public void addTagOrWrap(NBT tag) {
if (this.type == tag.getType()) {
this.tags.add((T) tag);
} else if (this.type == NBTType.COMPOUND) {
NBTCompound wrapped = new NBTCompound();
wrapped.setTag("", tag);
this.tags.add((T) wrapped);
} else {
throw new IllegalArgumentException("Can't add or wrap tag " + tag + " to list of type " + this.type);
}
}
private static NBT tryUnwrap(NBTCompound tag) {
if (tag.tags.size() == 1) {
NBT unwrapped = tag.getTagOrNull("");
if (unwrapped != null) {
return unwrapped;
}
}
return tag; // failed to unwrap
}
// vanilla allows heterogeneous lists by wrapping the different
// tag types in a compound tag list
public List<? extends NBT> unwrapTags() {
if (this.type != NBTType.COMPOUND) {
return new ArrayList<>(this.tags);
}
List<NBT> tags = new ArrayList<>(this.tags.size());
for (T tag : this.tags) {
if (tag instanceof NBTCompound) {
tags.add(tryUnwrap((NBTCompound) tag));
} else {
tags.add(tag);
}
}
return tags;
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
@@ -136,10 +136,9 @@ public class NBTCodec {
else if (nbt instanceof NBTCompound) {
JsonObject jsonObject = new JsonObject();
Map<String, NBT> compoundTags = ((NBTCompound)nbt).getTags();
for (String tagName : compoundTags.keySet()) {
NBT tag = compoundTags.get(tagName);
JsonElement jsonValue = nbtToJson(tag, parseByteAsBool);
jsonObject.add(tagName, jsonValue);
for (Map.Entry<String, NBT> entry : compoundTags.entrySet()) {
JsonElement jsonValue = nbtToJson(entry.getValue(), parseByteAsBool);
jsonObject.add(entry.getKey(), jsonValue);
}
return jsonObject;
}
@@ -18,72 +18,94 @@
package com.github.retrooper.packetevents.protocol.nbt.serializer;
import com.github.retrooper.packetevents.protocol.nbt.*;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTByte;
import com.github.retrooper.packetevents.protocol.nbt.NBTByteArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTDouble;
import com.github.retrooper.packetevents.protocol.nbt.NBTEnd;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTIntArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTLimiter;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTLong;
import com.github.retrooper.packetevents.protocol.nbt.NBTLongArray;
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 org.jetbrains.annotations.ApiStatus;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.List;
import java.util.Map.Entry;
public class DefaultNBTSerializer extends NBTSerializer<DataInput, DataOutput> {
@ApiStatus.Internal
public static final int OBJECT_HEADER_BYTES = 8;
@ApiStatus.Internal
public static final int ARRAY_HEADER_BYTES = 12;
@ApiStatus.Internal
public static final int OBJECT_REF_BYTES = 4;
@ApiStatus.Internal
public static final int STRING_SIZE_BYTES = 28;
public static final DefaultNBTSerializer INSTANCE = new DefaultNBTSerializer();
@SuppressWarnings("unchecked")
public DefaultNBTSerializer() {
super(
(limiter, dataInput) -> {
limiter.increment(1);
return dataInput.readByte();
},
(limiter, dataInput) -> dataInput.readByte(),
DataOutput::writeByte,
(limiter, dataInput) -> {
String name = dataInput.readUTF();
limiter.increment(name.length() * 2 + 28);
return name;
// only used for skipping strings
dataInput.skipBytes(dataInput.readUnsignedShort());
return "";
},
DataOutput::writeUTF
);
registerType(NBTType.END, 0, (limiter, stream) -> {
limiter.increment(8);
limiter.increment(OBJECT_HEADER_BYTES);
return NBTEnd.INSTANCE;
}, (stream, tag) -> {
});
registerType(NBTType.BYTE, 1, (limiter, stream) -> {
limiter.increment(9);
limiter.increment(OBJECT_HEADER_BYTES + Byte.BYTES);
return new NBTByte(stream.readByte());
}, (stream, tag) -> stream.writeByte(tag.getAsByte()));
registerType(NBTType.SHORT, 2, (limiter, stream) -> {
limiter.increment(10);
limiter.increment(OBJECT_HEADER_BYTES + Short.SIZE);
return new NBTShort(stream.readShort());
}, (stream, tag) -> stream.writeShort(tag.getAsShort()));
registerType(NBTType.INT, 3, (limiter, stream) -> {
limiter.increment(12);
limiter.increment(OBJECT_HEADER_BYTES + Integer.BYTES);
return new NBTInt(stream.readInt());
}, (stream, tag) -> stream.writeInt(tag.getAsInt()));
registerType(NBTType.LONG, 4, (limiter, stream) -> {
limiter.increment(16);
limiter.increment(OBJECT_HEADER_BYTES + Long.BYTES);
return new NBTLong(stream.readLong());
}, (stream, tag) -> stream.writeLong(tag.getAsLong()));
registerType(NBTType.FLOAT, 5, (limiter, stream) -> {
limiter.increment(12);
limiter.increment(OBJECT_HEADER_BYTES + Float.BYTES);
return new NBTFloat(stream.readFloat());
}, (stream, tag) -> stream.writeFloat(tag.getAsFloat()));
registerType(NBTType.DOUBLE, 6, (limiter, stream) -> {
limiter.increment(16);
limiter.increment(OBJECT_HEADER_BYTES + Double.BYTES);
return new NBTDouble(stream.readDouble());
}, (stream, tag) -> stream.writeDouble(tag.getAsDouble()));
registerType(
NBTType.BYTE_ARRAY, 7,
(limiter, stream) -> {
limiter.increment(24);
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int length = stream.readInt();
if (length >= 1 << 24)
if (length >= 1 << 24) {
throw new IllegalArgumentException("Byte array length is too large: " + length);
limiter.checkReadability(length);
limiter.increment(length);
}
limiter.increment(Byte.BYTES * length);
limiter.checkReadability(Byte.BYTES * length);
byte[] array = new byte[length];
stream.readFully(array);
@@ -96,28 +118,32 @@ public class DefaultNBTSerializer extends NBTSerializer<DataInput, DataOutput> {
}
);
registerType(NBTType.STRING, 8, (limiter, stream) -> {
limiter.increment(36);
limiter.increment(OBJECT_HEADER_BYTES + STRING_SIZE_BYTES);
String string = stream.readUTF();
limiter.increment(string.length() * 2);
limiter.increment(string.length() * Character.BYTES);
return new NBTString(string);
}, (stream, tag) -> stream.writeUTF(tag.getValue()));
registerType(
NBTType.LIST, 9,
(limiter, stream) -> {
limiter.increment(37);
NBTType<? extends NBT> valueType = readTagType(limiter, stream);
int size = stream.readInt();
if ((valueType == NBTType.END) && (size > 0)) {
throw new IllegalStateException("Missing nbt list values tag type");
limiter.enterDepth();
try {
limiter.increment(OBJECT_HEADER_BYTES + OBJECT_REF_BYTES // list tag
+ OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES); // arraylist
NBTType<? extends NBT> valueType = readTagType(limiter, stream);
int size = stream.readInt();
if (valueType == NBTType.END && size > 0) {
throw new IllegalStateException("Missing nbt list values tag type");
}
limiter.increment(OBJECT_REF_BYTES * size);
NBTList<NBT> list = new NBTList<>((NBTType<NBT>) valueType, size);
for (int i = 0; i < size; i++) {
list.addTag(readTag(limiter, stream, valueType));
}
return list;
} finally {
limiter.exitDepth();
}
limiter.increment(4 * size);
NBTList<NBT> list = new NBTList<>((NBTType<NBT>) valueType, size);
for (int i = 0; i < size; i++) {
list.addTag(readTag(limiter, stream, valueType));
}
return list;
},
(stream, tag) -> {
writeTagType(stream, tag.getTagsType());
@@ -130,17 +156,24 @@ public class DefaultNBTSerializer extends NBTSerializer<DataInput, DataOutput> {
registerType(
NBTType.COMPOUND, 10,
(limiter, stream) -> {
limiter.increment(48);
NBTCompound compound = new NBTCompound();
NBTType<?> valueType;
while ((valueType = readTagType(limiter, stream)) != NBTType.END) {
String name = readTagName(limiter, stream);
NBT nbt = readTag(limiter, stream, valueType);
if(!compound.getTags().containsKey(name)) limiter.increment(36);
compound.setTag(name, nbt);
limiter.enterDepth();
try {
limiter.increment(OBJECT_HEADER_BYTES + OBJECT_REF_BYTES // compound tag
+ OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES + Integer.BYTES + Integer.BYTES + Float.BYTES); // hashmap
NBTCompound compound = new NBTCompound();
NBTType<?> valueType;
while ((valueType = readTagType(limiter, stream)) != NBTType.END) {
String name = readString(limiter, stream);
NBT tag = readTag(limiter, stream, valueType);
if (!compound.getTags().containsKey(name)) {
limiter.increment(12 + OBJECT_HEADER_BYTES + Integer.BYTES + OBJECT_REF_BYTES + OBJECT_REF_BYTES + OBJECT_REF_BYTES);
}
compound.setTag(name, tag);
}
return compound;
} finally {
limiter.exitDepth();
}
return compound;
},
(stream, tag) -> {
for (Entry<String, NBT> entry : tag.getTags().entrySet()) {
@@ -155,14 +188,13 @@ public class DefaultNBTSerializer extends NBTSerializer<DataInput, DataOutput> {
registerType(
NBTType.INT_ARRAY, 11,
(limiter, stream) -> {
limiter.increment(24);
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int length = stream.readInt();
if (length >= 1 << 24)
if (length >= 1 << 24) {
throw new IllegalArgumentException("Int array length is too large: " + length);
limiter.checkReadability(length * 4);
limiter.increment(length * 4);
}
limiter.increment(length * Integer.BYTES);
limiter.checkReadability(length * Integer.BYTES);
int[] array = new int[length];
for (int i = 0; i < array.length; i++) {
@@ -181,14 +213,13 @@ public class DefaultNBTSerializer extends NBTSerializer<DataInput, DataOutput> {
registerType(
NBTType.LONG_ARRAY, 12,
(limiter, stream) -> {
limiter.increment(24);
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int length = stream.readInt();
if (length >= 1 << 24)
if (length >= 1 << 24) {
throw new IllegalArgumentException("Long array length is too large: " + length);
limiter.checkReadability(length * 8);
limiter.increment(length * 8);
}
limiter.increment(length * Long.BYTES);
limiter.checkReadability(length * Long.BYTES);
long[] array = new long[length];
for (int i = 0; i < array.length; i++) {
@@ -206,4 +237,10 @@ public class DefaultNBTSerializer extends NBTSerializer<DataInput, DataOutput> {
);
}
@ApiStatus.Internal
public static String readString(NBTLimiter limiter, DataInput input) throws IOException {
String string = input.readUTF();
limiter.increment(STRING_SIZE_BYTES + Character.BYTES * string.length());
return string;
}
}
@@ -21,12 +21,14 @@ package com.github.retrooper.packetevents.protocol.nbt.serializer;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTLimiter;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import org.jetbrains.annotations.ApiStatus;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
@ApiStatus.NonExtendable
public class NBTSerializer<IN, OUT> implements NBTReader<NBT, IN>, NBTWriter<NBT, OUT> {
protected final IdReader<IN> idReader;
@@ -37,6 +39,7 @@ public class NBTSerializer<IN, OUT> implements NBTReader<NBT, IN>, NBTWriter<NBT
protected final Map<NBTType<? extends NBT>, Integer> typeToId = new HashMap<>();
protected final Map<NBTType<? extends NBT>, TagReader<IN, ? extends NBT>> typeReaders = new HashMap<>();
protected final Map<NBTType<? extends NBT>, TagWriter<OUT, ? extends NBT>> typeWriters = new HashMap<>();
public NBTSerializer(
IdReader<IN> idReader, IdWriter<OUT> idWriter,
NameReader<IN> nameReader, NameWriter<OUT> nameWriter
@@ -98,6 +101,7 @@ public class NBTSerializer<IN, OUT> implements NBTReader<NBT, IN>, NBTWriter<NBT
return type;
}
@ApiStatus.Internal
String readTagName(NBTLimiter limiter, IN from) throws IOException {
return nameReader.readName(limiter, from);
}
@@ -17,11 +17,30 @@
*/
package com.github.retrooper.packetevents.protocol.nbt.serializer;
import com.github.retrooper.packetevents.protocol.nbt.*;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTLimiter;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.util.*;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import static com.github.retrooper.packetevents.protocol.nbt.serializer.DefaultNBTSerializer.ARRAY_HEADER_BYTES;
import static com.github.retrooper.packetevents.protocol.nbt.serializer.DefaultNBTSerializer.OBJECT_HEADER_BYTES;
import static com.github.retrooper.packetevents.protocol.nbt.serializer.DefaultNBTSerializer.OBJECT_REF_BYTES;
import static com.github.retrooper.packetevents.protocol.nbt.serializer.DefaultNBTSerializer.STRING_SIZE_BYTES;
public final class SequentialNBTReader implements NBTReader<NBT, DataInputStream> {
@@ -42,9 +61,9 @@ public final class SequentialNBTReader implements NBTReader<NBT, DataInputStream
NBT nbt;
if (type == NBTType.COMPOUND) {
nbt = new Compound(from, limiter, () -> {});
nbt = new Compound(from, limiter, () -> { /**/ });
} else if (type == NBTType.LIST) {
nbt = new List(from, limiter, () -> {});
nbt = new List(from, limiter, () -> { /**/ });
} else {
nbt = DefaultNBTSerializer.INSTANCE.readTag(limiter, from, type);
}
@@ -120,7 +139,7 @@ public final class SequentialNBTReader implements NBTReader<NBT, DataInputStream
try {
hasReadType = false;
String name = DefaultNBTSerializer.INSTANCE.readTagName(limiter, stream);
String name = DefaultNBTSerializer.readString(limiter, stream);
if (nextType == NBTType.COMPOUND) {
lastRead = new Compound(stream, limiter, this::runCompleted);
@@ -209,7 +228,7 @@ public final class SequentialNBTReader implements NBTReader<NBT, DataInputStream
// we have read a tag type, so we can start reading the tag
do {
String name = DefaultNBTSerializer.INSTANCE.readTagName(limiter, stream);
String name = DefaultNBTSerializer.readString(limiter, stream);
NBT nbt = DefaultNBTSerializer.INSTANCE.readTag(limiter, stream, nextType);
limiter.increment(36);
compound.setTag(name, nbt);
@@ -230,7 +249,7 @@ public final class SequentialNBTReader implements NBTReader<NBT, DataInputStream
((Skippable) lastRead).skip();
}
if (!hasNext()) return new byte[] { 10, 0 }; // empty compound
if (!hasNext()) return new byte[]{10, 0}; // empty compound
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(bytes)) {
out.write(10); // compound type
@@ -417,7 +436,7 @@ public final class SequentialNBTReader implements NBTReader<NBT, DataInputStream
((Skippable) lastRead).skip();
}
if (!hasNext()) return new byte[] { 9 };
if (!hasNext()) return new byte[]{9};
byte[] array = null;
for (int i = 0; i < remaining; i++) {
@@ -470,229 +489,224 @@ public final class SequentialNBTReader implements NBTReader<NBT, DataInputStream
static {
TAG_SKIPS.put(NBTType.BYTE, (limiter, in) -> {
limiter.increment(9);
limiter.increment(OBJECT_HEADER_BYTES + Byte.BYTES);
in.skipBytes(Byte.BYTES);
});
TAG_SKIPS.put(NBTType.SHORT, (limiter, in) -> {
limiter.increment(10);
limiter.increment(OBJECT_HEADER_BYTES + Short.BYTES);
in.skipBytes(Short.BYTES);
});
TAG_SKIPS.put(NBTType.INT, (limiter, in) -> {
limiter.increment(12);
limiter.increment(OBJECT_HEADER_BYTES + Integer.BYTES);
in.skipBytes(Integer.BYTES);
});
TAG_SKIPS.put(NBTType.LONG, (limiter, in) -> {
limiter.increment(16);
limiter.increment(OBJECT_HEADER_BYTES + Long.BYTES);
in.skipBytes(Long.BYTES);
});
TAG_SKIPS.put(NBTType.FLOAT, (limiter, in) -> {
limiter.increment(12);
limiter.increment(OBJECT_HEADER_BYTES + Float.BYTES);
in.skipBytes(Float.BYTES);
});
TAG_SKIPS.put(NBTType.DOUBLE, (limiter, in) -> {
limiter.increment(16);
limiter.increment(OBJECT_HEADER_BYTES + Double.BYTES);
in.skipBytes(Double.BYTES);
});
TAG_SKIPS.put(NBTType.BYTE_ARRAY, (limiter, in) -> {
limiter.increment(24);
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int length = in.readInt();
limiter.checkReadability(length);
limiter.increment(length);
limiter.increment(length * Byte.BYTES);
limiter.checkReadability(length * Byte.BYTES);
in.skipBytes(length);
});
TAG_SKIPS.put(NBTType.STRING, (limiter, in) -> {
limiter.increment(36);
limiter.increment(OBJECT_HEADER_BYTES + STRING_SIZE_BYTES);
int length = in.readUnsignedShort();
limiter.increment(length * 2);
limiter.increment(length * Character.BYTES);
in.skipBytes(length);
});
TAG_SKIPS.put(NBTType.LIST, (limiter, in) -> {
limiter.increment(37);
NBTType<?> listType = DefaultNBTSerializer.INSTANCE.readTagType(limiter, in);
int length = in.readInt();
limiter.increment(length * 4);
for (int i = 0; i < length; i++) {
TAG_SKIPS.get(listType).skip(limiter, in);
limiter.enterDepth();
try {
limiter.increment(OBJECT_HEADER_BYTES + OBJECT_REF_BYTES // list tag
+ OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES); // arraylist
NBTType<?> listType = DefaultNBTSerializer.INSTANCE.readTagType(limiter, in);
int length = in.readInt();
limiter.increment(length * OBJECT_REF_BYTES);
for (int i = 0; i < length; i++) {
TAG_SKIPS.get(listType).skip(limiter, in);
}
} finally {
limiter.exitDepth();
}
});
TAG_SKIPS.put(NBTType.COMPOUND, (limiter, in) -> {
limiter.increment(48);
NBTType<?> valueType;
while ((valueType = DefaultNBTSerializer.INSTANCE.readTagType(limiter, in)) != NBTType.END) {
int utfLen = in.readUnsignedShort();
in.skipBytes(utfLen);
limiter.increment(36);
TAG_SKIPS.get(valueType).skip(limiter, in);
limiter.enterDepth();
try {
limiter.increment(OBJECT_HEADER_BYTES + OBJECT_REF_BYTES // compound tag
+ OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES + Integer.BYTES + Integer.BYTES + Float.BYTES); // hashmap
Set<String> names = new HashSet<>();
NBTType<?> valueType;
while ((valueType = DefaultNBTSerializer.INSTANCE.readTagType(limiter, in)) != NBTType.END) {
String name = DefaultNBTSerializer.readString(limiter, in);
if (names.add(name)) {
limiter.increment(12 + OBJECT_HEADER_BYTES + Integer.BYTES + OBJECT_REF_BYTES + OBJECT_REF_BYTES + OBJECT_REF_BYTES);
}
TAG_SKIPS.get(valueType).skip(limiter, in);
}
} finally {
limiter.exitDepth();
}
});
TAG_SKIPS.put(NBTType.INT_ARRAY, (limiter, in) -> {
limiter.increment(24);
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int length = in.readInt();
limiter.checkReadability(length * 4);
limiter.increment(length * 4);
limiter.increment(length * Integer.BYTES);
limiter.checkReadability(length * Integer.BYTES);
in.skipBytes(length * Integer.BYTES);
});
TAG_SKIPS.put(NBTType.LONG_ARRAY, (limiter, in) -> {
limiter.increment(24);
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int length = in.readInt();
limiter.checkReadability(length * 8);
limiter.increment(length * 8);
limiter.increment(length * Long.BYTES);
limiter.checkReadability(length * Long.BYTES);
in.skipBytes(length * Long.BYTES);
});
TAG_BINARY_READERS.put(NBTType.BYTE, (limiter, in) -> {
limiter.increment(9);
return new byte[] { in.readByte() };
limiter.increment(OBJECT_HEADER_BYTES + Byte.BYTES);
return new byte[]{in.readByte()};
});
TAG_BINARY_READERS.put(NBTType.SHORT, (limiter, in) -> {
limiter.increment(10);
return new byte[] { in.readByte(), in.readByte() };
limiter.increment(OBJECT_HEADER_BYTES + Short.BYTES);
return new byte[]{in.readByte(), in.readByte()};
});
TAG_BINARY_READERS.put(NBTType.INT, (limiter, in) -> {
limiter.increment(12);
limiter.increment(OBJECT_HEADER_BYTES + Integer.BYTES);
byte[] bytes = new byte[Integer.BYTES];
in.readFully(bytes);
return bytes;
});
TAG_BINARY_READERS.put(NBTType.LONG, (limiter, in) -> {
limiter.increment(16);
limiter.increment(OBJECT_HEADER_BYTES + Long.BYTES);
byte[] bytes = new byte[Long.BYTES];
in.readFully(bytes);
return bytes;
});
TAG_BINARY_READERS.put(NBTType.FLOAT, (limiter, in) -> {
limiter.increment(12);
limiter.increment(OBJECT_HEADER_BYTES + Float.BYTES);
byte[] bytes = new byte[Float.BYTES];
in.readFully(bytes);
return bytes;
});
TAG_BINARY_READERS.put(NBTType.DOUBLE, (limiter, in) -> {
limiter.increment(16);
limiter.increment(OBJECT_HEADER_BYTES + Double.BYTES);
byte[] bytes = new byte[Double.BYTES];
in.readFully(bytes);
return bytes;
});
TAG_BINARY_READERS.put(NBTType.BYTE_ARRAY, (limiter, in) -> {
limiter.increment(24);
byte[] length = new byte[Integer.BYTES];
in.readFully(length);
int len = bytesToInt(length);
if (len >= 1 << 24)
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int len = in.readInt();
if (len >= 1 << 24) {
throw new IllegalArgumentException("Byte array length is too large: " + len);
limiter.checkReadability(len);
limiter.increment(len);
}
limiter.increment(len * Byte.BYTES);
limiter.checkReadability(len * Byte.BYTES);
byte[] array = new byte[Integer.BYTES + len];
System.arraycopy(length, 0, array, 0, Integer.BYTES);
intToBytes(array, len, 0);
in.readFully(array, Integer.BYTES, len);
return array;
});
TAG_BINARY_READERS.put(NBTType.STRING, (limiter, in) -> {
limiter.increment(36);
byte[] length = new byte[Short.BYTES];
in.readFully(length);
// read len
short signedVal = (short) ((length[0] & 0xFF) << 8 | (length[1] & 0xFF));
int len = signedVal >= 0 ? signedVal : 0x10000 + signedVal;
limiter.increment(OBJECT_HEADER_BYTES + STRING_SIZE_BYTES);
String string = in.readUTF();
limiter.increment(string.length() * Character.BYTES);
limiter.increment(len * 2);
byte[] array = new byte[Short.BYTES + len];
System.arraycopy(length, 0, array, 0, Short.BYTES);
in.readFully(array, Short.BYTES, len);
return array;
});
TAG_BINARY_READERS.put(NBTType.LIST, (limiter, in) -> {
limiter.increment(37);
byte type = in.readByte();
NBTType<? extends NBT> nbtType = DefaultNBTSerializer.INSTANCE.idToType.get((int) type);
byte[] length = new byte[Integer.BYTES];
in.readFully(length);
int len = bytesToInt(length);
limiter.increment(len * 4);
byte[] array = null;
for (int i = 0; i < len; i++) {
byte[] element = TAG_BINARY_READERS.get(nbtType).read(limiter, in);
if (array == null) {
array = new byte[1 + Integer.BYTES + len * element.length]; // all the remaining child tags will be of same size
array[0] = type;
System.arraycopy(length, 0, array, 1, Integer.BYTES);
}
System.arraycopy(element, 0, array, 1 + Integer.BYTES + i * element.length, element.length);
}
return array;
});
TAG_BINARY_READERS.put(NBTType.COMPOUND, (limiter, in) -> {
limiter.increment(48);
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream(); DataOutputStream out = new DataOutputStream(bytes)) {
byte type;
while ((type = in.readByte()) != 0) {
out.writeByte(type);
// name
byte[] name = TAG_BINARY_READERS.get(NBTType.STRING).read(NBTLimiter.noop(), in);
limiter.increment(name.length * 2 + 28);
out.write(name);
// nbt
byte[] nbt = TAG_BINARY_READERS.get(DefaultNBTSerializer.INSTANCE.idToType.get((int) type)).read(limiter, in);
limiter.increment(36);
out.write(nbt);
}
out.write(0); // end
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(bytes)) {
out.writeUTF(string);
return bytes.toByteArray();
}
});
TAG_BINARY_READERS.put(NBTType.INT_ARRAY, (limiter, in) -> {
limiter.increment(24);
byte[] length = new byte[Integer.BYTES];
in.readFully(length);
int len = bytesToInt(length);
TAG_BINARY_READERS.put(NBTType.LIST, (limiter, in) -> {
limiter.enterDepth();
try {
limiter.increment(OBJECT_HEADER_BYTES + OBJECT_REF_BYTES // list tag
+ OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES); // arraylist
byte type = in.readByte();
NBTType<? extends NBT> nbtType = DefaultNBTSerializer.INSTANCE.idToType.get((int) type);
limiter.checkReadability(len * 4);
limiter.increment(len * 4);
int len = in.readInt();
limiter.increment(len * OBJECT_REF_BYTES);
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(bytes)) {
out.write(type);
out.writeInt(len);
for (int i = 0; i < len; i++) {
out.write(TAG_BINARY_READERS.get(nbtType).read(limiter, in));
}
return bytes.toByteArray();
}
} finally {
limiter.exitDepth();
}
});
TAG_BINARY_READERS.put(NBTType.COMPOUND, (limiter, in) -> {
limiter.enterDepth();
try {
limiter.increment(OBJECT_HEADER_BYTES + OBJECT_REF_BYTES // compound tag
+ OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES + Integer.BYTES + Integer.BYTES + Float.BYTES); // hashmap
try (ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(bytes)) {
Set<String> names = new HashSet<>();
byte type;
while ((type = in.readByte()) != 0) {
out.write(type);
String name = DefaultNBTSerializer.readString(limiter, in);
out.writeUTF(name);
out.write(TAG_BINARY_READERS.get(DefaultNBTSerializer.INSTANCE.idToType.get((int) type)).read(limiter, in));
if (names.add(name)) {
limiter.increment(12 + OBJECT_HEADER_BYTES + Integer.BYTES + OBJECT_REF_BYTES + OBJECT_REF_BYTES + OBJECT_REF_BYTES);
}
}
out.write(type);
return bytes.toByteArray();
}
} finally {
limiter.exitDepth();
}
});
TAG_BINARY_READERS.put(NBTType.INT_ARRAY, (limiter, in) -> {
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int len = in.readInt();
limiter.increment(len * Integer.BYTES);
limiter.checkReadability(len * Integer.BYTES);
byte[] array = new byte[Integer.BYTES + len * Integer.BYTES];
System.arraycopy(length, 0, array, 0, Integer.BYTES);
intToBytes(array, len, 0);
in.readFully(array, Integer.BYTES, len * Integer.BYTES);
return array;
});
TAG_BINARY_READERS.put(NBTType.LONG_ARRAY, (limiter, in) -> {
limiter.increment(24);
byte[] length = new byte[Integer.BYTES];
in.readFully(length);
int len = bytesToInt(length);
limiter.checkReadability(len * 8);
limiter.increment(len * 8);
limiter.increment(OBJECT_HEADER_BYTES + ARRAY_HEADER_BYTES + Integer.BYTES);
int len = in.readInt();
limiter.increment(len * Long.BYTES);
limiter.checkReadability(len * Long.BYTES);
byte[] array = new byte[Integer.BYTES + len * Long.BYTES];
System.arraycopy(length, 0, array, 0, Integer.BYTES);
intToBytes(array, len, 0);
in.readFully(array, Integer.BYTES, len * Long.BYTES);
return array;
});
}
private static int bytesToInt(byte[] bytes) {
return ((bytes[0] & 0xFF) << 24) |
((bytes[1] & 0xFF) << 16) |
((bytes[2] & 0xFF) << 8 ) |
((bytes[3] & 0xFF));
public static void intToBytes(byte[] array, int val, int offset) {
array[offset] = (byte) ((val >>> 24) & 0xFF);
array[offset + 1] = (byte) ((val >>> 16) & 0xFF);
array[offset + 2] = (byte) ((val >>> 8) & 0xFF);
array[offset + 3] = (byte) (val & 0xFF);
}
}
@@ -42,6 +42,7 @@ import com.github.retrooper.packetevents.protocol.packettype.clientbound.Clientb
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_21_2;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_21_5;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_21_6;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_21_9;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_7_10;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_8;
import com.github.retrooper.packetevents.protocol.packettype.clientbound.ClientboundPacketType_1_9;
@@ -51,9 +52,11 @@ import com.github.retrooper.packetevents.protocol.packettype.config.clientbound.
import com.github.retrooper.packetevents.protocol.packettype.config.clientbound.ClientboundConfigPacketType_1_20_5;
import com.github.retrooper.packetevents.protocol.packettype.config.clientbound.ClientboundConfigPacketType_1_21;
import com.github.retrooper.packetevents.protocol.packettype.config.clientbound.ClientboundConfigPacketType_1_21_6;
import com.github.retrooper.packetevents.protocol.packettype.config.clientbound.ClientboundConfigPacketType_1_21_9;
import com.github.retrooper.packetevents.protocol.packettype.config.serverbound.ServerboundConfigPacketType_1_20_2;
import com.github.retrooper.packetevents.protocol.packettype.config.serverbound.ServerboundConfigPacketType_1_20_5;
import com.github.retrooper.packetevents.protocol.packettype.config.serverbound.ServerboundConfigPacketType_1_21_6;
import com.github.retrooper.packetevents.protocol.packettype.config.serverbound.ServerboundConfigPacketType_1_21_9;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_12;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_12_1;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_13;
@@ -73,12 +76,14 @@ import com.github.retrooper.packetevents.protocol.packettype.serverbound.Serverb
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_21_4;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_21_5;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_21_6;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_21_9;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_7_10;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_8;
import com.github.retrooper.packetevents.protocol.packettype.serverbound.ServerboundPacketType_1_9;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.VersionMapper;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientAcceptCodeOfConduct;
import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientConfigurationEndAck;
import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientCookieResponse;
import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientCustomClickAction;
@@ -89,6 +94,7 @@ import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperCon
import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientSelectKnownPacks;
import com.github.retrooper.packetevents.wrapper.configuration.client.WrapperConfigClientSettings;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerClearDialog;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerCodeOfConduct;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerConfigurationEnd;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerCookieRequest;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerCustomReportDetails;
@@ -140,6 +146,7 @@ import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientCr
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientCustomClickAction;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientDebugPing;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientDebugSampleSubscription;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientDebugSubscriptionRequest;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEditBook;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientGenerateStructure;
@@ -188,7 +195,162 @@ import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUp
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientUseItem;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientVehicleMove;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientWindowConfirmation;
import com.github.retrooper.packetevents.wrapper.play.server.*;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAcknowledgeBlockChanges;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAcknowledgePlayerDigging;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerActionBar;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAttachEntity;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockAction;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockBreakAnimation;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockChange;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBlockEntityData;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBossBar;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerBundle;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCamera;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChangeGameState;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatMessage;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChatPreview;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkBatchBegin;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkBatchEnd;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkData;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerChunkDataBulk;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerClearDialog;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerClearTitles;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCloseWindow;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCollectItem;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCombatEvent;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerConfigurationStart;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCookieRequest;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCraftRecipeResponse;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCustomChatCompletions;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCustomReportDetails;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDamageEvent;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDeathCombatEvent;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDebugBlockValue;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDebugChunkValue;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDebugEntityValue;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDebugEvent;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDebugPong;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDebugSample;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDeclareCommands;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDeclareRecipes;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDeleteChat;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDestroyEntities;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDifficulty;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisconnect;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisguisedChat;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDisplayScoreboard;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEffect;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEndCombatEvent;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEnterCombatEvent;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEffect;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityEquipment;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityHeadLook;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMovement;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityPositionSync;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRelativeMove;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRelativeMoveAndRotation;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityRotation;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntitySoundEffect;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityStatus;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityTeleport;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityVelocity;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerExplosion;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerFacePlayer;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerGameTestHighlightPos;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerHeldItemChange;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerHurtAnimation;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerInitializeWorldBorder;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerJoinGame;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerKeepAlive;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMapData;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMerchantOffers;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMoveMinecart;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMultiBlockChange;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerNBTQueryResponse;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerOpenBook;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerOpenHorseWindow;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerOpenSignEditor;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerOpenWindow;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerParticle;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPing;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerAbilities;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerChatHeader;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerListHeaderAndFooter;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerPositionAndLook;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerRotation;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPluginMessage;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerProjectilePower;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRecipeBookAdd;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRecipeBookRemove;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRecipeBookSettings;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRemoveEntityEffect;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerResetScore;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerResourcePackRemove;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerResourcePackSend;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerScoreboardObjective;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSelectAdvancementsTab;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerServerData;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerServerLinks;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetCompression;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetCooldown;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetCursorItem;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetDisplayChatPreview;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetExperience;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetPassengers;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetPlayerInventory;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleSubtitle;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleText;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetTitleTimes;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerShowDialog;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSoundEffect;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnExperienceOrb;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnLivingEntity;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPainting;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPlayer;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnPosition;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnWeatherEntity;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerStatistics;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerStoreCookie;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSystemChatMessage;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTabComplete;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTags;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTeams;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTestInstanceBlockStatus;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTickingState;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTickingStep;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTimeUpdate;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerTransfer;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUnloadChunk;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAdvancements;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateEnabledFeatures;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateEntityNBT;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateHealth;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateLight;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateScore;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateSimulationDistance;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateViewDistance;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateViewPosition;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUseBed;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerVehicleMove;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWaypoint;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowConfirmation;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowItems;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowProperty;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWorldBorder;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWorldBorderCenter;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWorldBorderSize;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWorldBorderWarningReach;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayWorldBorderLerpSize;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayWorldBorderWarningDelay;
import com.github.retrooper.packetevents.wrapper.status.client.WrapperStatusClientPing;
import com.github.retrooper.packetevents.wrapper.status.client.WrapperStatusClientRequest;
import com.github.retrooper.packetevents.wrapper.status.server.WrapperStatusServerPong;
@@ -231,7 +393,8 @@ public final class PacketType {
ClientVersion.V_1_21,
ClientVersion.V_1_21_2,
ClientVersion.V_1_21_5,
ClientVersion.V_1_21_6);
ClientVersion.V_1_21_6,
ClientVersion.V_1_21_9);
//TODO UPDATE Update packet type mappings (serverbound pt. 1)
private static final VersionMapper SERVERBOUND_PLAY_VERSION_MAPPER = new VersionMapper(
@@ -256,7 +419,8 @@ public final class PacketType {
ClientVersion.V_1_21_2,
ClientVersion.V_1_21_4,
ClientVersion.V_1_21_5,
ClientVersion.V_1_21_6);
ClientVersion.V_1_21_6,
ClientVersion.V_1_21_9);
// TODO UPDATE Update packet type mappings (config clientbound pt. 1)
private static final VersionMapper CLIENTBOUND_CONFIG_VERSION_MAPPER = new VersionMapper(
@@ -264,12 +428,14 @@ public final class PacketType {
ClientVersion.V_1_20_3,
ClientVersion.V_1_20_5,
ClientVersion.V_1_21,
ClientVersion.V_1_21_6);
ClientVersion.V_1_21_6,
ClientVersion.V_1_21_9);
// TODO UPDATE Update packet type mappings (config serverbound pt. 1)
private static final VersionMapper SERVERBOUND_CONFIG_VERSION_MAPPER = new VersionMapper(
ClientVersion.V_1_20_2,
ClientVersion.V_1_20_5,
ClientVersion.V_1_21_6);
ClientVersion.V_1_21_6,
ClientVersion.V_1_21_9);
public static void prepare() {
PacketType.Play.Client.load();
@@ -628,6 +794,10 @@ public final class PacketType {
* Added with 1.21.6
*/
CUSTOM_CLICK_ACTION(WrapperConfigClientCustomClickAction.class),
/**
* @versions 1.21.9+
*/
ACCEPT_CODE_OF_CONDUCT(WrapperConfigClientAcceptCodeOfConduct.class),
;
private static int INDEX = 0;
@@ -651,6 +821,7 @@ public final class PacketType {
loadPacketIds(ServerboundConfigPacketType_1_20_2.values());
loadPacketIds(ServerboundConfigPacketType_1_20_5.values());
loadPacketIds(ServerboundConfigPacketType_1_21_6.values());
loadPacketIds(ServerboundConfigPacketType_1_21_9.values());
// TODO UPDATE Update packet type mappings (config serverbound pt. 2)
}
@@ -754,6 +925,11 @@ public final class PacketType {
* Added with 1.21.6
*/
SHOW_DIALOG(WrapperConfigServerShowDialog.class),
/**
* @versions 1.21.9+
*/
CODE_OF_CONDUCT(WrapperConfigServerCodeOfConduct.class),
;
private static int INDEX = 0;
@@ -779,6 +955,7 @@ public final class PacketType {
loadPacketIds(ClientboundConfigPacketType_1_20_5.values());
loadPacketIds(ClientboundConfigPacketType_1_21.values());
loadPacketIds(ClientboundConfigPacketType_1_21_6.values());
loadPacketIds(ClientboundConfigPacketType_1_21_9.values());
// TODO UPDATE Update packet type mappings (config clientbound pt. 2)
}
@@ -936,8 +1113,9 @@ public final class PacketType {
*/
COOKIE_RESPONSE(WrapperPlayClientCookieResponse.class),
/**
* Added with 1.20.5
* @versions 1.20.5-1.21.8
*/
@ApiStatus.Obsolete
DEBUG_SAMPLE_SUBSCRIPTION(WrapperPlayClientDebugSampleSubscription.class),
/**
@@ -983,6 +1161,11 @@ public final class PacketType {
* Added with 1.21.6
*/
CUSTOM_CLICK_ACTION(WrapperPlayClientCustomClickAction.class),
/**
* @versions 1.21.9+
*/
DEBUG_SUBSCRIPTION_REQUEST(WrapperPlayClientDebugSubscriptionRequest.class),
;
private static int INDEX = 0;
@@ -1048,6 +1231,7 @@ public final class PacketType {
loadPacketIds(ServerboundPacketType_1_21_4.values());
loadPacketIds(ServerboundPacketType_1_21_5.values());
loadPacketIds(ServerboundPacketType_1_21_6.values());
loadPacketIds(ServerboundPacketType_1_21_9.values());
//TODO UPDATE Update packet type mappings (serverbound pt. 2)
}
@@ -1364,6 +1548,27 @@ public final class PacketType {
* Added with 1.21.6
*/
SHOW_DIALOG(WrapperPlayServerShowDialog.class),
/**
* @versions 1.21.9+
*/
DEBUG_BLOCK_VALUE(WrapperPlayServerDebugBlockValue.class),
/**
@versions 1.21.9+
*/
DEBUG_CHUNK_VALUE(WrapperPlayServerDebugChunkValue.class),
/**
@versions 1.21.9+
*/
DEBUG_ENTITY_VALUE(WrapperPlayServerDebugEntityValue.class),
/**
@versions 1.21.9+
*/
DEBUG_EVENT(WrapperPlayServerDebugEvent.class),
/**
@versions 1.21.9+
*/
GAME_TEST_HIGHLIGHT_POS(WrapperPlayServerGameTestHighlightPos.class),
;
private static int INDEX = 0;
@@ -1445,6 +1650,7 @@ public final class PacketType {
loadPacketIds(ClientboundPacketType_1_21_2.values());
loadPacketIds(ClientboundPacketType_1_21_5.values());
loadPacketIds(ClientboundPacketType_1_21_6.values());
loadPacketIds(ClientboundPacketType_1_21_9.values());
//TODO UPDATE Update packet type mappings (clientbound pt. 2)
}
}
@@ -0,0 +1,177 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.clientbound;
public enum ClientboundPacketType_1_21_9 {
BUNDLE,
SPAWN_ENTITY,
ENTITY_ANIMATION,
STATISTICS,
ACKNOWLEDGE_BLOCK_CHANGES,
BLOCK_BREAK_ANIMATION,
BLOCK_ENTITY_DATA,
BLOCK_ACTION,
BLOCK_CHANGE,
BOSS_BAR,
SERVER_DIFFICULTY,
CHUNK_BATCH_END,
CHUNK_BATCH_BEGIN,
CHUNK_BIOMES,
CLEAR_TITLES,
TAB_COMPLETE,
DECLARE_COMMANDS,
CLOSE_WINDOW,
WINDOW_ITEMS,
WINDOW_PROPERTY,
SET_SLOT,
COOKIE_REQUEST,
SET_COOLDOWN,
CUSTOM_CHAT_COMPLETIONS,
PLUGIN_MESSAGE,
DAMAGE_EVENT,
/**
* New packet
*/
DEBUG_BLOCK_VALUE,
/**
* New packet
*/
DEBUG_CHUNK_VALUE,
/**
* New packet
*/
DEBUG_ENTITY_VALUE,
/**
* New packet
*/
DEBUG_EVENT,
DEBUG_SAMPLE,
DELETE_CHAT,
DISCONNECT,
DISGUISED_CHAT,
ENTITY_STATUS,
ENTITY_POSITION_SYNC,
EXPLOSION,
UNLOAD_CHUNK,
CHANGE_GAME_STATE,
/**
* New packet
*/
GAME_TEST_HIGHLIGHT_POS,
OPEN_HORSE_WINDOW,
HURT_ANIMATION,
INITIALIZE_WORLD_BORDER,
KEEP_ALIVE,
CHUNK_DATA,
EFFECT,
PARTICLE,
UPDATE_LIGHT,
JOIN_GAME,
MAP_DATA,
MERCHANT_OFFERS,
ENTITY_RELATIVE_MOVE,
ENTITY_RELATIVE_MOVE_AND_ROTATION,
MOVE_MINECART,
ENTITY_ROTATION,
VEHICLE_MOVE,
OPEN_BOOK,
OPEN_WINDOW,
OPEN_SIGN_EDITOR,
PING,
DEBUG_PONG,
CRAFT_RECIPE_RESPONSE,
PLAYER_ABILITIES,
CHAT_MESSAGE,
END_COMBAT_EVENT,
ENTER_COMBAT_EVENT,
DEATH_COMBAT_EVENT,
PLAYER_INFO_REMOVE,
PLAYER_INFO_UPDATE,
FACE_PLAYER,
PLAYER_POSITION_AND_LOOK,
PLAYER_ROTATION,
RECIPE_BOOK_ADD,
RECIPE_BOOK_REMOVE,
RECIPE_BOOK_SETTINGS,
DESTROY_ENTITIES,
REMOVE_ENTITY_EFFECT,
RESET_SCORE,
RESOURCE_PACK_REMOVE,
RESOURCE_PACK_SEND,
RESPAWN,
ENTITY_HEAD_LOOK,
MULTI_BLOCK_CHANGE,
SELECT_ADVANCEMENTS_TAB,
SERVER_DATA,
ACTION_BAR,
WORLD_BORDER_CENTER,
WORLD_BORDER_LERP_SIZE,
WORLD_BORDER_SIZE,
WORLD_BORDER_WARNING_DELAY,
WORLD_BORDER_WARNING_REACH,
CAMERA,
UPDATE_VIEW_POSITION,
UPDATE_VIEW_DISTANCE,
SET_CURSOR_ITEM,
SPAWN_POSITION,
DISPLAY_SCOREBOARD,
ENTITY_METADATA,
ATTACH_ENTITY,
ENTITY_VELOCITY,
ENTITY_EQUIPMENT,
SET_EXPERIENCE,
UPDATE_HEALTH,
HELD_ITEM_CHANGE,
SCOREBOARD_OBJECTIVE,
SET_PASSENGERS,
SET_PLAYER_INVENTORY,
TEAMS,
UPDATE_SCORE,
UPDATE_SIMULATION_DISTANCE,
SET_TITLE_SUBTITLE,
TIME_UPDATE,
SET_TITLE_TEXT,
SET_TITLE_TIMES,
ENTITY_SOUND_EFFECT,
SOUND_EFFECT,
CONFIGURATION_START,
STOP_SOUND,
STORE_COOKIE,
SYSTEM_CHAT_MESSAGE,
PLAYER_LIST_HEADER_AND_FOOTER,
NBT_QUERY_RESPONSE,
COLLECT_ITEM,
ENTITY_TELEPORT,
TEST_INSTANCE_BLOCK_STATUS,
TICKING_STATE,
TICKING_STEP,
TRANSFER,
UPDATE_ADVANCEMENTS,
UPDATE_ATTRIBUTES,
ENTITY_EFFECT,
DECLARE_RECIPES,
TAGS,
PROJECTILE_POWER,
CUSTOM_REPORT_DETAILS,
SERVER_LINKS,
WAYPOINT,
CLEAR_DIALOG,
SHOW_DIALOG,
}
@@ -0,0 +1,46 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.config.clientbound;
public enum ClientboundConfigPacketType_1_21_9 {
COOKIE_REQUEST,
PLUGIN_MESSAGE,
DISCONNECT,
CONFIGURATION_END,
KEEP_ALIVE,
PING,
RESET_CHAT,
REGISTRY_DATA,
RESOURCE_PACK_REMOVE,
RESOURCE_PACK_SEND,
STORE_COOKIE,
TRANSFER,
UPDATE_ENABLED_FEATURES,
UPDATE_TAGS,
SELECT_KNOWN_PACKS,
CUSTOM_REPORT_DETAILS,
SERVER_LINKS,
CLEAR_DIALOG,
SHOW_DIALOG,
/**
* New packet
*/
CODE_OF_CONDUCT,
}
@@ -0,0 +1,36 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.config.serverbound;
public enum ServerboundConfigPacketType_1_21_9 {
CLIENT_SETTINGS,
COOKIE_RESPONSE,
PLUGIN_MESSAGE,
CONFIGURATION_END_ACK,
KEEP_ALIVE,
PONG,
RESOURCE_PACK_STATUS,
SELECT_KNOWN_PACKS,
CUSTOM_CLICK_ACTION,
/**
* New packet
*/
ACCEPT_CODE_OF_CONDUCT,
}
@@ -0,0 +1,92 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.packettype.serverbound;
public enum ServerboundPacketType_1_21_9 {
TELEPORT_CONFIRM,
QUERY_BLOCK_NBT,
SELECT_BUNDLE_ITEM,
SET_DIFFICULTY,
CHANGE_GAME_MODE,
CHAT_ACK,
CHAT_COMMAND_UNSIGNED,
CHAT_COMMAND,
CHAT_MESSAGE,
CHAT_SESSION_UPDATE,
CHUNK_BATCH_ACK,
CLIENT_STATUS,
CLIENT_TICK_END,
CLIENT_SETTINGS,
TAB_COMPLETE,
CONFIGURATION_ACK,
CLICK_WINDOW_BUTTON,
CLICK_WINDOW,
CLOSE_WINDOW,
SLOT_STATE_CHANGE,
COOKIE_RESPONSE,
PLUGIN_MESSAGE,
/**
* New packet
*/
DEBUG_SUBSCRIPTION_REQUEST,
EDIT_BOOK,
QUERY_ENTITY_NBT,
INTERACT_ENTITY,
GENERATE_STRUCTURE,
KEEP_ALIVE,
LOCK_DIFFICULTY,
PLAYER_POSITION,
PLAYER_POSITION_AND_ROTATION,
PLAYER_ROTATION,
PLAYER_FLYING,
VEHICLE_MOVE,
STEER_BOAT,
PICK_ITEM_FROM_BLOCK,
PICK_ITEM_FROM_ENTITY,
DEBUG_PING,
CRAFT_RECIPE_REQUEST,
PLAYER_ABILITIES,
PLAYER_DIGGING,
ENTITY_ACTION,
PLAYER_INPUT,
PLAYER_LOADED,
PONG,
SET_RECIPE_BOOK_STATE,
SET_DISPLAYED_RECIPE,
NAME_ITEM,
RESOURCE_PACK_STATUS,
ADVANCEMENT_TAB,
SELECT_TRADE,
SET_BEACON_EFFECT,
HELD_ITEM_CHANGE,
UPDATE_COMMAND_BLOCK,
UPDATE_COMMAND_BLOCK_MINECART,
CREATIVE_INVENTORY_ACTION,
UPDATE_JIGSAW_BLOCK,
UPDATE_STRUCTURE_BLOCK,
SET_TEST_BLOCK,
UPDATE_SIGN,
ANIMATION,
SPECTATE,
TEST_INSTANCE_BLOCK_ACTION,
PLAYER_BLOCK_PLACEMENT,
USE_ITEM,
CUSTOM_CLICK_ACTION,
}
@@ -86,4 +86,9 @@ public class Particle<T extends ParticleData> {
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Particle[" + this.type.getName() + ", " + this.data + ']';
}
}
@@ -0,0 +1,77 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.particle.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
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.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public class ParticlePowerData extends ParticleData {
private float power;
public ParticlePowerData(float power) {
this.power = power;
}
public static ParticlePowerData read(PacketWrapper<?> wrapper) {
float power = wrapper.getServerVersion().isOlderThan(ServerVersion.V_1_21_9) ? 1f : wrapper.readFloat();
return new ParticlePowerData(power);
}
public static void write(PacketWrapper<?> wrapper, ParticlePowerData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
wrapper.writeFloat(data.power);
}
}
@ApiStatus.Internal
public static ParticlePowerData decode(NBTCompound tag, ClientVersion version) {
float power = tag.getNumberTagValueOrDefault("power", 1f).floatValue();
return new ParticlePowerData(power);
}
@ApiStatus.Internal
public static void encode(ParticlePowerData data, ClientVersion version, NBTCompound tag) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9) && data.power != 1f) {
tag.setTag("power", new NBTFloat(data.power));
}
}
@Override
public boolean isEmpty() {
return false;
}
public float getPower() {
return this.power;
}
public void setPower(float power) {
this.power = power;
}
}
@@ -0,0 +1,99 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.particle.data;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.color.Color;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* @version 1.21.9+
*/
@NullMarked
public class ParticleSpellData extends ParticleData {
private Color color;
private float power;
public ParticleSpellData(Color color, float power) {
this.color = color;
this.power = power;
}
public static ParticleSpellData read(PacketWrapper<?> wrapper) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
Color color = Color.read(wrapper);
float power = wrapper.readFloat();
return new ParticleSpellData(color, power);
}
return new ParticleSpellData(Color.WHITE, 1f);
}
public static void write(PacketWrapper<?> wrapper, ParticleSpellData data) {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
Color.write(wrapper, data.color);
wrapper.writeFloat(data.power);
}
}
@ApiStatus.Internal
public static ParticleSpellData decode(NBTCompound compound, ClientVersion version) {
Color color = compound.getOr("color", Color::decode, Color.WHITE, null);
float power = compound.getNumberTagValueOrDefault("power", 1f).floatValue();
return new ParticleSpellData(color, power);
}
@ApiStatus.Internal
public static void encode(ParticleSpellData data, ClientVersion version, NBTCompound compound) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9)) {
if (!Color.WHITE.equals(data.color)) {
compound.setTag("color", Color.encode(data.color, version));
}
if (data.power != 1f) {
compound.setTag("power", new NBTFloat(data.power));
}
}
}
@Override
public boolean isEmpty() {
return false;
}
public Color getColor() {
return this.color;
}
public void setColor(Color color) {
this.color = color;
}
public float getPower() {
return this.power;
}
public void setPower(float power) {
this.power = power;
}
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.particle.type;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleBlockStateData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleColorData;
@@ -25,8 +26,10 @@ import com.github.retrooper.packetevents.protocol.particle.data.ParticleData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleDustColorTransitionData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleDustData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleItemStackData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticlePowerData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleSculkChargeData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleShriekData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleSpellData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleTrailData;
import com.github.retrooper.packetevents.protocol.particle.data.ParticleVibrationData;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
@@ -102,7 +105,9 @@ public final class ParticleTypes {
public static final ParticleType<ParticleData> CLOUD = define("cloud");
public static final ParticleType<ParticleData> CRIT = define("crit");
public static final ParticleType<ParticleData> DAMAGE_INDICATOR = define("damage_indicator");
public static final ParticleType<ParticleData> DRAGON_BREATH = define("dragon_breath");
public static final ParticleType<ParticlePowerData> DRAGON_BREATH = define("dragon_breath",
ParticlePowerData::read, ParticlePowerData::write,
ParticlePowerData::decode, ParticlePowerData::encode);
public static final ParticleType<ParticleData> DRIPPING_LAVA = define("dripping_lava");
public static final ParticleType<ParticleData> FALLING_LAVA = define("falling_lava");
public static final ParticleType<ParticleData> LANDING_LAVA = define("landing_lava");
@@ -114,7 +119,9 @@ public final class ParticleTypes {
public static final ParticleType<ParticleDustColorTransitionData> DUST_COLOR_TRANSITION = define("dust_color_transition",
ParticleDustColorTransitionData::read, ParticleDustColorTransitionData::write,
ParticleDustColorTransitionData::decode, ParticleDustColorTransitionData::encode);
public static final ParticleType<ParticleData> EFFECT = define("effect");
public static final ParticleType<ParticleSpellData> EFFECT = define("effect",
ParticleSpellData::read, ParticleSpellData::write,
ParticleSpellData::decode, ParticleSpellData::encode);
public static final ParticleType<ParticleData> ELDER_GUARDIAN = define("elder_guardian");
public static final ParticleType<ParticleData> ENCHANTED_HIT = define("enchanted_hit");
public static final ParticleType<ParticleData> ENCHANT = define("enchant");
@@ -138,11 +145,32 @@ public final class ParticleTypes {
public static final ParticleType<ParticleData> SCULK_CHARGE_POP = define("sculk_charge_pop");
public static final ParticleType<ParticleData> SOUL_FIRE_FLAME = define("soul_fire_flame");
public static final ParticleType<ParticleData> SOUL = define("soul");
public static final ParticleType<ParticleData> FLASH = define("flash");
public static final ParticleType<ParticleColorData> FLASH = define("flash",
wrapper -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
return ParticleColorData.read(wrapper);
}
return new ParticleColorData(0);
}, (wrapper, data) -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21_9)) {
ParticleColorData.write(wrapper, data);
}
}, (compound, version) -> {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9)) {
return ParticleColorData.decode(compound, version);
}
return new ParticleColorData(0);
}, (data, version, compound) -> {
if (version.isNewerThanOrEquals(ClientVersion.V_1_21_9)) {
ParticleColorData.encode(data, version, compound);
}
});
public static final ParticleType<ParticleData> HAPPY_VILLAGER = define("happy_villager");
public static final ParticleType<ParticleData> COMPOSTER = define("composter");
public static final ParticleType<ParticleData> HEART = define("heart");
public static final ParticleType<ParticleData> INSTANT_EFFECT = define("instant_effect");
public static final ParticleType<ParticleSpellData> INSTANT_EFFECT = define("instant_effect",
ParticleSpellData::read, ParticleSpellData::write,
ParticleSpellData::decode, ParticleSpellData::encode);
public static final ParticleType<ParticleItemStackData> ITEM = define("item",
ParticleItemStackData::read, ParticleItemStackData::write,
ParticleItemStackData::decode, ParticleItemStackData::encode);
@@ -235,30 +263,36 @@ public final class ParticleTypes {
public static final ParticleType<ParticleData> OMINOUS_SPAWNING = define("ominous_spawning");
public static final ParticleType<ParticleData> RAID_OMEN = define("raid_omen");
public static final ParticleType<ParticleData> TRIAL_OMEN = define("trial_omen");
// added with 1.21.2
/**
* @versions 1.21.2+
*/
public static final ParticleType<ParticleTrailData> TRAIL = define("trail",
ParticleTrailData::read, ParticleTrailData::write,
ParticleTrailData::decode, ParticleTrailData::encode);
/**
* @versions 1.21.2+
*/
public static final ParticleType<ParticleBlockStateData> BLOCK_CRUMBLE = define("block_crumble",
ParticleBlockStateData::read, ParticleBlockStateData::write,
ParticleBlockStateData::decode, ParticleBlockStateData::encode);
/**
* Added with 1.21.4
* @versions 1.21.4+
*/
public static final ParticleType<ParticleData> PALE_OAK_LEAVES = define("pale_oak_leaves");
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final ParticleType<ParticleColorData> TINTED_LEAVES = define("tinted_leaves",
ParticleColorData::read, ParticleColorData::write,
ParticleColorData::decode, ParticleColorData::encode);
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final ParticleType<ParticleData> FIREFLY = define("firefly");
/**
* @versions 1.21.9+
*/
public static final ParticleType<ParticleData> COPPER_FIRE_FLAME = define("copper_fire_flame");
/**
* Returns an immutable view of the particle types.
@@ -108,14 +108,21 @@ public enum ClientVersion {
V_1_21_4(769),
V_1_21_5(770),
V_1_21_6(771),
/**
* 1.21.7 and 1.21.8 have the same protocol version.
*/
V_1_21_7(772),
/**
* 1.21.9 and 1.21.10 have the same protocol version.
*/
V_1_21_9(773),
//TODO UPDATE Add new protocol version field
@Deprecated
LOWER_THAN_SUPPORTED_VERSIONS(V_1_7_2.protocolVersion - 1, true),
//TODO UPDATE Update HIGHER_THAN_SUPPORTED_VERSIONS field
@Deprecated
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_21_7.protocolVersion + 1, true),
HIGHER_THAN_SUPPORTED_VERSIONS(V_1_21_9.protocolVersion + 1, true),
UNKNOWN(-1, true);
@@ -0,0 +1,54 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.player;
import com.github.retrooper.packetevents.protocol.util.CodecNameable;
import com.github.retrooper.packetevents.protocol.util.NbtCodec;
import com.github.retrooper.packetevents.protocol.util.NbtCodecs;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
@NullMarked
public enum PlayerModelType implements CodecNameable {
SLIM("slim"),
WIDE("wide"),
;
public static final NbtCodec<PlayerModelType> CODEC = NbtCodecs.forEnum(values());
private final String codecName;
PlayerModelType(String codecName) {
this.codecName = codecName;
}
public static PlayerModelType read(PacketWrapper<?> wrapper) {
return wrapper.readBoolean() ? SLIM : WIDE;
}
public static void write(PacketWrapper<?> wrapper, PlayerModelType type) {
wrapper.writeBoolean(type == SLIM);
}
@Override
public String getCodecName() {
return this.codecName;
}
}
@@ -2344,11 +2344,182 @@ public final class Sounds {
* Added with 1.21.6
*/
public static final Sound ITEM_SADDLE_UNEQUIP = define("item.saddle.unequip");
/**
* Added with 1.21.7
* @versions 1.21.7+
*/
public static final Sound MUSIC_DISC_LAVA_CHICKEN = define("music_disc.lava_chicken");
/**
* * @versions 1.21.9+
*/
public static final Sound ITEM_ARMOR_EQUIP_COPPER = define("item.armor.equip_copper");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_CHEST_CLOSE = define("block.copper_chest.close");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_CHEST_OPEN = define("block.copper_chest.open");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_CHEST_WEATHERED_CLOSE = define("block.copper_chest_weathered.close");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_CHEST_WEATHERED_OPEN = define("block.copper_chest_weathered.open");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_CHEST_OXIDIZED_CLOSE = define("block.copper_chest_oxidized.close");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_CHEST_OXIDIZED_OPEN = define("block.copper_chest_oxidized.open");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_STEP = define("entity.copper_golem.step");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_HURT = define("entity.copper_golem.hurt");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_DEATH = define("entity.copper_golem.death");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_WEATHERED_STEP = define("entity.copper_golem_weathered.step");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_WEATHERED_HURT = define("entity.copper_golem_weathered.hurt");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_WEATHERED_DEATH = define("entity.copper_golem_weathered.death");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_OXIDIZED_STEP = define("entity.copper_golem_oxidized.step");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_OXIDIZED_HURT = define("entity.copper_golem_oxidized.hurt");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_OXIDIZED_DEATH = define("entity.copper_golem_oxidized.death");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_SPIN = define("entity.copper_golem.spin");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_WEATHERED_SPIN = define("entity.copper_golem_weathered.spin");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_OXIDIZED_SPIN = define("entity.copper_golem_oxidized.spin");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_NO_ITEM_GET = define("entity.copper_golem.no_item_get");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_NO_ITEM_NO_GET = define("entity.copper_golem.no_item_no_get");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_ITEM_DROP = define("entity.copper_golem.item_drop");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_ITEM_NO_DROP = define("entity.copper_golem.item_no_drop");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_BECOME_STATUE = define("entity.copper_golem_become_statue");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_GOLEM_STATUE_BREAK = define("block.copper_golem_statue.break");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_GOLEM_STATUE_PLACE = define("block.copper_golem_statue.place");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_GOLEM_STATUE_HIT = define("block.copper_golem_statue.hit");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_GOLEM_STATUE_STEP = define("block.copper_golem_statue.step");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_COPPER_GOLEM_STATUE_FALL = define("block.copper_golem_statue.fall");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_SPAWN = define("entity.copper_golem.spawn");
/**
* @versions 1.21.9+
*/
public static final Sound ENTITY_COPPER_GOLEM_SHEAR = define("entity.copper_golem.shear");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_ACTIVATE = define("block.shelf.activate");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_BREAK = define("block.shelf.break");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_DEACTIVATE = define("block.shelf.deactivate");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_FALL = define("block.shelf.fall");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_HIT = define("block.shelf.hit");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_MULTI_SWAP = define("block.shelf.multi_swap");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_PLACE = define("block.shelf.place");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_PLACE_ITEM = define("block.shelf.place_item");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_SINGLE_SWAP = define("block.shelf.single_swap");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_STEP = define("block.shelf.step");
/**
* @versions 1.21.9+
*/
public static final Sound BLOCK_SHELF_TAKE_ITEM = define("block.shelf.take_item");
/**
* @versions 1.21.9+
*/
public static final Sound WEATHER_END_FLASH = define("weather.end_flash");
/**
* Returns an immutable view of the sounds.
@@ -0,0 +1,27 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.util;
import org.jspecify.annotations.NullMarked;
@NullMarked
public interface CodecNameable {
String getCodecName();
}
@@ -0,0 +1,96 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.util;
import com.github.retrooper.packetevents.util.MathUtil;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Less/low precision encoding/decoding for {@link Vector3d},
* introduced in Minecraft 1.21.9.
*/
@NullMarked
@ApiStatus.Internal
public final class LpVector3d {
private static final double ABS_MAX_VALUE = Double.longBitsToDouble(0x420FFFFFFFF80000L);
private static final double ABS_MIN_VALUE = Double.longBitsToDouble(0x3F00004001000400L);
private LpVector3d() {
}
public static Vector3d read(PacketWrapper<?> wrapper) {
int b0 = wrapper.readUnsignedByte();
if (b0 == 0) {
return Vector3d.zero();
}
long bits = b0 | ((long) wrapper.readUnsignedByte() << 8) | (wrapper.readUnsignedInt() << 16);
long max = b0 & 0b11L;
if ((b0 & 0b100L) != 0) {
// continuation bit is set, read more
max |= ((long) wrapper.readVarInt() & 0xFFFFFFFFL) << 2;
}
return new Vector3d(
unpack(bits >> 3) * (double) max,
unpack(bits >> 18) * (double) max,
unpack(bits >> 33) * (double) max
);
}
public static void write(PacketWrapper<?> wrapper, Vector3d vector) {
double x = sanitize(vector.x);
double y = sanitize(vector.y);
double z = sanitize(vector.z);
double max = MathUtil.absMax(x, MathUtil.absMax(y, z));
if (max < ABS_MIN_VALUE) {
wrapper.writeByte(0);
return;
}
long maxLong = MathUtil.ceilLong(max);
boolean large = (maxLong & 0b11L) != maxLong;
long mul = large ? ((maxLong & 0b11L) | 0b100L) : maxLong;
long packedX = pack(x / (double) maxLong) << 3;
long packedY = pack(y / (double) maxLong) << 18;
long packedZ = pack(z / (double) maxLong) << 33;
long bits = mul | packedX | packedY | packedZ;
wrapper.writeShortLE((short) bits);
wrapper.writeInt((int) (bits >> 16));
if (large) {
wrapper.writeVarInt((int) (maxLong >> 2));
}
}
private static double sanitize(double comp) {
if (!Double.isNaN(comp)) {
return MathUtil.clamp(comp, -ABS_MAX_VALUE, ABS_MAX_VALUE);
}
return 0d;
}
private static long pack(double comp) {
return Math.round((comp * 0.5d + 0.5d) * (double) ((1 << 15) - 2));
}
private static double unpack(long bits) {
return Math.min((double) (bits & ((1L << 15) - 1)), (double) ((1 << 15) - 2)) * 2d / (double) ((1 << 15) - 2) - 1d;
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.util;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
@NullMarked
public interface NbtCodec<T> extends NbtEncoder<T>, NbtDecoder<T> {
default <Z> NbtCodec<Z> apply(Function<T, Z> forward, Function<Z, T> back) {
return new NbtCodec<Z>() {
@Override
public Z decode(NBT nbt, PacketWrapper<?> wrapper) {
return forward.apply(NbtCodec.this.decode(nbt, wrapper));
}
@Override
public NBT encode(PacketWrapper<?> wrapper, Z value) {
return NbtCodec.this.encode(wrapper, back.apply(value));
}
};
}
default NbtCodec<List<T>> applyList() {
return new NbtCodec<List<T>>() {
@Override
public List<T> decode(NBT nbt, PacketWrapper<?> wrapper) {
List<? extends NBT> list = NbtCodecs.GENERIC_LIST.decode(nbt, wrapper);
List<T> ret = new ArrayList<>(list.size());
for (NBT tag : list) {
ret.add(NbtCodec.this.decode(tag, wrapper));
}
return ret;
}
@Override
public NBT encode(PacketWrapper<?> wrapper, List<T> value) {
List<NBT> list = new ArrayList<>(value.size());
for (T ele : value) {
list.add(NbtCodec.this.encode(wrapper, ele));
}
return NbtCodecs.GENERIC_LIST.encode(wrapper, list);
}
};
}
}
@@ -0,0 +1,198 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.util;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTByte;
import com.github.retrooper.packetevents.protocol.nbt.NBTByteArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTIntArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTLong;
import com.github.retrooper.packetevents.protocol.nbt.NBTLongArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import com.github.retrooper.packetevents.util.UniqueIdUtil;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@NullMarked
@ApiStatus.Experimental
public final class NbtCodecs {
public static final NbtCodec<String> STRING = new NbtCodec<String>() {
@Override
public String decode(NBT nbt, PacketWrapper<?> wrapper) {
return ((NBTString) nbt).getValue();
}
@Override
public NBT encode(PacketWrapper<?> wrapper, String value) {
return new NBTString(value);
}
};
public static final NbtCodec<List<String>> STRING_LIST = STRING.applyList();
// this is the part of codecs I absolutely hate... there are a billion possible ways
// to represent a single damn thing with nbt/codecs...
// this codec converts the billion possible ways into a simple list of tags (at the cost
// of creating way too many nbt tag objects)
public static final NbtCodec<List<? extends NBT>> GENERIC_LIST = new NbtCodec<List<? extends NBT>>() {
@Override
public List<? extends NBT> decode(NBT nbt, PacketWrapper<?> wrapper) {
if (nbt instanceof NBTList) {
return ((NBTList<?>) nbt).unwrapTags();
} else if (nbt instanceof NBTIntArray) {
int[] arr = ((NBTIntArray) nbt).getValue();
List<NBTInt> list = new ArrayList<>(arr.length);
for (int num : arr) {
list.add(new NBTInt(num));
}
return list;
} else if (nbt instanceof NBTByteArray) {
byte[] arr = ((NBTByteArray) nbt).getValue();
List<NBTByte> list = new ArrayList<>(arr.length);
for (byte num : arr) {
list.add(new NBTByte(num));
}
return list;
} else if (nbt instanceof NBTLongArray) {
long[] arr = ((NBTLongArray) nbt).getValue();
List<NBTLong> list = new ArrayList<>(arr.length);
for (long num : arr) {
list.add(new NBTLong(num));
}
return list;
}
throw new RuntimeException("Not a list: " + nbt);
}
@Override
public NBT encode(PacketWrapper<?> wrapper, List<? extends NBT> value) {
if (value.isEmpty()) {
return new NBTList<>(NBTType.END, 0);
}
NBTType<?> type = NBTList.getCommonTagType(value);
if (type == NBTType.COMPOUND) {
// possibly heterogeneous list, try to wrap everything
NBTList<NBTCompound> list = new NBTList<>(NBTType.COMPOUND, value.size());
for (NBT tag : value) {
list.addTagOrWrap(tag);
}
return list;
} else if (type == NBTType.INT) {
// encode as int array
int[] arr = new int[value.size()];
for (int i = 0; i < arr.length; i++) {
arr[i] = ((NBTInt) value.get(i)).getAsInt();
}
return new NBTIntArray(arr);
} else if (type == NBTType.BYTE) {
// encode as byte array
byte[] arr = new byte[value.size()];
for (int i = 0; i < arr.length; i++) {
arr[i] = ((NBTByte) value.get(i)).getAsByte();
}
return new NBTByteArray(arr);
} else if (type == NBTType.LONG) {
// encode as long array
long[] arr = new long[value.size()];
for (int i = 0; i < arr.length; i++) {
arr[i] = ((NBTLong) value.get(i)).getAsLong();
}
return new NBTLongArray(arr);
} else {
// a single common list type, simple to construct
@SuppressWarnings("unchecked") // doesn't matter at runtime
NBTList<?> list = new NBTList<>((NBTType<NBT>) type, (List<NBT>) value);
return list;
}
}
};
public static final NbtCodec<int[]> INT_ARRAY = new NbtCodec<int[]>() {
@Override
public int[] decode(NBT nbt, PacketWrapper<?> wrapper) {
if (nbt instanceof NBTIntArray) {
return ((NBTIntArray) nbt).getValue();
}
List<? extends NBT> list = GENERIC_LIST.decode(nbt, wrapper);
int size = list.size();
int[] array = new int[size];
for (int i = 0; i < size; i++) {
NBT tag = list.get(i);
if (!(tag instanceof NBTNumber)) {
throw new RuntimeException("Some elements are not numbers: " + list);
}
array[i] = ((NBTNumber) tag).getAsInt();
}
return array;
}
@Override
public NBT encode(PacketWrapper<?> wrapper, int[] value) {
return new NBTIntArray(value);
}
};
public static final NbtCodec<UUID> UUID = INT_ARRAY
.apply(UniqueIdUtil::fromIntArray, UniqueIdUtil::toIntArray);
private NbtCodecs() {
}
public static <T extends Enum<T> & CodecNameable> NbtCodec<T> forEnum(T[] values) {
return new NbtCodec<T>() {
private final Map<String, T> map = new HashMap<>(values.length);
{
for (T value : values) {
T existingValue = this.map.putIfAbsent(value.getCodecName(), value);
if (existingValue != null) {
throw new IllegalStateException("Can't create codec for enum with duplicate names: " + existingValue);
}
}
}
@Override
public T decode(NBT nbt, PacketWrapper<?> wrapper) {
String key = ((NBTString) nbt).getValue();
T value = this.map.get(key);
if (value == null) {
throw new RuntimeException("Can't find " + key + " in " + this.map.keySet());
}
return value;
}
@Override
public NBT encode(PacketWrapper<?> wrapper, T value) {
return new NBTString(value.getCodecName());
}
};
}
}
@@ -0,0 +1,82 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.util;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.ArrayList;
import java.util.List;
@NullMarked
public final class WeightedList<T> {
private final List<Entry<T>> entries;
public WeightedList() {
this(new ArrayList<>());
}
public WeightedList(List<Entry<T>> entries) {
this.entries = entries;
}
public static <T> WeightedList<T> read(PacketWrapper<?> wrapper, PacketWrapper.Reader<T> reader) {
List<Entry<T>> entries = wrapper.readList(ew -> Entry.read(wrapper, reader));
return new WeightedList<>(entries);
}
public static <T> void write(PacketWrapper<?> wrapper, WeightedList<T> list, PacketWrapper.Writer<T> writer) {
wrapper.writeList(list.entries, (ew, entry) -> Entry.write(ew, entry, writer));
}
public List<Entry<T>> getEntries() {
return this.entries;
}
public static final class Entry<T> {
private final int weight;
private final T value;
public Entry(int weight, T value) {
this.weight = weight;
this.value = value;
}
public static <T> Entry<T> read(PacketWrapper<?> wrapper, PacketWrapper.Reader<T> reader) {
int weight = wrapper.readVarInt();
T value = reader.apply(wrapper);
return new Entry<>(weight, value);
}
public static <T> void write(PacketWrapper<?> wrapper, Entry<T> entry, PacketWrapper.Writer<T> writer) {
wrapper.writeVarInt(entry.weight);
writer.accept(wrapper, entry.value);
}
public int getWeight() {
return this.weight;
}
public T getValue() {
return this.value;
}
}
}
@@ -0,0 +1,81 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.world;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
@NullMarked
public final class BlockBoundingBox {
private final int minX;
private final int minY;
private final int minZ;
private final int maxX;
private final int maxY;
private final int maxZ;
public BlockBoundingBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
this.minX = Math.min(minX, maxX);
this.minY = Math.min(minY, maxY);
this.minZ = Math.min(minZ, maxZ);
this.maxX = Math.max(maxX, minX);
this.maxY = Math.max(maxY, minY);
this.maxZ = Math.max(maxZ, minZ);
}
public static BlockBoundingBox read(PacketWrapper<?> wrapper) {
Vector3i minPos = wrapper.readBlockPosition();
Vector3i maxPos = wrapper.readBlockPosition();
return new BlockBoundingBox(
minPos.x, minPos.y, minPos.z,
maxPos.x, maxPos.y, maxPos.z
);
}
public static void write(PacketWrapper<?> wrapper, BlockBoundingBox box) {
wrapper.writeBlockPosition(new Vector3i(box.minX, box.minY, box.minZ));
wrapper.writeBlockPosition(new Vector3i(box.maxX, box.maxY, box.maxZ));
}
public int getMinX() {
return this.minX;
}
public int getMinY() {
return this.minY;
}
public int getMinZ() {
return this.minZ;
}
public int getMaxX() {
return this.maxX;
}
public int getMaxY() {
return this.maxY;
}
public int getMaxZ() {
return this.maxZ;
}
}
@@ -19,16 +19,16 @@
package com.github.retrooper.packetevents.protocol.world;
import com.github.retrooper.packetevents.protocol.world.states.enums.Axis;
import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.util.Vector3i;
// From MCProtocolLib
public enum Direction {
DOWN(-1, Axis.Z, new Vector3i(0 , -1, 0)),
UP(-1, Axis.Z, new Vector3i(0, 1, 0)),
NORTH(0, Axis.Y, new Vector3i(0 , 0, -1)),
SOUTH(1, Axis.Y, new Vector3i(0 ,0 ,1)),
WEST(2, Axis.X, new Vector3i(-1, 0 ,0)),
DOWN(-1, Axis.Y, new Vector3i(0, -1, 0)),
UP(-1, Axis.Y, new Vector3i(0, 1, 0)),
NORTH(0, Axis.Z, new Vector3i(0, 0, -1)),
SOUTH(1, Axis.Z, new Vector3i(0, 0, 1)),
WEST(2, Axis.X, new Vector3i(-1, 0, 0)),
EAST(3, Axis.X, new Vector3i(1, 0, 0));
private final int horizontalIndex;
@@ -63,4 +63,4 @@ public enum Direction {
public Axis getAxis() {
return this.axis;
}
}
}
@@ -24,6 +24,9 @@ import com.github.retrooper.packetevents.util.Vector3i;
import org.jetbrains.annotations.NotNull;
public class WorldBlockPosition {
public static final ResourceLocation OVERWORLD_DIMENSION = ResourceLocation.minecraft("overworld");
private ResourceLocation world;
private Vector3i blockPosition;
@@ -95,19 +95,28 @@ public final class BlockEntityTypes {
public static final BlockEntityType VAULT = define("vault");
/**
* Added with 1.21.2
* @versions 1.21.2+
*/
public static final BlockEntityType CREAKING_HEART = define("creaking_heart");
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final BlockEntityType TEST_BLOCK = define("test_block");
/**
* Added with 1.21.5
* @versions 1.21.5+
*/
public static final BlockEntityType TEST_INSTANCE_BLOCK = define("test_instance_block");
/**
* @versions 1.21.9+
*/
public static final BlockEntityType SHELF = define("shelf");
/**
* @versions 1.21.9+
*/
public static final BlockEntityType COPPER_GOLEM_STATUE = define("copper_golem_statue");
/**
* Returns an immutable view of the block entity types.
*
@@ -27,6 +27,8 @@ package com.github.retrooper.packetevents.protocol.world.chunk.palette;
import com.github.retrooper.packetevents.protocol.stream.NetStreamInput;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Arrays;
/**
* A palette backed by a List.
*/
@@ -35,11 +37,12 @@ public class ListPalette implements Palette {
private final int bits;
private final int[] data;
private int nextId = 0;
private int nextId;
public ListPalette(int bitsPerEntry) {
this.bits = bitsPerEntry;
this.data = new int[1 << bitsPerEntry];
this.nextId = 0;
}
@Deprecated
@@ -63,6 +66,17 @@ public class ListPalette implements Palette {
this.nextId = paletteLength;
}
public ListPalette(int bitsPerEntry, int[] data) {
this.bits = bitsPerEntry;
final int expectedSize = (1 << this.bits);
if (data.length > expectedSize) {
throw new IllegalArgumentException("Data length exceeds the max size the bits can hold");
} else {
this.data = Arrays.copyOf(data, expectedSize);
}
this.nextId = data.length;
}
@Override
public int size() {
return this.nextId;
@@ -72,7 +72,7 @@ public class WrappedBlockState {
ClientVersion.V_1_16, ClientVersion.V_1_16_2, ClientVersion.V_1_17, ClientVersion.V_1_19,
ClientVersion.V_1_19_3, ClientVersion.V_1_19_4, ClientVersion.V_1_20, ClientVersion.V_1_20_2,
ClientVersion.V_1_20_3, ClientVersion.V_1_20_5, ClientVersion.V_1_21_2, ClientVersion.V_1_21_4,
ClientVersion.V_1_21_5, ClientVersion.V_1_21_6,
ClientVersion.V_1_21_5, ClientVersion.V_1_21_6, ClientVersion.V_1_21_9,
};
private static final byte[] MAPPING_INDEXES;
private static final ClientVersion[] MAPPING_VERSIONS;
@@ -1569,10 +1569,7 @@ public class WrappedBlockState {
}
/**
* This method is helpful if you want to check if a block can be
* waterlogged, or has other properties.
* <p>
* Unless you know what you are doing exactly, don't touch this method!
* Unless you know exactly what you are doing, don't touch this method!
* It can result in invalid block types when modified directly
*/
@Deprecated
@@ -1580,6 +1577,10 @@ public class WrappedBlockState {
return data;
}
public boolean hasProperty(StateValue property) {
return data.containsKey(property);
}
/**
* Global ID
* For pre-1.13: 4 bits of block data, 4 bits empty, 8 bits block type
@@ -336,6 +336,43 @@ public class BlockTags {
*/
public static final BlockTags TRIGGERS_AMBIENT_DESERT_DRY_VEGETATION_BLOCK_SOUNDS = bind("triggers_ambient_desert_dry_vegetation_block_sounds");
/**
* @versions 1.21.9+
*/
public static final BlockTags WOODEN_SHELVES = bind("wooden_shelves");
/**
* @versions 1.21.9+
*/
public static final BlockTags COPPER_CHESTS = bind("copper_chests");
/**
* @versions 1.21.9+
*/
public static final BlockTags LIGHTNING_RODS = bind("lightning_rods");
/**
* @versions 1.21.9+
*/
public static final BlockTags COPPER = bind("copper");
/**
* @versions 1.21.9+
*/
public static final BlockTags CHAINS = bind("chains");
/**
* @versions 1.21.9+
*/
public static final BlockTags COPPER_GOLEM_STATUES = bind("copper_golem_statues");
/**
* @versions 1.21.9+
*/
public static final BlockTags LANTERNS = bind("lanterns");
/**
* @versions 1.21.9+
*/
public static final BlockTags BARS = bind("bars");
/**
* @versions 1.21.9+
*/
public static final BlockTags INCORRECT_FOR_COPPER_TOOL = bind("incorrect_for_copper_tool");
/**
* Unofficial tag for all glass blocks
*/
@@ -366,6 +403,7 @@ public class BlockTags {
BlockTags.WOODEN_FENCES.add(StateTypes.OAK_FENCE, StateTypes.ACACIA_FENCE, StateTypes.DARK_OAK_FENCE, StateTypes.PALE_OAK_FENCE, StateTypes.SPRUCE_FENCE, StateTypes.BIRCH_FENCE, StateTypes.JUNGLE_FENCE, StateTypes.CRIMSON_FENCE, StateTypes.WARPED_FENCE, StateTypes.MANGROVE_FENCE, StateTypes.BAMBOO_FENCE, StateTypes.CHERRY_FENCE);
BlockTags.FENCE_GATES.add(StateTypes.ACACIA_FENCE_GATE, StateTypes.BIRCH_FENCE_GATE, StateTypes.DARK_OAK_FENCE_GATE, StateTypes.PALE_OAK_FENCE_GATE, StateTypes.JUNGLE_FENCE_GATE, StateTypes.OAK_FENCE_GATE, StateTypes.SPRUCE_FENCE_GATE, StateTypes.CRIMSON_FENCE_GATE, StateTypes.WARPED_FENCE_GATE, StateTypes.MANGROVE_FENCE_GATE, StateTypes.BAMBOO_FENCE_GATE, StateTypes.CHERRY_FENCE_GATE);
BlockTags.WOODEN_PRESSURE_PLATES.add(StateTypes.OAK_PRESSURE_PLATE, StateTypes.SPRUCE_PRESSURE_PLATE, StateTypes.BIRCH_PRESSURE_PLATE, StateTypes.JUNGLE_PRESSURE_PLATE, StateTypes.ACACIA_PRESSURE_PLATE, StateTypes.DARK_OAK_PRESSURE_PLATE, StateTypes.PALE_OAK_PRESSURE_PLATE, StateTypes.CRIMSON_PRESSURE_PLATE, StateTypes.WARPED_PRESSURE_PLATE, StateTypes.MANGROVE_PRESSURE_PLATE, StateTypes.BAMBOO_PRESSURE_PLATE, StateTypes.CHERRY_PRESSURE_PLATE);
BlockTags.WOODEN_SHELVES.add(StateTypes.ACACIA_SHELF, StateTypes.BAMBOO_SHELF, StateTypes.BIRCH_SHELF, StateTypes.CHERRY_SHELF, StateTypes.CRIMSON_SHELF, StateTypes.DARK_OAK_SHELF, StateTypes.JUNGLE_SHELF, StateTypes.MANGROVE_SHELF, StateTypes.OAK_SHELF, StateTypes.PALE_OAK_SHELF, StateTypes.SPRUCE_SHELF, StateTypes.WARPED_SHELF);
BlockTags.SAPLINGS.add(StateTypes.OAK_SAPLING, StateTypes.SPRUCE_SAPLING, StateTypes.BIRCH_SAPLING, StateTypes.JUNGLE_SAPLING, StateTypes.ACACIA_SAPLING, StateTypes.DARK_OAK_SAPLING, StateTypes.PALE_OAK_SAPLING, StateTypes.AZALEA, StateTypes.FLOWERING_AZALEA, StateTypes.MANGROVE_PROPAGULE, StateTypes.CHERRY_SAPLING);
BlockTags.BAMBOO_BLOCKS.add(StateTypes.BAMBOO_BLOCK, StateTypes.STRIPPED_BAMBOO_BLOCK);
BlockTags.OAK_LOGS.add(StateTypes.OAK_LOG, StateTypes.OAK_WOOD, StateTypes.STRIPPED_OAK_LOG, StateTypes.STRIPPED_OAK_WOOD);
@@ -402,6 +440,13 @@ public class BlockTags {
BlockTags.DIRT.add(StateTypes.DIRT, StateTypes.GRASS_BLOCK, StateTypes.PODZOL, StateTypes.COARSE_DIRT, StateTypes.MYCELIUM, StateTypes.ROOTED_DIRT, StateTypes.MOSS_BLOCK, StateTypes.PALE_MOSS_BLOCK, StateTypes.MUD, StateTypes.MUDDY_MANGROVE_ROOTS);
BlockTags.TERRACOTTA.add(StateTypes.TERRACOTTA, StateTypes.WHITE_TERRACOTTA, StateTypes.ORANGE_TERRACOTTA, StateTypes.MAGENTA_TERRACOTTA, StateTypes.LIGHT_BLUE_TERRACOTTA, StateTypes.YELLOW_TERRACOTTA, StateTypes.LIME_TERRACOTTA, StateTypes.PINK_TERRACOTTA, StateTypes.GRAY_TERRACOTTA, StateTypes.LIGHT_GRAY_TERRACOTTA, StateTypes.CYAN_TERRACOTTA, StateTypes.PURPLE_TERRACOTTA, StateTypes.BLUE_TERRACOTTA, StateTypes.BROWN_TERRACOTTA, StateTypes.GREEN_TERRACOTTA, StateTypes.RED_TERRACOTTA, StateTypes.BLACK_TERRACOTTA);
BlockTags.SHULKER_BOXES.add(StateTypes.SHULKER_BOX, StateTypes.BLACK_SHULKER_BOX, StateTypes.BLUE_SHULKER_BOX, StateTypes.BROWN_SHULKER_BOX, StateTypes.CYAN_SHULKER_BOX, StateTypes.GRAY_SHULKER_BOX, StateTypes.GREEN_SHULKER_BOX, StateTypes.LIGHT_BLUE_SHULKER_BOX, StateTypes.LIGHT_GRAY_SHULKER_BOX, StateTypes.LIME_SHULKER_BOX, StateTypes.MAGENTA_SHULKER_BOX, StateTypes.ORANGE_SHULKER_BOX, StateTypes.PINK_SHULKER_BOX, StateTypes.PURPLE_SHULKER_BOX, StateTypes.RED_SHULKER_BOX, StateTypes.WHITE_SHULKER_BOX, StateTypes.YELLOW_SHULKER_BOX);
BlockTags.COPPER_CHESTS.add(StateTypes.COPPER_CHEST, StateTypes.EXPOSED_COPPER_CHEST, StateTypes.WEATHERED_COPPER_CHEST, StateTypes.OXIDIZED_COPPER_CHEST, StateTypes.WAXED_COPPER_CHEST, StateTypes.WAXED_EXPOSED_COPPER_CHEST, StateTypes.WAXED_WEATHERED_COPPER_CHEST, StateTypes.WAXED_OXIDIZED_COPPER_CHEST);
BlockTags.LIGHTNING_RODS.add(StateTypes.LIGHTNING_ROD, StateTypes.EXPOSED_LIGHTNING_ROD, StateTypes.WEATHERED_LIGHTNING_ROD, StateTypes.OXIDIZED_LIGHTNING_ROD, StateTypes.WAXED_LIGHTNING_ROD, StateTypes.WAXED_EXPOSED_LIGHTNING_ROD, StateTypes.WAXED_WEATHERED_LIGHTNING_ROD, StateTypes.WAXED_OXIDIZED_LIGHTNING_ROD);
BlockTags.COPPER.add(StateTypes.COPPER_BLOCK, StateTypes.EXPOSED_COPPER, StateTypes.WEATHERED_COPPER, StateTypes.OXIDIZED_COPPER, StateTypes.WAXED_COPPER_BLOCK, StateTypes.WAXED_EXPOSED_COPPER, StateTypes.WAXED_WEATHERED_COPPER, StateTypes.WAXED_OXIDIZED_COPPER);
BlockTags.CHAINS.add(StateTypes.IRON_CHAIN, StateTypes.COPPER_CHAIN, StateTypes.WAXED_COPPER_CHAIN, StateTypes.EXPOSED_COPPER_CHAIN, StateTypes.WAXED_EXPOSED_COPPER_CHAIN, StateTypes.WEATHERED_COPPER_CHAIN, StateTypes.WAXED_WEATHERED_COPPER_CHAIN, StateTypes.OXIDIZED_COPPER_CHAIN, StateTypes.WAXED_OXIDIZED_COPPER_CHAIN);
BlockTags.COPPER_GOLEM_STATUES.add(StateTypes.COPPER_GOLEM_STATUE, StateTypes.EXPOSED_COPPER_GOLEM_STATUE, StateTypes.WEATHERED_COPPER_GOLEM_STATUE, StateTypes.OXIDIZED_COPPER_GOLEM_STATUE, StateTypes.WAXED_COPPER_GOLEM_STATUE, StateTypes.WAXED_EXPOSED_COPPER_GOLEM_STATUE, StateTypes.WAXED_WEATHERED_COPPER_GOLEM_STATUE, StateTypes.WAXED_OXIDIZED_COPPER_GOLEM_STATUE);
BlockTags.LANTERNS.add(StateTypes.LANTERN, StateTypes.SOUL_LANTERN, StateTypes.COPPER_LANTERN, StateTypes.WAXED_COPPER_LANTERN, StateTypes.EXPOSED_COPPER_LANTERN, StateTypes.WAXED_EXPOSED_COPPER_LANTERN, StateTypes.WEATHERED_COPPER_LANTERN, StateTypes.WAXED_WEATHERED_COPPER_LANTERN, StateTypes.OXIDIZED_COPPER_LANTERN, StateTypes.WAXED_OXIDIZED_COPPER_LANTERN);
BlockTags.BARS.add(StateTypes.IRON_BARS, StateTypes.COPPER_BARS, StateTypes.WAXED_COPPER_BARS, StateTypes.EXPOSED_COPPER_BARS, StateTypes.WAXED_EXPOSED_COPPER_BARS, StateTypes.WEATHERED_COPPER_BARS, StateTypes.WAXED_WEATHERED_COPPER_BARS, StateTypes.OXIDIZED_COPPER_BARS, StateTypes.WAXED_OXIDIZED_COPPER_BARS);
BlockTags.CEILING_HANGING_SIGNS.add(StateTypes.OAK_HANGING_SIGN, StateTypes.SPRUCE_HANGING_SIGN, StateTypes.BIRCH_HANGING_SIGN, StateTypes.ACACIA_HANGING_SIGN, StateTypes.CHERRY_HANGING_SIGN, StateTypes.JUNGLE_HANGING_SIGN, StateTypes.DARK_OAK_HANGING_SIGN, StateTypes.PALE_OAK_HANGING_SIGN, StateTypes.CRIMSON_HANGING_SIGN, StateTypes.WARPED_HANGING_SIGN, StateTypes.MANGROVE_HANGING_SIGN, StateTypes.BAMBOO_HANGING_SIGN);
BlockTags.STANDING_SIGNS.add(StateTypes.OAK_SIGN, StateTypes.SPRUCE_SIGN, StateTypes.BIRCH_SIGN, StateTypes.ACACIA_SIGN, StateTypes.JUNGLE_SIGN, StateTypes.DARK_OAK_SIGN, StateTypes.PALE_OAK_SIGN, StateTypes.CRIMSON_SIGN, StateTypes.WARPED_SIGN, StateTypes.MANGROVE_SIGN, StateTypes.BAMBOO_SIGN, StateTypes.CHERRY_SIGN);
BlockTags.BEE_ATTRACTIVE.add(StateTypes.DANDELION, StateTypes.OPEN_EYEBLOSSOM, StateTypes.POPPY, StateTypes.BLUE_ORCHID, StateTypes.ALLIUM, StateTypes.AZURE_BLUET, StateTypes.RED_TULIP, StateTypes.ORANGE_TULIP, StateTypes.WHITE_TULIP, StateTypes.PINK_TULIP, StateTypes.OXEYE_DAISY, StateTypes.CORNFLOWER, StateTypes.LILY_OF_THE_VALLEY, StateTypes.WITHER_ROSE, StateTypes.TORCHFLOWER, StateTypes.SUNFLOWER, StateTypes.LILAC, StateTypes.PEONY, StateTypes.ROSE_BUSH, StateTypes.PITCHER_PLANT, StateTypes.FLOWERING_AZALEA_LEAVES, StateTypes.FLOWERING_AZALEA, StateTypes.MANGROVE_PROPAGULE, StateTypes.CHERRY_LEAVES, StateTypes.PINK_PETALS, StateTypes.WILDFLOWERS, StateTypes.CHORUS_FLOWER, StateTypes.SPORE_BLOSSOM, StateTypes.CACTUS_FLOWER);
@@ -414,7 +459,7 @@ public class BlockTags {
BlockTags.FLOWER_POTS.add(StateTypes.FLOWER_POT, StateTypes.POTTED_OPEN_EYEBLOSSOM, StateTypes.POTTED_CLOSED_EYEBLOSSOM, StateTypes.POTTED_POPPY, StateTypes.POTTED_BLUE_ORCHID, StateTypes.POTTED_ALLIUM, StateTypes.POTTED_AZURE_BLUET, StateTypes.POTTED_RED_TULIP, StateTypes.POTTED_ORANGE_TULIP, StateTypes.POTTED_WHITE_TULIP, StateTypes.POTTED_PINK_TULIP, StateTypes.POTTED_OXEYE_DAISY, StateTypes.POTTED_DANDELION, StateTypes.POTTED_OAK_SAPLING, StateTypes.POTTED_SPRUCE_SAPLING, StateTypes.POTTED_BIRCH_SAPLING, StateTypes.POTTED_JUNGLE_SAPLING, StateTypes.POTTED_ACACIA_SAPLING, StateTypes.POTTED_DARK_OAK_SAPLING, StateTypes.POTTED_PALE_OAK_SAPLING, StateTypes.POTTED_RED_MUSHROOM, StateTypes.POTTED_BROWN_MUSHROOM, StateTypes.POTTED_DEAD_BUSH, StateTypes.POTTED_FERN, StateTypes.POTTED_CACTUS, StateTypes.POTTED_CORNFLOWER, StateTypes.POTTED_LILY_OF_THE_VALLEY, StateTypes.POTTED_WITHER_ROSE, StateTypes.POTTED_BAMBOO, StateTypes.POTTED_CRIMSON_FUNGUS, StateTypes.POTTED_WARPED_FUNGUS, StateTypes.POTTED_CRIMSON_ROOTS, StateTypes.POTTED_WARPED_ROOTS, StateTypes.POTTED_AZALEA_BUSH, StateTypes.POTTED_FLOWERING_AZALEA_BUSH, StateTypes.POTTED_MANGROVE_PROPAGULE, StateTypes.POTTED_CHERRY_SAPLING, StateTypes.POTTED_TORCHFLOWER);
BlockTags.ICE.add(StateTypes.ICE, StateTypes.PACKED_ICE, StateTypes.BLUE_ICE, StateTypes.FROSTED_ICE);
BlockTags.VALID_SPAWN.add(StateTypes.GRASS_BLOCK, StateTypes.PODZOL);
BlockTags.IMPERMEABLE.add(StateTypes.GLASS, StateTypes.WHITE_STAINED_GLASS, StateTypes.ORANGE_STAINED_GLASS, StateTypes.MAGENTA_STAINED_GLASS, StateTypes.LIGHT_BLUE_STAINED_GLASS, StateTypes.YELLOW_STAINED_GLASS, StateTypes.LIME_STAINED_GLASS, StateTypes.PINK_STAINED_GLASS, StateTypes.GRAY_STAINED_GLASS, StateTypes.LIGHT_GRAY_STAINED_GLASS, StateTypes.CYAN_STAINED_GLASS, StateTypes.PURPLE_STAINED_GLASS, StateTypes.BLUE_STAINED_GLASS, StateTypes.BROWN_STAINED_GLASS, StateTypes.GREEN_STAINED_GLASS, StateTypes.RED_STAINED_GLASS, StateTypes.BLACK_STAINED_GLASS, StateTypes.TINTED_GLASS);
BlockTags.IMPERMEABLE.add(StateTypes.GLASS, StateTypes.WHITE_STAINED_GLASS, StateTypes.ORANGE_STAINED_GLASS, StateTypes.MAGENTA_STAINED_GLASS, StateTypes.LIGHT_BLUE_STAINED_GLASS, StateTypes.YELLOW_STAINED_GLASS, StateTypes.LIME_STAINED_GLASS, StateTypes.PINK_STAINED_GLASS, StateTypes.GRAY_STAINED_GLASS, StateTypes.LIGHT_GRAY_STAINED_GLASS, StateTypes.CYAN_STAINED_GLASS, StateTypes.PURPLE_STAINED_GLASS, StateTypes.BLUE_STAINED_GLASS, StateTypes.BROWN_STAINED_GLASS, StateTypes.GREEN_STAINED_GLASS, StateTypes.RED_STAINED_GLASS, StateTypes.BLACK_STAINED_GLASS, StateTypes.TINTED_GLASS, StateTypes.BARRIER);
BlockTags.CORAL_BLOCKS.add(StateTypes.TUBE_CORAL_BLOCK, StateTypes.BRAIN_CORAL_BLOCK, StateTypes.BUBBLE_CORAL_BLOCK, StateTypes.FIRE_CORAL_BLOCK, StateTypes.HORN_CORAL_BLOCK);
BlockTags.WALL_CORALS.add(StateTypes.TUBE_CORAL_WALL_FAN, StateTypes.BRAIN_CORAL_WALL_FAN, StateTypes.BUBBLE_CORAL_WALL_FAN, StateTypes.FIRE_CORAL_WALL_FAN, StateTypes.HORN_CORAL_WALL_FAN);
BlockTags.CORAL_PLANTS.add(StateTypes.TUBE_CORAL, StateTypes.BRAIN_CORAL, StateTypes.BUBBLE_CORAL, StateTypes.FIRE_CORAL, StateTypes.HORN_CORAL);
@@ -452,7 +497,6 @@ public class BlockTags {
BlockTags.SWORD_INSTANTLY_MINES.add(StateTypes.BAMBOO, StateTypes.BAMBOO_SAPLING);
BlockTags.NEEDS_DIAMOND_TOOL.add(StateTypes.OBSIDIAN, StateTypes.CRYING_OBSIDIAN, StateTypes.NETHERITE_BLOCK, StateTypes.RESPAWN_ANCHOR, StateTypes.ANCIENT_DEBRIS);
BlockTags.NEEDS_IRON_TOOL.add(StateTypes.DIAMOND_BLOCK, StateTypes.DIAMOND_ORE, StateTypes.DEEPSLATE_DIAMOND_ORE, StateTypes.EMERALD_ORE, StateTypes.DEEPSLATE_EMERALD_ORE, StateTypes.EMERALD_BLOCK, StateTypes.GOLD_BLOCK, StateTypes.RAW_GOLD_BLOCK, StateTypes.GOLD_ORE, StateTypes.DEEPSLATE_GOLD_ORE, StateTypes.REDSTONE_ORE, StateTypes.DEEPSLATE_REDSTONE_ORE);
BlockTags.NEEDS_STONE_TOOL.add(StateTypes.IRON_BLOCK, StateTypes.RAW_IRON_BLOCK, StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE, StateTypes.LAPIS_BLOCK, StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE, StateTypes.COPPER_BLOCK, StateTypes.RAW_COPPER_BLOCK, StateTypes.COPPER_ORE, StateTypes.DEEPSLATE_COPPER_ORE, StateTypes.CUT_COPPER_SLAB, StateTypes.CUT_COPPER_STAIRS, StateTypes.CUT_COPPER, StateTypes.WEATHERED_COPPER, StateTypes.WEATHERED_CUT_COPPER_SLAB, StateTypes.WEATHERED_CUT_COPPER_STAIRS, StateTypes.WEATHERED_CUT_COPPER, StateTypes.OXIDIZED_COPPER, StateTypes.OXIDIZED_CUT_COPPER_SLAB, StateTypes.OXIDIZED_CUT_COPPER_STAIRS, StateTypes.OXIDIZED_CUT_COPPER, StateTypes.EXPOSED_COPPER, StateTypes.EXPOSED_CUT_COPPER_SLAB, StateTypes.EXPOSED_CUT_COPPER_STAIRS, StateTypes.EXPOSED_CUT_COPPER, StateTypes.WAXED_COPPER_BLOCK, StateTypes.WAXED_CUT_COPPER_SLAB, StateTypes.WAXED_CUT_COPPER_STAIRS, StateTypes.WAXED_CUT_COPPER, StateTypes.WAXED_WEATHERED_COPPER, StateTypes.WAXED_WEATHERED_CUT_COPPER_SLAB, StateTypes.WAXED_WEATHERED_CUT_COPPER_STAIRS, StateTypes.WAXED_WEATHERED_CUT_COPPER, StateTypes.WAXED_EXPOSED_COPPER, StateTypes.WAXED_EXPOSED_CUT_COPPER_SLAB, StateTypes.WAXED_EXPOSED_CUT_COPPER_STAIRS, StateTypes.WAXED_EXPOSED_CUT_COPPER, StateTypes.WAXED_OXIDIZED_COPPER, StateTypes.WAXED_OXIDIZED_CUT_COPPER_SLAB, StateTypes.WAXED_OXIDIZED_CUT_COPPER_STAIRS, StateTypes.WAXED_OXIDIZED_CUT_COPPER, StateTypes.LIGHTNING_ROD, StateTypes.CRAFTER, StateTypes.CHISELED_COPPER, StateTypes.EXPOSED_CHISELED_COPPER, StateTypes.WEATHERED_CHISELED_COPPER, StateTypes.OXIDIZED_CHISELED_COPPER, StateTypes.WAXED_CHISELED_COPPER, StateTypes.WAXED_EXPOSED_CHISELED_COPPER, StateTypes.WAXED_WEATHERED_CHISELED_COPPER, StateTypes.WAXED_OXIDIZED_CHISELED_COPPER, StateTypes.COPPER_GRATE, StateTypes.EXPOSED_COPPER_GRATE, StateTypes.WEATHERED_COPPER_GRATE, StateTypes.OXIDIZED_COPPER_GRATE, StateTypes.WAXED_COPPER_GRATE, StateTypes.WAXED_EXPOSED_COPPER_GRATE, StateTypes.WAXED_WEATHERED_COPPER_GRATE, StateTypes.WAXED_OXIDIZED_COPPER_GRATE, StateTypes.COPPER_BULB, StateTypes.EXPOSED_COPPER_BULB, StateTypes.WEATHERED_COPPER_BULB, StateTypes.OXIDIZED_COPPER_BULB, StateTypes.WAXED_COPPER_BULB, StateTypes.WAXED_EXPOSED_COPPER_BULB, StateTypes.WAXED_WEATHERED_COPPER_BULB, StateTypes.WAXED_OXIDIZED_COPPER_BULB, StateTypes.COPPER_TRAPDOOR, StateTypes.EXPOSED_COPPER_TRAPDOOR, StateTypes.WEATHERED_COPPER_TRAPDOOR, StateTypes.OXIDIZED_COPPER_TRAPDOOR, StateTypes.WAXED_COPPER_TRAPDOOR, StateTypes.WAXED_EXPOSED_COPPER_TRAPDOOR, StateTypes.WAXED_WEATHERED_COPPER_TRAPDOOR, StateTypes.WAXED_OXIDIZED_COPPER_TRAPDOOR);
copy(null, BlockTags.INCORRECT_FOR_NETHERITE_TOOL);
copy(null, BlockTags.INCORRECT_FOR_DIAMOND_TOOL);
BlockTags.FEATURES_CANNOT_REPLACE.add(StateTypes.BEDROCK, StateTypes.SPAWNER, StateTypes.CHEST, StateTypes.END_PORTAL_FRAME, StateTypes.REINFORCED_DEEPSLATE, StateTypes.TRIAL_SPAWNER, StateTypes.VAULT);
@@ -503,7 +547,7 @@ public class BlockTags {
BlockTags.DRAGON_TRANSPARENT.addTag(BlockTags.FIRE).add(StateTypes.LIGHT);
BlockTags.BEE_GROWABLES.addTag(BlockTags.CROPS).add(StateTypes.SWEET_BERRY_BUSH, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT);
BlockTags.FALL_DAMAGE_RESETTING.addTag(BlockTags.CLIMBABLE).add(StateTypes.SWEET_BERRY_BUSH, StateTypes.COBWEB);
BlockTags.GUARDED_BY_PIGLINS.addTag(BlockTags.SHULKER_BOXES).addTag(BlockTags.GOLD_ORES).add(StateTypes.GOLD_BLOCK, StateTypes.BARREL, StateTypes.CHEST, StateTypes.ENDER_CHEST, StateTypes.GILDED_BLACKSTONE, StateTypes.TRAPPED_CHEST, StateTypes.RAW_GOLD_BLOCK);
BlockTags.GUARDED_BY_PIGLINS.addTag(BlockTags.COPPER_CHESTS).addTag(BlockTags.SHULKER_BOXES).addTag(BlockTags.GOLD_ORES).add(StateTypes.GOLD_BLOCK, StateTypes.BARREL, StateTypes.CHEST, StateTypes.ENDER_CHEST, StateTypes.GILDED_BLACKSTONE, StateTypes.TRAPPED_CHEST, StateTypes.RAW_GOLD_BLOCK);
BlockTags.PREVENT_MOB_SPAWNING_INSIDE.addTag(BlockTags.RAILS);
BlockTags.UNSTABLE_BOTTOM_CENTER.addTag(BlockTags.FENCE_GATES);
BlockTags.INFINIBURN_NETHER.addTag(BlockTags.INFINIBURN_OVERWORLD);
@@ -518,13 +562,13 @@ public class BlockTags {
BlockTags.AZALEA_ROOT_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.DIRT).addTag(BlockTags.TERRACOTTA).add(StateTypes.RED_SAND, StateTypes.CLAY, StateTypes.GRAVEL, StateTypes.SAND, StateTypes.SNOW_BLOCK, StateTypes.POWDER_SNOW);
BlockTags.BIG_DRIPLEAF_PLACEABLE.addTag(BlockTags.SMALL_DRIPLEAF_PLACEABLE).add(StateTypes.DIRT, StateTypes.GRASS_BLOCK, StateTypes.PODZOL, StateTypes.COARSE_DIRT, StateTypes.MYCELIUM, StateTypes.ROOTED_DIRT, StateTypes.MOSS_BLOCK, StateTypes.MUD, StateTypes.MUDDY_MANGROVE_ROOTS, StateTypes.FARMLAND);
BlockTags.MINEABLE_HOE.addTag(BlockTags.LEAVES).add(StateTypes.NETHER_WART_BLOCK, StateTypes.WARPED_WART_BLOCK, StateTypes.HAY_BLOCK, StateTypes.DRIED_KELP_BLOCK, StateTypes.TARGET, StateTypes.SHROOMLIGHT, StateTypes.SPONGE, StateTypes.WET_SPONGE, StateTypes.SCULK_SENSOR, StateTypes.CALIBRATED_SCULK_SENSOR, StateTypes.MOSS_BLOCK, StateTypes.MOSS_CARPET, StateTypes.PALE_MOSS_BLOCK, StateTypes.PALE_MOSS_CARPET, StateTypes.SCULK, StateTypes.SCULK_CATALYST, StateTypes.SCULK_VEIN, StateTypes.SCULK_SHRIEKER);
BlockTags.MINEABLE_PICKAXE.addTag(BlockTags.STONE_BUTTONS).addTag(BlockTags.WALLS).addTag(BlockTags.SHULKER_BOXES).addTag(BlockTags.ANVIL).addTag(BlockTags.CAULDRONS).addTag(BlockTags.RAILS).add(StateTypes.STONE, StateTypes.GRANITE, StateTypes.POLISHED_GRANITE, StateTypes.DIORITE, StateTypes.POLISHED_DIORITE, StateTypes.ANDESITE, StateTypes.POLISHED_ANDESITE, StateTypes.COBBLESTONE, StateTypes.GOLD_ORE, StateTypes.DEEPSLATE_GOLD_ORE, StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE, StateTypes.COAL_ORE, StateTypes.DEEPSLATE_COAL_ORE, StateTypes.NETHER_GOLD_ORE, StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE, StateTypes.LAPIS_BLOCK, StateTypes.DISPENSER, StateTypes.SANDSTONE, StateTypes.CHISELED_SANDSTONE, StateTypes.CUT_SANDSTONE, StateTypes.GOLD_BLOCK, StateTypes.IRON_BLOCK, StateTypes.BRICKS, StateTypes.MOSSY_COBBLESTONE, StateTypes.OBSIDIAN, StateTypes.SPAWNER, StateTypes.DIAMOND_ORE, StateTypes.DEEPSLATE_DIAMOND_ORE, StateTypes.DIAMOND_BLOCK, StateTypes.FURNACE, StateTypes.COBBLESTONE_STAIRS, StateTypes.STONE_PRESSURE_PLATE, StateTypes.IRON_DOOR, StateTypes.REDSTONE_ORE, StateTypes.DEEPSLATE_REDSTONE_ORE, StateTypes.NETHERRACK, StateTypes.BASALT, StateTypes.POLISHED_BASALT, StateTypes.STONE_BRICKS, StateTypes.MOSSY_STONE_BRICKS, StateTypes.CRACKED_STONE_BRICKS, StateTypes.CHISELED_STONE_BRICKS, StateTypes.IRON_BARS, StateTypes.CHAIN, StateTypes.BRICK_STAIRS, StateTypes.STONE_BRICK_STAIRS, StateTypes.NETHER_BRICKS, StateTypes.NETHER_BRICK_FENCE, StateTypes.NETHER_BRICK_STAIRS, StateTypes.ENCHANTING_TABLE, StateTypes.BREWING_STAND, StateTypes.END_STONE, StateTypes.SANDSTONE_STAIRS, StateTypes.EMERALD_ORE, StateTypes.DEEPSLATE_EMERALD_ORE, StateTypes.ENDER_CHEST, StateTypes.EMERALD_BLOCK, StateTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, StateTypes.HEAVY_WEIGHTED_PRESSURE_PLATE, StateTypes.REDSTONE_BLOCK, StateTypes.NETHER_QUARTZ_ORE, StateTypes.HOPPER, StateTypes.QUARTZ_BLOCK, StateTypes.CHISELED_QUARTZ_BLOCK, StateTypes.QUARTZ_PILLAR, StateTypes.QUARTZ_STAIRS, StateTypes.DROPPER, StateTypes.WHITE_TERRACOTTA, StateTypes.ORANGE_TERRACOTTA, StateTypes.MAGENTA_TERRACOTTA, StateTypes.LIGHT_BLUE_TERRACOTTA, StateTypes.YELLOW_TERRACOTTA, StateTypes.LIME_TERRACOTTA, StateTypes.PINK_TERRACOTTA, StateTypes.GRAY_TERRACOTTA, StateTypes.LIGHT_GRAY_TERRACOTTA, StateTypes.CYAN_TERRACOTTA, StateTypes.PURPLE_TERRACOTTA, StateTypes.BLUE_TERRACOTTA, StateTypes.BROWN_TERRACOTTA, StateTypes.GREEN_TERRACOTTA, StateTypes.RED_TERRACOTTA, StateTypes.BLACK_TERRACOTTA, StateTypes.IRON_TRAPDOOR, StateTypes.PRISMARINE, StateTypes.PRISMARINE_BRICKS, StateTypes.DARK_PRISMARINE, StateTypes.PRISMARINE_STAIRS, StateTypes.PRISMARINE_BRICK_STAIRS, StateTypes.DARK_PRISMARINE_STAIRS, StateTypes.PRISMARINE_SLAB, StateTypes.PRISMARINE_BRICK_SLAB, StateTypes.DARK_PRISMARINE_SLAB, StateTypes.TERRACOTTA, StateTypes.COAL_BLOCK, StateTypes.RED_SANDSTONE, StateTypes.CHISELED_RED_SANDSTONE, StateTypes.CUT_RED_SANDSTONE, StateTypes.RED_SANDSTONE_STAIRS, StateTypes.STONE_SLAB, StateTypes.SMOOTH_STONE_SLAB, StateTypes.SANDSTONE_SLAB, StateTypes.CUT_SANDSTONE_SLAB, StateTypes.PETRIFIED_OAK_SLAB, StateTypes.COBBLESTONE_SLAB, StateTypes.BRICK_SLAB, StateTypes.STONE_BRICK_SLAB, StateTypes.NETHER_BRICK_SLAB, StateTypes.QUARTZ_SLAB, StateTypes.RED_SANDSTONE_SLAB, StateTypes.CUT_RED_SANDSTONE_SLAB, StateTypes.PURPUR_SLAB, StateTypes.SMOOTH_STONE, StateTypes.SMOOTH_SANDSTONE, StateTypes.SMOOTH_QUARTZ, StateTypes.SMOOTH_RED_SANDSTONE, StateTypes.PURPUR_BLOCK, StateTypes.PURPUR_PILLAR, StateTypes.PURPUR_STAIRS, StateTypes.END_STONE_BRICKS, StateTypes.MAGMA_BLOCK, StateTypes.RED_NETHER_BRICKS, StateTypes.BONE_BLOCK, StateTypes.OBSERVER, StateTypes.WHITE_GLAZED_TERRACOTTA, StateTypes.ORANGE_GLAZED_TERRACOTTA, StateTypes.MAGENTA_GLAZED_TERRACOTTA, StateTypes.LIGHT_BLUE_GLAZED_TERRACOTTA, StateTypes.YELLOW_GLAZED_TERRACOTTA, StateTypes.LIME_GLAZED_TERRACOTTA, StateTypes.PINK_GLAZED_TERRACOTTA, StateTypes.GRAY_GLAZED_TERRACOTTA, StateTypes.LIGHT_GRAY_GLAZED_TERRACOTTA, StateTypes.CYAN_GLAZED_TERRACOTTA, StateTypes.PURPLE_GLAZED_TERRACOTTA, StateTypes.BLUE_GLAZED_TERRACOTTA, StateTypes.BROWN_GLAZED_TERRACOTTA, StateTypes.GREEN_GLAZED_TERRACOTTA, StateTypes.RED_GLAZED_TERRACOTTA, StateTypes.BLACK_GLAZED_TERRACOTTA, StateTypes.WHITE_CONCRETE, StateTypes.ORANGE_CONCRETE, StateTypes.MAGENTA_CONCRETE, StateTypes.LIGHT_BLUE_CONCRETE, StateTypes.YELLOW_CONCRETE, StateTypes.LIME_CONCRETE, StateTypes.PINK_CONCRETE, StateTypes.GRAY_CONCRETE, StateTypes.LIGHT_GRAY_CONCRETE, StateTypes.CYAN_CONCRETE, StateTypes.PURPLE_CONCRETE, StateTypes.BLUE_CONCRETE, StateTypes.BROWN_CONCRETE, StateTypes.GREEN_CONCRETE, StateTypes.RED_CONCRETE, StateTypes.BLACK_CONCRETE, StateTypes.DEAD_TUBE_CORAL_BLOCK, StateTypes.DEAD_BRAIN_CORAL_BLOCK, StateTypes.DEAD_BUBBLE_CORAL_BLOCK, StateTypes.DEAD_FIRE_CORAL_BLOCK, StateTypes.DEAD_HORN_CORAL_BLOCK, StateTypes.TUBE_CORAL_BLOCK, StateTypes.BRAIN_CORAL_BLOCK, StateTypes.BUBBLE_CORAL_BLOCK, StateTypes.FIRE_CORAL_BLOCK, StateTypes.HORN_CORAL_BLOCK,Line truncated
BlockTags.MINEABLE_PICKAXE.addTag(BlockTags.STONE_BUTTONS).addTag(BlockTags.WALLS).addTag(BlockTags.SHULKER_BOXES).addTag(BlockTags.ANVIL).addTag(BlockTags.CAULDRONS).addTag(BlockTags.RAILS).addTag(BlockTags.COPPER_CHESTS).addTag(BlockTags.COPPER_GOLEM_STATUES).addTag(BlockTags.LIGHTNING_RODS).addTag(BlockTags.LANTERNS).addTag(BlockTags.CHAINS).addTag(BlockTags.BARS).add(StateTypes.STONE, StateTypes.GRANITE, StateTypes.POLISHED_GRANITE, StateTypes.DIORITE, StateTypes.POLISHED_DIORITE, StateTypes.ANDESITE, StateTypes.POLISHED_ANDESITE, StateTypes.COBBLESTONE, StateTypes.GOLD_ORE, StateTypes.DEEPSLATE_GOLD_ORE, StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE, StateTypes.COAL_ORE, StateTypes.DEEPSLATE_COAL_ORE, StateTypes.NETHER_GOLD_ORE, StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE, StateTypes.LAPIS_BLOCK, StateTypes.DISPENSER, StateTypes.SANDSTONE, StateTypes.CHISELED_SANDSTONE, StateTypes.CUT_SANDSTONE, StateTypes.GOLD_BLOCK, StateTypes.IRON_BLOCK, StateTypes.BRICKS, StateTypes.MOSSY_COBBLESTONE, StateTypes.OBSIDIAN, StateTypes.SPAWNER, StateTypes.DIAMOND_ORE, StateTypes.DEEPSLATE_DIAMOND_ORE, StateTypes.DIAMOND_BLOCK, StateTypes.FURNACE, StateTypes.COBBLESTONE_STAIRS, StateTypes.STONE_PRESSURE_PLATE, StateTypes.IRON_DOOR, StateTypes.REDSTONE_ORE, StateTypes.DEEPSLATE_REDSTONE_ORE, StateTypes.NETHERRACK, StateTypes.BASALT, StateTypes.POLISHED_BASALT, StateTypes.STONE_BRICKS, StateTypes.MOSSY_STONE_BRICKS, StateTypes.CRACKED_STONE_BRICKS, StateTypes.CHISELED_STONE_BRICKS, StateTypes.BRICK_STAIRS, StateTypes.STONE_BRICK_STAIRS, StateTypes.NETHER_BRICKS, StateTypes.NETHER_BRICK_FENCE, StateTypes.NETHER_BRICK_STAIRS, StateTypes.ENCHANTING_TABLE, StateTypes.BREWING_STAND, StateTypes.END_STONE, StateTypes.SANDSTONE_STAIRS, StateTypes.EMERALD_ORE, StateTypes.DEEPSLATE_EMERALD_ORE, StateTypes.ENDER_CHEST, StateTypes.EMERALD_BLOCK, StateTypes.LIGHT_WEIGHTED_PRESSURE_PLATE, StateTypes.HEAVY_WEIGHTED_PRESSURE_PLATE, StateTypes.REDSTONE_BLOCK, StateTypes.NETHER_QUARTZ_ORE, StateTypes.HOPPER, StateTypes.QUARTZ_BLOCK, StateTypes.CHISELED_QUARTZ_BLOCK, StateTypes.QUARTZ_PILLAR, StateTypes.QUARTZ_STAIRS, StateTypes.DROPPER, StateTypes.WHITE_TERRACOTTA, StateTypes.ORANGE_TERRACOTTA, StateTypes.MAGENTA_TERRACOTTA, StateTypes.LIGHT_BLUE_TERRACOTTA, StateTypes.YELLOW_TERRACOTTA, StateTypes.LIME_TERRACOTTA, StateTypes.PINK_TERRACOTTA, StateTypes.GRAY_TERRACOTTA, StateTypes.LIGHT_GRAY_TERRACOTTA, StateTypes.CYAN_TERRACOTTA, StateTypes.PURPLE_TERRACOTTA, StateTypes.BLUE_TERRACOTTA, StateTypes.BROWN_TERRACOTTA, StateTypes.GREEN_TERRACOTTA, StateTypes.RED_TERRACOTTA, StateTypes.BLACK_TERRACOTTA, StateTypes.IRON_TRAPDOOR, StateTypes.PRISMARINE, StateTypes.PRISMARINE_BRICKS, StateTypes.DARK_PRISMARINE, StateTypes.PRISMARINE_STAIRS, StateTypes.PRISMARINE_BRICK_STAIRS, StateTypes.DARK_PRISMARINE_STAIRS, StateTypes.PRISMARINE_SLAB, StateTypes.PRISMARINE_BRICK_SLAB, StateTypes.DARK_PRISMARINE_SLAB, StateTypes.TERRACOTTA, StateTypes.COAL_BLOCK, StateTypes.RED_SANDSTONE, StateTypes.CHISELED_RED_SANDSTONE, StateTypes.CUT_RED_SANDSTONE, StateTypes.RED_SANDSTONE_STAIRS, StateTypes.STONE_SLAB, StateTypes.SMOOTH_STONE_SLAB, StateTypes.SANDSTONE_SLAB, StateTypes.CUT_SANDSTONE_SLAB, StateTypes.PETRIFIED_OAK_SLAB, StateTypes.COBBLESTONE_SLAB, StateTypes.BRICK_SLAB, StateTypes.STONE_BRICK_SLAB, StateTypes.NETHER_BRICK_SLAB, StateTypes.QUARTZ_SLAB, StateTypes.RED_SANDSTONE_SLAB, StateTypes.CUT_RED_SANDSTONE_SLAB, StateTypes.PURPUR_SLAB, StateTypes.SMOOTH_STONE, StateTypes.SMOOTH_SANDSTONE, StateTypes.SMOOTH_QUARTZ, StateTypes.SMOOTH_RED_SANDSTONE, StateTypes.PURPUR_BLOCK, StateTypes.PURPUR_PILLAR, StateTypes.PURPUR_STAIRS, StateTypes.END_STONE_BRICKS, StateTypes.MAGMA_BLOCK, StateTypes.RED_NETHER_BRICKS, StateTypes.BONE_BLOCK, StateTypes.OBSERVER, StateTypes.WHITE_GLAZED_TERRACOTTA, StateTypes.ORANGE_GLAZED_TERRACOTTA, StateTypes.MAGENTA_GLAZED_TERRACOTTA, StateTypes.LIGHT_BLUE_GLAZED_TERRACOTTA, StateTypes.YELLOW_GLAZED_TERRACOTTA, StateTypes.LIME_GLAZED_TERRACOTTA, StateTypes.PINK_GLAZED_TERRACOTTA, StateTypes.GRAY_GLAZED_TERRACOTTA, StateTypes.LIGHT_GRAY_GLAZED_TERRACOTTA, StateTypes.CYAN_GLAZED_TERRACOTTA, StateTypes.PURPLE_GLAZED_TERRACOTTA, StateTypes.BLUE_GLAZED_TERRACOTTA, StateTypes.BROWN_GLAZED_TERRACOTTA, StateTypes.GREEN_GLAZED_TERRACOTTA, StateTypes.RED_GLAZED_TERRACOTTA, StateTypes.BLACK_GLAZED_TERRACOTTA, StateTypes.WHITE_CONCRETE, StateTypes.ORANGE_CONCRETE, StateTypes.MAGENTA_CONCRETE, StateTypes.LIGHT_BLUE_CONCRETE, StateTypes.YELLOW_CONCRETE, StateTypes.LIME_CONCRETE, StateTypes.PINK_CONCRETE, StateTypes.GRAY_CONCRETE, StateTypes.LIGHT_GRAY_CONCRETE, StateTypes.CYAN_CONCRETE, StateTypes.PURPLE_CONCRETE, StateTypes.BLUE_CONCRETE, StateTypes.BROWN_CONCRETE, StateTypes.GREEN_CONCRETE, StateTypes.RED_CONCRETE, StateTypes.BLACK_CONCRETE, StateTypes.DEAD_TUBE_CORAL_BLOCK, StateTypes.DEAD_BRAIN_CORAL_BLOCK, StateTypes.DEAD_BUBBLE_CORAL_BLOCK, StateTypes.DEAD_FIRE_CORAL_BLOCK, StateTypes.DEAD_HORN_CORAL_BLOCK, StateTypLine truncated
BlockTags.MINEABLE_SHOVEL.addTag(BlockTags.CONCRETE_POWDER).add(StateTypes.CLAY, StateTypes.DIRT, StateTypes.COARSE_DIRT, StateTypes.PODZOL, StateTypes.FARMLAND, StateTypes.GRASS_BLOCK, StateTypes.GRAVEL, StateTypes.MYCELIUM, StateTypes.SAND, StateTypes.RED_SAND, StateTypes.SNOW_BLOCK, StateTypes.SNOW, StateTypes.SOUL_SAND, StateTypes.DIRT_PATH, StateTypes.SOUL_SOIL, StateTypes.ROOTED_DIRT, StateTypes.MUDDY_MANGROVE_ROOTS, StateTypes.MUD, StateTypes.SUSPICIOUS_SAND, StateTypes.SUSPICIOUS_GRAVEL);
BlockTags.SWORD_EFFICIENT.addTag(BlockTags.LEAVES).add(StateTypes.VINE, StateTypes.GLOW_LICHEN, StateTypes.PUMPKIN, StateTypes.CARVED_PUMPKIN, StateTypes.JACK_O_LANTERN, StateTypes.MELON, StateTypes.COCOA, StateTypes.BIG_DRIPLEAF, StateTypes.BIG_DRIPLEAF_STEM, StateTypes.CHORUS_PLANT, StateTypes.CHORUS_FLOWER);
BlockTags.NEEDS_STONE_TOOL.addTag(BlockTags.COPPER_CHESTS).addTag(BlockTags.LIGHTNING_RODS).add(StateTypes.IRON_BLOCK, StateTypes.RAW_IRON_BLOCK, StateTypes.IRON_ORE, StateTypes.DEEPSLATE_IRON_ORE, StateTypes.LAPIS_BLOCK, StateTypes.LAPIS_ORE, StateTypes.DEEPSLATE_LAPIS_ORE, StateTypes.COPPER_BLOCK, StateTypes.RAW_COPPER_BLOCK, StateTypes.COPPER_ORE, StateTypes.DEEPSLATE_COPPER_ORE, StateTypes.CUT_COPPER_SLAB, StateTypes.CUT_COPPER_STAIRS, StateTypes.CUT_COPPER, StateTypes.WEATHERED_COPPER, StateTypes.WEATHERED_CUT_COPPER_SLAB, StateTypes.WEATHERED_CUT_COPPER_STAIRS, StateTypes.WEATHERED_CUT_COPPER, StateTypes.OXIDIZED_COPPER, StateTypes.OXIDIZED_CUT_COPPER_SLAB, StateTypes.OXIDIZED_CUT_COPPER_STAIRS, StateTypes.OXIDIZED_CUT_COPPER, StateTypes.EXPOSED_COPPER, StateTypes.EXPOSED_CUT_COPPER_SLAB, StateTypes.EXPOSED_CUT_COPPER_STAIRS, StateTypes.EXPOSED_CUT_COPPER, StateTypes.WAXED_COPPER_BLOCK, StateTypes.WAXED_CUT_COPPER_SLAB, StateTypes.WAXED_CUT_COPPER_STAIRS, StateTypes.WAXED_CUT_COPPER, StateTypes.WAXED_WEATHERED_COPPER, StateTypes.WAXED_WEATHERED_CUT_COPPER_SLAB, StateTypes.WAXED_WEATHERED_CUT_COPPER_STAIRS, StateTypes.WAXED_WEATHERED_CUT_COPPER, StateTypes.WAXED_EXPOSED_COPPER, StateTypes.WAXED_EXPOSED_CUT_COPPER_SLAB, StateTypes.WAXED_EXPOSED_CUT_COPPER_STAIRS, StateTypes.WAXED_EXPOSED_CUT_COPPER, StateTypes.WAXED_OXIDIZED_COPPER, StateTypes.WAXED_OXIDIZED_CUT_COPPER_SLAB, StateTypes.WAXED_OXIDIZED_CUT_COPPER_STAIRS, StateTypes.WAXED_OXIDIZED_CUT_COPPER, StateTypes.CRAFTER, StateTypes.CHISELED_COPPER, StateTypes.EXPOSED_CHISELED_COPPER, StateTypes.WEATHERED_CHISELED_COPPER, StateTypes.OXIDIZED_CHISELED_COPPER, StateTypes.WAXED_CHISELED_COPPER, StateTypes.WAXED_EXPOSED_CHISELED_COPPER, StateTypes.WAXED_WEATHERED_CHISELED_COPPER, StateTypes.WAXED_OXIDIZED_CHISELED_COPPER, StateTypes.COPPER_GRATE, StateTypes.EXPOSED_COPPER_GRATE, StateTypes.WEATHERED_COPPER_GRATE, StateTypes.OXIDIZED_COPPER_GRATE, StateTypes.WAXED_COPPER_GRATE, StateTypes.WAXED_EXPOSED_COPPER_GRATE, StateTypes.WAXED_WEATHERED_COPPER_GRATE, StateTypes.WAXED_OXIDIZED_COPPER_GRATE, StateTypes.COPPER_BULB, StateTypes.EXPOSED_COPPER_BULB, StateTypes.WEATHERED_COPPER_BULB, StateTypes.OXIDIZED_COPPER_BULB, StateTypes.WAXED_COPPER_BULB, StateTypes.WAXED_EXPOSED_COPPER_BULB, StateTypes.WAXED_WEATHERED_COPPER_BULB, StateTypes.WAXED_OXIDIZED_COPPER_BULB, StateTypes.COPPER_TRAPDOOR, StateTypes.EXPOSED_COPPER_TRAPDOOR, StateTypes.WEATHERED_COPPER_TRAPDOOR, StateTypes.OXIDIZED_COPPER_TRAPDOOR, StateTypes.WAXED_COPPER_TRAPDOOR, StateTypes.WAXED_EXPOSED_COPPER_TRAPDOOR, StateTypes.WAXED_WEATHERED_COPPER_TRAPDOOR, StateTypes.WAXED_OXIDIZED_COPPER_TRAPDOOR);
BlockTags.INCORRECT_FOR_IRON_TOOL.addTag(BlockTags.NEEDS_DIAMOND_TOOL);
BlockTags.INCORRECT_FOR_STONE_TOOL.addTag(BlockTags.NEEDS_DIAMOND_TOOL).addTag(BlockTags.NEEDS_IRON_TOOL);
BlockTags.INCORRECT_FOR_GOLD_TOOL.addTag(BlockTags.NEEDS_DIAMOND_TOOL).addTag(BlockTags.NEEDS_IRON_TOOL).addTag(BlockTags.NEEDS_STONE_TOOL);
copy(BlockTags.INCORRECT_FOR_GOLD_TOOL, BlockTags.INCORRECT_FOR_WOODEN_TOOL);
BlockTags.INCORRECT_FOR_COPPER_TOOL.addTag(BlockTags.NEEDS_DIAMOND_TOOL).addTag(BlockTags.NEEDS_IRON_TOOL);
copy(BlockTags.INCORRECT_FOR_COPPER_TOOL, BlockTags.INCORRECT_FOR_STONE_TOOL);
BlockTags.SCULK_REPLACEABLE.addTag(BlockTags.BASE_STONE_OVERWORLD).addTag(BlockTags.DIRT).addTag(BlockTags.TERRACOTTA).addTag(BlockTags.NYLIUM).addTag(BlockTags.BASE_STONE_NETHER).add(StateTypes.SAND, StateTypes.RED_SAND, StateTypes.GRAVEL, StateTypes.SOUL_SAND, StateTypes.SOUL_SOIL, StateTypes.CALCITE, StateTypes.SMOOTH_BASALT, StateTypes.CLAY, StateTypes.DRIPSTONE_BLOCK, StateTypes.END_STONE, StateTypes.RED_SANDSTONE, StateTypes.SANDSTONE);
BlockTags.ARMADILLO_SPAWNABLE_ON.addTag(BlockTags.ANIMALS_SPAWNABLE_ON).addTag(BlockTags.BADLANDS_TERRACOTTA).add(StateTypes.RED_SAND, StateTypes.COARSE_DIRT);
BlockTags.GOATS_SPAWNABLE_ON.addTag(BlockTags.ANIMALS_SPAWNABLE_ON).add(StateTypes.STONE, StateTypes.SNOW, StateTypes.SNOW_BLOCK, StateTypes.PACKED_ICE, StateTypes.GRAVEL);
@@ -541,11 +585,13 @@ public class BlockTags {
BlockTags.LOGS.addTag(BlockTags.LOGS_THAT_BURN).addTag(BlockTags.CRIMSON_STEMS).addTag(BlockTags.WARPED_STEMS);
BlockTags.UNDERWATER_BONEMEALS.addTag(BlockTags.CORALS).addTag(BlockTags.WALL_CORALS).add(StateTypes.SEAGRASS);
BlockTags.ALL_SIGNS.addTag(BlockTags.SIGNS).addTag(BlockTags.ALL_HANGING_SIGNS);
BlockTags.WALL_POST_OVERRIDE.addTag(BlockTags.SIGNS).addTag(BlockTags.BANNERS).addTag(BlockTags.PRESSURE_PLATES).add(StateTypes.TORCH, StateTypes.SOUL_TORCH, StateTypes.REDSTONE_TORCH, StateTypes.TRIPWIRE, StateTypes.CACTUS_FLOWER);
BlockTags.WALL_POST_OVERRIDE.addTag(BlockTags.SIGNS).addTag(BlockTags.BANNERS).addTag(BlockTags.PRESSURE_PLATES).add(StateTypes.TORCH, StateTypes.SOUL_TORCH, StateTypes.REDSTONE_TORCH, StateTypes.COPPER_TORCH, StateTypes.TRIPWIRE, StateTypes.CACTUS_FLOWER);
BlockTags.LUSH_GROUND_REPLACEABLE.addTag(BlockTags.MOSS_REPLACEABLE).add(StateTypes.CLAY, StateTypes.GRAVEL, StateTypes.SAND);
BlockTags.INCORRECT_FOR_GOLD_TOOL.addTag(BlockTags.NEEDS_DIAMOND_TOOL).addTag(BlockTags.NEEDS_IRON_TOOL).addTag(BlockTags.NEEDS_STONE_TOOL);
copy(BlockTags.INCORRECT_FOR_GOLD_TOOL, BlockTags.INCORRECT_FOR_WOODEN_TOOL);
BlockTags.SCULK_REPLACEABLE_WORLD_GEN.addTag(BlockTags.SCULK_REPLACEABLE).add(StateTypes.DEEPSLATE_BRICKS, StateTypes.DEEPSLATE_TILES, StateTypes.COBBLED_DEEPSLATE, StateTypes.CRACKED_DEEPSLATE_BRICKS, StateTypes.CRACKED_DEEPSLATE_TILES, StateTypes.POLISHED_DEEPSLATE);
BlockTags.COMPLETES_FIND_TREE_TUTORIAL.addTag(BlockTags.LOGS).addTag(BlockTags.LEAVES).addTag(BlockTags.WART_BLOCKS);
BlockTags.MINEABLE_AXE.addTag(BlockTags.BANNERS).addTag(BlockTags.FENCE_GATES).addTag(BlockTags.LOGS).addTag(BlockTags.PLANKS).addTag(BlockTags.SIGNS).addTag(BlockTags.WOODEN_BUTTONS).addTag(BlockTags.WOODEN_DOORS).addTag(BlockTags.WOODEN_FENCES).addTag(BlockTags.WOODEN_PRESSURE_PLATES).addTag(BlockTags.WOODEN_SLABS).addTag(BlockTags.WOODEN_STAIRS).addTag(BlockTags.WOODEN_TRAPDOORS).addTag(BlockTags.ALL_HANGING_SIGNS).addTag(BlockTags.BAMBOO_BLOCKS).add(StateTypes.NOTE_BLOCK, StateTypes.BAMBOO, StateTypes.BARREL, StateTypes.BEE_NEST, StateTypes.BEEHIVE, StateTypes.BIG_DRIPLEAF_STEM, StateTypes.BIG_DRIPLEAF, StateTypes.BOOKSHELF, StateTypes.BROWN_MUSHROOM_BLOCK, StateTypes.CAMPFIRE, StateTypes.CARTOGRAPHY_TABLE, StateTypes.CARVED_PUMPKIN, StateTypes.CHEST, StateTypes.CHORUS_FLOWER, StateTypes.CHORUS_PLANT, StateTypes.COCOA, StateTypes.COMPOSTER, StateTypes.CRAFTING_TABLE, StateTypes.DAYLIGHT_DETECTOR, StateTypes.FLETCHING_TABLE, StateTypes.GLOW_LICHEN, StateTypes.JACK_O_LANTERN, StateTypes.JUKEBOX, StateTypes.LADDER, StateTypes.LECTERN, StateTypes.LOOM, StateTypes.MELON, StateTypes.MUSHROOM_STEM, StateTypes.PUMPKIN, StateTypes.RED_MUSHROOM_BLOCK, StateTypes.SMITHING_TABLE, StateTypes.SOUL_CAMPFIRE, StateTypes.TRAPPED_CHEST, StateTypes.VINE, StateTypes.MANGROVE_ROOTS, StateTypes.BAMBOO_MOSAIC, StateTypes.BAMBOO_MOSAIC_SLAB, StateTypes.BAMBOO_MOSAIC_STAIRS, StateTypes.CHISELED_BOOKSHELF, StateTypes.CREAKING_HEART);
BlockTags.MINEABLE_AXE.addTag(BlockTags.BANNERS).addTag(BlockTags.FENCE_GATES).addTag(BlockTags.LOGS).addTag(BlockTags.PLANKS).addTag(BlockTags.SIGNS).addTag(BlockTags.WOODEN_BUTTONS).addTag(BlockTags.WOODEN_DOORS).addTag(BlockTags.WOODEN_FENCES).addTag(BlockTags.WOODEN_PRESSURE_PLATES).addTag(BlockTags.WOODEN_SLABS).addTag(BlockTags.WOODEN_STAIRS).addTag(BlockTags.WOODEN_TRAPDOORS).addTag(BlockTags.ALL_HANGING_SIGNS).addTag(BlockTags.BAMBOO_BLOCKS).addTag(BlockTags.WOODEN_SHELVES).add(StateTypes.NOTE_BLOCK, StateTypes.BAMBOO, StateTypes.BARREL, StateTypes.BEE_NEST, StateTypes.BEEHIVE, StateTypes.BIG_DRIPLEAF_STEM, StateTypes.BIG_DRIPLEAF, StateTypes.BOOKSHELF, StateTypes.BROWN_MUSHROOM_BLOCK, StateTypes.CAMPFIRE, StateTypes.CARTOGRAPHY_TABLE, StateTypes.CARVED_PUMPKIN, StateTypes.CHEST, StateTypes.CHORUS_FLOWER, StateTypes.CHORUS_PLANT, StateTypes.COCOA, StateTypes.COMPOSTER, StateTypes.CRAFTING_TABLE, StateTypes.DAYLIGHT_DETECTOR, StateTypes.FLETCHING_TABLE, StateTypes.GLOW_LICHEN, StateTypes.JACK_O_LANTERN, StateTypes.JUKEBOX, StateTypes.LADDER, StateTypes.LECTERN, StateTypes.LOOM, StateTypes.MELON, StateTypes.MUSHROOM_STEM, StateTypes.PUMPKIN, StateTypes.RED_MUSHROOM_BLOCK, StateTypes.SMITHING_TABLE, StateTypes.SOUL_CAMPFIRE, StateTypes.TRAPPED_CHEST, StateTypes.VINE, StateTypes.MANGROVE_ROOTS, StateTypes.BAMBOO_MOSAIC, StateTypes.BAMBOO_MOSAIC_SLAB, StateTypes.BAMBOO_MOSAIC_STAIRS, StateTypes.CHISELED_BOOKSHELF, StateTypes.CREAKING_HEART);
BlockTags.LAVA_POOL_STONE_CANNOT_REPLACE.addTag(BlockTags.FEATURES_CANNOT_REPLACE).addTag(BlockTags.LEAVES).addTag(BlockTags.LOGS);
BlockTags.PARROTS_SPAWNABLE_ON.addTag(BlockTags.LEAVES).addTag(BlockTags.LOGS).add(StateTypes.GRASS_BLOCK, StateTypes.AIR);
// legacy
@@ -500,6 +500,51 @@ public class ItemTags {
*/
public static final ItemTags HAPPY_GHAST_TEMPT_ITEMS = bind("happy_ghast_tempt_items");
/**
* @versions 1.21.9+
*/
public static final ItemTags WOODEN_SHELVES = bind("wooden_shelves");
/**
* @versions 1.21.9+
*/
public static final ItemTags COPPER_CHESTS = bind("copper_chests");
/**
* @versions 1.21.9+
*/
public static final ItemTags LIGHTNING_RODS = bind("lightning_rods");
/**
* @versions 1.21.9+
*/
public static final ItemTags COPPER_GOLEM_STATUES = bind("copper_golem_statues");
/**
* @versions 1.21.9+
*/
public static final ItemTags COPPER = bind("copper");
/**
* @versions 1.21.9+
*/
public static final ItemTags CHAINS = bind("chains");
/**
* @versions 1.21.9+
*/
public static final ItemTags LANTERNS = bind("lanterns");
/**
* @versions 1.21.9+
*/
public static final ItemTags BARS = bind("bars");
/**
* @versions 1.21.9+
*/
public static final ItemTags COPPER_TOOL_MATERIALS = bind("copper_tool_materials");
/**
* @versions 1.21.9+
*/
public static final ItemTags REPAIRS_COPPER_ARMOR = bind("repairs_copper_armor");
/**
* @versions 1.21.9+
*/
public static final ItemTags SHEARABLE_FROM_COPPER_GOLEM = bind("shearable_from_copper_golem");
static {
copy(BlockTags.WOOL, ItemTags.WOOL);
copy(BlockTags.PLANKS, ItemTags.PLANKS);
@@ -513,6 +558,7 @@ public class ItemTags {
copy(BlockTags.WOODEN_FENCES, ItemTags.WOODEN_FENCES);
copy(BlockTags.FENCE_GATES, ItemTags.FENCE_GATES);
copy(BlockTags.WOODEN_PRESSURE_PLATES, ItemTags.WOODEN_PRESSURE_PLATES);
copy(BlockTags.WOODEN_SHELVES, ItemTags.WOODEN_SHELVES);
copy(BlockTags.SAPLINGS, ItemTags.SAPLINGS);
copy(BlockTags.BAMBOO_BLOCKS, ItemTags.BAMBOO_BLOCKS);
copy(BlockTags.OAK_LOGS, ItemTags.OAK_LOGS);
@@ -549,6 +595,13 @@ public class ItemTags {
copy(BlockTags.DIRT, ItemTags.DIRT);
copy(BlockTags.TERRACOTTA, ItemTags.TERRACOTTA);
copy(BlockTags.SHULKER_BOXES, ItemTags.SHULKER_BOXES);
copy(BlockTags.COPPER_CHESTS, ItemTags.COPPER_CHESTS);
copy(BlockTags.LIGHTNING_RODS, ItemTags.LIGHTNING_RODS);
copy(BlockTags.COPPER_GOLEM_STATUES, ItemTags.COPPER_GOLEM_STATUES);
copy(BlockTags.COPPER, ItemTags.COPPER);
copy(BlockTags.CHAINS, ItemTags.CHAINS);
copy(BlockTags.LANTERNS, ItemTags.LANTERNS);
copy(BlockTags.BARS, ItemTags.BARS);
copy(BlockTags.STANDING_SIGNS, ItemTags.SIGNS);
copy(BlockTags.CEILING_HANGING_SIGNS, ItemTags.HANGING_SIGNS);
copy(BlockTags.BEE_ATTRACTIVE, ItemTags.BEE_FOOD);
@@ -587,7 +640,7 @@ public class ItemTags {
copy(ItemTags.CHICKEN_FOOD, ItemTags.PARROT_FOOD);
ItemTags.PARROT_POISONOUS_FOOD.add(ItemTypes.COOKIE);
ItemTags.AXOLOTL_FOOD.add(ItemTypes.TROPICAL_FISH_BUCKET);
ItemTags.NON_FLAMMABLE_WOOD.add(ItemTypes.WARPED_STEM, ItemTypes.STRIPPED_WARPED_STEM, ItemTypes.WARPED_HYPHAE, ItemTypes.STRIPPED_WARPED_HYPHAE, ItemTypes.CRIMSON_STEM, ItemTypes.STRIPPED_CRIMSON_STEM, ItemTypes.CRIMSON_HYPHAE, ItemTypes.STRIPPED_CRIMSON_HYPHAE, ItemTypes.CRIMSON_PLANKS, ItemTypes.WARPED_PLANKS, ItemTypes.CRIMSON_SLAB, ItemTypes.WARPED_SLAB, ItemTypes.CRIMSON_PRESSURE_PLATE, ItemTypes.WARPED_PRESSURE_PLATE, ItemTypes.CRIMSON_FENCE, ItemTypes.WARPED_FENCE, ItemTypes.CRIMSON_TRAPDOOR, ItemTypes.WARPED_TRAPDOOR, ItemTypes.CRIMSON_FENCE_GATE, ItemTypes.WARPED_FENCE_GATE, ItemTypes.CRIMSON_STAIRS, ItemTypes.WARPED_STAIRS, ItemTypes.CRIMSON_BUTTON, ItemTypes.WARPED_BUTTON, ItemTypes.CRIMSON_DOOR, ItemTypes.WARPED_DOOR, ItemTypes.CRIMSON_SIGN, ItemTypes.WARPED_SIGN, ItemTypes.WARPED_HANGING_SIGN, ItemTypes.CRIMSON_HANGING_SIGN);
ItemTags.NON_FLAMMABLE_WOOD.add(ItemTypes.WARPED_STEM, ItemTypes.STRIPPED_WARPED_STEM, ItemTypes.WARPED_HYPHAE, ItemTypes.STRIPPED_WARPED_HYPHAE, ItemTypes.CRIMSON_STEM, ItemTypes.STRIPPED_CRIMSON_STEM, ItemTypes.CRIMSON_HYPHAE, ItemTypes.STRIPPED_CRIMSON_HYPHAE, ItemTypes.CRIMSON_PLANKS, ItemTypes.WARPED_PLANKS, ItemTypes.CRIMSON_SLAB, ItemTypes.WARPED_SLAB, ItemTypes.CRIMSON_PRESSURE_PLATE, ItemTypes.WARPED_PRESSURE_PLATE, ItemTypes.CRIMSON_FENCE, ItemTypes.WARPED_FENCE, ItemTypes.CRIMSON_TRAPDOOR, ItemTypes.WARPED_TRAPDOOR, ItemTypes.CRIMSON_FENCE_GATE, ItemTypes.WARPED_FENCE_GATE, ItemTypes.CRIMSON_STAIRS, ItemTypes.WARPED_STAIRS, ItemTypes.CRIMSON_BUTTON, ItemTypes.WARPED_BUTTON, ItemTypes.CRIMSON_DOOR, ItemTypes.WARPED_DOOR, ItemTypes.CRIMSON_SIGN, ItemTypes.WARPED_SIGN, ItemTypes.WARPED_HANGING_SIGN, ItemTypes.CRIMSON_HANGING_SIGN, ItemTypes.WARPED_SHELF, ItemTypes.CRIMSON_SHELF);
ItemTags.CHEST_BOATS.add(ItemTypes.OAK_CHEST_BOAT, ItemTypes.SPRUCE_CHEST_BOAT, ItemTypes.BIRCH_CHEST_BOAT, ItemTypes.JUNGLE_CHEST_BOAT, ItemTypes.ACACIA_CHEST_BOAT, ItemTypes.DARK_OAK_CHEST_BOAT, ItemTypes.PALE_OAK_CHEST_BOAT, ItemTypes.MANGROVE_CHEST_BOAT, ItemTypes.BAMBOO_CHEST_RAFT, ItemTypes.CHERRY_CHEST_BOAT);
ItemTags.FISHES.add(ItemTypes.COD, ItemTypes.COOKED_COD, ItemTypes.SALMON, ItemTypes.COOKED_SALMON, ItemTypes.PUFFERFISH, ItemTypes.TROPICAL_FISH);
ItemTags.CREEPER_DROP_MUSIC_DISCS.add(ItemTypes.MUSIC_DISC_13, ItemTypes.MUSIC_DISC_CAT, ItemTypes.MUSIC_DISC_BLOCKS, ItemTypes.MUSIC_DISC_CHIRP, ItemTypes.MUSIC_DISC_FAR, ItemTypes.MUSIC_DISC_MALL, ItemTypes.MUSIC_DISC_MELLOHI, ItemTypes.MUSIC_DISC_STAL, ItemTypes.MUSIC_DISC_STRAD, ItemTypes.MUSIC_DISC_WARD, ItemTypes.MUSIC_DISC_11, ItemTypes.MUSIC_DISC_WAIT);
@@ -597,11 +650,13 @@ public class ItemTags {
ItemTags.BOOKSHELF_BOOKS.add(ItemTypes.BOOK, ItemTypes.WRITTEN_BOOK, ItemTypes.ENCHANTED_BOOK, ItemTypes.WRITABLE_BOOK, ItemTypes.KNOWLEDGE_BOOK);
ItemTags.BEACON_PAYMENT_ITEMS.add(ItemTypes.NETHERITE_INGOT, ItemTypes.EMERALD, ItemTypes.DIAMOND, ItemTypes.GOLD_INGOT, ItemTypes.IRON_INGOT);
ItemTags.STONE_TOOL_MATERIALS.add(ItemTypes.COBBLESTONE, ItemTypes.BLACKSTONE, ItemTypes.COBBLED_DEEPSLATE);
ItemTags.COPPER_TOOL_MATERIALS.add(ItemTypes.COPPER_INGOT);
ItemTags.IRON_TOOL_MATERIALS.add(ItemTypes.IRON_INGOT);
ItemTags.GOLD_TOOL_MATERIALS.add(ItemTypes.GOLD_INGOT);
ItemTags.DIAMOND_TOOL_MATERIALS.add(ItemTypes.DIAMOND);
ItemTags.NETHERITE_TOOL_MATERIALS.add(ItemTypes.NETHERITE_INGOT);
copy(ItemTags.IGNORED_BY_PIGLIN_BABIES, ItemTags.REPAIRS_LEATHER_ARMOR);
copy(ItemTags.COPPER_TOOL_MATERIALS, ItemTags.REPAIRS_COPPER_ARMOR);
copy(ItemTags.IRON_TOOL_MATERIALS, ItemTags.REPAIRS_CHAIN_ARMOR);
copy(ItemTags.IRON_TOOL_MATERIALS, ItemTags.REPAIRS_IRON_ARMOR);
copy(ItemTags.GOLD_TOOL_MATERIALS, ItemTags.REPAIRS_GOLD_ARMOR);
@@ -611,22 +666,22 @@ public class ItemTags {
ItemTags.REPAIRS_WOLF_ARMOR.add(ItemTypes.ARMADILLO_SCUTE);
copy(ItemTags.STONE_TOOL_MATERIALS, ItemTags.STONE_CRAFTING_MATERIALS);
ItemTags.FREEZE_IMMUNE_WEARABLES.add(ItemTypes.LEATHER_BOOTS, ItemTypes.LEATHER_LEGGINGS, ItemTypes.LEATHER_CHESTPLATE, ItemTypes.LEATHER_HELMET, ItemTypes.LEATHER_HORSE_ARMOR);
ItemTags.CLUSTER_MAX_HARVESTABLES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.IRON_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.WOODEN_PICKAXE);
ItemTags.CLUSTER_MAX_HARVESTABLES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.IRON_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.WOODEN_PICKAXE, ItemTypes.COPPER_PICKAXE);
ItemTags.COMPASSES.add(ItemTypes.COMPASS, ItemTypes.RECOVERY_COMPASS);
ItemTags.CREEPER_IGNITERS.add(ItemTypes.FLINT_AND_STEEL, ItemTypes.FIRE_CHARGE);
ItemTags.NOTEBLOCK_TOP_INSTRUMENTS.add(ItemTypes.ZOMBIE_HEAD, ItemTypes.SKELETON_SKULL, ItemTypes.CREEPER_HEAD, ItemTypes.DRAGON_HEAD, ItemTypes.WITHER_SKELETON_SKULL, ItemTypes.PIGLIN_HEAD, ItemTypes.PLAYER_HEAD);
ItemTags.FOOT_ARMOR.add(ItemTypes.LEATHER_BOOTS, ItemTypes.CHAINMAIL_BOOTS, ItemTypes.GOLDEN_BOOTS, ItemTypes.IRON_BOOTS, ItemTypes.DIAMOND_BOOTS, ItemTypes.NETHERITE_BOOTS);
ItemTags.LEG_ARMOR.add(ItemTypes.LEATHER_LEGGINGS, ItemTypes.CHAINMAIL_LEGGINGS, ItemTypes.GOLDEN_LEGGINGS, ItemTypes.IRON_LEGGINGS, ItemTypes.DIAMOND_LEGGINGS, ItemTypes.NETHERITE_LEGGINGS);
ItemTags.CHEST_ARMOR.add(ItemTypes.LEATHER_CHESTPLATE, ItemTypes.CHAINMAIL_CHESTPLATE, ItemTypes.GOLDEN_CHESTPLATE, ItemTypes.IRON_CHESTPLATE, ItemTypes.DIAMOND_CHESTPLATE, ItemTypes.NETHERITE_CHESTPLATE);
ItemTags.HEAD_ARMOR.add(ItemTypes.LEATHER_HELMET, ItemTypes.CHAINMAIL_HELMET, ItemTypes.GOLDEN_HELMET, ItemTypes.IRON_HELMET, ItemTypes.DIAMOND_HELMET, ItemTypes.NETHERITE_HELMET, ItemTypes.TURTLE_HELMET);
ItemTags.FOOT_ARMOR.add(ItemTypes.LEATHER_BOOTS, ItemTypes.COPPER_BOOTS, ItemTypes.CHAINMAIL_BOOTS, ItemTypes.GOLDEN_BOOTS, ItemTypes.IRON_BOOTS, ItemTypes.DIAMOND_BOOTS, ItemTypes.NETHERITE_BOOTS);
ItemTags.LEG_ARMOR.add(ItemTypes.LEATHER_LEGGINGS, ItemTypes.COPPER_LEGGINGS, ItemTypes.CHAINMAIL_LEGGINGS, ItemTypes.GOLDEN_LEGGINGS, ItemTypes.IRON_LEGGINGS, ItemTypes.DIAMOND_LEGGINGS, ItemTypes.NETHERITE_LEGGINGS);
ItemTags.CHEST_ARMOR.add(ItemTypes.LEATHER_CHESTPLATE, ItemTypes.COPPER_CHESTPLATE, ItemTypes.CHAINMAIL_CHESTPLATE, ItemTypes.GOLDEN_CHESTPLATE, ItemTypes.IRON_CHESTPLATE, ItemTypes.DIAMOND_CHESTPLATE, ItemTypes.NETHERITE_CHESTPLATE);
ItemTags.HEAD_ARMOR.add(ItemTypes.LEATHER_HELMET, ItemTypes.COPPER_HELMET, ItemTypes.CHAINMAIL_HELMET, ItemTypes.GOLDEN_HELMET, ItemTypes.IRON_HELMET, ItemTypes.DIAMOND_HELMET, ItemTypes.NETHERITE_HELMET, ItemTypes.TURTLE_HELMET);
ItemTags.SKULLS.add(ItemTypes.PLAYER_HEAD, ItemTypes.CREEPER_HEAD, ItemTypes.ZOMBIE_HEAD, ItemTypes.SKELETON_SKULL, ItemTypes.WITHER_SKELETON_SKULL, ItemTypes.DRAGON_HEAD, ItemTypes.PIGLIN_HEAD);
ItemTags.TRIM_MATERIALS.add(ItemTypes.AMETHYST_SHARD, ItemTypes.COPPER_INGOT, ItemTypes.DIAMOND, ItemTypes.EMERALD, ItemTypes.GOLD_INGOT, ItemTypes.IRON_INGOT, ItemTypes.LAPIS_LAZULI, ItemTypes.NETHERITE_INGOT, ItemTypes.QUARTZ, ItemTypes.REDSTONE, ItemTypes.RESIN_BRICK);
ItemTags.DECORATED_POT_SHERDS.add(ItemTypes.ANGLER_POTTERY_SHERD, ItemTypes.ARCHER_POTTERY_SHERD, ItemTypes.ARMS_UP_POTTERY_SHERD, ItemTypes.BLADE_POTTERY_SHERD, ItemTypes.BREWER_POTTERY_SHERD, ItemTypes.BURN_POTTERY_SHERD, ItemTypes.DANGER_POTTERY_SHERD, ItemTypes.EXPLORER_POTTERY_SHERD, ItemTypes.FRIEND_POTTERY_SHERD, ItemTypes.HEART_POTTERY_SHERD, ItemTypes.HEARTBREAK_POTTERY_SHERD, ItemTypes.HOWL_POTTERY_SHERD, ItemTypes.MINER_POTTERY_SHERD, ItemTypes.MOURNER_POTTERY_SHERD, ItemTypes.PLENTY_POTTERY_SHERD, ItemTypes.PRIZE_POTTERY_SHERD, ItemTypes.SHEAF_POTTERY_SHERD, ItemTypes.SHELTER_POTTERY_SHERD, ItemTypes.SKULL_POTTERY_SHERD, ItemTypes.SNORT_POTTERY_SHERD, ItemTypes.FLOW_POTTERY_SHERD, ItemTypes.GUSTER_POTTERY_SHERD, ItemTypes.SCRAPE_POTTERY_SHERD);
ItemTags.SWORDS.add(ItemTypes.DIAMOND_SWORD, ItemTypes.STONE_SWORD, ItemTypes.GOLDEN_SWORD, ItemTypes.NETHERITE_SWORD, ItemTypes.WOODEN_SWORD, ItemTypes.IRON_SWORD);
ItemTags.AXES.add(ItemTypes.DIAMOND_AXE, ItemTypes.STONE_AXE, ItemTypes.GOLDEN_AXE, ItemTypes.NETHERITE_AXE, ItemTypes.WOODEN_AXE, ItemTypes.IRON_AXE);
ItemTags.HOES.add(ItemTypes.DIAMOND_HOE, ItemTypes.STONE_HOE, ItemTypes.GOLDEN_HOE, ItemTypes.NETHERITE_HOE, ItemTypes.WOODEN_HOE, ItemTypes.IRON_HOE);
ItemTags.PICKAXES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.WOODEN_PICKAXE, ItemTypes.IRON_PICKAXE);
ItemTags.SHOVELS.add(ItemTypes.DIAMOND_SHOVEL, ItemTypes.STONE_SHOVEL, ItemTypes.GOLDEN_SHOVEL, ItemTypes.NETHERITE_SHOVEL, ItemTypes.WOODEN_SHOVEL, ItemTypes.IRON_SHOVEL);
ItemTags.SWORDS.add(ItemTypes.DIAMOND_SWORD, ItemTypes.STONE_SWORD, ItemTypes.GOLDEN_SWORD, ItemTypes.NETHERITE_SWORD, ItemTypes.WOODEN_SWORD, ItemTypes.IRON_SWORD, ItemTypes.COPPER_SWORD);
ItemTags.AXES.add(ItemTypes.DIAMOND_AXE, ItemTypes.STONE_AXE, ItemTypes.GOLDEN_AXE, ItemTypes.NETHERITE_AXE, ItemTypes.WOODEN_AXE, ItemTypes.IRON_AXE, ItemTypes.COPPER_AXE);
ItemTags.HOES.add(ItemTypes.DIAMOND_HOE, ItemTypes.STONE_HOE, ItemTypes.GOLDEN_HOE, ItemTypes.NETHERITE_HOE, ItemTypes.WOODEN_HOE, ItemTypes.IRON_HOE, ItemTypes.COPPER_HOE);
ItemTags.PICKAXES.add(ItemTypes.DIAMOND_PICKAXE, ItemTypes.STONE_PICKAXE, ItemTypes.GOLDEN_PICKAXE, ItemTypes.NETHERITE_PICKAXE, ItemTypes.WOODEN_PICKAXE, ItemTypes.IRON_PICKAXE, ItemTypes.COPPER_PICKAXE);
ItemTags.SHOVELS.add(ItemTypes.DIAMOND_SHOVEL, ItemTypes.STONE_SHOVEL, ItemTypes.GOLDEN_SHOVEL, ItemTypes.NETHERITE_SHOVEL, ItemTypes.WOODEN_SHOVEL, ItemTypes.IRON_SHOVEL, ItemTypes.COPPER_SHOVEL);
ItemTags.VILLAGER_PLANTABLE_SEEDS.add(ItemTypes.WHEAT_SEEDS, ItemTypes.POTATO, ItemTypes.CARROT, ItemTypes.BEETROOT_SEEDS, ItemTypes.TORCHFLOWER_SEEDS, ItemTypes.PITCHER_POD);
ItemTags.DYEABLE.add(ItemTypes.LEATHER_HELMET, ItemTypes.LEATHER_CHESTPLATE, ItemTypes.LEATHER_LEGGINGS, ItemTypes.LEATHER_BOOTS, ItemTypes.LEATHER_HORSE_ARMOR, ItemTypes.WOLF_ARMOR);
copy(ItemTags.COALS, ItemTags.FURNACE_MINECART_FUEL);
@@ -637,6 +692,7 @@ public class ItemTags {
ItemTags.PIGLIN_PREFERRED_WEAPONS.add(ItemTypes.CROSSBOW);
copy(ItemTags.PIGLIN_PREFERRED_WEAPONS, ItemTags.PILLAGER_PREFERRED_WEAPONS);
ItemTags.WITHER_SKELETON_DISLIKED_WEAPONS.add(ItemTypes.BOW, ItemTypes.CROSSBOW);
ItemTags.SHEARABLE_FROM_COPPER_GOLEM.add(ItemTypes.POPPY);
ItemTags.ENCHANTABLE_FISHING.add(ItemTypes.FISHING_ROD);
copy(ItemTags.DROWNED_PREFERRED_WEAPONS, ItemTags.ENCHANTABLE_TRIDENT);
copy(ItemTags.SKELETON_PREFERRED_WEAPONS, ItemTags.ENCHANTABLE_BOW);
@@ -0,0 +1,33 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.world.states.enums;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public enum CopperGolemPose {
STANDING,
SITTING,
RUNNING,
STAR,
}
@@ -0,0 +1,33 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.world.states.enums;
import org.jspecify.annotations.NullMarked;
/**
* @versions 1.21.9+
*/
@NullMarked
public enum SideChainPart {
UNCONNECTED,
RIGHT,
CENTER,
LEFT,
}
@@ -418,6 +418,10 @@ public final class StateTypes {
public static StateType RED_MUSHROOM_BLOCK = StateTypes.builder().name("RED_MUSHROOM_BLOCK").blastResistance(0.2f).hardness(0.2f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
public static StateType MUSHROOM_STEM = StateTypes.builder().name("MUSHROOM_STEM").blastResistance(0.2f).hardness(0.2f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
public static StateType IRON_BARS = StateTypes.builder().name("IRON_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.6-1.21.8
*/
@ApiStatus.Obsolete
public static StateType CHAIN = StateTypes.builder().name("CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
public static StateType GLASS_PANE = StateTypes.builder().name("GLASS_PANE").blastResistance(0.3f).hardness(0.3f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.GLASS).build();
public static StateType MELON = StateTypes.builder().name("MELON").blastResistance(1.0f).hardness(1.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.VEGETABLE).build();
@@ -1213,9 +1217,258 @@ public final class StateTypes {
public static StateType FIREFLY_BUSH = StateTypes.builder().name("FIREFLY_BUSH").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.PLANT).build();
/**
* Added with 1.21.6
* @versions 1.21.6+
*/
public static StateType DRIED_GHAST = StateTypes.builder().name("DRIED_GHAST").blastResistance(0.0f).hardness(0.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.STONE).build();
/**
* @versions 1.21.9+
*/
public static StateType ACACIA_SHELF = StateTypes.builder().name("ACACIA_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType BAMBOO_SHELF = StateTypes.builder().name("BAMBOO_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType BIRCH_SHELF = StateTypes.builder().name("BIRCH_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType CHERRY_SHELF = StateTypes.builder().name("CHERRY_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType CRIMSON_SHELF = StateTypes.builder().name("CRIMSON_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType DARK_OAK_SHELF = StateTypes.builder().name("DARK_OAK_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType JUNGLE_SHELF = StateTypes.builder().name("JUNGLE_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType MANGROVE_SHELF = StateTypes.builder().name("MANGROVE_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType OAK_SHELF = StateTypes.builder().name("OAK_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType PALE_OAK_SHELF = StateTypes.builder().name("PALE_OAK_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType SPRUCE_SHELF = StateTypes.builder().name("SPRUCE_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType WARPED_SHELF = StateTypes.builder().name("WARPED_SHELF").blastResistance(3.0f).hardness(2.0f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.WOOD).build();
/**
* @versions 1.21.9+
*/
public static StateType COPPER_TORCH = StateTypes.builder().name("COPPER_TORCH").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.DECORATION).build();
/**
* @versions 1.21.9+
*/
public static StateType COPPER_WALL_TORCH = StateTypes.builder().name("COPPER_WALL_TORCH").blastResistance(0.0f).hardness(0.0f).isBlocking(false).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.DECORATION).build();
/**
* @versions 1.21.9+
*/
public static StateType COPPER_BARS = StateTypes.builder().name("COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType EXPOSED_COPPER_BARS = StateTypes.builder().name("EXPOSED_COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WEATHERED_COPPER_BARS = StateTypes.builder().name("WEATHERED_COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType OXIDIZED_COPPER_BARS = StateTypes.builder().name("OXIDIZED_COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_COPPER_BARS = StateTypes.builder().name("WAXED_COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_EXPOSED_COPPER_BARS = StateTypes.builder().name("WAXED_EXPOSED_COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_WEATHERED_COPPER_BARS = StateTypes.builder().name("WAXED_WEATHERED_COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_OXIDIZED_COPPER_BARS = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_BARS").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType IRON_CHAIN = StateTypes.builder().name("IRON_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType COPPER_CHAIN = StateTypes.builder().name("COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType EXPOSED_COPPER_CHAIN = StateTypes.builder().name("EXPOSED_COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WEATHERED_COPPER_CHAIN = StateTypes.builder().name("WEATHERED_COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType OXIDIZED_COPPER_CHAIN = StateTypes.builder().name("OXIDIZED_COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_COPPER_CHAIN = StateTypes.builder().name("WAXED_COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_EXPOSED_COPPER_CHAIN = StateTypes.builder().name("WAXED_EXPOSED_COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_WEATHERED_COPPER_CHAIN = StateTypes.builder().name("WAXED_WEATHERED_COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_OXIDIZED_COPPER_CHAIN = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_CHAIN").blastResistance(6.0f).hardness(5.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType COPPER_LANTERN = StateTypes.builder().name("COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType EXPOSED_COPPER_LANTERN = StateTypes.builder().name("EXPOSED_COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WEATHERED_COPPER_LANTERN = StateTypes.builder().name("WEATHERED_COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType OXIDIZED_COPPER_LANTERN = StateTypes.builder().name("OXIDIZED_COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_COPPER_LANTERN = StateTypes.builder().name("WAXED_COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_EXPOSED_COPPER_LANTERN = StateTypes.builder().name("WAXED_EXPOSED_COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_WEATHERED_COPPER_LANTERN = StateTypes.builder().name("WAXED_WEATHERED_COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_OXIDIZED_COPPER_LANTERN = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_LANTERN").blastResistance(3.5f).hardness(3.5f).isBlocking(true).requiresCorrectTool(false).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType COPPER_CHEST = StateTypes.builder().name("COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType EXPOSED_COPPER_CHEST = StateTypes.builder().name("EXPOSED_COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WEATHERED_COPPER_CHEST = StateTypes.builder().name("WEATHERED_COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType OXIDIZED_COPPER_CHEST = StateTypes.builder().name("OXIDIZED_COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_COPPER_CHEST = StateTypes.builder().name("WAXED_COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_EXPOSED_COPPER_CHEST = StateTypes.builder().name("WAXED_EXPOSED_COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_WEATHERED_COPPER_CHEST = StateTypes.builder().name("WAXED_WEATHERED_COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_OXIDIZED_COPPER_CHEST = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_CHEST").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType COPPER_GOLEM_STATUE = StateTypes.builder().name("COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType EXPOSED_COPPER_GOLEM_STATUE = StateTypes.builder().name("EXPOSED_COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WEATHERED_COPPER_GOLEM_STATUE = StateTypes.builder().name("WEATHERED_COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType OXIDIZED_COPPER_GOLEM_STATUE = StateTypes.builder().name("OXIDIZED_COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_COPPER_GOLEM_STATUE = StateTypes.builder().name("WAXED_COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_EXPOSED_COPPER_GOLEM_STATUE = StateTypes.builder().name("WAXED_EXPOSED_COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_WEATHERED_COPPER_GOLEM_STATUE = StateTypes.builder().name("WAXED_WEATHERED_COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_OXIDIZED_COPPER_GOLEM_STATUE = StateTypes.builder().name("WAXED_OXIDIZED_COPPER_GOLEM_STATUE").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(false).isSolid(false).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType EXPOSED_LIGHTNING_ROD = StateTypes.builder().name("EXPOSED_LIGHTNING_ROD").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WEATHERED_LIGHTNING_ROD = StateTypes.builder().name("WEATHERED_LIGHTNING_ROD").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType OXIDIZED_LIGHTNING_ROD = StateTypes.builder().name("OXIDIZED_LIGHTNING_ROD").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_LIGHTNING_ROD = StateTypes.builder().name("WAXED_LIGHTNING_ROD").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_EXPOSED_LIGHTNING_ROD = StateTypes.builder().name("WAXED_EXPOSED_LIGHTNING_ROD").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_WEATHERED_LIGHTNING_ROD = StateTypes.builder().name("WAXED_WEATHERED_LIGHTNING_ROD").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
/**
* @versions 1.21.9+
*/
public static StateType WAXED_OXIDIZED_LIGHTNING_ROD = StateTypes.builder().name("WAXED_OXIDIZED_LIGHTNING_ROD").blastResistance(6.0f).hardness(3.0f).isBlocking(true).requiresCorrectTool(true).isSolid(true).setMaterial(MaterialType.METAL).build();
// </editor-fold>
static {
@@ -21,6 +21,7 @@ package com.github.retrooper.packetevents.protocol.world.states.type;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.protocol.world.states.enums.Attachment;
import com.github.retrooper.packetevents.protocol.world.states.enums.Axis;
import com.github.retrooper.packetevents.protocol.world.states.enums.CopperGolemPose;
import com.github.retrooper.packetevents.protocol.world.states.enums.CreakingHeartState;
import com.github.retrooper.packetevents.protocol.world.states.enums.East;
import com.github.retrooper.packetevents.protocol.world.states.enums.Face;
@@ -34,6 +35,7 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.Orientation
import com.github.retrooper.packetevents.protocol.world.states.enums.Part;
import com.github.retrooper.packetevents.protocol.world.states.enums.SculkSensorPhase;
import com.github.retrooper.packetevents.protocol.world.states.enums.Shape;
import com.github.retrooper.packetevents.protocol.world.states.enums.SideChainPart;
import com.github.retrooper.packetevents.protocol.world.states.enums.South;
import com.github.retrooper.packetevents.protocol.world.states.enums.Thickness;
import com.github.retrooper.packetevents.protocol.world.states.enums.Tilt;
@@ -163,9 +165,17 @@ public enum StateValue {
*/
MAP("map", boolean.class, Boolean::parseBoolean),
/**
* Added with 1.21.6
* @versions 1.21.6+
*/
HYDRATION("hydration", int.class, Integer::parseInt)
HYDRATION("hydration", int.class, Integer::parseInt),
/**
* @versions 1.21.9+
*/
SIDE_CHAIN("side_chain", SideChainPart.class, SideChainPart::valueOf),
/**
* @versions 1.21.9+
*/
COPPER_GOLEM_POSE("copper_golem_pose", CopperGolemPose.class, CopperGolemPose::valueOf),
;
public static final Index<String, StateValue> NAME_INDEX = Index.create(
@@ -20,11 +20,12 @@ package com.github.retrooper.packetevents.resources;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.util.NbtCodec;
import com.github.retrooper.packetevents.protocol.util.NbtCodecs;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jspecify.annotations.NullMarked;
@@ -33,6 +34,9 @@ import java.util.Objects;
@NullMarked
public class ResourceLocation implements Keyed {
public static final NbtCodec<ResourceLocation> CODEC = NbtCodecs.STRING
.apply(ResourceLocation::new, ResourceLocation::toString);
public static final String VANILLA_NAMESPACE = "minecraft";
protected final String namespace;
@@ -44,4 +44,13 @@ public final class MathUtil {
int temp = (int) value;
return value < (float) temp ? temp - 1 : temp;
}
public static long ceilLong(double value) {
long temp = (long) value;
return value > (double) temp ? temp + 1L : temp;
}
public static double absMax(double a, double b) {
return Math.max(Math.abs(a), Math.abs(b));
}
}
@@ -0,0 +1,58 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.util;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
@NullMarked
public final class Vector2i {
private final int x;
private final int z;
public Vector2i(int x, int z) {
this.x = x;
this.z = z;
}
public static Vector2i read(PacketWrapper<?> wrapper) {
return fromLong(wrapper.readLong());
}
public static void write(PacketWrapper<?> wrapper, Vector2i vec) {
wrapper.writeLong(vec.asLong());
}
public static Vector2i fromLong(long l) {
return new Vector2i((int) l, (int) (l >> 32));
}
public long asLong() {
return ((long) this.x & 0xFFFFFFFFL) | (((long) this.z & 0xFFFFFFFFL) << 32);
}
public int getX() {
return this.x;
}
public int getZ() {
return this.z;
}
}
@@ -38,6 +38,9 @@ import java.util.Objects;
* @since 1.8
*/
public class Vector3d {
private static final Vector3d ZERO = new Vector3d();
/**
* X (coordinate/angle/whatever you wish)
*/
@@ -268,6 +271,6 @@ public class Vector3d {
}
public static Vector3d zero() {
return new Vector3d();
return ZERO;
}
}
@@ -19,61 +19,29 @@
package com.github.retrooper.packetevents.util.adventure;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemProfile;
import com.github.retrooper.packetevents.protocol.dialog.Dialog;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTByte;
import com.github.retrooper.packetevents.protocol.nbt.NBTByteArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTDouble;
import com.github.retrooper.packetevents.protocol.nbt.NBTFloat;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTIntArray;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTLong;
import com.github.retrooper.packetevents.protocol.nbt.NBTLongArray;
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.nbt.*;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.util.UniqueIdUtil;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.text.BlockNBTComponent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.EntityNBTComponent;
import net.kyori.adventure.text.KeybindComponent;
import net.kyori.adventure.text.NBTComponent;
import net.kyori.adventure.text.ScoreComponent;
import net.kyori.adventure.text.SelectorComponent;
import net.kyori.adventure.text.StorageNBTComponent;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.TranslationArgument;
import net.kyori.adventure.text.*;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.DataComponentValue;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.ShadowColor;
import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.format.*;
import net.kyori.adventure.text.object.ObjectContents;
import net.kyori.adventure.text.object.PlayerHeadObjectContents;
import net.kyori.adventure.text.object.SpriteObjectContents;
import net.kyori.adventure.text.serializer.ComponentSerializer;
import net.kyori.adventure.text.serializer.gson.BackwardCompatUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -225,6 +193,8 @@ public class AdventureNBTSerializer implements ComponentSerializer<Component, Co
Key nbtStorage = reader.readUTF("storage", Key::key);
List<Component> extra = reader.readList("extra", tag -> this.deserializeComponentList(tag, wrapper));
Component separator = reader.read("separator", tag -> this.deserialize(tag, wrapper));
NBT player = reader.read("player", Function.identity());
String sprite = reader.readUTF("sprite", Function.identity());
Style style = this.deserializeStyle(compound, wrapper);
// build component from read values
@@ -268,6 +238,28 @@ public class AdventureNBTSerializer implements ComponentSerializer<Component, Co
} else {
throw new IllegalStateException("Illegal nbt component, block/entity/storage is missing");
}
} else if (player != null) {
if (BackwardCompatUtil.IS_4_25_0_OR_NEWER) {
ItemProfile profile = ItemProfile.decode(player, wrapper);
PlayerHeadObjectContents playerHead = ObjectContents.playerHead()
.id(profile.getId()).name(profile.getName())
.profileProperties(profile.getAdventureProperties())
.hat(Optional.ofNullable(reader.readBoolean("hat", Function.identity())).orElse(true))
.build();
builder = Component.object().contents(playerHead);
} else {
builder = Component.text();
}
} else if (sprite != null) {
if (BackwardCompatUtil.IS_4_25_0_OR_NEWER) {
Key spriteKey = Key.key(sprite);
Key atlasKey = reader.readUTF("atlas", atlas -> Key.key(atlas));
builder = Component.object().contents(atlasKey != null
? ObjectContents.sprite(atlasKey, spriteKey)
: ObjectContents.sprite(spriteKey));
} else {
builder = Component.text();
}
} else {
throw new IllegalStateException("Illegal nbt component, component type could not be determined");
}
@@ -373,6 +365,38 @@ public class AdventureNBTSerializer implements ComponentSerializer<Component, Co
Key storage = ((StorageNBTComponent) component).storage();
writer.writeUTF("storage", storage.asString());
}
} else if (component instanceof ObjectComponent) {
if (BackwardCompatUtil.IS_4_25_0_OR_NEWER && this.version.isNewerThanOrEquals(ClientVersion.V_1_21_9)) {
// object contents
ObjectContents objectContents = ((ObjectComponent) component).contents();
if (objectContents instanceof PlayerHeadObjectContents) {
// player head object
PlayerHeadObjectContents playerHead = ((PlayerHeadObjectContents) objectContents);
// player head profile
ItemProfile profile = ItemProfile.fromAdventure(playerHead);
writer.write("player", ItemProfile.encode(wrapper, profile));
// player head hat
if (playerHead.hat() != PlayerHeadObjectContents.DEFAULT_HAT) {
writer.writeBoolean("hat", playerHead.hat());
}
} else if (objectContents instanceof SpriteObjectContents) {
// sprite object
SpriteObjectContents spriteObjectContents = ((SpriteObjectContents) objectContents);
// atlas
if (!spriteObjectContents.atlas().equals(SpriteObjectContents.DEFAULT_ATLAS)) {
writer.writeUTF("atlas", spriteObjectContents.atlas().toString());
}
// sprite
writer.writeUTF("sprite", spriteObjectContents.sprite().toString());
}
} else {
// skip
writer.writeUTF("text", "");
}
}
if (component.hasStyling()) {
@@ -476,6 +500,7 @@ public class AdventureNBTSerializer implements ComponentSerializer<Component, Co
}
NBTReader item = modernEvents ? hoverEvent : hoverEvent.child("contents");
if (item == null) break;
Key itemId = item.readUTF("id", Key::key);
Integer count = item.readNumber("count", Number::intValue);
int nonNullCount = count == null ? 1 : count;
@@ -503,10 +528,12 @@ public class AdventureNBTSerializer implements ComponentSerializer<Component, Co
break;
case "show_entity":
NBTReader entity = modernEvents ? hoverEvent : hoverEvent.child("contents");
style.hoverEvent(HoverEvent.showEntity(
entity.readUTF(modernEvents ? "id" : "type", Key::key),
entity.readIntArray(modernEvents ? "uuid" : "id", UniqueIdUtil::fromIntArray),
entity.read("name", name -> this.deserialize(name, wrapper))));
if (entity != null) {
style.hoverEvent(HoverEvent.showEntity(
entity.readUTF(modernEvents ? "id" : "type", Key::key),
entity.readIntArray(modernEvents ? "uuid" : "id", UniqueIdUtil::fromIntArray),
entity.read("name", name -> this.deserialize(name, wrapper))));
}
break;
}
}
@@ -637,10 +664,12 @@ public class AdventureNBTSerializer implements ComponentSerializer<Component, Co
case "show_entity":
HoverEvent.ShowEntity showEntity = (HoverEvent.ShowEntity) hoverEvent.value();
NBTWriter entity = modern ? child : child.child("contents");
entity.writeUTF(modern ? "id" : "type", showEntity.type().asString());
entity.writeIntArray(modern ? "uuid" : "id", UniqueIdUtil.toIntArray(showEntity.id()));
if (showEntity.name() != null) {
entity.write("name", this.serialize(showEntity.name(), wrapper));
if (entity != null) {
entity.writeUTF(modern ? "id" : "type", showEntity.type().asString());
entity.writeIntArray(modern ? "uuid" : "id", UniqueIdUtil.toIntArray(showEntity.id()));
if (showEntity.name() != null) {
entity.write("name", this.serialize(showEntity.name(), wrapper));
}
}
break;
}
@@ -226,24 +226,34 @@ public final class AdventureSerializer implements NbtEncoder<Component>, NbtDeco
if (this.gson == null) {
this.gson = GsonComponentSerializer.builder()
.editOptions(builder -> {
builder
.values(JSONOptions.byDataVersion().at(0))
.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.BOTH)
.value(JSONOptions.SHOW_ITEM_HOVER_DATA_MODE, JSONOptions.ShowItemHoverDataMode.EMIT_EITHER);
if (this.version.isNewerThanOrEquals(ClientVersion.V_1_16)
&& !PacketEvents.getAPI().getSettings().shouldDownsampleColors()) {
builder.value(JSONOptions.EMIT_RGB, true);
builder.values(JSONOptions.byDataVersion().at(0));
if (this.version.isNewerThanOrEquals(ClientVersion.V_1_16)) {
builder.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.CAMEL_CASE);
if (!PacketEvents.getAPI().getSettings().shouldDownsampleColors()) {
builder.value(JSONOptions.EMIT_RGB, true);
}
}
if (this.version.isNewerThanOrEquals(ClientVersion.V_1_20_3)) {
builder.value(JSONOptions.EMIT_COMPACT_TEXT_COMPONENT, true);
builder.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, true);
builder.value(JSONOptions.VALIDATE_STRICT_EVENTS, true);
}
if (this.version.isNewerThanOrEquals(ClientVersion.V_1_20_5)) {
builder.value(JSONOptions.EMIT_DEFAULT_ITEM_HOVER_QUANTITY, true);
builder.value(JSONOptions.SHOW_ITEM_HOVER_DATA_MODE, JSONOptions.ShowItemHoverDataMode.EMIT_DATA_COMPONENTS);
}
if (this.version.isNewerThanOrEquals(ClientVersion.V_1_21_4)) {
builder.value(JSONOptions.SHADOW_COLOR_MODE, JSONOptions.ShadowColorEmitMode.EMIT_INTEGER);
}
if (this.version.isNewerThanOrEquals(ClientVersion.V_1_21_5)) {
builder.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.SNAKE_CASE);
builder.value(JSONOptions.EMIT_CLICK_EVENT_TYPE, JSONOptions.ClickEventValueMode.SNAKE_CASE);
builder.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_KEY_AS_TYPE_AND_UUID_AS_ID, false);
builder.value(JSONOptions.EMIT_CLICK_URL_HTTPS, true);
}
if (this.version.isNewerThanOrEquals(ClientVersion.V_1_21_6)) {
builder.value(JSONOptions.EMIT_CHANGE_PAGE_CLICK_EVENT_PAGE_AS_STRING, false);
}
})
.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get())
.showAchievementToComponent(input -> Statistics.getById(input).display())
@@ -98,7 +98,8 @@ public class TypesBuilder {
final Consumer<ClientVersion> mapLoader = version -> {
final Map<String, Integer> map = new HashMap<>();
for (int i = 0; i < lastEntries.size(); i++) {
int size = lastEntries.size();
for (int i = 0; i < size; i++) {
map.put(lastEntries.get(i), i);
}
this.entries.put(version, map);
@@ -51,15 +51,8 @@ import com.github.retrooper.packetevents.manager.server.VersionComparison;
import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper;
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
import com.github.retrooper.packetevents.protocol.PacketSide;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.ChatTypes;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.MessageSignature;
import com.github.retrooper.packetevents.protocol.chat.Node;
import com.github.retrooper.packetevents.protocol.chat.Parsers;
import com.github.retrooper.packetevents.protocol.chat.*;
import com.github.retrooper.packetevents.protocol.chat.Parsers.Parser;
import com.github.retrooper.packetevents.protocol.chat.RemoteChatSession;
import com.github.retrooper.packetevents.protocol.chat.SignedCommandArgument;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMaskType;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
@@ -90,11 +83,7 @@ import com.github.retrooper.packetevents.protocol.recipe.data.MerchantOffer;
import com.github.retrooper.packetevents.protocol.world.Dimension;
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Either;
import com.github.retrooper.packetevents.util.KnownPack;
import com.github.retrooper.packetevents.util.MathUtil;
import com.github.retrooper.packetevents.util.StringUtil;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.util.*;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.util.crypto.MinecraftEncryptionUtil;
import com.github.retrooper.packetevents.util.crypto.SaltSignature;
@@ -113,16 +102,7 @@ import java.lang.reflect.Array;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.EnumSet;
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.BiFunction;
import java.util.function.Function;
@@ -388,6 +368,10 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
ByteBufHelper.writeInt(buffer, value);
}
public long readUnsignedInt() {
return ByteBufHelper.readUnsignedInt(buffer);
}
public int readMedium() {
return ByteBufHelper.readMedium(buffer);
}
@@ -665,6 +649,10 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
ByteBufHelper.writeShort(buffer, value);
}
public void writeShortLE(int value) {
ByteBufHelper.writeShortLE(buffer, value);
}
public int readVarShort() {
int low = readUnsignedShort();
int high = 0;
@@ -1403,6 +1391,21 @@ public class PacketWrapper<T extends PacketWrapper<T>> {
}
}
public <K> Set<K> readSet(Reader<K> reader) {
return this.readCollection(HashSet::new, reader);
}
public <K> Set<K> readSet(Reader<K> reader, int maxSize) {
return this.readCollection(HashSet::new, reader, maxSize);
}
public <K> void writeSet(Set<K> set, Writer<K> writer) {
this.writeVarInt(set.size());
for (K key : set) {
writer.accept(this, key);
}
}
@SuppressWarnings("unchecked") // not unchecked
public <K> K[] readArray(Reader<K> reader, Class<K> clazz) {
int length = this.readVarInt();
@@ -0,0 +1,41 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.configuration.client;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* Mojang name: ServerboundAcceptCodeOfConductPacket
*
* @versions 1.21.9+
*/
@NullMarked
public class WrapperConfigClientAcceptCodeOfConduct extends PacketWrapper<WrapperConfigClientAcceptCodeOfConduct> {
public WrapperConfigClientAcceptCodeOfConduct(PacketReceiveEvent event) {
super(event);
}
public WrapperConfigClientAcceptCodeOfConduct() {
super(PacketType.Configuration.Client.ACCEPT_CODE_OF_CONDUCT);
}
}
@@ -0,0 +1,67 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.configuration.server;
import com.github.retrooper.packetevents.event.PacketSendEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
/**
* Mojang name: ClientboundCodeOfConductPacket
*
* @versions 1.21.9+
*/
@NullMarked
public class WrapperConfigServerCodeOfConduct extends PacketWrapper<WrapperConfigServerCodeOfConduct> {
private String codeOfConduct;
public WrapperConfigServerCodeOfConduct(PacketSendEvent event) {
super(event);
}
public WrapperConfigServerCodeOfConduct(String codeOfConduct) {
super(PacketType.Configuration.Server.CODE_OF_CONDUCT);
this.codeOfConduct = codeOfConduct;
}
@Override
public void read() {
this.codeOfConduct = this.readString();
}
@Override
public void write() {
this.writeString(this.codeOfConduct);
}
@Override
public void copy(WrapperConfigServerCodeOfConduct wrapper) {
this.codeOfConduct = wrapper.codeOfConduct;
}
public String getCodeOfConduct() {
return this.codeOfConduct;
}
public void setCodeOfConduct(String codeOfConduct) {
this.codeOfConduct = codeOfConduct;
}
}
@@ -26,8 +26,10 @@ import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -62,7 +64,7 @@ public class WrapperPlayClientClickWindow extends PacketWrapper<WrapperPlayClien
/**
* Added with 1.21.5
*/
private @Nullable Optional<HashedStack> carriedHashedStack;
private @Nullable HashedStack carriedHashedStack;
public WrapperPlayClientClickWindow(PacketReceiveEvent event) {
super(event);
@@ -100,28 +102,31 @@ public class WrapperPlayClientClickWindow extends PacketWrapper<WrapperPlayClien
this.button = button;
this.windowClickType = windowClickType;
this.hashedSlots = hashedSlots;
this.carriedHashedStack = carriedHashedStack;
this.carriedHashedStack = carriedHashedStack != null
? carriedHashedStack.orElse(null) : null;
}
@Override
public void read() {
boolean v1_17 = this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_17);
this.windowID = this.readContainerId();
this.stateID = this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_17_1) ? this.readVarInt() : null;
this.slot = this.readShort();
this.button = this.readByte();
this.actionNumber = v1_17 ? null : (int) this.readShort();
this.actionNumber = this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_17) ? null : (int) this.readShort();
this.windowClickType = WindowClickType.getById(this.readVarInt());
readSlots();
}
protected void readSlots() {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
this.hashedSlots = this.readMap(
ew -> Math.toIntExact(ew.readShort()),
HashedStack::read,
HashedStack::readOptional,
MAX_SLOT_COUNT
);
this.carriedHashedStack = HashedStack.read(this);
} else {
if (v1_17) {
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_17)) {
this.slots = this.readMap(
packetWrapper -> Math.toIntExact(packetWrapper.readShort()),
PacketWrapper::readItemStack
@@ -160,7 +165,7 @@ public class WrapperPlayClientClickWindow extends PacketWrapper<WrapperPlayClien
this.writeVarInt(this.windowClickType.ordinal());
if (this.serverVersion.isNewerThanOrEquals(ServerVersion.V_1_21_5)) {
this.writeMap(this.hashedSlots != null ? this.hashedSlots : Collections.emptyMap(),
PacketWrapper::writeShort, HashedStack::write);
PacketWrapper::writeShort, HashedStack::writeOptional);
HashedStack.write(this, this.carriedHashedStack);
} else {
if (v1_17) {
@@ -236,21 +241,49 @@ public class WrapperPlayClientClickWindow extends PacketWrapper<WrapperPlayClien
/**
* Added with 1.17, not actually optional; Removed with 1.21.5, replaced with {@link #getHashedSlots()}
*/
@ApiStatus.Obsolete
public Optional<Map<Integer, ItemStack>> getSlots() {
return Optional.ofNullable(this.slots);
if (this.slots != null) {
return Optional.of(this.slots);
} else if (this.hashedSlots != null) {
Map<Integer, ItemStack> ret = new HashMap<>(this.hashedSlots.size());
for (Map.Entry<Integer, Optional<HashedStack>> entry : this.hashedSlots.entrySet()) {
HashedStack stack = entry.getValue().orElse(null);
ret.put(entry.getKey(), stack != null ? stack.asItemStack() : ItemStack.EMPTY);
}
return Optional.of(ret);
}
return Optional.empty();
}
/**
* Added with 1.17, not actually optional; Removed with 1.21.5, replaced with {@link #setHashedSlots(Map)}
*/
@ApiStatus.Obsolete
public void setSlots(Map<Integer, ItemStack> slots) {
this.setSlots(Optional.ofNullable(slots));
}
/**
* Added with 1.17, not actually optional; Removed with 1.21.5, replaced with {@link #setHashedSlots(Map)}
*/
@ApiStatus.Obsolete
public void setSlots(Optional<Map<Integer, ItemStack>> slots) {
this.slots = slots.orElse(null);
if (this.slots != null) {
this.hashedSlots = new HashMap<>(this.slots.size());
for (Map.Entry<Integer, ItemStack> entry : this.slots.entrySet()) {
this.hashedSlots.put(entry.getKey(), HashedStack.toOptionalFromItemStack(entry.getValue()));
}
} else {
this.hashedSlots = null;
}
}
/**
* Added with 1.21.5
*/
public Map<Integer, Optional<HashedStack>> getHashedSlots() {
public @UnknownNullability Map<Integer, Optional<HashedStack>> getHashedSlots() {
return this.hashedSlots;
}
@@ -264,18 +297,20 @@ public class WrapperPlayClientClickWindow extends PacketWrapper<WrapperPlayClien
/**
* Removed with 1.21.5, replaced with {@link #getCarriedHashedStack()}
*/
@ApiStatus.Obsolete
public ItemStack getCarriedItemStack() {
if (this.carriedItemStack == null && this.carriedHashedStack != null) {
return this.carriedHashedStack
.map(HashedStack::asItemStack)
.orElse(ItemStack.EMPTY);
if (this.carriedItemStack != null) {
return this.carriedItemStack;
} else if (this.carriedHashedStack != null) {
return this.carriedHashedStack.asItemStack();
}
return this.carriedItemStack;
return ItemStack.EMPTY;
}
/**
* Removed with 1.21.5, replaced with {@link #setCarriedHashedStack(Optional)}
* Removed with 1.21.5, replaced with {@link #setCarriedHashedStack(HashedStack)}
*/
@ApiStatus.Obsolete
public void setCarriedItemStack(ItemStack carriedItemStack) {
this.carriedItemStack = carriedItemStack;
this.carriedHashedStack = HashedStack.fromItemStack(carriedItemStack);
@@ -285,14 +320,21 @@ public class WrapperPlayClientClickWindow extends PacketWrapper<WrapperPlayClien
* Added with 1.21.5
*/
public Optional<HashedStack> getCarriedHashedStack() {
return this.carriedHashedStack;
return Optional.ofNullable(this.carriedHashedStack);
}
/**
* Added with 1.21.5
*/
public void setCarriedHashedStack(@Nullable HashedStack carriedHashedStack) {
this.carriedHashedStack = carriedHashedStack;
}
/**
* Added with 1.21.5
*/
public void setCarriedHashedStack(Optional<HashedStack> carriedHashedStack) {
this.carriedHashedStack = carriedHashedStack;
this.carriedHashedStack = carriedHashedStack.orElse(null);
}
public enum WindowClickType {
@@ -22,7 +22,14 @@ import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerDebugSample.SampleType;
import org.jetbrains.annotations.ApiStatus;
/**
* Mojang name: ServerboundDebugSampleSubscriptionPacket
*
* @versions 1.21.5-1.21.8
*/
@ApiStatus.Obsolete
public class WrapperPlayClientDebugSampleSubscription extends PacketWrapper<WrapperPlayClientDebugSampleSubscription> {
private SampleType sampleType;
@@ -0,0 +1,71 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2025 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.wrapper.play.client;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.debug.DebugSubscription;
import com.github.retrooper.packetevents.protocol.debug.DebugSubscriptions;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jspecify.annotations.NullMarked;
import java.util.Set;
/**
* Mojang name: ServerboundDebugSubscriptionRequestPacket
*
* @versions 1.21.9+
*/
@NullMarked
public class WrapperPlayClientDebugSubscriptionRequest extends PacketWrapper<WrapperPlayClientDebugSubscriptionRequest> {
private Set<DebugSubscription<?>> subscriptions;
public WrapperPlayClientDebugSubscriptionRequest(PacketReceiveEvent event) {
super(event);
}
public WrapperPlayClientDebugSubscriptionRequest(Set<DebugSubscription<?>> subscriptions) {
super(PacketType.Play.Client.DEBUG_SUBSCRIPTION_REQUEST);
this.subscriptions = subscriptions;
}
@Override
public void read() {
this.subscriptions = this.readSet(ew -> ew.readMappedEntity(DebugSubscriptions.getRegistry()));
}
@Override
public void write() {
this.writeSet(this.subscriptions, PacketWrapper::writeMappedEntity);
}
@Override
public void copy(WrapperPlayClientDebugSubscriptionRequest wrapper) {
this.subscriptions = wrapper.subscriptions;
}
public Set<DebugSubscription<?>> getSubscriptions() {
return this.subscriptions;
}
public void setSubscriptions(Set<DebugSubscription<?>> subscriptions) {
this.subscriptions = subscriptions;
}
}
@@ -33,6 +33,10 @@ public class WrapperPlayServerBlockChange extends PacketWrapper<WrapperPlayServe
super(event);
}
public WrapperPlayServerBlockChange(Vector3i blockPosition, WrappedBlockState state) {
this(blockPosition, state.getGlobalId());
}
public WrapperPlayServerBlockChange(Vector3i blockPosition, int blockID) {
super(PacketType.Play.Server.BLOCK_CHANGE);
this.blockPosition = blockPosition;
@@ -194,8 +194,13 @@ public class WrapperPlayServerChunkData extends PacketWrapper<WrapperPlayServerC
// verify the full chunk has been read
int readerIndex = ByteBufHelper.readerIndex(this.buffer);
if (expectedReaderIndex != readerIndex) {
throw new RuntimeException("Error while decoding chunk at " + chunkX + " " + chunkZ
+ "; expected reader index " + expectedReaderIndex + ", got " + readerIndex);
if (expectedReaderIndex < readerIndex) {
// we advanced too far, error
throw new RuntimeException("Error while decoding chunk at " + chunkX + " " + chunkZ
+ "; expected reader index " + expectedReaderIndex + ", got " + readerIndex);
}
// we didn't read the whole buffer, skip the rest
ByteBufHelper.readerIndex(this.buffer, expectedReaderIndex);
}
} finally {
// change buffer back if it has been switched
Loaded 100 of 180 files, more files were not shown because too many files have changed in this diff. Show more