Compare commits

...
564 Commits
Author SHA1 Message Date
retrooper 3400877958 Release of 2.4.0 2024-06-30 22:56:57 +02:00
retrooper b5a2c0ac29 Merge pull request #865 from cswhite2000/2.0
Switch EventManager listenerSet to CopyOnWriteArraySet
2024-06-30 09:40:48 +02:00
Christopher White c43dd6425a Switch EventManager listenerSet to CopyOnWriteArraySet 2024-06-29 23:21:34 -07:00
retrooper 8b643ae238 Small change of updater messages. 2024-06-30 08:07:55 +02:00
retrooper b07461340e Corrected latest chat type mappings to represent 1.20 2024-06-30 07:59:44 +02:00
retrooper 4cec8fe549 Correct the chat type mappings, temporarily assume that the 1.20.1 is referring to 1.20.2? 2024-06-30 07:56:23 +02:00
booky10 55ea059640 Merge pull request #864 from booky10/fix/sound-mappings-1.21
Fix missing/renamed sounds for 1.21
2024-06-30 05:09:09 +02:00
booky10 5429e80f66 Fix missing/renamed sounds for 1.21 2024-06-30 04:01:06 +02:00
retrooper 16c71fad14 Start working on WolfVariant in EntityMetadata packet. 2024-06-29 00:47:38 +02:00
retrooper d27a97c322 Bump version up to 2.4.0-SNAPSHOT! 2024-06-29 00:46:38 +02:00
retrooper 59ccfa89db Trying out PacketWrapper#writeVarInt optimization, written by Steinborn. 2024-06-29 00:26:55 +02:00
retrooper b6f25939be Correction in javadocs for SpigotConversionUtil 2024-06-29 00:10:23 +02:00
retrooper d19406edf4 Merge pull request #858 from Bram1903/chore/BlockDataMethodCleanup
Removed: Unnecessary 1.7.10 version check and improved JavaDocs
2024-06-29 00:04:29 +02:00
retrooper 0702ff3716 Merge pull request #852 from AbhigyaKrishna/2.0
feat: chat type mappings update
2024-06-29 00:00:22 +02:00
Bram 4577c5a948 Removed: Unnecessary 1.7.10 version check
Added: JavaDocs to SpigotConversionUtil#fromBukkitMaterialData and #toBukkitMaterialData
2024-06-28 16:32:11 +02:00
booky10 d073f716f9 Merge pull request #855 from dawon/bugfix/fix-new-potion-effects
Fix new potion effects
2024-06-27 23:56:06 +02:00
Jakub Zacek 5051c31bea Fix new potion effects 2024-06-27 23:48:47 +02:00
retrooper eb2d91745a Merge pull request #854 from booky10/fix/bungee-compat
Fix more bungee compatibility issues
2024-06-27 21:46:47 +02:00
booky10 9d40bc506e Disable debug mode in bungee plugin 2024-06-27 21:07:29 +02:00
booky10 0fa3be1ce2 Extract channel from player on login
Caused by login success being sent after the PostLoginEvent gets fired
2024-06-27 20:59:28 +02:00
booky10 acecdb57f4 Skip bungeecord query handler handler 2024-06-27 20:58:00 +02:00
retrooper 33d3a72d4d Fix bungee packetevents injector. 2024-06-27 20:18:10 +02:00
retrooper 2ce1fc1e79 Final change to this all 2024-06-27 19:08:56 +02:00
retrooper 63b9e27ebf More changes to the bungee pipeline injector? 2024-06-27 19:04:55 +02:00
retrooper 8093481f08 Last changes to the bungee pipeline injector? 2024-06-27 18:51:35 +02:00
AbhigyaKrishna 629871fcb5 fix: type naming 2024-06-27 21:15:13 +05:30
AbhigyaKrishna d2d9135c45 feat: chat type mappings update 2024-06-27 21:11:15 +05:30
retrooper bf5c3e90b3 Merge pull request #851 from booky10/fix/dimtype-reg-via-velocity
Fix errors on velocity when via is installed on backends
2024-06-27 16:58:01 +02:00
retrooper d100fd54de Delete .travis.yml
We no longer use Travis CI. The Jenkins builds are working again,
2024-06-27 16:54:46 +02:00
retrooper c8137956f1 Merge pull request #799 from booky10/fix/recipe-packet
Fix recipe packet writing/reading
2024-06-27 16:53:18 +02:00
booky10 e7739bac22 Remove MCProtocolLib credits from rewritten classes 2024-06-27 16:36:15 +02:00
booky10 5c9cfcb25d Merge branch '2.0' into fix/recipe-packet 2024-06-27 16:35:08 +02:00
booky10 4364d7a646 Check for dimension type registry name without vanilla namespace 2024-06-27 16:31:57 +02:00
booky10 0ba826f578 Work around missing dimension type registry causing join errors 2024-06-27 16:29:57 +02:00
retrooper 3e21b7d384 Merge pull request #836 from ManInMyVan/#693
Add #693
2024-06-27 16:10:20 +02:00
retrooper b934d7361d Merge pull request #844 from booky10/fix/item-hover-component
Support reading components in show_item hover events
2024-06-27 15:55:59 +02:00
retrooper 4047bafc6a Merge pull request #848 from booky10/feat/itemstack-builder-utils
Add utility methods to ItemStack builder
2024-06-24 17:13:36 +02:00
booky10 27de28476e Add utility methods to ItemStack builder
Allows easier modification of components and nbt data
2024-06-24 15:01:29 +02:00
retrooper e5dfb84a53 Update DefaultNBTSerializer 2024-06-24 00:15:50 +02:00
retrooper 2b3c77b6b8 Update DefaultNBTSerializer to have limit for LONG_ARRAY 2024-06-24 00:15:31 +02:00
retrooper 16294ccc63 Merge pull request #847 from Bram1903/fix/NettyVersionResolving
Fix: Netty Version not being properly converted to an PEVersion
2024-06-23 23:56:50 +02:00
Bram 9ae2cd0538 Fix: Netty Version not being properly converted to an PEVersion due to not using semantic versioning 2024-06-23 23:44:13 +02:00
retrooper 30492a7b1f chores: Format the multi-line comment appropriately and clarify references to the generated PEVersions class 2024-06-23 12:10:29 +02:00
AbhigyaKrishna ecce9d8c4e chores: Added default comment to the generated file 2024-06-23 15:32:23 +05:30
AbhigyaKrishna 448f7be2ae fix: include generateVersionFile task in task graph 2024-06-23 02:49:43 +05:30
Abhigya 4e3c45bc7e Merge pull request #819 from Bram1903/feat/GlobalVersioning
Feat: Global Versioning
2024-06-23 00:46:09 +05:30
AbhigyaKrishna ccd3fd4b7b chores: following some code design 2024-06-22 21:35:47 +05:30
Bram 5003d578c7 Fix: toArray being mend to be called asArray 2024-06-22 17:18:15 +02:00
AbhigyaKrishna 881a66740f feat: Removed version resolution from manifest 2024-06-22 15:39:14 +05:30
AbhigyaKrishna c9ae98814c Merge branch 'feat/GlobalVersioning' of github.com:Bram1903/packetevents into Bram1903-feat/GlobalVersioning 2024-06-22 15:36:43 +05:30
AbhigyaKrishna ee2c562c9e feat: PEVersions file generation 2024-06-22 15:33:36 +05:30
Bram cbd38ea581 Reverted: Previously changed comparison method 2024-06-22 11:08:08 +02:00
Bram 983b27d071 Added: Old toArray method and marked it as deprecated to prevent breaking changes 2024-06-22 10:39:03 +02:00
Bram b2a827e97b Merge branch 'refs/heads/2.0' into feat/GlobalVersioning 2024-06-22 10:31:59 +02:00
AbhigyaKrishna a709e5f746 fix: Velocity adventure issue 2024-06-22 08:13:58 +05:30
AbhigyaKrishna c1f482dd35 feat: MappingCompression task to depend on mapping files 2024-06-22 08:13:31 +05:30
booky10 269ca7ad43 Fix support for adventure <4.17.0 2024-06-22 04:17:14 +02:00
booky10 594f8cdc6e Fix show item hover support for <1.20.3 2024-06-22 04:14:20 +02:00
booky10 187041bd47 Support reading components in show_item hover events 2024-06-22 03:29:55 +02:00
booky10 68eb537b66 Merge pull request #843 from booky10/fix/light-data-1.17-newer
Fix light data throwing errors for 1.17+
2024-06-22 01:56:48 +02:00
AbhigyaKrishna b18884a5b3 fix: manifest implementation version should be in shadowJar 2024-06-22 05:19:26 +05:30
AbhigyaKrishna 061d1c25e8 fix: Version comparison 2024-06-22 04:57:11 +05:30
booky10 b1a881bfab Fix light data throwing errors for 1.17+ 2024-06-22 01:26:48 +02:00
AbhigyaKrishna e68dbe4155 chore: method design pattern 2024-06-22 04:56:39 +05:30
AbhigyaKrishna 60e33ef0a3 Merge branch 'feat/GlobalVersioning' of github.com:Bram1903/packetevents into Bram1903-feat/GlobalVersioning 2024-06-22 04:12:04 +05:30
AbhigyaKrishna eac72687cb Merge branch 'Bram1903-feat/NativeFoliaSupport' into 2.0-pe 2024-06-22 04:03:03 +05:30
AbhigyaKrishna d205d83f61 chore: Property access from a global final isFolia variable
Accessing a global final variable is better than having a copy in every class
2024-06-22 04:01:03 +05:30
AbhigyaKrishna 61969bf9df chore: Work directory set to rootDir
Work directory now set to rootDir for easier navigation
2024-06-22 03:45:46 +05:30
AbhigyaKrishna ed9ff0c5da Merge branch 'feat/NativeFoliaSupport' of https://github.com/Bram1903/packetevents into Bram1903-feat/NativeFoliaSupport 2024-06-22 03:34:20 +05:30
Abhigya 371ec62571 Merge pull request #842 from AbhigyaKrishna/2.0
fix: Fixes NoSuchMethodError for GsonComponentSerializer on version 1.16.5
2024-06-22 03:19:31 +05:30
AbhigyaKrishna 4eaf000dea fix: Fixes NoSuchMethodError for GsonComponentSerializer on version 1.16.5
Fixed NoSuchMethodError in GsonComponentSerializer due to older version of abstract classes in version 1.16.5

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

Related to #741
2024-05-05 02:15:47 +02:00
booky10 803a50542c Add support for components in existing ItemStack nbt utilities
Includes damage, max damage and nbt

Also fixes ItemStack match/equals methods
2024-05-05 01:11:17 +02:00
AoElite 150acb64c3 Merge pull request #742 from booky10/fix/particles-packet
Fix particle packet for 1.20.5+
2024-05-04 18:55:09 -04:00
booky10 009f0a7c13 Fix particle packet for 1.20.5+
Fixes #740
2024-05-05 00:14:28 +02:00
retrooper db99d1f187 Update gradle publish 2024-05-04 00:56:25 +02:00
retrooper 6514b84adf Fix to netty injection on fabric 2024-05-04 00:54:04 +02:00
retrooper e40dfe35b8 Merge pull request #737 from booky10/fix/fabric-adventure-include
Include adventure dependency in fabric recursively
2024-05-04 00:31:30 +02:00
booky10 fee0ff6e26 Include adventure dependency in fabric recursively 2024-05-04 00:30:22 +02:00
retrooper 9ed447164a SpigotConversionUtil for MainHand 2024-05-04 00:27:08 +02:00
retrooper 6102208f45 SpigotConversionUtil#toBukkitPose and fromBukkitPose added 2024-05-04 00:14:06 +02:00
retrooper ec31fb0cbb Merge branch '2.0' of https://github.com/retrooper/packetevents into 2.0 2024-05-03 23:59:45 +02:00
retrooper c4660b4821 Remove random test code in fabric 2024-05-03 23:59:38 +02:00
retrooper 978be6bbcc Merge pull request #736 from booky10/fix/armadillo-state-metadata
Fix armadillo state metadata enum
2024-05-03 23:58:24 +02:00
booky10 ee8b1e9458 Fix armadillo state metadata enum
Fixes #735
2024-05-03 23:54:51 +02:00
retrooper 4fdd047026 Add Fabric to PacketEvents repo 2024-05-03 23:53:53 +02:00
retrooper 5c22920393 Fixing build task order 2024-05-03 19:44:59 +02:00
retrooper 8a18947fd2 Merge pull request #733 from booky10/fix/block-state-properties
Fix block state properties being left unparsed
2024-05-03 19:29:33 +02:00
booky10 bbb3e47a50 Add new attributes for 1.21 2024-05-03 19:27:46 +02:00
AoElite e903aa52e3 Merge pull request #734 from Bram1903/FoliaCompatUtilPatch
Fixed: Paper Schedulers 0 delay handling
2024-05-03 13:27:36 -04:00
Bram 9ff8cf30b4 Fixed: Some paper schedulers that do not allow a delay of 0 in either the initial or regular delay 2024-05-03 18:53:49 +02:00
retrooper 8092bbdb3b Revert "Fix shadowJar build issues"
This reverts commit bff9ef2f6b.
2024-05-03 18:51:42 +02:00
retrooper bff9ef2f6b Fix shadowJar build issues 2024-05-03 18:42:29 +02:00
AoElite cc1bd65841 fix runAtFixedRate tick conversion in AsyncScheduler 2024-05-03 11:54:06 -04:00
booky10 8a84b1fc15 Fix block state properties being left unparsed
Fixes #728
2024-05-03 17:50:45 +02:00
booky10 09ab2ff82b Revert legacy itemtypes being changed 2024-05-03 16:24:55 +02:00
booky10 a59a8e116c Update all itemtypes for 1.21 2024-05-03 16:17:47 +02:00
booky10 9adfa831bf Update block and item tags for 1.21 2024-05-03 16:13:56 +02:00
booky10 3a4daec265 Add item type mappings for 1.21 2024-05-03 16:13:47 +02:00
booky10 de87ca203e Implement painting variant registry 2024-05-03 16:07:04 +02:00
booky10 9957cb3de9 Add 1.21 banner patterns 2024-05-03 15:57:17 +02:00
booky10 2ac60d7055 Add 1.21 version constants 2024-05-03 15:55:07 +02:00
Abhigya 3015f40531 Merge pull request #731 from AbhigyaKrishna/2.0
Mapping generation fix and task upToDate check
2024-05-03 12:53:24 +05:30
AbhigyaKrishna f4e5dab1d8 feat: mapping task upToDate check 2024-05-03 12:51:20 +05:30
AbhigyaKrishna 2792dd4c78 fix: mappings generation issue 2024-05-03 12:50:54 +05:30
AbhigyaKrishna b4d45f0fba Merge remote-tracking branch 'origin/2.0' into 2.0 2024-05-03 03:50:25 +05:30
AoElite 3443a482b3 async runAtFixedRate fix 2024-05-02 18:12:57 -04:00
AbhigyaKrishna d89af56959 feat: mapping task upToDate check 2024-05-03 03:19:54 +05:30
AoElite 80d7c4a5a9 add runAtFixedRate specifically for ticks in AsyncScheduler 2024-05-02 17:36:36 -04:00
retrooper 810b205cfa Merge pull request #709 from Bram1903/FoliaCompatUtilPatch
Folia Compatibility Utility Rewrite
2024-05-02 23:00:48 +02:00
Bram 0c452ab842 Merge branch 'refs/heads/2.0' into FoliaCompatUtilPatch 2024-05-02 18:16:45 +02:00
Abhigya be414fceb6 Merge pull request #727 from AbhigyaKrishna/2.0
Added missing StateValue for 1.20.5
2024-05-02 21:10:27 +05:30
AbhigyaKrishna 95099e9763 feat: added missing StateValue 2024-05-02 21:09:27 +05:30
Bram f806773cbe Merge branch 'refs/heads/2.0' into FoliaCompatUtilPatch 2024-05-02 17:30:04 +02:00
retrooper 9af8bab57f Merge pull request #724 from LeeGodSRC/fix/cb-relocation
fix: Fixed CB Relocation on Paper 1.20.5+
2024-05-02 17:05:27 +02:00
Bram 20c5d9f28a Merge branch 'refs/heads/2.0' into FoliaCompatUtilPatch 2024-05-02 16:42:54 +02:00
Abhigya cbe474dafa Merge pull request #648 from AbhigyaKrishna/mapping-compression
Mapping compression
2024-05-02 19:21:18 +05:30
AbhigyaKrishna af90c6534b feat: updated license 2024-05-02 19:01:46 +05:30
AbhigyaKrishna 4130fcf172 fix: diff patching 2024-05-02 18:58:29 +05:30
AbhigyaKrishna e321a169c2 test: created mapping test 2024-05-02 18:58:01 +05:30
AbhigyaKrishna 54d4614600 feat: diff interface 2024-05-02 16:52:07 +05:30
AbhigyaKrishna 8fc10e8f62 feat: implement new diff system 2024-05-02 16:45:35 +05:30
AbhigyaKrishna e770a1c9ee feat: robust diff system 2024-05-02 16:45:13 +05:30
AbhigyaKrishna c999f3a810 feat: compression task update 2024-05-02 12:54:05 +05:30
leegod 8e070aac9a fix: Fixed CB Relocation on Paper 1.20.5+ 2024-05-02 13:50:30 +08:00
AbhigyaKrishna faecd9dd9c Updated all mapping to 1.20.5 2024-05-02 04:00:15 +05:30
AbhigyaKrishna e40d8c875f Updated code for new type builder system 2024-05-02 02:39:12 +05:30
Bram 10765058f8 Fixed: Another Return statement missing after scheduling a task on Bukkit rather than Folia 2024-05-01 22:42:44 +02:00
Bram c71d6da310 Fixed: GlobalRegionScheduler#Execute being marked as private
Fixed: Return statement missing after scheduling a task on Bukkit rather than Folia
2024-05-01 22:39:54 +02:00
AbhigyaKrishna 4ec106e36f Merge 2.0 into mapping-compression 2024-05-02 01:44:09 +05:30
Abhigya 66a7ef3ffa Merge pull request #658 from booky10/dev/1.20.5
1.20.5 update
2024-05-02 01:23:56 +05:30
booky10 3d858013e6 Merge branch '2.0' into dev/1.20.5 2024-05-01 17:47:06 +02:00
booky10 3c15e5409f Move general components to another package
Components could potentially be used for something other than items in the future
2024-04-29 18:27:44 +02:00
retrooper 206d484f27 Rename the new FoliaCompatUtil to FoliaScheduler 2024-04-28 23:36:56 +02:00
retrooper e2949ade16 Update copyright years 2024-04-28 23:35:00 +02:00
retrooper 896ed7ff07 Optimizations in event system. 2024-04-28 18:10:22 +02:00
retrooper 4ca682704a Fix finding minecraft server instance on 1.20.5 (atleast on paper) 2024-04-28 18:06:22 +02:00
booky10 2275091e76 Add 1.20.6 versions 2024-04-26 16:53:28 +02:00
booky10 dd71d9ae69 Fix SCUTE/GRASS item types being invalid 2024-04-25 18:21:30 +02:00
booky10 b2d3aee10e Add constants for commonly used tool attribute uuids 2024-04-25 18:18:53 +02:00
booky10 1891307753 Fix GENERIC_GRAVITY attribute key 2024-04-24 20:48:21 +02:00
booky10 399d831d04 Fix reading entity effect for 1.20.5 2024-04-24 19:08:43 +02:00
booky10 29ad41f42f Fix reading mapped entities being two ids offset 2024-04-24 18:55:26 +02:00
booky10 bab19e14bd Merge branch '2.0' into dev/1.20.5 2024-04-24 18:48:09 +02:00
booky10 286ea801d8 Fix explosion sound in WrapperPlayServerExplosion 2024-04-24 18:43:06 +02:00
booky10 6320cc314e Prevent NPE on missing world data
Caused by server not sending data the client already knows about
2024-04-24 18:33:42 +02:00
booky10 cb094f1af3 Fix WrapperConfigServerSelectKnownPacks constructor 2024-04-24 18:22:25 +02:00
booky10 d00d138a21 Fix User#getWorldNBT(Dimension) 2024-04-24 18:22:05 +02:00
booky10 8b86b3e48b Read world nbt from restructured registry data packet 2024-04-24 18:05:46 +02:00
booky10 3232c69a5a Implement dummy component type for components without content 2024-04-24 17:53:15 +02:00
retrooper 4ee24812f4 Merge remote-tracking branch 'origin/2.0' into 2.0 2024-04-24 17:38:07 +02:00
retrooper a2139718a5 Properly cleanup user on proxy 2024-04-24 17:37:42 +02:00
booky10 57e536b8b2 Fix itemstack conversion between bukkit and nms 2024-04-24 17:33:38 +02:00
booky10 ab0e4030c3 Add sound mappings for <1.20.5 2024-04-23 21:32:07 +02:00
booky10 89fe7f43a7 Fix component value writing 2024-04-23 19:15:04 +02:00
booky10 fffb4e08b8 Add tostring handling for components 2024-04-23 19:14:56 +02:00
booky10 1b071e6564 Adjust for new handler names on channel init 2024-04-23 18:58:33 +02:00
booky10 efb1b1e1eb Fix statetype registration 2024-04-19 22:11:31 +02:00
booky10 60421a6727 Fix serverbound configuration phase packets 2024-04-19 22:11:13 +02:00
booky10 7f7107a79a Fix NPE in StateTypes#getByName 2024-04-19 21:12:03 +02:00
booky10 94827892cc Fix attributes for <1.20.5 2024-04-19 16:03:08 +02:00
booky10 78d0d674b5 Implement 1.20.5-rc1 changes for WrapperLoginServerLoginSuccess 2024-04-18 23:25:41 +02:00
booky10 ed681fadd1 Fix sound packet wrappers for >= 1.19.3 when using unregistered sounds 2024-04-18 22:49:27 +02:00
booky10 35de72c331 Implement TrimMaterial and TrimPattern registries
Technically wrong as datapacks can add more stuff, but this works until packetevents actually tracks registry data sent on login
2024-04-18 22:35:19 +02:00
booky10 018d611b2b Small cleanup to component types definition logic 2024-04-18 14:12:49 +02:00
booky10 852d34cdcf Fix equality checks for all component values 2024-04-17 22:33:22 +02:00
booky10 d4fead85b8 Add all generated default components to items 2024-04-17 22:16:12 +02:00
Bram a8bbc97d00 Fixed: Wrong message applied upon detecting an invalid packet 2024-04-17 21:55:34 +02:00
Bram 94d77e94da Merge branch 'refs/heads/2.0' into FoliaCompatUtilPatch 2024-04-17 21:52:37 +02:00
booky10 b1e2a746e3 Implement directly encoded instruments
Also implements sound event registry which is required for this (currently only for 1.20.5)
2024-04-17 19:00:45 +02:00
booky10 1b8e23dcf5 Fix showintooltip empty state for ItemEnchantments component value 2024-04-16 23:35:25 +02:00
booky10 ecd87f2fc6 Finish support for setting components on item type definition 2024-04-16 22:33:35 +02:00
booky10 22453a2fac Implement static component map builder and add shared item type components 2024-04-16 22:22:16 +02:00
booky10 80c1413811 Wrap lore component 2024-04-16 22:21:59 +02:00
booky10 0fcd8d57c0 Implement registry for state types 2024-04-16 22:06:35 +02:00
booky10 750d8813f3 Finish making all components mutable 2024-04-16 21:01:51 +02:00
booky10 ca546a9e59 Start making all components mutable 2024-04-16 19:15:41 +02:00
booky10 29fd80865c Fix compile issues 2024-04-16 18:59:26 +02:00
booky10 ab253a0976 Add potion registry 2024-04-16 18:56:57 +02:00
booky10 5545de8886 Fix equality checks for newly added registries 2024-04-16 18:56:44 +02:00
booky10 637aecbf4b Add armor material registry 2024-04-16 18:39:04 +02:00
booky10 aaf6d41766 Add instrument registry 2024-04-16 18:38:52 +02:00
booky10 f814d0ecf8 Finish implement component type serializers 2024-04-16 18:28:17 +02:00
booky10 f20e8432b1 Finish banner patterns registry 2024-04-16 18:07:56 +02:00
booky10 0e558e4baf Implement even more component types 2024-04-16 17:44:15 +02:00
booky10 5eb7d5b3fc Implement more component types 2024-04-16 13:28:28 +02:00
leegod 87c2ca3c07 feat: Added getter and setter for LightData in WrapperPlayServerChunkData
chore: Added packet transformation for pre 1.18 (where light data and chunk data are sent separately)
2024-04-16 16:39:26 +08:00
leegod 1f1b1aabd1 feat: Added WrapperPlayServerUpdateLight
chore: Moved away LightData values from WrapperPlayServerChunkData
2024-04-16 16:27:53 +08:00
booky10 4a5382b14c Start implementing serializers for some component types
Mojang literally serializes half their entire codebase with these component types, this will take a while
2024-04-15 23:23:59 +02:00
booky10 c2b006ddab Add default component definition support to ItemTypes 2024-04-15 22:42:08 +02:00
booky10 e4b60d55f3 Re-generate all ItemTypes 2024-04-15 22:15:41 +02:00
booky10 4521ce8037 Make all ItemTypes final
187/1344 weren't before, idk why
2024-04-15 21:49:36 +02:00
booky10 73490b8ff6 Implement serialization for new itemstack component patches 2024-04-15 21:36:05 +02:00
AoElite 0549c8e486 Merge pull request #713 from booky10/fix/tab-complete-packet
Fix WrapperPlayClientTabComplete discarding certain fields
2024-04-15 14:51:55 -04:00
booky10 af7c0d346f Unload file mappings after PotionTypes creation 2024-04-15 20:26:25 +02:00
booky10 9a5da1bc9a Implement mappings for potion types 2024-04-15 20:18:51 +02:00
booky10 96a601da74 Fix WrapperPlayClientTabComplete discarding certain fields
Transaction id and assume command flag are lost as these fields get set after the constructor reads from the event
2024-04-15 19:57:44 +02:00
booky10 f29626311c Fix time argument parser for <1.19.4 2024-04-14 23:08:28 +02:00
booky10 ea0b9a497e Implement mappings for command argument parsers
Should also resolve #700, but needs testing
2024-04-14 22:51:31 +02:00
booky10 b11e76494e Implement mappings for block entity types 2024-04-14 22:22:15 +02:00
booky10 cb3a62cf71 Add block entity type mappings data 2024-04-14 22:13:49 +02:00
booky10 992d4855e7 Read unsigned short in creative inventory action packet 2024-04-14 21:55:28 +02:00
booky10 a684b56dc3 Use varints for amplifiers in entity effect wrapper 2024-04-14 21:50:09 +02:00
booky10 e6c86a7e4f Update dimension encoding/decoding 2024-04-14 21:49:58 +02:00
booky10 73e34d8f0b Update WrapperConfigServerRegistryData to 1.20.5-pre1 2024-04-14 21:37:21 +02:00
booky10 d006974e7b Add packet wrappers for all new packets 2024-04-14 21:22:27 +02:00
booky10 0742f24973 Add new potion types 2024-04-14 20:52:16 +02:00
booky10 76bde2568b Add new command argument parsers 2024-04-14 20:52:12 +02:00
booky10 40bd7d60d4 Update packet type ids 2024-04-14 20:51:20 +02:00
booky10 6d7718428a Fix BlockTags/ItemTags 2024-04-14 20:26:40 +02:00
booky10 92229a90e9 Fix WrapperCommonCookieResponse 2024-04-14 20:11:53 +02:00
booky10 7dd6fbd9af Update entity types to 1.20.5-pre1 2024-04-14 20:09:43 +02:00
booky10 2fa285ddde Update particle types to 1.20.5-pre1 2024-04-14 20:05:37 +02:00
booky10 8962c80495 Update some mappings and registries to 1.20.5-pre1 2024-04-14 19:17:46 +02:00
booky10 2dccce47bf Merge branch '2.0' into dev/1.20.5 2024-04-14 03:34:39 +02:00
Bram 6231e8c7d4 Fixed: AsyncScheduler now converts back the delay to ticks using the convertTimeToTicks method when using the Bukkit scheduler 2024-04-09 19:38:57 +02:00
Bram 5ba3080d00 Improved: InternalBukkitListener no longer unnecessarily uses the entity scheduler, but the region scheduler instead
Added: Chunk coordinates to region scheduler world methods
2024-04-09 19:17:54 +02:00
Bram a110c549be Fixed: EntityScheduler being wrongly invoked 2024-04-09 18:57:24 +02:00
Bram 021460ba08 Removed: Unnecessary comments 2024-04-09 09:17:54 +02:00
Bram 74d14166d5 Added: Proper deprecation annotations and documentation
Added: Copyright Notice
2024-04-08 21:42:17 +02:00
Bram f24add4246 Fixed: RegionScheduler being a protected class, instead of public (I only meant to make the constructor protected) 2024-04-08 19:09:03 +02:00
Bram acf631a54f Improved: Java docs 2024-04-06 19:30:48 +02:00
Bram a6b4087454 Fixed: Reflection method name mismatch in the AsyncScheduler and the GlobalRegionScheduler 2024-04-06 18:44:30 +02:00
Bram f392495474 Schedulers are now only able to be initialized from within the FoliaCompatUtil 2024-04-06 18:31:49 +02:00
Bram b8fdd74f96 Added: Paper Schedulers 2024-04-06 16:40:03 +02:00
Bram 9dba5d40ca Added: TaskWrapper
Improved: FoliaCompatUtil reflection caching
2024-04-05 21:30:08 +02:00
retrooper 78c7709add Recognition of SpigotConversionUtil#getEntityById 2024-03-31 01:21:58 +01:00
retrooper 7a0908faaf Fix SpigotConversionUtil#getEntityById for paper 2024-03-31 01:14:49 +01:00
retrooper 0624b1766f On legacy minecraft versions (older than 1.16), the colors are already "down-sampled" so the setting is redundant. On 1.16+, the downsampled setting is set to false by default, and will allows costumization of hex colors. 2024-03-30 23:49:12 +01:00
retrooper 651de583b6 Fix SpigotReflectionUtil#getEntityById for 1.17+ 2024-03-30 23:38:07 +01:00
retrooper c29847af02 Final change in exception handling of readUTF 2024-03-29 21:47:18 +01:00
retrooper 87c8147514 Merge remote-tracking branch 'origin/2.0' into 2.0 2024-03-29 19:48:33 +01:00
retrooper 57778b5eb3 Minor change in exception handling of readUTF 2024-03-29 19:48:11 +01:00
retrooper f2d136af0a Removed unused variable in Location 2024-03-26 18:46:45 +01:00
retrooper 22d568f30e Added direction functionality to location 2024-03-26 18:31:28 +01:00
retrooper 49a81fa4f7 Merge pull request #705 from Leymooo/2.0
Fix UUID serialization on < 1.20.3 servers with Adventure 4.15+
2024-03-24 16:45:27 +01:00
Leymooo 57f9a8fe3a Fix UUID serialization on < 1.20.3 servers with Adventure 4.15+ 2024-03-23 23:33:19 +02:00
retrooper 94c731afbf Merge pull request #704 from z7087/patch-3
Fix BlockFace.getBlockFaceByValue may return OTHER
2024-03-23 01:06:49 +01:00
z7087 98304cb41e Update BlockFace.java 2024-03-17 02:42:53 +08:00
AoElite 70d68d7860 Merge pull request #698 from Wekylend/fix/item-types-map
Fix ItemTypes ITEM_TYPE_MAP key loading
2024-03-16 01:55:30 -04:00
AoElite 5502c4a434 Merge pull request #692 from ytnoos/viaver-dev
Support for ViaVersion dev builds, Fixes #689
2024-03-16 01:45:59 -04:00
Wekylend f424b9bd66 Fix ITEM_TYPE_MAP key loading
This subsequently should fix the getByName method always returning null.
2024-03-09 01:24:29 +01:00
Abhigya c8d0733935 Merge pull request #697 from booky10/fix/missing-block-properties-api
Add missing blockstate property methods for dusted and flower_amount
2024-03-08 10:55:31 +05:30
Abhigya c2ba3304f7 Merge pull request #694 from hypemc-pl/2.0
Correct NBT component style serialization
2024-03-08 10:51:23 +05:30
booky10 510bf9301c Add missing blockstate property getters for dusted and flower_amount 2024-03-07 15:01:54 +01:00
Abhigya 8a64746b18 Merge pull request #695 from AbhigyaKrishna/2.0
Removed invalid function from NBTCodec
2024-03-04 13:45:27 +05:30
AbhigyaKrishna feab6ba0bd Removed invalid function from NBTCodec 2024-03-04 13:42:31 +05:30
Kamilkime f11a5dd31c Correct NBT component style serialization 2024-03-04 02:08:40 +01:00
ytnoos 5a3a4f6507 Support for ViaVersion dev builds 2024-03-02 11:11:11 +01:00
ytnoos e2865ce4be Fix re-encode for new bytebufs that were bigger than the received one 2024-03-02 10:47:52 +01:00
ytnoos f53f182090 MessageSignature limits 2024-03-02 10:34:35 +01:00
ytnoos 2ec7771a8a ByteBufInputStream limits 2024-03-02 10:32:17 +01:00
ytnoos 75320ef583 implemented NBT read limits following vanilla values 2024-03-02 10:29:02 +01:00
retrooper 40fa932d33 Merge pull request #683 from AbhigyaKrishna/2.0
AdventureNBTSerializer reworked
2024-03-01 21:33:57 +01:00
AbhigyaKrishna 1355ca6bdd Optimised imports 2024-02-29 12:46:56 +05:30
AoElite 5639c2b85e Merge pull request #687 from Syntellix/2.0
Implement settings for printing packet exception stacktraces and kicking the player for packet exceptions
2024-02-27 14:48:05 -05:00
AoElite baa8837987 Merge pull request #686 from SamB440/feat/read-only-block-data
Add methods for getting WrappedBlockStates without cloning
2024-02-27 13:48:03 -05:00
MachineBreaker 38f2783149 Apply requested changes 2024-02-27 14:17:17 -04:00
MachineBreaker 43a5e2c590 Add settings for full stacktrace and player kicking
Idea from AoElite
2024-02-27 13:59:41 -04:00
MachineBreaker 9a124b8e68 Don't print full stacktrace if debug is not enabled 2024-02-27 13:27:32 -04:00
SamB440 02b9e9260f Add methods for getting WrappedBlockStates without cloning 2024-02-27 16:29:57 +00:00
AbhigyaKrishna d109e9dd54 Reading text field from number and boolean 2024-02-25 13:24:13 +05:30
AbhigyaKrishna 2ea24250a0 Component serialization for boolean and number 2024-02-25 13:06:45 +05:30
AbhigyaKrishna 39d555f3ec Update license 2024-02-24 20:31:32 +05:30
AbhigyaKrishna 6e09ec2e2b Simplified decoration reading 2024-02-24 17:37:18 +05:30
AbhigyaKrishna f91de06044 AdventureNBTSerializer rework (minor patch) 2024-02-24 13:36:59 +05:30
AbhigyaKrishna 63e3563a1a Merge remote-tracking branch 'origin/2.0' into 2.0
# Conflicts:
#	api/src/main/java/com/github/retrooper/packetevents/util/adventure/AdventureNBTSerializer.java
2024-02-24 13:34:22 +05:30
AbhigyaKrishna 655d97c73a AdventureNBTSerializer rework 2024-02-24 13:33:58 +05:30
AbhigyaKrishna a7c8f21d31 AdventureNBTSerializer rework 2024-02-24 13:18:28 +05:30
AbhigyaKrishna f23ff3d421 pattern matching for excluding gson 2024-02-24 13:17:44 +05:30
AbhigyaKrishna 766f0c0a32 NBT toString implementation 2024-02-24 13:15:45 +05:30
retrooper e13d52a518 Attempted fixes at WrapperPlayServerDeclareCommands 2024-02-23 19:55:27 +01:00
AbhigyaKrishna 329b8adefa Removed debug statements 2024-02-12 02:51:22 +05:30
AbhigyaKrishna a7949eb096 Merge remote-tracking branch 'origin/mapping-compression' into mapping-compression 2024-02-12 02:50:11 +05:30
AbhigyaKrishna a4288ca29c Fixed loading of Block states 2024-02-12 02:49:51 +05:30
retrooper e5b5845ebf Update copyright year on newly created files. 2024-02-11 19:56:36 +01:00
booky10 3726f6629a Add common packet implementation for cookie responses 2024-01-19 20:12:38 +01:00
booky10 33aae65e35 Update particle type mappings for 24w03b 2024-01-19 18:05:07 +01:00
booky10 2d495b7570 Add backwards compatibility for sweeping edge renaming 2024-01-17 23:09:27 +01:00
booky10 5a8acfdffd Add packet wrapper for all new packets 2024-01-17 22:49:48 +01:00
booky10 1938f9f3bf Fix missing play PacketType 2024-01-17 22:39:35 +01:00
booky10 672b8e47fd Update login encryption request packet 2024-01-17 22:33:25 +01:00
booky10 846d0a893e Update secure chat enforcement fields 2024-01-17 22:33:14 +01:00
booky10 fb45b5b35a Update handshake packet for 24w03a 2024-01-17 22:27:31 +01:00
booky10 1205020451 Update block and item tags 2024-01-17 22:19:12 +01:00
booky10 3ed2735d0e Rename enchantment "sweeping" to "sweeping_edge" 2024-01-17 22:11:53 +01:00
booky10 5b3d6ae7a2 Update attribute mappings for 24w03a 2024-01-17 22:09:11 +01:00
booky10 e3d9638b47 Update packet types and ids for 24w03a 2024-01-17 21:58:02 +01:00
booky10 9ec6118159 Merge branch '2.0' into dev/1.20.5 2024-01-17 21:43:47 +01:00
AbhigyaKrishna af251d03b8 Use new mappings scheme 2024-01-07 15:48:35 +05:30
AbhigyaKrishna 1445057145 Mapping Compression Task 2024-01-07 15:47:45 +05:30
booky10 721532ee44 Merge branch '2.0' into dev/1.20.5 2023-12-30 05:10:54 +01:00
booky10 c936c9da31 Merge branch '2.0' into dev/1.20.5 2023-12-26 03:56:11 +01:00
booky10 28cb480ac3 Merge branch '2.0' into dev/1.20.5 2023-12-22 02:49:37 +01:00
booky10 26eee81455 Also add validity check to ItemTags 2023-12-19 21:42:56 +01:00
booky10 8c63a7c7b6 Update item tags to 23w51b 2023-12-19 21:38:44 +01:00
booky10 d221869491 Re-generate block-/item-tags
But this time with correct ordering
2023-12-19 21:36:46 +01:00
booky10 539b814a5a Update attributes update packet structure
Attributes are now encoded as id instead of writing their keys
2023-12-19 21:05:05 +01:00
booky10 d0da1d710b Add attribute mappings
Attributes are now encoded with their id in packets
2023-12-19 20:56:17 +01:00
booky10 2771959dd8 Update effect packet structure
Removes factor data
2023-12-19 20:43:34 +01:00
booky10 aa17d098c4 Update entity data type mappings 2023-12-19 20:40:15 +01:00
booky10 7a1f432652 Update item type mappings 2023-12-19 20:35:22 +01:00
booky10 bca60bfa19 Update entity type mappings 2023-12-19 20:35:17 +01:00
booky10 94e2dc0378 Add 1.20.5 version constants 2023-12-19 20:35:09 +01:00
395 changed files with 1838038 additions and 262652 deletions

No files matched your search

+9 -3
View File
@@ -13,10 +13,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v3
with:
java-version: '17'
java-version: '21'
distribution: 'adopt'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
@@ -52,4 +52,10 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: velocity-build
path: velocity/build/libs
path: velocity/build/libs
- name: Upload build artifacts fabric
uses: actions/upload-artifact@v3
with:
name: fabric-build
path: fabric/build/libs
-23
View File
@@ -1,23 +0,0 @@
// papermc repo + disableAutoTargetJvm needed for mockbukkit
repositories {
maven { url 'https://repo.papermc.io/repository/maven-public/' }
}
java {
disableAutoTargetJvm()
}
dependencies {
compileOnly(adventureDependencies)
testImplementation(adventureDependencies)
testImplementation(project(":netty-common"))
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.9.0")
testImplementation("org.slf4j:slf4j-simple:2.0.7")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.0")
}
test {
useJUnitPlatform()
}
+138
View File
@@ -0,0 +1,138 @@
import com.github.retrooper.compression.strategy.JsonArrayCompressionStrategy
import com.github.retrooper.compression.strategy.JsonObjectCompressionStrategy
import com.github.retrooper.compression.strategy.JsonToNbtStrategy
import com.github.retrooper.excludeAdventure
plugins {
packetevents.`shadow-conventions`
packetevents.`library-conventions`
`mapping-compression`
`pe-version`
}
// papermc repo + disableAutoTargetJvm needed for mockbukkit
repositories {
maven("https://repo.papermc.io/repository/maven-public/")
}
java {
withJavadocJar()
}
dependencies {
compileOnlyApi(libs.bundles.adventure)
implementation(libs.adventure.api)
api(project(":patch:adventure-text-serializer-gson", "shadow")) {
excludeAdventure()
}
api(libs.adventure.text.serializer.legacy) {
excludeAdventure()
}
compileOnly(libs.gson)
testImplementation(libs.bundles.adventure)
testImplementation(project(":patch:adventure-text-serializer-gson"))
testImplementation(libs.adventure.text.serializer.legacy)
testImplementation(project(":netty-common"))
testImplementation(testlibs.mockbukkit)
testImplementation(testlibs.slf4j)
testImplementation(testlibs.bundles.junit)
}
mappingCompression {
mappingDirectory = rootDir.resolve("mappings")
outDirectory = project.layout.buildDirectory.dir("mappings/generated/assets/mappings")
with<JsonToNbtStrategy> {
compress("block/legacy_block_mappings.json")
compress("block/modern_block_mappings.json")
compress("stats/statistics.json")
}
with<JsonArrayCompressionStrategy> {
compress("attribute/attribute_mappings.json")
compress("block/block_entity_type_mappings.json")
compress("block/block_type_mappings.json")
compress("chat/chat_type_mappings.json")
compress("command/argument_parser_mappings.json")
compress("entity/entity_data_type_mappings.json")
compress("entity/painting_mappings.json")
compress("item/item_armor_material_mappings.json")
compress("item/item_banner_pattern_mappings.json")
compress("item/item_component_mappings.json")
compress("item/item_instrument_mappings.json")
compress("item/item_map_decoration_type_mappings.json")
compress("item/item_potion_mappings.json")
compress("item/item_trim_material_mappings.json")
compress("item/item_trim_pattern_mappings.json")
compress("item/recipe_serializer_mappings.json")
compress("particle/particle_type_mappings.json")
compress("sound/sound_mappings.json")
compress("world/world_position_source_mappings.json")
}
with<JsonObjectCompressionStrategy> {
compress("enchantment/enchantment_type_mappings.json")
compress("entity/entity_effect_mappings.json")
compress("entity/entity_type_mappings.json")
compress("entity/legacy_entity_type_mappings.json")
compress("item/item_type_mappings.json")
}
}
tasks {
javadoc {
setDestinationDir(file("${project.layout.buildDirectory.asFile.get()}/docs/javadoc"))
options {
(this as CoreJavadocOptions).addBooleanOption("Xdoclint:none", true)
}
mustRunAfter(generateVersionsFile)
}
sourcesJar {
mustRunAfter(generateVersionsFile)
}
withType<JavaCompile> {
dependsOn(generateVersionsFile)
}
processResources {
dependsOn(compressMappings)
from(project.layout.buildDirectory.dir("mappings/generated").get())
}
generateVersionsFile {
packageName = "com.github.retrooper.packetevents.util"
}
test {
useJUnitPlatform()
}
shadowJar {
exclude {
val path = it.path
path.startsWith("net/kyori") && !path.startsWith("net/kyori/adventure/text/serializer") && !path.startsWith("net/kyori/option")
}
}
}
publishing {
publications {
named<MavenPublication>("shadow") {
artifact(tasks["javadocJar"])
}
}
}
@@ -27,6 +27,8 @@ import com.github.retrooper.packetevents.netty.NettyManager;
import com.github.retrooper.packetevents.settings.PacketEventsSettings;
import com.github.retrooper.packetevents.util.LogManager;
import com.github.retrooper.packetevents.util.PEVersion;
//Note: The PEVersions class is generated. Refer to PEVersionTask.kt
import com.github.retrooper.packetevents.util.PEVersions;
import com.github.retrooper.packetevents.util.updatechecker.UpdateChecker;
import java.util.logging.Logger;
@@ -35,11 +37,9 @@ public abstract class PacketEventsAPI<T> {
private static final EventManager EVENT_MANAGER = new EventManager();
private static final PacketEventsSettings SETTINGS = new PacketEventsSettings();
private static final UpdateChecker UPDATE_CHECKER = new UpdateChecker();
private final Logger LOGGER = Logger.getLogger(PacketEventsAPI.class.getName());
private static final LogManager LOG_MANAGER = new LogManager();
//TODO UPDATE
private static final PEVersion VERSION = new PEVersion(2, 2, 1);
private static final Logger LOGGER = Logger.getLogger(PacketEventsAPI.class.getName());
public EventManager getEventManager() {
return EVENT_MANAGER;
}
@@ -53,7 +53,8 @@ public abstract class PacketEventsAPI<T> {
}
public PEVersion getVersion() {
return VERSION;
//Note: The PEVersions class is generated by the auto-version task. Refer to PEVersionTask.kt
return PEVersions.CURRENT;
}
public Logger getLogger() {
@@ -22,13 +22,13 @@ import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.exception.InvalidHandshakeException;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Level;
public class EventManager {
private final Map<Byte, Set<PacketListenerCommon>> listenersMap = new ConcurrentHashMap<>();
private final Map<PacketListenerPriority, Set<PacketListenerCommon>> listenersMap =
Collections.synchronizedMap(new EnumMap<>(PacketListenerPriority.class));
/**
* Call the PacketEvent.
@@ -44,7 +44,7 @@ public class EventManager {
}
public void callEvent(PacketEvent event, @Nullable Runnable postCallListenerAction) {
for (byte priority = PacketListenerPriority.LOWEST.getId(); priority <= PacketListenerPriority.MONITOR.getId(); priority++) {
for (PacketListenerPriority priority : PacketListenerPriority.values()) {
Set<PacketListenerCommon> listeners = listenersMap.get(priority);
if (listeners != null) {
for (PacketListenerCommon listener : listeners) {
@@ -80,13 +80,12 @@ public class EventManager {
* @param listener {@link PacketListenerCommon}
*/
public PacketListenerCommon registerListener(PacketListenerCommon listener) {
byte priority = listener.getPriority().getId();
Set<PacketListenerCommon> listenerSet = listenersMap.get(priority);
Set<PacketListenerCommon> listenerSet = listenersMap.get(listener.getPriority());
if (listenerSet == null) {
listenerSet = ConcurrentHashMap.newKeySet();
listenerSet = new CopyOnWriteArraySet<>();
}
listenerSet.add(listener);
listenersMap.put(priority, listenerSet);
listenersMap.put(listener.getPriority(), listenerSet);
return listener;
}
@@ -103,7 +102,7 @@ public class EventManager {
}
public void unregisterListener(PacketListenerCommon listener) {
Set<PacketListenerCommon> listenerSet = listenersMap.get(listener.getPriority().getId());
Set<PacketListenerCommon> listenerSet = listenersMap.get(listener.getPriority());
if (listenerSet == null) return;
listenerSet.remove(listener);
}
@@ -27,21 +27,30 @@ import com.github.retrooper.packetevents.manager.protocol.ProtocolManager;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.ConnectionState;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.player.User;
import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerRegistryData;
import com.github.retrooper.packetevents.wrapper.configuration.server.WrapperConfigServerRegistryData.RegistryElement;
import com.github.retrooper.packetevents.wrapper.handshaking.client.WrapperHandshakingClientHandshake;
import com.github.retrooper.packetevents.wrapper.login.server.WrapperLoginServerLoginSuccess;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerJoinGame;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
import java.net.InetSocketAddress;
import java.util.List;
public class InternalPacketListener extends PacketListenerAbstract {
private static final ResourceLocation DIMENSION_TYPE_REGISTRY_KEY =
ResourceLocation.minecraft("dimension_type");
public InternalPacketListener() {
this(PacketListenerPriority.LOWEST);
}
@@ -89,10 +98,41 @@ public class InternalPacketListener extends PacketListenerAbstract {
// Store world data
NBTCompound registryDataTag = registryData.getRegistryData();
if (registryDataTag != null) {
NBTList<NBTCompound> list = registryDataTag
.getCompoundTagOrNull("minecraft:dimension_type")
.getCompoundListTagOrNull("value");
NBTList<NBTCompound> list = null;
if (registryDataTag != null) { // <1.20.5
//Handle dimension type
NBTCompound dimensionTypes = registryDataTag
.getCompoundTagOrNull(DIMENSION_TYPE_REGISTRY_KEY.toString());
if (dimensionTypes == null) {
dimensionTypes = registryDataTag
.getCompoundTagOrNull(DIMENSION_TYPE_REGISTRY_KEY.getKey());
}
if (dimensionTypes != null) {
list = dimensionTypes.getCompoundListTagOrNull("value");
}
if (list == null) {
list = new NBTList<>(NBTType.COMPOUND);
PacketEvents.getAPI().getLogger().warning("Can't find dimension type registry in registry data, "
+ "this may cause issues; available registries: " + registryDataTag.getTags().keySet());
}
} else if (DIMENSION_TYPE_REGISTRY_KEY.equals(registryData.getRegistryKey())) { // >=1.20.5
// remap to legacy format
list = new NBTList<>(NBTType.COMPOUND);
List<RegistryElement> elements = registryData.getElements();
if (elements != null) {
int i = 0;
for (RegistryElement element : elements) {
NBTCompound tag = new NBTCompound();
tag.setTag("name", new NBTString(element.getId().toString()));
tag.setTag("id", new NBTInt(i++));
if (element.getData() != null) { // may be null because of known packs not being sent
tag.setTag("element", element.getData());
}
list.addTag(tag);
}
}
}
if (list != null) {
user.setWorldNBT(list);
}
}
@@ -109,19 +149,26 @@ public class InternalPacketListener extends PacketListenerAbstract {
// Store world data
NBTCompound dimensionCodec = joinGame.getDimensionCodec();
if (dimensionCodec != null) {
NBTList<NBTCompound> list = dimensionCodec
.getCompoundTagOrNull("minecraft:dimension_type")
.getCompoundListTagOrNull("value");
user.setWorldNBT(list);
NBTList<NBTCompound> types = null;
NBTCompound dimensionTypes = dimensionCodec
.getCompoundTagOrNull(DIMENSION_TYPE_REGISTRY_KEY.toString());
if (dimensionTypes == null) {
dimensionTypes = dimensionCodec
.getCompoundTagOrNull(DIMENSION_TYPE_REGISTRY_KEY.getKey());
}
if (dimensionTypes != null) { // account for dimension type registry somehow going missing
types = dimensionTypes.getCompoundListTagOrNull("value");
}
if (types == null) {
types = new NBTList<>(NBTType.COMPOUND);
PacketEvents.getAPI().getLogger().warning("Can't find dimension type registry in join packet, "
+ "this may cause issues; available registries: " + dimensionCodec.getTags().keySet());
}
user.setWorldNBT(types);
}
// Update world height
NBTCompound dimension = user.getWorldNBT(joinGame.getDimension().getDimensionName());
if (dimension != null) {
NBTCompound worldNBT = dimension.getCompoundTagOrNull("element");
user.setMinWorldHeight(worldNBT.getNumberTagOrNull("min_y").getAsInt());
user.setTotalWorldHeight(worldNBT.getNumberTagOrNull("height").getAsInt());
}
user.switchDimensionType(joinGame.getServerVersion(), joinGame.getDimension());
}
// Respawn is used to switch dimensions
@@ -132,12 +179,7 @@ public class InternalPacketListener extends PacketListenerAbstract {
return; // Fixed world height, no tags are sent to the client
}
NBTCompound dimension = user.getWorldNBT(respawn.getDimension().getDimensionName());
if (dimension != null) {
NBTCompound worldNBT = dimension.getCompoundTagOrNull("element"); // This is 1.17+, it always sends the world name
user.setMinWorldHeight(worldNBT.getNumberTagOrNull("min_y").getAsInt());
user.setTotalWorldHeight(worldNBT.getNumberTagOrNull("height").getAsInt());
}
user.switchDimensionType(respawn.getServerVersion(), respawn.getDimension());
} else if (event.getPacketType() == PacketType.Play.Server.CONFIGURATION_START) {
user.setEncoderState(ConnectionState.CONFIGURATION);
} else if (event.getPacketType() == PacketType.Configuration.Server.CONFIGURATION_END) {
@@ -47,8 +47,9 @@ public enum ServerVersion {
V_1_18(757), V_1_18_1(757), V_1_18_2(758),
//1.19.1 and 1.19.2 have the same protocol version
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.
V_1_20(763), V_1_20_1(763), V_1_20_2(764), V_1_20_3(765), V_1_20_4(765),
//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),
V_1_21(767),
//TODO UPDATE Add server version constant
ERROR(-1, true);
@@ -24,8 +24,11 @@ public interface ByteBufAllocationOperator {
Object copiedBuffer(byte[] bytes);
Object buffer();
Object buffer(int initialCapacity);
Object directBuffer();
Object directBuffer(int initialCapacity);
Object compositeBuffer();
Object compositeBuffer(int maxNumComponents);
}
@@ -103,6 +103,14 @@ public class ByteBufHelper {
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeShort(buffer, value);
}
public static int readMedium(Object buffer) {
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().readMedium(buffer);
}
public static void writeMedium(Object buffer, int value) {
PacketEvents.getAPI().getNettyManager().getByteBufOperator().writeMedium(buffer, value);
}
public static int readInt(Object buffer) {
return PacketEvents.getAPI().getNettyManager().getByteBufOperator().readInt(buffer);
}
@@ -18,6 +18,8 @@
package com.github.retrooper.packetevents.netty.buffer;
import com.github.retrooper.packetevents.exception.PacketProcessException;
import java.io.*;
//TODO give netty credit
public class ByteBufInputStream extends InputStream implements DataInput {
@@ -40,27 +42,27 @@ public class ByteBufInputStream extends InputStream implements DataInput {
this(buffer, ByteBufHelper.readableBytes(buffer), releaseOnClose);
}
public ByteBufInputStream(Object buffer, int length, boolean releaseOnClose) {
public ByteBufInputStream(Object buffer, int maxLength, boolean releaseOnClose) {
this.lineBuf = new StringBuilder();
if (buffer == null) {
throw new NullPointerException("buffer");
} else if (length < 0) {
} else if (maxLength < 0) {
if (releaseOnClose) {
ByteBufHelper.release(buffer);
}
throw new IllegalArgumentException("length: " + length);
} else if (length > ByteBufHelper.readableBytes(buffer)) {
throw new IllegalArgumentException("maxLength: " + maxLength);
} else if (ByteBufHelper.readableBytes(buffer) > maxLength) {
if (releaseOnClose) {
ByteBufHelper.release(buffer);
}
throw new IndexOutOfBoundsException("Too many bytes to be read - Needs " + length + ", maximum is " + ByteBufHelper.readableBytes(buffer));
throw new IndexOutOfBoundsException("Too many bytes to be read - Found " + ByteBufHelper.readableBytes(buffer) + ", maximum is " + maxLength);
} else {
this.releaseOnClose = releaseOnClose;
this.buffer = buffer;
this.startIndex = ByteBufHelper.readerIndex(buffer);
this.endIndex = this.startIndex + length;
this.endIndex = this.startIndex + ByteBufHelper.readableBytes(buffer);
ByteBufHelper.markReaderIndex(buffer);
}
}
@@ -204,7 +206,8 @@ public class ByteBufInputStream extends InputStream implements DataInput {
}
public String readUTF() throws IOException {
return DataInputStream.readUTF(this);
String text = DataInputStream.readUTF(this);
return text;
}
public int readUnsignedByte() throws IOException {
@@ -225,7 +228,14 @@ public class ByteBufInputStream extends InputStream implements DataInput {
if (fieldSize < 0) {
throw new IndexOutOfBoundsException("fieldSize cannot be a negative number");
} else if (fieldSize > this.available()) {
throw new EOFException("fieldSize is too long! Length is " + fieldSize + ", but maximum is " + this.available());
int value = this.available();
String msg = "fieldSize is too long! Length is " + fieldSize + ", but maximum is " + value;
if (value == 0) {
throw new PacketProcessException(msg);
}
else {
throw new EOFException(msg);
}
}
}
}
@@ -35,12 +35,14 @@ public interface ByteBufOperator {
byte readByte(Object buffer);
short readShort(Object buffer);
int readMedium(Object buffer);
int readInt(Object buffer);
long readUnsignedInt(Object buffer);
long readLong(Object buffer);
void writeByte(Object buffer, int value);
void writeShort(Object buffer, int value);
void writeMedium(Object buffer, int value);
void writeInt(Object buffer, int value);
void writeLong(Object buffer, long value);
@@ -40,4 +40,16 @@ public class UnpooledByteBufAllocationHelper {
public static Object compositeBuffer() {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer();
}
public static Object buffer(int initialCapacity) {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().buffer(initialCapacity);
}
public static Object directBuffer(int initialCapacity) {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().directBuffer(initialCapacity);
}
public static Object compositeBuffer(int maxNumComponents) {
return PacketEvents.getAPI().getNettyManager().getByteBufAllocationOperator().compositeBuffer(maxNumComponents);
}
}
@@ -0,0 +1,24 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.attribute;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
public interface Attribute extends MappedEntity {
}
@@ -0,0 +1,25 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.attribute;
public enum AttributeOperation {
ADDITION,
MULTIPLY_BASE,
MULTIPLY_TOTAL,
}
@@ -0,0 +1,117 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.attribute;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.ApiStatus;
import java.util.HashMap;
import java.util.Map;
public class Attributes {
private static final Map<String, Attribute> ATTRIBUTE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, Attribute>> ATTRIBUTE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("attribute/attribute_mappings");
public static Attribute define(String key) {
TypesBuilderData data = TYPES_BUILDER.define(key);
Attribute attribute = new Attribute() {
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Attribute) {
return this.getName().equals(((Attribute) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, ATTRIBUTE_MAP, ATTRIBUTE_ID_MAP, attribute);
return attribute;
}
// with minecraft:key
public static Attribute getByName(String name) {
return ATTRIBUTE_MAP.get(name);
}
public static Attribute getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, Attribute> idMap = ATTRIBUTE_ID_MAP.get((byte) index);
return idMap.get(id);
}
public static final Attribute GENERIC_ARMOR = define("generic.armor");
public static final Attribute GENERIC_ARMOR_TOUGHNESS = define("generic.armor_toughness");
public static final Attribute GENERIC_ATTACK_DAMAGE = define("generic.attack_damage");
public static final Attribute GENERIC_ATTACK_KNOCKBACK = define("generic.attack_knockback");
public static final Attribute GENERIC_ATTACK_SPEED = define("generic.attack_speed");
public static final Attribute GENERIC_FLYING_SPEED = define("generic.flying_speed");
public static final Attribute GENERIC_FOLLOW_RANGE = define("generic.follow_range");
@ApiStatus.Obsolete // renamed in 1.20.5
public static final Attribute HORSE_JUMP_STRENGTH = define("horse.jump_strength");
public static final Attribute GENERIC_KNOCKBACK_RESISTANCE = define("generic.knockback_resistance");
public static final Attribute GENERIC_LUCK = define("generic.luck");
public static final Attribute GENERIC_MAX_HEALTH = define("generic.max_health");
public static final Attribute GENERIC_MOVEMENT_SPEED = define("generic.movement_speed");
public static final Attribute ZOMBIE_SPAWN_REINFORCEMENTS = define("zombie.spawn_reinforcements");
// Added in 1.20.2
public static final Attribute GENERIC_MAX_ABSORPTION = define("generic.max_absorption");
// Added in 1.20.5
public static final Attribute PLAYER_BLOCK_BREAK_SPEED = define("player.block_break_speed");
public static final Attribute PLAYER_BLOCK_INTERACTION_RANGE = define("player.block_interaction_range");
public static final Attribute PLAYER_ENTITY_INTERACTION_RANGE = define("player.entity_interaction_range");
public static final Attribute GENERIC_FALL_DAMAGE_MULTIPLIER = define("generic.fall_damage_multiplier");
public static final Attribute GENERIC_GRAVITY = define("generic.gravity");
public static final Attribute GENERIC_JUMP_STRENGTH = define("generic.jump_strength");
public static final Attribute GENERIC_SAFE_FALL_DISTANCE = define("generic.safe_fall_distance");
public static final Attribute GENERIC_SCALE = define("generic.scale");
public static final Attribute GENERIC_STEP_HEIGHT = define("generic.step_height");
// Added in 1.21
public static final Attribute GENERIC_BURNING_TIME = define("generic.burning_time");
public static final Attribute GENERIC_EXPLOSION_KNOCKBACK_RESISTANCE = define("generic.explosion_knockback_resistance");
public static final Attribute PLAYER_MINING_EFFICIENCY = define("player.mining_efficiency");
public static final Attribute GENERIC_MOVEMENT_EFFICIENCY = define("generic.movement_efficiency");
public static final Attribute GENERIC_OXYGEN_BONUS = define("generic.oxygen_bonus");
public static final Attribute PLAYER_SNEAKING_SPEED = define("player.sneaking_speed");
public static final Attribute PLAYER_SUBMERGED_MINING_SPEED = define("player.submerged_mining_speed");
public static final Attribute PLAYER_SWEEPING_DAMAGE_RATIO = define("player.sweeping_damage_ratio");
public static final Attribute GENERIC_WATER_MOVEMENT_EFFICIENCY = define("generic.water_movement_efficiency");
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -18,8 +18,32 @@
package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_1;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
public interface ChatType extends MappedEntity {
ChatTypeDecoration getChatDecoration();
ChatTypeDecoration getNarrationDecoration();
static ChatType readDirect(PacketWrapper<?> wrapper) {
ChatTypeDecoration chatDecoration = ChatTypeDecoration.read(wrapper);
ChatTypeDecoration narrationDecoration = ChatTypeDecoration.read(wrapper);
return new StaticChatType(chatDecoration, narrationDecoration);
}
static void writeDirect(PacketWrapper<?> wrapper, ChatType chatType) {
ChatTypeDecoration.write(wrapper, chatType.getChatDecoration());
ChatTypeDecoration.write(wrapper, chatType.getNarrationDecoration());
}
class Bound extends ChatMessage_v1_19_1.ChatTypeBoundNetwork {
public Bound(ChatType type, Component name, @Nullable Component targetName) {
super(type, name, targetName);
}
}
}
@@ -0,0 +1,155 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage_v1_19_1;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.format.Style;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.Parameter.*;
import static java.util.Arrays.asList;
import static net.kyori.adventure.text.format.NamedTextColor.GRAY;
import static net.kyori.adventure.text.format.Style.empty;
import static net.kyori.adventure.text.format.Style.style;
import static net.kyori.adventure.text.format.TextDecoration.ITALIC;
public class ChatTypeDecoration {
private final String translationKey;
private final List<Parameter> parameters;
private final Style style;
public ChatTypeDecoration(String translationKey, List<Parameter> parameters, Style style) {
this.translationKey = translationKey;
this.parameters = Collections.unmodifiableList(new ArrayList<>(parameters));
this.style = style;
}
public ChatTypeDecoration(NBTCompound nbt) {
//Read the translation key
this.translationKey = nbt.getStringTagValueOrDefault("translation_key", null);
//Read parameters
List<Parameter> temporaryList = new ArrayList<>();
NBTList<NBTString> parametersTag = nbt.getStringListTagOrNull("parameters");
if (parametersTag != null) {
for (NBTString p : parametersTag.getTags()) {
Parameter parameter = Parameter.valueByName(p.getValue().toUpperCase());
if (parameter != null) {
temporaryList.add(parameter);
}
}
}
this.parameters = Collections.unmodifiableList(temporaryList);
//Read style
NBTCompound styleTag = nbt.getCompoundTagOrNull("style");
if (styleTag != null) {
style = AdventureSerializer.getNBTSerializer().deserializeStyle(styleTag);
} else {
style = empty();
}
}
public static ChatTypeDecoration read(PacketWrapper<?> wrapper) {
String translationKey = wrapper.readString();
List<Parameter> parameters = wrapper.readList(ew -> ew.readEnum(Parameter.values()));
Style style = wrapper.readStyle();
return new ChatTypeDecoration(translationKey, parameters, style);
}
public static void write(PacketWrapper<?> wrapper, ChatTypeDecoration decoration) {
wrapper.writeString(decoration.translationKey);
wrapper.writeList(decoration.parameters, PacketWrapper::writeEnum);
wrapper.writeStyle(decoration.style);
}
public static ChatTypeDecoration withSender(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(SENDER, CONTENT), empty());
}
public static ChatTypeDecoration incomingDirectMessage(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(SENDER, CONTENT),
style(GRAY, ITALIC));
}
public static ChatTypeDecoration outgoingDirectMessage(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(TARGET, CONTENT),
style(GRAY, ITALIC));
}
public static ChatTypeDecoration teamMessage(String translationKey) {
return new ChatTypeDecoration(translationKey, asList(TARGET, SENDER, CONTENT), empty());
}
public Component decorate(Component component, ChatType.Bound chatType) {
ComponentLike[] components = new ComponentLike[this.parameters.size()];
for (int i = 0; i < components.length; i++) {
Parameter parameter = this.parameters.get(i);
components[i] = parameter.selector.apply(component, chatType);
}
return Component.translatable(this.translationKey, null, this.style, components);
}
public String getTranslationKey() {
return this.translationKey;
}
public List<Parameter> getParameters() {
return this.parameters;
}
public Style getStyle() {
return this.style;
}
public enum Parameter {
SENDER((component, type) -> type.getName()),
TARGET((component, type) -> type.getTargetName() != null ? type.getTargetName() : Component.empty()),
CONTENT((component, type) -> component);
private final BiFunction<Component, ChatType.Bound, Component> selector;
Parameter(BiFunction<Component, ChatType.Bound, Component> selector) {
this.selector = selector;
}
@Nullable
public static Parameter valueByName(String name) {
try {
return valueOf(name);
} catch (IllegalArgumentException ex) {
return null;
}
}
}
}
@@ -20,29 +20,47 @@ package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.TypesBuilder;
import com.github.retrooper.packetevents.util.TypesBuilderData;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.incomingDirectMessage;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.outgoingDirectMessage;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.teamMessage;
import static com.github.retrooper.packetevents.protocol.chat.ChatTypeDecoration.withSender;
public class ChatTypes {
private static final Map<String, ChatType> CHAT_TYPE_MAP = new HashMap<>();
//Key - mappings version, value - map with chat type ids and chat types
private static final Map<Byte, Map<Integer, ChatType>> CHAT_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("chat/chat_type_mappings",
ClientVersion.V_1_18_2,
ClientVersion.V_1_19,
ClientVersion.V_1_19_1);
static {
TYPES_BUILDER.unloadFileMappings();
}
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("chat/chat_type_mappings");
public static ChatType define(String key) {
return define(key, withSender("chat.type.text"));
}
public static ChatType define(String key, ChatTypeDecoration chatDeco) {
return define(key, chatDeco, withSender("chat.type.text.narrate"));
}
public static ChatType define(String key, ChatTypeDecoration chatDeco, ChatTypeDecoration narrationDeco) {
TypesBuilderData data = TYPES_BUILDER.define(key);
ChatType chatType = new ChatType() {
private final int[] ids = data.getData();
@Override
public ChatTypeDecoration getChatDecoration() {
return chatDeco;
}
@Override
public ChatTypeDecoration getNarrationDecoration() {
return narrationDeco;
}
@Override
public ResourceLocation getName() {
@@ -51,16 +69,10 @@ public class ChatTypes {
@Override
public int getId(ClientVersion version) {
int index = TYPES_BUILDER.getDataIndex(version);
return ids[index];
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
};
CHAT_TYPE_MAP.put(chatType.getName().toString(), chatType);
for (ClientVersion version : TYPES_BUILDER.getVersions()) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, ChatType> typeIdMap = CHAT_TYPE_ID_MAP.computeIfAbsent((byte) index, k -> new HashMap<>());
typeIdMap.put(chatType.getId(version), chatType);
}
MappingHelper.registerMapping(TYPES_BUILDER, CHAT_TYPE_MAP, CHAT_TYPE_ID_MAP, chatType);
return chatType;
}
@@ -75,12 +87,21 @@ public class ChatTypes {
}
public static final ChatType CHAT = define("chat");
public static final ChatType SAY_COMMAND = define("say_command");
public static final ChatType MSG_COMMAND_INCOMING = define("msg_command_incoming");
public static final ChatType MSG_COMMAND_OUTGOING = define("msg_command_outgoing");
public static final ChatType TEAM_MSG_COMMAND_INCOMING = define("team_msg_command_incoming");
public static final ChatType TEAM_MSG_COMMAND_OUTGOING = define("team_msg_command_outgoing");
public static final ChatType EMOTE_COMMAND = define("emote_command");
public static final ChatType SAY_COMMAND = define("say_command",
withSender("chat.type.announcement"));
public static final ChatType MSG_COMMAND_INCOMING = define("msg_command_incoming",
incomingDirectMessage("commands.message.display.incoming"));
public static final ChatType MSG_COMMAND_OUTGOING = define("msg_command_outgoing",
outgoingDirectMessage("commands.message.display.outgoing"));
public static final ChatType TEAM_MSG_COMMAND_INCOMING = define("team_msg_command_incoming",
teamMessage("chat.type.team.text"));
public static final ChatType TEAM_MSG_COMMAND_OUTGOING = define("team_msg_command_outgoing",
teamMessage("chat.type.team.sent"));
public static final ChatType EMOTE_COMMAND = define("emote_command",
withSender("chat.type.emote"),
withSender("chat.type.emote"));
// added by CraftBukkit for a few versions
public static final ChatType RAW = define("raw");
@Deprecated
@@ -91,4 +112,16 @@ public class ChatTypes {
public static final ChatType MSG_COMMAND = define("msg_command");
@Deprecated
public static final ChatType TEAM_MSG_COMMAND = define("team_msg_command");
/**
* Returns an immutable view of the chat types.
* @return Chat Types
*/
public static Collection<ChatType> values() {
return Collections.unmodifiableCollection(CHAT_TYPE_MAP.values());
}
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -16,9 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.protocol.chat.Parsers.Parser;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
@@ -26,20 +27,33 @@ import java.util.List;
import java.util.Optional;
public class Node {
private byte flags;
private List<Integer> children;
private Optional<Integer> redirectNodeIndex;
private int redirectNodeIndex;
private Optional<String> name;
private Optional<Integer> parserID;
private Optional<Parser> parser;
private Optional<List<Object>> properties;
private Optional<ResourceLocation> suggestionsType;
public Node(byte flags, List<Integer> children, @Nullable Integer redirectNodeIndex, @Nullable String name, @Nullable Integer parserID, @Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType) {
public Node(
byte flags, List<Integer> children, int redirectNodeIndex, @Nullable String name,
@Nullable Integer parserID, @Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType
) {
this(flags, children, redirectNodeIndex, name, parserID == null ? null : Parsers.getById(
PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), parserID),
properties, suggestionsType);
}
public Node(
byte flags, List<Integer> children, int redirectNodeIndex, @Nullable String name, @Nullable Parser parser,
@Nullable List<Object> properties, @Nullable ResourceLocation suggestionsType
) {
this.flags = flags;
this.children = children;
this.redirectNodeIndex = Optional.ofNullable(redirectNodeIndex);
this.redirectNodeIndex = redirectNodeIndex;
this.name = Optional.ofNullable(name);
this.parserID = Optional.ofNullable(parserID);
this.parser = Optional.ofNullable(parser);
this.properties = Optional.ofNullable(properties);
this.suggestionsType = Optional.ofNullable(suggestionsType);
}
@@ -60,11 +74,11 @@ public class Node {
this.children = children;
}
public Optional<Integer> getRedirectNodeIndex() {
public int getRedirectNodeIndex() {
return redirectNodeIndex;
}
public void setRedirectNodeIndex(Optional<Integer> redirectNodeIndex) {
public void setRedirectNodeIndex(int redirectNodeIndex) {
this.redirectNodeIndex = redirectNodeIndex;
}
@@ -76,12 +90,22 @@ public class Node {
this.name = name;
}
public Optional<Parser> getParser() {
return this.parser;
}
public void setParser(Optional<Parser> parser) {
this.parser = parser;
}
public Optional<Integer> getParserID() {
return parserID;
return this.parser.map(parser -> parser.getId(PacketEvents.getAPI()
.getServerManager().getVersion().toClientVersion()));
}
public void setParserID(Optional<Integer> parserID) {
this.parserID = parserID;
this.parser = parserID.map(id -> Parsers.getById(PacketEvents.getAPI()
.getServerManager().getVersion().toClientVersion(), id));
}
public Optional<List<Object>> getProperties() {
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2022 retrooper and contributors
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,171 +16,265 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class Parsers {
private static final List<Parser> parsers = Arrays.asList(
new Parser("brigadier:bool", null, null),
new Parser("brigadier:float",
packetWrapper -> {
byte flags = packetWrapper.readByte();
float min = (flags & 0x01) != 0 ? packetWrapper.readFloat() : -Float.MAX_VALUE;
float max = (flags & 0x02) != 0 ? packetWrapper.readFloat() : Float.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeFloat((float) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeFloat((float) properties.get(2));
}
),
new Parser("brigadier:double",
packetWrapper -> {
byte flags = packetWrapper.readByte();
double min = (flags & 0x01) != 0 ? packetWrapper.readDouble() : -Double.MAX_VALUE;
double max = (flags & 0x02) != 0 ? packetWrapper.readDouble() : Double.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeDouble((double) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeDouble((double) properties.get(2));
}
),
new Parser("brigadier:integer",
packetWrapper -> {
byte flags = packetWrapper.readByte();
int min = (flags & 0x01) != 0 ? packetWrapper.readInt() : Integer.MIN_VALUE;
int max = (flags & 0x02) != 0 ? packetWrapper.readInt() : Integer.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeInt((int) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeInt((int) properties.get(2));
}
),
new Parser("brigadier:long",
packetWrapper -> {
byte flags = packetWrapper.readByte();
long min = (flags & 0x01) != 0 ? packetWrapper.readLong() : Long.MIN_VALUE;
long max = (flags & 0x02) != 0 ? packetWrapper.readLong() : Long.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeLong((long) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeLong((long) properties.get(2));
}
),
new Parser("brigadier:string",
packetWrapper -> Collections.singletonList(packetWrapper.readVarInt()),
(packetWrapper, properties) -> packetWrapper.writeVarInt((Integer) properties.get(0))
),
new Parser("minecraft:entity",
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
),
new Parser("minecraft:game_profile", null, null),
new Parser("minecraft:block_pos", null, null),
new Parser("minecraft:column_pos", null, null),
new Parser("minecraft:vec3", null, null),
new Parser("minecraft:vec2", null, null),
new Parser("minecraft:block_state", null, null),
new Parser("minecraft:block_predicate", null, null),
new Parser("minecraft:item_stack", null, null),
new Parser("minecraft:item_predicate", null, null),
new Parser("minecraft:color", null, null),
new Parser("minecraft:component", null, null),
new Parser("minecraft:style", null, null),
new Parser("minecraft:message", null, null),
new Parser("minecraft:nbt", null, null),
new Parser("minecraft:nbt_tag", null, null),
new Parser("minecraft:nbt_path", null, null),
new Parser("minecraft:objective", null, null),
new Parser("minecraft:objective_criteria", null, null),
new Parser("minecraft:operation", null, null),
new Parser("minecraft:particle", null, null),
new Parser("minecraft:angle", null, null),
new Parser("minecraft:rotation", null, null),
new Parser("minecraft:scoreboard_slot", null, null),
new Parser("minecraft:score_holder",
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
),
new Parser("minecraft:swizzle", null, null),
new Parser("minecraft:team", null, null),
new Parser("minecraft:item_slot", null, null),
new Parser("minecraft:resource_location", null, null),
new Parser("minecraft:function", null, null),
new Parser("minecraft:entity_anchor", null, null),
new Parser("minecraft:int_range", null, null),
new Parser("minecraft:float_range", null, null),
new Parser("minecraft:dimension", null, null),
new Parser("minecraft:gamemode", null, null),
new Parser("minecraft:time",
packetWrapper -> Collections.singletonList(packetWrapper.readInt()),
(packetWrapper, properties) -> packetWrapper.writeInt((int) properties.get(0))
),
new Parser("minecraft:resource_or_tag",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("minecraft:resource_or_tag_key",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("minecraft:resource",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("minecraft:resource_key",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
),
new Parser("minecraft:template_mirror", null, null),
new Parser("minecraft:template_rotation", null, null),
new Parser("minecraft:heightmap", null, null),
new Parser("minecraft:uuid", null, null)
);
public static List<Parser> getParsers() {
return parsers;
private static final List<Parser> ALL_PARSERS = new ArrayList<>(); // support for old methods
private static final Map<String, Parser> PARSER_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, Parser>> PARSER_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("command/argument_parser_mappings");
public static Parser define(String key) {
return define(key, null, null);
}
public static final class Parser {
private final String name; //not really needed, just for toString or something
private final Optional<Function<PacketWrapper<?>, List<Object>>> read;
private final Optional<BiConsumer<PacketWrapper<?>, List<Object>>> write;
public static Parser define(String key, @Nullable Reader reader, @Nullable Writer writer) {
TypesBuilderData data = TYPES_BUILDER.define(key);
Parser parser = new Parser(data, reader, writer);
ALL_PARSERS.add(parser);
MappingHelper.registerMapping(TYPES_BUILDER, PARSER_MAP, PARSER_ID_MAP, parser);
return parser;
}
// with key
public static Parser getByName(String name) {
return PARSER_MAP.get(name);
}
public static Parser getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, Parser> idMap = PARSER_ID_MAP.get((byte) index);
return idMap.get(id);
}
public static List<Parser> getParsers() {
return Collections.unmodifiableList(ALL_PARSERS);
}
public static final Parser BRIGADIER_BOOL = define("brigadier:bool", null, null);
public static final Parser BRIGADIER_FLOAT = define("brigadier:float",
packetWrapper -> {
byte flags = packetWrapper.readByte();
float min = (flags & 0x01) != 0 ? packetWrapper.readFloat() : -Float.MAX_VALUE;
float max = (flags & 0x02) != 0 ? packetWrapper.readFloat() : Float.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeFloat((float) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeFloat((float) properties.get(2));
}
);
public static final Parser BRIGADIER_DOUBLE = define("brigadier:double",
packetWrapper -> {
byte flags = packetWrapper.readByte();
double min = (flags & 0x01) != 0 ? packetWrapper.readDouble() : -Double.MAX_VALUE;
double max = (flags & 0x02) != 0 ? packetWrapper.readDouble() : Double.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeDouble((double) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeDouble((double) properties.get(2));
}
);
public static final Parser BRIGADIER_INTEGER = define("brigadier:integer",
packetWrapper -> {
byte flags = packetWrapper.readByte();
int min = (flags & 0x01) != 0 ? packetWrapper.readInt() : Integer.MIN_VALUE;
int max = (flags & 0x02) != 0 ? packetWrapper.readInt() : Integer.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeInt((int) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeInt((int) properties.get(2));
}
);
public static final Parser BRIGADIER_LONG = define("brigadier:long",
packetWrapper -> {
byte flags = packetWrapper.readByte();
long min = (flags & 0x01) != 0 ? packetWrapper.readLong() : Long.MIN_VALUE;
long max = (flags & 0x02) != 0 ? packetWrapper.readLong() : Long.MAX_VALUE;
return Arrays.asList(flags, min, max);
},
(packetWrapper, properties) -> {
byte flags = (byte) properties.get(0);
packetWrapper.writeByte(flags);
if ((flags & 0x01) != 0) packetWrapper.writeLong((long) properties.get(1));
if ((flags & 0x02) != 0) packetWrapper.writeLong((long) properties.get(2));
}
);
public static final Parser BRIGADIER_STRING = define("brigadier:string",
packetWrapper -> Collections.singletonList(packetWrapper.readVarInt()),
(packetWrapper, properties) -> packetWrapper.writeVarInt((Integer) properties.get(0))
);
public static final Parser ENTITY = define("entity",
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
);
public static final Parser GAME_PROFILE = define("game_profile", null, null);
public static final Parser BLOCK_POS = define("block_pos", null, null);
public static final Parser COLUMN_POS = define("column_pos", null, null);
public static final Parser VEC3 = define("vec3", null, null);
public static final Parser VEC2 = define("vec2", null, null);
public static final Parser BLOCK_STATE = define("block_state", null, null);
public static final Parser BLOCK_PREDICATE = define("block_predicate", null, null);
public static final Parser ITEM_STACK = define("item_stack", null, null);
public static final Parser ITEM_PREDICATE = define("item_predicate", null, null);
public static final Parser COLOR = define("color", null, null);
public static final Parser COMPONENT = define("component", null, null);
public static final Parser STYLE = define("style", null, null);
public static final Parser MESSAGE = define("message", null, null);
public static final Parser NBT_COMPOUND_TAG = define("nbt_compound_tag", null, null);
@Deprecated
public static final Parser NBT = NBT_COMPOUND_TAG;
public static final Parser NBT_TAG = define("nbt_tag", null, null);
public static final Parser NBT_PATH = define("nbt_path", null, null);
public static final Parser OBJECTIVE = define("objective", null, null);
public static final Parser OBJECTIVE_CRITERIA = define("objective_criteria", null, null);
public static final Parser OPERATION = define("operation", null, null);
public static final Parser PARTICLE = define("particle", null, null);
public static final Parser ANGLE = define("angle", null, null);
public static final Parser ROTATION = define("rotation", null, null);
public static final Parser SCOREBOARD_SLOT = define("scoreboard_slot", null, null);
public static final Parser SCORE_HOLDER = define("score_holder",
packetWrapper -> Collections.singletonList(packetWrapper.readByte()),
(packetWrapper, properties) -> packetWrapper.writeByte(((Byte) properties.get(0)).intValue())
);
public static final Parser SWIZZLE = define("swizzle", null, null);
public static final Parser TEAM = define("team", null, null);
public static final Parser ITEM_SLOT = define("item_slot", null, null);
public static final Parser ITEM_SLOTS = define("item_slots", null, null);
public static final Parser RESOURCE_LOCATION = define("resource_location", null, null);
public static final Parser MOB_EFFECT = define("mob_effect", null, null);
public static final Parser FUNCTION = define("function", null, null);
public static final Parser ENTITY_ANCHOR = define("entity_anchor", null, null);
public static final Parser INT_RANGE = define("int_range", null, null);
public static final Parser FLOAT_RANGE = define("float_range", null, null);
public static final Parser ITEM_ENCHANTMENT = define("item_enchantment", null, null);
public static final Parser ENTITY_SUMMON = define("entity_summon", null, null);
public static final Parser DIMENSION = define("dimension", null, null);
public static final Parser GAMEMODE = define("gamemode", null, null);
public static final Parser TIME = define("time",
wrapper -> Collections.singletonList(wrapper.getServerVersion()
.isNewerThanOrEquals(ServerVersion.V_1_19_4) ? wrapper.readInt() : 0),
(wrapper, properties) -> {
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_19_4)) {
wrapper.writeInt((int) properties.get(0));
}
}
);
public static final Parser RESOURCE_OR_TAG = define("resource_or_tag",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
);
public static final Parser RESOURCE_OR_TAG_KEY = define("resource_or_tag_key",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
);
public static final Parser RESOURCE = define("resource",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
);
public static final Parser RESOURCE_KEY = define("resource_key",
packetWrapper -> Collections.singletonList(packetWrapper.readIdentifier()),
(packetWrapper, properties) -> packetWrapper.writeIdentifier((ResourceLocation) properties.get(0))
);
public static final Parser TEMPLATE_MIRROR = define("template_mirror", null, null);
public static final Parser TEMPLATE_ROTATION = define("template_rotation", null, null);
public static final Parser HEIGHTMAP = define("heightmap", null, null);
public static final Parser LOOT_TABLE = define("loot_table", null, null);
public static final Parser LOOT_PREDICATE = define("loot_predicate", null, null);
public static final Parser LOOT_MODIFIER = define("loot_modifier", null, null);
public static final Parser UUID = define("uuid", null, null);
static {
TYPES_BUILDER.unloadFileMappings();
}
@FunctionalInterface
public interface Reader extends Function<PacketWrapper<?>, List<Object>> {}
@FunctionalInterface
public interface Writer extends BiConsumer<PacketWrapper<?>, List<Object>> {}
public static final class Parser implements MappedEntity {
private final TypesBuilderData data;
private final Reader reader;
private final Writer writer;
@Deprecated
public Parser(String name, @Nullable Function<PacketWrapper<?>, List<Object>> read, @Nullable BiConsumer<PacketWrapper<?>, List<Object>> write) {
this.name = name;
this.read = Optional.ofNullable(read);
this.write = Optional.ofNullable(write);
this(
new TypesBuilderData(new ResourceLocation(name), new int[0]),
read == null ? null : read::apply,
write == null ? null : write::accept
);
}
public Optional<List<Object>> readProperties(PacketWrapper<?> packetWrapper) {
return read.map(fn -> fn.apply(packetWrapper));
private Parser(TypesBuilderData data, @Nullable Reader reader, Writer writer) {
this.data = data;
this.reader = reader;
this.writer = writer;
}
public void writeProperties(PacketWrapper<?> packetWrapper, List<Object> properties) {
write.ifPresent(fn -> fn.accept(packetWrapper, properties));
public Optional<List<Object>> readProperties(PacketWrapper<?> wrapper) {
if (this.reader != null) {
return Optional.of(this.reader.apply(wrapper));
}
return Optional.empty();
}
public void writeProperties(PacketWrapper<?> wrapper, List<Object> properties) {
if (this.writer != null) {
this.writer.accept(wrapper, properties);
}
}
@Override
public ResourceLocation getName() {
return this.data.getName();
}
@Override
public int getId(ClientVersion version) {
int index = TYPES_BUILDER.getDataIndex(version);
return this.data.getData()[index];
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Parser) {
return this.getName().equals(((Parser) obj).getName());
}
return false;
}
}
}
@@ -2,9 +2,9 @@ package com.github.retrooper.packetevents.protocol.chat;
public class SignedCommandArgument {
private String argument;
private byte[] signature;
private MessageSignature signature;
public SignedCommandArgument(String argument, byte[] signature) {
public SignedCommandArgument(String argument, MessageSignature signature) {
this.argument = argument;
this.signature = signature;
}
@@ -17,11 +17,11 @@ public class SignedCommandArgument {
this.argument = argument;
}
public byte[] getSignature() {
public MessageSignature getSignature() {
return signature;
}
public void setSignature(byte[] signature) {
public void setSignature(MessageSignature signature) {
this.signature = signature;
}
}
@@ -0,0 +1,58 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.chat;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
public class StaticChatType implements ChatType {
private final ChatTypeDecoration chatDecoration;
private final ChatTypeDecoration narrationDecoration;
public StaticChatType(ChatTypeDecoration chatDecoration, ChatTypeDecoration narrationDecoration) {
this.chatDecoration = chatDecoration;
this.narrationDecoration = narrationDecoration;
}
@Override
public ChatTypeDecoration getChatDecoration() {
return this.chatDecoration;
}
@Override
public ChatTypeDecoration getNarrationDecoration() {
return this.narrationDecoration;
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
}
@Override
public int getId(ClientVersion version) {
throw new UnsupportedOperationException();
}
@Override
public boolean isRegistered() {
return false;
}
}
@@ -30,7 +30,7 @@ import java.util.UUID;
public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
private String plainContent;
private @Nullable Component unsignedChatContent;
private ChatTypeBoundNetwork chatType;
private ChatType.Bound chatFormatting;
private byte @Nullable [] previousSignature;
private byte[] signature;
private Instant timestamp;
@@ -40,15 +40,15 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
public ChatMessage_v1_19_1(String plainContent, Component decoratedChatContent,
@Nullable Component unsignedChatContent,
UUID senderUUID, ChatTypeBoundNetwork chatType,
UUID senderUUID, ChatType.Bound chatFormatting,
byte @Nullable [] previousSignature, byte[] signature,
Instant timestamp, long salt,
LastSeenMessages lastSeenMessages,
FilterMask filterMask) {
super(decoratedChatContent, chatType.getType(), senderUUID);
super(decoratedChatContent, chatFormatting.getType(), senderUUID);
this.plainContent = plainContent;
this.unsignedChatContent = unsignedChatContent;
this.chatType = chatType;
this.chatFormatting = chatFormatting;
this.previousSignature = previousSignature;
this.signature = signature;
this.timestamp = timestamp;
@@ -79,20 +79,38 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
@Override
public ChatType getType() {
return chatType.getType();
return chatFormatting.getType();
}
@Override
public void setType(ChatType type) {
chatType.setType(type);
chatFormatting.setType(type);
}
public ChatTypeBoundNetwork getChatType() {
return chatType;
public ChatType.Bound getChatFormatting() {
return chatFormatting;
}
public void setChatType(ChatTypeBoundNetwork type) {
this.chatType = type;
public void setChatFormatting(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
/**
* Retrieves the chat formatting. Please refer to {@link ChatMessage_v1_19_1#getChatFormatting}
* @return chat formatting which contains the actual chat type.
*/
@Deprecated
public ChatType.Bound getChatType() {
return chatFormatting;
}
/**
* Sets the chat formatting. Please refer to {@link ChatMessage_v1_19_1#setChatFormatting}
* @param chatFormatting formatting which contains the actual chat type.
*/
@Deprecated
public void setChatType(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
public byte @Nullable [] getPreviousSignature() {
@@ -143,6 +161,10 @@ public class ChatMessage_v1_19_1 extends ChatMessage_v1_16 {
this.filterMask = filterMask;
}
/**
* Please refer to {@link com.github.retrooper.packetevents.protocol.chat.ChatType.Bound}
*/
@Deprecated
public static class ChatTypeBoundNetwork {
private ChatType type;
private Component name;
@@ -1,5 +1,6 @@
package com.github.retrooper.packetevents.protocol.chat.message;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import com.github.retrooper.packetevents.util.adventure.AdventureSerializer;
@@ -19,10 +20,10 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
LastSeenMessages.Packed lastSeenMessagesPacked;
@Nullable Component unsignedChatContent;
FilterMask filterMask;
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType;
ChatType.Bound chatFormatting;
public ChatMessage_v1_19_3(UUID senderUUID, int index, byte[] signature, String plainContent, Instant timestamp, long salt, LastSeenMessages.Packed lastSeenMessagesPacked, @Nullable Component unsignedChatContent, FilterMask filterMask, ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType) {
super(Component.text(plainContent), chatType.getType(), senderUUID);
public ChatMessage_v1_19_3(UUID senderUUID, int index, byte[] signature, String plainContent, Instant timestamp, long salt, LastSeenMessages.Packed lastSeenMessagesPacked, @Nullable Component unsignedChatContent, FilterMask filterMask, ChatType.Bound chatFormatting) {
super(Component.text(plainContent), chatFormatting.getType(), senderUUID);
this.index = index;
this.signature = signature;
this.plainContent = plainContent;
@@ -31,7 +32,7 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
this.lastSeenMessagesPacked = lastSeenMessagesPacked;
this.unsignedChatContent = unsignedChatContent;
this.filterMask = filterMask;
this.chatType = chatType;
this.chatFormatting = chatFormatting;
}
public int getIndex() {
@@ -109,11 +110,30 @@ public class ChatMessage_v1_19_3 extends ChatMessage_v1_16 {
this.filterMask = filterMask;
}
public ChatMessage_v1_19_1.ChatTypeBoundNetwork getChatType() {
return chatType;
public ChatType.Bound getChatFormatting() {
return chatFormatting;
}
public void setChatType(ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType) {
this.chatType = chatType;
public void setChatFormatting(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
/**
* Retrieves the chat formatting. Please refer to {@link ChatMessage_v1_19_3#getChatFormatting}
* @return chat formatting which contains the actual chat type.
*/
@Deprecated
public ChatType.Bound getChatType() {
return chatFormatting;
}
/**
* Sets the chat formatting. Please refer to {@link ChatMessage_v1_19_3#setChatFormatting}
* @param chatFormatting formatting which contains the actual chat type.
*/
@Deprecated
public void setChatType(ChatType.Bound chatFormatting) {
this.chatFormatting = chatFormatting;
}
}
@@ -50,8 +50,8 @@ public class ChatMessageProcessor_v1_19_1 implements ChatMessageProcessor {
LastSeenMessages lastSeenMessages = wrapper.readLastSeenMessages();
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
FilterMask filterMask = wrapper.readFilterMask();
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType = wrapper.readChatTypeBoundNetwork();
return new ChatMessage_v1_19_1(plainContent, chatContent, unsignedChatContent, senderUUID, chatType,
ChatType.Bound chatFormatting = wrapper.readChatTypeBoundNetwork();
return new ChatMessage_v1_19_1(plainContent, chatContent, unsignedChatContent, senderUUID, chatFormatting,
previousSignature, signature, timestamp, salt, lastSeenMessages, filterMask);
}
@@ -68,6 +68,6 @@ public class ChatMessageProcessor_v1_19_1 implements ChatMessageProcessor {
wrapper.writeLastSeenMessages(newData.getLastSeenMessages());
wrapper.writeOptional(newData.getUnsignedChatContent(), PacketWrapper::writeComponent);
wrapper.writeFilterMask(newData.getFilterMask());
wrapper.writeChatTypeBoundNetwork(newData.getChatType());
wrapper.writeChatTypeBoundNetwork(newData.getChatFormatting());
}
}
@@ -1,5 +1,6 @@
package com.github.retrooper.packetevents.protocol.chat.message.reader.impl;
import com.github.retrooper.packetevents.protocol.chat.ChatType;
import com.github.retrooper.packetevents.protocol.chat.LastSeenMessages;
import com.github.retrooper.packetevents.protocol.chat.filter.FilterMask;
import com.github.retrooper.packetevents.protocol.chat.message.ChatMessage;
@@ -25,7 +26,7 @@ public class ChatMessageProcessor_v1_19_3 implements ChatMessageProcessor {
LastSeenMessages.Packed lastSeenMessagesPacked = wrapper.readLastSeenMessagesPacked();
Component unsignedChatContent = wrapper.readOptional(PacketWrapper::readComponent);
FilterMask filterMask = wrapper.readFilterMask();
ChatMessage_v1_19_1.ChatTypeBoundNetwork chatType = wrapper.readChatTypeBoundNetwork();
ChatType.Bound chatType = wrapper.readChatTypeBoundNetwork();
return new ChatMessage_v1_19_3(senderUUID, index, signature, plainContent, timestamp, salt, lastSeenMessagesPacked, unsignedChatContent, filterMask, chatType);
}
@@ -42,6 +43,6 @@ public class ChatMessageProcessor_v1_19_3 implements ChatMessageProcessor {
wrapper.writeLastSeenMessagesPacked(newData.getLastSeenMessagesPacked());
wrapper.writeOptional(newData.getUnsignedChatContent().orElse(null), PacketWrapper::writeComponent);
wrapper.writeFilterMask(newData.getFilterMask());
wrapper.writeChatTypeBoundNetwork(newData.getChatType());
wrapper.writeChatTypeBoundNetwork(newData.getChatFormatting());
}
}
@@ -0,0 +1,91 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
public class ComponentPredicate implements Predicate<IComponentMap> {
private List<ComponentValue<?>> requiredComponents;
public ComponentPredicate(List<ComponentValue<?>> requiredComponents) {
this.requiredComponents = requiredComponents;
}
public static ComponentPredicate read(PacketWrapper<?> wrapper) {
List<ComponentValue<?>> components = wrapper.readList(ComponentValue::read);
return new ComponentPredicate(components);
}
public static void write(PacketWrapper<?> wrapper, ComponentPredicate predicate) {
wrapper.writeList(predicate.requiredComponents, ComponentValue::write);
}
public static ComponentPredicate emptyPredicate() {
return new ComponentPredicate(new ArrayList<>());
}
@SuppressWarnings("unchecked")
public static ComponentPredicate fromPatches(PatchableComponentMap components) {
Map<ComponentType<?>, Optional<?>> patches = components.getPatches();
List<ComponentValue<?>> values = new ArrayList<>(patches.size());
for (Map.Entry<ComponentType<?>, Optional<?>> patch : patches.entrySet()) {
if (patch.getValue().isPresent()) {
values.add(new ComponentValue<>(
(ComponentType<Object>) patch.getKey(),
patch.getValue().get()
));
}
}
return new ComponentPredicate(values);
}
public PatchableComponentMap asPatches(StaticComponentMap base) {
PatchableComponentMap patched = new PatchableComponentMap(base);
for (ComponentValue<?> component : this.requiredComponents) {
patched.set(component);
}
return patched;
}
@Override
public boolean test(IComponentMap components) {
for (ComponentValue<?> component : this.requiredComponents) {
Optional<?> value = components.getOptional(component.getType());
if (!value.isPresent() || !component.getValue().equals(value.get())) {
return false;
}
}
return true;
}
public List<ComponentValue<?>> getRequiredComponents() {
return this.requiredComponents;
}
public void setRequiredComponents(List<ComponentValue<?>> requiredComponents) {
this.requiredComponents = requiredComponents;
}
}
@@ -0,0 +1,29 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface ComponentType<T> extends MappedEntity {
T read(PacketWrapper<?> wrapper);
void write(PacketWrapper<?> wrapper, T content);
}
@@ -0,0 +1,275 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ArmorTrim;
import com.github.retrooper.packetevents.protocol.component.builtin.item.BannerLayers;
import com.github.retrooper.packetevents.protocol.component.builtin.item.BundleContents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ChargedProjectiles;
import com.github.retrooper.packetevents.protocol.component.builtin.item.CustomData;
import com.github.retrooper.packetevents.protocol.component.builtin.item.DebugStickState;
import com.github.retrooper.packetevents.protocol.component.builtin.item.FireworkExplosion;
import com.github.retrooper.packetevents.protocol.component.builtin.item.FoodProperties;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAdventurePredicate;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAttributeModifiers;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBees;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemBlockStateProperties;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerContents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemContainerLoot;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemDyeColor;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemFireworks;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemJukeboxPlayable;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLock;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLore;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemMapDecorations;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemMapPostProcessingState;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemPotionContents;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemProfile;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRarity;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRecipes;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemTool;
import com.github.retrooper.packetevents.protocol.component.builtin.item.LodestoneTracker;
import com.github.retrooper.packetevents.protocol.component.builtin.item.PotDecorations;
import com.github.retrooper.packetevents.protocol.component.builtin.item.SuspiciousStewEffects;
import com.github.retrooper.packetevents.protocol.component.builtin.item.WritableBookContent;
import com.github.retrooper.packetevents.protocol.component.builtin.item.WrittenBookContent;
import com.github.retrooper.packetevents.protocol.item.instrument.Instrument;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Dummy;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
public class ComponentTypes {
private static final Map<String, ComponentType<?>> COMPONENT_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, ComponentType<?>>> COMPONENT_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_component_mappings");
public static <T> ComponentType<T> define(String key) {
return define(key, null, null);
}
public static <T> ComponentType<T> define(String key, @Nullable Reader<T> reader, @Nullable Writer<T> writer) {
TypesBuilderData data = TYPES_BUILDER.define(key);
ComponentType<T> type = new ComponentType<T>() {
@Override
public T read(PacketWrapper<?> wrapper) {
return reader == null ? null : reader.apply(wrapper);
}
@Override
public void write(PacketWrapper<?> wrapper, T content) {
if (writer != null) {
writer.accept(wrapper, content);
}
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ComponentType<?>) {
return this.getName().equals(((ComponentType<?>) obj).getName());
}
return false;
}
@Override
public String toString() {
return "Component[" + this.getName() + "]";
}
};
MappingHelper.registerMapping(TYPES_BUILDER, COMPONENT_TYPE_MAP, COMPONENT_TYPE_ID_MAP, type);
return type;
}
// with key
public static ComponentType<?> getByName(String name) {
return COMPONENT_TYPE_MAP.get(name);
}
public static ComponentType<?> getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, ComponentType<?>> idMap = COMPONENT_TYPE_ID_MAP.get((byte) index);
return idMap.get(id);
}
// item component types
public static final ComponentType<NBTCompound> CUSTOM_DATA = define("custom_data",
// mojang wraps their "persistent" codec as a stream codec just here,
// so packetevents has to handle nbt strings
CustomData::read, CustomData::write);
public static final ComponentType<Integer> MAX_STACK_SIZE = define("max_stack_size",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Integer> MAX_DAMAGE = define("max_damage",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Integer> DAMAGE = define("damage",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Boolean> UNBREAKABLE = define("unbreakable",
PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
public static final ComponentType<Component> CUSTOM_NAME = define("custom_name",
PacketWrapper::readComponent, PacketWrapper::writeComponent);
public static final ComponentType<Component> ITEM_NAME = define("item_name",
PacketWrapper::readComponent, PacketWrapper::writeComponent);
public static final ComponentType<ItemLore> LORE = define("lore",
ItemLore::read, ItemLore::write);
public static final ComponentType<ItemRarity> RARITY = define("rarity",
wrapper -> wrapper.readEnum(ItemRarity.values()), PacketWrapper::writeEnum);
public static final ComponentType<ItemEnchantments> ENCHANTMENTS = define("enchantments",
ItemEnchantments::read, ItemEnchantments::write);
public static final ComponentType<ItemAdventurePredicate> CAN_PLACE_ON = define("can_place_on",
ItemAdventurePredicate::read, ItemAdventurePredicate::write);
public static final ComponentType<ItemAdventurePredicate> CAN_BREAK = define("can_break",
ItemAdventurePredicate::read, ItemAdventurePredicate::write);
public static final ComponentType<ItemAttributeModifiers> ATTRIBUTE_MODIFIERS = define("attribute_modifiers",
ItemAttributeModifiers::read, ItemAttributeModifiers::write);
public static final ComponentType<Integer> CUSTOM_MODEL_DATA = define("custom_model_data",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Dummy> HIDE_ADDITIONAL_TOOLTIP = define("hide_additional_tooltip",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<Dummy> HIDE_TOOLTIP = define("hide_tooltip",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<Integer> REPAIR_COST = define("repair_cost",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<Dummy> CREATIVE_SLOT_LOCK = define("creative_slot_lock",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<Boolean> ENCHANTMENT_GLINT_OVERRIDE = define("enchantment_glint_override",
PacketWrapper::readBoolean, PacketWrapper::writeBoolean);
public static final ComponentType<Dummy> INTANGIBLE_PROJECTILE = define("intangible_projectile",
Dummy::dummyReadNbt, Dummy::dummyWriteNbt);
public static final ComponentType<FoodProperties> FOOD = define("food",
FoodProperties::read, FoodProperties::write);
public static final ComponentType<Dummy> FIRE_RESISTANT = define("fire_resistant",
Dummy::dummyRead, Dummy::dummyWrite);
public static final ComponentType<ItemTool> TOOL = define("tool",
ItemTool::read, ItemTool::write);
public static final ComponentType<ItemEnchantments> STORED_ENCHANTMENTS = define("stored_enchantments",
ItemEnchantments::read, ItemEnchantments::write);
public static final ComponentType<ItemDyeColor> DYED_COLOR = define("dyed_color",
ItemDyeColor::read, ItemDyeColor::write);
public static final ComponentType<Integer> MAP_COLOR = define("map_color",
PacketWrapper::readInt, PacketWrapper::writeInt);
public static final ComponentType<Integer> MAP_ID = define("map_id",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<ItemMapDecorations> MAP_DECORATIONS = define("map_decorations",
ItemMapDecorations::read, ItemMapDecorations::write);
public static final ComponentType<ItemMapPostProcessingState> MAP_POST_PROCESSING = define("map_post_processing",
wrapper -> wrapper.readEnum(ItemMapPostProcessingState.values()), PacketWrapper::writeEnum);
public static final ComponentType<ChargedProjectiles> CHARGED_PROJECTILES = define("charged_projectiles",
ChargedProjectiles::read, ChargedProjectiles::write);
public static final ComponentType<BundleContents> BUNDLE_CONTENTS = define("bundle_contents",
BundleContents::read, BundleContents::write);
public static final ComponentType<ItemPotionContents> POTION_CONTENTS = define("potion_contents",
ItemPotionContents::read, ItemPotionContents::write);
public static final ComponentType<SuspiciousStewEffects> SUSPICIOUS_STEW_EFFECTS = define("suspicious_stew_effects",
SuspiciousStewEffects::read, SuspiciousStewEffects::write);
public static final ComponentType<WritableBookContent> WRITABLE_BOOK_CONTENT = define("writable_book_content",
WritableBookContent::read, WritableBookContent::write);
public static final ComponentType<WrittenBookContent> WRITTEN_BOOK_CONTENT = define("written_book_content",
WrittenBookContent::read, WrittenBookContent::write);
public static final ComponentType<ArmorTrim> TRIM = define("trim",
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<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<Instrument> INSTRUMENT = define("instrument",
Instrument::read, Instrument::write);
public static final ComponentType<Integer> OMINOUS_BOTTLE_AMPLIFIER = define("ominous_bottle_amplifier",
PacketWrapper::readVarInt, PacketWrapper::writeVarInt);
public static final ComponentType<ItemRecipes> RECIPES = define("recipes",
ItemRecipes::read, ItemRecipes::write);
public static final ComponentType<LodestoneTracker> LODESTONE_TRACKER = define("lodestone_tracker",
LodestoneTracker::read, LodestoneTracker::write);
public static final ComponentType<FireworkExplosion> FIREWORK_EXPLOSION = define("firework_explosion",
FireworkExplosion::read, FireworkExplosion::write);
public static final ComponentType<ItemFireworks> FIREWORKS = define("fireworks",
ItemFireworks::read, ItemFireworks::write);
public static final ComponentType<ItemProfile> PROFILE = define("profile",
ItemProfile::read, ItemProfile::write);
public static final ComponentType<ResourceLocation> NOTE_BLOCK_SOUND = define("note_block_sound",
PacketWrapper::readIdentifier, PacketWrapper::writeIdentifier);
public static final ComponentType<BannerLayers> BANNER_PATTERNS = define("banner_patterns",
BannerLayers::read, BannerLayers::write);
public static final ComponentType<DyeColor> BASE_COLOR = define("base_color",
wrapper -> wrapper.readEnum(DyeColor.values()), PacketWrapper::writeEnum);
public static final ComponentType<PotDecorations> POT_DECORATIONS = define("pot_decorations",
PotDecorations::read, PotDecorations::write);
public static final ComponentType<ItemContainerContents> CONTAINER = define("container",
ItemContainerContents::read, ItemContainerContents::write);
public static final ComponentType<ItemBlockStateProperties> BLOCK_STATE = define("block_state",
ItemBlockStateProperties::read, ItemBlockStateProperties::write);
public static final ComponentType<ItemBees> BEES = define("bees",
ItemBees::read, ItemBees::write);
public static final ComponentType<ItemLock> LOCK = define("lock",
ItemLock::read, ItemLock::write);
public static final ComponentType<ItemContainerLoot> CONTAINER_LOOT = define("container_loot",
ItemContainerLoot::read, ItemContainerLoot::write);
// added in 1.21
public static final ComponentType<ItemJukeboxPlayable> JUKEBOX_PLAYABLE = define("jukebox_playable",
ItemJukeboxPlayable::read, ItemJukeboxPlayable::write);
/**
* Returns an immutable view of the component types.
*
* @return Component Types
*/
public static Collection<ComponentType<?>> values() {
return Collections.unmodifiableCollection(COMPONENT_TYPE_MAP.values());
}
static {
TYPES_BUILDER.unloadFileMappings();
}
@FunctionalInterface
public interface Reader<T> extends Function<PacketWrapper<?>, T> {}
@FunctionalInterface
public interface Writer<T> extends BiConsumer<PacketWrapper<?>, T> {}
}
@@ -0,0 +1,76 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public final class ComponentValue<T> {
private final ComponentType<T> type;
private final T value;
public ComponentValue(ComponentType<T> type, T value) {
this.type = type;
this.value = value;
}
public static ComponentValue<?> read(PacketWrapper<?> wrapper) {
ComponentType<?> type = wrapper.readMappedEntity(ComponentTypes::getById);
return read0(wrapper, type);
}
private static <T> ComponentValue<T> read0(PacketWrapper<?> wrapper, ComponentType<T> type) {
// additional method required here for proper handling because of how generics work
return new ComponentValue<>(type, type.read(wrapper));
}
public static <T> void write(PacketWrapper<?> wrapper, ComponentValue<T> value) {
wrapper.writeMappedEntity(value.type);
value.type.write(wrapper, value.value);
}
public ComponentType<T> getType() {
return this.type;
}
public T getValue() {
return this.value;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ComponentValue)) return false;
ComponentValue<?> that = (ComponentValue<?>) obj;
if (!this.type.equals(that.type)) return false;
return this.value.equals(that.value);
}
@Override
public int hashCode() {
return Objects.hash(this.type, this.value);
}
@Override
public String toString() {
return "ComponentValue{type=" + this.type + ", value=" + this.value + '}';
}
}
@@ -0,0 +1,58 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
public interface IComponentMap {
default <T> Optional<T> getOptional(ComponentType<T> type) {
return Optional.ofNullable(this.get(type));
}
boolean has(ComponentType<?> type);
@Contract("_, !null -> !null")
default <T> @Nullable T getOr(ComponentType<T> type, @Nullable T otherValue) {
T value = this.get(type);
if (value != null) {
return value;
}
return otherValue;
}
<T> @Nullable T get(ComponentType<T> type);
default <T> void set(ComponentValue<T> component) {
this.set(component.getType(), component.getValue());
}
default <T> void set(ComponentType<T> type, @Nullable T value) {
this.set(type, Optional.ofNullable(value));
}
default <T> void unset(ComponentType<T> type) {
this.set(type, Optional.empty());
}
<T> void set(ComponentType<T> type, Optional<T> value);
}
@@ -0,0 +1,103 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
public class PatchableComponentMap implements IComponentMap {
public static final PatchableComponentMap EMPTY = new PatchableComponentMap(
Collections.emptyMap(), Collections.emptyMap());
private final Map<ComponentType<?>, ?> base;
private final Map<ComponentType<?>, Optional<?>> patches;
public PatchableComponentMap(StaticComponentMap base) {
this(base.getDelegate(), new HashMap<>());
}
public PatchableComponentMap(Map<ComponentType<?>, ?> base) {
this(base, new HashMap<>());
}
public PatchableComponentMap(
StaticComponentMap base,
Map<ComponentType<?>, Optional<?>> patches
) {
this(base.getDelegate(), patches);
}
public PatchableComponentMap(
Map<ComponentType<?>, ?> base,
Map<ComponentType<?>, Optional<?>> patches
) {
this.base = Collections.unmodifiableMap(new HashMap<>(base));
this.patches = patches;
}
@SuppressWarnings("unchecked") // no
@Override
public <T> @Nullable T get(ComponentType<T> type) {
Optional<?> patched = this.patches.get(type);
if (patched != null) {
return (T) patched.orElse(null);
}
return (T) this.base.get(type);
}
@Override
public <T> void set(ComponentType<T> type, Optional<T> value) {
Object baseVal = this.base.get(type);
T newVal = value.orElse(null);
if (Objects.equals(baseVal, newVal)) {
this.patches.remove(type); // fallback to base
} else {
this.patches.put(type, value);
}
}
@Override
public boolean has(ComponentType<?> type) {
Optional<?> patched = this.patches.get(type);
return patched != null ? patched.isPresent() : this.base.containsKey(type);
}
public PatchableComponentMap copy() {
return new PatchableComponentMap(this.base, new HashMap<>(this.patches));
}
public Map<ComponentType<?>, ?> getBase() {
return this.base;
}
public Map<ComponentType<?>, Optional<?>> getPatches() {
return this.patches;
}
@Override
public String toString() {
return "PatchableComponentMap{base=" + this.base + ", patches=" + this.patches + '}';
}
}
@@ -0,0 +1,121 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemAttributeModifiers;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemLore;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemRarity;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class StaticComponentMap implements IComponentMap {
public static final StaticComponentMap EMPTY = new StaticComponentMap(Collections.emptyMap());
public static final StaticComponentMap SHARED_ITEM_COMPONENTS = builder()
.set(ComponentTypes.MAX_STACK_SIZE, 64)
.set(ComponentTypes.LORE, ItemLore.EMPTY)
.set(ComponentTypes.ENCHANTMENTS, ItemEnchantments.EMPTY)
.set(ComponentTypes.REPAIR_COST, 0)
.set(ComponentTypes.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY)
.set(ComponentTypes.RARITY, ItemRarity.COMMON)
.build();
private final boolean empty;
private final Map<ComponentType<?>, ?> delegate;
public StaticComponentMap(Map<ComponentType<?>, ?> delegate) {
this.empty = delegate.isEmpty();
this.delegate = this.empty ? Collections.emptyMap()
: Collections.unmodifiableMap(new HashMap<>(delegate));
}
public static Builder builder() {
return new Builder();
}
@Override
public boolean has(ComponentType<?> type) {
return !this.empty && this.delegate.containsKey(type);
}
@SuppressWarnings("unchecked") // no
@Override
public <T> @Nullable T get(ComponentType<T> type) {
return this.empty ? null : (T) this.delegate.get(type);
}
@Override
public <T> void set(ComponentType<T> type, Optional<T> value) {
throw new UnsupportedOperationException();
}
public StaticComponentMap merge(StaticComponentMap prioritizedMap) {
return builder().setAll(this).setAll(prioritizedMap).build();
}
public Map<ComponentType<?>, ?> getDelegate() {
return this.delegate;
}
public boolean isEmpty() {
return this.empty;
}
public static class Builder {
private final Map<ComponentType<?>, Object> map = new HashMap<>();
public Builder() {
}
public StaticComponentMap build() {
return new StaticComponentMap(this.map);
}
public Builder setAll(StaticComponentMap map) {
return this.setAll(map.getDelegate());
}
@SuppressWarnings("unchecked")
public Builder setAll(Map<ComponentType<?>, ?> map) {
for (Map.Entry<ComponentType<?>, ?> entry : map.entrySet()) {
this.set((ComponentType<Object>) entry.getKey(), entry.getValue());
}
return this;
}
public <T> Builder set(ComponentType<T> type, Optional<T> value) {
return this.set(type, value.orElse(null));
}
public <T> Builder set(ComponentType<T> type, @Nullable T value) {
if (value == null) {
this.map.remove(type);
} else {
this.map.put(type, value);
}
return this;
}
}
}
@@ -0,0 +1,95 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.trimmaterial.TrimMaterial;
import com.github.retrooper.packetevents.protocol.item.trimpattern.TrimPattern;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ArmorTrim {
private TrimMaterial material;
private TrimPattern pattern;
private boolean showInTooltip;
public ArmorTrim(TrimMaterial material, TrimPattern pattern, boolean showInTooltip) {
this.material = material;
this.pattern = pattern;
this.showInTooltip = showInTooltip;
}
public static ArmorTrim read(PacketWrapper<?> wrapper) {
TrimMaterial material = TrimMaterial.read(wrapper);
TrimPattern pattern = TrimPattern.read(wrapper);
boolean showInTooltip = wrapper.readBoolean();
return new ArmorTrim(material, pattern, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ArmorTrim trim) {
TrimMaterial.write(wrapper, trim.material);
TrimPattern.write(wrapper, trim.pattern);
wrapper.writeBoolean(trim.showInTooltip);
}
public TrimMaterial getMaterial() {
return this.material;
}
public void setMaterial(TrimMaterial material) {
this.material = material;
}
public TrimPattern getPattern() {
return this.pattern;
}
public void setPattern(TrimPattern pattern) {
this.pattern = pattern;
}
public boolean isShowInTooltip() {
return this.showInTooltip;
}
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ArmorTrim)) return false;
ArmorTrim armorTrim = (ArmorTrim) obj;
if (this.showInTooltip != armorTrim.showInTooltip) return false;
if (!this.material.equals(armorTrim.material)) return false;
return this.pattern.equals(armorTrim.pattern);
}
@Override
public int hashCode() {
return Objects.hash(this.material, this.pattern, this.showInTooltip);
}
@Override
public String toString() {
return "ArmorTrim{material=" + this.material + ", pattern=" + this.pattern + ", showInTooltip=" + this.showInTooltip + '}';
}
}
@@ -0,0 +1,123 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.color.DyeColor;
import com.github.retrooper.packetevents.protocol.item.banner.BannerPattern;
import com.github.retrooper.packetevents.protocol.item.banner.BannerPatterns;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class BannerLayers {
private List<Layer> layers;
public BannerLayers(List<Layer> layers) {
this.layers = layers;
}
public static BannerLayers read(PacketWrapper<?> wrapper) {
List<Layer> layers = wrapper.readList(Layer::read);
return new BannerLayers(layers);
}
public static void write(PacketWrapper<?> wrapper, BannerLayers patterns) {
wrapper.writeList(patterns.layers, Layer::write);
}
public void addLayer(Layer layer) {
this.layers.add(layer);
}
public List<Layer> getLayers() {
return this.layers;
}
public void setLayers(List<Layer> layers) {
this.layers = layers;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof BannerLayers)) return false;
BannerLayers that = (BannerLayers) obj;
return this.layers.equals(that.layers);
}
@Override
public int hashCode() {
return Objects.hashCode(this.layers);
}
public static class Layer {
private BannerPattern pattern;
private DyeColor color;
public Layer(BannerPattern pattern, DyeColor color) {
this.pattern = pattern;
this.color = color;
}
public static Layer read(PacketWrapper<?> wrapper) {
BannerPattern pattern = wrapper.readMappedEntityOrDirect(
BannerPatterns::getById, BannerPattern::readDirect);
DyeColor color = wrapper.readEnum(DyeColor.values());
return new Layer(pattern, color);
}
public static void write(PacketWrapper<?> wrapper, Layer layer) {
wrapper.writeMappedEntityOrDirect(layer.pattern, BannerPattern::writeDirect);
wrapper.writeEnum(layer.color);
}
public BannerPattern getPattern() {
return this.pattern;
}
public void setPattern(BannerPattern pattern) {
this.pattern = pattern;
}
public DyeColor getColor() {
return this.color;
}
public void setColor(DyeColor color) {
this.color = color;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Layer)) return false;
Layer layer = (Layer) obj;
if (!this.pattern.equals(layer.pattern)) return false;
return this.color == layer.color;
}
@Override
public int hashCode() {
return Objects.hash(this.pattern, this.color);
}
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class BundleContents {
private List<ItemStack> items;
public BundleContents(List<ItemStack> items) {
this.items = items;
}
public static BundleContents read(PacketWrapper<?> wrapper) {
List<ItemStack> items = wrapper.readList(PacketWrapper::readPresentItemStack);
return new BundleContents(items);
}
public static void write(PacketWrapper<?> wrapper, BundleContents projectiles) {
wrapper.writeList(projectiles.items, PacketWrapper::writePresentItemStack);
}
public void addItem(ItemStack itemStack) {
this.items.add(itemStack);
}
public List<ItemStack> getItems() {
return this.items;
}
public void setItems(List<ItemStack> items) {
this.items = items;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof BundleContents)) return false;
BundleContents that = (BundleContents) obj;
return this.items.equals(that.items);
}
@Override
public int hashCode() {
return Objects.hashCode(this.items);
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ChargedProjectiles {
private List<ItemStack> items;
public ChargedProjectiles(List<ItemStack> items) {
this.items = items;
}
public static ChargedProjectiles read(PacketWrapper<?> wrapper) {
List<ItemStack> items = wrapper.readList(PacketWrapper::readPresentItemStack);
return new ChargedProjectiles(items);
}
public static void write(PacketWrapper<?> wrapper, ChargedProjectiles projectiles) {
wrapper.writeList(projectiles.items, PacketWrapper::writePresentItemStack);
}
public void addItem(ItemStack itemStack) {
this.items.add(itemStack);
}
public List<ItemStack> getItems() {
return this.items;
}
public void setItems(List<ItemStack> items) {
this.items = items;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ChargedProjectiles)) return false;
ChargedProjectiles that = (ChargedProjectiles) obj;
return this.items.equals(that.items);
}
@Override
public int hashCode() {
return Objects.hashCode(this.items);
}
}
@@ -0,0 +1,45 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class CustomData {
private CustomData() {
}
public static NBTCompound read(PacketWrapper<?> wrapper) {
NBT nbt = wrapper.readNBTRaw();
if (nbt instanceof NBTCompound) {
return (NBTCompound) nbt;
}
if (nbt instanceof NBTString) {
// TODO: parse nbt string
}
throw new UnsupportedOperationException("Unsupported custom data nbt type: " + nbt.getType());
}
public static void write(PacketWrapper<?> wrapper, NBTCompound compound) {
wrapper.writeNBT(compound);
}
}
@@ -0,0 +1,93 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class DebugStickState {
private Map<StateType, String> properties;
public DebugStickState(Map<StateType, String> properties) {
this.properties = properties;
}
public static DebugStickState read(PacketWrapper<?> wrapper) {
NBTCompound compound = wrapper.readNBT();
Map<StateType, String> properties = new HashMap<>(compound.size());
for (Map.Entry<String, NBT> tag : compound.getTags().entrySet()) {
StateType stateType = StateTypes.getByName(tag.getKey());
String property = ((NBTString) tag.getValue()).getValue();
properties.put(stateType, property);
}
return new DebugStickState(properties);
}
public static void write(PacketWrapper<?> wrapper, DebugStickState state) {
NBTCompound compound = new NBTCompound();
for (Map.Entry<StateType, String> property : state.properties.entrySet()) {
compound.setTag(property.getKey().getName(),
new NBTString(property.getValue()));
}
wrapper.writeNBT(compound);
}
public @Nullable String getProperty(StateType stateType) {
return this.properties.get(stateType);
}
public void setProperty(StateType stateType, @Nullable String property) {
if (property != null) {
this.properties.put(stateType, property);
} else {
this.properties.remove(stateType);
}
}
public Map<StateType, String> getProperties() {
return this.properties;
}
public void setProperties(Map<StateType, String> properties) {
this.properties = properties;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof DebugStickState)) return false;
DebugStickState that = (DebugStickState) o;
return this.properties.equals(that.properties);
}
@Override
public int hashCode() {
return Objects.hashCode(this.properties);
}
}
@@ -0,0 +1,134 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class FireworkExplosion {
private Shape shape;
private List<Integer> colors;
private List<Integer> fadeColors;
private boolean hasTrail;
private boolean hasTwinkle;
public FireworkExplosion(
Shape shape, List<Integer> colors, List<Integer> fadeColors,
boolean hasTrail, boolean hasTwinkle
) {
this.shape = shape;
this.colors = colors;
this.fadeColors = fadeColors;
this.hasTrail = hasTrail;
this.hasTwinkle = hasTwinkle;
}
public static FireworkExplosion read(PacketWrapper<?> wrapper) {
Shape shape = wrapper.readEnum(Shape.values());
List<Integer> colors = wrapper.readList(PacketWrapper::readInt);
List<Integer> fadeColors = wrapper.readList(PacketWrapper::readInt);
boolean hasTrail = wrapper.readBoolean();
boolean hasTwinkle = wrapper.readBoolean();
return new FireworkExplosion(shape, colors, fadeColors, hasTrail, hasTwinkle);
}
public static void write(PacketWrapper<?> wrapper, FireworkExplosion explosion) {
wrapper.writeEnum(explosion.shape);
wrapper.writeList(explosion.colors, PacketWrapper::writeInt);
wrapper.writeList(explosion.fadeColors, PacketWrapper::writeInt);
wrapper.writeBoolean(explosion.hasTrail);
wrapper.writeBoolean(explosion.hasTwinkle);
}
public Shape getShape() {
return this.shape;
}
public void setShape(Shape shape) {
this.shape = shape;
}
public void addColor(int color) {
this.colors.add(color);
}
public List<Integer> getColors() {
return this.colors;
}
public void setColors(List<Integer> colors) {
this.colors = colors;
}
public void addFadeColor(int color) {
this.fadeColors.add(color);
}
public List<Integer> getFadeColors() {
return this.fadeColors;
}
public void setFadeColors(List<Integer> fadeColors) {
this.fadeColors = fadeColors;
}
public boolean isHasTrail() {
return this.hasTrail;
}
public void setHasTrail(boolean hasTrail) {
this.hasTrail = hasTrail;
}
public boolean isHasTwinkle() {
return this.hasTwinkle;
}
public void setHasTwinkle(boolean hasTwinkle) {
this.hasTwinkle = hasTwinkle;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof FireworkExplosion)) return false;
FireworkExplosion that = (FireworkExplosion) obj;
if (this.hasTrail != that.hasTrail) return false;
if (this.hasTwinkle != that.hasTwinkle) return false;
if (this.shape != that.shape) return false;
if (!this.colors.equals(that.colors)) return false;
return this.fadeColors.equals(that.fadeColors);
}
@Override
public int hashCode() {
return Objects.hash(this.shape, this.colors, this.fadeColors, this.hasTrail, this.hasTwinkle);
}
public enum Shape {
SMALL_BALL,
LARGE_BALL,
STAR,
CREEPER,
BURST,
}
}
@@ -0,0 +1,203 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public class FoodProperties {
private int nutrition;
private float saturation;
private boolean canAlwaysEat;
private float eatSeconds;
private List<PossibleEffect> effects;
private @Nullable ItemStack usingConvertsTo;
public FoodProperties(
int nutrition, float saturation, boolean canAlwaysEat,
float eatSeconds, List<PossibleEffect> effects
) {
this(nutrition, saturation, canAlwaysEat, eatSeconds, effects, null);
}
public FoodProperties(
int nutrition, float saturation, boolean canAlwaysEat, float eatSeconds,
List<PossibleEffect> effects, @Nullable ItemStack usingConvertsTo
) {
this.nutrition = nutrition;
this.saturation = saturation;
this.canAlwaysEat = canAlwaysEat;
this.eatSeconds = eatSeconds;
this.effects = effects;
this.usingConvertsTo = usingConvertsTo;
}
public static FoodProperties read(PacketWrapper<?> wrapper) {
int nutrition = wrapper.readVarInt();
float saturation = wrapper.readFloat();
boolean canAlwaysEat = wrapper.readBoolean();
float eatSeconds = wrapper.readFloat();
List<PossibleEffect> effects = wrapper.readList(PossibleEffect::read);
ItemStack usingConvertsTo = wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)
? wrapper.readOptional(PacketWrapper::readItemStack) : null;
return new FoodProperties(nutrition, saturation, canAlwaysEat, eatSeconds, effects, usingConvertsTo);
}
public static void write(PacketWrapper<?> wrapper, FoodProperties props) {
wrapper.writeVarInt(props.nutrition);
wrapper.writeFloat(props.saturation);
wrapper.writeBoolean(props.canAlwaysEat);
wrapper.writeFloat(props.eatSeconds);
wrapper.writeList(props.effects, PossibleEffect::write);
if (wrapper.getServerVersion().isNewerThanOrEquals(ServerVersion.V_1_21)) {
wrapper.writeOptional(props.usingConvertsTo, PacketWrapper::writeItemStack);
}
}
public int getNutrition() {
return this.nutrition;
}
public void setNutrition(int nutrition) {
this.nutrition = nutrition;
}
public float getSaturation() {
return this.saturation;
}
public void setSaturation(float saturation) {
this.saturation = saturation;
}
public boolean isCanAlwaysEat() {
return this.canAlwaysEat;
}
public void setCanAlwaysEat(boolean canAlwaysEat) {
this.canAlwaysEat = canAlwaysEat;
}
public float getEatSeconds() {
return this.eatSeconds;
}
public void setEatSeconds(float eatSeconds) {
this.eatSeconds = eatSeconds;
}
public void addEffect(PossibleEffect effect) {
this.effects.add(effect);
}
public List<PossibleEffect> getEffects() {
return this.effects;
}
public void setEffects(List<PossibleEffect> effects) {
this.effects = effects;
}
public @Nullable ItemStack getUsingConvertsTo() {
return this.usingConvertsTo;
}
public void setUsingConvertsTo(@Nullable ItemStack usingConvertsTo) {
this.usingConvertsTo = usingConvertsTo;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof FoodProperties)) return false;
FoodProperties that = (FoodProperties) obj;
if (this.nutrition != that.nutrition) return false;
if (Float.compare(that.saturation, this.saturation) != 0) return false;
if (this.canAlwaysEat != that.canAlwaysEat) return false;
if (Float.compare(that.eatSeconds, this.eatSeconds) != 0) return false;
if (!this.effects.equals(that.effects)) return false;
return Objects.equals(this.usingConvertsTo, that.usingConvertsTo);
}
@Override
public int hashCode() {
return Objects.hash(this.nutrition, this.saturation, this.canAlwaysEat, this.eatSeconds, this.effects, this.usingConvertsTo);
}
public static class PossibleEffect {
private PotionEffect effect;
private float probability;
public PossibleEffect(PotionEffect effect, float probability) {
this.effect = effect;
this.probability = probability;
}
public static PossibleEffect read(PacketWrapper<?> wrapper) {
PotionEffect effect = PotionEffect.read(wrapper);
float probability = wrapper.readFloat();
return new PossibleEffect(effect, probability);
}
public static void write(PacketWrapper<?> wrapper, PossibleEffect effect) {
PotionEffect.write(wrapper, effect.effect);
wrapper.writeFloat(effect.probability);
}
public PotionEffect getEffect() {
return this.effect;
}
public void setEffect(PotionEffect effect) {
this.effect = effect;
}
public float getProbability() {
return this.probability;
}
public void setProbability(float probability) {
this.probability = probability;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof PossibleEffect)) return false;
PossibleEffect that = (PossibleEffect) obj;
if (Float.compare(that.probability, this.probability) != 0) return false;
return this.effect.equals(that.effect);
}
@Override
public int hashCode() {
return Objects.hash(this.effect, this.probability);
}
}
}
@@ -0,0 +1,329 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
// why do I have to implement this mess, I just want to deserialize items
public class ItemAdventurePredicate {
private List<BlockPredicate> predicates;
private boolean showInTooltip;
public ItemAdventurePredicate(List<BlockPredicate> predicates, boolean showInTooltip) {
this.predicates = predicates;
this.showInTooltip = showInTooltip;
}
public static ItemAdventurePredicate read(PacketWrapper<?> wrapper) {
List<BlockPredicate> predicates = wrapper.readList(BlockPredicate::read);
boolean showInTooltip = wrapper.readBoolean();
return new ItemAdventurePredicate(predicates, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemAdventurePredicate predicate) {
wrapper.writeList(predicate.predicates, BlockPredicate::write);
wrapper.writeBoolean(predicate.showInTooltip);
}
public void addPredicate(BlockPredicate predicate) {
this.predicates.add(predicate);
}
public List<BlockPredicate> getPredicates() {
return this.predicates;
}
public void setPredicates(List<BlockPredicate> predicates) {
this.predicates = predicates;
}
public boolean isShowInTooltip() {
return this.showInTooltip;
}
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemAdventurePredicate)) return false;
ItemAdventurePredicate that = (ItemAdventurePredicate) obj;
if (this.showInTooltip != that.showInTooltip) return false;
return this.predicates.equals(that.predicates);
}
@Override
public int hashCode() {
return Objects.hash(this.predicates, this.showInTooltip);
}
public static class BlockPredicate {
private @Nullable MappedEntitySet<StateType.Mapped> blocks;
private @Nullable List<PropertyMatcher> properties;
private @Nullable NBTCompound nbt;
public BlockPredicate(
@Nullable MappedEntitySet<StateType.Mapped> blocks,
@Nullable List<PropertyMatcher> properties,
@Nullable NBTCompound nbt
) {
this.blocks = blocks;
this.properties = properties;
this.nbt = nbt;
}
public static BlockPredicate read(PacketWrapper<?> wrapper) {
MappedEntitySet<StateType.Mapped> blocks = wrapper.readOptional(
ew -> MappedEntitySet.read(ew, StateTypes::getMappedById));
List<PropertyMatcher> properties = wrapper.readList(PropertyMatcher::read);
NBTCompound nbt = wrapper.readNBT();
return new BlockPredicate(blocks, properties, nbt);
}
public static void write(PacketWrapper<?> wrapper, BlockPredicate predicate) {
wrapper.writeOptional(predicate.blocks, MappedEntitySet::write);
wrapper.writeOptional(predicate.properties,
(ew, val) -> ew.writeList(val, PropertyMatcher::write));
wrapper.writeOptional(predicate.nbt, PacketWrapper::writeNBT);
}
public @Nullable MappedEntitySet<StateType.Mapped> getBlocks() {
return this.blocks;
}
public void setBlocks(@Nullable MappedEntitySet<StateType.Mapped> blocks) {
this.blocks = blocks;
}
public void addProperty(PropertyMatcher propertyMatcher) {
if (this.properties == null) {
this.properties = new ArrayList<>(4);
}
this.properties.add(propertyMatcher);
}
public @Nullable List<PropertyMatcher> getProperties() {
return this.properties;
}
public void setProperties(@Nullable List<PropertyMatcher> properties) {
this.properties = properties;
}
public @Nullable NBTCompound getNbt() {
return this.nbt;
}
public void setNbt(@Nullable NBTCompound nbt) {
this.nbt = nbt;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof BlockPredicate)) return false;
BlockPredicate that = (BlockPredicate) obj;
if (!Objects.equals(this.blocks, that.blocks)) return false;
if (!Objects.equals(this.properties, that.properties)) return false;
return Objects.equals(this.nbt, that.nbt);
}
@Override
public int hashCode() {
return Objects.hash(this.blocks, this.properties, this.nbt);
}
}
public static class PropertyMatcher {
private String name;
private ValueMatcher matcher;
public PropertyMatcher(String name, ValueMatcher matcher) {
this.name = name;
this.matcher = matcher;
}
public static PropertyMatcher read(PacketWrapper<?> wrapper) {
String name = wrapper.readString();
ValueMatcher matcher = ValueMatcher.read(wrapper);
return new PropertyMatcher(name, matcher);
}
public static void write(PacketWrapper<?> wrapper, PropertyMatcher matcher) {
wrapper.writeString(matcher.name);
ValueMatcher.write(wrapper, matcher.matcher);
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public ValueMatcher getMatcher() {
return this.matcher;
}
public void setMatcher(ValueMatcher matcher) {
this.matcher = matcher;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof PropertyMatcher)) return false;
PropertyMatcher that = (PropertyMatcher) obj;
if (!this.name.equals(that.name)) return false;
return this.matcher.equals(that.matcher);
}
@Override
public int hashCode() {
return Objects.hash(this.name, this.matcher);
}
}
public interface ValueMatcher {
static ValueMatcher read(PacketWrapper<?> wrapper) {
if (wrapper.readBoolean()) {
return ExactValueMatcher.read(wrapper);
}
return RangedValueMatcher.read(wrapper);
}
static void write(PacketWrapper<?> wrapper, ValueMatcher matcher) {
if (matcher instanceof ExactValueMatcher) {
wrapper.writeBoolean(true);
ExactValueMatcher.write(wrapper, (ExactValueMatcher) matcher);
} else if (matcher instanceof RangedValueMatcher) {
wrapper.writeBoolean(false);
RangedValueMatcher.write(wrapper, (RangedValueMatcher) matcher);
} else {
throw new IllegalArgumentException("Illegal matcher implementation: " + matcher);
}
}
}
public static class ExactValueMatcher implements ValueMatcher {
private String value;
public ExactValueMatcher(String value) {
this.value = value;
}
public static ExactValueMatcher read(PacketWrapper<?> wrapper) {
return new ExactValueMatcher(wrapper.readString());
}
public static void write(PacketWrapper<?> wrapper, ExactValueMatcher matcher) {
wrapper.writeString(matcher.value);
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ExactValueMatcher)) return false;
ExactValueMatcher that = (ExactValueMatcher) obj;
return this.value.equals(that.value);
}
@Override
public int hashCode() {
return Objects.hashCode(this.value);
}
}
public static class RangedValueMatcher implements ValueMatcher {
private @Nullable String minValue;
private @Nullable String maxValue;
public RangedValueMatcher(@Nullable String minValue, @Nullable String maxValue) {
this.minValue = minValue;
this.maxValue = maxValue;
}
public static RangedValueMatcher read(PacketWrapper<?> wrapper) {
String minValue = wrapper.readOptional(PacketWrapper::readString);
String maxValue = wrapper.readOptional(PacketWrapper::readString);
return new RangedValueMatcher(minValue, maxValue);
}
public static void write(PacketWrapper<?> wrapper, RangedValueMatcher matcher) {
wrapper.writeOptional(matcher.minValue, PacketWrapper::writeString);
wrapper.writeOptional(matcher.maxValue, PacketWrapper::writeString);
}
public @Nullable String getMinValue() {
return this.minValue;
}
public void setMinValue(@Nullable String minValue) {
this.minValue = minValue;
}
public @Nullable String getMaxValue() {
return this.maxValue;
}
public void setMaxValue(@Nullable String maxValue) {
this.maxValue = maxValue;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof RangedValueMatcher)) return false;
RangedValueMatcher that = (RangedValueMatcher) obj;
if (!Objects.equals(this.minValue, that.minValue)) return false;
return Objects.equals(this.maxValue, that.maxValue);
}
@Override
public int hashCode() {
return Objects.hash(this.minValue, this.maxValue);
}
}
}
@@ -0,0 +1,264 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.attribute.Attribute;
import com.github.retrooper.packetevents.protocol.attribute.AttributeOperation;
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
public class ItemAttributeModifiers {
public static final ItemAttributeModifiers EMPTY = new ItemAttributeModifiers(
Collections.emptyList(), true) {
@Override
public void setShowInTooltip(boolean showInTooltip) {
throw new UnsupportedOperationException();
}
};
private List<ModifierEntry> modifiers;
private boolean showInTooltip;
public ItemAttributeModifiers(List<ModifierEntry> modifiers, boolean showInTooltip) {
this.modifiers = modifiers;
this.showInTooltip = showInTooltip;
}
public static ItemAttributeModifiers read(PacketWrapper<?> wrapper) {
List<ModifierEntry> modifiers = wrapper.readList(ModifierEntry::read);
boolean showInTooltip = wrapper.readBoolean();
return new ItemAttributeModifiers(modifiers, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemAttributeModifiers modifiers) {
wrapper.writeList(modifiers.modifiers, ModifierEntry::write);
wrapper.writeBoolean(modifiers.showInTooltip);
}
public void addModifier(ModifierEntry modifier) {
this.modifiers.add(modifier);
}
public List<ModifierEntry> getModifiers() {
return this.modifiers;
}
public void setModifiers(List<ModifierEntry> modifiers) {
this.modifiers = modifiers;
}
public boolean isShowInTooltip() {
return this.showInTooltip;
}
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemAttributeModifiers)) return false;
ItemAttributeModifiers that = (ItemAttributeModifiers) obj;
if (this.showInTooltip != that.showInTooltip) return false;
return this.modifiers.equals(that.modifiers);
}
@Override
public int hashCode() {
return Objects.hash(this.modifiers, this.showInTooltip);
}
@Override
public String toString() {
return "ItemAttributeModifiers{modifiers=" + this.modifiers + ", showInTooltip=" + this.showInTooltip + '}';
}
public static class ModifierEntry {
private Attribute attribute;
private Modifier modifier;
private EquipmentSlotGroup slotGroup;
public ModifierEntry(Attribute attribute, Modifier modifier, EquipmentSlotGroup slotGroup) {
this.attribute = attribute;
this.modifier = modifier;
this.slotGroup = slotGroup;
}
public static ModifierEntry read(PacketWrapper<?> wrapper) {
Attribute attribute = wrapper.readMappedEntity(Attributes::getById);
Modifier modifier = Modifier.read(wrapper);
EquipmentSlotGroup slot = wrapper.readEnum(EquipmentSlotGroup.values());
return new ModifierEntry(attribute, modifier, slot);
}
public static void write(PacketWrapper<?> wrapper, ModifierEntry entry) {
wrapper.writeMappedEntity(entry.attribute);
Modifier.write(wrapper, entry.modifier);
wrapper.writeEnum(entry.slotGroup);
}
public Attribute getAttribute() {
return this.attribute;
}
public void setAttribute(Attribute attribute) {
this.attribute = attribute;
}
public Modifier getModifier() {
return this.modifier;
}
public void setModifier(Modifier modifier) {
this.modifier = modifier;
}
public EquipmentSlotGroup getSlotGroup() {
return this.slotGroup;
}
public void setSlotGroup(EquipmentSlotGroup slotGroup) {
this.slotGroup = slotGroup;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ModifierEntry)) return false;
ModifierEntry that = (ModifierEntry) obj;
if (!this.attribute.equals(that.attribute)) return false;
if (!this.modifier.equals(that.modifier)) return false;
return this.slotGroup == that.slotGroup;
}
@Override
public int hashCode() {
return Objects.hash(this.attribute, this.modifier, this.slotGroup);
}
@Override
public String toString() {
return "ModifierEntry{attribute=" + this.attribute + ", modifier=" + this.modifier + ", slotGroup=" + this.slotGroup + '}';
}
}
public static class Modifier {
private UUID id;
private String name;
private double value;
private AttributeOperation operation;
public Modifier(UUID id, String name, double value, AttributeOperation operation) {
this.id = id;
this.name = name;
this.value = value;
this.operation = operation;
}
public static Modifier read(PacketWrapper<?> wrapper) {
UUID id = wrapper.readUUID();
String name = wrapper.readString();
double value = wrapper.readDouble();
AttributeOperation operation = wrapper.readEnum(AttributeOperation.values());
return new Modifier(id, name, value, operation);
}
public static void write(PacketWrapper<?> wrapper, Modifier modifier) {
wrapper.writeUUID(modifier.id);
wrapper.writeString(modifier.name);
wrapper.writeDouble(modifier.value);
wrapper.writeEnum(modifier.operation);
}
public UUID getId() {
return this.id;
}
public void setId(UUID id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public double getValue() {
return this.value;
}
public void setValue(double value) {
this.value = value;
}
public AttributeOperation getOperation() {
return this.operation;
}
public void setOperation(AttributeOperation operation) {
this.operation = operation;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Modifier)) return false;
Modifier modifier = (Modifier) obj;
if (Double.compare(modifier.value, this.value) != 0) return false;
if (!this.id.equals(modifier.id)) return false;
if (!this.name.equals(modifier.name)) return false;
return this.operation == modifier.operation;
}
@Override
public int hashCode() {
return Objects.hash(this.id, this.name, this.value, this.operation);
}
@Override
public String toString() {
return "Modifier{id=" + this.id + ", name='" + this.name + '\'' + ", value=" + this.value + ", operation=" + this.operation + '}';
}
}
public enum EquipmentSlotGroup {
ANY,
MAINHAND,
OFFHAND,
HAND,
FEET,
LEGS,
CHEST,
HEAD,
ARMOR,
BODY,
}
}
@@ -0,0 +1,133 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ItemBees {
private List<BeeEntry> bees;
public ItemBees(List<BeeEntry> bees) {
this.bees = bees;
}
public static ItemBees read(PacketWrapper<?> wrapper) {
List<BeeEntry> bees = wrapper.readList(BeeEntry::read);
return new ItemBees(bees);
}
public static void write(PacketWrapper<?> wrapper, ItemBees bees) {
wrapper.writeList(bees.bees, BeeEntry::write);
}
public void addBee(BeeEntry bee) {
this.bees.add(bee);
}
public List<BeeEntry> getBees() {
return this.bees;
}
public void setBees(List<BeeEntry> bees) {
this.bees = bees;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemBees)) return false;
ItemBees itemBees = (ItemBees) obj;
return this.bees.equals(itemBees.bees);
}
@Override
public int hashCode() {
return Objects.hashCode(this.bees);
}
public static class BeeEntry {
private NBTCompound entityData;
private int ticksInHive;
private int minTicksInHive;
public BeeEntry(NBTCompound entityData, int ticksInHive, int minTicksInHive) {
this.entityData = entityData;
this.ticksInHive = ticksInHive;
this.minTicksInHive = minTicksInHive;
}
public static BeeEntry read(PacketWrapper<?> wrapper) {
NBTCompound entityData = wrapper.readNBT();
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);
wrapper.writeVarInt(bee.ticksInHive);
wrapper.writeVarInt(bee.minTicksInHive);
}
public NBTCompound getEntityData() {
return this.entityData;
}
public void setEntityData(NBTCompound entityData) {
this.entityData = entityData;
}
public int getTicksInHive() {
return this.ticksInHive;
}
public void setTicksInHive(int ticksInHive) {
this.ticksInHive = ticksInHive;
}
public int getMinTicksInHive() {
return this.minTicksInHive;
}
public void setMinTicksInHive(int minTicksInHive) {
this.minTicksInHive = minTicksInHive;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof BeeEntry)) return false;
BeeEntry beeEntry = (BeeEntry) obj;
if (this.ticksInHive != beeEntry.ticksInHive) return false;
if (this.minTicksInHive != beeEntry.minTicksInHive) return false;
return this.entityData.equals(beeEntry.entityData);
}
@Override
public int hashCode() {
return Objects.hash(this.entityData, this.ticksInHive, this.minTicksInHive);
}
}
}
@@ -0,0 +1,100 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.world.states.type.StateValue;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Objects;
public class ItemBlockStateProperties {
private Map<String, String> properties;
public ItemBlockStateProperties(Map<String, String> properties) {
this.properties = properties;
}
public static ItemBlockStateProperties read(PacketWrapper<?> wrapper) {
Map<String, String> properties = wrapper.readMap(
PacketWrapper::readString, PacketWrapper::readString);
return new ItemBlockStateProperties(properties);
}
public static void write(PacketWrapper<?> wrapper, ItemBlockStateProperties props) {
wrapper.writeMap(props.properties,
PacketWrapper::writeString,
PacketWrapper::writeString);
}
public @Nullable Object getProperty(StateValue stateValue) {
String value = this.getProperty(stateValue.getName());
if (value != null) {
return stateValue.getParser().apply(value);
}
return null;
}
public @Nullable String getProperty(String key) {
return this.properties.get(key);
}
public void setProperty(StateValue stateValue, @Nullable Object value) {
this.setProperty(stateValue.getName(), value == null ? null : value.toString());
}
public void setProperty(String key, @Nullable String value) {
if (value == null) {
this.properties.remove(key);
} else {
this.properties.put(key, value);
}
}
public void unsetProperty(StateValue stateValue) {
this.unsetProperty(stateValue.getName());
}
public void unsetProperty(String key) {
this.setProperty(key, null);
}
public Map<String, String> getProperties() {
return this.properties;
}
public void setProperties(Map<String, String> properties) {
this.properties = properties;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemBlockStateProperties)) return false;
ItemBlockStateProperties that = (ItemBlockStateProperties) obj;
return this.properties.equals(that.properties);
}
@Override
public int hashCode() {
return Objects.hashCode(this.properties);
}
}
@@ -0,0 +1,68 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ItemContainerContents {
private List<ItemStack> items;
public ItemContainerContents(List<ItemStack> items) {
this.items = items;
}
public static ItemContainerContents read(PacketWrapper<?> wrapper) {
List<ItemStack> items = wrapper.readList(PacketWrapper::readItemStack);
return new ItemContainerContents(items);
}
public static void write(PacketWrapper<?> wrapper, ItemContainerContents contents) {
wrapper.writeList(contents.items, PacketWrapper::writeItemStack);
}
public void addItem(ItemStack itemStack) {
this.items.add(itemStack);
}
public List<ItemStack> getItems() {
return this.items;
}
public void setItems(List<ItemStack> items) {
this.items = items;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemContainerContents)) return false;
ItemContainerContents that = (ItemContainerContents) obj;
return this.items.equals(that.items);
}
@Override
public int hashCode() {
return Objects.hashCode(this.items);
}
}
@@ -0,0 +1,86 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTLong;
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemContainerLoot {
private ResourceLocation lootTable;
private long seed;
public ItemContainerLoot(ResourceLocation lootTable, long seed) {
this.lootTable = lootTable;
this.seed = seed;
}
public static ItemContainerLoot read(PacketWrapper<?> wrapper) {
NBTCompound compound = wrapper.readNBT();
ResourceLocation lootTable = new ResourceLocation(compound.getStringTagValueOrThrow("loot_table"));
NBTNumber seedTag = compound.getNumberTagOrNull("seed");
long seed = seedTag == null ? 0L : seedTag.getAsLong();
return new ItemContainerLoot(lootTable, seed);
}
public static void write(PacketWrapper<?> wrapper, ItemContainerLoot loot) {
NBTCompound compound = new NBTCompound();
compound.setTag("loot_table", new NBTString(loot.lootTable.toString()));
if (loot.seed != 0L) {
compound.setTag("seed", new NBTLong(loot.seed));
}
wrapper.writeNBT(compound);
}
public ResourceLocation getLootTable() {
return this.lootTable;
}
public void setLootTable(ResourceLocation lootTable) {
this.lootTable = lootTable;
}
public long getSeed() {
return this.seed;
}
public void setSeed(long seed) {
this.seed = seed;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemContainerLoot)) return false;
ItemContainerLoot that = (ItemContainerLoot) obj;
if (this.seed != that.seed) return false;
return this.lootTable.equals(that.lootTable);
}
@Override
public int hashCode() {
return Objects.hash(this.lootTable, this.seed);
}
}
@@ -0,0 +1,75 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemDyeColor {
private int rgb;
private boolean showInTooltip;
public ItemDyeColor(int rgb, boolean showInTooltip) {
this.rgb = rgb;
this.showInTooltip = showInTooltip;
}
public static ItemDyeColor read(PacketWrapper<?> wrapper) {
int rgb = wrapper.readInt();
boolean showInTooltip = wrapper.readBoolean();
return new ItemDyeColor(rgb, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemDyeColor color) {
wrapper.writeInt(color.rgb);
wrapper.writeBoolean(color.showInTooltip);
}
public int getRgb() {
return this.rgb;
}
public void setRgb(int rgb) {
this.rgb = rgb;
}
public boolean isShowInTooltip() {
return this.showInTooltip;
}
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemDyeColor)) return false;
ItemDyeColor that = (ItemDyeColor) obj;
if (this.rgb != that.rgb) return false;
return this.showInTooltip == that.showInTooltip;
}
@Override
public int hashCode() {
return Objects.hash(this.rgb, this.showInTooltip);
}
}
@@ -0,0 +1,127 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentType;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
public class ItemEnchantments implements Iterable<Map.Entry<EnchantmentType, Integer>> {
public static final ItemEnchantments EMPTY = new ItemEnchantments(
Collections.emptyMap(), true) {
@Override
public void setShowInTooltip(boolean showInTooltip) {
throw new UnsupportedOperationException();
}
};
private Map<EnchantmentType, Integer> enchantments;
private boolean showInTooltip;
public ItemEnchantments(Map<EnchantmentType, Integer> enchantments, boolean showInTooltip) {
this.enchantments = Collections.unmodifiableMap(enchantments);
this.showInTooltip = showInTooltip;
}
public static ItemEnchantments read(PacketWrapper<?> wrapper) {
ClientVersion version = wrapper.getServerVersion().toClientVersion();
Map<EnchantmentType, Integer> enchantments = wrapper.readMap(
ew -> EnchantmentTypes.getById(version, ew.readVarInt()),
PacketWrapper::readVarInt
);
boolean showInTooltip = wrapper.readBoolean();
return new ItemEnchantments(enchantments, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemEnchantments enchantments) {
ClientVersion version = wrapper.getServerVersion().toClientVersion();
wrapper.writeMap(enchantments.getEnchantments(),
(ew, enchantment) -> ew.writeVarInt(enchantment.getId(version)),
PacketWrapper::writeVarInt
);
wrapper.writeBoolean(enchantments.isShowInTooltip());
}
public int getEnchantmentLevel(EnchantmentType enchantment) {
return this.enchantments.getOrDefault(enchantment, 0);
}
public void setEnchantmentLevel(EnchantmentType enchantment, int level) {
if (level == 0) {
this.enchantments.remove(enchantment);
} else {
this.enchantments.put(enchantment, level);
}
}
public boolean isEmpty() {
return this.getEnchantmentCount() < 1;
}
public int getEnchantmentCount() {
return this.enchantments.size();
}
public Map<EnchantmentType, Integer> getEnchantments() {
return this.enchantments;
}
public void setEnchantments(Map<EnchantmentType, Integer> enchantments) {
this.enchantments = enchantments;
}
public boolean isShowInTooltip() {
return this.showInTooltip;
}
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public Iterator<Map.Entry<EnchantmentType, Integer>> iterator() {
return this.enchantments.entrySet().iterator();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemEnchantments)) return false;
ItemEnchantments that = (ItemEnchantments) obj;
if (this.showInTooltip != that.showInTooltip) return false;
return this.enchantments.equals(that.enchantments);
}
@Override
public int hashCode() {
return Objects.hash(this.enchantments, this.showInTooltip);
}
@Override
public String toString() {
return "ItemEnchantments{enchantments=" + this.enchantments + ", showInTooltip=" + this.showInTooltip + '}';
}
}
@@ -0,0 +1,80 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ItemFireworks {
private int flightDuration;
private List<FireworkExplosion> explosions;
public ItemFireworks(int flightDuration, List<FireworkExplosion> explosions) {
this.flightDuration = flightDuration;
this.explosions = explosions;
}
public static ItemFireworks read(PacketWrapper<?> wrapper) {
int flightDuration = wrapper.readVarInt();
List<FireworkExplosion> explosions = wrapper.readList(FireworkExplosion::read);
return new ItemFireworks(flightDuration, explosions);
}
public static void write(PacketWrapper<?> wrapper, ItemFireworks fireworks) {
wrapper.writeVarInt(fireworks.flightDuration);
wrapper.writeList(fireworks.explosions, FireworkExplosion::write);
}
public int getFlightDuration() {
return this.flightDuration;
}
public void setFlightDuration(int flightDuration) {
this.flightDuration = flightDuration;
}
public void addExplosion(FireworkExplosion explosion) {
this.explosions.add(explosion);
}
public List<FireworkExplosion> getExplosions() {
return this.explosions;
}
public void setExplosions(List<FireworkExplosion> explosions) {
this.explosions = explosions;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemFireworks)) return false;
ItemFireworks that = (ItemFireworks) obj;
if (this.flightDuration != that.flightDuration) return false;
return this.explosions.equals(that.explosions);
}
@Override
public int hashCode() {
return Objects.hash(this.flightDuration, this.explosions);
}
}
@@ -0,0 +1,115 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.jukebox.JukeboxSong;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class ItemJukeboxPlayable {
private @Nullable JukeboxSong song;
private @Nullable ResourceLocation songKey;
private boolean showInTooltip;
public ItemJukeboxPlayable(
@Nullable JukeboxSong song,
@Nullable ResourceLocation songKey,
boolean showInTooltip
) {
if ((song == null) == (songKey == null)) {
throw new IllegalStateException("Illegal state of both song and "
+ "song key combined: " + song + " / " + songKey);
}
this.song = song;
this.songKey = songKey;
this.showInTooltip = showInTooltip;
}
public static ItemJukeboxPlayable read(PacketWrapper<?> wrapper) {
JukeboxSong song;
ResourceLocation songKey;
if (wrapper.readBoolean()) {
song = JukeboxSong.read(wrapper);
songKey = null;
} else {
song = null;
songKey = wrapper.readIdentifier();
}
boolean showInTooltip = wrapper.readBoolean();
return new ItemJukeboxPlayable(song, songKey, showInTooltip);
}
public static void write(PacketWrapper<?> wrapper, ItemJukeboxPlayable jukeboxPlayable) {
if (jukeboxPlayable.song != null) {
wrapper.writeBoolean(true);
JukeboxSong.write(wrapper, jukeboxPlayable.song);
} else {
assert jukeboxPlayable.songKey != null;
wrapper.writeBoolean(false);
wrapper.writeIdentifier(jukeboxPlayable.songKey);
}
wrapper.writeBoolean(jukeboxPlayable.showInTooltip);
}
public @Nullable JukeboxSong getSong() {
return this.song;
}
public void setSong(JukeboxSong song) {
this.song = song;
this.songKey = null;
}
public @Nullable ResourceLocation getSongKey() {
return this.songKey;
}
public void setSongKey(ResourceLocation songKey) {
this.song = null;
this.songKey = songKey;
}
public boolean isShowInTooltip() {
return this.showInTooltip;
}
public void setShowInTooltip(boolean showInTooltip) {
this.showInTooltip = showInTooltip;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemJukeboxPlayable)) return false;
ItemJukeboxPlayable that = (ItemJukeboxPlayable) obj;
if (this.showInTooltip != that.showInTooltip) return false;
if (!Objects.equals(this.song, that.song)) return false;
return Objects.equals(this.songKey, that.songKey);
}
@Override
public int hashCode() {
return Objects.hash(this.song, this.songKey, this.showInTooltip);
}
}
@@ -0,0 +1,63 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.Objects;
public class ItemLock {
private String code;
public ItemLock(String code) {
this.code = code;
}
public static ItemLock read(PacketWrapper<?> wrapper) {
NBTString codeTag = (NBTString) wrapper.readNBTRaw();
return new ItemLock(codeTag.getValue());
}
public static void write(PacketWrapper<?> wrapper, ItemLock lock) {
wrapper.writeNBTRaw(new NBTString(lock.code));
}
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemLock)) return false;
ItemLock itemLock = (ItemLock) obj;
return this.code.equals(itemLock.code);
}
@Override
public int hashCode() {
return Objects.hashCode(this.code);
}
}
@@ -0,0 +1,76 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class ItemLore {
public static final ItemLore EMPTY = new ItemLore(Collections.emptyList());
private List<Component> lines;
public ItemLore(List<Component> lines) {
this.lines = lines;
}
public static ItemLore read(PacketWrapper<?> wrapper) {
List<Component> lines = wrapper.readList(PacketWrapper::readComponent);
return new ItemLore(lines);
}
public static void write(PacketWrapper<?> wrapper, ItemLore lore) {
wrapper.writeList(lore.lines, PacketWrapper::writeComponent);
}
public void addLine(Component line) {
this.lines.add(line);
}
public List<Component> getLines() {
return this.lines;
}
public void setLines(List<Component> lines) {
this.lines = lines;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemLore)) return false;
ItemLore itemLore = (ItemLore) obj;
return this.lines.equals(itemLore.lines);
}
@Override
public int hashCode() {
return Objects.hash(this.lines);
}
@Override
public String toString() {
return "ItemLore{lines=" + this.lines + '}';
}
}
@@ -0,0 +1,176 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.mapdecoration.MapDecorationType;
import com.github.retrooper.packetevents.protocol.item.mapdecoration.MapDecorationTypes;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
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.NBTString;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class ItemMapDecorations {
private Map<String, Decoration> decorations;
public ItemMapDecorations(Map<String, Decoration> decorations) {
this.decorations = decorations;
}
public static ItemMapDecorations read(PacketWrapper<?> wrapper) {
NBTCompound compound = wrapper.readNBT();
Map<String, Decoration> decorations = new HashMap<>(compound.size());
for (Map.Entry<String, NBT> tag : compound.getTags().entrySet()) {
Decoration decoration = Decoration.readCompound((NBTCompound) tag.getValue());
decorations.put(tag.getKey(), decoration);
}
return new ItemMapDecorations(decorations);
}
public static void write(PacketWrapper<?> wrapper, ItemMapDecorations decorations) {
NBTCompound compound = new NBTCompound();
for (Map.Entry<String, Decoration> decoration : decorations.decorations.entrySet()) {
NBTCompound entry = new NBTCompound();
Decoration.writeCompound(entry, decoration.getValue());
compound.setTag(decoration.getKey(), entry);
}
wrapper.writeNBT(compound);
}
public @Nullable Decoration getDecoration(String key) {
return this.decorations.get(key);
}
public void setDecoration(String key, @Nullable Decoration decoration) {
if (decoration != null) {
this.decorations.put(key, decoration);
} else {
this.decorations.remove(key);
}
}
public Map<String, Decoration> getDecorations() {
return this.decorations;
}
public void setDecorations(Map<String, Decoration> decorations) {
this.decorations = decorations;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemMapDecorations)) return false;
ItemMapDecorations that = (ItemMapDecorations) obj;
return this.decorations.equals(that.decorations);
}
@Override
public int hashCode() {
return Objects.hashCode(this.decorations);
}
public static final class Decoration {
private MapDecorationType type;
private double x;
private double z;
private float rotation;
public Decoration(MapDecorationType type, double x, double z, float rotation) {
this.type = type;
this.x = x;
this.z = z;
this.rotation = rotation;
}
@ApiStatus.Internal
public static Decoration readCompound(NBTCompound compound) {
MapDecorationType type = MapDecorationTypes.getByName(compound.getStringTagValueOrThrow("type"));
double x = compound.getNumberTagOrThrow("x").getAsDouble();
double z = compound.getNumberTagOrThrow("z").getAsDouble();
float rotation = compound.getNumberTagOrThrow("rotation").getAsFloat();
return new Decoration(type, x, z, rotation);
}
@ApiStatus.Internal
public static void writeCompound(NBTCompound compound, Decoration decoration) {
compound.setTag("type", new NBTString(decoration.type.getName().toString()));
compound.setTag("x", new NBTDouble(decoration.x));
compound.setTag("z", new NBTDouble(decoration.z));
compound.setTag("rotation", new NBTFloat(decoration.rotation));
}
public MapDecorationType getType() {
return this.type;
}
public void setType(MapDecorationType type) {
this.type = type;
}
public double getX() {
return this.x;
}
public void setX(double x) {
this.x = x;
}
public double getZ() {
return this.z;
}
public void setZ(double z) {
this.z = z;
}
public float getRotation() {
return this.rotation;
}
public void setRotation(float rotation) {
this.rotation = rotation;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Decoration)) return false;
Decoration that = (Decoration) obj;
if (Double.compare(that.x, this.x) != 0) return false;
if (Double.compare(that.z, this.z) != 0) return false;
if (Float.compare(that.rotation, this.rotation) != 0) return false;
return this.type.equals(that.type);
}
@Override
public int hashCode() {
return Objects.hash(this.type, this.x, this.z, this.rotation);
}
}
}
@@ -0,0 +1,24 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
public enum ItemMapPostProcessingState {
LOCKED,
SCALED,
}
@@ -0,0 +1,101 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.potion.Potion;
import com.github.retrooper.packetevents.protocol.potion.PotionEffect;
import com.github.retrooper.packetevents.protocol.potion.Potions;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public class ItemPotionContents {
private @Nullable Potion potion;
private @Nullable Integer customColor;
private List<PotionEffect> customEffects;
public ItemPotionContents(
@Nullable Potion potion,
@Nullable Integer customColor,
List<PotionEffect> customEffects
) {
this.potion = potion;
this.customColor = customColor;
this.customEffects = customEffects;
}
public static ItemPotionContents read(PacketWrapper<?> wrapper) {
Potion potionId = wrapper.readOptional(ew -> ew.readMappedEntity(Potions::getById));
Integer customColor = wrapper.readOptional(PacketWrapper::readInt);
List<PotionEffect> customEffects = wrapper.readList(PotionEffect::read);
return new ItemPotionContents(potionId, customColor, customEffects);
}
public static void write(PacketWrapper<?> wrapper, ItemPotionContents contents) {
wrapper.writeOptional(contents.potion, PacketWrapper::writeMappedEntity);
wrapper.writeOptional(contents.customColor, PacketWrapper::writeInt);
wrapper.writeList(contents.customEffects, PotionEffect::write);
}
public @Nullable Potion getPotion() {
return this.potion;
}
public void setPotion(@Nullable Potion potion) {
this.potion = potion;
}
public @Nullable Integer getCustomColor() {
return this.customColor;
}
public void setCustomColor(@Nullable Integer customColor) {
this.customColor = customColor;
}
private void addCustomEffect(PotionEffect effect) {
this.customEffects.add(effect);
}
public List<PotionEffect> getCustomEffects() {
return this.customEffects;
}
public void setCustomEffects(List<PotionEffect> customEffects) {
this.customEffects = customEffects;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemPotionContents)) return false;
ItemPotionContents that = (ItemPotionContents) obj;
if (!Objects.equals(this.potion, that.potion)) return false;
if (!Objects.equals(this.customColor, that.customColor)) return false;
return this.customEffects.equals(that.customEffects);
}
@Override
public int hashCode() {
return Objects.hash(this.potion, this.customColor, this.customEffects);
}
}
@@ -0,0 +1,165 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
public class ItemProfile {
private @Nullable String name;
private @Nullable UUID id;
private List<Property> properties;
public ItemProfile(
@Nullable String name,
@Nullable UUID id,
List<Property> properties
) {
this.name = name;
this.id = id;
this.properties = properties;
}
public static ItemProfile read(PacketWrapper<?> wrapper) {
String name = wrapper.readOptional(ew -> ew.readString(16));
UUID id = wrapper.readOptional(PacketWrapper::readUUID);
List<Property> properties = wrapper.readList(Property::read);
return new ItemProfile(name, id, properties);
}
public static void write(PacketWrapper<?> wrapper, ItemProfile profile) {
wrapper.writeOptional(profile.name, (ew, name) -> ew.writeString(name, 16));
wrapper.writeOptional(profile.id, PacketWrapper::writeUUID);
wrapper.writeList(profile.properties, Property::write);
}
public @Nullable String getName() {
return this.name;
}
public void setName(@Nullable String name) {
this.name = name;
}
public @Nullable UUID getId() {
return this.id;
}
public void setId(@Nullable UUID id) {
this.id = id;
}
public void addProperty(Property property) {
this.properties.add(property);
}
public List<Property> getProperties() {
return this.properties;
}
public void setProperties(List<Property> properties) {
this.properties = properties;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemProfile)) return false;
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);
}
@Override
public int hashCode() {
return Objects.hash(this.name, this.id, this.properties);
}
public static class Property {
private String name;
private String value;
private @Nullable String signature;
public Property(String name, String value, @Nullable String signature) {
this.name = name;
this.value = value;
this.signature = signature;
}
public static Property read(PacketWrapper<?> wrapper) {
String name = wrapper.readString(64);
String value = wrapper.readString(32767);
String signature = wrapper.readOptional(ew -> ew.readString(1024));
return new Property(name, value, signature);
}
public static void write(PacketWrapper<?> wrapper, Property property) {
wrapper.writeString(property.name, 64);
wrapper.writeString(property.value, 32767);
wrapper.writeOptional(property.signature,
(ew, signature) -> ew.writeString(signature, 1024));
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
public @Nullable String getSignature() {
return this.signature;
}
public void setSignature(@Nullable String signature) {
this.signature = signature;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Property)) return false;
Property property = (Property) obj;
if (!this.name.equals(property.name)) return false;
if (!this.value.equals(property.value)) return false;
return Objects.equals(this.signature, property.signature);
}
@Override
public int hashCode() {
return Objects.hash(this.name, this.value, this.signature);
}
}
}
@@ -0,0 +1,26 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
public enum ItemRarity {
COMMON,
UNCOMMON,
RARE,
EPIC,
}
@@ -0,0 +1,72 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class ItemRecipes {
private List<ResourceLocation> recipes;
public ItemRecipes(List<ResourceLocation> recipes) {
this.recipes = recipes;
}
public static ItemRecipes read(PacketWrapper<?> wrapper) {
List<ResourceLocation> recipes = wrapper.readList(PacketWrapper::readIdentifier);
return new ItemRecipes(recipes);
}
public static void write(PacketWrapper<?> wrapper, ItemRecipes recipes) {
wrapper.writeList(recipes.recipes, PacketWrapper::writeIdentifier);
}
public void addRecipe(ResourceLocation recipeKey) {
this.recipes.add(recipeKey);
}
public void removeRecipe(ResourceLocation recipeKey) {
this.recipes.remove(recipeKey);
}
public List<ResourceLocation> getRecipes() {
return this.recipes;
}
public void setRecipes(List<ResourceLocation> recipes) {
this.recipes = recipes;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemRecipes)) return false;
ItemRecipes that = (ItemRecipes) obj;
return this.recipes.equals(that.recipes);
}
@Override
public int hashCode() {
return Objects.hashCode(this.recipes);
}
}
@@ -0,0 +1,166 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public class ItemTool {
private List<Rule> rules;
private float defaultMiningSpeed;
private int damagePerBlock;
public ItemTool(List<Rule> rules, float defaultMiningSpeed, int damagePerBlock) {
this.rules = rules;
this.defaultMiningSpeed = defaultMiningSpeed;
this.damagePerBlock = damagePerBlock;
}
public static ItemTool read(PacketWrapper<?> wrapper) {
List<Rule> rules = wrapper.readList(Rule::read);
float defaultMiningSpeed = wrapper.readFloat();
int damagePerBlock = wrapper.readVarInt();
return new ItemTool(rules, defaultMiningSpeed, damagePerBlock);
}
public static void write(PacketWrapper<?> wrapper, ItemTool tool) {
wrapper.writeList(tool.rules, Rule::write);
wrapper.writeFloat(tool.defaultMiningSpeed);
wrapper.writeVarInt(tool.damagePerBlock);
}
public void addRule(Rule rule) {
this.rules.add(rule);
}
public List<Rule> getRules() {
return this.rules;
}
public void setRules(List<Rule> rules) {
this.rules = rules;
}
public float getDefaultMiningSpeed() {
return this.defaultMiningSpeed;
}
public void setDefaultMiningSpeed(float defaultMiningSpeed) {
this.defaultMiningSpeed = defaultMiningSpeed;
}
public int getDamagePerBlock() {
return this.damagePerBlock;
}
public void setDamagePerBlock(int damagePerBlock) {
this.damagePerBlock = damagePerBlock;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof ItemTool)) return false;
ItemTool itemTool = (ItemTool) obj;
if (Float.compare(itemTool.defaultMiningSpeed, this.defaultMiningSpeed) != 0) return false;
if (this.damagePerBlock != itemTool.damagePerBlock) return false;
return this.rules.equals(itemTool.rules);
}
@Override
public int hashCode() {
return Objects.hash(this.rules, this.defaultMiningSpeed, this.damagePerBlock);
}
public static class Rule {
private MappedEntitySet<StateType.Mapped> blocks;
private @Nullable Float speed;
private @Nullable Boolean correctForDrops;
public Rule(
MappedEntitySet<StateType.Mapped> blocks,
@Nullable Float speed,
@Nullable Boolean correctForDrops
) {
this.blocks = blocks;
this.speed = speed;
this.correctForDrops = correctForDrops;
}
public static Rule read(PacketWrapper<?> wrapper) {
MappedEntitySet<StateType.Mapped> blocks = MappedEntitySet.read(wrapper, StateTypes::getMappedById);
Float speed = wrapper.readOptional(PacketWrapper::readFloat);
Boolean correctForDrops = wrapper.readOptional(PacketWrapper::readBoolean);
return new Rule(blocks, speed, correctForDrops);
}
public static void write(PacketWrapper<?> wrapper, Rule rule) {
MappedEntitySet.write(wrapper, rule.blocks);
wrapper.writeOptional(rule.speed, PacketWrapper::writeFloat);
wrapper.writeOptional(rule.correctForDrops, PacketWrapper::writeBoolean);
}
public MappedEntitySet<StateType.Mapped> getBlocks() {
return this.blocks;
}
public void setBlocks(MappedEntitySet<StateType.Mapped> blocks) {
this.blocks = blocks;
}
public @Nullable Float getSpeed() {
return this.speed;
}
public void setSpeed(@Nullable Float speed) {
this.speed = speed;
}
public @Nullable Boolean getCorrectForDrops() {
return this.correctForDrops;
}
public void setCorrectForDrops(@Nullable Boolean correctForDrops) {
this.correctForDrops = correctForDrops;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Rule)) return false;
Rule rule = (Rule) obj;
if (!this.blocks.equals(rule.blocks)) return false;
if (!Objects.equals(this.speed, rule.speed)) return false;
return Objects.equals(this.correctForDrops, rule.correctForDrops);
}
@Override
public int hashCode() {
return Objects.hash(this.blocks, this.speed, this.correctForDrops);
}
}
}
@@ -0,0 +1,77 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public class LodestoneTracker {
private @Nullable WorldBlockPosition target;
private boolean tracked;
public LodestoneTracker(@Nullable WorldBlockPosition target, boolean tracked) {
this.target = target;
this.tracked = tracked;
}
public static LodestoneTracker read(PacketWrapper<?> wrapper) {
WorldBlockPosition target = wrapper.readOptional(PacketWrapper::readWorldBlockPosition);
boolean tracked = wrapper.readBoolean();
return new LodestoneTracker(target, tracked);
}
public static void write(PacketWrapper<?> wrapper, LodestoneTracker tracker) {
wrapper.writeOptional(tracker.target, PacketWrapper::writeWorldBlockPosition);
wrapper.writeBoolean(tracker.tracked);
}
public @Nullable WorldBlockPosition getTarget() {
return this.target;
}
public void setTarget(@Nullable WorldBlockPosition target) {
this.target = target;
}
public boolean isTracked() {
return this.tracked;
}
public void setTracked(boolean tracked) {
this.tracked = tracked;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof LodestoneTracker)) return false;
LodestoneTracker that = (LodestoneTracker) obj;
if (this.tracked != that.tracked) return false;
return Objects.equals(this.target, that.target);
}
@Override
public int hashCode() {
return Objects.hash(this.target, this.tracked);
}
}
@@ -0,0 +1,136 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Queue;
public class PotDecorations {
private @Nullable ItemType back;
private @Nullable ItemType left;
private @Nullable ItemType right;
private @Nullable ItemType front;
private PotDecorations(Queue<Optional<ItemType>> items) {
this(
items.isEmpty() ? null : items.remove().orElse(null),
items.isEmpty() ? null : items.remove().orElse(null),
items.isEmpty() ? null : items.remove().orElse(null),
items.isEmpty() ? null : items.remove().orElse(null)
);
}
public PotDecorations(
@Nullable ItemType back,
@Nullable ItemType left,
@Nullable ItemType right,
@Nullable ItemType front
) {
this.back = back;
this.left = left;
this.right = right;
this.front = front;
}
private List<Optional<ItemType>> asList() {
return Arrays.asList(
Optional.ofNullable(this.back),
Optional.ofNullable(this.left),
Optional.ofNullable(this.right),
Optional.ofNullable(this.front)
);
}
private static Optional<ItemType> readItem(PacketWrapper<?> wrapper) {
ItemType type = wrapper.readMappedEntity(ItemTypes::getById);
return type == ItemTypes.BRICK ? Optional.empty() : Optional.of(type);
}
public static PotDecorations read(PacketWrapper<?> wrapper) {
Queue<Optional<ItemType>> items = wrapper.<Optional<ItemType>, Queue<Optional<ItemType>>>
readCollection(ArrayDeque::new, PotDecorations::readItem);
return new PotDecorations(items);
}
private static void writeItem(PacketWrapper<?> wrapper, Optional<ItemType> type) {
wrapper.writeMappedEntity(type.orElse(ItemTypes.BRICK));
}
public static void write(PacketWrapper<?> wrapper, PotDecorations decorations) {
wrapper.writeList(decorations.asList(), PotDecorations::writeItem);
}
public @Nullable ItemType getBack() {
return this.back;
}
public void setBack(@Nullable ItemType back) {
this.back = back;
}
public @Nullable ItemType getLeft() {
return this.left;
}
public void setLeft(@Nullable ItemType left) {
this.left = left;
}
public @Nullable ItemType getRight() {
return this.right;
}
public void setRight(@Nullable ItemType right) {
this.right = right;
}
public @Nullable ItemType getFront() {
return this.front;
}
public void setFront(@Nullable ItemType front) {
this.front = front;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof PotDecorations)) return false;
PotDecorations that = (PotDecorations) obj;
if (!Objects.equals(this.back, that.back)) return false;
if (!Objects.equals(this.left, that.left)) return false;
if (!Objects.equals(this.right, that.right)) return false;
return Objects.equals(this.front, that.front);
}
@Override
public int hashCode() {
return Objects.hash(this.back, this.left, this.right, this.front);
}
}
@@ -0,0 +1,121 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.protocol.potion.PotionType;
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import java.util.List;
import java.util.Objects;
public class SuspiciousStewEffects {
private List<EffectEntry> effects;
public SuspiciousStewEffects(List<EffectEntry> effects) {
this.effects = effects;
}
public static SuspiciousStewEffects read(PacketWrapper<?> wrapper) {
List<EffectEntry> effects = wrapper.readList(EffectEntry::read);
return new SuspiciousStewEffects(effects);
}
public static void write(PacketWrapper<?> wrapper, SuspiciousStewEffects effects) {
wrapper.writeList(effects.effects, EffectEntry::write);
}
public void addEffect(EffectEntry effect) {
this.effects.add(effect);
}
public List<EffectEntry> getEffects() {
return this.effects;
}
public void setEffects(List<EffectEntry> effects) {
this.effects = effects;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof SuspiciousStewEffects)) return false;
SuspiciousStewEffects that = (SuspiciousStewEffects) obj;
return this.effects.equals(that.effects);
}
@Override
public int hashCode() {
return Objects.hashCode(this.effects);
}
public static class EffectEntry {
private PotionType type;
private int duration;
public EffectEntry(PotionType type, int duration) {
this.type = type;
this.duration = duration;
}
public static EffectEntry read(PacketWrapper<?> wrapper) {
PotionType type = wrapper.readMappedEntity(PotionTypes::getById);
int duration = wrapper.readVarInt();
return new EffectEntry(type, duration);
}
public static void write(PacketWrapper<?> wrapper, EffectEntry effect) {
wrapper.writeMappedEntity(effect.type);
wrapper.writeVarInt(effect.duration);
}
public PotionType getType() {
return this.type;
}
public void setType(PotionType type) {
this.type = type;
}
public int getDuration() {
return this.duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof EffectEntry)) return false;
EffectEntry that = (EffectEntry) obj;
if (this.duration != that.duration) return false;
return this.type.equals(that.type);
}
@Override
public int hashCode() {
return Objects.hash(this.type, this.duration);
}
}
}
@@ -0,0 +1,75 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.util.Filterable;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public class WritableBookContent {
private List<Filterable<String>> pages;
public WritableBookContent(List<Filterable<String>> pages) {
this.pages = pages;
}
public static WritableBookContent read(PacketWrapper<?> wrapper) {
List<Filterable<String>> pages = wrapper.readList(ew -> Filterable.read(
ew, eew -> eew.readString(1024)));
return new WritableBookContent(pages);
}
public static void write(PacketWrapper<?> wrapper, WritableBookContent content) {
wrapper.writeList(content.pages, (ew, page) -> Filterable.write(
ew, page, (eew, text) -> eew.writeString(text, 1024)));
}
public @Nullable Filterable<String> getPage(int index) {
return index >= 0 && index < this.pages.size() ? this.pages.get(index) : null;
}
public void addPage(Filterable<String> page) {
this.pages.add(page);
}
public List<Filterable<String>> getPages() {
return this.pages;
}
public void setPages(List<Filterable<String>> pages) {
this.pages = pages;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof WritableBookContent)) return false;
WritableBookContent that = (WritableBookContent) obj;
return this.pages.equals(that.pages);
}
@Override
public int hashCode() {
return Objects.hashCode(this.pages);
}
}
@@ -0,0 +1,131 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.component.builtin.item;
import com.github.retrooper.packetevents.util.Filterable;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public class WrittenBookContent {
private Filterable<String> title;
private String author;
private int generation;
private List<Filterable<Component>> pages;
private boolean resolved;
public WrittenBookContent(
Filterable<String> title, String author, int generation,
List<Filterable<Component>> pages, boolean resolved
) {
this.title = title;
this.author = author;
this.generation = generation;
this.pages = pages;
this.resolved = resolved;
}
public static WrittenBookContent read(PacketWrapper<?> wrapper) {
Filterable<String> title = Filterable.read(wrapper, ew -> ew.readString(32));
String author = wrapper.readString();
int generation = wrapper.readVarInt();
List<Filterable<Component>> pages = wrapper.readList(ew -> Filterable.read(
ew, PacketWrapper::readComponent));
boolean resolved = wrapper.readBoolean();
return new WrittenBookContent(title, author, generation, pages, resolved);
}
public static void write(PacketWrapper<?> wrapper, WrittenBookContent content) {
Filterable.write(wrapper, content.title, (ew, text) -> ew.writeString(text, 32));
wrapper.writeString(content.author);
wrapper.writeVarInt(content.generation);
wrapper.writeList(content.pages, (ew, page) -> Filterable.write(
ew, page, PacketWrapper::writeComponent));
wrapper.writeBoolean(content.resolved);
}
public Filterable<String> getTitle() {
return this.title;
}
public void setTitle(Filterable<String> title) {
this.title = title;
}
public String getAuthor() {
return this.author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getGeneration() {
return this.generation;
}
public void setGeneration(int generation) {
this.generation = generation;
}
public @Nullable Filterable<Component> getPage(int index) {
return index >= 0 && index < this.pages.size() ? this.pages.get(index) : null;
}
public void addPage(Filterable<Component> page) {
this.pages.add(page);
}
public List<Filterable<Component>> getPages() {
return this.pages;
}
public void setPages(List<Filterable<Component>> pages) {
this.pages = pages;
}
public boolean isResolved() {
return this.resolved;
}
public void setResolved(boolean resolved) {
this.resolved = resolved;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof WrittenBookContent)) return false;
WrittenBookContent that = (WrittenBookContent) obj;
if (this.generation != that.generation) return false;
if (this.resolved != that.resolved) return false;
if (!this.title.equals(that.title)) return false;
if (!this.author.equals(that.author)) return false;
return this.pages.equals(that.pages);
}
@Override
public int hashCode() {
return Objects.hash(this.title, this.author, this.generation, this.pages, this.resolved);
}
}
@@ -0,0 +1,27 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2023 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.armadillo;
public enum ArmadilloState {
IDLE,
ROLLING,
SCARED,
UNROLLING,
}
@@ -20,30 +20,26 @@ package com.github.retrooper.packetevents.protocol.entity.data;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.armadillo.ArmadilloState;
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
import com.github.retrooper.packetevents.protocol.entity.sniffer.SnifferState;
import com.github.retrooper.packetevents.protocol.entity.villager.VillagerData;
import com.github.retrooper.packetevents.protocol.item.ItemStack;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.particle.Particle;
import com.github.retrooper.packetevents.protocol.particle.type.ParticleType;
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.world.BlockFace;
import com.github.retrooper.packetevents.protocol.world.WorldBlockPosition;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.Quaternion4f;
import com.github.retrooper.packetevents.util.TypesBuilder;
import com.github.retrooper.packetevents.util.TypesBuilderData;
import com.github.retrooper.packetevents.util.Vector3f;
import com.github.retrooper.packetevents.util.Vector3i;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
@@ -55,15 +51,7 @@ public class EntityDataTypes {
private static final Map<String, EntityDataType<?>> ENTITY_DATA_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, EntityDataType<?>>> ENTITY_DATA_TYPE_ID_MAP = new HashMap<>();
protected static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_data_type_mappings",
ClientVersion.V_1_8,
ClientVersion.V_1_9,
ClientVersion.V_1_11,
ClientVersion.V_1_13,
ClientVersion.V_1_14,
ClientVersion.V_1_19,
ClientVersion.V_1_19_3,
ClientVersion.V_1_19_4);
protected static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_data_type_mappings");
public static final EntityDataType<Byte> BYTE = define("byte", PacketWrapper::readByte, PacketWrapper::writeByte);
@@ -153,14 +141,7 @@ public class EntityDataTypes {
public static final EntityDataType<NBTCompound> NBT = define("nbt", PacketWrapper::readNBT, PacketWrapper::writeNBT);
public static final EntityDataType<Particle> PARTICLE = define("particle", wrapper -> {
int id = wrapper.readVarInt();
ParticleType type = ParticleTypes.getById(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(), id);
return new Particle(type, type.readDataFunction().apply(wrapper));
}, (wrapper, particle) -> {
wrapper.writeVarInt(particle.getType().getId(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()));
particle.getType().writeDataFunction().accept(wrapper, particle.getData());
});
public static final EntityDataType<Particle<?>> PARTICLE = define("particle", Particle::read, Particle::write);
public static final EntityDataType<VillagerData> VILLAGER_DATA = define("villager_data", PacketWrapper::readVillagerData, PacketWrapper::writeVillagerData);
@@ -194,7 +175,6 @@ public class EntityDataTypes {
return SnifferState.values()[id];
}, (PacketWrapper<?> wrapper, SnifferState value) -> wrapper.writeVarInt(value.ordinal()));
public static final EntityDataType<Vector3f> VECTOR3F = define("vector3f",
(PacketWrapper<?> wrapper) -> new Vector3f(wrapper.readFloat(), wrapper.readFloat(), wrapper.readFloat()),
(PacketWrapper<?> wrapper, Vector3f value) -> {
@@ -212,6 +192,28 @@ public class EntityDataTypes {
wrapper.writeFloat(value.getW());
});
// Added in 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())
);
public static final EntityDataType<List<Particle<?>>> PARTICLES = define("particles",
wrapper -> wrapper.readList(Particle::read),
(wrapper, particles) -> wrapper.writeList(particles, Particle::write)
);
public static final EntityDataType<Integer> WOLF_VARIANT =
define("wolf_variant_type", readIntDeserializer(), writeIntSerializer());
/**
* Returns an immutable view of the entity-data types.
* @return Entity-Data Types
*/
public static Collection<EntityDataType<?>> values() {
return Collections.unmodifiableCollection(ENTITY_DATA_TYPE_MAP.values());
}
public static EntityDataType<?> getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, EntityDataType<?>> typeIdMap = ENTITY_DATA_TYPE_ID_MAP.get((byte) index);
@@ -367,4 +369,8 @@ public class EntityDataTypes {
}
}
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -20,46 +20,19 @@ package com.github.retrooper.packetevents.protocol.entity.type;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.TypesBuilder;
import com.github.retrooper.packetevents.util.TypesBuilderData;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.*;
public class EntityTypes {
private static final Map<String, EntityType> ENTITY_TYPE_MAP = new HashMap<>();
//Key - mappings version, value - map with entity type ids and entity types
private static final Map<Byte, Map<Integer, EntityType>> ENTITY_TYPE_ID_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, EntityType>> LEGACY_ENTITY_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_type_mappings",
ClientVersion.V_1_10,
ClientVersion.V_1_11,
ClientVersion.V_1_12,
ClientVersion.V_1_13,
ClientVersion.V_1_14,
ClientVersion.V_1_15,
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_3);
private static final TypesBuilder LEGACY_TYPES_BUILDER = new TypesBuilder("entity/legacy_entity_type_mappings",
ClientVersion.V_1_8,
ClientVersion.V_1_9,
ClientVersion.V_1_10,
ClientVersion.V_1_11,
ClientVersion.V_1_12,
ClientVersion.V_1_13);
static {
TYPES_BUILDER.unloadFileMappings();
LEGACY_TYPES_BUILDER.unloadFileMappings();
}
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("entity/entity_type_mappings");
private static final TypesBuilder LEGACY_TYPES_BUILDER = new TypesBuilder("entity/legacy_entity_type_mappings");
public static EntityType define(String key, @Nullable EntityType parent) {
TypesBuilderData data = TYPES_BUILDER.define(key);
@@ -313,5 +286,25 @@ public class EntityTypes {
// Added in 1.20.3
public static final EntityType BREEZE = define("breeze", ABSTRACT_MONSTER);
public static final EntityType WIND_CHARGE = define("wind_charge", PROJECTILE_ABSTRACT);
public static final EntityType ABSTRACT_WIND_CHARGE = define("abstract_wind_charge", PROJECTILE_ABSTRACT);
public static final EntityType WIND_CHARGE = define("wind_charge", ABSTRACT_WIND_CHARGE);
// Added in 1.20.5
public static final EntityType ARMADILLO = define("armadillo", ABSTRACT_ANIMAL);
public static final EntityType BOGGED = define("bogged", ABSTRACT_SKELETON);
public static final EntityType BREEZE_WIND_CHARGE = define("breeze_wind_charge", ABSTRACT_WIND_CHARGE);
public static final EntityType OMINOUS_ITEM_SPAWNER = define("ominous_item_spawner", ENTITY);
/**
* Returns an immutable view of the entity types.
* @return Entity Types
*/
public static Collection<EntityType> values() {
return Collections.unmodifiableCollection(ENTITY_TYPE_MAP.values());
}
static {
TYPES_BUILDER.unloadFileMappings();
LEGACY_TYPES_BUILDER.unloadFileMappings();
}
}
@@ -19,7 +19,6 @@
package com.github.retrooper.packetevents.protocol.entity.villager.profession;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.TypesBuilder;
import java.util.HashMap;
import java.util.Map;
@@ -20,6 +20,8 @@ package com.github.retrooper.packetevents.protocol.entity.villager.type;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -62,4 +64,12 @@ public class VillagerTypes {
public static final VillagerType SNOW = define(4, "minecraft:snow");
public static final VillagerType SWAMP = define(5, "minecraft:swamp");
public static final VillagerType TAIGA = define(6, "minecraft:taiga");
/**
* Returns an immutable view of the villager types.
* @return Villager Types
*/
public static Collection<VillagerType> values() {
return Collections.unmodifiableCollection(VILLAGER_TYPE_MAP.values());
}
}
@@ -0,0 +1,14 @@
package com.github.retrooper.packetevents.protocol.entity.wolfvariant;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import java.util.Set;
//TODO Finish Wolf-Variant class
public class WolfVariant {
private ResourceLocation wildId, tameId, angryId;
public WolfVariant(ResourceLocation wildId, ResourceLocation tameId, ResourceLocation angryId) {
}
}
@@ -18,18 +18,38 @@
package com.github.retrooper.packetevents.protocol.item;
import com.github.retrooper.packetevents.protocol.component.ComponentType;
import com.github.retrooper.packetevents.protocol.component.ComponentTypes;
import com.github.retrooper.packetevents.protocol.component.PatchableComponentMap;
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
import com.github.retrooper.packetevents.protocol.component.builtin.item.ItemEnchantments;
import com.github.retrooper.packetevents.protocol.item.enchantment.Enchantment;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentType;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.nbt.*;
import com.github.retrooper.packetevents.protocol.nbt.NBT;
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
import com.github.retrooper.packetevents.protocol.nbt.NBTInt;
import com.github.retrooper.packetevents.protocol.nbt.NBTList;
import com.github.retrooper.packetevents.protocol.nbt.NBTShort;
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
import com.github.retrooper.packetevents.protocol.nbt.NBTType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.DAMAGE;
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.ENCHANTMENTS;
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.MAX_DAMAGE;
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.MAX_STACK_SIZE;
import static com.github.retrooper.packetevents.protocol.component.ComponentTypes.STORED_ENCHANTMENTS;
public class ItemStack {
public static final ItemStack EMPTY = new ItemStack(ItemTypes.AIR, 0, new NBTCompound(), 0);
@@ -37,20 +57,35 @@ public class ItemStack {
private int amount;
@Nullable
private NBTCompound nbt;
@Nullable // lazy loaded
private PatchableComponentMap components; // Added in 1.20.5
private int legacyData = -1;
private boolean cachedIsEmpty = false;
private ItemStack(ItemType type, int amount, @Nullable NBTCompound nbt, int legacyData) {
this(type, amount, nbt, null, legacyData);
}
private ItemStack(
ItemType type,
int amount,
@Nullable NBTCompound nbt,
@Nullable PatchableComponentMap components,
int legacyData
) {
this.type = type;
this.amount = amount;
this.nbt = nbt;
this.components = components;
this.legacyData = legacyData;
updateCachedEmptyStatus();
}
public int getMaxStackSize() {
return getType().getMaxAmount();
return this.getComponentOr(MAX_STACK_SIZE,
// fallback to legacy specified max stack size
this.getType().getMaxAmount());
}
public boolean isStackable() {
@@ -58,11 +93,9 @@ public class ItemStack {
}
public boolean isDamageableItem() {
if (!this.cachedIsEmpty && this.getType().getMaxDurability() > 0) {
NBTCompound tag = this.getNBT();
return tag == null || !tag.getBoolean("Unbreakable");
}
return false;
return !this.cachedIsEmpty && this.getMaxDamage() > 0
&& (this.nbt == null || !this.nbt.getBoolean("Unbreakable"))
&& !this.getComponentOr(ComponentTypes.UNBREAKABLE, false);
}
public boolean isDamaged() {
@@ -70,17 +103,27 @@ public class ItemStack {
}
public int getDamageValue() {
if (nbt == null) return 0;
NBTInt damage = this.nbt.getTagOfTypeOrNull("Damage", NBTInt.class);
return damage == null ? 0 : damage.getAsInt();
if (this.nbt != null) {
NBTInt damage = this.nbt.getTagOfTypeOrNull("Damage", NBTInt.class);
if (damage != null) {
return damage.getAsInt();
}
}
return this.getComponentOr(DAMAGE, 0);
}
public void setDamageValue(int damage) {
this.getOrCreateTag().setTag("Damage", new NBTInt(Math.max(0, damage)));
int cappedDamage = Math.max(0, damage);
// set in legacy nbt
this.getOrCreateTag().setTag("Damage", new NBTInt(cappedDamage));
// set in components
this.setComponent(DAMAGE, cappedDamage);
}
public int getMaxDamage() {
return this.getType().getMaxDurability();
return this.getComponentOr(MAX_DAMAGE,
// fallback to legacy specified max durability
this.getType().getMaxDurability());
}
public NBTCompound getOrCreateTag() {
@@ -125,7 +168,12 @@ public class ItemStack {
}
public ItemStack copy() {
return cachedIsEmpty ? EMPTY : new ItemStack(type, amount, nbt == null ? null : nbt.copy(), legacyData);
return cachedIsEmpty ? EMPTY : new ItemStack(
type, amount,
nbt == null ? null : nbt.copy(),
components == null ? null : components.copy(),
legacyData
);
}
@Nullable
@@ -137,6 +185,58 @@ public class ItemStack {
this.nbt = nbt;
}
public <T> T getComponentOr(ComponentType<T> type, T otherValue) {
if (this.hasComponentPatches()) {
return this.getComponents().getOr(type, otherValue);
}
return this.getType().getComponents().getOr(type, otherValue);
}
public <T> Optional<T> getComponent(ComponentType<T> type) {
if (this.hasComponentPatches()) {
return this.getComponents().getOptional(type);
}
return this.getType().getComponents().getOptional(type);
}
public <T> void setComponent(ComponentType<T> type, T value) {
this.getComponents().set(type, value);
}
public <T> void unsetComponent(ComponentType<T> type) {
this.getComponents().unset(type);
}
public <T> void setComponent(ComponentType<T> type, Optional<T> value) {
this.getComponents().set(type, value);
}
public boolean hasComponent(ComponentType<?> type) {
if (this.hasComponentPatches()) {
return this.getComponents().has(type);
}
return this.getType().getComponents().has(type);
}
public boolean hasComponentPatches() {
return this.components != null && !this.components.getPatches().isEmpty();
}
public PatchableComponentMap getComponents() {
if (this.components == null) { // lazy load on access
this.components = new PatchableComponentMap(
this.type.getComponents(), new HashMap<>(4));
}
return this.components;
}
/**
* @param components if set null will reset to components of {@link ItemType}
*/
public void setComponents(@Nullable PatchableComponentMap components) {
this.components = components;
}
public int getLegacyData() {
return legacyData;
}
@@ -152,49 +252,99 @@ public class ItemStack {
}
public boolean isEnchanted(ClientVersion version) {
String tagName = getEnchantmentsTagName(version);
return !isEmpty() && this.nbt != null && this.nbt.getCompoundListTagOrNull(tagName) != null && !this.nbt.getCompoundListTagOrNull(tagName).getTags().isEmpty();
}
private List<Enchantment> getEnchantments(@Nullable NBTCompound nbt, ClientVersion version) {
String tagName = getEnchantmentsTagName(version);
if (nbt == null || nbt.getCompoundListTagOrNull(tagName) == null)
return new ArrayList<>(0);
NBTList<NBTCompound> nbtList = nbt.getCompoundListTagOrNull(tagName);
List<NBTCompound> compounds = nbtList.getTags();
List<Enchantment> enchantments = new ArrayList<>(compounds.size());
for (NBTCompound compound : compounds) {
EnchantmentType type = getEnchantmentTypeFromTag(compound, version);
if (type != null) {
NBTShort levelTag = compound.getTagOfTypeOrNull("lvl", NBTShort.class);
int level = levelTag.getAsInt();
Enchantment enchantment = Enchantment.builder().type(type).level(level).build();
enchantments.add(enchantment);
}
if (this.isEmpty()) {
return false;
}
return enchantments;
// check for components
if (!this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty()
|| !this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty()) {
return true;
}
// check for legacy nbt
if (this.nbt != null) {
String tagName = this.getEnchantmentsTagName(version);
NBTList<NBTCompound> enchantments = this.nbt.getCompoundListTagOrNull(tagName);
return enchantments != null && !enchantments.getTags().isEmpty();
}
return false;
}
public List<Enchantment> getEnchantments(ClientVersion version) {
return getEnchantments(this.nbt, version);
if (this.isEmpty()) {
return new ArrayList<>(0);
}
// check for components
ItemEnchantments enchantmentsComp = this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY);
ItemEnchantments storedEnchantmentsComp = this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY);
if (!enchantmentsComp.isEmpty() || !storedEnchantmentsComp.isEmpty()) {
List<Enchantment> enchantmentsList = new ArrayList<>(
enchantmentsComp.getEnchantmentCount() + storedEnchantmentsComp.getEnchantmentCount());
for (Map.Entry<EnchantmentType, Integer> enchantment : enchantmentsComp) {
enchantmentsList.add(new Enchantment(enchantment.getKey(), enchantment.getValue()));
}
for (Map.Entry<EnchantmentType, Integer> enchantment : storedEnchantmentsComp) {
enchantmentsList.add(new Enchantment(enchantment.getKey(), enchantment.getValue()));
}
return enchantmentsList;
}
// check for legacy nbt
if (this.nbt != null) {
String tagName = this.getEnchantmentsTagName(version);
NBTList<NBTCompound> nbtList = this.nbt.getCompoundListTagOrNull(tagName);
if (nbtList != null) {
List<NBTCompound> compounds = nbtList.getTags();
List<Enchantment> enchantments = new ArrayList<>(compounds.size());
for (NBTCompound compound : compounds) {
EnchantmentType type = getEnchantmentTypeFromTag(compound, version);
if (type != null) {
NBTShort levelTag = compound.getTagOfTypeOrNull("lvl", NBTShort.class);
int level = levelTag.getAsInt();
Enchantment enchantment = Enchantment.builder().type(type).level(level).build();
enchantments.add(enchantment);
}
}
return enchantments;
}
}
return new ArrayList<>(0);
}
public int getEnchantmentLevel(EnchantmentType enchantment, ClientVersion version) {
if (isEnchanted(version)) {
// isEnchanted() is true, so we can assume that nbt is not null
assert nbt != null;
String tagName = getEnchantmentsTagName(version);
for (NBTCompound base : nbt.getCompoundListTagOrNull(tagName).getTags()) {
EnchantmentType type = getEnchantmentTypeFromTag(base, version);
if (enchantment == type) {
NBTShort nbtShort = base.getTagOfTypeOrNull("lvl", NBTShort.class);
if (nbtShort == null) return 0; // this might need to be set to 1
return nbtShort.getAsInt();
if (this.isEmpty()) {
return 0;
}
// check for components
ItemEnchantments enchantmentsComp = this.getComponentOr(ENCHANTMENTS, ItemEnchantments.EMPTY);
if (!enchantmentsComp.isEmpty()) {
int level = enchantmentsComp.getEnchantmentLevel(enchantment);
if (level > 0) {
return level;
}
}
ItemEnchantments storedEnchantmentsComp = this.getComponentOr(STORED_ENCHANTMENTS, ItemEnchantments.EMPTY);
if (!storedEnchantmentsComp.isEmpty()) {
int level = storedEnchantmentsComp.getEnchantmentLevel(enchantment);
if (level > 0) {
return level;
}
}
if (this.nbt != null) {
String tagName = this.getEnchantmentsTagName(version);
NBTList<NBTCompound> nbtList = this.nbt.getCompoundListTagOrNull(tagName);
if (nbtList != null) {
for (NBTCompound base : nbtList.getTags()) {
EnchantmentType type = getEnchantmentTypeFromTag(base, version);
if (enchantment == type) {
NBTShort nbtShort = base.getTagOfTypeOrNull("lvl", NBTShort.class);
return nbtShort != null ? nbtShort.getAsInt() : 0;
}
}
}
}
@@ -202,8 +352,7 @@ public class ItemStack {
return 0;
}
@Nullable
private static EnchantmentType getEnchantmentTypeFromTag(NBTCompound tag, ClientVersion version) {
private static @Nullable EnchantmentType getEnchantmentTypeFromTag(NBTCompound tag, ClientVersion version) {
if (version.isNewerThanOrEquals(ClientVersion.V_1_13)) {
String id = tag.getStringTagValueOrNull("id");
return EnchantmentTypes.getByName(id);
@@ -214,6 +363,7 @@ public class ItemStack {
}
public void setEnchantments(List<Enchantment> enchantments, ClientVersion version) {
// set in legacy nbt
nbt = getOrCreateTag(); // Create tag if null
String tagName = getEnchantmentsTagName(version);
if (enchantments.isEmpty()) {
@@ -237,8 +387,20 @@ public class ItemStack {
assert nbt != null; // NBT was created in getOrCreateTag()
nbt.setTag(tagName, new NBTList<>(NBTType.COMPOUND, list));
}
// set in components
Map<EnchantmentType, Integer> enchantmentsMap = new HashMap<>(enchantments.size());
for (Enchantment enchantment : enchantments) {
enchantmentsMap.put(enchantment.getType(), enchantment.getLevel());
}
ComponentType<ItemEnchantments> componentType = this.type == ItemTypes.ENCHANTED_BOOK
? STORED_ENCHANTMENTS : ENCHANTMENTS;
Optional<ItemEnchantments> prevEnchantments = this.getComponent(componentType);
boolean showInTooltip = prevEnchantments.map(ItemEnchantments::isShowInTooltip).orElse(true);
this.setComponent(componentType, new ItemEnchantments(enchantmentsMap, showInTooltip));
}
@Deprecated
public String getEnchantmentsTagName(ClientVersion version) {
String tagName = version.isNewerThanOrEquals(ClientVersion.V_1_13) ? "Enchantments" : "ench";
if (type == ItemTypes.ENCHANTED_BOOK) {
@@ -256,7 +418,10 @@ public class ItemStack {
}
public static boolean isSameItemSameTags(ItemStack stack, ItemStack otherStack) {
return stack.is(otherStack.getType()) && ItemStack.tagMatches(stack, otherStack);
return stack.is(otherStack.getType())
&& (stack.isEmpty() && otherStack.isEmpty()
|| (ItemStack.tagMatches(stack, otherStack)
&& Objects.equals(stack.components, otherStack.components)));
}
public static boolean tagMatches(ItemStack left, ItemStack right) {
@@ -269,7 +434,8 @@ public class ItemStack {
if (right == null) {
return left.isEmpty();
}
return Objects.equals(left.nbt, right.nbt);
return Objects.equals(left.nbt, right.nbt)
&& Objects.equals(left.components, right.components);
}
@Override
@@ -281,6 +447,7 @@ public class ItemStack {
return getType().equals(itemStack.getType())
&& amount == itemStack.amount
&& Objects.equals(nbt, itemStack.nbt)
&& Objects.equals(components, itemStack.components)
&& legacyData == itemStack.legacyData;
}
return false;
@@ -294,7 +461,8 @@ public class ItemStack {
String identifier = type == null ? "null" : type.getName().toString();
int maxAmount = getType().getMaxAmount();
return "ItemStack[type=" + identifier + ", amount=" + amount + "/" + maxAmount
+ ", nbt tag names: " + (nbt != null ? nbt.getTagNames() : "[null]") + ", legacyData=" + legacyData + "]";
+ ", nbt tag names: " + (nbt != null ? nbt.getTagNames() : "[null]")
+ ", legacyData=" + legacyData + ", components=" + components + "]";
}
}
@@ -310,6 +478,7 @@ public class ItemStack {
private ItemType type;
private int amount = 1;
private NBTCompound nbt = null;
private PatchableComponentMap components = null;
private int legacyData = -1;
public Builder type(ItemType type) {
@@ -327,13 +496,35 @@ public class ItemStack {
return this;
}
public Builder nbt(String key, NBT tag) {
if (this.nbt == null) {
this.nbt = new NBTCompound();
}
this.nbt.setTag(key, tag);
return this;
}
public Builder components(@Nullable PatchableComponentMap components) {
this.components = components;
return this;
}
public <T> Builder component(ComponentType<T> type, @Nullable T value) {
if (this.components == null) {
this.components = new PatchableComponentMap(this.type == null
? StaticComponentMap.SHARED_ITEM_COMPONENTS : this.type.getComponents());
}
this.components.set(type, value);
return this;
}
public Builder legacyData(int legacyData) {
this.legacyData = legacyData;
return this;
}
public ItemStack build() {
return new ItemStack(type, amount, nbt, legacyData);
return new ItemStack(type, amount, nbt, components, legacyData);
}
}
@@ -0,0 +1,24 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.armormaterial;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
public interface ArmorMaterial extends MappedEntity {
}
@@ -0,0 +1,90 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.armormaterial;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import java.util.HashMap;
import java.util.Map;
public class ArmorMaterials {
private static final Map<String, ArmorMaterial> MATERIAL_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, ArmorMaterial>> MATERIAL_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_armor_material_mappings");
public static ArmorMaterial define(String key) {
TypesBuilderData data = TYPES_BUILDER.define(key);
ArmorMaterial instrument = new ArmorMaterial() {
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ArmorMaterial) {
return getName().equals(((ArmorMaterial) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, MATERIAL_MAP, MATERIAL_ID_MAP, instrument);
return instrument;
}
// with key
public static ArmorMaterial getByName(String name) {
return MATERIAL_MAP.get(name);
}
public static ArmorMaterial getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, ArmorMaterial> idMap = MATERIAL_ID_MAP.get((byte) index);
return idMap.get(id);
}
public static final ArmorMaterial LEATHER = define("leather");
public static final ArmorMaterial CHAINMAIL = define("chainmail");
public static final ArmorMaterial IRON = define("iron");
public static final ArmorMaterial GOLD = define("gold");
public static final ArmorMaterial DIAMOND = define("diamond");
// Added with 1.13
public static final ArmorMaterial TURTLE = define("turtle");
// Added with 1.16
public static final ArmorMaterial NETHERITE = define("netherite");
// Added with 1.20.5
public static final ArmorMaterial ARMADILLO = define("armadillo");
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -0,0 +1,41 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.banner;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface BannerPattern extends MappedEntity {
ResourceLocation getAssetId();
String getTranslationKey();
static BannerPattern readDirect(PacketWrapper<?> wrapper) {
ResourceLocation assetId = wrapper.readIdentifier();
String translationKey = wrapper.readString();
return new StaticBannerPattern(assetId, translationKey);
}
static void writeDirect(PacketWrapper<?> wrapper, BannerPattern pattern) {
wrapper.writeIdentifier(pattern.getAssetId());
wrapper.writeString(pattern.getTranslationKey());
}
}
@@ -0,0 +1,147 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.banner;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class BannerPatterns {
private static final Map<String, BannerPattern> PATTERN_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, BannerPattern>> PATTERN_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_banner_pattern_mappings");
public static BannerPattern define(String key) {
ResourceLocation assetId = ResourceLocation.minecraft(key);
String translationKey = "block.minecraft.banner." + key;
return define(key, assetId, translationKey);
}
public static BannerPattern define(String key, ResourceLocation assetId, String translationKey) {
TypesBuilderData data = TYPES_BUILDER.define(key);
BannerPattern pattern = new BannerPattern() {
@Override
public ResourceLocation getAssetId() {
return assetId;
}
@Override
public String getTranslationKey() {
return translationKey;
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BannerPattern) {
return getName().equals(((BannerPattern) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, PATTERN_TYPE_MAP, PATTERN_TYPE_ID_MAP, pattern);
return pattern;
}
// with key
public static BannerPattern getByName(String name) {
return PATTERN_TYPE_MAP.get(name);
}
public static BannerPattern getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, BannerPattern> idMap = PATTERN_TYPE_ID_MAP.get((byte) index);
return idMap.get(id);
}
public static final BannerPattern SQUARE_BOTTOM_LEFT = define("square_bottom_left");
public static final BannerPattern STRIPE_BOTTOM = define("stripe_bottom");
public static final BannerPattern CREEPER = define("creeper");
public static final BannerPattern HALF_HORIZONTAL = define("half_horizontal");
public static final BannerPattern STRIPE_MIDDLE = define("stripe_middle");
public static final BannerPattern BASE = define("base");
public static final BannerPattern DIAGONAL_UP_RIGHT = define("diagonal_up_right");
public static final BannerPattern HALF_HORIZONTAL_BOTTOM = define("half_horizontal_bottom");
public static final BannerPattern SMALL_STRIPES = define("small_stripes");
public static final BannerPattern GRADIENT_UP = define("gradient_up");
public static final BannerPattern CIRCLE = define("circle");
public static final BannerPattern STRIPE_DOWNLEFT = define("stripe_downleft");
public static final BannerPattern RHOMBUS = define("rhombus");
public static final BannerPattern TRIANGLES_BOTTOM = define("triangles_bottom");
public static final BannerPattern STRIPE_CENTER = define("stripe_center");
public static final BannerPattern SQUARE_BOTTOM_RIGHT = define("square_bottom_right");
public static final BannerPattern DIAGONAL_RIGHT = define("diagonal_right");
public static final BannerPattern MOJANG = define("mojang");
public static final BannerPattern STRIPE_LEFT = define("stripe_left");
public static final BannerPattern SQUARE_TOP_LEFT = define("square_top_left");
public static final BannerPattern TRIANGLE_BOTTOM = define("triangle_bottom");
public static final BannerPattern SKULL = define("skull");
public static final BannerPattern SQUARE_TOP_RIGHT = define("square_top_right");
public static final BannerPattern GLOBE = define("globe");
public static final BannerPattern STRIPE_TOP = define("stripe_top");
public static final BannerPattern CROSS = define("cross");
public static final BannerPattern BRICKS = define("bricks");
public static final BannerPattern HALF_VERTICAL = define("half_vertical");
public static final BannerPattern STRIPE_DOWNRIGHT = define("stripe_downright");
public static final BannerPattern TRIANGLES_TOP = define("triangles_top");
public static final BannerPattern STRIPE_RIGHT = define("stripe_right");
public static final BannerPattern DIAGONAL_UP_LEFT = define("diagonal_up_left");
public static final BannerPattern HALF_VERTICAL_RIGHT = define("half_vertical_right");
public static final BannerPattern TRIANGLE_TOP = define("triangle_top");
public static final BannerPattern FLOWER = define("flower");
public static final BannerPattern STRAIGHT_CROSS = define("straight_cross");
public static final BannerPattern GRADIENT = define("gradient");
public static final BannerPattern CURLY_BORDER = define("curly_border");
public static final BannerPattern BORDER = define("border");
public static final BannerPattern PIGLIN = define("piglin");
public static final BannerPattern DIAGONAL_LEFT = define("diagonal_left");
// Added with 1.21
public static final BannerPattern FLOW = define("flow");
public static final BannerPattern GUSTER = define("guster");
/**
* Returns an immutable view of the banner patterns.
* @return Banner Patterns
*/
public static Collection<BannerPattern> values() {
return Collections.unmodifiableCollection(PATTERN_TYPE_MAP.values());
}
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -0,0 +1,74 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.banner;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import java.util.Objects;
public class StaticBannerPattern implements BannerPattern {
private final ResourceLocation assetId;
private final String translationKey;
public StaticBannerPattern(ResourceLocation assetId, String translationKey) {
this.assetId = assetId;
this.translationKey = translationKey;
}
@Override
public ResourceLocation getAssetId() {
return this.assetId;
}
@Override
public String getTranslationKey() {
return this.translationKey;
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
}
@Override
public int getId(ClientVersion version) {
throw new UnsupportedOperationException();
}
@Override
public boolean isRegistered() {
return false;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticBannerPattern)) return false;
StaticBannerPattern that = (StaticBannerPattern) obj;
if (!this.assetId.equals(that.assetId)) return false;
return this.translationKey.equals(that.translationKey);
}
@Override
public int hashCode() {
return Objects.hash(this.assetId, this.translationKey);
}
}
@@ -19,13 +19,12 @@
package com.github.retrooper.packetevents.protocol.item.enchantment;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentType;
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
public class Enchantment {
private EnchantmentType type;
private int level;
private Enchantment(EnchantmentType type, int level) {
public Enchantment(EnchantmentType type, int level) {
this.type = type;
this.level = level;
}
@@ -20,28 +20,30 @@ package com.github.retrooper.packetevents.protocol.item.enchantment.type;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.TypesBuilder;
import com.github.retrooper.packetevents.util.TypesBuilderData;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class EnchantmentTypes {
private static final Map<String, String> STRING_UPDATER = new HashMap<>();
static {
// renamed in 24w03a, during the 1.20.5 update
STRING_UPDATER.put("minecraft:sweeping", "minecraft:sweeping_edge");
}
private static final Map<String, EnchantmentType> ENCHANTMENT_TYPE_MAPPINGS = new HashMap<>();
private static final Map<Byte, Map<Integer, EnchantmentType>> ENCHANTMENT_TYPE_ID_MAPPINGS = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("enchantment/enchantment_type_mappings",
ClientVersion.V_1_12,
ClientVersion.V_1_13,
ClientVersion.V_1_14,
ClientVersion.V_1_16,
ClientVersion.V_1_19);
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("enchantment/enchantment_type_mappings");
public static EnchantmentType define(String key) {
TypesBuilderData data = TYPES_BUILDER.define(key);
EnchantmentType enchantmentType = new EnchantmentType() {
private final int[] ids = data.getData();
@Override
public ResourceLocation getName() {
return data.getName();
@@ -49,8 +51,7 @@ public class EnchantmentTypes {
@Override
public int getId(ClientVersion version) {
int index = TYPES_BUILDER.getDataIndex(version);
return ids[index];
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
@@ -62,18 +63,14 @@ public class EnchantmentTypes {
}
};
ENCHANTMENT_TYPE_MAPPINGS.put(enchantmentType.getName().toString(), enchantmentType);
for (ClientVersion version : TYPES_BUILDER.getVersions()) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, EnchantmentType> typeIdMap = ENCHANTMENT_TYPE_ID_MAPPINGS.computeIfAbsent((byte) index, k -> new HashMap<>());
typeIdMap.put(enchantmentType.getId(version), enchantmentType);
}
MappingHelper.registerMapping(TYPES_BUILDER, ENCHANTMENT_TYPE_MAPPINGS, ENCHANTMENT_TYPE_ID_MAPPINGS, enchantmentType);
return enchantmentType;
}
@Nullable
public static EnchantmentType getByName(String name) {
return ENCHANTMENT_TYPE_MAPPINGS.get(name);
String fixedName = STRING_UPDATER.getOrDefault(name, name);
return ENCHANTMENT_TYPE_MAPPINGS.get(fixedName);
}
@Nullable
@@ -102,7 +99,7 @@ public class EnchantmentTypes {
public static final EnchantmentType KNOCKBACK = define("knockback");
public static final EnchantmentType FIRE_ASPECT = define("fire_aspect");
public static final EnchantmentType MOB_LOOTING = define("looting");
public static final EnchantmentType SWEEPING_EDGE = define("sweeping");
public static final EnchantmentType SWEEPING_EDGE = define("sweeping_edge");
public static final EnchantmentType BLOCK_EFFICIENCY = define("efficiency");
public static final EnchantmentType SILK_TOUCH = define("silk_touch");
public static final EnchantmentType UNBREAKING = define("unbreaking");
@@ -123,6 +120,11 @@ public class EnchantmentTypes {
public static final EnchantmentType MENDING = define("mending");
public static final EnchantmentType VANISHING_CURSE = define("vanishing_curse");
// Added in 1.20.5
public static final EnchantmentType DENSITY = define("density");
public static final EnchantmentType BREACH = define("breach");
public static final EnchantmentType WIND_BURST = define("wind_burst");
static {
TYPES_BUILDER.unloadFileMappings();
}
@@ -0,0 +1,53 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.instrument;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public interface Instrument extends MappedEntity {
Sound getSound();
int getUseDuration();
float getRange();
static Instrument read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntityOrDirect(Instruments::getById, Instrument::readDirect);
}
static Instrument readDirect(PacketWrapper<?> wrapper) {
Sound sound = Sound.read(wrapper);
int useDuration = wrapper.readVarInt();
float range = wrapper.readFloat();
return new StaticInstrument(sound, useDuration, range);
}
static void write(PacketWrapper<?> wrapper, Instrument instrument) {
wrapper.writeMappedEntityOrDirect(instrument, Instrument::writeDirect);
}
static void writeDirect(PacketWrapper<?> wrapper, Instrument instrument) {
Sound.write(wrapper, instrument.getSound());
wrapper.writeVarInt(instrument.getUseDuration());
wrapper.writeFloat(instrument.getRange());
}
}
@@ -0,0 +1,106 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.instrument;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.protocol.sound.Sounds;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import java.util.HashMap;
import java.util.Map;
public class Instruments {
private static final Map<String, Instrument> INSTRUMENT_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, Instrument>> INSTRUMENT_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_instrument_mappings");
public static Instrument define(String key, Sound sound) {
// vanilla defaults for goat horns
return define(key, sound, 140, 256f);
}
public static Instrument define(String key, Sound sound, int useDuration, float range) {
TypesBuilderData data = TYPES_BUILDER.define(key);
Instrument instrument = new Instrument() {
@Override
public Sound getSound() {
return sound;
}
@Override
public int getUseDuration() {
return useDuration;
}
@Override
public float getRange() {
return range;
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Instrument) {
return getName().equals(((Instrument) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, INSTRUMENT_MAP, INSTRUMENT_ID_MAP, instrument);
return instrument;
}
// with key
public static Instrument getByName(String name) {
return INSTRUMENT_MAP.get(name);
}
public static Instrument getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, Instrument> idMap = INSTRUMENT_ID_MAP.get((byte) index);
return idMap.get(id);
}
public static final Instrument PONDER_GOAT_HORN = define("ponder_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_0);
public static final Instrument SING_GOAT_HORN = define("sing_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_1);
public static final Instrument SEEK_GOAT_HORN = define("seek_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_2);
public static final Instrument FEEL_GOAT_HORN = define("feel_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_3);
public static final Instrument ADMIRE_GOAT_HORN = define("admire_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_4);
public static final Instrument CALL_GOAT_HORN = define("call_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_5);
public static final Instrument YEARN_GOAT_HORN = define("yearn_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_6);
public static final Instrument DREAM_GOAT_HORN = define("dream_goat_horn", Sounds.ITEM_GOAT_HORN_SOUND_7);
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -0,0 +1,83 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.instrument;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import java.util.Objects;
public class StaticInstrument implements Instrument {
private final Sound sound;
private final int useDuration;
private final float range;
public StaticInstrument(Sound sound, int useDuration, float range) {
this.sound = sound;
this.useDuration = useDuration;
this.range = range;
}
@Override
public Sound getSound() {
return this.sound;
}
@Override
public int getUseDuration() {
return this.useDuration;
}
@Override
public float getRange() {
return this.range;
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
}
@Override
public int getId(ClientVersion version) {
throw new UnsupportedOperationException();
}
@Override
public boolean isRegistered() {
return false;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticInstrument)) return false;
StaticInstrument that = (StaticInstrument) obj;
if (this.useDuration != that.useDuration) return false;
if (Float.compare(that.range, this.range) != 0) return false;
return this.sound.equals(that.sound);
}
@Override
public int hashCode() {
return Objects.hash(this.sound, this.useDuration, this.range);
}
}
@@ -0,0 +1,103 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.jukebox;
import com.github.retrooper.packetevents.protocol.sound.Sound;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import java.util.Objects;
public class JukeboxSong {
private Sound sound;
private Component description;
private float lengthInSeconds;
private int comparatorOutput;
public JukeboxSong(Sound sound, Component description, float lengthInSeconds, int comparatorOutput) {
this.sound = sound;
this.description = description;
this.lengthInSeconds = lengthInSeconds;
this.comparatorOutput = comparatorOutput;
}
public static JukeboxSong read(PacketWrapper<?> wrapper) {
Sound sound = Sound.read(wrapper);
Component description = wrapper.readComponent();
float lengthInSeconds = wrapper.readFloat();
int comparatorOutput = wrapper.readVarInt();
return new JukeboxSong(sound, description, lengthInSeconds, comparatorOutput);
}
public static void write(PacketWrapper<?> wrapper, JukeboxSong song) {
Sound.write(wrapper, song.sound);
wrapper.writeComponent(song.description);
wrapper.writeFloat(song.lengthInSeconds);
wrapper.writeVarInt(song.comparatorOutput);
}
public Sound getSound() {
return this.sound;
}
public void setSound(Sound sound) {
this.sound = sound;
}
public Component getDescription() {
return this.description;
}
public void setDescription(Component description) {
this.description = description;
}
public float getLengthInSeconds() {
return this.lengthInSeconds;
}
public void setLengthInSeconds(float lengthInSeconds) {
this.lengthInSeconds = lengthInSeconds;
}
public int getComparatorOutput() {
return this.comparatorOutput;
}
public void setComparatorOutput(int comparatorOutput) {
this.comparatorOutput = comparatorOutput;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof JukeboxSong)) return false;
JukeboxSong that = (JukeboxSong) obj;
if (Float.compare(that.lengthInSeconds, this.lengthInSeconds) != 0) return false;
if (this.comparatorOutput != that.comparatorOutput) return false;
if (!this.sound.equals(that.sound)) return false;
return this.description.equals(that.description);
}
@Override
public int hashCode() {
return Objects.hash(this.sound, this.description, this.lengthInSeconds, this.comparatorOutput);
}
}
@@ -0,0 +1,35 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.mapdecoration;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
public interface MapDecorationType extends MappedEntity {
ResourceLocation getAssetId();
boolean isShowOnItemFrame();
int getMapColor();
boolean isExplorationMapElement();
boolean isTrackCount();
}
@@ -0,0 +1,221 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.mapdecoration;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static com.github.retrooper.packetevents.resources.ResourceLocation.minecraft;
public class MapDecorationTypes {
private static final Map<String, MapDecorationType> DECORATION_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, MapDecorationType>> DECORATION_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_map_decoration_type_mappings");
public static MapDecorationType define(String key, boolean showOnItemFrame, boolean trackCount) {
return define(key, minecraft(key), showOnItemFrame, trackCount);
}
public static MapDecorationType define(
String key, ResourceLocation assetId,
boolean showOnItemFrame, boolean trackCount
) {
return define(key, assetId, showOnItemFrame,
-1, false, trackCount);
}
public static MapDecorationType define(
String key,
boolean showOnItemFrame, int mapColor,
boolean explorationMapElement, boolean trackCount
) {
return define(key, minecraft(key),
showOnItemFrame, mapColor, explorationMapElement, trackCount);
}
public static MapDecorationType define(
String key, ResourceLocation assetId,
boolean showOnItemFrame, int mapColor,
boolean explorationMapElement, boolean trackCount
) {
TypesBuilderData data = TYPES_BUILDER.define(key);
MapDecorationType potionType = new MapDecorationType() {
@Override
public ResourceLocation getAssetId() {
return assetId;
}
@Override
public boolean isShowOnItemFrame() {
return showOnItemFrame;
}
@Override
public int getMapColor() {
return mapColor;
}
@Override
public boolean isExplorationMapElement() {
return explorationMapElement;
}
@Override
public boolean isTrackCount() {
return trackCount;
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof MapDecorationType) {
return this.getName().equals(((MapDecorationType) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, DECORATION_TYPE_MAP, DECORATION_TYPE_ID_MAP, potionType);
return potionType;
}
public static @Nullable MapDecorationType getByName(String name) {
return DECORATION_TYPE_MAP.get(name);
}
public static @Nullable MapDecorationType getById(int id, ClientVersion version) {
return getById(version, id);
}
public static @Nullable MapDecorationType getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, MapDecorationType> idMap = DECORATION_TYPE_ID_MAP.get((byte) index);
return idMap.get(id);
}
// color constants used by vanilla
private static final int LIGHT_GRAY_COLOR = 0x999999;
private static final int COPPER_COLOR = 0xC26B4C;
public static final MapDecorationType PLAYER = define("player",
false, true);
public static final MapDecorationType FRAME = define("frame",
true, true);
public static final MapDecorationType RED_MARKER = define("red_marker",
false, true);
public static final MapDecorationType BLUE_MARKER = define("blue_marker",
false, true);
public static final MapDecorationType TARGET_X = define("target_x",
true, false);
public static final MapDecorationType TARGET_POINT = define("target_point",
true, false);
public static final MapDecorationType PLAYER_OFF_MAP = define("player_off_map",
false, true);
public static final MapDecorationType PLAYER_OFF_LIMITS = define("player_off_limits",
false, true);
public static final MapDecorationType MANSION = define("mansion",
true, 0x524C44, true, false);
public static final MapDecorationType MONUMENT = define("monument",
true, 0x3A7265, true, false);
public static final MapDecorationType BANNER_WHITE = define("banner_white",
minecraft("white_banner"), true, true);
public static final MapDecorationType BANNER_ORANGE = define("banner_orange",
minecraft("orange_banner"), true, true);
public static final MapDecorationType BANNER_MAGENTA = define("banner_magenta",
minecraft("magenta_banner"), true, true);
public static final MapDecorationType BANNER_LIGHT_BLUE = define("banner_light_blue",
minecraft("light_blue_banner"), true, true);
public static final MapDecorationType BANNER_YELLOW = define("banner_yellow",
minecraft("yellow_banner"), true, true);
public static final MapDecorationType BANNER_LIME = define("banner_lime",
minecraft("lime_banner"), true, true);
public static final MapDecorationType BANNER_PINK = define("banner_pink",
minecraft("pink_banner"), true, true);
public static final MapDecorationType BANNER_GRAY = define("banner_gray",
minecraft("gray_banner"), true, true);
public static final MapDecorationType BANNER_LIGHT_GRAY = define("banner_light_gray",
minecraft("light_gray_banner"), true, true);
public static final MapDecorationType BANNER_CYAN = define("banner_cyan",
minecraft("cyan_banner"), true, true);
public static final MapDecorationType BANNER_PURPLE = define("banner_purple",
minecraft("purple_banner"), true, true);
public static final MapDecorationType BANNER_BLUE = define("banner_blue",
minecraft("blue_banner"), true, true);
public static final MapDecorationType BANNER_BROWN = define("banner_brown",
minecraft("brown_banner"), true, true);
public static final MapDecorationType BANNER_GREEN = define("banner_green",
minecraft("green_banner"), true, true);
public static final MapDecorationType BANNER_RED = define("banner_red",
minecraft("red_banner"), true, true);
public static final MapDecorationType BANNER_BLACK = define("banner_black",
minecraft("black_banner"), true, true);
public static final MapDecorationType RED_X = define("red_x",
true, false);
// Added with 1.20.2
public static final MapDecorationType VILLAGE_DESERT = define("village_desert", minecraft("desert_village"),
true, LIGHT_GRAY_COLOR, true, false);
public static final MapDecorationType VILLAGE_PLAINS = define("village_plains", minecraft("plains_village"),
true, LIGHT_GRAY_COLOR, true, false);
public static final MapDecorationType VILLAGE_SAVANNA = define("village_savanna", minecraft("savanna_village"),
true, LIGHT_GRAY_COLOR, true, false);
public static final MapDecorationType VILLAGE_SNOWY = define("village_snowy", minecraft("snowy_village"),
true, LIGHT_GRAY_COLOR, true, false);
public static final MapDecorationType VILLAGE_TAIGA = define("village_taiga", minecraft("taiga_village"),
true, LIGHT_GRAY_COLOR, true, false);
public static final MapDecorationType JUNGLE_TEMPLE = define("jungle_temple",
true, LIGHT_GRAY_COLOR, true, false);
public static final MapDecorationType SWAMP_HUT = define("swamp_hut",
true, LIGHT_GRAY_COLOR, true, false);
// Added with 1.20.5
public static final MapDecorationType TRIAL_CHAMBERS = define("trial_chambers",
true, COPPER_COLOR, true, false);
/**
* Returns an immutable view of the map decoration types.
* @return Map Decoration Types
*/
public static Collection<MapDecorationType> values() {
return Collections.unmodifiableCollection(DECORATION_TYPE_MAP.values());
}
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -0,0 +1,106 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.trimmaterial;
import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMaterial;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
import java.util.Objects;
public class StaticTrimMaterial implements TrimMaterial {
private final String assetName;
private final ItemType ingredient;
private final float itemModelIndex;
private final Map<ArmorMaterial, String> overrideArmorMaterials;
private final Component description;
public StaticTrimMaterial(
String assetName, ItemType ingredient, float itemModelIndex,
Map<ArmorMaterial, String> overrideArmorMaterials, Component description
) {
this.assetName = assetName;
this.ingredient = ingredient;
this.itemModelIndex = itemModelIndex;
this.overrideArmorMaterials = overrideArmorMaterials;
this.description = description;
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
}
@Override
public int getId(ClientVersion version) {
throw new UnsupportedOperationException();
}
@Override
public boolean isRegistered() {
return false;
}
@Override
public String getAssetName() {
return this.assetName;
}
@Override
public ItemType getIngredient() {
return this.ingredient;
}
@Override
public float getItemModelIndex() {
return this.itemModelIndex;
}
@Override
public Map<ArmorMaterial, String> getOverrideArmorMaterials() {
return this.overrideArmorMaterials;
}
@Override
public Component getDescription() {
return this.description;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticTrimMaterial)) return false;
StaticTrimMaterial material = (StaticTrimMaterial) obj;
if (Float.compare(material.itemModelIndex, this.itemModelIndex) != 0) return false;
if (!this.assetName.equals(material.assetName)) return false;
if (!this.ingredient.equals(material.ingredient)) return false;
if (!this.overrideArmorMaterials.equals(material.overrideArmorMaterials)) return false;
return this.description.equals(material.description);
}
@Override
public int hashCode() {
return Objects.hash(this.assetName, this.ingredient, this.itemModelIndex, this.overrideArmorMaterials, this.description);
}
}
@@ -0,0 +1,75 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.trimmaterial;
import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMaterial;
import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMaterials;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public interface TrimMaterial extends MappedEntity {
String getAssetName();
ItemType getIngredient();
float getItemModelIndex();
default @Nullable String getArmorMaterialOverride(ArmorMaterial armorMaterial) {
return this.getOverrideArmorMaterials().get(armorMaterial);
}
Map<ArmorMaterial, String> getOverrideArmorMaterials();
Component getDescription();
static TrimMaterial read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntityOrDirect(TrimMaterials::getById, TrimMaterial::readDirect);
}
static TrimMaterial readDirect(PacketWrapper<?> wrapper) {
String assetName = wrapper.readString();
ItemType ingredient = wrapper.readMappedEntity(ItemTypes::getById);
float itemModelIndex = wrapper.readFloat();
Map<ArmorMaterial, String> overrideArmorMaterials = wrapper.readMap(
ew -> ew.readMappedEntity(ArmorMaterials::getById),
PacketWrapper::readString);
Component description = wrapper.readComponent();
return new StaticTrimMaterial(assetName, ingredient, itemModelIndex, overrideArmorMaterials, description);
}
static void write(PacketWrapper<?> wrapper, TrimMaterial material) {
wrapper.writeMappedEntityOrDirect(material, TrimMaterial::writeDirect);
}
static void writeDirect(PacketWrapper<?> wrapper, TrimMaterial material) {
wrapper.writeString(material.getAssetName());
wrapper.writeMappedEntity(material.getIngredient());
wrapper.writeFloat(material.getItemModelIndex());
wrapper.writeMap(material.getOverrideArmorMaterials(),
PacketWrapper::writeMappedEntity, PacketWrapper::writeString);
wrapper.writeComponent(material.getDescription());
}
}
@@ -0,0 +1,146 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.trimmaterial;
import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMaterial;
import com.github.retrooper.packetevents.protocol.item.armormaterial.ArmorMaterials;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import net.kyori.adventure.text.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static net.kyori.adventure.text.Component.translatable;
import static net.kyori.adventure.text.format.TextColor.color;
public class TrimMaterials {
private static final Map<String, TrimMaterial> TRIM_MATERIAL_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, TrimMaterial>> TRIM_MATERIAL_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_trim_material_mappings");
public static TrimMaterial define(String key, ItemType ingredient, float itemModelIndex, int color) {
// darken own armor material - if present
Map<ArmorMaterial, String> overrideArmorMaterials = new HashMap<>(2);
String armorMaterialId = ResourceLocation.minecraft(key).toString();
ArmorMaterial armorMaterial = ArmorMaterials.getByName(armorMaterialId);
if (armorMaterial != null) {
overrideArmorMaterials.put(armorMaterial, key + "_darker");
}
Component description = translatable("trim_material.minecraft." + key, color(color));
return define(key, key, ingredient, itemModelIndex, overrideArmorMaterials, description);
}
public static TrimMaterial define(
String key, String assetName, ItemType ingredient, float itemModelIndex,
Map<ArmorMaterial, String> overrideArmorMaterials, Component description
) {
TypesBuilderData data = TYPES_BUILDER.define(key);
TrimMaterial material = new TrimMaterial() {
@Override
public String getAssetName() {
return assetName;
}
@Override
public ItemType getIngredient() {
return ingredient;
}
@Override
public float getItemModelIndex() {
return itemModelIndex;
}
@Override
public Map<ArmorMaterial, String> getOverrideArmorMaterials() {
return overrideArmorMaterials;
}
@Override
public Component getDescription() {
return description;
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TrimMaterial) {
return this.getName().equals(((TrimMaterial) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, TRIM_MATERIAL_MAP, TRIM_MATERIAL_ID_MAP, material);
return material;
}
// with key
public static TrimMaterial getByName(String name) {
return TRIM_MATERIAL_MAP.get(name);
}
public static TrimMaterial getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, TrimMaterial> idMap = TRIM_MATERIAL_ID_MAP.get((byte) index);
return idMap.get(id);
}
// Added in 1.19.4
public static final TrimMaterial AMETHYST = define("amethyst", ItemTypes.AMETHYST_SHARD, 1f, 0x9A5CC6);
public static final TrimMaterial COPPER = define("copper", ItemTypes.COPPER_INGOT, 0.5f, 0xB4684D);
public static final TrimMaterial DIAMOND = define("diamond", ItemTypes.DIAMOND, 0.8f, 0x6EECD2);
public static final TrimMaterial EMERALD = define("emerald", ItemTypes.EMERALD, 0.7f, 0x11A036);
public static final TrimMaterial GOLD = define("gold", ItemTypes.GOLD_INGOT, 0.6f, 0xDEB12D);
public static final TrimMaterial IRON = define("iron", ItemTypes.IRON_INGOT, 0.2f, 0xECECEC);
public static final TrimMaterial LAPIS = define("lapis", ItemTypes.LAPIS_LAZULI, 0.9f, 0x416E97);
public static final TrimMaterial NETHERITE = define("netherite", ItemTypes.NETHERITE_INGOT, 0.3f, 0x625859);
public static final TrimMaterial QUARTZ = define("quartz", ItemTypes.QUARTZ, 0.1f, 0xE3D4C4);
public static final TrimMaterial REDSTONE = define("redstone", ItemTypes.REDSTONE, 0.4f, 0x971607);
/**
* Returns an immutable view of the trim materials.
* @return Trim Materials
*/
public static Collection<TrimMaterial> values() {
return Collections.unmodifiableCollection(TRIM_MATERIAL_MAP.values());
}
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -0,0 +1,95 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.trimpattern;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import net.kyori.adventure.text.Component;
import java.util.Objects;
public class StaticTrimPattern implements TrimPattern {
private final ResourceLocation assetId;
private final ItemType templateItem;
private final Component description;
private final boolean decal;
public StaticTrimPattern(
ResourceLocation assetId, ItemType templateItem,
Component description, boolean decal
) {
this.assetId = assetId;
this.templateItem = templateItem;
this.description = description;
this.decal = decal;
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
}
@Override
public int getId(ClientVersion version) {
throw new UnsupportedOperationException();
}
@Override
public boolean isRegistered() {
return false;
}
@Override
public ResourceLocation getAssetId() {
return this.assetId;
}
@Override
public ItemType getTemplateItem() {
return this.templateItem;
}
@Override
public Component getDescription() {
return this.description;
}
@Override
public boolean isDecal() {
return this.decal;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof StaticTrimPattern)) return false;
StaticTrimPattern pattern = (StaticTrimPattern) obj;
if (this.decal != pattern.decal) return false;
if (!this.assetId.equals(pattern.assetId)) return false;
if (!this.templateItem.equals(pattern.templateItem)) return false;
return this.description.equals(pattern.description);
}
@Override
public int hashCode() {
return Objects.hash(this.assetId, this.templateItem, this.description, this.decal);
}
}
@@ -0,0 +1,60 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.trimpattern;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import net.kyori.adventure.text.Component;
public interface TrimPattern extends MappedEntity {
ResourceLocation getAssetId();
ItemType getTemplateItem();
Component getDescription();
boolean isDecal();
static TrimPattern read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntityOrDirect(TrimPatterns::getById, TrimPattern::readDirect);
}
static TrimPattern readDirect(PacketWrapper<?> wrapper) {
ResourceLocation assetId = wrapper.readIdentifier();
ItemType templateItem = wrapper.readMappedEntity(ItemTypes::getById);
Component description = wrapper.readComponent();
boolean decal = wrapper.readBoolean();
return new StaticTrimPattern(assetId, templateItem, description, decal);
}
static void write(PacketWrapper<?> wrapper, TrimPattern pattern) {
wrapper.writeMappedEntityOrDirect(pattern, TrimPattern::writeDirect);
}
static void writeDirect(PacketWrapper<?> wrapper, TrimPattern pattern) {
wrapper.writeIdentifier(pattern.getAssetId());
wrapper.writeMappedEntity(pattern.getTemplateItem());
wrapper.writeComponent(pattern.getDescription());
wrapper.writeBoolean(pattern.isDecal());
}
}
@@ -0,0 +1,133 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.item.trimpattern;
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.util.mappings.MappingHelper;
import com.github.retrooper.packetevents.util.mappings.TypesBuilder;
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
import net.kyori.adventure.text.Component;
import java.util.HashMap;
import java.util.Map;
public class TrimPatterns {
private static final Map<String, TrimPattern> PATTERN_TYPE_MAP = new HashMap<>();
private static final Map<Byte, Map<Integer, TrimPattern>> PATTERN_TYPE_ID_MAP = new HashMap<>();
private static final TypesBuilder TYPES_BUILDER = new TypesBuilder("item/item_trim_pattern_mappings");
public static TrimPattern define(String key) {
ResourceLocation assetId = ResourceLocation.minecraft(key);
ItemType templateItem = ItemTypes.getByName(assetId + "_armor_trim_smithing_template");
Component description = Component.translatable("trim_pattern.minecraft." + key);
boolean decal = false;
return define(key, assetId, templateItem, description, decal);
}
public static TrimPattern define(
String key, ResourceLocation assetId, ItemType templateItem,
Component description, boolean decal
) {
TypesBuilderData data = TYPES_BUILDER.define(key);
TrimPattern pattern = new TrimPattern() {
@Override
public ResourceLocation getAssetId() {
return assetId;
}
@Override
public ItemType getTemplateItem() {
return templateItem;
}
@Override
public Component getDescription() {
return description;
}
@Override
public boolean isDecal() {
return decal;
}
@Override
public ResourceLocation getName() {
return data.getName();
}
@Override
public int getId(ClientVersion version) {
return MappingHelper.getId(version, TYPES_BUILDER, data);
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TrimPattern) {
return this.getName().equals(((TrimPattern) obj).getName());
}
return false;
}
};
MappingHelper.registerMapping(TYPES_BUILDER, PATTERN_TYPE_MAP, PATTERN_TYPE_ID_MAP, pattern);
return pattern;
}
// with key
public static TrimPattern getByName(String name) {
return PATTERN_TYPE_MAP.get(name);
}
public static TrimPattern getById(ClientVersion version, int id) {
int index = TYPES_BUILDER.getDataIndex(version);
Map<Integer, TrimPattern> idMap = PATTERN_TYPE_ID_MAP.get((byte) index);
return idMap.get(id);
}
// Added in 1.19.4
public static final TrimPattern COAST = define("coast");
public static final TrimPattern DUNE = define("dune");
public static final TrimPattern EYE = define("eye");
public static final TrimPattern RIB = define("rib");
public static final TrimPattern SENTRY = define("sentry");
public static final TrimPattern SNOUT = define("snout");
public static final TrimPattern SPIRE = define("spire");
public static final TrimPattern TIDE = define("tide");
public static final TrimPattern VEX = define("vex");
public static final TrimPattern WARD = define("ward");
public static final TrimPattern WILD = define("wild");
// Added in 1.20
public static final TrimPattern RAISER = define("raiser");
public static final TrimPattern HOST = define("host");
public static final TrimPattern SILENCE = define("silence");
public static final TrimPattern SHAPER = define("shaper");
public static final TrimPattern WAYFINDER = define("wayfinder");
// Added in 1.20.5
public static final TrimPattern BOLT = define("bolt");
public static final TrimPattern FLOW = define("flow");
static {
TYPES_BUILDER.unloadFileMappings();
}
}
@@ -18,6 +18,7 @@
package com.github.retrooper.packetevents.protocol.item.type;
import com.github.retrooper.packetevents.protocol.component.StaticComponentMap;
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
import org.jetbrains.annotations.Nullable;
@@ -39,4 +40,8 @@ public interface ItemType extends MappedEntity {
Set<ItemTypes.ItemAttribute> getAttributes();
boolean hasAttribute(ItemTypes.ItemAttribute attribute);
default StaticComponentMap getComponents() {
return StaticComponentMap.EMPTY;
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,58 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.mapper;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
public class GenericMappedEntity implements StaticMappedEntity {
private final int id;
public GenericMappedEntity(ClientVersion ignoredVersion, int id) {
this(id);
}
public GenericMappedEntity(int id) {
this.id = id;
}
public static GenericMappedEntity getById(ClientVersion version, int id) {
return new GenericMappedEntity(version, id);
}
public static GenericMappedEntity read(PacketWrapper<?> wrapper) {
return wrapper.readMappedEntity(GenericMappedEntity::new);
}
public static void write(PacketWrapper<?> wrapper, GenericMappedEntity entity) {
wrapper.writeMappedEntity(entity);
}
@Override
public int getId() {
return this.id;
}
@Override
public ResourceLocation getName() {
throw new UnsupportedOperationException();
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2022 retrooper and contributors
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,12 @@ import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
public interface MappedEntity {
ResourceLocation getName();
int getId(ClientVersion version);
default boolean isRegistered() {
return true;
}
}
@@ -0,0 +1,83 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2024 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.retrooper.packetevents.protocol.mapper;
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
import com.github.retrooper.packetevents.resources.ResourceLocation;
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
/**
* Either a key to a specific tag or a list of possible entities.
*/
public class MappedEntitySet<T> {
private final @Nullable ResourceLocation tagKey;
private final @Nullable List<T> entities;
public MappedEntitySet(ResourceLocation tagKey) {
this(tagKey, null);
}
public MappedEntitySet(List<T> entities) {
this(null, entities);
}
public MappedEntitySet(
@Nullable ResourceLocation tagKey,
@Nullable List<T> entities
) {
if (tagKey == null && entities == null) {
throw new IllegalArgumentException("Illegal generic holder set: either tag key or holder ids have to be set");
}
this.tagKey = tagKey;
this.entities = entities;
}
public static <Z extends MappedEntity> MappedEntitySet<Z> read(
PacketWrapper<?> wrapper, BiFunction<ClientVersion, Integer, Z> getter) {
int count = wrapper.readVarInt() - 1;
if (count == -1) {
return new MappedEntitySet<>(wrapper.readIdentifier(), null);
}
List<Z> entities = new ArrayList<>(Math.min(count, 65536));
for (int i = 0; i < count; i++) {
entities.add(wrapper.readMappedEntity(getter));
}
return new MappedEntitySet<>(null, entities);
}
public static <Z extends MappedEntity> void write(PacketWrapper<?> wrapper, MappedEntitySet<Z> set) {
if (set.tagKey != null) {
wrapper.writeByte(0);
wrapper.writeIdentifier(set.tagKey);
return;
}
assert set.entities != null; // can't be null, verified in ctor
wrapper.writeVarInt(set.entities.size() + 1);
for (Z entity : set.entities) {
wrapper.writeMappedEntity(entity);
}
}
}
@@ -94,4 +94,9 @@ public class NBTByte extends NBTNumber {
public NBTByte copy() {
return this;
}
@Override
public String toString() {
return "Byte(" + value + ")";
}
}
@@ -62,4 +62,9 @@ public class NBTByteArray extends NBT {
System.arraycopy(this.array, 0, abyte, 0, this.array.length);
return new NBTByteArray(abyte);
}
@Override
public String toString() {
return "ByteArray(" + Arrays.toString(array) + ")";
}
}
@@ -18,6 +18,8 @@
package com.github.retrooper.packetevents.protocol.nbt;
import org.jetbrains.annotations.Nullable;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.LinkedHashMap;
@@ -45,6 +47,10 @@ public class NBTCompound extends NBT {
return Collections.unmodifiableMap(tags);
}
public int size() {
return tags.size();
}
public NBT getTagOrThrow(String key) {
NBT tag = getTagOrNull(key);
if (tag == null) {
@@ -53,7 +59,7 @@ public class NBTCompound extends NBT {
return tag;
}
public NBT getTagOrNull(String key) {
public @Nullable NBT getTagOrNull(String key) {
return tags.get(key);
}
@@ -68,7 +74,7 @@ public class NBTCompound extends NBT {
}
@SuppressWarnings("unchecked")
public <T extends NBT> T getTagOfTypeOrNull(String key, Class<T> type) {
public <T extends NBT> @Nullable T getTagOfTypeOrNull(String key, Class<T> type) {
NBT tag = getTagOrNull(key);
if (type.isInstance(tag)) {
return (T) tag;
@@ -86,7 +92,7 @@ public class NBTCompound extends NBT {
}
@SuppressWarnings("unchecked")
public <T extends NBT> NBTList<T> getTagListOfTypeOrNull(String key, Class<T> type) {
public <T extends NBT> @Nullable NBTList<T> getTagListOfTypeOrNull(String key, Class<T> type) {
NBTList<? extends NBT> list = getTagOfTypeOrNull(key, NBTList.class);
if ((list != null) && type.isAssignableFrom(list.getTagsType().getNBTClass())) {
return (NBTList<T>) list;
@@ -98,7 +104,7 @@ public class NBTCompound extends NBT {
return getTagOfTypeOrThrow(key, NBTCompound.class);
}
public NBTCompound getCompoundTagOrNull(String key) {
public @Nullable NBTCompound getCompoundTagOrNull(String key) {
return getTagOfTypeOrNull(key, NBTCompound.class);
}
@@ -106,7 +112,7 @@ public class NBTCompound extends NBT {
return getTagOfTypeOrThrow(key, NBTNumber.class);
}
public NBTNumber getNumberTagOrNull(String key) {
public @Nullable NBTNumber getNumberTagOrNull(String key) {
return getTagOfTypeOrNull(key, NBTNumber.class);
}
@@ -114,7 +120,7 @@ public class NBTCompound extends NBT {
return getTagOfTypeOrThrow(key, NBTString.class);
}
public NBTString getStringTagOrNull(String key) {
public @Nullable NBTString getStringTagOrNull(String key) {
return getTagOfTypeOrNull(key, NBTString.class);
}
@@ -122,7 +128,7 @@ public class NBTCompound extends NBT {
return getTagListOfTypeOrThrow(key, NBTCompound.class);
}
public NBTList<NBTCompound> getCompoundListTagOrNull(String key) {
public @Nullable NBTList<NBTCompound> getCompoundListTagOrNull(String key) {
return getTagListOfTypeOrNull(key, NBTCompound.class);
}
@@ -130,7 +136,7 @@ public class NBTCompound extends NBT {
return getTagListOfTypeOrThrow(key, NBTNumber.class);
}
public NBTList<NBTNumber> getNumberListTagOrNull(String key) {
public @Nullable NBTList<NBTNumber> getNumberListTagOrNull(String key) {
return getTagListOfTypeOrNull(key, NBTNumber.class);
}
@@ -138,7 +144,7 @@ public class NBTCompound extends NBT {
return getTagListOfTypeOrThrow(key, NBTString.class);
}
public NBTList<NBTString> getStringListTagOrNull(String key) {
public @Nullable NBTList<NBTString> getStringListTagOrNull(String key) {
return getTagListOfTypeOrNull(key, NBTString.class);
}
@@ -146,7 +152,7 @@ public class NBTCompound extends NBT {
return getStringTagOrThrow(key).getValue();
}
public String getStringTagValueOrNull(String key) {
public @Nullable String getStringTagValueOrNull(String key) {
NBT tag = getTagOrNull(key);
if (tag instanceof NBTString) {
return ((NBTString) tag).getValue();
@@ -222,4 +228,8 @@ public class NBTCompound extends NBT {
return tags.hashCode();
}
@Override
public String toString() {
return "Compound{" + tags + "}";
}
}
@@ -90,4 +90,9 @@ public class NBTDouble extends NBTNumber {
public NBTDouble copy() {
return this;
}
@Override
public String toString() {
return "Double(" + value + ")";
}
}
Loaded 100 of 395 files, more files were not shown because too many files have changed in this diff. Show more