Compare commits

...
257 Commits
Author SHA1 Message Date
retrooper e3a984ca72 Merge remote-tracking branch 'origin/master' 2024-07-18 00:09:35 +02:00
retrooper f8fad9607b Really... 2024-07-18 00:09:14 +02:00
retrooper a9e40c2abc Genuinely last push now 2024-07-17 23:47:20 +02:00
retrooper da12521d0b Final commit to this... 2024-07-17 23:38:28 +02:00
retrooper de1f91104d Now really should be the last commit for this ancient version. 2024-06-23 12:46:10 +02:00
retrooper f02b77c0ba Probably last commit but silence trivial uninjection error. 2024-06-21 00:32:07 +02:00
retrooper bf2e88ed8f minimal update for pe 1.8 (likely one of the last) 2024-06-19 14:49:43 +02:00
retrooper f04a3c75a9 fixes to attribute snapshot 2024-06-03 05:20:22 +02:00
retrooper 80408424dd fixes to attribute snapshot 2024-06-02 20:52:09 +02:00
retrooper cb897dabe5 fixes to client command 2024-05-31 19:47:02 +02:00
retrooper 92cb0d024d fixes 2 2024-05-30 23:17:08 +02:00
retrooper 72e617624a fixes 2024-05-30 22:52:04 +02:00
retrooper 239d712b5f Fixes entity effect 2024-05-30 19:40:18 +02:00
retrooper 9b9ab1ade6 Fixes 2024-05-30 01:00:52 +02:00
retrooper 63383579b4 fixes 2024-05-30 00:42:30 +02:00
retrooper a2e19f7020 Fix WrappedPacketInCustomPayload 2024-05-28 20:32:15 +02:00
retrooper 7ff578e1c6 Fix Bukkit package access code. 2024-05-28 06:42:37 +02:00
retrooper 95952588f1 * Added version constants for 1.20.5 & 1.20.6
* Updated minecraft internals to adapt to 1.20.5/1.20.6 (tested on paper experimental builds)
* Adapt to further breaking changes introduced by paper
* Updated custom payload wrapper for 1.20.5/1.20.6
2024-04-28 23:22:07 +02:00
retrooper 8d4d89f049 Fix WrappedPacketOutExplosion for 1.20.4 2023-12-27 15:24:04 +01:00
retrooper 74ddbacff5 1.20.3/1.20.4 support 2023-12-08 14:44:48 +01:00
retrooper 2b1d6c636d Update build.gradle 2023-11-19 17:50:47 +01:00
retrooper e47c10966e Fix build errors for jitpack 2023-11-04 23:42:12 +01:00
retrooper 9153aa6945 Attempt to replace spigot pt 3 2023-11-04 23:39:25 +01:00
retrooper 34e4007f7d Attempt to replace spigot pt 2 2023-11-04 23:33:51 +01:00
retrooper 0528eb7035 Attempt to replace spigot 2023-11-04 23:31:47 +01:00
retrooper 3a25a933ff Attempt to replace spigot 2023-11-04 23:30:44 +01:00
retrooper efa694c8e1 Fix the way we access network manager (for 1.20.2) 2023-11-04 23:11:27 +01:00
retrooper 289a71106a Fix WrappedPacketInCustomPayload and added CONFIG packet event 2023-10-07 21:24:07 +02:00
retrooper 012bcae2d5 Fix WrappedPacketHandshakingInSetProtocol implementation for 1.20.2 2023-10-03 00:18:52 +02:00
retrooper c84641cc83 Fix EntityEffect ID processing 2023-10-02 22:05:26 +02:00
retrooper baf93f527c Attempt to fix 2023-10-02 00:46:15 +02:00
retrooper d95d5394eb Bug fix for entity effect 2023-10-02 00:36:30 +02:00
retrooper 2675b41c3e 1.20.2 fix for entity effects 2023-10-02 00:25:22 +02:00
retrooper 4d27d6e967 1.20.2 should be working 2023-09-27 17:11:31 +02:00
retrooper 9ecadae4f9 Fix NPE when sending packets to null channels. 2023-09-16 18:20:23 +02:00
retrooper 5939573ee3 Able to detect 1.20.1 servers 2023-06-14 23:24:25 +02:00
retrooper 1bbc2cba77 Minimal 1.20 update for v1.8 packetevents 2023-06-12 17:59:24 +02:00
retrooper 1c35fe3b92 Ignore modern spoof players 2023-04-23 23:03:17 +02:00
retrooper e6a7b7a3b1 Fix weird entity player classes 2023-04-07 22:40:54 +02:00
retrooper 3581e23923 Minimal 1.19.4 update 2023-04-02 17:25:52 +02:00
MWHunter 33c0d9d934 fix multiple exceptions with update checker and clean up code 2023-02-25 23:25:56 -06:00
retrooper 70eaec04c7 Merge pull request #514 from FlorianMichael/master
fixed ArrayIndexOutOfBoundsException
2023-01-02 19:13:36 +01:00
JesseUwU be7aca69ef fixed ArrayIndexOutOfBoundsException
make WrappedPacketOutPlayerInfo#getPlayerInfo playerInfoArray big enough
2023-01-01 22:37:13 +01:00
retrooper 6777809d1c Update WrappedPacketOutEntityMetadata for 1.19.3 2022-12-12 18:33:36 +01:00
retrooper 39ec3dc117 WrappedPacketOutPlayerInfo was removed in 1.19.3 2022-12-11 00:07:06 +01:00
retrooper d52a96722d Minimal 1.19.3 update 2022-12-10 23:42:13 +01:00
retrooper 7e76aaa2af trying to fix spoofmc errors once again... 2022-12-10 23:37:56 +01:00
retrooper 022c081527 Cache channels for logged in players. 2022-10-03 19:32:06 +02:00
retrooper 0b3f49cc53 Ignore fake connections. 2022-10-03 18:12:13 +02:00
AoElite 54a68013f8 fix chat exception (#476) 2022-09-07 23:45:36 +02:00
retrooper 3b947e7b9a 1.19.2 support is ready 2022-08-05 17:07:04 +02:00
retrooper 01b201cef9 Fix for injection desync on late injectors. 2022-08-04 18:33:12 +02:00
retrooper 8fdd8e5676 Preparing for 1.19.2 update. 2022-08-04 18:31:02 +02:00
retrooper 7fd4015b4f Added dependency 2022-08-02 17:33:00 +02:00
retrooper 4f2f355a98 Minor fix for WrappedPacketOutChat on 1.19+ when loading. 2022-08-02 17:28:31 +02:00
Julianandretrooper 62afe05c28 1.19.1 Update (PE 1.8) (#453)
* feat: add 1.19.1 version support to Client-/ & Server version

* feat: added 1.19.1 support to CLIENT_VERSIONS array

* feat: updated ChatPosition and added little TODO comment

* feat: added `getPlayerUUID` and `setPlayerUUID` to WrappedPacketLoginInStart (still needs SignatureData)

* Added minimal 1.19.1 support, only wrapper complete 1.19.1 support is PlayerInfo.

Won't add the newly 1.19.1 created wrappers as this version is slowly dying

Co-authored-by: retrooper <retrooperdev@gmail.com>
2022-08-02 06:12:34 +02:00
retrooper b910cd189f Merge remote-tracking branch 'origin/master' 2022-07-18 08:31:22 +02:00
retrooper 1692451244 Support multiple channel types now. (IO_URING fix for you guys) & Fix SpoofMC 2022-07-18 08:31:10 +02:00
retrooper 26fde1e9a3 Fix WrappedPacketOutEntityEffect for 1.19 2022-06-22 14:43:34 +02:00
retrooper 5e42bef488 Minor changes to Main class 2022-06-20 05:49:17 +02:00
retrooper f7aacf1ad6 WrappedPacketOutEntityEffect 1.19 support,
SystemChat relocated
2022-06-20 05:42:17 +02:00
retrooper 87aedb23fd WrappedPacketOutEntity 1.19 support 2022-06-20 05:23:31 +02:00
retrooper bf60cb0543 No debugs. 2022-06-18 20:38:51 +02:00
retrooper 367f561eb3 WrappedPacketOutSystemChat created along with its PacketType 2022-06-18 20:38:35 +02:00
retrooper bb9132a673 WrappedPacketOutChat now minimally supports 1.19 (atleast reading) 2022-06-18 20:10:16 +02:00
retrooper b843499ac6 WrappedPacketInChat now has the 1.19 features 2022-06-18 20:00:31 +02:00
retrooper 8809088b66 Since our game profiles don't support texture property reading we're going to make login success packet unsendable. (Which means packetevents plugins can't send it using our API, please update to 2.0 if you need this feature) 2022-06-18 19:50:47 +02:00
retrooper d5d4a9bffc Fixed WrappedPacketOutSetSlot for 1.17.1+
Fixed WrappedPacketLoginInEncryptionBegin for 1.19+
2022-06-18 19:44:00 +02:00
retrooper 14f3d26630 Minor progress 2022-06-16 22:00:46 +02:00
retrooper dacf44dc29 Merge remote-tracking branch 'origin/master' 2022-06-16 08:14:37 +02:00
retrooper b2d7219105 Working on 1.19 support but its not working? 2022-06-16 08:14:22 +02:00
retrooper 362bb8dbe7 Merge pull request #413 from Jaren8r/patch-1
Fix GPLv3 badge link
2022-05-30 13:54:09 +02:00
Jaren 59935293a6 Fix GPLv3 badge link
It was going to a blob on the dev branch, which no longer exists.
2022-05-30 07:52:42 -04:00
retrooper 1c0d932c48 Bump up version to 1.8.4;
Deprecated the "async" loading methods in PacketEvents.java
2022-04-27 19:25:59 +02:00
retrooper c43d992619 Removed debugs. 2022-04-27 19:22:32 +02:00
retrooper c2e0fe6b4c More changes to README 2022-04-17 22:49:08 +02:00
retrooper 14a783560c Removed currently deleted pages 2022-04-17 22:42:04 +02:00
retrooper 2767b99479 We now don't discard packets sent by bytebuf packet plugins (for example beta 2.0 version of packetevents) 2022-04-15 22:43:54 +02:00
retrooper 3d7a0d901f WrappedPacketOutBlockChange hopefully now supports 1.18.1+ 2022-03-31 23:05:25 +02:00
retrooper 177e9b7f4e Releasing 1.8.3 2022-03-24 20:07:23 +01:00
retrooper 4711ede9bc Merge remote-tracking branch 'origin/master' 2022-03-22 23:03:22 +01:00
retrooper 6bd531efc0 Fixed 1.7 injector noclassdefined errors. 2022-03-22 23:03:11 +01:00
retrooper d6f1bf972e Updated bug report template. 2022-03-22 21:00:14 +01:00
retrooper 3295b1fc89 Update feature_request.md 2022-03-10 23:28:36 +01:00
retrooper f620e45a9c Update feature_request.md 2022-03-10 23:27:10 +01:00
retrooper 825b61a24e Updated to 1.8.2 (Support latest ProtocolLib snapshots & supposed to support future 5.0.0 release of protocollib) 2022-03-08 19:23:30 +01:00
retrooper dc5d15ba85 We now support latest ProtocolLib snapshots. I'm sort of perplexed why this works, but seems like our initializer is wrapping itself somehow? Well it works 2022-03-08 19:20:14 +01:00
retrooper 0b458c2e4c Older versions of packetevents' update checker will break. We never followed version semantics till now. 2022-03-07 22:33:09 +01:00
retrooper bb9fe18a76 1.8.1 releasing. 2022-03-07 22:28:51 +01:00
retrooper 73420efbb7 Following semantic versioning. Release version: 1.8.0 2022-03-07 21:09:01 +01:00
retrooper c3bc1906b1 Merge remote-tracking branch 'origin/master' 2022-03-07 20:49:46 +01:00
retrooper 3c4a7323a0 Minor change to metrics. 2022-03-07 20:49:31 +01:00
retrooper 0a4fedff09 Finally releasing packetevents 1.8. 2022-03-07 20:42:41 +01:00
retrooper d1fb535ca7 WrappedPacketOutEntityEffect bug fix for 1.18.2 2022-03-05 17:43:43 +01:00
retrooper 5865e056d8 WrappedPacketOutEntity and WrappedPacketOutEntityHeadRotation now accept(support) floats for yaw and pitch, not that weird encoded byte angle.
NPC relative movement hopefully fixed.
2022-02-28 23:02:48 +01:00
retrooper eb561b98b2 Updated to 1.18.2. 2022-02-28 22:50:17 +01:00
retrooper 13b3ac7107 Bug fix in injecting players. 2022-02-04 19:22:58 +01:00
retrooper 1943ba2da1 Removed debug. 2022-02-04 15:22:03 +01:00
retrooper f90925e09b GeyserUtils fixed, now supports 2.0 Geyser API.
We now only inject into real socket channels.
2022-02-04 15:21:13 +01:00
retrooper e2ecb21892 Updated to Geyser 2.0 API 2022-02-02 21:33:39 +01:00
retrooper 80bc492370 Fixed broken ProtocolLib compatibility. 2022-01-31 21:30:14 +01:00
retrooper 691e8eb070 Little comment added 2022-01-21 22:48:58 +01:00
retrooper a83c3bac2a I know this isn't a perfect solution, but we want to process outgoing packets after ProtocolLib. So I went out of my way to for now only process the PLAY packets after them. We adjust our handler when protocollib is available.
PacketEventsSettings#compatInjector deprecated
2022-01-18 19:35:58 +01:00
retrooper 60a5357c34 PacketEvents v1.8 now sends the API Version to bStats. 2022-01-16 22:39:35 +01:00
retrooper af477f8479 Merge pull request #190 from retrooper/dev
1.18 support and more bug fixes merged to master branch
2022-01-06 12:40:29 +01:00
retrooper 6b82b38b59 Fixed javadocs and added plugin.yml to repository 2022-01-04 20:26:57 +01:00
retrooper 77918bb771 Minor change to a debug 2021-12-25 21:22:21 +01:00
retrooper c200b8fe35 1.8-pre-19 launching 2021-12-25 19:25:20 +01:00
DefineOutside 01cac8ded9 Merge pull request #177 from LIWKK/patch-30 2021-12-23 10:45:33 -06:00
Johannes d7a0d89d8e Fix WindowClick 1.9-1.16.5 2021-12-23 18:44:08 +02:00
retrooper 90ec7560b7 Merge remote-tracking branch 'origin/dev' into dev 2021-12-12 15:10:50 +01:00
retrooper eb96c5216b Fixed NMSUtils#getEffectId and NMSUtils#getMobEffectListById (Used in WrappedPacketOutRemoveEntityEffect) on 1.18 2021-12-12 15:10:34 +01:00
DefineOutside 176f2f7895 Merge remote-tracking branch 'origin/dev' into dev 2021-12-11 14:26:36 -06:00
DefineOutside 2489b7651b Fix 1.17.1+ support on set slot 2021-12-11 14:26:23 -06:00
retrooper 30981f8283 Merge remote-tracking branch 'origin/dev' into dev 2021-12-10 21:04:52 +01:00
retrooper 4537ac2d29 Added 1.18.1 support 2021-12-10 21:04:28 +01:00
retrooper 577d3476bb Merge pull request #171 from AlessioGr/master
Add Github actions to packetevents 1.8
2021-12-08 23:26:38 +01:00
DefineOutside 7adb2c2ecd Remove incorrect window click reflection to support 1.17 2021-12-07 16:33:23 -06:00
DefineOutside 1f02892284 1.17 support for the window click packet 2021-12-07 16:19:17 -06:00
DefineOutside 590e94ffc0 Add 1.17 support for the section position class 2021-12-06 17:16:20 -06:00
DefineOutside d5c2619bb3 Try fixing window items packet on 1.17.1 and 1.18 2021-12-06 17:15:05 -06:00
retrooper 935c9782a1 Fixed WrappedPacket#readGameMode and WrappedPacket#writeGameMode 2021-12-06 20:21:11 +01:00
retrooper 33b92f59d5 Small correction to WrappedPacket#writeAnyObject 2021-12-04 19:05:24 +01:00
MWHunter 6d7a06b93f Add support for SectionPosition in 1.18 2021-12-02 16:53:47 -06:00
MWHunter 0e42d7d14f Fix blockpos reflection on 1.18 2021-12-02 16:43:20 -06:00
Alessio Gravili 5cbdcc4158 JDK 8 2021-12-02 17:07:21 +01:00
Alessio Gravili db8f291475 Update gradle-publish.yml 2021-12-02 10:28:50 +01:00
Alessio Gravili 187084dca1 Update gradle-publish.yml 2021-12-02 10:26:52 +01:00
Alessio Gravili 316bc8070a Update gradle-publish.yml 2021-12-02 10:23:58 +01:00
Alessio Gravili 62685e9330 Create gradle-publish.yml 2021-12-02 10:22:58 +01:00
DefineOutside 169105af78 Update gradle-wrapper.properties 2021-12-01 10:44:51 -06:00
DefineOutside 398bb4b6db Update gradle-wrapper.properties 2021-12-01 10:43:56 -06:00
retrooper df56ea0aa6 Merge remote-tracking branch 'origin/dev' into dev 2021-12-01 17:25:32 +01:00
retrooper 95e73c775c Another minor bug fix in settings packet. 2021-12-01 17:25:23 +01:00
DefineOutside b8823ce00f Try fixing the map chunk packet for 1.18 2021-11-30 21:00:43 -06:00
DefineOutside 01658ce3c9 Add 1.18 support for WrappedPacketOutMapChunk 2021-11-30 18:29:57 -06:00
DefineOutside 934c181753 Support for reading 1.18 block positions 2021-11-30 17:11:20 -06:00
retrooper 0e3099e751 We should now work on 1.18 servers 2021-11-30 18:24:21 +01:00
retrooper 43ea7737ec Minor WrappedPacketInSettings change 2021-11-28 22:59:01 +01:00
retrooper 905dd43a0d Minor bug fix 2021-11-28 22:48:39 +01:00
retrooper 17f7c69b11 WrappedPacketInSettings updated to 1.18 2021-11-28 20:29:07 +01:00
retrooper 13965a4517 Added support for 1.18-rc3 2021-11-28 20:08:50 +01:00
retrooper 679d0ba037 One more minor change 2021-11-28 19:37:58 +01:00
retrooper 67e82e6d25 Merge remote-tracking branch 'origin/dev' 2021-11-28 19:32:55 +01:00
retrooper 9e58db6cb1 Minor optimizations by removing redundant/abandoned files;
ClientVersion and ServerVersion enums updated;
build.gradle optimized to remove unnecessary files;
2021-11-28 19:31:52 +01:00
retrooper e1fe2b9d99 Merge pull request #170 from byteful/unregister-listeners
Added methods to unregister PacketListenerAbstract(s).
2021-11-10 00:16:52 +01:00
byteful fd3b42ef6e Cleaned up the code a bit more. 2021-11-06 22:17:22 -05:00
byteful cf708adf55 Removed unnecessary code. 2021-11-06 22:03:36 -05:00
byteful 9f8a14b58a Added methods to unregister PacketListenerAbstract. 2021-11-06 21:39:55 -05:00
DefineOutside 1d31e06679 Merge pull request #169 from retrooper/MWHunter-patch-1
Try to fix build by updating geyser connector
2021-10-23 14:44:32 -05:00
DefineOutside a94e72ccd0 Revert to previous geyser api version 2021-10-23 14:37:34 -05:00
DefineOutside 35bd312ecf Try to fix build by updating geyser connector 2021-10-23 14:27:28 -05:00
DefineOutside 362d021745 Partially revert https://github.com/retrooper/packetevents/commit/5d1371c479c9811b87cc87a225063498654c96fe 2021-10-15 09:31:58 -05:00
DefineOutside 9d98af54e6 Data watcher takes NMS entity as argument, not bukkit entity 2021-10-13 20:30:07 -05:00
retrooper cb1438c86f Fixed WrappedPacketOutEntityVelocity#setVelocity 2021-10-10 18:23:45 +02:00
retrooper 75512add39 Fixed WrappedPacketOutWindowItems for 1.17.1 2021-10-09 20:40:43 +02:00
retrooper db1c913a3e Fixed WrappedPacketOutWindowItems for 1.17 2021-10-03 20:17:20 +02:00
DefineOutside 9c2609f4ee Vector3f should return Vector3f when cloned 2021-09-29 13:50:13 -05:00
DefineOutside 8336017bb9 Fix cloning vectors 2021-09-29 13:46:57 -05:00
retrooper 1ea4880ded Merge remote-tracking branch 'origin/dev' into dev 2021-09-26 15:52:26 +02:00
retrooper f54b8d7138 We now read the channel in network manager correctly 2021-09-26 15:52:19 +02:00
DefineOutside 52e7385864 Fix WrappedPacketOutSetCooldown 2021-09-24 22:20:09 -05:00
DefineOutside 5d1371c479 Optimize ServerVersion 2021-09-21 15:02:20 -05:00
DefineOutside 91916d0eaf Clean up WrappedPacketOutMapChunk 2021-09-20 16:44:53 -05:00
DefineOutside 73505209bc Use bitsets for WrappedPacketOutMapChunk 2021-09-20 16:35:49 -05:00
DefineOutside 934d5378e5 If a version lookup failed, try to resolve the client version again 2021-09-15 23:37:04 -05:00
retrooper 1ac55ffd50 1.8-pre-18 update 2021-09-10 20:50:45 +02:00
retrooper 9f265ef9ee Fixed cancelling event logic in listeners. 2021-09-10 20:47:44 +02:00
retrooper 0595fb6e03 Merge pull request #160 from retrooper/dev
Update master branch to a more stable build of PacketEvents.
2021-08-31 20:33:11 +02:00
retrooper 9172cd3c91 Fixed legacy viaversion api accessor 2021-08-31 20:28:57 +02:00
retrooper 7f655ad54b Created constructor for WrappedPacketLoginOutCustomPayload 2021-08-24 15:23:18 +02:00
retrooper 51af277d48 Netty channels are now acessible in the NMSPacketEvents 2021-08-23 21:21:49 +02:00
retrooper 8f566032aa Removed gradle build files, IDE files, and plugin.yml 2021-08-22 10:16:38 +02:00
retrooper d01fdce16a ServerUtils#getEntityById bug fixes 2021-08-19 07:20:13 +02:00
retrooper b956ca966b Hopefully minimized some bugs for ServerUtils#getEntityById 2021-08-18 22:41:35 +02:00
retrooper 4887d040ed Update README.md 2021-08-14 14:13:27 +02:00
retrooper 341f6632f5 Merge pull request #157 from LIWKK/patch-29
Update ViaVersionLookupUtils.java
2021-08-10 11:01:42 +02:00
Johannes 2cf93d6e17 Update ViaVersionLookupUtils.java 2021-08-09 20:17:24 +03:00
retrooper 4bbf43e83e Build issue fixed 2021-08-08 08:10:19 +02:00
retrooper bcd60977f5 WrappedPacketOutSetSlot now works on 1.17.1 2021-08-08 08:00:11 +02:00
retrooper 3c899e41b5 Adding some build files 2021-08-03 10:59:48 +02:00
retrooper 3653c9b07a Merge pull request #154 from MWHunter/viaversionclientversion
Fix getting player version for the first time with ViaVersion
2021-08-03 10:48:27 +02:00
DefineOutside c667980997 Fix getting player version for the first time with ViaVersion 2021-08-02 10:22:29 -05:00
retrooper df29b947a6 ViaVersion linkage error hopefully fixed 2021-08-02 10:48:10 +02:00
retrooper 55c3b9a446 Removed debugs when ViaVersion is present 2021-07-28 20:27:07 +02:00
retrooper 76ad95c63a PlayerUtils#writePacket and PlayerUtils#flushPackets created 2021-07-23 12:21:32 +02:00
retrooper e7235f1ef7 Fixed WrappedPacketInCustomPayload#getChannelName always returning "minecraft:brand" on 1.13+ server versions. 2021-07-21 22:16:02 +02:00
retrooper 1e26293c51 Extra NMS class added 2021-07-20 19:49:37 +02:00
retrooper 84f9bbf207 Removed invalid enum constants in ServerVersion 2021-07-20 13:59:32 +02:00
retrooper 40e13755ff NPC#teleport 2021-07-15 13:00:54 +02:00
retrooper 093c45609c Removed license notice from build files 2021-07-14 23:21:05 +02:00
retrooper 06d4333524 Copied Bukkit's BoundingBox util;
Fixed getEntityBoundingBox bugs on some newer server versions;
Corrected license notice in some files;
2021-07-14 23:15:37 +02:00
retrooper 78773c3a7b WrappedPacketOutSpawnEntity created;
Fixed incompatibilities with future ViaVersion versions(stopped using legacy API);
2021-07-14 21:58:24 +02:00
retrooper bd36cae8d0 ServerUtils#getEntityBoundingBox created 2021-07-14 21:08:26 +02:00
retrooper 2babb1ac44 Merge remote-tracking branch 'origin/dev' into dev 2021-07-14 12:13:30 +02:00
retrooper e29a15db7e Fixed sending WrappedPacketOutPosition for 1.9 -> 1.16.5 2021-07-14 12:13:22 +02:00
retrooper bb87ce9e77 Merge pull request #146 from MWHunter/fixserverversion
Fix ServerVersion#isNewerThan
2021-07-14 01:28:54 +02:00
DefineOutside b2b7687b33 Fix ServerVersion comparison 2021-07-13 18:13:16 -05:00
retrooper d182f9bd5b WrappedPacketInCustomPayload#getTag -> WrappedPacketInCustomPayload#getChannelName;
WrappedPacketOutCustomPayload#getTag -> WrappedPacketOutCustomPayload#getChannelName;
WrappedPacketLoginOutCustomPayload#getTag -> WrappedPacketLoginOutCustomPayload#getChannelName;

The channel name now also contains the namespace on newer server versions, it can be "minecraft:brand" on newer server versions instead of just "brand". Older versions such as 1.8 always had the namespace. I just made the names consistent. This is a sort of breaking change, thats why I didn't end up deprecating getTag, i want you guys to be aware of the breaking change.
2021-07-13 22:53:41 +02:00
retrooper ab4dba254d Code cleanup 2021-07-13 14:03:11 +02:00
retrooper 380b1e9a73 Merge pull request #143 from MWHunter/destroyattempttwo
Fix reading destroy packet on 1.17
2021-07-13 13:47:41 +02:00
retrooper 395cb6a6b7 WrappedPacketOutEntityDestroy now has 1.17.1 and has been cleaned up. 2021-07-13 13:47:27 +02:00
retrooper e3a6bec0ae Merge pull request #145 from MWHunter/useItem
Add WrappedPacketInUseItem
2021-07-13 13:17:01 +02:00
retrooper 8cd52c4f4d WrappedPacketInUseItem completed;
WrappedPacketInBlockPlace_1_9 optimized;
2021-07-13 13:16:31 +02:00
retrooper ef758b4ee3 Merge remote-tracking branch 'origin/dev' into dev 2021-07-13 12:57:51 +02:00
retrooper a75ad0e58e Small change 2021-07-13 12:57:34 +02:00
DefineOutside 2d282bee8e Add WrappedPacketInUseItem 2021-07-11 18:14:35 -05:00
DefineOutside 4b30678d6b Fix reading entity destroy on 1.17.1 2021-07-10 14:22:15 -05:00
retrooper 70ae66df17 Merge pull request #142 from MWHunter/flying
Fix FLYING packet on 1.17
2021-07-10 21:21:05 +02:00
retrooper 0a98140a1c Merge pull request #141 from MWHunter/dev
Fix WrappedPacketOutMapChunk for 1.17 void chunks
2021-07-10 21:18:55 +02:00
DefineOutside 2ce25c24ee Fix FLYING packet on 1.17 2021-07-10 13:57:23 -05:00
DefineOutside f27688c89f Fix WrappedPacketOutMapChunk for 1.17 void chunks 2021-07-10 12:07:39 -05:00
retrooper e287e63c58 WrappedPacketOutCollect fixed when attempting to send on 1.11+ 2021-07-09 11:35:25 +02:00
retrooper 6a44c3edbf Merge branch 'dev' of https://github.com/retrooper/packetevents into dev
 Conflicts:
	.gradle/7.0/executionHistory/executionHistory.bin
	.gradle/7.0/executionHistory/executionHistory.lock
	.gradle/7.0/fileHashes/fileHashes.bin
	.gradle/7.0/fileHashes/fileHashes.lock
	.gradle/buildOutputCleanup/buildOutputCleanup.lock
	.gradle/checksums/checksums.lock
2021-07-09 07:34:48 +02:00
retrooper cd28ced0c7 Merge pull request #138 from Tecnio/dev
Added WrappedPacketOutCollect
2021-07-09 07:32:41 +02:00
retrooper b05496db09 Fixed WrappedPacketOutCollect bugs and improved. 2021-07-09 07:31:14 +02:00
Tecnio c914ccbb90 Added WrappedPacketOutCollect 2021-07-09 04:49:00 +03:00
retrooper a236fb5523 packetevents 1.8-pre-17 2021-07-08 15:24:32 +02:00
retrooper 1768ea518e Official packetevents 1.8-pre-17 2021-07-08 13:42:17 +02:00
retrooper 0c7f185174 WrappedPacketOutMapChunk#getPrimaryBitMap deprecated, it was a typo 2021-07-08 13:40:30 +02:00
retrooper 2d8cf55985 WrappedPacketOutMapChunk#getPrimaryBitMaskBitSet created for 1.17, WrappedPacketOutMapChunk#getPrimaryBitMask won't say empty on 1.17 XD 2021-07-08 13:35:49 +02:00
retrooper 15e746687a packetevents 1.8-pre-17 2021-07-08 13:13:33 +02:00
retrooper ee9a870144 New Packet IDs for packets added in 1.17 2021-07-08 13:10:10 +02:00
retrooper 932ef480b5 Build issues fixed 2021-07-07 05:47:45 +02:00
retrooper 41125cee92 ServerVersion#v_1_17_1 created;
ClientVersion#v_1_17_1 created;
ConcurrentModificationException when calling getEntityById method fixed;
2021-07-07 05:08:42 +02:00
retrooper a9585a1117 Wrapper bug fixes for 1.17. 2021-07-06 20:06:40 +02:00
retrooper 5aaee6fb63 Much more efficient entity ID caching. 2021-07-02 12:57:09 +02:00
retrooper 8722dd0c34 WrappedPacketInUseEntity fixed for Paper;
WrappedPacketOutRemoveEntityEffect fixed for 1.17;
2021-07-01 23:00:19 +02:00
retrooper 267468f731 StackOverflow when calling getEntityById fixed; 2021-07-01 12:24:07 +02:00
retrooper 610975b957 Fixed duplicate-handler exception on server reloads. 2021-06-30 22:11:58 +02:00
retrooper f09617b2c2 PacketEvents.get().getServerUtils().getEntityById(@Nullable World world, int entityID) created;
WrappedPacketEntityAbstraction#getEntity Asynchronous Chunk getEntities call exception on 1.17 fixed;

WrappedPacketOutMapChunk#getChunkX and WrappedPacketOutMapChunk#getChunkZ fixed on 1.17
2021-06-30 21:53:57 +02:00
retrooper 96a3de9744 Caching the entity id of players when they join the server 2021-06-29 19:15:01 +02:00
retrooper 78f88fcede Fixed WrappedPacketOutEntity and WrappedPacketOutNamedEntitySpawn;
NPC API inconsistencies fixed;
2021-06-28 23:15:17 +02:00
retrooper 612a9c318f WrappedPacket#readGameMode, WrappedPacket#writeGameMode fixed 2021-06-26 12:58:26 +02:00
retrooper d1bf9a09ae Debugs removed. 2021-06-22 20:34:36 +02:00
retrooper 6e01c76e24 Fixed PacketType.Play.Client.POSITION, POSITION_LOOK and LOOK on 1.7.10 2021-06-21 20:34:59 +02:00
retrooper ccf401ff6d Potential memory leaks fixed. 2021-06-20 21:28:19 +02:00
retrooper 6b86d7fdc6 Fixed WrappedPacketEntityAbstraction#getEntity, we cache entity ID ourself. We need to do some performance tests. (looking at main-threa d load and TPS);
WrappedPacketOutMapChunk bug fix on 1.8.x
2021-06-20 20:15:09 +02:00
retrooper de3988ca29 Progress to fixing WrappedPacketEntityAbstraction#getEntity 2021-06-18 22:41:59 +02:00
retrooper 0b35e5ae5f Build issue fix. 2021-06-18 17:49:49 +02:00
retrooper 007f1030a9 All accessible packet-wrappers should be usable on 1.17. 2021-06-18 17:07:06 +02:00
retrooper 938f9184b2 1.17 support for some more client-bound packet-wrappers. 2021-06-17 21:09:13 +02:00
retrooper 4c0c57ace6 WrappedPacketInBlockPlace bug fix 2021-06-17 15:19:47 +02:00
retrooper af4906396b Build issues fixed. 2021-06-16 21:26:49 +02:00
retrooper 3a68338da4 1.17 support to more client-bound packet-wrappers 2021-06-16 20:34:52 +02:00
retrooper bb195f28ec NPC.java bug fixes and cleaned up 2021-06-16 19:18:44 +02:00
retrooper bd0d9cc528 PacketType corrections 2021-06-16 17:57:25 +02:00
retrooper 39756e4490 1.17 support for some more client-bound packet-wrappers;
WrappedPacketInJigsawGenerate package corrected;
2021-06-16 07:30:16 +02:00
retrooper d406506189 1.17 support for some more client-bound packet-wrappers;
WrappedPacketOutAnimation optimized and bug fixes (especially fake entity support)
2021-06-15 22:25:36 +02:00
retrooper 9de94b79be Fixed some PacketTypes; 2021-06-13 19:30:55 +02:00
retrooper 5cded7923a Some client-bound packet-wrappers now support 1.17! 2021-06-13 14:47:52 +02:00
retrooper 8c6adafebc Most functionality in server-bound packet-wrappers should work on 1.17, WrappedPacketInUseEntity might still need some completing. 2021-06-13 09:33:53 +02:00
retrooper 39cd41a2d3 Added 1.17 support to some more server-bound packet-wrappers;
License/Copyright holder notice in some injector classes corrected;
2021-06-12 22:27:59 +02:00
retrooper 37feadb421 Many server-bound play wrappers now support 1.17. 2021-06-11 21:48:45 +02:00
retrooper 34c079d757 All status, handshake and login packets support 1.17. Play packets remaining. 2021-06-11 20:37:20 +02:00
retrooper bd52d59801 PacketType.Play.Client.PONG, PacketType.Server.PING added (last commit actually);
Player#getNMSPing 1.17 support (last commit actually);
WrappedPacketInPong created;
WrappedPacketOutPing created;
WrappedPacketInFlying#hasPositionChanged deprecated, use isMoving;
WrappedPacketInFlying#hasRotationChanged deprecated, use isRotating;
2021-06-11 19:27:42 +02:00
retrooper 015038c9b6 Added support for the critical 1.17 NMS breaking changes. 2021-06-11 18:17:27 +02:00
164 changed files with 6277 additions and 2166 deletions

No files matched your search

+15 -18
View File
@@ -1,7 +1,7 @@
---
name: Bug report
about: Report a bug to help us fix
title: "[BUG REPORT]"
about: Report bugs to help us improve our software.
title: ""
labels: bug
assignees: ''
@@ -10,11 +10,21 @@ assignees: ''
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
**Software brand**
Please let us know what software you are using.
Eg. Spigot 1.18.2, Paper 1.18.2, Tuinity 1.18.2, Pufferfish 1.18.2, etc...
Make sure to mention the version of the software.
**Plugins**
Please give us a list of your plugins. Sometimes we run into incompatibilities. Having an overview of the plugins on your server can really help identify the problem quicker.
Eg. ViaVersion, ProtocolLib, HolographicDisplays
You may also provide a screenshot.
**How To Reproduce**
Steps to reproduce the behavior:
*Example:*
1. Login on the 1.16.4 minecraft client.
2. Join the server while it is still starting up.
1. Join with the 1.18.2 vanilla minecraft client.
2. Spam
3. ....
4. See error
@@ -24,18 +34,5 @@ A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**About your server (please complete the following information):**
- Spigot: [eg. Paper or Tuinity]
We only accept reports that are reproducible
on one of the supported spigots.
- Server Version: [eg. 1.16.4]
Feel free to report bugs for versions newer than 1.7.10, even if we
don’t support them yet, but be aware that we might have already
found the bug and fixed it in a dev build, just before you reported it.
Please don’t get frustrated in such cases.
- Plugins List if possible: [eg. ViaVersion, ProtocolLib, HolographicDisplays]
**Additional context**
Add any other context about the problem here.
+33
View File
@@ -0,0 +1,33 @@
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
name: Gradle Package
on: [ push, pull_request ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v2
- name: Set up JDK 8
uses: actions/setup-java@v2
with:
java-version: '8'
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
- name: Build with Gradle
run: gradle :clean :build
- name: Upload build artifacts
uses: actions/upload-artifact@v1
with:
name: packetevents-dev-build.jar
path: build/libs
+5 -1
View File
@@ -110,4 +110,8 @@ dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
.mvn/wrapper/maven-wrapper.jar
/src/main/resources/
/.gradle/
/.idea/
/build/
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4 -10
View File
@@ -1,29 +1,23 @@
# packetevents
[![](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://github.com/retrooper/packetevents/blob/dev/LICENSE)
[![](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://github.com/retrooper/packetevents/blob/master/LICENSE)
[![](https://jitpack.io/v/retrooper/packetevents.svg)](https://jitpack.io/#retrooper/packetevents)
PacketEvents is an open-source Packet API. It has many cross-version packet-wrappers. You can process incoming and outgoing packets on the server. You can even send packets with our packet-wrappers. We are here to save you a ton of time.
PacketEvents is a powerful packet library. Our packet wrappers are efficient and easy to use. We support many protocol versions. (1.8+)
### Resources
* [SpigotMC](https://www.spigotmc.org/resources/packetevents-api.80279/)
* [JavaDoc](https://packetevents.github.io/javadocs)
* [Discord](https://discord.me/packetevents)
### Setup
[Learn more](https://github.com/retrooper/packetevents/wiki/1.-Setup)
### Discord
[Learn more](https://discord.me/packetevents)
### Contributing/Forking
[Learn more](https://github.com/retrooper/packetevents/wiki/2.-Contributing-and-Forking)\
Our discord server has a role for contributors and forkers.
### Sponsorships
[![](https://www.ej-technologies.com/images/product_banners/jprofiler_small.png)](https://www.ej-technologies.com/products/jprofiler/overview.html)
### Statistics
PacketEvents collects statistics anonymously through bStats. Participation is completely optional and you can opt-out at any time, although it is really helpful in figuring out what environments the plugin is running in (i.e. versions of Spigot, Java), so I can adjust development accordingly.
PacketEvents collects statistics anonymously using bStats. It helps give us an overview of what platforms use our project. If you really don't like, you can turn it off.
### Credit
PacketEvents uses an injector that is extremely similar to ViaVersion's injector. I have included license and copyright holder notice in the files taken from ViaVersion. Thank you ViaVersion.
+11 -22
View File
@@ -34,10 +34,6 @@ repositories {
url = uri('https://jitpack.io/')
}
maven {
url = uri('https://nexus.funkemunky.cc/content/repositories/releases/')
}
maven {
url = uri('https://repo.viaversion.com/')
}
@@ -49,34 +45,27 @@ repositories {
maven {
url = uri('https://repo.maven.apache.org/maven2/')
}
mavenCentral()
}
dependencies {
implementation 'org.jetbrains:annotations:20.1.0'
/*compileOnly 'org.github.spigot:1.16.2:1.16.2'
compileOnly 'org.github.spigot:1.8.8:1.8.8'
compileOnly 'org.github.spigot:1.7.10:1.7.10'*/
compileOnly 'org.github.spigot:1.16.2:1.16.2'
compileOnly 'org.github.spigot:1.13.2:1.13.2'
compileOnly 'org.github.spigot:1.13:1.13'
compileOnly 'org.github.spigot:1.12.2:1.12.2'
compileOnly 'org.github.spigot:1.9.4:1.9.4'
compileOnly 'org.github.spigot:1.9:1.9'
compileOnly 'org.github.spigot:1.8.8:1.8.8'
compileOnly 'org.github.spigot:1.7.10:1.7.10'
implementation 'org.jetbrains:annotations:23.0.0'
compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'
compileOnly 'com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT'
compileOnly 'org.geysermc:connector:1.2.1-SNAPSHOT'
compileOnly 'us.myles:viaversion:3.2.0'
compileOnly 'com.viaversion:viaversion-api:4.0.1'
compileOnly 'com.github.ProtocolSupport:ProtocolSupport:3d24efeda6'
compileOnly group: 'com.github.azbh111', name: 'craftbukkit-1.14.3', version: 'R'
compileOnly group: 'com.github.azbh111', name: 'craftbukkit-1.8.8', version: 'R'
compileOnly group: 'com.github.azbh111', name: 'craftbukkit-1.7.10', version: 'R'
}
group = 'io.github.retrooper'
version = '1.8-pre-16'
version = '1.8.4'
description = 'packetevents'
java.sourceCompatibility = JavaVersion.VERSION_1_8
java.targetCompatibility = JavaVersion.VERSION_1_8
publishing {
publications {
maven(MavenPublication) {
@@ -87,4 +76,4 @@ publishing {
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
-16
View File
@@ -1,21 +1,5 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
@@ -27,11 +27,13 @@ import io.github.retrooper.packetevents.injector.GlobalChannelInjector;
import io.github.retrooper.packetevents.packettype.PacketType;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.play.out.entityequipment.WrappedPacketOutEntityEquipment;
import io.github.retrooper.packetevents.processor.BukkitEventProcessorInternal;
import io.github.retrooper.packetevents.processor.PacketProcessorInternal;
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
import io.github.retrooper.packetevents.updatechecker.UpdateChecker;
import io.github.retrooper.packetevents.utils.entityfinder.EntityFinderUtils;
import io.github.retrooper.packetevents.utils.guava.GuavaUtils;
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil;
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil_7;
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil_8;
@@ -41,6 +43,8 @@ import io.github.retrooper.packetevents.utils.server.ServerUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.utils.version.PEVersion;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
@@ -53,7 +57,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
public final class PacketEvents implements Listener, EventManager {
private static PacketEvents instance;
private static Plugin plugin;
private final PEVersion version = new PEVersion(1, 7, 9, 16);
private final PEVersion version = new PEVersion(1, 8, 4);
private final EventManager eventManager = new PEEventManager();
private final PlayerUtils playerUtils = new PlayerUtils();
private final ServerUtils serverUtils = new ServerUtils();
@@ -120,6 +124,21 @@ public final class PacketEvents implements Listener, EventManager {
PacketType.load();
EntityFinderUtils.load();
getServerUtils().entityCache = GuavaUtils.makeMap();
if (version.isNewerThanOrEquals(ServerVersion.v_1_9)) {
for (WrappedPacketOutEntityEquipment.EquipmentSlot slot : WrappedPacketOutEntityEquipment.EquipmentSlot.values()) {
slot.id = (byte) slot.ordinal();
}
} else {
WrappedPacketOutEntityEquipment.EquipmentSlot.MAINHAND.id = 0;
WrappedPacketOutEntityEquipment.EquipmentSlot.OFFHAND.id = -1; //Invalid
WrappedPacketOutEntityEquipment.EquipmentSlot.BOOTS.id = 1;
WrappedPacketOutEntityEquipment.EquipmentSlot.LEGGINGS.id = 2;
WrappedPacketOutEntityEquipment.EquipmentSlot.CHESTPLATE.id = 3;
WrappedPacketOutEntityEquipment.EquipmentSlot.HELMET.id = 4;
}
} catch (Exception ex) {
loading = false;
throw new PacketEventsLoadFailureException(ex);
@@ -142,10 +161,12 @@ public final class PacketEvents implements Listener, EventManager {
}
}
@Deprecated
public void loadAsyncNewThread() {
new Thread(this::load).start();
}
@Deprecated
public void loadAsync(ExecutorService executorService) {
executorService.execute(this::load);
}
@@ -172,6 +193,10 @@ public final class PacketEvents implements Listener, EventManager {
if (settings.isbStatsEnabled()) {
Metrics metrics = new Metrics((JavaPlugin) getPlugin(), 11327);
//Just to have an idea what versions of packetevents people use
metrics.addCustomChart(new Metrics.SimplePie("packetevents_version", () -> {
return getVersion().toString();
}));
}
//We must wait for the injector to initialize.
@@ -179,12 +204,13 @@ public final class PacketEvents implements Listener, EventManager {
//Wait for the injector to be ready.
while (!injectorReady.get()) {
}
Runnable postInjectTask = () -> {
Bukkit.getPluginManager().registerEvents(bukkitEventProcessorInternal, plugin);
for (final Player p : Bukkit.getOnlinePlayers()) {
try {
injector.injectPlayer(p);
PacketEvents.get().getEventManager().callEvent(new PostPlayerInjectEvent(p, false));
getEventManager().callEvent(new PostPlayerInjectEvent(p, false));
} catch (Exception ex) {
p.kickPlayer("Failed to inject... Please rejoin!");
}
@@ -199,7 +225,6 @@ public final class PacketEvents implements Listener, EventManager {
postInjectTask.run();
}
initialized = true;
initializing = false;
}
@@ -310,8 +335,11 @@ public final class PacketEvents implements Listener, EventManager {
}
private void handleUpdateCheck() {
if (updateChecker == null) {
updateChecker = new UpdateChecker();
}
Thread thread = new Thread(() -> {
PacketEvents.get().getPlugin().getLogger().info("[packetevents] Checking for an update, please wait...");
getPlugin().getLogger().info("[packetevents] Checking for an update, please wait...");
UpdateChecker.UpdateCheckerStatus status = updateChecker.checkForUpdate();
int seconds = 5;
int retryCount = 5;
@@ -319,7 +347,7 @@ public final class PacketEvents implements Listener, EventManager {
if (status != UpdateChecker.UpdateCheckerStatus.FAILED) {
break;
}
PacketEvents.get().getPlugin().getLogger().severe("[packetevents] Checking for an update again in " + seconds + " seconds...");
getPlugin().getLogger().severe("[packetevents] Checking for an update again in " + seconds + " seconds...");
try {
Thread.sleep(seconds * 1000L);
} catch (InterruptedException e) {
@@ -331,7 +359,7 @@ public final class PacketEvents implements Listener, EventManager {
status = updateChecker.checkForUpdate();
if (i == (retryCount - 1)) {
PacketEvents.get().getPlugin().getLogger().severe("[packetevents] PacketEvents failed to check for an update. No longer retrying.");
getPlugin().getLogger().severe("[packetevents] PacketEvents failed to check for an update. No longer retrying.");
break;
}
@@ -18,21 +18,34 @@
package io.github.retrooper.packetevents;
import io.github.retrooper.packetevents.event.PacketListenerAbstract;
import io.github.retrooper.packetevents.event.impl.PacketConfigReceiveEvent;
import io.github.retrooper.packetevents.event.impl.PacketPlayReceiveEvent;
import io.github.retrooper.packetevents.event.impl.PacketPlaySendEvent;
import io.github.retrooper.packetevents.packettype.PacketType;
import io.github.retrooper.packetevents.packetwrappers.play.in.blockdig.WrappedPacketInBlockDig;
import io.github.retrooper.packetevents.packetwrappers.play.in.custompayload.WrappedPacketInCustomPayload;
import io.github.retrooper.packetevents.packetwrappers.play.in.entityaction.WrappedPacketInEntityAction;
import io.github.retrooper.packetevents.packetwrappers.play.in.flying.WrappedPacketInFlying;
import io.github.retrooper.packetevents.packetwrappers.play.in.useentity.WrappedPacketInUseEntity;
import io.github.retrooper.packetevents.packetwrappers.play.out.entity.WrappedPacketOutEntity;
import io.github.retrooper.packetevents.packetwrappers.play.out.entityeffect.WrappedPacketOutEntityEffect;
import io.github.retrooper.packetevents.packetwrappers.play.out.entityvelocity.WrappedPacketOutEntityVelocity;
import io.github.retrooper.packetevents.packetwrappers.play.out.setslot.WrappedPacketOutSetSlot;
import io.github.retrooper.packetevents.settings.PacketEventsSettings;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import java.nio.charset.StandardCharsets;
public class PacketEventsPlugin extends JavaPlugin {
//TODO finish remaining wrappers
//1.8.1 - PacketListener will have all listener methods, packetlistenerabstract will implement it with filter system additionally.
@Override
public void onLoad() {
//Return value of create is your PacketEvents instance.
PacketEvents.create(this);
PacketEventsSettings settings = PacketEvents.get().getSettings();
PacketEventsSettings settings = PacketEvents.create(this).getSettings();
settings
.fallbackServerVersion(ServerVersion.v_1_7_10)
.compatInjector(false)
.fallbackServerVersion(ServerVersion.getLatest())
.checkForUpdates(true)
.bStats(true);
PacketEvents.get().loadAsyncNewThread();
@@ -41,6 +54,59 @@ public class PacketEventsPlugin extends JavaPlugin {
@Override
public void onEnable() {
/*PacketEvents.get().getEventManager().registerListener(new PacketListenerAbstract() {
@Override
public void onPacketPlayReceive(PacketPlayReceiveEvent event) {
if (event.getPacketId() == PacketType.Play.Client.USE_ENTITY) {
System.out.println("Yes");
WrappedPacketInUseEntity ue = new WrappedPacketInUseEntity(event.getNMSPacket());
event.getPlayer().sendMessage("action: " + ue.getAction());
event.getPlayer().sendMessage("target: " + ue.getTarget());
ItemStack stack = new ItemStack(Material.STICK);
WrappedPacketOutSetSlot setSlot = new WrappedPacketOutSetSlot(0, 37, stack);
PacketEvents.get().getPlayerUtils().sendPacket(event.getPlayer(), setSlot);
} else if (event.getPacketId() == PacketType.Play.Client.CUSTOM_PAYLOAD) {
WrappedPacketInCustomPayload cp = new WrappedPacketInCustomPayload(event.getNMSPacket());
String name = cp.getChannelName();
System.out.println("name play: " + name);
System.out.println("Data: " + ((new String(cp.getData(), StandardCharsets.UTF_8))));
}
else if (event.getPacketId() == PacketType.Play.Client.ENTITY_ACTION) {
WrappedPacketInEntityAction ea = new WrappedPacketInEntityAction(event.getNMSPacket());
event.getPlayer().sendMessage("EA: " + ea.getAction());
} else if (PacketType.Play.Client.BLOCK_DIG == event.getPacketId()) {
WrappedPacketInBlockDig bd = new WrappedPacketInBlockDig(event.getNMSPacket());
event.getPlayer().sendMessage("bd: " + bd.getDigType());
}
else if (PacketType.Play.Client.Util.isInstanceOfFlying(event.getPacketId())) {
WrappedPacketInFlying f = new WrappedPacketInFlying(event.getNMSPacket());
System.out.println("flying: " + f.getPosition().toString() + ", pitch and yaw: " + f.getPitch() + ", " + f.getYaw());
}
}
@Override
public void onPacketConfigReceive(PacketConfigReceiveEvent event) {
if (event.getPacketId() == PacketType.Play.Client.CUSTOM_PAYLOAD) {
WrappedPacketInCustomPayload cp = new WrappedPacketInCustomPayload(event.getNMSPacket());
String name = cp.getChannelName();
System.out.println("name: " + name);
System.out.println("Data: " + ((new String(cp.getData(), StandardCharsets.UTF_8))));
}
}
@Override
public void onPacketPlaySend(PacketPlaySendEvent event) {
if (PacketType.Play.Server.Util.isInstanceOfEntity(event.getPacketId())) {
WrappedPacketOutEntity entity = new WrappedPacketOutEntity(event.getNMSPacket());
} else if (event.getPacketId() == PacketType.Play.Server.ENTITY_EFFECT) {
WrappedPacketOutEntityEffect eff = new WrappedPacketOutEntityEffect(event.getNMSPacket());
//TODO Broken on 1.20.5 eff.setEffectId(eff.getEffectId());
System.out.println("eff: " + eff.getEffectId() + ", ampl: " + eff.getAmplifier() + ", dur:" + eff.getDuration());
} else if (event.getPacketId() == PacketType.Play.Server.ENTITY_VELOCITY) {
WrappedPacketOutEntityVelocity ev = new WrappedPacketOutEntityVelocity(event.getNMSPacket());
}
}
});*/
PacketEvents.get().init();
}
@@ -80,6 +80,12 @@ public abstract class PacketListenerAbstract {
public void onPacketLoginSend(PacketLoginSendEvent event) {
}
public void onPacketConfigReceive(PacketConfigReceiveEvent event) {
}
public void onPacketConfigSend(PacketConfigSendEvent event) {
}
public void onPacketPlayReceive(PacketPlayReceiveEvent event) {
}
@@ -1,21 +1,19 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 retrooper and contributors
*
* * This file is part of packetevents - https://github.com/retrooper/packetevents
* * Copyright (C) 2016-2021 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/>.
* 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 io.github.retrooper.packetevents.event;
@@ -29,10 +29,6 @@ public abstract class CancellableNMSPacketEvent extends NMSPacketEvent implement
super(channel, packet);
}
public CancellableNMSPacketEvent(InetSocketAddress address, NMSPacket packet) {
super(address, packet);
}
@Override
public boolean isCancelled() {
return cancelled;
@@ -35,17 +35,14 @@ import java.net.InetSocketAddress;
* @since 1.8
*/
public abstract class NMSPacketEvent extends PacketEvent implements CallableEvent {
private final Object channel;
private final InetSocketAddress socketAddress;
private final byte packetID;
protected NMSPacket packet;
protected boolean cancelled;
public NMSPacketEvent(Object channel, NMSPacket packet) {
this(ChannelUtils.getSocketAddress(channel), packet);//Call the constructor below
}
public NMSPacketEvent(InetSocketAddress address, NMSPacket packet) {
this.socketAddress = address;
this.channel = channel;
this.socketAddress = ChannelUtils.getSocketAddress(channel);
this.packet = packet;
packetID = PacketType.packetIDMap.getOrDefault(packet.getRawNMSPacket().getClass(), PacketType.INVALID);
}
@@ -59,6 +56,14 @@ public abstract class NMSPacketEvent extends PacketEvent implements CallableEven
return socketAddress;
}
/**
* Get the associated player's netty channel.
* @return Netty channel
*/
public Object getChannel() {
return channel;
}
/**
* This method returns the NMS name of the packet.
* To get the name of the packet we get the class of the packet and then the simple name of the class.
@@ -1,21 +1,19 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 retrooper and contributors
*
* * This file is part of packetevents - https://github.com/retrooper/packetevents
* * Copyright (C) 2016-2021 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/>.
* 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 io.github.retrooper.packetevents.event.eventtypes;
@@ -0,0 +1,44 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 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 io.github.retrooper.packetevents.event.impl;
import io.github.retrooper.packetevents.event.PacketListenerAbstract;
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
/**
* The {@code PacketConfigReceiveEvent} event is fired whenever the a CONFIG packet is received from a client.
* Use the {@link #getSocketAddress()} to identify who sends the packet.
*
* @author retrooper
* @see <a href="https://wiki.vg/Protocol#Configuration">https://wiki.vg/Protocol#Configuration</a>
* @since 1.8
*/
public class PacketConfigReceiveEvent extends CancellableNMSPacketEvent {
public PacketConfigReceiveEvent(Object channel, NMSPacket packet) {
super(channel, packet);
}
@Override
public void call(PacketListenerAbstract listener) {
if (listener.clientSidedLoginAllowance == null || listener.clientSidedLoginAllowance.contains(getPacketId())) {
listener.onPacketConfigReceive(this);
}
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 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 io.github.retrooper.packetevents.event.impl;
import io.github.retrooper.packetevents.event.PacketListenerAbstract;
import io.github.retrooper.packetevents.event.eventtypes.CancellableNMSPacketEvent;
import io.github.retrooper.packetevents.event.eventtypes.PostTaskEvent;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import org.jetbrains.annotations.NotNull;
/**
* The {@code PacketConfigSendEvent} event is fired whenever the a LOGIN packet is being planned to be sent to the client.
* Use the {@link #getSocketAddress()} to identify who sends the packet.
*
* @author retrooper
* @see <a href="https://wiki.vg/Protocol#Configuration">https://wiki.vg/Protocol#Configuration</a>
* @since 1.8
*/
public class PacketConfigSendEvent extends CancellableNMSPacketEvent implements PostTaskEvent {
private Runnable postTask;
public PacketConfigSendEvent(Object channel, NMSPacket packet) {
super(channel, packet);
}
@Override
public boolean isPostTaskAvailable() {
return postTask != null;
}
@Override
public Runnable getPostTask() {
return postTask;
}
@Override
public void setPostTask(@NotNull Runnable postTask) {
this.postTask = postTask;
}
@Override
public void call(PacketListenerAbstract listener) {
if (listener.serverSidedLoginAllowance == null || listener.serverSidedLoginAllowance.contains(getPacketId())) {
listener.onPacketConfigSend(this);
}
}
}
@@ -34,14 +34,10 @@ import java.net.InetSocketAddress;
* @since 1.8
*/
public class PacketHandshakeReceiveEvent extends CancellableNMSPacketEvent {
public PacketHandshakeReceiveEvent(final Object channel, final NMSPacket packet) {
public PacketHandshakeReceiveEvent(Object channel, NMSPacket packet) {
super(channel, packet);
}
public PacketHandshakeReceiveEvent(final InetSocketAddress socketAddress, final NMSPacket packet) {
super(socketAddress, packet);
}
@Override
public void call(PacketListenerAbstract listener) {
if (listener.clientSidedLoginAllowance == null || listener.clientSidedLoginAllowance.contains(getPacketId())) {
@@ -34,14 +34,10 @@ import java.net.InetSocketAddress;
* @since 1.8
*/
public class PacketLoginReceiveEvent extends CancellableNMSPacketEvent {
public PacketLoginReceiveEvent(final Object channel, final NMSPacket packet) {
public PacketLoginReceiveEvent(Object channel, NMSPacket packet) {
super(channel, packet);
}
public PacketLoginReceiveEvent(final InetSocketAddress socketAddress, final NMSPacket packet) {
super(socketAddress, packet);
}
@Override
public void call(PacketListenerAbstract listener) {
if (listener.clientSidedLoginAllowance == null || listener.clientSidedLoginAllowance.contains(getPacketId())) {
@@ -41,10 +41,6 @@ public class PacketLoginSendEvent extends CancellableNMSPacketEvent implements P
super(channel, packet);
}
public PacketLoginSendEvent(InetSocketAddress address, NMSPacket packet) {
super(address, packet);
}
@Override
public boolean isPostTaskAvailable() {
return postTask != null;
@@ -38,10 +38,6 @@ public class PacketStatusReceiveEvent extends CancellableNMSPacketEvent {
super(channel, packet);
}
public PacketStatusReceiveEvent(final InetSocketAddress socketAddress, final NMSPacket packet) {
super(socketAddress, packet);
}
@Override
public void call(PacketListenerAbstract listener) {
if (listener.clientSidedStatusAllowance == null || listener.clientSidedStatusAllowance.contains(getPacketId())) {
@@ -44,10 +44,6 @@ public class PacketStatusSendEvent extends CancellableNMSPacketEvent implements
super(channel, packet);
}
public PacketStatusSendEvent(InetSocketAddress address, NMSPacket packet) {
super(address, packet);
}
@Override
public boolean isPostTaskAvailable() {
return postTask != null;
@@ -156,6 +156,30 @@ public interface EventManager {
return this;
}
/**
* Unregister a PacketListenerAbstract listener.
*
* @param listener {@link PacketListenerAbstract}
* @return Same event manager instance.
*/
default EventManager unregisterListener(PacketListenerAbstract listener) {
if (listener != null) {
PEEventManager.EVENT_MANAGER_MODERN.unregisterListener(listener);
}
return this;
}
/**
* Unregister multiple PacketListenerAbstract listeners.
*
* @param listeners {@link PacketListenerAbstract}
* @return Same event manager instance.
*/
default EventManager unregisterListeners(PacketListenerAbstract... listeners) {
PEEventManager.EVENT_MANAGER_MODERN.unregisterListeners(listeners);
return this;
}
/**
* Unregister all registered event listeners.
* All the deprecated and the dynamic listeners will be unregistered.
@@ -45,10 +45,6 @@ class EventManagerModern {
* @see EventManagerLegacy#callEvent(PacketEvent, byte)
*/
public void callEvent(final PacketEvent event) {
boolean cancel = false;
if (event instanceof CancellableEvent) {
cancel = ((CancellableEvent) event).isCancelled();
}
byte highestReachedPriority = (byte) (PacketListenerPriority.LOWEST.getId() - 1);
for (byte priority = PacketListenerPriority.LOWEST.getId(); priority <= PacketListenerPriority.MONITOR.getId(); priority++) {
HashSet<PacketListenerAbstract> listeners = listenersMap.get(priority);
@@ -63,17 +59,10 @@ class EventManagerModern {
//TODO Remove, because its redundant. We are only keeping it for compatibility with the legacy event manager.
if (event instanceof CancellableEvent) {
if (priority > highestReachedPriority) {
CancellableEvent ce = (CancellableEvent) event;
cancel = ce.isCancelled();
highestReachedPriority = priority;
}
}
}
//TODO Remove. This is also redundant. The listeners are always called in order, the event is always being modified by each listener. The last listener therefore has the last decision on the cancellation.
if (event instanceof CancellableEvent) {
CancellableEvent ce = (CancellableEvent) event;
ce.setCancelled(cancel);
}
}
}
PEEventManager.EVENT_MANAGER_LEGACY.callEvent(event, highestReachedPriority);
@@ -105,6 +94,30 @@ class EventManagerModern {
}
}
/**
* Unregister the dynamic packet event listener.
*
* @param listener {@link PacketListenerAbstract}
*/
public synchronized void unregisterListener(final PacketListenerAbstract listener) {
byte priority = listener.getPriority().getId();
HashSet<PacketListenerAbstract> listenerSet = listenersMap.get(priority);
if (listenerSet != null) {
listenerSet.remove(listener);
}
}
/**
* Unregister multiple dynamic packet event listeners with one method.
*
* @param listeners {@link PacketListenerAbstract}
*/
public synchronized void unregisterListeners(PacketListenerAbstract... listeners) {
for (PacketListenerAbstract listener : listeners) {
unregisterListener(listener);
}
}
/**
* Unregister all dynamic packet event listeners.
*/
@@ -35,5 +35,9 @@ public interface ChannelInjector {
boolean hasInjected(Player player);
void writePacket(Object channel, Object rawNMSPacket);
void flushPackets(Object channel);
void sendPacket(Object channel, Object rawNMSPacket);
}
@@ -84,6 +84,14 @@ public class GlobalChannelInjector {
return injector.hasInjected(player);
}
public void writePacket(Object ch, Object rawNMSPacket) {
injector.writePacket(ch, rawNMSPacket);
}
public void flushPackets(Object ch) {
injector.flushPackets(ch);
}
public void sendPacket(Object ch, Object rawNMSPacket) {
injector.sendPacket(ch, rawNMSPacket);
}
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 retrooper and contributors
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion 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
@@ -20,13 +20,13 @@ package io.github.retrooper.packetevents.injector.legacy;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.processor.PacketProcessorInternal;
import net.minecraft.util.io.netty.buffer.ByteBuf;
import net.minecraft.util.io.netty.channel.ChannelDuplexHandler;
import net.minecraft.util.io.netty.channel.ChannelHandler;
import net.minecraft.util.io.netty.channel.ChannelHandlerContext;
import net.minecraft.util.io.netty.channel.ChannelPromise;
import org.bukkit.entity.Player;
import java.util.logging.Level;
@ChannelHandler.Sharable
public class PlayerChannelHandlerLegacy extends ChannelDuplexHandler {
/**
* Associated player.
@@ -36,32 +36,29 @@ public class PlayerChannelHandlerLegacy extends ChannelDuplexHandler {
@Override
public void channelRead(final ChannelHandlerContext ctx, Object packet) throws Exception {
try {
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().read(player, ctx.channel(), packet);
if (data.packet != null) {
super.channelRead(ctx, data.packet);
PacketEvents.get().getInternalPacketProcessor().postRead(player, ctx.channel(), data.packet);
}
} catch (Throwable t) {
PacketEvents.get().getPlugin().getLogger().log(Level.SEVERE, "Unable to handle an incoming packet ", t.getMessage());
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().read(player, ctx.channel(), packet);
if (data.packet != null) {
super.channelRead(ctx, data.packet);
PacketEvents.get().getInternalPacketProcessor().postRead(player, ctx.channel(), data.packet);
}
}
@Override
public void write(final ChannelHandlerContext ctx, Object packet, final ChannelPromise promise) throws Exception {
try {
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().write(player, ctx.channel(), packet);
if (data.postAction != null) {
promise.addListener(f -> {
data.postAction.run();
});
}
if (data.packet != null) {
super.write(ctx, data.packet, promise);
PacketEvents.get().getInternalPacketProcessor().postWrite(player, ctx.channel(), data.packet);
}
} catch (Throwable t) {
PacketEvents.get().getPlugin().getLogger().log(Level.SEVERE, "Unable to handle an outgoing packet ", t.getMessage());
if (packet instanceof ByteBuf) {
//Ignore bytebufs!
super.write(ctx, packet, promise);
return;
}
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().write(player, ctx.channel(), packet);
if (data.postAction != null) {
promise.addListener(f -> {
data.postAction.run();
});
}
if (data.packet != null) {
super.write(ctx, data.packet, promise);
PacketEvents.get().getInternalPacketProcessor().postWrite(player, ctx.channel(), data.packet);
}
}
}
@@ -25,6 +25,7 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.list.ListWrapper;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelFuture;
import net.minecraft.util.io.netty.channel.ChannelHandler;
@@ -125,11 +126,15 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
List<Object> networkManagers = NMSUtils.getNetworkManagers();
synchronized (networkManagers) {
for (Object networkManager : networkManagers) {
WrappedPacket networkManagerWrapper = new WrappedPacket(new NMSPacket(networkManager));
WrappedPacket networkManagerWrapper = new WrappedPacket(new NMSPacket(networkManager), NMSUtils.networkManagerClass);
Channel channel = (Channel) networkManagerWrapper.readObject(0, NMSUtils.nettyChannelClass);
if (channel == null) {
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
continue;
}
if (channel.pipeline().get(PacketEvents.get().getHandlerName()) != null) {
channel.pipeline().remove(PacketEvents.get().getHandlerName());
}
if (channel.pipeline().get("packet_handler") != null) {
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), new PlayerChannelHandlerLegacy());
@@ -222,7 +227,7 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
childHandlerField.set(bootstrapAcceptor, ((PEChannelInitializerLegacy) oldInit).getOldChannelInitializer());
}
} catch (Exception e) {
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
}
}
injectedFutures.clear();
@@ -238,7 +243,7 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
}
} catch (IllegalAccessException e) {
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
}
}
@@ -275,9 +280,36 @@ public class EarlyChannelInjectorLegacy implements EarlyInjector {
return handler != null && handler.player != null;
}
@Override
public void writePacket(Object ch, Object rawNMSPacket) {
Channel channel = (Channel) ch;
//Don't write packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.write(rawNMSPacket);
}
@Override
public void flushPackets(Object ch) {
Channel channel = (Channel) ch;
//Don't flush packets for fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.flush();
}
@Override
public void sendPacket(Object ch, Object rawNMSPacket) {
Channel channel = (Channel) ch;
//Don't send packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.writeAndFlush(rawNMSPacket);
}
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 retrooper and contributors
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion 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
@@ -20,6 +20,7 @@ package io.github.retrooper.packetevents.injector.legacy.early;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.injector.legacy.PlayerChannelHandlerLegacy;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelInitializer;
@@ -47,6 +48,10 @@ public class PEChannelInitializerLegacy extends ChannelInitializer<Channel> {
protected void initChannel(Channel channel) throws Exception {
initChannelMethod.invoke(oldChannelInitializer, channel);
PlayerChannelHandlerLegacy channelHandler = new PlayerChannelHandlerLegacy();
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
if (channel.pipeline().get("packet_handler") != null) {
String handlerName = PacketEvents.get().getHandlerName();
if (channel.pipeline().get(handlerName) != null) {
@@ -21,6 +21,7 @@ package io.github.retrooper.packetevents.injector.legacy.late;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.injector.LateInjector;
import io.github.retrooper.packetevents.injector.legacy.PlayerChannelHandlerLegacy;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import net.minecraft.util.io.netty.channel.Channel;
import org.bukkit.entity.Player;
@@ -40,7 +41,11 @@ public class LateChannelInjectorLegacy implements LateInjector {
PlayerChannelHandlerLegacy playerChannelHandlerLegacy = new PlayerChannelHandlerLegacy();
playerChannelHandlerLegacy.player = player;
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerLegacy);
if (channel != null) {
channel.eventLoop().execute(() -> {
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerLegacy);
});
}
}
@Override
@@ -58,12 +63,39 @@ public class LateChannelInjectorLegacy implements LateInjector {
@Override
public boolean hasInjected(Player player) {
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
return channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
return channel != null && channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
}
@Override
public void writePacket(Object ch, Object rawNMSPacket) {
Channel channel = (Channel) ch;
//Don't write packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.write(rawNMSPacket);
}
@Override
public void flushPackets(Object ch) {
Channel channel = (Channel) ch;
//Don't flush packets for fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.flush();
}
@Override
public void sendPacket(Object rawChannel, Object packet) {
Channel channel = (Channel) rawChannel;
//Don't send packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.pipeline().writeAndFlush(packet);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 retrooper and contributors
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion 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
@@ -20,13 +20,14 @@ package io.github.retrooper.packetevents.injector.modern;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.processor.PacketProcessorInternal;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import org.bukkit.entity.Player;
import java.util.logging.Level;
@ChannelHandler.Sharable
public class PlayerChannelHandlerModern extends ChannelDuplexHandler {
/**
* Associated player.
@@ -36,32 +37,29 @@ public class PlayerChannelHandlerModern extends ChannelDuplexHandler {
@Override
public void channelRead(final ChannelHandlerContext ctx, Object packet) throws Exception {
try {
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().read(player, ctx.channel(), packet);
if (data.packet != null) {
super.channelRead(ctx, data.packet);
PacketEvents.get().getInternalPacketProcessor().postRead(player, ctx.channel(), data.packet);
}
} catch (Throwable t) {
PacketEvents.get().getPlugin().getLogger().log(Level.SEVERE, "Unable to handle an incoming packet ", t.getMessage());
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().read(player, ctx.channel(), packet);
if (data.packet != null) {
super.channelRead(ctx, data.packet);
PacketEvents.get().getInternalPacketProcessor().postRead(player, ctx.channel(), data.packet);
}
}
@Override
public void write(final ChannelHandlerContext ctx, Object packet, final ChannelPromise promise) throws Exception {
try {
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().write(player, ctx.channel(), packet);
if (data.postAction != null) {
promise.addListener(f -> {
data.postAction.run();
});
}
if (data.packet != null) {
super.write(ctx, data.packet, promise);
PacketEvents.get().getInternalPacketProcessor().postWrite(player, ctx.channel(), data.packet);
}
} catch (Throwable t) {
PacketEvents.get().getPlugin().getLogger().log(Level.SEVERE, "Unable to handle an outgoing packet ", t.getMessage());
if (packet instanceof ByteBuf) {
//Ignore bytebufs!
super.write(ctx, packet, promise);
return;
}
PacketProcessorInternal.PacketData data = PacketEvents.get().getInternalPacketProcessor().write(player, ctx.channel(), packet);
if (data.postAction != null) {
promise.addListener(f -> {
data.postAction.run();
});
}
if (data.packet != null) {
super.write(ctx, data.packet, promise);
PacketEvents.get().getInternalPacketProcessor().postWrite(player, ctx.channel(), data.packet);
}
}
}
@@ -25,6 +25,7 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.list.ListWrapper;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
@@ -73,10 +74,10 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
@Override
public void inject() {
try {
if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
/* if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
PaperChannelInjector.setPaperChannelInitializeListener();
return;
}
}*/
Object serverConnection = NMSUtils.getMinecraftServerConnection();
for (Field field : serverConnection.getClass().getDeclaredFields()) {
field.setAccessible(true);
@@ -128,12 +129,17 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
List<Object> networkManagers = NMSUtils.getNetworkManagers();
synchronized (networkManagers) {
for (Object networkManager : networkManagers) {
WrappedPacket networkManagerWrapper = new WrappedPacket(new NMSPacket(networkManager));
WrappedPacket networkManagerWrapper = new WrappedPacket(new NMSPacket(networkManager), NMSUtils.networkManagerClass);
Channel channel = (Channel) networkManagerWrapper.readObject(0, NMSUtils.nettyChannelClass);
if (channel == null) {
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
continue;
}
if (channel.pipeline().get(PacketEvents.get().getHandlerName()) != null) {
channel.pipeline().remove(PacketEvents.get().getHandlerName());
}
if (channel.pipeline().get("packet_handler") != null) {
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), new PlayerChannelHandlerModern());
}
@@ -191,13 +197,13 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
@Override
public void eject() {
// TODO: Uninject from players currently online to prevent protocol lib issues.
if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
/* if (PaperChannelInjector.PAPER_INJECTION_METHOD) {
try {
PaperChannelInjector.removePaperChannelInitializeListener();
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
}*/
Field childHandlerField = null;
for (ChannelFuture future : injectedFutures) {
List<String> names = future.channel().pipeline().names();
@@ -231,7 +237,7 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
childHandlerField.set(bootstrapAcceptor, ((PEChannelInitializerModern) oldInit).getOldChannelInitializer());
}
} catch (Exception e) {
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!");
}
}
injectedFutures.clear();
@@ -247,7 +253,7 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
}
} catch (IllegalAccessException e) {
PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
//PacketEvents.get().getPlugin().getLogger().severe("PacketEvents failed to eject the injection handler! Please reboot!!");
}
}
@@ -266,9 +272,8 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
public void ejectPlayer(Player player) {
Object channel = PacketEvents.get().getPlayerUtils().getChannel(player);
if (channel != null) {
Channel chnl = (Channel) channel;
try {
chnl.pipeline().remove(PacketEvents.get().getHandlerName());
((Channel)channel).pipeline().remove(PacketEvents.get().getHandlerName());
} catch (Exception ignored) {
}
}
@@ -284,9 +289,36 @@ public class EarlyChannelInjectorModern implements EarlyInjector {
return handler != null && handler.player != null;
}
@Override
public void writePacket(Object ch, Object rawNMSPacket) {
Channel channel = (Channel) ch;
//Don't write packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.write(rawNMSPacket);
}
@Override
public void flushPackets(Object ch) {
Channel channel = (Channel) ch;
//Don't flush packets for fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.flush();
}
@Override
public void sendPacket(Object ch, Object rawNMSPacket) {
Channel channel = (Channel) ch;
//Don't send packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.writeAndFlush(rawNMSPacket);
}
@@ -1,6 +1,6 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 retrooper and contributors
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion 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
@@ -20,6 +20,7 @@ package io.github.retrooper.packetevents.injector.modern.early;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.injector.modern.PlayerChannelHandlerModern;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
@@ -36,11 +37,16 @@ public class PEChannelInitializerModern extends ChannelInitializer<Channel> {
}
public static void postInitChannel(Channel channel) {
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
PlayerChannelHandlerModern channelHandler = new PlayerChannelHandlerModern();
if (channel.pipeline().get("packet_handler") != null) {
String handlerName = PacketEvents.get().getHandlerName();
if (channel.pipeline().get(handlerName) != null) {
PacketEvents.get().getPlugin().getLogger().warning("[PacketEvents] Attempted to initialize a channel twice!");
//Just ignore this to support latest ProtocolLib snapshots.
//PacketEvents.get().getPlugin().getLogger().warning("[PacketEvents] Attempted to initialize a channel twice!");
} else {
channel.pipeline().addBefore("packet_handler", handlerName, channelHandler);
}
@@ -1,67 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion 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 io.github.retrooper.packetevents.injector.modern.early;
import io.github.retrooper.packetevents.PacketEvents;
import io.netty.channel.Channel;
import net.kyori.adventure.key.Key;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class PaperChannelInjector {
public static final boolean PAPER_INJECTION_METHOD = hasPaperInjectionMethod();
private PaperChannelInjector() {
}
public static void setPaperChannelInitializeListener() throws ReflectiveOperationException {
// Call io.papermc.paper.network.ChannelInitializeListenerHolder.addListener(net.kyori.adventure.key.Key, io.papermc.paper.network.ChannelInitializeListener)
// Create an interface proxy of ChannelInitializeListener
Class<?> listenerClass = Class.forName("io.papermc.paper.network.ChannelInitializeListener");
Object channelInitializeListener = Proxy.newProxyInstance(EarlyChannelInjectorModern.class.getClassLoader(), new Class[]{listenerClass}, (proxy, method, args) -> {
if (method.getName().equals("afterInitChannel")) {
PEChannelInitializerModern.postInitChannel((Channel) args[0]);
return null;
}
return method.invoke(proxy, args);
});
Class<?> holderClass = Class.forName("io.papermc.paper.network.ChannelInitializeListenerHolder");
Method addListenerMethod = holderClass.getDeclaredMethod("addListener", Key.class, listenerClass);
Key key = Key.key(PacketEvents.get().getHandlerName().toLowerCase(), "injector");
addListenerMethod.invoke(null, key, channelInitializeListener);
}
public static void removePaperChannelInitializeListener() throws ReflectiveOperationException {
Class<?> holderClass = Class.forName("io.papermc.paper.network.ChannelInitializeListenerHolder");
Method addListenerMethod = holderClass.getDeclaredMethod("removeListener", Key.class);
Key key = Key.key(PacketEvents.get().getHandlerName().toLowerCase(), "injector");
addListenerMethod.invoke(null, key);
}
private static boolean hasPaperInjectionMethod() {
try {
Class.forName("io.papermc.paper.network.ChannelInitializeListener");
return true;
} catch (ReflectiveOperationException e) {
return false;
}
}
}
@@ -21,6 +21,7 @@ package io.github.retrooper.packetevents.injector.modern.late;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.injector.LateInjector;
import io.github.retrooper.packetevents.injector.modern.PlayerChannelHandlerModern;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import io.netty.channel.Channel;
import org.bukkit.entity.Player;
@@ -40,16 +41,19 @@ public class LateChannelInjectorModern implements LateInjector {
PlayerChannelHandlerModern playerChannelHandlerModern = new PlayerChannelHandlerModern();
playerChannelHandlerModern.player = player;
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerModern);
if (channel != null) {
channel.eventLoop().execute(() -> {
channel.pipeline().addBefore("packet_handler", PacketEvents.get().getHandlerName(), playerChannelHandlerModern);
});
}
}
@Override
public void ejectPlayer(Player player) {
Object channel = PacketEvents.get().getPlayerUtils().getChannel(player);
if (channel != null) {
Channel chnl = (Channel) channel;
try {
chnl.pipeline().remove(PacketEvents.get().getHandlerName());
((Channel) channel).pipeline().remove(PacketEvents.get().getHandlerName());
} catch (Exception ex) {
}
@@ -59,12 +63,39 @@ public class LateChannelInjectorModern implements LateInjector {
@Override
public boolean hasInjected(Player player) {
Channel channel = (Channel) PacketEvents.get().getPlayerUtils().getChannel(player);
return channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
return channel != null && channel.pipeline().get(PacketEvents.get().getHandlerName()) != null;
}
@Override
public void writePacket(Object ch, Object rawNMSPacket) {
Channel channel = (Channel) ch;
//Don't write packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.write(rawNMSPacket);
}
@Override
public void flushPackets(Object ch) {
Channel channel = (Channel) ch;
//Don't flush packets for fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.flush();
}
@Override
public void sendPacket(Object rawChannel, Object packet) {
Channel channel = (Channel) rawChannel;
//Don't send packets to fake channels
if (channel == null || ClassUtil.getClassSimpleName(channel.getClass()).equals("FakeChannel")
|| ClassUtil.getClassSimpleName(channel.getClass()).equals("SpoofedChannel")) {
return;
}
channel.pipeline().writeAndFlush(packet);
}
}
@@ -23,5 +23,5 @@ package io.github.retrooper.packetevents.packettype;
* @since 1.8
*/
public enum PacketState {
STATUS, HANDSHAKING, LOGIN, PLAY
STATUS, HANDSHAKING, LOGIN, CONFIG, PLAY
}
@@ -39,6 +39,7 @@ public class PacketType {
*/
public static final byte INVALID = -128;
public static final Map<Class<?>, Byte> packetIDMap = new IdentityHashMap<>();
private static final boolean isNine = ServerVersion.getVersion().isNewerThanOrEquals(ServerVersion.v_1_9);
private static void insertPacketID(Class<?> cls, byte packetID) {
if (cls != null) {
@@ -196,7 +197,7 @@ public class PacketType {
ADVANCEMENTS = -81, TR_SEL = -80, BEACON = -79, HELD_ITEM_SLOT = -78,
SET_COMMAND_BLOCK = -77, SET_COMMAND_MINECART = -76, SET_CREATIVE_SLOT = -75, SET_JIGSAW = -74,
STRUCT = -73, UPDATE_SIGN = -72, ARM_ANIMATION = -71, SPECTATE = -70,
USE_ITEM = -69, BLOCK_PLACE = -68;
USE_ITEM = -69, BLOCK_PLACE = -68, PONG = 28;
private static void load() {
insertPacketID(PacketTypeClasses.Play.Client.TELEPORT_ACCEPT, TELEPORT_ACCEPT);
@@ -220,7 +221,7 @@ public class PacketType {
insertPacketID(PacketTypeClasses.Play.Client.POSITION, POSITION);
insertPacketID(PacketTypeClasses.Play.Client.POSITION_LOOK, POSITION_LOOK);
insertPacketID(PacketTypeClasses.Play.Client.LOOK, LOOK);
insertPacketID(PacketTypeClasses.Play.Client.FLYING, FLYING);
insertPacketID(PacketTypeClasses.Play.Client.GROUND, FLYING);
insertPacketID(PacketTypeClasses.Play.Client.VEHICLE_MOVE, VEHICLE_MOVE);
insertPacketID(PacketTypeClasses.Play.Client.BOAT_MOVE, BOAT_MOVE);
insertPacketID(PacketTypeClasses.Play.Client.PICK_ITEM, PICK_ITEM);
@@ -246,6 +247,7 @@ public class PacketType {
insertPacketID(PacketTypeClasses.Play.Client.SPECTATE, SPECTATE);
insertPacketID(PacketTypeClasses.Play.Client.USE_ITEM, USE_ITEM);
insertPacketID(PacketTypeClasses.Play.Client.BLOCK_PLACE, BLOCK_PLACE);
insertPacketID(PacketTypeClasses.Play.Client.PONG, PONG);
}
/**
@@ -285,10 +287,7 @@ public class PacketType {
* @return Has the client placed a block?
*/
public static boolean isBlockPlace(final byte packetID) {
final ServerVersion version = PacketEvents.get().getServerUtils().getVersion();
return version.isNewerThan(ServerVersion.v_1_8_8) ?
packetID == PacketType.Play.Client.USE_ITEM
: packetID == PacketType.Play.Client.BLOCK_PLACE;
return isNine ? packetID == PacketType.Play.Client.USE_ITEM : packetID == PacketType.Play.Client.BLOCK_PLACE;
}
}
}
@@ -323,7 +322,11 @@ public class PacketType {
SCOREBOARD_SCORE = 10, SPAWN_POSITION = 11, UPDATE_TIME = 12, TITLE = 13,
ENTITY_SOUND = 14, NAMED_SOUND_EFFECT = 15, STOP_SOUND = 16, PLAYER_LIST_HEADER_FOOTER = 17,
NBT_QUERY = 18, COLLECT = 19, ENTITY_TELEPORT = 20, ADVANCEMENTS = 21, UPDATE_ATTRIBUTES = 22,
ENTITY_EFFECT = 23, RECIPE_UPDATE = 24, TAGS = 25, MAP_CHUNK_BULK = 26, NAMED_ENTITY_SPAWN = 27;
ENTITY_EFFECT = 23, RECIPE_UPDATE = 24, TAGS = 25, MAP_CHUNK_BULK = 26, NAMED_ENTITY_SPAWN = 27, PING = 29,
ADD_VIBRATION_SIGNAL = 30, CLEAR_TITLES = 31, INITIALIZE_BORDER = 32, PLAYER_COMBAT_END = 33,
PLAYER_COMBAT_ENTER = 34, PLAYER_COMBAT_KILL = 35, SET_ACTIONBAR_TEXT = 36, SET_BORDER_CENTER = 37,
SET_BORDER_LERP_SIZE = 38, SET_BORDER_SIZE = 39, SET_BORDER_WARNING_DELAY = 40, SET_BORDER_WARNING_DISTANCE = 41,
SET_SUBTITLE_TEXT = 42, SET_TITLES_ANIMATION = 43, SET_TITLE_TEXT = 44, SYSTEM_CHAT = 45;
private static void load() {
insertPacketID(PacketTypeClasses.Play.Server.SPAWN_ENTITY, SPAWN_ENTITY);
@@ -340,7 +343,6 @@ public class PacketType {
insertPacketID(PacketTypeClasses.Play.Server.BLOCK_ACTION, BLOCK_ACTION);
insertPacketID(PacketTypeClasses.Play.Server.BLOCK_CHANGE, BLOCK_CHANGE);
insertPacketID(PacketTypeClasses.Play.Server.BOSS, BOSS);
insertPacketID(PacketTypeClasses.Play.Server.SPAWN_ENTITY, SPAWN_ENTITY);
insertPacketID(PacketTypeClasses.Play.Server.SERVER_DIFFICULTY, SERVER_DIFFICULTY);
insertPacketID(PacketTypeClasses.Play.Server.CHAT, CHAT);
insertPacketID(PacketTypeClasses.Play.Server.MULTI_BLOCK_CHANGE, MULTI_BLOCK_CHANGE);
@@ -363,7 +365,6 @@ public class PacketType {
insertPacketID(PacketTypeClasses.Play.Server.KEEP_ALIVE, KEEP_ALIVE);
insertPacketID(PacketTypeClasses.Play.Server.MAP_CHUNK, MAP_CHUNK);
insertPacketID(PacketTypeClasses.Play.Server.WORLD_EVENT, WORLD_EVENT);
insertPacketID(PacketTypeClasses.Play.Server.WORLD_EVENT, SPAWN_ENTITY);
insertPacketID(PacketTypeClasses.Play.Server.WORLD_PARTICLES, WORLD_PARTICLES);
insertPacketID(PacketTypeClasses.Play.Server.LIGHT_UPDATE, LIGHT_UPDATE);
insertPacketID(PacketTypeClasses.Play.Server.LOGIN, LOGIN);
@@ -423,6 +424,23 @@ public class PacketType {
insertPacketID(PacketTypeClasses.Play.Server.TAGS, TAGS);
insertPacketID(PacketTypeClasses.Play.Server.MAP_CHUNK_BULK, MAP_CHUNK_BULK);
insertPacketID(PacketTypeClasses.Play.Server.NAMED_ENTITY_SPAWN, NAMED_ENTITY_SPAWN);
insertPacketID(PacketTypeClasses.Play.Server.PING, PING);
insertPacketID(PacketTypeClasses.Play.Server.ADD_VIBRATION_SIGNAL, ADD_VIBRATION_SIGNAL);
insertPacketID(PacketTypeClasses.Play.Server.CLEAR_TITLES, CLEAR_TITLES );
insertPacketID(PacketTypeClasses.Play.Server.INITIALIZE_BORDER, INITIALIZE_BORDER);
insertPacketID(PacketTypeClasses.Play.Server.PLAYER_COMBAT_END, PLAYER_COMBAT_END);
insertPacketID(PacketTypeClasses.Play.Server.PLAYER_COMBAT_ENTER, PLAYER_COMBAT_ENTER);
insertPacketID(PacketTypeClasses.Play.Server.PLAYER_COMBAT_KILL, PLAYER_COMBAT_KILL);
insertPacketID(PacketTypeClasses.Play.Server.SET_ACTIONBAR_TEXT, SET_ACTIONBAR_TEXT);
insertPacketID(PacketTypeClasses.Play.Server.SET_BORDER_CENTER, SET_BORDER_CENTER);
insertPacketID(PacketTypeClasses.Play.Server.SET_BORDER_LERP_SIZE, SET_BORDER_LERP_SIZE);
insertPacketID(PacketTypeClasses.Play.Server.SET_BORDER_SIZE, SET_BORDER_SIZE);
insertPacketID(PacketTypeClasses.Play.Server.SET_BORDER_WARNING_DELAY, SET_BORDER_WARNING_DELAY);
insertPacketID(PacketTypeClasses.Play.Server.SET_BORDER_WARNING_DISTANCE, SET_BORDER_WARNING_DISTANCE);
insertPacketID(PacketTypeClasses.Play.Server.SET_SUBTITLE_TEXT, SET_SUBTITLE_TEXT);
insertPacketID(PacketTypeClasses.Play.Server.SET_TITLES_ANIMATION, SET_TITLES_ANIMATION);
insertPacketID(PacketTypeClasses.Play.Server.SET_TITLE_TEXT, SET_TITLE_TEXT);
insertPacketID(PacketTypeClasses.Play.Server.SYSTEM_CHAT, SYSTEM_CHAT);
}
/**
@@ -19,7 +19,7 @@
package io.github.retrooper.packetevents.packettype;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
@@ -40,61 +40,96 @@ public class PacketTypeClasses {
public static class Status {
public static class Client {
private static String PREFIX;
public static Class<?> START, PING;
public static void load() {
Client.START = NMSUtils.getNMSClassWithoutException("PacketStatusInStart");
Client.PING = NMSUtils.getNMSClassWithoutException("PacketStatusInPing");
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
PREFIX = "net.minecraft.network.protocol.status.";
}
else {
PREFIX = ServerVersion.getNMSDirectory();
}
Client.START = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusInStart");
Client.PING = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusInPing");
}
}
public static class Server {
private static String PREFIX;
public static Class<?> PONG, SERVER_INFO;
public static void load() {
Server.PONG = NMSUtils.getNMSClassWithoutException("PacketStatusOutPong");
Server.SERVER_INFO = NMSUtils.getNMSClassWithoutException("PacketStatusOutServerInfo");
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
PREFIX = "net.minecraft.network.protocol.status.";
}
else {
PREFIX = ServerVersion.getNMSDirectory();
}
Server.PONG = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusOutPong");
Server.SERVER_INFO = Reflection.getClassByNameWithoutException(PREFIX + "PacketStatusOutServerInfo");
}
}
}
public static class Handshaking {
public static class Client {
private static String PREFIX;
public static Class<?> SET_PROTOCOL;
public static void load() {
Handshaking.Client.SET_PROTOCOL = NMSUtils.getNMSClassWithoutException("PacketHandshakingInSetProtocol");
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
PREFIX = "net.minecraft.network.protocol.handshake.";
}
else {
PREFIX = ServerVersion.getNMSDirectory();
}
Handshaking.Client.SET_PROTOCOL = Reflection.getClassByNameWithoutException(PREFIX + "PacketHandshakingInSetProtocol");
}
}
}
public static class Login {
public static class Client {
private static String PREFIX;
public static Class<?> CUSTOM_PAYLOAD, START, ENCRYPTION_BEGIN;
public static void load() {
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
PREFIX = "net.minecraft.network.protocol.login.";
}
else {
PREFIX = ServerVersion.getNMSDirectory();
}
//In and Out custom payload login packets have been here since 1.13
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_13)) {
Client.CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginInCustomPayload");
Client.CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginInCustomPayload");
}
Client.START = NMSUtils.getNMSClassWithoutException("PacketLoginInStart");
Client.ENCRYPTION_BEGIN = NMSUtils.getNMSClassWithoutException("PacketLoginInEncryptionBegin");
Client.START = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginInStart");
Client.ENCRYPTION_BEGIN = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginInEncryptionBegin");
}
}
public static class Server {
private static String PREFIX;
public static Class<?> CUSTOM_PAYLOAD, DISCONNECT, ENCRYPTION_BEGIN, SUCCESS, SET_COMPRESSION;
public static void load() {
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
PREFIX = "net.minecraft.network.protocol.login.";
}
else {
PREFIX = ServerVersion.getNMSDirectory();
}
//In and Out custom payload login packets have been here since 1.13
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_13)) {
Server.CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException("PacketLoginOutCustomPayload");
Server.CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginOutCustomPayload");
}
Server.DISCONNECT = NMSUtils.getNMSClassWithoutException("PacketLoginOutDisconnect");
Server.ENCRYPTION_BEGIN = NMSUtils.getNMSClassWithoutException("PacketLoginOutEncryptionBegin");
Server.SUCCESS = NMSUtils.getNMSClassWithoutException("PacketLoginOutSuccess");
Server.DISCONNECT = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginOutDisconnect");
Server.ENCRYPTION_BEGIN = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginOutEncryptionBegin");
Server.SUCCESS = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginOutSuccess");
if (PacketEvents.get().getServerUtils().getVersion().isNewerThan(ServerVersion.v_1_7_10)) {
Server.SET_COMPRESSION = NMSUtils.getNMSClassWithoutException("PacketLoginOutSetCompression");
Server.SET_COMPRESSION = Reflection.getClassByNameWithoutException(PREFIX + "PacketLoginOutSetCompression");
}
}
}
@@ -102,8 +137,8 @@ public class PacketTypeClasses {
public static class Play {
public static class Client {
private static final String PREFIX = "PacketPlayIn";
public static Class<?> FLYING, POSITION, POSITION_LOOK, LOOK, CLIENT_COMMAND,
private static String COMMON_PREFIX, PREFIX, PREFIX_COMMON_STATES;
public static Class<?> FLYING, POSITION, POSITION_LOOK, LOOK, GROUND, CLIENT_COMMAND,
TRANSACTION, BLOCK_DIG, ENTITY_ACTION, USE_ENTITY,
WINDOW_CLICK, STEER_VEHICLE, CUSTOM_PAYLOAD, ARM_ANIMATION,
BLOCK_PLACE, USE_ITEM, ABILITIES, HELD_ITEM_SLOT,
@@ -113,76 +148,118 @@ public class PacketTypeClasses {
JIGSAW_GENERATE, DIFFICULTY_LOCK, VEHICLE_MOVE, BOAT_MOVE, PICK_ITEM,
AUTO_RECIPE, RECIPE_DISPLAYED, ITEM_NAME, RESOURCE_PACK_STATUS,
ADVANCEMENTS, TR_SEL, BEACON, SET_COMMAND_BLOCK,
SET_COMMAND_MINECART, SET_JIGSAW, STRUCT, UPDATE_SIGN, SPECTATE;
SET_COMMAND_MINECART, SET_JIGSAW, STRUCT, UPDATE_SIGN, SPECTATE, PONG;
/**
* Initiate all server-bound play packet classes.
*/
public static void load() {
FLYING = NMSUtils.getNMSClassWithoutException(PREFIX + "Flying");
try {
POSITION = NMSUtils.getNMSClass(PREFIX + "Position");
POSITION_LOOK = NMSUtils.getNMSClass(PREFIX + "PositionLook");
LOOK = NMSUtils.getNMSClass(PREFIX + "Look");
} catch (Exception e) {
POSITION = SubclassUtil.getSubClass(FLYING, PREFIX + "Position");
POSITION_LOOK = SubclassUtil.getSubClass(FLYING, PREFIX + "PositionLook");
LOOK = SubclassUtil.getSubClass(FLYING, PREFIX + "Look");
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
PREFIX = "net.minecraft.network.protocol.game.";
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_20_2)) {
PREFIX_COMMON_STATES = "net.minecraft.network.protocol.common.";
}
}
else {
PREFIX = ServerVersion.getNMSDirectory();
}
COMMON_PREFIX = PREFIX + "PacketPlayIn";
FLYING = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Flying");
try {
SETTINGS = NMSUtils.getNMSClass(PREFIX + "Settings");
ENCHANT_ITEM = NMSUtils.getNMSClass(PREFIX + "EnchantItem");
POSITION = Class.forName(COMMON_PREFIX + "Position");
POSITION_LOOK = Class.forName(COMMON_PREFIX + "PositionLook");
LOOK = Class.forName(COMMON_PREFIX + "Look");
} catch (ClassNotFoundException ex) {
POSITION = SubclassUtil.getSubClass(FLYING,"PacketPlayInPosition");
POSITION_LOOK = SubclassUtil.getSubClass(FLYING, "PacketPlayInPositionLook");
LOOK = SubclassUtil.getSubClass(FLYING, "PacketPlayInLook");
}
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
GROUND = SubclassUtil.getSubClass(FLYING, "d");
if (GROUND == null) {
GROUND = SubclassUtil.getSubClass(FLYING, 0);
}
if (POSITION == null) {
POSITION = SubclassUtil.getSubClass(FLYING, 2);
}
if (POSITION_LOOK == null) {
POSITION_LOOK = SubclassUtil.getSubClass(FLYING, 3);
}
CLIENT_COMMAND = NMSUtils.getNMSClass(PREFIX + "ClientCommand");
TRANSACTION = NMSUtils.getNMSClass(PREFIX + "Transaction");
BLOCK_DIG = NMSUtils.getNMSClass(PREFIX + "BlockDig");
ENTITY_ACTION = NMSUtils.getNMSClass(PREFIX + "EntityAction");
USE_ENTITY = NMSUtils.getNMSClass(PREFIX + "UseEntity");
WINDOW_CLICK = NMSUtils.getNMSClass(PREFIX + "WindowClick");
STEER_VEHICLE = NMSUtils.getNMSClass(PREFIX + "SteerVehicle");
CUSTOM_PAYLOAD = NMSUtils.getNMSClass(PREFIX + "CustomPayload");
ARM_ANIMATION = NMSUtils.getNMSClass(PREFIX + "ArmAnimation");
ABILITIES = NMSUtils.getNMSClass(PREFIX + "Abilities");
HELD_ITEM_SLOT = NMSUtils.getNMSClass(PREFIX + "HeldItemSlot");
CLOSE_WINDOW = NMSUtils.getNMSClass(PREFIX + "CloseWindow");
TAB_COMPLETE = NMSUtils.getNMSClass(PREFIX + "TabComplete");
CHAT = NMSUtils.getNMSClass(PREFIX + "Chat");
SET_CREATIVE_SLOT = NMSUtils.getNMSClass(PREFIX + "SetCreativeSlot");
KEEP_ALIVE = NMSUtils.getNMSClass(PREFIX + "KeepAlive");
UPDATE_SIGN = NMSUtils.getNMSClassWithoutException(PREFIX + "UpdateSign");
if (LOOK == null) {
LOOK = SubclassUtil.getSubClass(FLYING, 1);
}
}
else {
GROUND = FLYING;
}
//This packet does not exist in the 1.17+ protocol
TRANSACTION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Transaction");
//This packet was added in 1.17 protocol
PONG = Reflection.getClassByNameWithoutException(PREFIX + "ServerboundPongPacket");
if (PONG == null) {
PONG = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundPongPacket");
}
SETTINGS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Settings");
if (SETTINGS == null) {
SETTINGS = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundClientInformationPacket");
}
try {
ENCHANT_ITEM = Class.forName(COMMON_PREFIX + "EnchantItem");
CLIENT_COMMAND = Class.forName(COMMON_PREFIX + "ClientCommand");
BLOCK_DIG = Class.forName(COMMON_PREFIX + "BlockDig");
ENTITY_ACTION = Class.forName(COMMON_PREFIX + "EntityAction");
USE_ENTITY = Class.forName(COMMON_PREFIX + "UseEntity");
WINDOW_CLICK = Class.forName(COMMON_PREFIX + "WindowClick");
STEER_VEHICLE = Class.forName(COMMON_PREFIX + "SteerVehicle");
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CustomPayload");
if (CUSTOM_PAYLOAD == null) {
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundCustomPayloadPacket");
}
ARM_ANIMATION = Class.forName(COMMON_PREFIX + "ArmAnimation");
ABILITIES = Class.forName(COMMON_PREFIX + "Abilities");
HELD_ITEM_SLOT = Class.forName(COMMON_PREFIX + "HeldItemSlot");
CLOSE_WINDOW = Class.forName(COMMON_PREFIX + "CloseWindow");
TAB_COMPLETE = Class.forName(COMMON_PREFIX + "TabComplete");
CHAT = Class.forName(COMMON_PREFIX + "Chat");
SET_CREATIVE_SLOT = Class.forName(COMMON_PREFIX + "SetCreativeSlot");
KEEP_ALIVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "KeepAlive");
if (KEEP_ALIVE == null) {
KEEP_ALIVE = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ServerboundKeepAlivePacket");
}
UPDATE_SIGN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "UpdateSign");
TELEPORT_ACCEPT = NMSUtils.getNMSClassWithoutException(PREFIX + "TeleportAccept");
TILE_NBT_QUERY = NMSUtils.getNMSClassWithoutException(PREFIX + "TileNBTQuery");
DIFFICULTY_CHANGE = NMSUtils.getNMSClassWithoutException(PREFIX + "DifficultyChange");
B_EDIT = NMSUtils.getNMSClassWithoutException(PREFIX + "BEdit");
ENTITY_NBT_QUERY = NMSUtils.getNMSClassWithoutException(PREFIX + "EntityNBTQuery");
JIGSAW_GENERATE = NMSUtils.getNMSClassWithoutException(PREFIX + "JigsawGenerate");
DIFFICULTY_LOCK = NMSUtils.getNMSClassWithoutException(PREFIX + "DifficultyLock");
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(PREFIX + "VehicleMove");
BOAT_MOVE = NMSUtils.getNMSClassWithoutException(PREFIX + "BoatMove");
PICK_ITEM = NMSUtils.getNMSClassWithoutException(PREFIX + "PickItem");
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(PREFIX + "AutoRecipe");
RECIPE_DISPLAYED = NMSUtils.getNMSClassWithoutException(PREFIX + "RecipeDisplayed");
ITEM_NAME = NMSUtils.getNMSClassWithoutException(PREFIX + "ItemName");
TELEPORT_ACCEPT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "TeleportAccept");
TILE_NBT_QUERY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "TileNBTQuery");
DIFFICULTY_CHANGE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "DifficultyChange");
B_EDIT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "BEdit");
ENTITY_NBT_QUERY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityNBTQuery");
JIGSAW_GENERATE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "JigsawGenerate");
DIFFICULTY_LOCK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "DifficultyLock");
VEHICLE_MOVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "VehicleMove");
BOAT_MOVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "BoatMove");
PICK_ITEM = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "PickItem");
AUTO_RECIPE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "AutoRecipe");
RECIPE_DISPLAYED = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RecipeDisplayed");
ITEM_NAME = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ItemName");
//1.8+
RESOURCE_PACK_STATUS = NMSUtils.getNMSClassWithoutException(PREFIX + "ResourcePackStatus");
RESOURCE_PACK_STATUS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ResourcePackStatus");
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(PREFIX + "Advancements");
TR_SEL = NMSUtils.getNMSClassWithoutException(PREFIX + "TrSel");
BEACON = NMSUtils.getNMSClassWithoutException(PREFIX + "Beacon");
SET_COMMAND_BLOCK = NMSUtils.getNMSClassWithoutException(PREFIX + "SetCommandBlock");
SET_COMMAND_MINECART = NMSUtils.getNMSClassWithoutException(PREFIX + "SetCommandMinecart");
SET_JIGSAW = NMSUtils.getNMSClassWithoutException(PREFIX + "SetJigsaw");
STRUCT = NMSUtils.getNMSClassWithoutException(PREFIX + "Struct");
SPECTATE = NMSUtils.getNMSClassWithoutException(PREFIX + "Spectate");
ADVANCEMENTS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Advancements");
TR_SEL = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "TrSel");
BEACON = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Beacon");
SET_COMMAND_BLOCK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SetCommandBlock");
SET_COMMAND_MINECART = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SetCommandMinecart");
SET_JIGSAW = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SetJigsaw");
STRUCT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Struct");
SPECTATE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Spectate");
} catch (Exception e) {
e.printStackTrace();
}
try {
BLOCK_PLACE = NMSUtils.getNMSClass(PREFIX + "BlockPlace");
USE_ITEM = NMSUtils.getNMSClass(PREFIX + "UseItem");
BLOCK_PLACE = Class.forName(COMMON_PREFIX + "BlockPlace");
USE_ITEM = Class.forName(COMMON_PREFIX + "UseItem");
} catch (Exception ignored) {
}
@@ -190,7 +267,7 @@ public class PacketTypeClasses {
}
public static class Server {
private static final String s = "PacketPlayOut";
private static String COMMON_PREFIX, PREFIX, PREFIX_COMMON_STATES;
public static Class<?> SPAWN_ENTITY, SPAWN_ENTITY_EXPERIENCE_ORB, SPAWN_ENTITY_WEATHER, SPAWN_ENTITY_LIVING,
SPAWN_ENTITY_PAINTING, SPAWN_ENTITY_SPAWN, ANIMATION, STATISTIC,
BLOCK_BREAK, BLOCK_BREAK_ANIMATION, TILE_ENTITY_DATA, BLOCK_ACTION,
@@ -213,115 +290,177 @@ public class PacketTypeClasses {
SCOREBOARD_SCORE, SPAWN_POSITION, UPDATE_TIME, TITLE,
ENTITY_SOUND, NAMED_SOUND_EFFECT, STOP_SOUND, PLAYER_LIST_HEADER_FOOTER,
NBT_QUERY, COLLECT, ENTITY_TELEPORT, ADVANCEMENTS, UPDATE_ATTRIBUTES,
ENTITY_EFFECT, RECIPE_UPDATE, TAGS, MAP_CHUNK_BULK, NAMED_ENTITY_SPAWN;
ENTITY_EFFECT, RECIPE_UPDATE, TAGS, MAP_CHUNK_BULK, NAMED_ENTITY_SPAWN, PING, ADD_VIBRATION_SIGNAL,
CLEAR_TITLES, INITIALIZE_BORDER, PLAYER_COMBAT_END, PLAYER_COMBAT_ENTER, PLAYER_COMBAT_KILL,
SET_ACTIONBAR_TEXT, SET_BORDER_CENTER, SET_BORDER_LERP_SIZE, SET_BORDER_SIZE, SET_BORDER_WARNING_DELAY,
SET_BORDER_WARNING_DISTANCE, SET_SUBTITLE_TEXT, SET_TITLES_ANIMATION, SET_TITLE_TEXT,
SYSTEM_CHAT;
/**
* Initiate all client-bound packet classes.
*/
public static void load() {
SPAWN_ENTITY = NMSUtils.getNMSClassWithoutException(s + "SpawnEntity");
SPAWN_ENTITY_EXPERIENCE_ORB = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityExperienceOrb");
SPAWN_ENTITY_WEATHER = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityWeather");
SPAWN_ENTITY_LIVING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityLiving");
SPAWN_ENTITY_PAINTING = NMSUtils.getNMSClassWithoutException(s + "SpawnEntityPainting");
SPAWN_ENTITY_SPAWN = NMSUtils.getNMSClassWithoutException(s + "SpawnEntitySpawn");
ANIMATION = NMSUtils.getNMSClassWithoutException(s + "Animation");
STATISTIC = NMSUtils.getNMSClassWithoutException(s + "Statistic");
BLOCK_BREAK = NMSUtils.getNMSClassWithoutException(s + "BlockBreak");
BLOCK_BREAK_ANIMATION = NMSUtils.getNMSClassWithoutException(s + "BlockBreakAnimation");
TILE_ENTITY_DATA = NMSUtils.getNMSClassWithoutException(s + "TileEntityData");
BLOCK_ACTION = NMSUtils.getNMSClassWithoutException(s + "BlockAction");
BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "BlockChange");
BOSS = NMSUtils.getNMSClassWithoutException(s + "Boss");
SERVER_DIFFICULTY = NMSUtils.getNMSClassWithoutException(s + "ServerDifficulty");
CHAT = NMSUtils.getNMSClassWithoutException(s + "Chat");
MULTI_BLOCK_CHANGE = NMSUtils.getNMSClassWithoutException(s + "MultiBlockChange");
TAB_COMPLETE = NMSUtils.getNMSClassWithoutException(s + "TabComplete");
COMMANDS = NMSUtils.getNMSClassWithoutException(s + "Commands");
TRANSACTION = NMSUtils.getNMSClassWithoutException(s + "Transaction");
CLOSE_WINDOW = NMSUtils.getNMSClassWithoutException(s + "CloseWindow");
WINDOW_ITEMS = NMSUtils.getNMSClassWithoutException(s + "WindowItems");
WINDOW_DATA = NMSUtils.getNMSClassWithoutException(s + "WindowData");
SET_SLOT = NMSUtils.getNMSClassWithoutException(s + "SetSlot");
SET_COOLDOWN = NMSUtils.getNMSClassWithoutException(s + "SetCooldown");
CUSTOM_PAYLOAD = NMSUtils.getNMSClassWithoutException(s + "CustomPayload");
CUSTOM_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "CustomSoundEffect");
KICK_DISCONNECT = NMSUtils.getNMSClassWithoutException(s + "KickDisconnect");
ENTITY_STATUS = NMSUtils.getNMSClassWithoutException(s + "EntityStatus");
EXPLOSION = NMSUtils.getNMSClassWithoutException(s + "Explosion");
UNLOAD_CHUNK = NMSUtils.getNMSClassWithoutException(s + "UnloadChunk");
GAME_STATE_CHANGE = NMSUtils.getNMSClassWithoutException(s + "GameStateChange");
OPEN_WINDOW_HORSE = NMSUtils.getNMSClassWithoutException(s + "OpenWindowHorse");
KEEP_ALIVE = NMSUtils.getNMSClassWithoutException(s + "KeepAlive");
MAP_CHUNK = NMSUtils.getNMSClassWithoutException(s + "MapChunk");
WORLD_EVENT = NMSUtils.getNMSClassWithoutException(s + "WorldEvent");
WORLD_PARTICLES = NMSUtils.getNMSClassWithoutException(s + "WorldParticles");
LIGHT_UPDATE = NMSUtils.getNMSClassWithoutException(s + "LightUpdate");
LOGIN = NMSUtils.getNMSClassWithoutException(s + "Login");
MAP = NMSUtils.getNMSClassWithoutException(s + "Map");
OPEN_WINDOW_MERCHANT = NMSUtils.getNMSClassWithoutException(s + "OpenWindowMerchant");
ENTITY = NMSUtils.getNMSClassWithoutException(s + "Entity");
REL_ENTITY_MOVE = SubclassUtil.getSubClass(ENTITY, s + "RelEntityMove");
REL_ENTITY_MOVE_LOOK = SubclassUtil.getSubClass(ENTITY, s + "RelEntityMoveLook");
ENTITY_LOOK = SubclassUtil.getSubClass(ENTITY, s + "EntityLook");
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_17)) {
PREFIX = "net.minecraft.network.protocol.game.";
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_20_2)) {
PREFIX_COMMON_STATES = "net.minecraft.network.protocol.common.";
}
}
else {
PREFIX = ServerVersion.getNMSDirectory();
}
COMMON_PREFIX = PREFIX + "PacketPlayOut";
SPAWN_ENTITY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnEntity");
SPAWN_ENTITY_EXPERIENCE_ORB = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnEntityExperienceOrb");
SPAWN_ENTITY_WEATHER = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnEntityWeather");
SPAWN_ENTITY_LIVING = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnEntityLiving");
SPAWN_ENTITY_PAINTING = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnEntityPainting");
SPAWN_ENTITY_SPAWN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnEntitySpawn");
ANIMATION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Animation");
STATISTIC = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Statistic");
BLOCK_BREAK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "BlockBreak");
BLOCK_BREAK_ANIMATION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "BlockBreakAnimation");
TILE_ENTITY_DATA = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "TileEntityData");
BLOCK_ACTION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "BlockAction");
BLOCK_CHANGE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "BlockChange");
BOSS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Boss");
SERVER_DIFFICULTY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ServerDifficulty");
CHAT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Chat");
if (CHAT == null) {
CHAT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundPlayerChatPacket");
}
MULTI_BLOCK_CHANGE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "MultiBlockChange");
TAB_COMPLETE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "TabComplete");
COMMANDS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Commands");
TRANSACTION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Transaction");
CLOSE_WINDOW = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CloseWindow");
WINDOW_ITEMS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "WindowItems");
WINDOW_DATA = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "WindowData");
SET_SLOT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SetSlot");
SET_COOLDOWN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SetCooldown");
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CustomPayload");
if (CUSTOM_PAYLOAD == null) {
CUSTOM_PAYLOAD = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundCustomPayloadPacket");
}
CUSTOM_SOUND_EFFECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CustomSoundEffect");
KICK_DISCONNECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "KickDisconnect");
if (KICK_DISCONNECT == null) {
KICK_DISCONNECT = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundDisconnectPacket");
}
ENTITY_STATUS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityStatus");
EXPLOSION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Explosion");
UNLOAD_CHUNK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "UnloadChunk");
GAME_STATE_CHANGE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "GameStateChange");
OPEN_WINDOW_HORSE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "OpenWindowHorse");
KEEP_ALIVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "KeepAlive");
if (KEEP_ALIVE == null) {
KEEP_ALIVE = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundKeepAlivePacket");
}
MAP_CHUNK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "MapChunk");
WORLD_EVENT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "WorldEvent");
WORLD_PARTICLES = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "WorldParticles");
LIGHT_UPDATE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "LightUpdate");
LOGIN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Login");
MAP = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Map");
OPEN_WINDOW_MERCHANT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "OpenWindowMerchant");
ENTITY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Entity");
REL_ENTITY_MOVE = SubclassUtil.getSubClass(ENTITY, "PacketPlayOutRelEntityMove");
REL_ENTITY_MOVE_LOOK = SubclassUtil.getSubClass(ENTITY, "PacketPlayOutRelEntityMoveLook");
ENTITY_LOOK = SubclassUtil.getSubClass(ENTITY, "PacketPlayOutEntityLook");
if (REL_ENTITY_MOVE == null) {
//is not a subclass and should be accessed normally
REL_ENTITY_MOVE = NMSUtils.getNMSClassWithoutException(s + "RelEntityMove");
REL_ENTITY_MOVE_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityMoveLook");
ENTITY_LOOK = NMSUtils.getNMSClassWithoutException(s + "RelEntityLook");
REL_ENTITY_MOVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RelEntityMove");
REL_ENTITY_MOVE_LOOK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RelEntityMoveLook");
ENTITY_LOOK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RelEntityLook");
if (REL_ENTITY_MOVE == null) {
REL_ENTITY_MOVE = SubclassUtil.getSubClass(ENTITY, 1);
}
if (REL_ENTITY_MOVE_LOOK == null) {
REL_ENTITY_MOVE_LOOK = SubclassUtil.getSubClass(ENTITY, 2);
}
if (ENTITY_LOOK == null) {
ENTITY_LOOK = SubclassUtil.getSubClass(ENTITY, 0);
}
}
VEHICLE_MOVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "VehicleMove");
OPEN_BOOK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "OpenBook");
OPEN_WINDOW = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "OpenWindow");
OPEN_SIGN_EDITOR = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "OpenSignEditor");
AUTO_RECIPE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "AutoRecipe");
ABILITIES = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Abilities");
COMBAT_EVENT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "CombatEvent");
PLAYER_INFO = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "PlayerInfo");
LOOK_AT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "LookAt");
POSITION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Position");
RECIPES = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Recipes");
ENTITY_DESTROY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityDestroy");
REMOVE_ENTITY_EFFECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RemoveEntityEffect");
RESOURCE_PACK_SEND = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ResourcePackSend");
RESPAWN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Respawn");
ENTITY_HEAD_ROTATION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityHeadRotation");
SELECT_ADVANCEMENT_TAB = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SelectAdvancementTab");
WORLD_BORDER = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "WorldBorder");
CAMERA = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Camera");
HELD_ITEM_SLOT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "HeldItemSlot");
VIEW_CENTRE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ViewCentre");
VIEW_DISTANCE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ViewDistance");
SCOREBOARD_DISPLAY_OBJECTIVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ScoreboardDisplayObjective");
ENTITY_METADATA = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityMetadata");
ATTACH_ENTITY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "AttachEntity");
ENTITY_VELOCITY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityVelocity");
ENTITY_EQUIPMENT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityEquipment");
EXPERIENCE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Experience");
UPDATE_HEALTH = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "UpdateHealth");
SCOREBOARD_OBJECTIVE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ScoreboardObjective");
MOUNT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Mount");
SCOREBOARD_TEAM = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ScoreboardTeam");
SCOREBOARD_SCORE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "ScoreboardScore");
SPAWN_POSITION = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "SpawnPosition");
UPDATE_TIME = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "UpdateTime");
TITLE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Title");
ENTITY_SOUND = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntitySound");
NAMED_SOUND_EFFECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "NamedSoundEffect");
STOP_SOUND = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "StopSound");
PLAYER_LIST_HEADER_FOOTER = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "PlayerListHeaderFooter");
NBT_QUERY = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "NBTQuery");
COLLECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Collect");
ENTITY_TELEPORT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityTeleport");
ADVANCEMENTS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Advancements");
UPDATE_ATTRIBUTES = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "UpdateAttributes");
ENTITY_EFFECT = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "EntityEffect");
RECIPE_UPDATE = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "RecipeUpdate");
TAGS = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "Tags");
MAP_CHUNK_BULK = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "MapChunkBulk");
NAMED_ENTITY_SPAWN = Reflection.getClassByNameWithoutException(COMMON_PREFIX + "NamedEntitySpawn");
//These packets were added in 1.17
PING = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundPingPacket");
if (PING == null) {
PING = Reflection.getClassByNameWithoutException(PREFIX_COMMON_STATES + "ClientboundPingPacket");
}
ADD_VIBRATION_SIGNAL = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundAddVibrationSignalPacket");
CLEAR_TITLES = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundClearTitlesPacket");
INITIALIZE_BORDER = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundInitializeBorderPacket");
PLAYER_COMBAT_END = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundPlayerCombatEndPacket");
PLAYER_COMBAT_ENTER = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundPlayerCombatEnterPacket");
PLAYER_COMBAT_KILL = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundPlayerCombatKillPacket");
SET_ACTIONBAR_TEXT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetActionBarTextPacket");
SET_BORDER_CENTER = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetBorderCenterPacket");
SET_BORDER_LERP_SIZE = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetBorderLerpSizePacket");
SET_BORDER_SIZE = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetBorderSizePacket");
SET_BORDER_WARNING_DELAY = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetBorderWarningDelayPacket");
SET_BORDER_WARNING_DISTANCE = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetBorderWarningDistancePacket");
SET_SUBTITLE_TEXT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetSubtitleTextPacket");
SET_TITLES_ANIMATION = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetTitlesAnimationPacket");
SET_TITLE_TEXT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSetTitleTextPacket");
SYSTEM_CHAT = Reflection.getClassByNameWithoutException(PREFIX + "ClientboundSystemChatPacket");
// 1.18+ only, doesn't follow the naming convention
if (MAP_CHUNK == null) {
MAP_CHUNK = Reflection.getClassByNameWithoutException("net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket");
}
VEHICLE_MOVE = NMSUtils.getNMSClassWithoutException(s + "VehicleMove");
OPEN_BOOK = NMSUtils.getNMSClassWithoutException(s + "OpenBook");
OPEN_WINDOW = NMSUtils.getNMSClassWithoutException(s + "OpenWindow");
OPEN_SIGN_EDITOR = NMSUtils.getNMSClassWithoutException(s + "OpenSignEditor");
AUTO_RECIPE = NMSUtils.getNMSClassWithoutException(s + "AutoRecipe");
ABILITIES = NMSUtils.getNMSClassWithoutException(s + "Abilities");
COMBAT_EVENT = NMSUtils.getNMSClassWithoutException(s + "CombatEvent");
PLAYER_INFO = NMSUtils.getNMSClassWithoutException(s + "PlayerInfo");
LOOK_AT = NMSUtils.getNMSClassWithoutException(s + "LookAt");
POSITION = NMSUtils.getNMSClassWithoutException(s + "Position");
RECIPES = NMSUtils.getNMSClassWithoutException(s + "Recipes");
ENTITY_DESTROY = NMSUtils.getNMSClassWithoutException(s + "EntityDestroy");
REMOVE_ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "RemoveEntityEffect");
RESOURCE_PACK_SEND = NMSUtils.getNMSClassWithoutException(s + "ResourcePackSend");
RESPAWN = NMSUtils.getNMSClassWithoutException(s + "Respawn");
ENTITY_HEAD_ROTATION = NMSUtils.getNMSClassWithoutException(s + "EntityHeadRotation");
SELECT_ADVANCEMENT_TAB = NMSUtils.getNMSClassWithoutException(s + "SelectAdvancementTab");
WORLD_BORDER = NMSUtils.getNMSClassWithoutException(s + "WorldBorder");
CAMERA = NMSUtils.getNMSClassWithoutException(s + "Camera");
HELD_ITEM_SLOT = NMSUtils.getNMSClassWithoutException(s + "HeldItemSlot");
VIEW_CENTRE = NMSUtils.getNMSClassWithoutException(s + "ViewCentre");
VIEW_DISTANCE = NMSUtils.getNMSClassWithoutException(s + "ViewDistance");
SCOREBOARD_DISPLAY_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardDisplayObjective");
ENTITY_METADATA = NMSUtils.getNMSClassWithoutException(s + "EntityMetadata");
ATTACH_ENTITY = NMSUtils.getNMSClassWithoutException(s + "AttachEntity");
ENTITY_VELOCITY = NMSUtils.getNMSClassWithoutException(s + "EntityVelocity");
ENTITY_EQUIPMENT = NMSUtils.getNMSClassWithoutException(s + "EntityEquipment");
EXPERIENCE = NMSUtils.getNMSClassWithoutException(s + "Experience");
UPDATE_HEALTH = NMSUtils.getNMSClassWithoutException(s + "UpdateHealth");
SCOREBOARD_OBJECTIVE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardObjective");
MOUNT = NMSUtils.getNMSClassWithoutException(s + "Mount");
SCOREBOARD_TEAM = NMSUtils.getNMSClassWithoutException(s + "ScoreboardTeam");
SCOREBOARD_SCORE = NMSUtils.getNMSClassWithoutException(s + "ScoreboardScore");
SPAWN_POSITION = NMSUtils.getNMSClassWithoutException(s + "SpawnPosition");
UPDATE_TIME = NMSUtils.getNMSClassWithoutException(s + "UpdateTime");
TITLE = NMSUtils.getNMSClassWithoutException(s + "Title");
ENTITY_SOUND = NMSUtils.getNMSClassWithoutException(s + "EntitySound");
NAMED_SOUND_EFFECT = NMSUtils.getNMSClassWithoutException(s + "NamedSoundEffect");
STOP_SOUND = NMSUtils.getNMSClassWithoutException(s + "StopSound");
PLAYER_LIST_HEADER_FOOTER = NMSUtils.getNMSClassWithoutException(s + "PlayerListHeaderFooter");
NBT_QUERY = NMSUtils.getNMSClassWithoutException(s + "NBTQuery");
COLLECT = NMSUtils.getNMSClassWithoutException(s + "Collect");
ENTITY_TELEPORT = NMSUtils.getNMSClassWithoutException(s + "EntityTeleport");
ADVANCEMENTS = NMSUtils.getNMSClassWithoutException(s + "Advancements");
UPDATE_ATTRIBUTES = NMSUtils.getNMSClassWithoutException(s + "UpdateAttributes");
ENTITY_EFFECT = NMSUtils.getNMSClassWithoutException(s + "EntityEffect");
RECIPE_UPDATE = NMSUtils.getNMSClassWithoutException(s + "RecipeUpdate");
TAGS = NMSUtils.getNMSClassWithoutException(s + "Tags");
MAP_CHUNK_BULK = NMSUtils.getNMSClassWithoutException(s + "MapChunkBulk");
NAMED_ENTITY_SPAWN = NMSUtils.getNMSClassWithoutException(s + "NamedEntitySpawn");
}
}
}
}
@@ -24,6 +24,8 @@ import io.github.retrooper.packetevents.exceptions.WrapperUnsupportedUsageExcept
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.api.WrapperPacketReader;
import io.github.retrooper.packetevents.packetwrappers.api.WrapperPacketWriter;
import io.github.retrooper.packetevents.utils.ConditionalValue;
import io.github.retrooper.packetevents.utils.MojangEitherUtil;
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.player.GameMode;
@@ -34,6 +36,7 @@ import io.github.retrooper.packetevents.utils.vector.Vector3i;
import io.github.retrooper.packetevents.utils.world.Difficulty;
import io.github.retrooper.packetevents.utils.world.Dimension;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -42,18 +45,16 @@ import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
import java.util.logging.Level;
public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
private static final Map<Class<? extends WrappedPacket>, Boolean> LOADED_WRAPPERS = new ConcurrentHashMap<>();
private static final Map<Class<?>, Map<Class<?>, Field[]>> FIELD_CACHE = new ConcurrentHashMap<>();
private static final Field[] EMPTY_FIELD_ARRAY = new Field[0];
private static byte isVersion_1_17 = -1;
public static ServerVersion version;
protected final NMSPacket packet;
private final Class<?> packetClass;
@@ -80,15 +81,15 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
}
private void load0() {
if (!isSupported()) {
throw new WrapperUnsupportedUsageException(getClass());
}
final Class<? extends WrappedPacket> clazz = getClass();
if (!LOADED_WRAPPERS.containsKey(clazz)) {
if (!isSupported()) {
throw new WrapperUnsupportedUsageException(getClass());
}
try {
load();
} catch (Exception ex) {
String wrapperName = ClassUtil.getClassSimpleName(getClass());
String wrapperName = ClassUtil.getClassSimpleName(clazz);
PacketEvents.get().getPlugin().getLogger()
.log(Level.SEVERE, "PacketEvents found an exception while loading the " + wrapperName + " packet wrapper. Please report this bug! Tell us about your server version, spigot and code(of you using the wrapper)", ex);
LOADED_WRAPPERS.put(clazz, false);
@@ -382,6 +383,9 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
public void writeAnyObject(int index, Object value) {
try {
Field f = packetClass.getDeclaredFields()[index];
if (!f.isAccessible()) {
f.setAccessible(true);
}
f.set(packet.getRawNMSPacket(), value);
} catch (Exception e) {
throw new WrapperFieldNotFoundException("PacketEvents failed to find any field indexed " + index + " in the " + ClassUtil.getClassSimpleName(packetClass) + " class!");
@@ -390,12 +394,15 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
@Override
public void writeEnumConstant(int index, Enum<?> enumConstant) {
write(enumConstant.getClass(), index, enumConstant);
try {
write(enumConstant.getClass(), index, enumConstant);
} catch (WrapperFieldNotFoundException ex) {
write(enumConstant.getDeclaringClass(), index, enumConstant);
}
}
public void write(Class<?> type, int index, Object value) throws WrapperFieldNotFoundException {
Field field = getField(type, index);
//Reflection.getFieldWithoutFinalModifier(field);
if (field == null) {
throw new WrapperFieldNotFoundException(packetClass, type, index);
}
@@ -409,9 +416,30 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
public Vector3i readBlockPosition(int index) {
Object blockPosObj = readObject(index, NMSUtils.blockPosClass);
try {
int x = (int) NMSUtils.getBlockPosX.invoke(blockPosObj);
int y = (int) NMSUtils.getBlockPosY.invoke(blockPosObj);
int z = (int) NMSUtils.getBlockPosZ.invoke(blockPosObj);
int x, y, z;
if (version.isNewerThanOrEquals(ServerVersion.v_1_20_5)) {
x = (int) NMSUtils.getBaseBlockPosX.get(blockPosObj);
y = (int) NMSUtils.getBaseBlockPosY.get(blockPosObj);
z = (int) NMSUtils.getBaseBlockPosZ.get(blockPosObj);
}
else {
x = (int) NMSUtils.getBlockPosX.invoke(blockPosObj);
y = (int) NMSUtils.getBlockPosY.invoke(blockPosObj);
z = (int) NMSUtils.getBlockPosZ.invoke(blockPosObj);
}
return new Vector3i(x, y, z);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
}
public Vector3i readSectionPosition(int index) {
Object blockPosObj = readObject(index, NMSUtils.sectionPositionClass);
try {
int x = (Integer) NMSUtils.getBlockPosX.invoke(blockPosObj);
int y = (Integer) NMSUtils.getBlockPosY.invoke(blockPosObj);
int z = (Integer) NMSUtils.getBlockPosZ.invoke(blockPosObj);
return new Vector3i(x, y, z);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
@@ -434,13 +462,19 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
write(NMSUtils.nmsItemStackClass, index, nmsItemStack);
}
@Nullable
public GameMode readGameMode(int index) {
Enum<?> enumConst = readEnumConstant(index, NMSUtils.enumGameModeClass);
return GameMode.valueOf(enumConst.name());
int targetIndex = enumConst.ordinal() - 1;
if (targetIndex == -1) {
return null;
}
return GameMode.values()[targetIndex];
}
public void writeGameMode(int index, GameMode gameMode) {
Enum<?> enumConst = EnumUtil.valueOf(NMSUtils.enumGameModeClass, gameMode.name());
public void writeGameMode(int index, @Nullable GameMode gameMode) {
int i = gameMode != null ? (gameMode.ordinal() + 1) : (0);
Enum<?> enumConst = EnumUtil.valueByIndex(NMSUtils.enumGameModeClass, i);
writeEnumConstant(index, enumConst);
}
@@ -487,6 +521,22 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
write(NMSUtils.iChatBaseComponentClass, index, iChatBaseComponent);
}
public String readMinecraftKey(int index) {
if (isVersion_1_17 == -1) {
isVersion_1_17 = (byte) (version.isNewerThanOrEquals(ServerVersion.v_1_17) ? 1 : 0);
}
int namespaceIndex = isVersion_1_17 == 1 ? 2 : 0;
int keyIndex = isVersion_1_17 == 1 ? 3 : 1;
Object minecraftKey = readObject(index, NMSUtils.minecraftKeyClass);
WrappedPacket minecraftKeyWrapper = new WrappedPacket(new NMSPacket(minecraftKey));
return minecraftKeyWrapper.readString(namespaceIndex) + ":" + minecraftKeyWrapper.readString(keyIndex);
}
public void writeMinecraftKey(int index, String content) {
Object minecraftKey = NMSUtils.generateMinecraftKeyNew(content);
write(NMSUtils.minecraftKeyClass, index, minecraftKey);
}
public List<Object> readList(int index) {
return read(index, List.class);
}
@@ -495,6 +545,34 @@ public class WrappedPacket implements WrapperPacketReader, WrapperPacketWriter {
write(List.class, index, list);
}
public <T, K> ConditionalValue<T, K> readEither(int index) {
Object either = readObject(index, NMSUtils.mojangEitherClass);
Optional<T> left = MojangEitherUtil.getLeft(either);
if (left.isPresent()) {
return ConditionalValue.makeLeft(left.get());
}
else {
Optional<K> right = MojangEitherUtil.getRight(either);
try {
return ConditionalValue.makeRight(right.orElseThrow((Supplier<Throwable>) () -> new IllegalStateException("Conditional value has no values. Atleast one side must have a value!")));
} catch (Throwable e) {
e.printStackTrace();
}
}
return null;
}
public <T, K> void writeEither(int index, ConditionalValue<T, K> conditionalValue) {
Object either;
if (conditionalValue.left().isPresent()) {
either = MojangEitherUtil.makeLeft(conditionalValue.left().get());
}
else {
either = MojangEitherUtil.makeRight(conditionalValue.right().get());
}
write(NMSUtils.mojangEitherClass, index, either);
}
private Field getField(Class<?> type, int index) {
Map<Class<?>, Field[]> cached = FIELD_CACHE.computeIfAbsent(packetClass, k -> new ConcurrentHashMap<>());
Field[] fields = cached.computeIfAbsent(type, typeClass -> getFields(typeClass, packetClass.getDeclaredFields()));
@@ -18,6 +18,7 @@
package io.github.retrooper.packetevents.packetwrappers.api.helper;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
@@ -72,11 +73,15 @@ public abstract class WrappedPacketEntityAbstraction extends WrappedPacket {
if (entity != null) {
return entity;
}
return entity = NMSUtils.getEntityById(world, getEntityId());
return PacketEvents.get().getServerUtils().getEntityById(world, getEntityId());
}
@Nullable
public Entity getEntity() {
return getEntity(null);
if (entity != null) {
return entity;
}
return PacketEvents.get().getServerUtils().getEntityById(getEntityId());
}
public void setEntity(@NotNull Entity entity) {
@@ -20,27 +20,33 @@ package io.github.retrooper.packetevents.packetwrappers.handshaking.setprotocol;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
public class WrappedPacketHandshakingInSetProtocol extends WrappedPacket {
private static boolean between_V_1_17_And_1_20_1;
public WrappedPacketHandshakingInSetProtocol(NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
between_V_1_17_And_1_20_1 = version.isNewerThanOrEquals(ServerVersion.v_1_17) && version.isOlderThan(ServerVersion.v_1_20_2);
}
public int getProtocolVersion() {
return readInt(0);
return readInt(between_V_1_17_And_1_20_1 ? 1 : 0);
}
public void setProtocolVersion(int protocolVersion) {
writeInt(0, protocolVersion);
writeInt(between_V_1_17_And_1_20_1 ? 1 : 0, protocolVersion);
}
public int getPort() {
return readInt(1);
return readInt(between_V_1_17_And_1_20_1 ? 2 : 1);
}
public void setPort(int port) {
writeInt(1, port);
writeInt(between_V_1_17_And_1_20_1 ? 2 : 1, port);
}
public String getHostName() {
@@ -25,16 +25,22 @@ import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
public class WrappedPacketLoginInCustomPayload extends WrappedPacket {
private static boolean v_1_17;
public WrappedPacketLoginInCustomPayload(NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
}
public int getMessageId() {
return readInt(0);
return readInt(v_1_17 ? 1 : 0);
}
public void setMessageId(int id) {
writeInt(0, id);
writeInt(v_1_17 ? 1 : 0, id);
}
public byte[] getData() {
@@ -21,12 +21,38 @@ package io.github.retrooper.packetevents.packetwrappers.login.in.encryptionbegin
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.ConditionalValue;
import io.github.retrooper.packetevents.utils.MojangEitherUtil;
import io.github.retrooper.packetevents.utils.SaltSignature;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.ClassUtil;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketLoginInEncryptionBegin extends WrappedPacket {
private static Class<?> VANILLA_SALT_SIGNATURE_CLASS;
private static Constructor<?> VANILLA_SALT_SIGNATURE_CONSTRUCTOR;
public WrappedPacketLoginInEncryptionBegin(NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
Class<?> minecraftEncryptionClass = Reflection.getClassByNameWithoutException("net.minecraft.util.MinecraftEncryption");
if (minecraftEncryptionClass != null) {
VANILLA_SALT_SIGNATURE_CLASS = SubclassUtil.getSubClass(minecraftEncryptionClass, "b");
try {
VANILLA_SALT_SIGNATURE_CONSTRUCTOR = VANILLA_SALT_SIGNATURE_CLASS.getConstructor(long.class, byte[].class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
public byte[] getPublicKey() {
return readByteArray(0);
}
@@ -35,12 +61,46 @@ public class WrappedPacketLoginInEncryptionBegin extends WrappedPacket {
writeByteArray(0, key);
}
public byte[] getVerifyToken() {
return readByteArray(1);
public ConditionalValue<byte[], SaltSignature> getVerifyTokenOrSaltSignature() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
ConditionalValue<byte[], Object> rawEither = readEither(0);
if (rawEither.left().isPresent()) {
return ConditionalValue.makeLeft(rawEither.left().get());
}
else {
Object rawRight = rawEither.right().get();
WrappedPacket rawRightWrapper = new WrappedPacket(new NMSPacket(rawRight));
SaltSignature ss = new SaltSignature(rawRightWrapper.readLong(0), rawRightWrapper.readByteArray(0));
return ConditionalValue.makeRight(ss);
}
}
else {
return ConditionalValue.makeLeft(readByteArray(1));
}
}
public void setVerifyToken(byte[] token) {
writeByteArray(1, token);
public void setVerifyTokenOrSaltSignature(ConditionalValue<byte[], SaltSignature> value) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
Object either;
if (value.left().isPresent()) {
either = MojangEitherUtil.makeLeft(value.left().get());
}
else {
SaltSignature ss = value.right().get();
Object rawSS = null;
try {
rawSS = VANILLA_SALT_SIGNATURE_CONSTRUCTOR.newInstance(ss.getSalt(), ss.getSignature());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
either = MojangEitherUtil.makeRight(rawSS);
}
write(NMSUtils.mojangEitherClass, 0, either);
}
else {
writeByteArray(1, value.left().get());
}
}
@Override
@@ -24,19 +24,71 @@ import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.gameprofile.GameProfileUtil;
import io.github.retrooper.packetevents.utils.gameprofile.WrappedGameProfile;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
import java.util.UUID;
// TODO: This wrapper needs Signature data @retrooper
public class WrappedPacketLoginInStart extends WrappedPacket {
public WrappedPacketLoginInStart(NMSPacket packet) {
super(packet);
}
public WrappedGameProfile getGameProfile() {
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass));
//TODO Allow accessing game profile property
public Optional<WrappedGameProfile> getGameProfile() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
return Optional.empty();
}
return Optional.of(GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass)));
}
//TODO Add support for game profile property
public void setGameProfile(WrappedGameProfile wrappedGameProfile) {
Object gameProfile = GameProfileUtil.getGameProfile(wrappedGameProfile.getId(), wrappedGameProfile.getName());
write(NMSUtils.gameProfileClass, 0, gameProfile);
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
writeString(0, wrappedGameProfile.getName());
}
else {
Object gameProfile = GameProfileUtil.getGameProfile(wrappedGameProfile.getId(), wrappedGameProfile.getName());
write(NMSUtils.gameProfileClass, 0, gameProfile);
}
}
public String getUsername() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
return readString(0);
}
else {
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass)).getName();
}
}
public void setUsername(String username) throws IllegalAccessException {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
writeString(0, username);
}
else {
throw new IllegalAccessException("Please use the setGameProfile method in the WrappedPacketLoginInStart wrapper to change the username!");
}
}
public @Nullable UUID getPlayerUUID() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
return readObject(0, UUID.class);
}
else {
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass)).getId();
}
}
public void setPlayerUUID(UUID playerUUID) throws IllegalAccessException {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
writeObject(0, playerUUID);
}
else {
throw new IllegalAccessException("Please use the setGameProfile method in the WrappedPacketLoginInStart wrapper to change the uuid!");
}
}
@Override
@@ -24,11 +24,12 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketLoginOutCustomPayload extends WrappedPacket implements SendableWrapper {
private static boolean v_1_17;
private static Constructor<?> constructor;
private static Constructor<?> packetDataSerializerConstructor;
private int messageID;
@@ -39,8 +40,15 @@ public class WrappedPacketLoginOutCustomPayload extends WrappedPacket implements
super(packet);
}
public WrappedPacketLoginOutCustomPayload(int messageID, String channelName, byte[] data) {
this.messageID = messageID;
this.channelName = channelName;
this.data = data;
}
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
Class<?> packetClass = PacketTypeClasses.Login.Server.CUSTOM_PAYLOAD;
if (packetClass != null) {
try {
@@ -52,7 +60,7 @@ public class WrappedPacketLoginOutCustomPayload extends WrappedPacket implements
}
try {
constructor = packetClass.getConstructor();
constructor = packetClass.getConstructor(int.class, NMSUtils.minecraftKeyClass, NMSUtils.packetDataSerializerClass);
} catch (NoSuchMethodException e3) {
throw new IllegalStateException("PacketEvents is unable to resolve the PacketPlayOutCustomPayload constructor.");
}
@@ -61,14 +69,14 @@ public class WrappedPacketLoginOutCustomPayload extends WrappedPacket implements
public int getMessageId() {
if (packet != null) {
return readInt(0);
return readInt(v_1_17 ? 1 : 0);
}
return messageID;
}
public void setMessageId(int messageID) {
if (packet != null) {
writeInt(0, messageID);
writeInt(v_1_17 ? 1 : 0, messageID);
} else {
this.messageID = messageID;
}
@@ -76,16 +84,16 @@ public class WrappedPacketLoginOutCustomPayload extends WrappedPacket implements
public String getChannelName() {
if (packet != null) {
Object minecraftKey = readObject(0, NMSUtils.minecraftKeyClass);
return NMSUtils.getStringFromMinecraftKey(minecraftKey);
return readMinecraftKey(0);
}
else {
return channelName;
}
return channelName;
}
public void setChannelName(String channelName) {
if (packet != null) {
Object minecraftKey = NMSUtils.generateMinecraftKey(channelName);
writeObject(0, minecraftKey);
writeMinecraftKey(0, channelName);
} else {
this.channelName = channelName;
}
@@ -97,12 +105,17 @@ public class WrappedPacketLoginOutCustomPayload extends WrappedPacket implements
WrappedPacket byteBufWrapper = new WrappedPacket(new NMSPacket(dataSerializer));
Object byteBuf = byteBufWrapper.readObject(0, NMSUtils.byteBufClass);
return PacketEvents.get().getByteBufUtil().getBytes(byteBuf);
} else {
return data;
}
return data;
}
public void setData(byte[] data) {
PacketEvents.get().getByteBufUtil().setBytes(getBuffer(), data);
if (packet != null) {
PacketEvents.get().getByteBufUtil().setBytes(getBuffer(), data);
} else {
this.data = data;
}
}
private Object getBuffer() {
@@ -114,19 +127,9 @@ public class WrappedPacketLoginOutCustomPayload extends WrappedPacket implements
@Override
public Object asNMSPacket() throws Exception {
Object byteBufObject = PacketEvents.get().getByteBufUtil().newByteBuf(data);
try {
Object minecraftKey = NMSUtils.generateMinecraftKey(channelName);
Object dataSerializer = packetDataSerializerConstructor.newInstance(byteBufObject);
Object packetInstance = constructor.newInstance();
WrappedPacket packetWrapper = new WrappedPacket(new NMSPacket(packetInstance));
packetWrapper.writeInt(0, messageID);
packetWrapper.writeObject(0, minecraftKey);
packetWrapper.writeObject(0, dataSerializer);
return packetInstance;
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
Object minecraftKey = NMSUtils.generateMinecraftKeyNew(channelName);
Object dataSerializer = packetDataSerializerConstructor.newInstance(byteBufObject);
return constructor.newInstance(getMessageId(), minecraftKey, dataSerializer);
}
@Override
@@ -27,23 +27,22 @@ import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import java.lang.reflect.Constructor;
public class WrappedPacketLoginOutDisconnect extends WrappedPacket implements SendableWrapper {
private static Constructor<?> packetConstructor;
private String reason;
public WrappedPacketLoginOutDisconnect(final NMSPacket packet) {
public WrappedPacketLoginOutDisconnect(NMSPacket packet) {
super(packet);
}
public WrappedPacketLoginOutDisconnect(final String reason) {
public WrappedPacketLoginOutDisconnect(String reason) {
this.reason = reason;
}
@Override
protected void load() {
try {
packetConstructor = PacketTypeClasses.Login.Server.DISCONNECT.getConstructors()[1];
} catch (final Exception e) {
packetConstructor = PacketTypeClasses.Login.Server.DISCONNECT.getConstructor(NMSUtils.iChatBaseComponentClass);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@@ -66,9 +65,7 @@ public class WrappedPacketLoginOutDisconnect extends WrappedPacket implements Se
@Override
public Object asNMSPacket() throws Exception {
return packetConstructor.newInstance(
NMSUtils.generateIChatBaseComponent(getReason())
);
return packetConstructor.newInstance(NMSUtils.generateIChatBaseComponent(getReason()));
}
@Override
@@ -21,14 +21,24 @@ package io.github.retrooper.packetevents.packetwrappers.login.out.encryptionbegi
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class WrappedPacketLoginOutEncryptionBegin extends WrappedPacket {
private static boolean v_1_17;
public WrappedPacketLoginOutEncryptionBegin(NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
}
public String getEncodedString() {
return readString(0);
}
@@ -38,19 +48,34 @@ public class WrappedPacketLoginOutEncryptionBegin extends WrappedPacket {
}
public PublicKey getPublicKey() {
return readObject(1, PublicKey.class);
return v_1_17 ? encrypt(readByteArray(0)) : readObject(0, PublicKey.class);
}
public void setPublicKey(PublicKey key) {
writeObject(0, key);
if (v_1_17) {
writeByteArray(0, key.getEncoded());
} else {
writeObject(0, key);
}
}
public byte[] getVerifyToken() {
return readByteArray(0);
return readByteArray(v_1_17 ? 1 : 0);
}
public void setVerifyToken(byte[] verifyToken) {
writeByteArray(0, verifyToken);
writeByteArray(v_1_17 ? 1 : 0, verifyToken);
}
private PublicKey encrypt(byte[] bytes) {
try {
EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(bytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(encodedKeySpec);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
@Override
@@ -25,9 +25,7 @@ import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//This packet does not exist on 1.7.10
public class WrappedPacketLoginOutSetCompression extends WrappedPacket implements SendableWrapper {
private static Constructor<?> constructor;
private int threshold;
@@ -73,12 +71,7 @@ public class WrappedPacketLoginOutSetCompression extends WrappedPacket implement
@Override
public Object asNMSPacket() throws Exception {
try {
return constructor.newInstance(getThreshold());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
return constructor.newInstance(getThreshold());
}
@Override
@@ -28,28 +28,14 @@ import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import java.lang.reflect.Constructor;
public class WrappedPacketLoginOutSuccess extends WrappedPacket implements SendableWrapper {
private static Constructor<?> packetConstructor;
public class WrappedPacketLoginOutSuccess extends WrappedPacket {
private WrappedGameProfile wrappedGameProfile;
public WrappedPacketLoginOutSuccess(final NMSPacket packet) {
super(packet);
}
public WrappedPacketLoginOutSuccess(final WrappedGameProfile wrappedGameProfile) {
this.wrappedGameProfile = wrappedGameProfile;
}
@Override
protected void load() {
try {
packetConstructor = PacketTypeClasses.Login.Server.SUCCESS.getConstructors()[1];
} catch (final Exception e) {
e.printStackTrace();
}
}
//TODO Support property reading in wrapped game profile(NECESSARY IN 1.19!, PLEASE UPDATE TO 2.0 PACKETEVENTS)
public WrappedGameProfile getGameProfile() {
if (packet != null) {
return GameProfileUtil.getWrappedGameProfile(readObject(0, NMSUtils.gameProfileClass));
@@ -58,6 +44,7 @@ public class WrappedPacketLoginOutSuccess extends WrappedPacket implements Senda
}
}
//TODO Support writing property in wrapped game profile(NECESSARY IN 1.19!, PLEASE UPDATE TO 2.0 PACKETEVENTS)
public void setGameProfile(final WrappedGameProfile wrappedGameProfile) {
if (packet != null) {
final Object gameProfile = GameProfileUtil.getGameProfile(wrappedGameProfile.getId(), wrappedGameProfile.getName());
@@ -67,14 +54,6 @@ public class WrappedPacketLoginOutSuccess extends WrappedPacket implements Senda
}
}
@Override
public Object asNMSPacket() throws Exception {
WrappedGameProfile gp = getGameProfile();
return packetConstructor.newInstance(
GameProfileUtil.getGameProfile(gp.getId(), gp.getName())
);
}
@Override
public boolean isSupported() {
return PacketTypeClasses.Login.Server.SUCCESS != null;
@@ -26,23 +26,30 @@ import io.github.retrooper.packetevents.utils.player.Hand;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
public class WrappedPacketInArmAnimation extends WrappedPacket {
private static boolean v_1_9;
public WrappedPacketInArmAnimation(NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
v_1_9 = version.isNewerThanOrEquals(ServerVersion.v_1_9);
}
public Hand getHand() {
if (version.isOlderThan(ServerVersion.v_1_9)) {
return Hand.MAIN_HAND;
} else {
if (v_1_9) {
Enum<?> enumConst = readEnumConstant(0, NMSUtils.enumHandClass);
return Hand.valueOf(enumConst.name());
return Hand.values()[enumConst.ordinal()];
}
else {
return Hand.MAIN_HAND;
}
}
public void setHand(Hand hand) {
//Optimize to do nothing on legacy versions. The protocol of the legacy versions only support one hand, the main hand.
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
Enum<?> enumConst = EnumUtil.valueOf(NMSUtils.enumHandClass, hand.name());
if (v_1_9) {
Enum<?> enumConst = EnumUtil.valueByIndex(NMSUtils.enumHandClass, hand.ordinal());
writeEnumConstant(0, enumConst);
}
}
@@ -47,6 +47,9 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
} catch (ClassNotFoundException e) {
//It is probably a subclass
digTypeClass = SubclassUtil.getEnumSubClass(blockDigClass, "EnumPlayerDigType");
if (digTypeClass == null) {
digTypeClass = SubclassUtil.getEnumSubClass(blockDigClass, 0);
}
}
}
}
@@ -82,7 +85,7 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
return Direction.getDirection(readInt(3));
} else {
Enum<?> enumDir = readEnumConstant(0, NMSUtils.enumDirectionClass);
return Direction.valueOf(enumDir.name());
return Direction.values()[enumDir.ordinal()];
}
}
@@ -90,7 +93,7 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
if (isVersionLowerThan_v_1_8) {
writeInt(3, direction.getFaceValue());
} else {
Enum<?> enumConst = EnumUtil.valueOf(NMSUtils.enumDirectionClass, direction.name());
Enum<?> enumConst = EnumUtil.valueByIndex(NMSUtils.enumDirectionClass, direction.ordinal());
write(NMSUtils.enumDirectionClass, 0, enumConst);
}
}
@@ -104,7 +107,7 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
if (isVersionLowerThan_v_1_8) {
return PlayerDigType.values()[readInt(4)];
} else {
return PlayerDigType.valueOf(readObject(0, digTypeClass).name());
return PlayerDigType.values()[readEnumConstant(0, digTypeClass).ordinal()];
}
}
@@ -112,8 +115,8 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
if (isVersionLowerThan_v_1_8) {
writeInt(4, type.ordinal());
} else {
Enum<?> enumConst = EnumUtil.valueOf(digTypeClass, type.name());
write(digTypeClass, 0, enumConst);
Enum<?> enumConst = EnumUtil.valueByIndex(digTypeClass, type.ordinal());
writeEnumConstant(0, enumConst);
}
}
@@ -124,14 +127,6 @@ public final class WrappedPacketInBlockDig extends WrappedPacket {
DROP_ALL_ITEMS,
DROP_ITEM,
RELEASE_USE_ITEM,
/**
* Doesn't exist on the newest versions.
*/
@Deprecated
SWAP_HELD_ITEMS,
SWAP_ITEM_WITH_OFFHAND,
UNKNOWN
SWAP_ITEM_WITH_OFFHAND
}
}
@@ -53,19 +53,20 @@ public final class WrappedPacketInBlockPlace extends WrappedPacket {
}
public Hand getHand() {
if (version.isOlderThan(ServerVersion.v_1_9)) {
return Hand.MAIN_HAND;
} else {
if (newerThan_v_1_8_8) {
Enum<?> enumConst = readEnumConstant(handEnumIndex, NMSUtils.enumHandClass);
return Hand.valueOf(enumConst.name());
return Hand.values()[enumConst.ordinal()];
}
else {
return Hand.MAIN_HAND;
}
}
public void setHand(Hand hand) {
//Optimize to do nothing on legacy versions. The protocol of the legacy versions only support one hand, the main hand.
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
Enum<?> enumConst = EnumUtil.valueOf(NMSUtils.enumHandClass, hand.name());
write(NMSUtils.enumHandClass, handEnumIndex, enumConst);
if (newerThan_v_1_8_8) {
Enum<?> enumConst = EnumUtil.valueByIndex(NMSUtils.enumHandClass, hand.ordinal());
writeEnumConstant(handEnumIndex, enumConst);
}
}
@@ -149,7 +150,7 @@ public final class WrappedPacketInBlockPlace extends WrappedPacket {
public void setItemStack(ItemStack stack) {
if (newerThan_v_1_8_8) {
//Newer versions do not contain an itemstack
} else if (newerThan_v_1_7_10) {
WrappedPacketInBlockPlace_1_8 blockPlace_1_8 = new WrappedPacketInBlockPlace_1_8(packet);
blockPlace_1_8.setItemStack(stack);
@@ -34,7 +34,6 @@ final class WrappedPacketInBlockPlace_1_7_10 extends WrappedPacket {
}
public void setBlockPosition(Vector3i blockPos) {
Vector3i currentBlockPos = getBlockPosition();
writeInt(0, blockPos.x);
writeInt(1, blockPos.y);
writeInt(2, blockPos.z);
@@ -29,74 +29,57 @@ import io.github.retrooper.packetevents.utils.vector.Vector3i;
import java.lang.reflect.InvocationTargetException;
final class WrappedPacketInBlockPlace_1_9 extends WrappedPacket {
private static Class<?> movingObjectPositionBlockClass;
private Object movingObjPos;
public WrappedPacketInBlockPlace_1_9(final NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
movingObjectPositionBlockClass = NMSUtils.getNMSClassWithoutException("MovingObjectPositionBlock");
}
public Vector3i getBlockPosition() {
Vector3i blockPos = new Vector3i();
Object blockPosObj;
if (movingObjectPositionBlockClass == null) {
blockPosObj = readObject(0, NMSUtils.blockPosClass);
if (NMSUtils.movingObjectPositionBlockClass == null) {
return readBlockPosition(0);
} else {
if (movingObjPos == null) {
movingObjPos = readObject(0, movingObjectPositionBlockClass);
movingObjPos = readObject(0, NMSUtils.movingObjectPositionBlockClass);
}
WrappedPacket movingObjectPosWrapper = new WrappedPacket(new NMSPacket(movingObjPos));
blockPosObj = movingObjectPosWrapper.readObject(0, NMSUtils.blockPosClass);
return movingObjectPosWrapper.readBlockPosition(0);
}
try {
blockPos.x = (int) NMSUtils.getBlockPosX.invoke(blockPosObj);
blockPos.y = (int) NMSUtils.getBlockPosY.invoke(blockPosObj);
blockPos.z = (int) NMSUtils.getBlockPosZ.invoke(blockPosObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return blockPos;
}
public void setBlockPosition(Vector3i blockPos) {
Object blockPosObj = NMSUtils.generateNMSBlockPos(blockPos);
if (movingObjectPositionBlockClass == null) {
write(NMSUtils.blockPosClass, 0, blockPosObj);
if (NMSUtils.movingObjectPositionBlockClass == null) {
writeBlockPosition(0, blockPos);
} else {
if (movingObjPos == null) {
movingObjPos = readObject(0, movingObjectPositionBlockClass);
movingObjPos = readObject(0, NMSUtils.movingObjectPositionBlockClass);
}
WrappedPacket movingObjectPosWrapper = new WrappedPacket(new NMSPacket(movingObjPos));
movingObjectPosWrapper.write(NMSUtils.blockPosClass, 0, blockPos);
movingObjectPosWrapper.writeBlockPosition(0, blockPos);
}
}
public Direction getDirection() {
Enum<?> enumConst;
if (movingObjectPositionBlockClass == null) {
if (NMSUtils.movingObjectPositionBlockClass == null) {
enumConst = readEnumConstant(0, NMSUtils.enumDirectionClass);
} else {
if (movingObjPos == null) {
movingObjPos = readObject(0, movingObjectPositionBlockClass);
movingObjPos = readObject(0, NMSUtils.movingObjectPositionBlockClass);
}
WrappedPacket movingObjectPosWrapper = new WrappedPacket(new NMSPacket(movingObjPos));
enumConst = movingObjectPosWrapper.readEnumConstant(0, NMSUtils.enumDirectionClass);
}
return Direction.valueOf(enumConst.name());
return Direction.values()[enumConst.ordinal()];
}
public void setDirection(Direction direction) {
Enum<?> enumConst = EnumUtil.valueOf(NMSUtils.enumDirectionClass, direction.name());
if (movingObjectPositionBlockClass == null) {
Enum<?> enumConst = EnumUtil.valueByIndex(NMSUtils.enumDirectionClass, direction.ordinal());
if (NMSUtils.movingObjectPositionBlockClass == null) {
writeEnumConstant(0, enumConst);
} else {
if (movingObjPos == null) {
movingObjPos = readObject(0, movingObjectPositionBlockClass);
movingObjPos = readObject(0, NMSUtils.movingObjectPositionBlockClass);
}
WrappedPacket movingObjectPosWrapper = new WrappedPacket(new NMSPacket(movingObjPos));
movingObjectPosWrapper.writeEnumConstant(0, enumConst);
@@ -20,23 +20,92 @@ package io.github.retrooper.packetevents.packetwrappers.play.in.chat;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.SaltSignature;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.time.Instant;
import java.util.Optional;
public final class WrappedPacketInChat extends WrappedPacket {
private String message = null;
private static Class<?> VANILLA_SALT_SIGNATURE_CLASS;
private static Constructor<?> VANILLA_SALT_SIGNATURE_CONSTRUCTOR;
public WrappedPacketInChat(NMSPacket packet) {
super(packet);
}
public String getMessage() {
if (message != null) {
return message;
@Override
protected void load() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
Class<?> minecraftEncryptionClass = Reflection.getClassByNameWithoutException("net.minecraft.util.MinecraftEncryption");
if (minecraftEncryptionClass != null) {
VANILLA_SALT_SIGNATURE_CLASS = SubclassUtil.getSubClass(minecraftEncryptionClass, "b");
try {
VANILLA_SALT_SIGNATURE_CONSTRUCTOR = VANILLA_SALT_SIGNATURE_CLASS.getConstructor(long.class, byte[].class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
return message = readString(0);
}
public String getMessage() {
return readString(0);
}
public void setMessage(String message) {
this.message = message;
writeString(0, message);
}
public Optional<Instant> getInstant() {
return version.isNewerThanOrEquals(ServerVersion.v_1_19) ? Optional.of(readObject(0, Instant.class)) : Optional.empty();
}
public void setInstant(Instant instant) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
writeObject(0, instant);
}
}
public Optional<SaltSignature> getSaltSignature() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
Object rawSS = readObject(0, VANILLA_SALT_SIGNATURE_CLASS);
WrappedPacket rawSSWrapper = new WrappedPacket(new NMSPacket(rawSS));
SaltSignature ss = new SaltSignature(rawSSWrapper.readLong(0), rawSSWrapper.readByteArray(0));
return Optional.of(ss);
}
else {
return Optional.empty();
}
}
public void setSaltSignature(SaltSignature saltSignature) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
Object rawSS = null;
try {
rawSS = VANILLA_SALT_SIGNATURE_CONSTRUCTOR.newInstance(saltSignature.getSalt(), saltSignature.getSignature());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
write(VANILLA_SALT_SIGNATURE_CLASS, 0, rawSS);
}
}
public boolean isSignedPreview() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
return readBoolean(0);
}
else {
return false;
}
}
public void setSignedPreview(boolean signedPreview) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
writeBoolean(0, signedPreview);
}
}
}
@@ -27,6 +27,7 @@ import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
public final class WrappedPacketInClientCommand extends WrappedPacket {
private static boolean v_1_16;
private static Class<? extends Enum<?>> enumClientCommandClass;
public WrappedPacketInClientCommand(NMSPacket packet) {
@@ -35,26 +36,28 @@ public final class WrappedPacketInClientCommand extends WrappedPacket {
@Override
protected void load() {
Class<?> packetClass = PacketTypeClasses.Play.Client.CLIENT_COMMAND;
try {
enumClientCommandClass = NMSUtils.getNMSEnumClass("EnumClientCommand");
} catch (ClassNotFoundException e) {
v_1_16 = version.isNewerThanOrEquals(ServerVersion.v_1_16);
enumClientCommandClass = NMSUtils.getNMSEnumClassWithoutException("EnumClientCommand");
if (enumClientCommandClass == null) {
//Probably a subclass
enumClientCommandClass = SubclassUtil.getEnumSubClass(packetClass, "EnumClientCommand");
enumClientCommandClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.CLIENT_COMMAND, "EnumClientCommand");
if (enumClientCommandClass == null) {
enumClientCommandClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.CLIENT_COMMAND, 0);
}
}
}
public ClientCommand getClientCommand() {
Enum<?> emumConst = readEnumConstant(0, enumClientCommandClass);
return ClientCommand.valueOf(emumConst.name());
Enum<?> enumConst = readEnumConstant(0, enumClientCommandClass);
return ClientCommand.values()[enumConst.ordinal()];
}
public void setClientCommand(ClientCommand command) throws UnsupportedOperationException {
if (command == ClientCommand.OPEN_INVENTORY_ACHIEVEMENT && version.isNewerThan(ServerVersion.v_1_16)) {
if (command == ClientCommand.OPEN_INVENTORY_ACHIEVEMENT && v_1_16) {
throwUnsupportedOperation(command);
}
Enum<?> enumConst = EnumUtil.valueOf(enumClientCommandClass, command.name());
Enum<?> enumConst = EnumUtil.valueByIndex(enumClientCommandClass, command.ordinal());
writeEnumConstant(0, enumConst);
}
@@ -22,11 +22,21 @@ import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.netty.bytebuf.ByteBufUtil;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public final class WrappedPacketInCustomPayload extends WrappedPacket {
private static boolean strPresent, byteArrayPresent;
private static boolean strPresent, byteArrayPresent, customPacketPayloadPresent;
private static Class<?> CUSTOM_PACKET_PAYLOAD, BRAND_PAYLOAD, DISCARDED_PAYLOAD;
private static Method CUSTOM_PACKET_PAYLOAD_MINECRAFT_KEY, CUSTOM_PACKET_PAYLOAD_PACKETDATASERIALIZER;
private static byte isVersion_1_17 = -1;
private static boolean isVersion_1_20_5;
private static boolean isVersion_1_20_6;
public WrappedPacketInCustomPayload(NMSPacket packet) {
super(packet);
@@ -34,31 +44,107 @@ public final class WrappedPacketInCustomPayload extends WrappedPacket {
@Override
protected void load() {
Class<?> packetClass = PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD;
strPresent = Reflection.getField(packetClass, String.class, 0) != null;
byteArrayPresent = Reflection.getField(packetClass, byte[].class, 0) != null;
}
public String getTag() {
if (strPresent) {
return readString(0);
} else {
Object minecraftKey = readObject(0, NMSUtils.minecraftKeyClass);
return NMSUtils.getStringFromMinecraftKey(minecraftKey);
strPresent = Reflection.getField(PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD, String.class, 0) != null;
byteArrayPresent = Reflection.getField(PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD, byte[].class, 0) != null;
CUSTOM_PACKET_PAYLOAD = Reflection.getClassByNameWithoutException("net.minecraft.network.protocol.common.custom.CustomPacketPayload");
customPacketPayloadPresent = Reflection.getField(PacketTypeClasses.Play.Client.CUSTOM_PAYLOAD, CUSTOM_PACKET_PAYLOAD, 0) != null;
if (customPacketPayloadPresent) {
CUSTOM_PACKET_PAYLOAD_MINECRAFT_KEY = Reflection.getMethod(CUSTOM_PACKET_PAYLOAD, NMSUtils.minecraftKeyClass, 0);
CUSTOM_PACKET_PAYLOAD_PACKETDATASERIALIZER = Reflection.getMethod(CUSTOM_PACKET_PAYLOAD, 0, NMSUtils.packetDataSerializerClass);
}
isVersion_1_20_5 = version.isNewerThanOrEquals(ServerVersion.v_1_20_5);
isVersion_1_20_6 = version.isNewerThanOrEquals(ServerVersion.v_1_20_6);
if (isVersion_1_20_5) {
BRAND_PAYLOAD = NMSUtils.getNMClassWithoutException("network.protocol.common.custom.BrandPayload");
DISCARDED_PAYLOAD = NMSUtils.getNMClassWithoutException("network.protocol.common.custom.DiscardedPayload");
}
}
public void setTag(String tag) {
if (strPresent) {
writeString(0, tag);
private Object getModernPayloadObject() {
return readObject(0, CUSTOM_PACKET_PAYLOAD);
}
public String getChannelName() {
if (customPacketPayloadPresent) {
Object payload = getModernPayloadObject();
if (isVersion_1_20_5) {
if (BRAND_PAYLOAD.isInstance(payload)) {
WrappedPacket reflectBrandPayload = new WrappedPacket(new NMSPacket(payload));
return reflectBrandPayload.readString(0);
}
else if (DISCARDED_PAYLOAD.isInstance(payload)) {
WrappedPacket reflectBrandPayload = new WrappedPacket(new NMSPacket(payload));
if (isVersion_1_20_6) {
return reflectBrandPayload.readMinecraftKey(0);
}
else {
return reflectBrandPayload.readString(0);
}
}
else {
return null;
}
}
else {
try {
if (isVersion_1_17 == -1) {
isVersion_1_17 = (byte) (version.isNewerThanOrEquals(ServerVersion.v_1_17) ? 1 : 0);
}
int namespaceIndex = isVersion_1_17 == 1 ? 2 : 0;
int keyIndex = isVersion_1_17 == 1 ? 3 : 1;
Object minecraftKey = CUSTOM_PACKET_PAYLOAD_MINECRAFT_KEY.invoke(payload);
WrappedPacket minecraftKeyWrapper = new WrappedPacket(new NMSPacket(minecraftKey));
return minecraftKeyWrapper.readString(namespaceIndex) + ":" + minecraftKeyWrapper.readString(keyIndex);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
} else if (strPresent) {
return readString(0);
} else {
Object minecraftKey = NMSUtils.generateMinecraftKey(tag);
write(NMSUtils.minecraftKeyClass, 0, minecraftKey);
return readMinecraftKey(1);
}
}
public void setChannelName(String channelName) {
if (customPacketPayloadPresent) {
throw new UnsupportedOperationException("PacketEvents v1.8 is a dying version, setting the channel name is not supported!");
}
else if (strPresent) {
writeString(0, channelName);
} else {
writeMinecraftKey(1, channelName);
}
}
public byte[] getData() {
if (byteArrayPresent) {
if (customPacketPayloadPresent) {
Object payload = getModernPayloadObject();
if (isVersion_1_20_6) {
if (DISCARDED_PAYLOAD.isInstance(payload)) {
WrappedPacket reflectDiscardedPayload = new WrappedPacket(new NMSPacket(payload));
Object buffer = reflectDiscardedPayload.readObject(0, NMSUtils.byteBufClass);
return PacketEvents.get().getByteBufUtil().getBytes(buffer);
}
else {
return null;
}
}
else {
Object buffer = PacketEvents.get().getByteBufUtil().buffer();
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(buffer);
try {
CUSTOM_PACKET_PAYLOAD_PACKETDATASERIALIZER.invoke(payload, packetDataSerializer);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
byte[] data = PacketEvents.get().getByteBufUtil().getBytes(buffer);
PacketEvents.get().getByteBufUtil().release(buffer);
return data;
}
}
else if (byteArrayPresent) {
return readByteArray(0);
} else {
return PacketEvents.get().getByteBufUtil().getBytes(getBuffer());
@@ -81,13 +167,13 @@ public final class WrappedPacketInCustomPayload extends WrappedPacket {
}
public void retain() {
if (!byteArrayPresent) {
if (packet != null && !byteArrayPresent) {
PacketEvents.get().getByteBufUtil().retain(getBuffer());
}
}
public void release() {
if (!byteArrayPresent) {
if (packet != null && !byteArrayPresent) {
PacketEvents.get().getByteBufUtil().release(getBuffer());
}
}
@@ -21,13 +21,14 @@ package io.github.retrooper.packetevents.packetwrappers.play.in.entityaction;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.jetbrains.annotations.Nullable;
public final class WrappedPacketInEntityAction extends WrappedPacket {
public final class WrappedPacketInEntityAction extends WrappedPacketEntityAbstraction {
private static Class<? extends Enum<?>> enumPlayerActionClass;
private static boolean newerThan_v_1_8_8;
@@ -42,6 +43,9 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
if (enumPlayerActionClass == null) {
enumPlayerActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.ENTITY_ACTION, "EnumPlayerAction");
}
if (version.isNewerThanOrEquals(ServerVersion.v_1_20_6)) {
enumPlayerActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.ENTITY_ACTION, 0);
}
}
@@ -51,6 +55,9 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
return PlayerAction.getByActionValue((byte) (animationIndex));
} else {
Enum<?> enumConst = readEnumConstant(0, enumPlayerActionClass);
if (newerThan_v_1_8_8) {
return PlayerAction.getByActionValue((byte) enumConst.ordinal());
}
return PlayerAction.getByName(enumConst.name());
}
}
@@ -65,7 +72,7 @@ public final class WrappedPacketInEntityAction extends WrappedPacket {
if (action == PlayerAction.RIDING_JUMP) {
throwUnsupportedOperation(action);
}
enumConst = EnumUtil.valueByIndex(enumPlayerActionClass, action.ordinal());
enumConst = EnumUtil.valueByIndex(enumPlayerActionClass, action.getActionValue());
} else {
enumConst = EnumUtil.valueOf(enumPlayerActionClass, action.name());
@@ -58,6 +58,46 @@ public class WrappedPacketInFlying extends WrappedPacket {
writeDouble(2, z);
}
@Deprecated
public boolean isPosition() {
return readBoolean(1);
}
@Deprecated
public void setIsPosition(boolean isPosition) {
writeBoolean(1, isPosition);
}
@Deprecated
public boolean isLook() {
return readBoolean(2);
}
@Deprecated
public void setIsLook(boolean isLook) {
writeBoolean(2, isLook);
}
@Deprecated
public boolean hasPositionChanged() {
return readBoolean(1);
}
@Deprecated
public void setPositionChanged(boolean positionChanged) {
writeBoolean(1, positionChanged);
}
@Deprecated
public boolean hasRotationChanged() {
return readBoolean(2);
}
@Deprecated
public void setRotationChanged(boolean rotationChanged) {
writeBoolean(2, rotationChanged);
}
public Vector3d getPosition() {
return new Vector3d(readDouble(0), readDouble(1), readDouble(2));
}
@@ -92,39 +132,19 @@ public class WrappedPacketInFlying extends WrappedPacket {
writeBoolean(0, onGround);
}
@Deprecated
public boolean isPosition() {
public boolean isMoving() {
return readBoolean(1);
}
@Deprecated
public void setIsPosition(boolean isPosition) {
writeBoolean(1, isPosition);
public void setMoving(boolean moving) {
writeBoolean(1, moving);
}
@Deprecated
public boolean isLook() {
public boolean isRotating() {
return readBoolean(2);
}
@Deprecated
public void setIsLook(boolean isLook) {
writeBoolean(2, isLook);
}
public boolean hasPositionChanged() {
return readBoolean(1);
}
public void setPositionChanged(boolean positionChanged) {
writeBoolean(1, positionChanged);
}
public boolean hasRotationChanged() {
return readBoolean(2);
}
public void setRotationChanged(boolean rotationChanged) {
writeBoolean(2, rotationChanged);
public void setRotating(boolean rotating) {
writeBoolean(2, rotating);
}
}
@@ -1,4 +1,22 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.jigsawgenerate;
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 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 io.github.retrooper.packetevents.packetwrappers.play.in.jigsawgenerate;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
@@ -8,7 +26,6 @@ import io.github.retrooper.packetevents.utils.vector.Vector3i;
* Sent when Generate is pressed on the Jigsaw Block interface.
*
* @author Tecnio
* @see <a href="https://wiki.vg/Protocol#Generate_Structure"</a>
*/
public class WrappedPacketInJigsawGenerate extends WrappedPacket {
@@ -16,28 +16,41 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.github.retrooper.packetevents.packetwrappers.play.out.multiblockchange;
package io.github.retrooper.packetevents.packetwrappers.play.in.pong;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
//TODO finish this wrapper
class WrappedPacketOutMultiBlockChange extends WrappedPacket {
public class WrappedPacketInPong extends WrappedPacket {
private int id;
public WrappedPacketOutMultiBlockChange(NMSPacket packet) {
public WrappedPacketInPong(NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
net.minecraft.server.v1_7_R4.PacketPlayOutMultiBlockChange a0;
net.minecraft.server.v1_8_R3.PacketPlayOutMultiBlockChange a1;
net.minecraft.server.v1_9_R1.PacketPlayOutMultiBlockChange a2;
net.minecraft.server.v1_9_R2.PacketPlayOutMultiBlockChange a3;
net.minecraft.server.v1_12_R1.PacketPlayOutMultiBlockChange a4;
net.minecraft.server.v1_13_R1.PacketPlayOutMultiBlockChange a5;
net.minecraft.server.v1_13_R2.PacketPlayOutMultiBlockChange a6;
net.minecraft.server.v1_16_R2.PacketPlayOutMultiBlockChange a7;
public WrappedPacketInPong(int id) {
this.id = id;
}
public int getId() {
if (packet != null) {
return readInt(0);
} else {
return id;
}
}
public void setId(int id) {
if (packet != null) {
writeInt(0, id);
} else {
this.id = id;
}
}
@Override
public boolean isSupported() {
return version.isNewerThanOrEquals(ServerVersion.v_1_17);
}
}
@@ -39,11 +39,11 @@ public class WrappedPacketInResourcePackStatus extends WrappedPacket {
public ResourcePackStatus getStatus() {
Enum<?> enumConst = readEnumConstant(0, enumResourcePackStatusClass);
return ResourcePackStatus.valueOf(enumConst.name());
return ResourcePackStatus.values()[enumConst.ordinal()];
}
public void setStatus(ResourcePackStatus status) {
Enum<?> enumConst = EnumUtil.valueOf(enumResourcePackStatusClass, status.name());
Enum<?> enumConst = EnumUtil.valueByIndex(enumResourcePackStatusClass, status.ordinal());
writeEnumConstant(0, enumConst);
}
@@ -26,13 +26,13 @@ import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
public class WrappedPacketInSettings extends WrappedPacket {
private static Class<? extends Enum<?>> chatVisibilityEnumClass;
private static boolean isLowerThan_v_1_8;
private Object chatVisibilityEnumObj;
private static boolean isLowerThan_v_1_8, v_1_17, v_1_18;
public WrappedPacketInSettings(final NMSPacket packet) {
super(packet);
@@ -41,13 +41,16 @@ public class WrappedPacketInSettings extends WrappedPacket {
@Override
protected void load() {
isLowerThan_v_1_8 = version.isOlderThan(ServerVersion.v_1_8);
try {
chatVisibilityEnumClass = NMSUtils.getNMSEnumClass("EnumChatVisibility");
} catch (ClassNotFoundException e) {
Class<?> entityHumanClass = NMSUtils.getNMSClassWithoutException("EntityHuman");
//They are just on an outdated version
chatVisibilityEnumClass = SubclassUtil.getEnumSubClass(entityHumanClass, "EnumChatVisibility");
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
v_1_18 = version.isNewerThanOrEquals(ServerVersion.v_1_18);
chatVisibilityEnumClass = NMSUtils.getNMSEnumClassWithoutException("EnumChatVisibility");
if (chatVisibilityEnumClass == null) {
//They are on 1.17+
chatVisibilityEnumClass = NMSUtils.getNMEnumClassWithoutException("world.entity.player.EnumChatVisibility");
if (chatVisibilityEnumClass == null) {
//They are just on an outdated version
chatVisibilityEnumClass = SubclassUtil.getEnumSubClass(NMSUtils.entityHumanClass, "EnumChatVisibility");
}
}
}
@@ -60,20 +63,20 @@ public class WrappedPacketInSettings extends WrappedPacket {
}
public int getViewDistance() {
return readInt(0);
return readInt((v_1_17 && !v_1_18) ? 1 : 0);
}
public void setViewDistance(int viewDistance) {
writeInt(0, viewDistance);
writeInt((v_1_17 && !v_1_18) ? 1 : 0, viewDistance);
}
public ChatVisibility getChatVisibility() {
Enum<?> enumConst = readEnumConstant(0, chatVisibilityEnumClass);
return ChatVisibility.valueOf(enumConst.name());
return ChatVisibility.values()[enumConst.ordinal()];
}
public void setChatVisibility(ChatVisibility visibility) {
Enum<?> enumConst = EnumUtil.valueByIndex(chatVisibilityEnumClass, visibility.ordinal()); //Ordinal is faster than name comparison.
Enum<?> enumConst = EnumUtil.valueByIndex(chatVisibilityEnumClass, visibility.ordinal());
writeEnumConstant(0, enumConst);
}
@@ -85,6 +88,37 @@ public class WrappedPacketInSettings extends WrappedPacket {
writeBoolean(0, chatColors);
}
//Added in 1.17
public boolean isTextFilteringEnabled() {
if (v_1_17) {
return readBoolean(1);
}
return false;
}
//Added in 1.17
public void setTextFilteringEnabled(boolean enabled) {
if (v_1_17) {
writeBoolean(1, enabled);
}
}
//Added in 1.18
public boolean isServerListingsAllowed() {
if (v_1_18) {
return readBoolean(2);
}
return true;
}
//Added in 1.18
public void setServerListingsAllowed(boolean allowed) {
if (v_1_18) {
writeBoolean(2, allowed);
}
}
public byte getDisplaySkinPartsMask() {
byte mask = 0;
if (isLowerThan_v_1_8) {
@@ -93,7 +127,7 @@ public class WrappedPacketInSettings extends WrappedPacket {
mask |= 0x01;
}
} else {
mask = (byte) readInt(1);
mask = (byte) readInt((v_1_17 && !v_1_18) ? 2 : 1);
}
return mask;
}
@@ -103,7 +137,7 @@ public class WrappedPacketInSettings extends WrappedPacket {
boolean capeEnabled = (mask & 0x01) == 0x01;
writeBoolean(1, capeEnabled);
} else {
writeInt(1, mask);
writeInt((v_1_17 && !v_1_18) ? 2 : 1, mask);
}
}
@@ -18,6 +18,7 @@
package io.github.retrooper.packetevents.packetwrappers.play.in.transaction;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
@@ -49,4 +50,10 @@ public final class WrappedPacketInTransaction extends WrappedPacket {
public void setAccepted(boolean isAccepted) {
writeBoolean(0, isAccepted);
}
@Override
public boolean isSupported() {
//1.7.10 -> 1.16.5, removed at 1.17
return PacketTypeClasses.Play.Client.TRANSACTION != null;
}
}
@@ -23,6 +23,7 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.utils.vector.Vector3i;
public class WrappedPacketInUpdateSign extends WrappedPacket {
@@ -61,10 +62,10 @@ public class WrappedPacketInUpdateSign extends WrappedPacket {
public String[] getTextLines() {
if (strArrayMode) {
//1.7.10
//1.7.10 and 1.17+
return readStringArray(0);
} else {
//1.8 and above
//1.8 -> 1.16.5
Object[] iChatComponents = (Object[]) readAnyObject(1);
return NMSUtils.readIChatBaseComponents(iChatComponents);
}
@@ -78,4 +79,19 @@ public class WrappedPacketInUpdateSign extends WrappedPacket {
writeAnyObject(1, iChatComponents);
}
}
public boolean isFrontText() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
return readBoolean(0);
}
else {
return true;
}
}
public void setFrontText(boolean frontText) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
writeBoolean(0,frontText);
}
}
}
@@ -18,23 +18,29 @@
package io.github.retrooper.packetevents.packetwrappers.play.in.useentity;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.player.Hand;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.utils.vector.Vector3d;
import java.util.Objects;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Optional;
public final class WrappedPacketInUseEntity extends WrappedPacketEntityAbstraction {
private static Class<? extends Enum<?>> enumEntityUseActionClass, enumHandClass;
private static Class<? extends Enum<?>> enumEntityUseActionClass;
private static Class<?> obfuscatedDataInterface, obfuscatedHandContainerClass, obfuscatedTargetAndHandContainerClass;
private static Method getObfuscatedEntityUseActionMethod;
private static boolean v_1_7_10, v_1_9, v_1_17, v_1_20_5;
private EntityUseAction action;
private Object obfuscatedDataObj;
public WrappedPacketInUseEntity(final NMSPacket packet) {
super(packet);
@@ -42,33 +48,73 @@ public final class WrappedPacketInUseEntity extends WrappedPacketEntityAbstracti
@Override
protected void load() {
Class<?> useEntityClass = NMSUtils.getNMSClassWithoutException("PacketPlayInUseEntity");
try {
enumHandClass = NMSUtils.getNMSEnumClass("EnumHand");
} catch (ClassNotFoundException e) {
//Probably a 1.7.10 or 1.8.x server
}
v_1_7_10 = version.isOlderThan(ServerVersion.v_1_8);
v_1_9 = version.isNewerThanOrEquals(ServerVersion.v_1_9);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
v_1_20_5 = version.isNewerThanOrEquals(ServerVersion.v_1_20_5);
try {
enumEntityUseActionClass = NMSUtils.getNMSEnumClass("EnumEntityUseAction");
} catch (ClassNotFoundException e) {
//That is fine, it is probably a subclass
enumEntityUseActionClass = SubclassUtil.getEnumSubClass(useEntityClass, "EnumEntityUseAction");
if (v_1_17) {
enumEntityUseActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "b");
if (v_1_20_5) {
if (enumEntityUseActionClass == null) {
enumEntityUseActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, 3);
}
}
obfuscatedDataInterface = SubclassUtil.getSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "EnumEntityUseAction");
if (v_1_20_5) {
obfuscatedDataInterface = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, 0);
}
obfuscatedHandContainerClass = SubclassUtil.getSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "d");
obfuscatedTargetAndHandContainerClass = SubclassUtil.getSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "e");
if (obfuscatedTargetAndHandContainerClass == null) {
obfuscatedTargetAndHandContainerClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, 2);
}
getObfuscatedEntityUseActionMethod = Reflection.getMethod(obfuscatedDataInterface, enumEntityUseActionClass, 0);
} else {
enumEntityUseActionClass = SubclassUtil.getEnumSubClass(PacketTypeClasses.Play.Client.USE_ENTITY, "EnumEntityUseAction");
}
}
}
public Optional<Vector3d> getTarget() {
if (PacketEvents.get().getServerUtils().getVersion() == ServerVersion.v_1_7_10
|| getAction() != EntityUseAction.INTERACT_AT) {
if (v_1_7_10 || getAction() != EntityUseAction.INTERACT_AT) {
return Optional.empty();
}
Object vec3DObj = readObject(0, NMSUtils.vec3DClass);
Object vec3DObj;
if (v_1_17) {
if (obfuscatedDataObj == null) {
obfuscatedDataObj = readObject(0, obfuscatedDataInterface);
}
if (obfuscatedTargetAndHandContainerClass.isInstance(obfuscatedDataObj)) {
Object obfuscatedTargetAndHandContainerObj = obfuscatedTargetAndHandContainerClass.cast(obfuscatedDataObj);
WrappedPacket wrappedTargetAndHandContainer = new WrappedPacket(new NMSPacket(obfuscatedTargetAndHandContainerObj));
vec3DObj = wrappedTargetAndHandContainer.readObject(0, NMSUtils.vec3DClass);
} else {
return Optional.empty();
}
} else {
vec3DObj = readObject(0, NMSUtils.vec3DClass);
}
WrappedPacket vec3DWrapper = new WrappedPacket(new NMSPacket(vec3DObj));
return Optional.of(new Vector3d(vec3DWrapper.readDouble(0), vec3DWrapper.readDouble(1), vec3DWrapper.readDouble(2)));
}
public void setTarget(Vector3d target) {
if (PacketEvents.get().getServerUtils().getVersion() != ServerVersion.v_1_7_10
&& getAction() == EntityUseAction.INTERACT_AT) {
if (v_1_17) {
Object vec3DObj = NMSUtils.generateVec3D(target.x, target.y, target.z);
if (obfuscatedDataObj == null) {
obfuscatedDataObj = readObject(0, obfuscatedDataInterface);
}
if (obfuscatedTargetAndHandContainerClass.isInstance(obfuscatedDataObj)) {
Object obfuscatedTargetAndHandContainerObj = obfuscatedTargetAndHandContainerClass.cast(obfuscatedDataObj);
WrappedPacket wrappedTargetAndHandContainer = new WrappedPacket(new NMSPacket(obfuscatedTargetAndHandContainerObj));
wrappedTargetAndHandContainer.write(NMSUtils.vec3DClass, 0, vec3DObj);
}
}
else if (v_1_7_10 && getAction() == EntityUseAction.INTERACT_AT) {
Object vec3DObj = NMSUtils.generateVec3D(target.x, target.y, target.z);
write(NMSUtils.vec3DClass, 0, vec3DObj);
}
@@ -76,45 +122,93 @@ public final class WrappedPacketInUseEntity extends WrappedPacketEntityAbstracti
public EntityUseAction getAction() {
if (action == null) {
Enum<?> useActionEnum = readEnumConstant(0, enumEntityUseActionClass);
if (useActionEnum == null) {
//This happens on some weird spigots apparently? Not sure why this field is null.
return EntityUseAction.INTERACT;
Enum<?> useActionEnum;
if (v_1_17) {
if (obfuscatedDataObj == null) {
obfuscatedDataObj = readObject(0, obfuscatedDataInterface);
}
try {
useActionEnum = (Enum<?>) getObfuscatedEntityUseActionMethod.invoke(obfuscatedDataObj);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
} else {
useActionEnum = readEnumConstant(0, (Class<? extends Enum<?>>) enumEntityUseActionClass);
if (useActionEnum == null) {
//This happens on some weird spigots apparently? Not sure why this is null.
return action = EntityUseAction.INTERACT;
}
}
return action = EntityUseAction.valueOf(useActionEnum.name());
return action = EntityUseAction.values()[useActionEnum.ordinal()];
}
return action;
}
public void setAction(EntityUseAction action) {
//TODO Finish this
protected void setAction(EntityUseAction action) {
this.action = action;
Enum<?> enumConst = EnumUtil.valueOf(enumEntityUseActionClass, action.name());
writeEnumConstant(0, enumConst);
Enum<?> enumConst = EnumUtil.valueByIndex((Class<? extends Enum<?>>) enumEntityUseActionClass, action.ordinal());
if (v_1_17) {
//TODO Add 1.17+ support
}
else {
writeEnumConstant(0, enumConst);
}
}
public Hand getHand() {
if ((getAction() == EntityUseAction.INTERACT || getAction() == EntityUseAction.INTERACT_AT)
&& PacketEvents.get().getServerUtils().getVersion().isNewerThan(ServerVersion.v_1_8_8)) {
Object enumHandObj = readObject(0, enumHandClass);
//Should actually never be null, but we will handle such a case
if (enumHandObj == null) {
return Hand.MAIN_HAND;
public Optional<Hand> getHand() {
if (v_1_9 && (getAction() == EntityUseAction.INTERACT || getAction() == EntityUseAction.INTERACT_AT)) {
Enum<?> enumHandConst;
if (v_1_17) {
if (obfuscatedDataObj == null) {
obfuscatedDataObj = readObject(0, obfuscatedDataInterface);
}
if (obfuscatedHandContainerClass.isInstance(obfuscatedDataObj)) {
Object obfuscatedHandContainerObj = obfuscatedHandContainerClass.cast(obfuscatedDataObj);
WrappedPacket wrappedHandContainer = new WrappedPacket(new NMSPacket(obfuscatedHandContainerObj));
enumHandConst = wrappedHandContainer.readEnumConstant(0, NMSUtils.enumHandClass);
} else if (obfuscatedTargetAndHandContainerClass.isInstance(obfuscatedDataObj)) {
Object obfuscatedTargetAndHandContainerObj = obfuscatedTargetAndHandContainerClass.cast(obfuscatedDataObj);
WrappedPacket wrappedTargetAndHandContainer = new WrappedPacket(new NMSPacket(obfuscatedTargetAndHandContainerObj));
enumHandConst = wrappedTargetAndHandContainer.readEnumConstant(0, NMSUtils.enumHandClass);
} else {
return Optional.empty();
}
} else {
enumHandConst = readEnumConstant(0, NMSUtils.enumHandClass);
}
return Hand.valueOf(Objects.requireNonNull(enumHandObj).toString());
//Should actually never be null, but we will handle such a case
if (enumHandConst == null) {
return Optional.empty();
}
return Optional.of(Hand.values()[enumHandConst.ordinal()]);
}
return Hand.MAIN_HAND;
return Optional.empty();
}
public void setHand(Hand hand) {
if (PacketEvents.get().getServerUtils().getVersion().isNewerThanOrEquals(ServerVersion.v_1_9) &&
(getAction() == EntityUseAction.INTERACT || getAction() == EntityUseAction.INTERACT_AT)) {
Enum<?> enumConst = EnumUtil.valueOf(enumHandClass, hand.name());
Enum<?> enumConst = EnumUtil.valueByIndex(NMSUtils.enumHandClass, hand.ordinal());
if (v_1_17) {
if (obfuscatedDataObj == null) {
obfuscatedDataObj = readObject(0, obfuscatedDataInterface);
}
if (obfuscatedHandContainerClass.isInstance(obfuscatedDataObj)) {
Object obfuscatedHandContainerObj = obfuscatedHandContainerClass.cast(obfuscatedDataObj);
WrappedPacket wrappedHandContainer = new WrappedPacket(new NMSPacket(obfuscatedHandContainerObj));
wrappedHandContainer.writeEnumConstant(0, enumConst);
} else if (obfuscatedTargetAndHandContainerClass.isInstance(obfuscatedDataObj)) {
Object obfuscatedTargetAndHandContainerObj = obfuscatedTargetAndHandContainerClass.cast(obfuscatedDataObj);
WrappedPacket wrappedTargetAndHandContainer = new WrappedPacket(new NMSPacket(obfuscatedTargetAndHandContainerObj));
wrappedTargetAndHandContainer.writeEnumConstant(0, enumConst);
}
}
else if (v_1_9 && (getAction() == EntityUseAction.INTERACT || getAction() == EntityUseAction.INTERACT_AT)) {
writeEnumConstant(0, enumConst);
}
}
public enum EntityUseAction {
INTERACT, INTERACT_AT, ATTACK
INTERACT, ATTACK, INTERACT_AT
}
}
@@ -0,0 +1,81 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 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 io.github.retrooper.packetevents.packetwrappers.play.in.useitem;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.player.Hand;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.utils.vector.Vector3i;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class WrappedPacketInUseItem extends WrappedPacket {
private static boolean v_1_14;
public WrappedPacketInUseItem(final NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
v_1_14 = version.isNewerThanOrEquals(ServerVersion.v_1_14);
}
public Hand getHand() {
return Hand.values()[readEnumConstant(0, NMSUtils.enumHandClass).ordinal()];
}
public void setHand(Hand hand) {
Enum<?> enumConstant = EnumUtil.valueByIndex(NMSUtils.enumHandClass, hand.ordinal());
writeEnumConstant(0, enumConstant);
}
public Vector3i getBlockPosition() {
if (v_1_14) {
Object movingBlockPosition = readObject(0, NMSUtils.movingObjectPositionBlockClass);
WrappedPacket movingBlockPositionWrapper = new WrappedPacket(new NMSPacket(movingBlockPosition));
return movingBlockPositionWrapper.readBlockPosition(0);
}
else {
return readBlockPosition(0);
}
}
public void setBlockPosition(Vector3i blockPosition) {
if (v_1_14) {
Object movingBlockPosition = readObject(0, NMSUtils.movingObjectPositionBlockClass);
WrappedPacket movingBlockPositionWrapper = new WrappedPacket(new NMSPacket(movingBlockPosition));
movingBlockPositionWrapper.writeBlockPosition(0, blockPosition);
}
else {
writeBlockPosition(0, blockPosition);
}
}
@Override
public boolean isSupported() {
return version.isNewerThanOrEquals(ServerVersion.v_1_9);
}
}
@@ -37,7 +37,6 @@ public class WrappedPacketInVehicleMove extends WrappedPacket {
writeDouble(2, position.z);
}
//TODO Cut off at 1.8.1
@Deprecated
public double getX() {
return readDouble(0);
@@ -18,140 +18,77 @@
package io.github.retrooper.packetevents.packetwrappers.play.in.windowclick;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class WrappedPacketInWindowClick extends WrappedPacket {
private static final HashMap<Integer, ArrayList<WindowClickType>> WINDOW_CLICK_TYPE_CACHE = new HashMap<>();
private static boolean legacy, v_1_17;
private static Class<? extends Enum<?>> invClickTypeClass;
private static boolean isClickModePrimitive;
public WrappedPacketInWindowClick(NMSPacket packet) {
super(packet);
}
private static ArrayList<WindowClickType> getArrayListOfWindowClickTypes(WindowClickType... types) {
ArrayList<WindowClickType> arrayList = new ArrayList<>(types.length);
arrayList.addAll(Arrays.asList(types));
return arrayList;
}
@Override
protected void load() {
Class<?> packetClass = PacketTypeClasses.Play.Client.WINDOW_CLICK;
legacy = version.isOlderThanOrEquals(ServerVersion.v_1_8_8);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
invClickTypeClass = NMSUtils.getNMSEnumClassWithoutException("InventoryClickType");
//MODE 0
WINDOW_CLICK_TYPE_CACHE.put(0, getArrayListOfWindowClickTypes(WindowClickType.LEFT_MOUSE_CLICK,
WindowClickType.RIGHT_MOUSE_CLICK));
//MODE 1
WINDOW_CLICK_TYPE_CACHE.put(1, getArrayListOfWindowClickTypes(WindowClickType.SHIFT_LEFT_MOUSE_CLICK,
WindowClickType.SHIFT_RIGHT_MOUSE_CLICK));
//MODE 2
WINDOW_CLICK_TYPE_CACHE.put(2, getArrayListOfWindowClickTypes(
WindowClickType.KEY_NUMBER1,
WindowClickType.KEY_NUMBER2,
WindowClickType.KEY_NUMBER3,
WindowClickType.KEY_NUMBER4,
WindowClickType.KEY_NUMBER5,
WindowClickType.KEY_NUMBER6,
WindowClickType.KEY_NUMBER7,
WindowClickType.KEY_NUMBER8,
WindowClickType.KEY_NUMBER9));
//MODE 3
WINDOW_CLICK_TYPE_CACHE.put(3, getArrayListOfWindowClickTypes(WindowClickType.UNKNOWN, WindowClickType.UNKNOWN, WindowClickType.CREATIVE_MIDDLE_CLICK));
//MODE 4
WINDOW_CLICK_TYPE_CACHE.put(4, getArrayListOfWindowClickTypes(WindowClickType.KEY_DROP,
WindowClickType.KEY_DROP_STACK));
//MODE 5
WINDOW_CLICK_TYPE_CACHE.put(5, getArrayListOfWindowClickTypes(
WindowClickType.STARTING_LEFT_MOUSE_DRAG,
WindowClickType.ADD_SLOT_LEFT_MOUSE_DRAG,
WindowClickType.ENDING_LEFT_MOUSE_DRAG,
WindowClickType.UNKNOWN,
WindowClickType.STARTING_RIGHT_MOUSE_DRAG,
WindowClickType.ADD_SLOT_RIGHT_MOUSE_DRAG,
WindowClickType.CREATIVE_STARTING_MIDDLE_MOUSE_DRAG,
WindowClickType.ADD_SLOT_MIDDLE_MOUSE_DRAG,
WindowClickType.ENDING_MIDDLE_MOUSE_DRAG));
WINDOW_CLICK_TYPE_CACHE.put(6, getArrayListOfWindowClickTypes(WindowClickType.DOUBLE_CLICK));
isClickModePrimitive = Reflection.getField(packetClass, int.class, 3) != null;
if (invClickTypeClass == null) {
invClickTypeClass = NMSUtils.getNMEnumClassWithoutException("world.inventory.InventoryClickType");
}
}
// Unique ID for the inventory, 0 for player's inventory
public int getWindowId() {
return readInt(0);
return readInt(v_1_17 ? 1 : 0);
}
public void setWindowId(int windowID) {
writeInt(0, windowID);
writeInt(v_1_17 ? 1 : 0, windowID);
}
// Id of clicked slot
public int getWindowSlot() {
return readInt(1);
return readInt(v_1_17 ? 3 : 1);
}
public void setWindowSlot(int slot) {
writeInt(1, slot);
writeInt(v_1_17 ? 3 : 1, slot);
}
// Left or right click
public int getWindowButton() {
return readInt(2);
return readInt(v_1_17 ? 4 : 2);
}
public void setWindowButton(int button) {
writeInt(2, button);
writeInt(v_1_17 ? 4 : 2, button);
}
public short getActionNumber() {
// Used to sync together client and server
public int getActionNumber() {
if (v_1_17) {
return readInt(2);
}
return readShort(0);
}
public void setActionNumber(short actionNumber) {
writeShort(0, actionNumber);
}
@Deprecated
public WindowClickType getWindowClickType() {
int mode = getMode();
if (WINDOW_CLICK_TYPE_CACHE.get(mode) == null) {
return WindowClickType.UNKNOWN;
}
int windowButton = getWindowButton();
if (windowButton + 1 > WINDOW_CLICK_TYPE_CACHE.size()) {
return WindowClickType.UNKNOWN;
}
if (mode == 4) {
int windowSlot = getWindowSlot();
if (windowSlot == -999) {
if (windowButton == 0) {
return WindowClickType.LEFT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING;
} else if (windowButton == 1) {
return WindowClickType.RIGHT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING;
}
}
}
return WINDOW_CLICK_TYPE_CACHE.get(mode).get(windowButton);
public void setActionNumber(int actionNumber) {
if (v_1_17) {
writeInt(2, actionNumber);
} else {
writeShort(0, (short) actionNumber);
}
}
// Type of click - shift clicking, hotbar, drag, pickup...
public int getMode() {
if (isClickModePrimitive) {
if(legacy) {
return readInt(3);
} else {
Enum<?> enumConst = readEnumConstant(0, invClickTypeClass);
@@ -160,7 +97,7 @@ public class WrappedPacketInWindowClick extends WrappedPacket {
}
public void setMode(int mode) {
if (isClickModePrimitive) {
if(legacy) {
writeInt(3, mode);
} else {
Enum<?> enumConst = EnumUtil.valueByIndex(invClickTypeClass, mode);
@@ -174,42 +111,10 @@ public class WrappedPacketInWindowClick extends WrappedPacket {
* @return Get Clicked ItemStack
*/
public ItemStack getClickedItemStack() {
Object nmsItemStack = readObject(0, NMSUtils.nmsItemStackClass);
return NMSUtils.toBukkitItemStack(nmsItemStack);
return readItemStack(0);
}
public void setClickedItemStack(ItemStack stack) {
Object nmsItemStack = NMSUtils.toNMSItemStack(stack);
write(NMSUtils.nmsItemStackClass, 0, nmsItemStack);
}
@Deprecated
public enum WindowClickType {
LEFT_MOUSE_CLICK, RIGHT_MOUSE_CLICK,
SHIFT_LEFT_MOUSE_CLICK, SHIFT_RIGHT_MOUSE_CLICK,
CREATIVE_MIDDLE_CLICK, CREATIVE_STARTING_MIDDLE_MOUSE_DRAG,
KEY_NUMBER1, KEY_NUMBER2, KEY_NUMBER3, KEY_NUMBER4,
KEY_NUMBER5, KEY_NUMBER6, KEY_NUMBER7, KEY_NUMBER8,
KEY_NUMBER9, KEY_DROP, KEY_DROP_STACK,
LEFT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING,
RIGHT_CLICK_OUTSIDE_WINDOW_HOLDING_NOTHING,
STARTING_LEFT_MOUSE_DRAG,
STARTING_RIGHT_MOUSE_DRAG,
ADD_SLOT_LEFT_MOUSE_DRAG,
ADD_SLOT_RIGHT_MOUSE_DRAG,
ADD_SLOT_MIDDLE_MOUSE_DRAG,
ENDING_LEFT_MOUSE_DRAG,
ENDING_RIGHT_MOUSE_DRAG,
ENDING_MIDDLE_MOUSE_DRAG,
DOUBLE_CLICK,
UNKNOWN
writeItemStack(0, stack);
}
}
@@ -49,11 +49,10 @@ public final class WrappedPacketOutAbilities extends WrappedPacket implements Se
@Override
protected void load() {
Class<?> packetClass = PacketTypeClasses.Play.Server.ABILITIES;
try {
playerAbilitiesClass = NMSUtils.getNMSClass("PlayerAbilities");
} catch (ClassNotFoundException e) {
e.printStackTrace();
playerAbilitiesClass = NMSUtils.getNMClassWithoutException("world.entity.player.PlayerAbilities");
}
if (playerAbilitiesClass != null) {
@@ -65,7 +64,7 @@ public final class WrappedPacketOutAbilities extends WrappedPacket implements Se
}
try {
packetConstructor = packetClass.getConstructor(playerAbilitiesClass);
packetConstructor = PacketTypeClasses.Play.Server.ABILITIES.getConstructor(playerAbilitiesClass);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -18,30 +18,35 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.animation;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.entity.Entity;
import java.lang.reflect.Constructor;
public final class WrappedPacketOutAnimation extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static Constructor<?> animationConstructor;
private static boolean v_1_17;
private static Constructor<?> packetConstructor;
private EntityAnimationType type;
public WrappedPacketOutAnimation(final NMSPacket packet) {
super(packet);
super(packet, v_1_17 ? 6 : 0);
}
public WrappedPacketOutAnimation(final Entity target, final EntityAnimationType type) {
super(v_1_17 ? 6 : 0);
this.entityID = target.getEntityId();
this.entity = target;
this.type = type;
}
public WrappedPacketOutAnimation(final int entityID, final EntityAnimationType type) {
super(v_1_17 ? 6 : 0);
this.entityID = entityID;
this.entity = null;
this.type = type;
@@ -49,10 +54,14 @@ public final class WrappedPacketOutAnimation extends WrappedPacketEntityAbstract
@Override
protected void load() {
Class<?> animationClass = PacketTypeClasses.Play.Server.ANIMATION;
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
try {
animationConstructor = animationClass.getConstructor(NMSUtils.nmsEntityClass, int.class);
if (v_1_17) {
packetConstructor = PacketTypeClasses.Play.Server.ANIMATION.getConstructor(NMSUtils.packetDataSerializerClass);
}
else {
packetConstructor = PacketTypeClasses.Play.Server.ANIMATION.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -60,8 +69,8 @@ public final class WrappedPacketOutAnimation extends WrappedPacketEntityAbstract
public EntityAnimationType getAnimationType() {
if (packet != null) {
byte id = (byte) readInt(1);
return EntityAnimationType.getById(id);
byte id = (byte) readInt(v_1_17 ? 7 : 1);
return EntityAnimationType.values()[id];
} else {
return type;
}
@@ -69,7 +78,7 @@ public final class WrappedPacketOutAnimation extends WrappedPacketEntityAbstract
public void setAnimationType(EntityAnimationType type) {
if (packet != null) {
writeInt(1, type.ordinal());
writeInt(v_1_17 ? 7 : 1, type.ordinal());
} else {
this.type = type;
}
@@ -77,21 +86,23 @@ public final class WrappedPacketOutAnimation extends WrappedPacketEntityAbstract
@Override
public Object asNMSPacket() throws Exception {
final Object nmsEntity = NMSUtils.getNMSEntity(getEntity());
final int index = getAnimationType().ordinal();
return animationConstructor.newInstance(nmsEntity, index);
Object packetInstance;
if (v_1_17) {
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(PacketEvents.get().getByteBufUtil().newByteBuf(
new byte[] {0, 0, 0, 0, 0, 0, 0, 0}));
packetInstance = packetConstructor.newInstance(packetDataSerializer);
}
else {
packetInstance = packetConstructor.newInstance();
}
WrappedPacketOutAnimation animation = new WrappedPacketOutAnimation(new NMSPacket(packetInstance));
animation.setEntityId(getEntityId());
animation.setAnimationType(getAnimationType());
return packetInstance;
}
public enum EntityAnimationType {
SWING_MAIN_ARM, TAKE_DAMAGE, LEAVE_BED,
SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT;
EntityAnimationType() {
}
public static EntityAnimationType getById(byte id) {
return values()[id]; //id is at the same time the index
}
SWING_OFFHAND, CRITICAL_EFFECT, MAGIC_CRITICAL_EFFECT
}
}
@@ -1,3 +1,21 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 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 io.github.retrooper.packetevents.packetwrappers.play.out.bedit;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
@@ -12,14 +30,20 @@ import java.util.Optional;
/**
* @author Tecnio
* @see <a href="https://wiki.vg/Protocol#Edit_Book"</a>
*/
public class WrappedPacketInBEdit extends WrappedPacket {
private static boolean v_1_13, v_1_17;
public WrappedPacketInBEdit(final NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
v_1_13 = version.isNewerThanOrEquals(ServerVersion.v_1_13);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
}
public ItemStack getItemStack() {
return readItemStack(0);
}
@@ -36,9 +60,11 @@ public class WrappedPacketInBEdit extends WrappedPacket {
writeBoolean(0, signing);
}
@SupportedVersions(ranges = {ServerVersion.v_1_13, ServerVersion.v_1_16_5})
@SupportedVersions(ranges = {ServerVersion.v_1_13, ServerVersion.ERROR})
public Optional<Hand> getHand() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_13)) {
if (v_1_17) {
return Optional.of(Hand.values()[readInt(0)]);
} else if (v_1_13) {
final Enum<?> enumConst = readEnumConstant(0, NMSUtils.enumHandClass);
return Optional.of(Hand.valueOf(enumConst.name()));
}
@@ -46,9 +72,11 @@ public class WrappedPacketInBEdit extends WrappedPacket {
return Optional.empty();
}
@SupportedVersions(ranges = {ServerVersion.v_1_13, ServerVersion.v_1_16_5})
@SupportedVersions(ranges = {ServerVersion.v_1_13, ServerVersion.ERROR})
public void setHand(final Hand hand) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_13)) {
if (v_1_17) {
writeInt(0, hand.ordinal());
} else if (v_1_13) {
final Enum<?> enumConst = EnumUtil.valueOf(NMSUtils.enumHandClass, hand.name());
writeEnumConstant(0, enumConst);
}
@@ -32,59 +32,45 @@ import java.lang.reflect.Constructor;
* This packet is used for a number of actions and animations performed by blocks, usually non-persistent.
*
* @author Tecnio
* @see <a href="https://wiki.vg/Protocol#Block_Action"</a>
*/
public class WrappedPacketOutBlockAction extends WrappedPacket implements SendableWrapper {
private static Constructor<?> packetConstructor;
private Vector3i blockPos;
private int action, actionParam;
private Material material;
private int actionID, actionData;
private Material blockType;
public WrappedPacketOutBlockAction(final NMSPacket packet) {
public WrappedPacketOutBlockAction(NMSPacket packet) {
super(packet);
}
public WrappedPacketOutBlockAction(final Vector3i blockPos, final int action, final int actionParam, final Material material) {
public WrappedPacketOutBlockAction(Vector3i blockPos, int actionID, int actionData, Material blockType) {
this.blockPos = blockPos;
this.action = action;
this.actionParam = actionParam;
this.material = material;
this.actionID = actionID;
this.actionData = actionData;
this.blockType = blockType;
}
@Override
protected void load() {
try {
packetConstructor = PacketTypeClasses.Play.Server.BLOCK_ACTION.getConstructors()[1];
} catch (final Exception e) {
packetConstructor = PacketTypeClasses.Play.Server.BLOCK_ACTION.getConstructor(NMSUtils.blockPosClass, NMSUtils.blockClass, int.class, int.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public Vector3i getBlockPosition() {
if (packet != null) {
final Vector3i blockPos = new Vector3i();
final Object blockPosObj = readObject(0, NMSUtils.blockPosClass);
try {
blockPos.x = (int) NMSUtils.getBlockPosX.invoke(blockPosObj);
blockPos.y = (int) NMSUtils.getBlockPosY.invoke(blockPosObj);
blockPos.z = (int) NMSUtils.getBlockPosZ.invoke(blockPosObj);
} catch (final Exception e) {
e.printStackTrace();
}
return blockPos;
return readBlockPosition(0);
} else {
return this.blockPos;
}
}
public void setBlockPosition(final Vector3i blockPos) {
public void setBlockPosition(Vector3i blockPos) {
if (packet != null) {
final Object nmsBlockPos = NMSUtils.generateNMSBlockPos(blockPos);
write(NMSUtils.blockPosClass, 0, nmsBlockPos);
writeBlockPosition(0, blockPos);
} else {
this.blockPos = blockPos;
}
@@ -94,31 +80,41 @@ public class WrappedPacketOutBlockAction extends WrappedPacket implements Sendab
if (packet != null) {
return readInt(0);
} else {
return this.action;
return this.actionID;
}
}
public void setActionId(final int actionId) {
public void setActionId(int actionID) {
if (packet != null) {
writeInt(0, actionId);
writeInt(0, actionID);
} else {
this.action = actionId;
this.actionID = actionID;
}
}
@Deprecated
public int getActionParam() {
return getActionData();
}
@Deprecated
public void setActionParam(int actionParam) {
setActionData(actionParam);
}
public int getActionData() {
if (packet != null) {
return readInt(1);
} else {
return this.actionParam;
return this.actionData;
}
}
public void setActionParam(final int actionParam) {
public void setActionData(int actionData) {
if (packet != null) {
writeInt(1, actionParam);
writeInt(1, actionData);
} else {
this.actionParam = actionParam;
this.actionData = actionData;
}
}
@@ -126,26 +122,23 @@ public class WrappedPacketOutBlockAction extends WrappedPacket implements Sendab
if (packet != null) {
return NMSUtils.getMaterialFromNMSBlock(readObject(0, NMSUtils.blockClass));
} else {
return this.material;
return this.blockType;
}
}
public void setBlockType(final Material material) {
public void setBlockType(Material blockType) {
if (packet != null) {
final Object nmsBlock = NMSUtils.getNMSBlockFromMaterial(material);
final Object nmsBlock = NMSUtils.getNMSBlockFromMaterial(blockType);
write(NMSUtils.blockClass, 0, nmsBlock);
} else {
this.material = material;
this.blockType = blockType;
}
}
@Override
public Object asNMSPacket() throws Exception {
final Object nmsBlockPos = NMSUtils.generateNMSBlockPos(blockPos);
final Object nmsBlock = NMSUtils.getNMSBlockFromMaterial(material);
return packetConstructor.newInstance(
nmsBlockPos, nmsBlock, action, actionParam
);
Object nmsBlockPos = NMSUtils.generateNMSBlockPos(getBlockPosition());
Object nmsBlock = NMSUtils.getNMSBlockFromMaterial(getBlockType());
return packetConstructor.newInstance(nmsBlockPos, nmsBlock, getActionId(), getActionData());
}
}
@@ -31,6 +31,7 @@ import java.lang.reflect.Constructor;
public class WrappedPacketOutBlockBreakAnimation extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static Constructor<?> packetConstructor;
private static boolean v_1_7_10;
private Vector3i blockPosition;
private int destroyStage;
@@ -53,6 +54,7 @@ public class WrappedPacketOutBlockBreakAnimation extends WrappedPacketEntityAbst
@Override
protected void load() {
v_1_7_10 = version.isOlderThan(ServerVersion.v_1_8);
try {
packetConstructor = PacketTypeClasses.Play.Server.BLOCK_BREAK_ANIMATION.getConstructor(int.class, int.class, int.class, int.class, int.class);
} catch (NoSuchMethodException e) {
@@ -66,7 +68,7 @@ public class WrappedPacketOutBlockBreakAnimation extends WrappedPacketEntityAbst
public Vector3i getBlockPosition() {
if (packet != null) {
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
int x = readInt(1);
int y = readInt(2);
int z = readInt(3);
@@ -81,7 +83,7 @@ public class WrappedPacketOutBlockBreakAnimation extends WrappedPacketEntityAbst
public void setBlockPosition(Vector3i blockPosition) {
if (packet != null) {
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
writeInt(1, blockPosition.x);
writeInt(2, blockPosition.y);
writeInt(3, blockPosition.z);
@@ -95,7 +97,7 @@ public class WrappedPacketOutBlockBreakAnimation extends WrappedPacketEntityAbst
public int getDestroyStage() {
if (packet != null) {
int index = version.isOlderThan(ServerVersion.v_1_8) ? 4 : 1;
int index = v_1_7_10 ? 4 : 1;
return readInt(index);
} else {
return this.destroyStage;
@@ -104,7 +106,7 @@ public class WrappedPacketOutBlockBreakAnimation extends WrappedPacketEntityAbst
public void setDestroyStage(int destroyStage) {
if (packet != null) {
int index = version.isOlderThan(ServerVersion.v_1_8) ? 4 : 1;
int index = v_1_7_10 ? 4 : 1;
writeInt(index, destroyStage);
} else {
this.destroyStage = destroyStage;
@@ -114,7 +116,7 @@ public class WrappedPacketOutBlockBreakAnimation extends WrappedPacketEntityAbst
@Override
public Object asNMSPacket() throws Exception {
Vector3i blockPosition = getBlockPosition();
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
return packetConstructor.newInstance(getEntityId(), blockPosition.x, blockPosition.y, blockPosition.z, getDestroyStage());
} else {
Object nmsBlockPos = NMSUtils.generateNMSBlockPos(blockPosition);
@@ -35,13 +35,14 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class WrappedPacketOutBlockChange extends WrappedPacket implements SendableWrapper {
private static boolean v_1_7_10, v_1_17;
private static Constructor<?> packetConstructor;
private static Method getNMSBlockMethodCache = null;
private static Method getNMSWorldTypeMethodCache = null;
private Vector3i blockPos;
private World world;
private Material material;
private Material blockType;
public WrappedPacketOutBlockChange(NMSPacket packet) {
super(packet);
@@ -57,21 +58,37 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
this.world = location.getWorld();
}
public WrappedPacketOutBlockChange(World world, Vector3i blockPos, Material material) {
public WrappedPacketOutBlockChange(World world, Vector3i blockPos, Material blockType) {
this(world, blockPos);
this.material = material;
this.blockType = blockType;
}
public WrappedPacketOutBlockChange(Location location, Material material) {
public WrappedPacketOutBlockChange(Location location, Material blockType) {
this(location);
this.material = material;
this.blockType = blockType;
}
@Override
protected void load() {
getNMSBlockMethodCache = Reflection.getMethod(NMSUtils.iBlockDataClass, "getBlock", 0);
if (getNMSBlockMethodCache == null) {
Class<?> blockDataClass = NMSUtils.iBlockDataClass.getSuperclass();
getNMSBlockMethodCache = Reflection.getMethod(blockDataClass, NMSUtils.blockClass, 0);
}
getNMSWorldTypeMethodCache = Reflection.getMethod(NMSUtils.nmsWorldClass, "getType", 0);
if (version.equals(ServerVersion.v_1_7_10)) {
if (getNMSWorldTypeMethodCache == null) {
getNMSWorldTypeMethodCache = Reflection.getMethod(NMSUtils.nmsWorldClass,
"getBlockStateIfLoaded", 0);
}
v_1_7_10 = version.isOlderThan(ServerVersion.v_1_8);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
if (v_1_17) {
try {
packetConstructor = PacketTypeClasses.Play.Server.BLOCK_CHANGE.getConstructor(NMSUtils.blockPosClass, NMSUtils.iBlockDataClass);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
} else if (v_1_7_10) {
try {
packetConstructor = PacketTypeClasses.Play.Server.BLOCK_CHANGE.getConstructor(int.class, int.class, int.class, NMSUtils.nmsWorldClass);
} catch (NoSuchMethodException e) {
@@ -88,7 +105,7 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
public Vector3i getBlockPosition() {
if (packet != null) {
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
int x = readInt(0);
int y = readInt(1);
int z = readInt(2);
@@ -104,7 +121,7 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
public void setBlockPosition(Vector3i blockPos) {
if (packet != null) {
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
writeInt(0, blockPos.x);
writeInt(1, blockPos.y);
writeInt(2, blockPos.z);
@@ -116,10 +133,20 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
}
}
@Deprecated
public Material getMaterial() {
return getBlockType();
}
@Deprecated
public void setMaterial(Material material) {
setBlockType(material);
}
public Material getBlockType() {
if (packet != null) {
Object nmsBlock = null;
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
nmsBlock = readObject(0, NMSUtils.blockClass);
} else {
Object iBlockDataObj = readObject(0, NMSUtils.iBlockDataClass);
@@ -131,14 +158,14 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
}
return NMSUtils.getMaterialFromNMSBlock(nmsBlock);
} else {
return material;
return blockType;
}
}
public void setMaterial(Material material) {
public void setBlockType(Material blockType) {
if (packet != null) {
Object nmsBlock = NMSUtils.getNMSBlockFromMaterial(material);
if (version.isOlderThan(ServerVersion.v_1_8)) {
Object nmsBlock = NMSUtils.getNMSBlockFromMaterial(blockType);
if (v_1_7_10) {
write(NMSUtils.blockClass, 0, nmsBlock);
} else {
WrappedPacket nmsBlockWrapper = new WrappedPacket(new NMSPacket(nmsBlock), NMSUtils.blockClass);
@@ -146,7 +173,7 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
write(NMSUtils.iBlockDataClass, 0, iBlockData);
}
} else {
this.material = material;
this.blockType = blockType;
}
}
@@ -155,19 +182,27 @@ public class WrappedPacketOutBlockChange extends WrappedPacket implements Sendab
Object packetPlayOutBlockChangeInstance;
WrappedPacketOutBlockChange blockChange;
Vector3i blockPosition = getBlockPosition();
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_17) {
Object nmsBlockPos = NMSUtils.generateNMSBlockPos(blockPosition);
Object nmsBlock = NMSUtils.getNMSBlockFromMaterial(getBlockType());
WrappedPacket nmsBlockWrapper = new WrappedPacket(new NMSPacket(nmsBlock), NMSUtils.blockClass);
Object nmsIBlockData = nmsBlockWrapper.readObject(0, NMSUtils.iBlockDataClass);
packetPlayOutBlockChangeInstance = packetConstructor.newInstance(nmsBlockPos, nmsIBlockData);
} else if (v_1_7_10) {
Object nmsWorld = NMSUtils.convertBukkitWorldToWorldServer(world);
packetPlayOutBlockChangeInstance = packetConstructor.newInstance(blockPosition.x, blockPosition.y, blockPosition.z, nmsWorld);
blockChange = new WrappedPacketOutBlockChange(new NMSPacket(packetPlayOutBlockChangeInstance));
if (getMaterial() != null) {
blockChange.setMaterial(getMaterial());
Material bt = getBlockType();
if (bt != null) {
blockChange.setBlockType(bt);
}
} else {
packetPlayOutBlockChangeInstance = packetConstructor.newInstance();
blockChange = new WrappedPacketOutBlockChange(new NMSPacket(packetPlayOutBlockChangeInstance));
if (getMaterial() != null) {
blockChange.setMaterial(getMaterial());
Material bt = getBlockType();
if (bt != null) {
blockChange.setBlockType(bt);
} else {
Object nmsBlockPos = NMSUtils.generateNMSBlockPos(blockPosition);
Object worldServer = NMSUtils.convertBukkitWorldToWorldServer(world);
@@ -18,55 +18,66 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.camera;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.Constructor;
public class WrappedPacketOutCamera extends WrappedPacket implements SendableWrapper {
public class WrappedPacketOutCamera extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static boolean v_1_17;
private static Constructor<?> packetConstructor;
private int cameraID;
public WrappedPacketOutCamera(NMSPacket packet) {
super(packet);
}
public WrappedPacketOutCamera(int cameraID) {
this.cameraID = cameraID;
public WrappedPacketOutCamera(int entityID) {
setEntityId(entityID);
}
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
try {
packetConstructor = PacketTypeClasses.Play.Server.CAMERA.getConstructor();
if (v_1_17) {
packetConstructor = PacketTypeClasses.Play.Server.CAMERA.getConstructor(NMSUtils.packetDataSerializerClass);
} else {
packetConstructor = PacketTypeClasses.Play.Server.CAMERA.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Deprecated
public int getCameraId() {
if (packet != null) {
return readInt(0);
}
return cameraID;
return getEntityId();
}
@Deprecated
public void setCameraId(int cameraID) {
if (packet != null) {
writeInt(0, cameraID);
} else {
this.cameraID = cameraID;
}
setEntityId(cameraID);
}
@Override
public Object asNMSPacket() throws Exception {
Object packetInstance = packetConstructor.newInstance();
Object packetInstance;
if (v_1_17) {
//You call it lazy, I call it smart
Object byteBuf = PacketEvents.get().getByteBufUtil().newByteBuf(new byte[]{1});
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(byteBuf);
packetInstance = packetConstructor.newInstance(packetDataSerializer);
} else {
packetInstance = packetConstructor.newInstance();
}
WrappedPacket packetWrapper = new WrappedPacket(new NMSPacket(packetInstance));
packetWrapper.writeInt(0, getCameraId());
packetWrapper.writeInt(0, getEntityId());
return packetInstance;
}
@@ -22,19 +22,24 @@ import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.utils.enums.EnumUtil;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.*;
public final class WrappedPacketOutChat extends WrappedPacket implements SendableWrapper {
private static Constructor<?> chatClassConstructor;
private static Class<?> packetClass, iChatBaseComponentClass, chatMessageTypeEnum;
private static Method chatMessageTypeCreatorMethod;
private static Class<? extends Enum<?>> chatMessageTypeEnum;
private static Class<?> PLAYER_CHAT_MESSAGE_CLASS, SIGNED_MESSAGE_BODY_CLASS,
CHAT_MESSAGE_CONTENT_CLASS, CHAT_MESSAGE_TYPE_CLASS, NETWORK_BOUND_CHAT_TYPE_CLASS;
//0 = IChatBaseComponent, Byte
//1 = IChatBaseComponent, Int
//2 = IChatBaseComponent, ChatMessageType
@@ -68,66 +73,71 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
@Override
protected void load() {
try {
packetClass = PacketTypeClasses.Play.Server.CHAT;
iChatBaseComponentClass = NMSUtils.getNMSClass("IChatBaseComponent");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
boolean isVeryOutdated = false;
try {
chatMessageTypeEnum = NMSUtils.getNMSClass("ChatMessageType");
} catch (ClassNotFoundException e) {
isVeryOutdated = true;
}
if (!isVeryOutdated) {
chatMessageTypeCreatorMethod = Reflection.getMethod(chatMessageTypeEnum, 0, byte.class);
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, chatMessageTypeEnum);
constructorMode = 2;
} catch (NoSuchMethodException e) {
//Just a much newer version(1.16.x and above right now)
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, chatMessageTypeEnum, UUID.class);
constructorMode = 3;
} catch (NoSuchMethodException e2) {
//Failed to resolve the constructor
e2.printStackTrace();
}
Class<?> packetClass = PacketTypeClasses.Play.Server.CHAT;
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
PLAYER_CHAT_MESSAGE_CLASS = NMSUtils.getNMClassWithoutException("network.chat.PlayerChatMessage");
SIGNED_MESSAGE_BODY_CLASS = NMSUtils.getNMClassWithoutException("network.chat.SignedMessageBody");
CHAT_MESSAGE_CONTENT_CLASS = NMSUtils.getNMClassWithoutException("network.chat.ChatMessageContent");
CHAT_MESSAGE_TYPE_CLASS = NMSUtils.getNMClassWithoutException("network.chat.ChatMessageType");
NETWORK_BOUND_CHAT_TYPE_CLASS = SubclassUtil.getSubClass(CHAT_MESSAGE_TYPE_CLASS, 1);
}
} else {
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, byte.class);
constructorMode = 0;
} catch (NoSuchMethodException e) {
//That is fine, they are most likely on an older version.
//Cause we read getChatPosition using constructor mode
constructorMode = 4;
}
else {
chatMessageTypeEnum = NMSUtils.getNMSEnumClassWithoutException("ChatMessageType");
if (chatMessageTypeEnum == null) {
chatMessageTypeEnum = NMSUtils.getNMEnumClassWithoutException("network.chat.ChatMessageType");
}
if (chatMessageTypeEnum != null) {
try {
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass, int.class);
constructorMode = 1;
} catch (NoSuchMethodException e2) {
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, chatMessageTypeEnum);
constructorMode = 2;
} catch (NoSuchMethodException e) {
//Just a much newer version(1.16.x and above right now)
try {
//Some weird 1.7.10 spigots remove that int parameter for no reason, I won't keep adding support for any more spigots and might stop
//accepting pull requests for support for spigots breaking things that normal spigot has.
chatClassConstructor = packetClass.getConstructor(iChatBaseComponentClass);
constructorMode = -1;
} catch (NoSuchMethodException noSuchMethodException) {
noSuchMethodException.printStackTrace();
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, chatMessageTypeEnum, UUID.class);
constructorMode = 3;
} catch (NoSuchMethodException e2) {
//Failed to resolve the constructor
e2.printStackTrace();
}
}
} else {
try {
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, byte.class);
constructorMode = 0;
} catch (NoSuchMethodException e) {
//That is fine, they are most likely on an older version.
try {
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass, int.class);
constructorMode = 1;
} catch (NoSuchMethodException e2) {
try {
//Some weird 1.7.10 spigots remove that int parameter for no reason, I won't keep adding support for any more spigots and might stop
//accepting pull requests for support for spigots breaking things that normal spigot has.
chatClassConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass);
constructorMode = -1;
} catch (NoSuchMethodException e3) {
e3.printStackTrace();
}
}
}
}
}
}
@Override
public Object asNMSPacket() throws Exception {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
throw new IllegalStateException("You are trying to send the WrappedPacketOutChat packet on 1.19 or above. Please update to packetevents 2.0, this is not supported.");
}
byte chatPos = (byte) getChatPosition().ordinal();
Object chatMessageTypeInstance = null;
Enum<?> chatMessageTypeInstance = null;
if (chatMessageTypeEnum != null) {
chatMessageTypeInstance = chatMessageTypeCreatorMethod.invoke(null, chatPos);
chatMessageTypeInstance = EnumUtil.valueByIndex(chatMessageTypeEnum, chatPos);
}
switch (constructorMode) {
case -1:
@@ -152,13 +162,72 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
*/
public String getMessage() {
if (packet != null) {
final Object iChatBaseObj = readObject(0, iChatBaseComponentClass);
return NMSUtils.readIChatBaseComponent(iChatBaseObj);
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
Object signedMessageBody = playerChatMessageWrapper.readObject(0, SIGNED_MESSAGE_BODY_CLASS);
WrappedPacket wrappedSignedMessageBody = new WrappedPacket(new NMSPacket(signedMessageBody));
Object chatMessageContent = wrappedSignedMessageBody.readObject(0, CHAT_MESSAGE_CONTENT_CLASS);
WrappedPacket wrappedChatMessage = new WrappedPacket(new NMSPacket(chatMessageContent));
return wrappedChatMessage.readIChatBaseComponent(0);
}
return readIChatBaseComponent(0);
} else {
return message;
}
}
public void setMessage(String message) {
if (packet != null) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
Object signedMessageBody = playerChatMessageWrapper.readObject(0, SIGNED_MESSAGE_BODY_CLASS);
WrappedPacket wrappedSignedMessageBody = new WrappedPacket(new NMSPacket(signedMessageBody));
Object chatMessageContent = wrappedSignedMessageBody.readObject(0, CHAT_MESSAGE_CONTENT_CLASS);
WrappedPacket wrappedChatMessage = new WrappedPacket(new NMSPacket(chatMessageContent));
wrappedChatMessage.writeIChatBaseComponent(0, message);
return;
}
writeIChatBaseComponent(0, message);
} else {
this.message = message;
}
}
public Optional<String> getUnsignedMessage() {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
Optional<?> opt = playerChatMessageWrapper.readObject(0, Optional.class);
if (opt.isPresent()) {
Object iChatBaseComponent = opt.get();
return Optional.ofNullable(NMSUtils.readIChatBaseComponent(iChatBaseComponent));
}
}
else if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
Optional<?> opt = readObject(0, Optional.class);
if (opt.isPresent()) {
Object iChatBaseComponent = opt.get();
return Optional.ofNullable(NMSUtils.readIChatBaseComponent(iChatBaseComponent));
}
}
return Optional.empty();
}
public void setUnsignedMessage(String unsignedMessage) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
Object playerChatMessage = readObject(0, PLAYER_CHAT_MESSAGE_CLASS);
WrappedPacket playerChatMessageWrapper = new WrappedPacket(new NMSPacket(playerChatMessage));
Object iChatBaseComponent = NMSUtils.generateIChatBaseComponent(unsignedMessage);
playerChatMessageWrapper.write(Optional.class, 0, Optional.ofNullable(iChatBaseComponent));
}
else if (version.isNewerThanOrEquals(ServerVersion.v_1_19)) {
Object iChatBaseComponent = NMSUtils.generateIChatBaseComponent(unsignedMessage);
write(Optional.class, 0, Optional.ofNullable(iChatBaseComponent));
}
}
/**
* Get the chat position.
* <p>
@@ -172,7 +241,7 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
byte chatPositionValue;
switch (constructorMode) {
case -1:
chatPositionValue = (byte) ChatPosition.CHAT.ordinal();
chatPositionValue = (byte) ChatPosition.CHAT.getId(version);
break;
case 0:
chatPositionValue = readByte(0);
@@ -182,28 +251,108 @@ public final class WrappedPacketOutChat extends WrappedPacket implements Sendabl
break;
case 2:
case 3:
Object chatTypeEnumInstance = readObject(0, chatMessageTypeEnum);
return ChatPosition.valueOf(chatTypeEnumInstance.toString());
Enum<?> chatTypeEnumInstance = readEnumConstant(0, chatMessageTypeEnum);
return ChatPosition.values()[chatTypeEnumInstance.ordinal()];
case 4:
Object chatMsgType = readObject(0, NETWORK_BOUND_CHAT_TYPE_CLASS);
WrappedPacket chatMsgTypeWrapper = new WrappedPacket(new NMSPacket(chatMsgType));
chatPositionValue = (byte) chatMsgTypeWrapper.readInt(0);
break;
default:
chatPositionValue = 0;
break;
}
return ChatPosition.getByPositionValue(chatPositionValue);
return ChatPosition.getById(version, chatPositionValue);
} else {
return chatPosition;
}
}
public enum ChatPosition {
CHAT,
SYSTEM_MESSAGE,
GAME_INFO;
public void setChatPosition(ChatPosition chatPosition) {
if (packet != null) {
switch (constructorMode) {
case 0:
writeByte(0, (byte) chatPosition.getId(version));
break;
case 1:
writeInt(0, chatPosition.getId(version));
break;
case 2:
case 3:
Enum<?> chatTypeEnumInstance = EnumUtil.valueByIndex(chatMessageTypeEnum,
chatPosition.getId(version));
writeEnumConstant(0, chatTypeEnumInstance);
break;
case 4:
Object chatMsgType = readObject(0, NETWORK_BOUND_CHAT_TYPE_CLASS);
WrappedPacket chatMsgTypeWrapper = new WrappedPacket(new NMSPacket(chatMsgType));
chatMsgTypeWrapper.writeInt(0, chatPosition.getId(version));
break;
}
} else {
this.chatPosition = chatPosition;
}
}
ChatPosition() {
// TODO: Add support to every single Wrapper usage
public enum ChatPosition {
CHAT(0),
@Deprecated
SYSTEM(-1),
@Deprecated
GAME_INFO(-1),
SAY_COMMAND(1),
@Deprecated
MSG_COMMAND(-1),
MSG_COMMAND_INCOMING(2),
MSG_COMMAND_OUTGOING(3),
@Deprecated
TEAM_MSG_COMMAND(-1),
TEAM_MSG_COMMAND_INCOMING(4),
TEAM_MSG_COMMAND_OUTGOING(5),
EMOTE_COMMAND(6),
@Deprecated
TELLRAW_COMMAND(-1);
private final byte modernId;
ChatPosition(int modernId) {
this.modernId = (byte) modernId;
}
public static ChatPosition getByPositionValue(byte position) {
return values()[position];
private static final ChatPosition[] VALUES;
private static final Map<Byte, ChatPosition> MODERN_CHAT_TYPE_MAP;
static {
VALUES = values();
MODERN_CHAT_TYPE_MAP = new HashMap<>();
Arrays.stream(VALUES)
.filter(chatType -> chatType.modernId != -1)
.forEach(chatType -> MODERN_CHAT_TYPE_MAP.put(chatType.modernId, chatType));
}
public int getId(ServerVersion version) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
return modernId;
}
return ordinal();
}
@Nullable
public static ChatPosition getById(ServerVersion version, int id) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_1)) {
return MODERN_CHAT_TYPE_MAP.get((byte) id);
} else {
return VALUES[id];
}
}
}
}
@@ -0,0 +1,121 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2021 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 io.github.retrooper.packetevents.packetwrappers.play.out.collect;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.Constructor;
import java.util.Optional;
public class WrappedPacketOutCollect extends WrappedPacket implements SendableWrapper {
private static boolean v_1_11;
private static Constructor<?> packetConstructor;
private int collectedEntityId, collectorEntityId, itemCount;
public WrappedPacketOutCollect(NMSPacket packet) {
super(packet);
}
public WrappedPacketOutCollect(int collectedEntityId, int collectorEntityId, int itemCount) {
this.collectedEntityId = collectedEntityId;
this.collectorEntityId = collectorEntityId;
this.itemCount = itemCount;
}
@Override
protected void load() {
v_1_11 = version.isNewerThanOrEquals(ServerVersion.v_1_11);
try {
if (v_1_11) {
packetConstructor = PacketTypeClasses.Play.Server.COLLECT.getConstructor(int.class, int.class, int.class);
} else {
packetConstructor = PacketTypeClasses.Play.Server.COLLECT.getConstructor(int.class, int.class);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public int getCollectedEntityId() {
if (packet != null) {
return readInt(0);
} else {
return this.collectedEntityId;
}
}
public void setCollectedEntityId(int id) {
if (packet != null) {
writeInt(0, id);
} else {
this.collectedEntityId = id;
}
}
public int getCollectorEntityId() {
if (packet != null) {
return readInt(1);
} else {
return this.collectorEntityId;
}
}
public void setCollectorEntityId(int id) {
if (packet != null) {
writeInt(1, id);
} else {
this.collectorEntityId = id;
}
}
public Optional<Integer> getItemCount() {
if (!v_1_11) {
return Optional.empty();
}
if (packet != null) {
return Optional.of(readInt(2));
} else {
return Optional.of(this.itemCount);
}
}
public void setItemCount(int count) {
if (v_1_11) {
if (packet != null) {
writeInt(2, count);
} else {
this.itemCount = count;
}
}
}
@Override
public Object asNMSPacket() throws Exception {
/*
* On newer versions the packet has an extra field which is the picked up item count.
*/
return v_1_11
? packetConstructor.newInstance(getCollectedEntityId(), getCollectorEntityId(), (int) (getItemCount().get()))
: packetConstructor.newInstance(getCollectedEntityId(), getCollectorEntityId());
}
}
@@ -35,11 +35,11 @@ public class WrappedPacketOutCustomPayload extends WrappedPacket implements Send
private static int minecraftKeyIndexInClass;
private static byte constructorMode;
private String tag;
private String channelName;
private byte[] data;
public WrappedPacketOutCustomPayload(String tag, byte[] data) {
this.tag = tag;
public WrappedPacketOutCustomPayload(String channelName, byte[] data) {
this.channelName = channelName;
this.data = data;
}
@@ -53,7 +53,7 @@ public class WrappedPacketOutCustomPayload extends WrappedPacket implements Send
try {
packetDataSerializerConstructor = NMSUtils.packetDataSerializerClass.getConstructor(NMSUtils.byteBufClass);
} catch (NullPointerException | NoSuchMethodException e) {
//For some reason some 1.7.10 spigots don't have this constructor although its on normal spigot 1.7.10???
//For some reason some annoying 1.7.10 spigot forks don't have this constructor?
}
//Constructors:
@@ -92,33 +92,35 @@ public class WrappedPacketOutCustomPayload extends WrappedPacket implements Send
}
}
public String getTag() {
public String getChannelName() {
if (packet != null) {
switch (constructorMode) {
case 0:
case 1:
return readString(0);
case 2:
Object minecraftKey = readObject(minecraftKeyIndexInClass, NMSUtils.minecraftKeyClass);
return NMSUtils.getStringFromMinecraftKey(minecraftKey);
return readMinecraftKey(minecraftKeyIndexInClass);
default:
return null;
}
return null;
}
return tag;
else {
return channelName;
}
}
public void setTag(String tag) {
public void setChannelName(String channelName) {
if (packet != null) {
switch (constructorMode) {
case 0:
case 1:
writeString(0, tag);
writeString(0, channelName);
case 2:
Object minecraftKey = NMSUtils.generateMinecraftKey(tag);
write(NMSUtils.minecraftKeyClass, minecraftKeyIndexInClass, minecraftKey);
writeMinecraftKey(0, channelName);
}
} else {
this.tag = tag;
}
else {
this.channelName = channelName;
}
}
@@ -130,8 +132,9 @@ public class WrappedPacketOutCustomPayload extends WrappedPacket implements Send
case 1:
case 2:
return PacketEvents.get().getByteBufUtil().getBytes(getBuffer());
default:
return new byte[0];
}
return new byte[0];
}
return data;
}
@@ -156,19 +159,22 @@ public class WrappedPacketOutCustomPayload extends WrappedPacket implements Send
private Object getBuffer() {
Object dataSerializer = readObject(0, NMSUtils.packetDataSerializerClass);
WrappedPacket dataSerializerWrapper = new WrappedPacket(new NMSPacket(dataSerializer));
return dataSerializerWrapper.readObject(0, NMSUtils.byteBufClass);
}
public void retain() {
if (constructorMode != 0) {
PacketEvents.get().getByteBufUtil().retain(getBuffer());
if (packet != null) {
if (constructorMode != 0) {
PacketEvents.get().getByteBufUtil().retain(getBuffer());
}
}
}
public void release() {
if (constructorMode != 0) {
PacketEvents.get().getByteBufUtil().release(getBuffer());
if (packet != null) {
if (constructorMode != 0) {
PacketEvents.get().getByteBufUtil().release(getBuffer());
}
}
}
@@ -178,12 +184,12 @@ public class WrappedPacketOutCustomPayload extends WrappedPacket implements Send
Object dataSerializer;
switch (constructorMode) {
case 0:
return constructor.newInstance(getTag(), data);
return constructor.newInstance(getChannelName(), data);
case 1:
dataSerializer = packetDataSerializerConstructor.newInstance(PacketEvents.get().getByteBufUtil().newByteBuf(data));
return constructor.newInstance(getTag(), dataSerializer);
return constructor.newInstance(getChannelName(), dataSerializer);
case 2:
Object minecraftKey = NMSUtils.generateMinecraftKey(getTag());
Object minecraftKey = NMSUtils.generateMinecraftKeyNew(getChannelName());
dataSerializer = packetDataSerializerConstructor.newInstance(PacketEvents.get().getByteBufUtil().newByteBuf(data));
return constructor.newInstance(minecraftKey, dataSerializer);
default:
@@ -23,23 +23,25 @@ import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.entity.Entity;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects;
import java.util.Optional;
public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static boolean v_1_8, v_1_15, v_1_17;
//Byte = 1.7.10->1.8.8, Int = 1.9->1.15.x, Short = 1.16.x
private static byte mode; //byte = 0, int = 1, short = 2
private static double dXYZDivisor;
private static int yawByteIndex;
private static final float ROTATION_FACTOR = 256.0F / 360.0F;
private static int yawByteIndex = 0;
private static int pitchByteIndex = 1;
private static Constructor<?> entityPacketConstructor, entityRelMovePacketConstructor, entityLookConstructor, entityRelMoveLookConstructor;
private double deltaX, deltaY, deltaZ;
private byte pitch, yaw;
private boolean onGround, isLook;
private float pitch, yaw;
private boolean onGround, rotating, moving;
public WrappedPacketOutEntity(NMSPacket packet) {
super(packet);
@@ -47,7 +49,7 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
}
public WrappedPacketOutEntity(int entityID, double deltaX, double deltaY, double deltaZ,
byte yaw, byte pitch, boolean onGround, boolean isLook) {
float yaw, float pitch, boolean onGround, boolean rotating, boolean moving) {
this.entityID = entityID;
this.deltaX = deltaX;
this.deltaY = deltaY;
@@ -55,86 +57,95 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
this.yaw = yaw;
this.pitch = pitch;
this.onGround = onGround;
this.isLook = isLook;
this.rotating = rotating;
this.moving = moving;
}
public WrappedPacketOutEntity(int entityID, double deltaX, double deltaY, double deltaZ,
byte yaw, byte pitch, boolean onGround) {
this.entityID = entityID;
this.deltaX = deltaX;
this.deltaY = deltaY;
this.deltaZ = deltaZ;
this.pitch = pitch;
this.yaw = yaw;
this.onGround = onGround;
this.isLook = false;
float yaw, float pitch, boolean onGround, boolean rotating) {
this(entityID, deltaX, deltaY, deltaZ, yaw, pitch, onGround, rotating, false);
}
public WrappedPacketOutEntity(int entityID, double deltaX, double deltaY, double deltaZ,
float yaw, float pitch, boolean onGround) {
this(entityID, deltaX, deltaY, deltaZ, yaw, pitch, onGround, false, false);
}
public WrappedPacketOutEntity(Entity entity, double deltaX, double deltaY, double deltaZ,
byte yaw, byte pitch, boolean onGround, boolean isLook) {
float yaw, float pitch, boolean onGround, boolean isLook) {
this(entity.getEntityId(), deltaX, deltaY, deltaZ, yaw, pitch, onGround, isLook);
}
public WrappedPacketOutEntity(Entity entity, double deltaX, double deltaY, double deltaZ,
byte yaw, byte pitch, boolean onGround) {
float yaw, float pitch, boolean onGround) {
this(entity.getEntityId(), deltaX, deltaY, deltaZ, yaw, pitch, onGround, false);
}
@Override
protected void load() {
v_1_8 = version.isNewerThanOrEquals(ServerVersion.v_1_8);
v_1_15 = version.isNewerThanOrEquals(ServerVersion.v_1_15);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
Class<?> packetClass = PacketTypeClasses.Play.Server.ENTITY;
Field dxField = Reflection.getField(packetClass, 1);
Field dxField = Reflection.getField(packetClass, v_1_17 ? 2 : 1);
if (Objects.requireNonNull(dxField).equals(Reflection.getField(packetClass, byte.class, 0))) {
mode = 0;
yawByteIndex = 3;
pitchByteIndex = 4;
} else if (dxField.equals(Reflection.getField(packetClass, int.class, 1))) {
mode = 1;
} else if (dxField.equals(Reflection.getField(packetClass, short.class, 0))) {
} else if (dxField.equals(Reflection.getField(packetClass, short.class, 0))
//1.19 support
|| dxField.equals(Reflection.getField(packetClass, short.class, 1))) {
mode = 2;
}
if (mode == 0) {
dXYZDivisor = 32.0;
} else {
dXYZDivisor = 4096.0;
}
try {
entityPacketConstructor = packetClass.getConstructor(int.class);
if (v_1_17) {
entityPacketConstructor = packetClass.getDeclaredConstructor(int.class, short.class, short.class, short.class,
byte.class, byte.class, boolean.class, boolean.class, boolean.class);
entityPacketConstructor.setAccessible(true);
} else {
entityPacketConstructor = packetClass.getConstructor(int.class);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public byte getPitch() {
public float getPitch() {
if (packet != null) {
return readByte(pitchByteIndex);
return readByte(pitchByteIndex) / ROTATION_FACTOR;
} else {
return pitch;
}
}
public void setPitch(byte pitch) {
public void setPitch(float pitch) {
if (packet != null) {
writeByte(pitchByteIndex, pitch);
writeByte(pitchByteIndex, (byte) (pitch * ROTATION_FACTOR));
} else {
this.pitch = pitch;
}
}
public byte getYaw() {
public float getYaw() {
if (packet != null) {
return readByte(yawByteIndex);
return readByte(yawByteIndex) / ROTATION_FACTOR;
} else {
return yaw;
}
}
public void setYaw(byte yaw) {
public void setYaw(float yaw) {
if (packet != null) {
writeByte(yawByteIndex, yaw);
writeByte(yawByteIndex, (byte) (yaw * ROTATION_FACTOR));
}
}
@@ -262,25 +273,58 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
}
}
public boolean isLook() {
public Optional<Boolean> isRotating() {
if (!v_1_8) {
return Optional.empty();
}
if (packet != null) {
return readBoolean(1);
return Optional.of(readBoolean(1));
} else {
return isLook;
return Optional.of(rotating);
}
}
public void setLook(boolean isLook) {
public void setRotating(boolean rotating) {
if (v_1_8) {
if (packet != null) {
writeBoolean(1, rotating);
} else {
this.rotating = rotating;
}
}
}
public Optional<Boolean> isMoving() {
if (!v_1_15) {
return Optional.empty();
}
if (packet != null) {
writeBoolean(1, isLook);
return Optional.of(readBoolean(2));
} else {
this.isLook = isLook;
return Optional.of(moving);
}
}
public void setMoving(boolean moving) {
if (v_1_15) {
if (packet != null) {
writeBoolean(2, moving);
} else {
this.moving = moving;
}
}
}
@Override
public Object asNMSPacket() throws Exception {
try {
if (v_1_17) {
byte angleYaw = (byte) (getYaw() * ROTATION_FACTOR);
byte anglePitch = (byte) (getPitch() * ROTATION_FACTOR);
return entityPacketConstructor.newInstance(getEntityId(),
(short) (getDeltaX() * dXYZDivisor), (short) (getDeltaY() * dXYZDivisor),
(short) (getDeltaZ() * dXYZDivisor),
angleYaw, anglePitch, isOnGround(), isRotating().get(), isMoving().get());
} else {
Object packetInstance = entityPacketConstructor.newInstance(getEntityId());
WrappedPacketOutEntity wrapper = new WrappedPacketOutEntity(new NMSPacket(packetInstance));
wrapper.setDeltaX(getDeltaX());
@@ -289,12 +333,14 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
wrapper.setYaw(getYaw());
wrapper.setPitch(getPitch());
wrapper.setOnGround(isOnGround());
wrapper.setLook(isLook());
if (v_1_8) {
wrapper.setRotating(isRotating().get());
/*if (v_1_16) {
wrapper.setMoving(isMoving().get());
}*/
}
return packetInstance;
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public static class WrappedPacketOutEntityLook extends WrappedPacketOutEntity {
@@ -302,7 +348,7 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
super(packet);
}
public WrappedPacketOutEntityLook(int entityID, byte yaw, byte pitch, boolean onGround) {
public WrappedPacketOutEntityLook(int entityID, float yaw, float pitch, boolean onGround) {
super(entityID, 0, 0, 0, yaw, pitch, onGround, true);
}
@@ -310,7 +356,12 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
protected void load() {
super.load();
try {
entityLookConstructor = PacketTypeClasses.Play.Server.ENTITY_LOOK.getConstructor();
if (v_1_17) {
entityLookConstructor = PacketTypeClasses.Play.Server.ENTITY_LOOK.getConstructor(int.class, byte.class, byte.class, boolean.class);
}
else {
entityLookConstructor = PacketTypeClasses.Play.Server.ENTITY_LOOK.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -318,13 +369,23 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
@Override
public Object asNMSPacket() throws Exception {
Object packetInstance = entityLookConstructor.newInstance();
WrappedPacketOutEntityLook wrapper = new WrappedPacketOutEntityLook(new NMSPacket(packetInstance));
wrapper.setEntityId(getEntityId());
wrapper.setYaw(getYaw());
wrapper.setPitch(getPitch());
wrapper.setOnGround(isOnGround());
wrapper.setLook(true);
Object packetInstance;
if (v_1_17) {
byte angleYaw = (byte) (getYaw() * ROTATION_FACTOR);
byte anglePitch = (byte) (getPitch() * ROTATION_FACTOR);
packetInstance = entityLookConstructor.newInstance(getEntityId(), angleYaw, anglePitch, isOnGround());
}
else {
packetInstance = entityLookConstructor.newInstance();
WrappedPacketOutEntityLook wrapper = new WrappedPacketOutEntityLook(new NMSPacket(packetInstance));
wrapper.setEntityId(getEntityId());
wrapper.setYaw(getYaw());
wrapper.setPitch(getPitch());
wrapper.setOnGround(isOnGround());
if (v_1_8) {
wrapper.setRotating(true);
}
}
return packetInstance;
}
}
@@ -335,14 +396,19 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
}
public WrappedPacketOutRelEntityMove(int entityID, double deltaX, double deltaY, double deltaZ, boolean onGround) {
super(entityID, deltaX, deltaY, deltaZ, (byte) 0, (byte) 0, onGround, false);
super(entityID, deltaX, deltaY, deltaZ, 0, 0, onGround, false);
}
@Override
protected void load() {
super.load();
try {
entityRelMovePacketConstructor = PacketTypeClasses.Play.Server.REL_ENTITY_MOVE.getConstructor();
if (v_1_17) {
entityRelMovePacketConstructor = PacketTypeClasses.Play.Server.REL_ENTITY_MOVE.getConstructor(int.class, short.class, short.class, short.class, boolean.class);
}
else {
entityRelMovePacketConstructor = PacketTypeClasses.Play.Server.REL_ENTITY_MOVE.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -350,14 +416,26 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
@Override
public Object asNMSPacket() throws Exception {
Object packetInstance = entityRelMovePacketConstructor.newInstance();
WrappedPacketOutRelEntityMove wrapper = new WrappedPacketOutRelEntityMove(new NMSPacket(packetInstance));
wrapper.setEntityId(getEntityId());
wrapper.setDeltaX(getDeltaX());
wrapper.setDeltaY(getDeltaY());
wrapper.setDeltaZ(getDeltaZ());
wrapper.setOnGround(isOnGround());
wrapper.setLook(false);
Object packetInstance;
if (v_1_17) {
short dx = (short) (getDeltaX() * dXYZDivisor);
short dy = (short) (getDeltaY() * dXYZDivisor);
short dz = (short) (getDeltaZ() * dXYZDivisor);
packetInstance = entityRelMovePacketConstructor.newInstance(getEntityId(), dx, dy, dz, isOnGround());
}
else {
packetInstance = entityRelMovePacketConstructor.newInstance();
WrappedPacketOutRelEntityMove wrapper = new WrappedPacketOutRelEntityMove(new NMSPacket(packetInstance));
wrapper.setEntityId(getEntityId());
wrapper.setDeltaX(getDeltaX());
wrapper.setDeltaY(getDeltaY());
wrapper.setDeltaZ(getDeltaZ());
wrapper.setOnGround(isOnGround());
if (v_1_15) {
wrapper.setMoving(true);
}
}
return packetInstance;
}
}
@@ -367,7 +445,8 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
super(packet);
}
public WrappedPacketOutRelEntityMoveLook(int entityID, double deltaX, double deltaY, double deltaZ, byte yaw, byte pitch, boolean onGround) {
public WrappedPacketOutRelEntityMoveLook(int entityID, double deltaX, double deltaY, double deltaZ,
float yaw, float pitch, boolean onGround) {
super(entityID, deltaX, deltaY, deltaZ, yaw, pitch, onGround, false);
}
@@ -375,7 +454,12 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
protected void load() {
super.load();
try {
entityRelMoveLookConstructor = PacketTypeClasses.Play.Server.REL_ENTITY_MOVE_LOOK.getConstructor();
if (v_1_17) {
entityRelMoveLookConstructor = PacketTypeClasses.Play.Server.REL_ENTITY_MOVE_LOOK.getConstructor(int.class, short.class, short.class, short.class, byte.class, byte.class, boolean.class);
}
else {
entityRelMoveLookConstructor = PacketTypeClasses.Play.Server.REL_ENTITY_MOVE_LOOK.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -383,16 +467,32 @@ public class WrappedPacketOutEntity extends WrappedPacketEntityAbstraction imple
@Override
public Object asNMSPacket() throws Exception {
Object packetInstance = entityRelMoveLookConstructor.newInstance();
WrappedPacketOutRelEntityMoveLook wrapper = new WrappedPacketOutRelEntityMoveLook(new NMSPacket(packetInstance));
wrapper.setEntityId(getEntityId());
wrapper.setDeltaX(getDeltaX());
wrapper.setDeltaY(getDeltaY());
wrapper.setDeltaZ(getDeltaZ());
wrapper.setYaw(getYaw());
wrapper.setPitch(getPitch());
wrapper.setOnGround(isOnGround());
wrapper.setLook(true);
Object packetInstance;
if (v_1_17) {
short dx = (short) (getDeltaX() * dXYZDivisor);
short dy = (short) (getDeltaY() * dXYZDivisor);
short dz = (short) (getDeltaZ() * dXYZDivisor);
byte angleYaw = (byte) (getYaw() * ROTATION_FACTOR);
byte anglePitch = (byte) (getPitch() * ROTATION_FACTOR);
packetInstance = entityRelMoveLookConstructor.newInstance(getEntityId(), dx, dy, dz, angleYaw, anglePitch, isOnGround());
}
else {
packetInstance = entityRelMoveLookConstructor.newInstance();
WrappedPacketOutRelEntityMoveLook wrapper = new WrappedPacketOutRelEntityMoveLook(new NMSPacket(packetInstance));
wrapper.setEntityId(getEntityId());
wrapper.setDeltaX(getDeltaX());
wrapper.setDeltaY(getDeltaY());
wrapper.setDeltaZ(getDeltaZ());
wrapper.setYaw(getYaw());
wrapper.setPitch(getPitch());
wrapper.setOnGround(isOnGround());
if (v_1_8) {
wrapper.setRotating(true);
if (v_1_15) {
wrapper.setMoving(true);
}
}
}
return packetInstance;
}
}
@@ -20,91 +20,197 @@ package io.github.retrooper.packetevents.packetwrappers.play.out.entitydestroy;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import org.bukkit.World;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.entity.Entity;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author yanjulang
* @author yanjulang, MWHunter
* @since 1.8
*/
public class WrappedPacketOutEntityDestroy extends WrappedPacket implements SendableWrapper {
public class WrappedPacketOutEntityDestroy extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static Class<?> INT_COLLECTION_CLASS;
private static Class<?> INT_LIST_CLASS;
private static Class<?> INT_ARRAY_LIST_CLASS;
private static Constructor<?> INT_ARRAY_LIST_CONSTRUCTOR;
private static Method TO_INT_ARRAY_METHOD;
private static boolean v_1_17;
private static boolean v_1_17_1;
private static Constructor<?> packetConstructor;
private int[] entityIds;
private Entity[] entities;
private int[] entityIds = new int[0];
public WrappedPacketOutEntityDestroy(NMSPacket packet) {
super(packet);
}
@Deprecated
public WrappedPacketOutEntityDestroy(int... entityIds) {
this.entityIds = entityIds;
}
public WrappedPacketOutEntityDestroy(Entity... entities) {
setEntities(entities);
public WrappedPacketOutEntityDestroy(int entityID) {
setEntityId(entityID);
}
public WrappedPacketOutEntityDestroy(Entity entity) {
setEntity(entity);
}
@Override
protected void load() {
v_1_17_1 = version.isNewerThanOrEquals(ServerVersion.v_1_17_1);
v_1_17 = version.equals(ServerVersion.v_1_17);
if (v_1_17_1) {
if (INT_COLLECTION_CLASS == null) {
INT_COLLECTION_CLASS = Reflection.getClassByNameWithoutException("it.unimi.dsi.fastutil.ints.IntCollection");
INT_LIST_CLASS = Reflection.getClassByNameWithoutException("it.unimi.dsi.fastutil.ints.IntList");
INT_ARRAY_LIST_CLASS = Reflection.getClassByNameWithoutException("it.unimi.dsi.fastutil.ints.IntArrayList");
try {
INT_ARRAY_LIST_CONSTRUCTOR = INT_ARRAY_LIST_CLASS.getConstructor(int[].class);
INT_ARRAY_LIST_CONSTRUCTOR.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
TO_INT_ARRAY_METHOD = INT_COLLECTION_CLASS.getDeclaredMethod("toIntArray");
TO_INT_ARRAY_METHOD.setAccessible(true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
try {
packetConstructor =
PacketTypeClasses.Play.Server.ENTITY_DESTROY.getConstructor(int[].class);
if (v_1_17) {
packetConstructor =
PacketTypeClasses.Play.Server.ENTITY_DESTROY.getConstructor(int.class);
} else {
packetConstructor =
PacketTypeClasses.Play.Server.ENTITY_DESTROY.getConstructor(int[].class);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public int[] getEntityIds() {
if (packet != null && entityIds == null) {
return entityIds = readIntArray(0);
@Override
public int getEntityId() {
if (entityID != -1 || entityIds.length > 0 || packet == null) {
if (v_1_17) {
return entityID;
} else {
return entityIds[0];
}
} else {
return entityIds;
if (v_1_17_1) {
Object list = readObject(0, INT_LIST_CLASS);
try {
entityIds = (int[]) TO_INT_ARRAY_METHOD.invoke(list);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return entityIds[0];
} else if (v_1_17) {
return entityID = readInt(0);
} else {
entityIds = readIntArray(0);
return entityIds[0];
}
}
}
@Override
public void setEntityId(int entityID) {
if (packet != null) {
if (v_1_17) {
writeInt(0, this.entityID = entityID);
} else {
this.entityIds = new int[]{entityID};
if (v_1_17_1) {
Object intArrayList = null;
try {
intArrayList = INT_ARRAY_LIST_CONSTRUCTOR.newInstance(this.entityIds);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
write(INT_LIST_CLASS, 0, intArrayList);
} else {
writeIntArray(0, new int[]{this.entityIds[0]});
}
}
} else {
if (v_1_17) {
this.entityID = entityID;
} else {
this.entityIds = new int[]{entityID};
}
}
this.entity = null;
}
public int[] getEntityIds() {
if (packet != null) {
if (v_1_17) {
return new int[]{getEntityId()};
} else if (v_1_17_1) {
Object list = readObject(0, INT_LIST_CLASS);
try {
return (int[]) TO_INT_ARRAY_METHOD.invoke(list);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
} else {
return readIntArray(0);
}
} else {
if (v_1_17) {
return new int[]{entityID};
} else {
return entityIds;
}
}
}
public void setEntityIds(int... entityIds) {
this.entityIds = entityIds;
if (packet != null) {
writeIntArray(0, entityIds);
}
}
public Entity[] getEntities(@Nullable World world) {
if (packet != null && entities == null) {
int[] entityIDs = getEntityIds();
entities = new Entity[entityIDs.length];
for (int i = 0; i < entityIDs.length; i++) {
entities[i] = NMSUtils.getEntityById(world, entityIDs[i]);
if (v_1_17) {
setEntityId(entityIds[0]);
} else if (v_1_17_1) {
Object intArrayList = null;
try {
intArrayList = INT_ARRAY_LIST_CONSTRUCTOR.newInstance(entityIds);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
write(INT_LIST_CLASS, 0, intArrayList);
} else {
writeIntArray(0, entityIds);
}
} else {
if (v_1_17) {
this.entityID = entityIds[0];
} else {
this.entityIds = entityIds;
}
}
return entities;
}
public Entity[] getEntities() {
return getEntities(null);
}
public void setEntities(Entity... entities) {
this.entityIds = new int[entities.length];
this.entities = entities;
for (int i = 0; i < entities.length; i++) {
Entity entity = entities[i];
entityIds[i] = entity.getEntityId();
}
if (packet != null) {
writeIntArray(0, entityIds);
}
}
@Override
public Object asNMSPacket() throws Exception {
return packetConstructor.newInstance(entityIds);
if (v_1_17) {
return packetConstructor.newInstance(getEntityId());
} else {
return packetConstructor.newInstance(getEntityIds());
}
}
}
@@ -18,29 +18,41 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.entityeffect;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.Effect;
import org.bukkit.entity.Entity;
import org.bukkit.potion.PotionEffectType;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Optional;
public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static Constructor<?> packetDefaultConstructor;
private int effectID = -1;
private int amplifier = -1;
private int duration = -1;
private static boolean v_1_7_10, v_1_17, v_1_18_2, v_1_19, v_1_20_5;
private static Constructor<?> packetConstructor;
private static Class<?> holderClass;
private static Method accessHolderValueMethod;
private static boolean hasHolder = false;
private int effectID;
private int amplifier;
private int duration;
private byte byteMask;
private boolean byteMaskInitialized = false;
public WrappedPacketOutEntityEffect(NMSPacket packet) {
super(packet);
super(packet, v_1_17 ? 3 : 0);
}
public WrappedPacketOutEntityEffect(Entity entity, int effectID, int amplifier, int duration) {
super(v_1_17 ? 3 : 0);
this.entityID = entity.getEntityId();
this.entity = entity;
this.effectID = effectID;
@@ -50,6 +62,7 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
}
public WrappedPacketOutEntityEffect(int entityID, int effectID, int amplifier, int duration, boolean hideParticles, boolean ambient, boolean showIcon) {
super(v_1_17 ? 3 : 0);
this.entityID = entityID;
this.effectID = effectID;
this.amplifier = amplifier;
@@ -77,21 +90,75 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
}
}
public WrappedPacketOutEntityEffect(Entity entity, PotionEffectType effectType, int amplifier, int duration) {
this(entity, effectType.getId(), amplifier, duration);
}
public WrappedPacketOutEntityEffect(int entityID, PotionEffectType effectType, int amplifier, int duration, boolean hideParticles, boolean ambient, boolean showIcon) {
this(entityID, effectType.getId(), amplifier, duration, hideParticles, ambient, showIcon);
}
public WrappedPacketOutEntityEffect(Entity entity, Effect effect, int amplifier, int duration) {
this(entity, effect.getId(), amplifier, duration);
}
public WrappedPacketOutEntityEffect(int entityID, Effect effect, int amplifier, int duration, boolean hideParticles, boolean ambient, boolean showIcon) {
this(entityID, effect.getId(), amplifier, duration, hideParticles, ambient, showIcon);
}
@Override
protected void load() {
v_1_7_10 = version.isOlderThan(ServerVersion.v_1_8);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
v_1_18_2 = version.isNewerThanOrEquals(ServerVersion.v_1_18_2);
v_1_19 = version.isNewerThanOrEquals(ServerVersion.v_1_19);
v_1_20_5 = version.isNewerThanOrEquals(ServerVersion.v_1_20_5);
try {
packetDefaultConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getConstructor();
if (v_1_17) {
/*packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getDeclaredConstructor(NMSUtils.packetDataSerializerClass);
packetConstructor.setAccessible(true);
if (packetConstructor == null) {
Class<?> registryFriendlyByteBuf = NMSUtils.getNMClassWithoutException("network.RegistryFriendlyByteBuf");
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getDeclaredConstructor(registryFriendlyByteBuf);
}*/
} else {
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EFFECT.getConstructor();
}
holderClass = NMSUtils.getNMClassWithoutException("core.Holder");
if (holderClass != null) {
hasHolder = Reflection.getField(PacketTypeClasses.Play.Server.ENTITY_EFFECT, holderClass, 0) != null;
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public int getEffectId() {
if (effectID != -1) {
return effectID;
}
if (packet != null) {
return effectID = readByte(0);
if (v_1_19) {
Object mobEffectList = null;
if (hasHolder) {
Object holder = readObject(0, holderClass);
if (accessHolderValueMethod == null) {
accessHolderValueMethod = Reflection.getMethod(holderClass, 0);
}
try {
mobEffectList = accessHolderValueMethod.invoke(holder);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
else {
mobEffectList = readObject(0, NMSUtils.mobEffectListClass);
}
return NMSUtils.getEffectId(mobEffectList);
} else if (v_1_18_2) {
return readInt(4);
} else {
return readByte(0);
}
} else {
return effectID;
}
@@ -99,18 +166,25 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
public void setEffectId(int effectID) {
if (packet != null) {
writeByte(0, (byte) (this.effectID = effectID));
if (v_1_19) {
Object mobEffectList = NMSUtils.getMobEffectListById(effectID);
write(NMSUtils.mobEffectListClass, 0, mobEffectList);
} else if (v_1_18_2) {
writeInt(4, effectID);
} else {
writeByte(0, (byte) effectID);
}
} else {
this.effectID = effectID;
}
}
public int getAmplifier() {
if (amplifier != -1) {
return amplifier;
}
if (packet != null) {
return amplifier = readByte(1);
if (v_1_20_5) {
return readInt(5);
}
return readByte(v_1_18_2 ? 0 : 1);
} else {
return amplifier;
}
@@ -118,21 +192,34 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
public void setAmplifier(int amplifier) {
if (packet != null) {
writeByte(1, (byte) (this.amplifier = amplifier));
if (v_1_20_5) {
writeInt(5, amplifier);
}
writeByte(v_1_18_2 ? 0 : 1, (byte) amplifier);
} else {
this.amplifier = amplifier;
}
}
public int getDuration() {
if (duration != -1) {
return duration;
}
if (packet != null) {
if (version.isOlderThan(ServerVersion.v_1_8)) {
return duration = readShort(1);
} else {
return duration = readInt(1);
//1.7 and only 1.7(below 1.8)
if (v_1_7_10) {
return readShort(1);
}
else if (v_1_20_5) {
return readInt(6);
}
else if (v_1_19) {
return readInt(4);
}
//1.18.2+
else if (v_1_18_2) {
return readInt(5);
}
//1.17 - 1.8
else {
return readInt(v_1_17 ? 4 : 1);
}
} else {
return duration;
@@ -142,15 +229,23 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
public void setDuration(int duration) {
if (packet != null) {
this.duration = duration;
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
if (duration > Short.MAX_VALUE) {
duration = Short.MAX_VALUE;
} else if (duration < Short.MIN_VALUE) {
duration = Short.MIN_VALUE;
}
writeShort(0, (short) duration);
}
else if (v_1_20_5) {
writeInt(6, duration);
}
else if (v_1_19) {
writeInt(4, duration);
} else if (v_1_18_2) {
writeInt(5, duration);
} else {
writeInt(1, duration);
writeInt(v_1_17 ? 4 : 1, duration);
}
} else {
this.duration = duration;
@@ -158,21 +253,27 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
}
private Optional<Byte> getByteMask() {
if (version.isOlderThan(ServerVersion.v_1_8)) {
if (v_1_7_10) {
return Optional.empty();
}
if (packet != null && !byteMaskInitialized) {
return Optional.of(byteMask = readByte(2));
if (v_1_20_5) {
return Optional.of(readByte(0));
}
return Optional.of(byteMask = readByte(v_1_18_2 ? 1 : 2));
} else {
return Optional.of(byteMask);
}
}
private void setByteMask(byte byteMask) {
if (version.isNewerThan(ServerVersion.v_1_7_10)) {
if (!v_1_7_10) {
this.byteMask = byteMask;
if (packet != null) {
writeByte(2, byteMask);
if (v_1_20_5) {
writeByte(0, byteMask);
}
writeByte(v_1_18_2 ? 1 : 2, byteMask);
}
}
}
@@ -271,15 +372,25 @@ public class WrappedPacketOutEntityEffect extends WrappedPacketEntityAbstraction
@Override
public Object asNMSPacket() throws Exception {
Object packetPlayOutEntityEffectInstance = packetDefaultConstructor.newInstance();
Object packetInstance;
if (v_1_17) {
//Lazy and stupid way
//was size 12
byte[] buffer = new byte[30];
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(PacketEvents.get().getByteBufUtil().newByteBuf(buffer));
packetInstance = packetConstructor.newInstance(packetDataSerializer);
} else {
packetInstance = packetConstructor.newInstance();
}
WrappedPacketOutEntityEffect wrappedPacketOutEntityEffect =
new WrappedPacketOutEntityEffect(new NMSPacket(packetPlayOutEntityEffectInstance));
new WrappedPacketOutEntityEffect(new NMSPacket(packetInstance));
wrappedPacketOutEntityEffect.setEntityId(getEntityId());
wrappedPacketOutEntityEffect.setEffectId(getEffectId());
wrappedPacketOutEntityEffect.setAmplifier(getAmplifier());
wrappedPacketOutEntityEffect.setDuration(getDuration());
Optional<Byte> optionalByteMask = getByteMask();
optionalByteMask.ifPresent(wrappedPacketOutEntityEffect::setByteMask);
return packetPlayOutEntityEffectInstance;
return packetInstance;
}
}
@@ -18,6 +18,7 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.entityequipment;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
@@ -36,8 +37,9 @@ import java.util.ArrayList;
import java.util.List;
public class WrappedPacketOutEntityEquipment extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static boolean v_1_17;
private static Class<? extends Enum<?>> enumItemSlotClass;
private static Constructor<?> packetDefaultConstructor;
private static Constructor<?> packetConstructor;
private List<Pair<EquipmentSlot, ItemStack>> equipment;
private EquipmentSlot legacySlot;
private ItemStack legacyItemStack;
@@ -82,23 +84,19 @@ public class WrappedPacketOutEntityEquipment extends WrappedPacketEntityAbstract
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
try {
packetDefaultConstructor = PacketTypeClasses.Play.Server.ENTITY_EQUIPMENT.getConstructor();
if (v_1_17) {
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EQUIPMENT.getConstructor(NMSUtils.packetDataSerializerClass);
} else {
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_EQUIPMENT.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
enumItemSlotClass = NMSUtils.getNMSEnumClassWithoutException("EnumItemSlot");
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
for (EquipmentSlot slot : EquipmentSlot.values()) {
slot.id = (byte) slot.ordinal();
}
} else {
EquipmentSlot.MAINHAND.id = 0;
EquipmentSlot.OFFHAND.id = -1; //Invalid
EquipmentSlot.BOOTS.id = 1;
EquipmentSlot.LEGGINGS.id = 2;
EquipmentSlot.CHESTPLATE.id = 3;
EquipmentSlot.HELMET.id = 4;
if (enumItemSlotClass == null) {
enumItemSlotClass = NMSUtils.getNMEnumClassWithoutException("world.entity.EnumItemSlot");
}
}
@@ -210,7 +208,14 @@ public class WrappedPacketOutEntityEquipment extends WrappedPacketEntityAbstract
@Override
public Object asNMSPacket() throws Exception {
Object packetInstance = packetDefaultConstructor.newInstance();
Object packetInstance;
if (v_1_17) {
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(PacketEvents.get().getByteBufUtil().newByteBuf(new byte[] {0, 0, 0, 0}));
packetInstance = packetConstructor.newInstance(packetDataSerializer);
}
else {
packetInstance = packetConstructor.newInstance();
}
WrappedPacketOutEntityEquipment wrappedPacketOutEntityEquipment = new WrappedPacketOutEntityEquipment(new NMSPacket(packetInstance));
wrappedPacketOutEntityEquipment.setEntityId(getEntityId());
wrappedPacketOutEntityEquipment.setEquipment(getEquipment());
@@ -225,7 +230,7 @@ public class WrappedPacketOutEntityEquipment extends WrappedPacketEntityAbstract
CHESTPLATE,
HELMET;
private byte id;
public byte id;
@Nullable
public static EquipmentSlot getById(byte id) {
@@ -18,28 +18,33 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.entityheadrotation;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.entity.Entity;
import java.lang.reflect.Constructor;
public class WrappedPacketOutEntityHeadRotation extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static Constructor<?> packetDefaultConstructor;
private byte yaw;
private static boolean v_1_17;
private static Constructor<?> packetConstructor;
private static final float ROTATION_FACTOR = 256.0F / 360.0F;
private float yaw;
public WrappedPacketOutEntityHeadRotation(NMSPacket packet) {
super(packet);
}
public WrappedPacketOutEntityHeadRotation(int entityID, byte yaw) {
public WrappedPacketOutEntityHeadRotation(int entityID, float yaw) {
this.entityID = entityID;
this.yaw = yaw;
}
public WrappedPacketOutEntityHeadRotation(Entity entity, byte yaw) {
public WrappedPacketOutEntityHeadRotation(Entity entity, float yaw) {
this.entityID = entity.getEntityId();
this.entity = entity;
this.yaw = yaw;
@@ -47,24 +52,30 @@ public class WrappedPacketOutEntityHeadRotation extends WrappedPacketEntityAbstr
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
try {
packetDefaultConstructor = PacketTypeClasses.Play.Server.ENTITY_HEAD_ROTATION.getConstructor();
if (v_1_17) {
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_HEAD_ROTATION.getConstructor(NMSUtils.packetDataSerializerClass);
}
else {
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_HEAD_ROTATION.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
public byte getYaw() {
public float getYaw() {
if (packet != null) {
return readByte(0);
return readByte(0) / ROTATION_FACTOR;
} else {
return yaw;
}
}
public void setYaw(byte yaw) {
public void setYaw(float yaw) {
if (packet != null) {
writeByte(0, yaw);
writeByte(0, (byte) (yaw * ROTATION_FACTOR));
} else {
this.yaw = yaw;
}
@@ -72,10 +83,17 @@ public class WrappedPacketOutEntityHeadRotation extends WrappedPacketEntityAbstr
@Override
public Object asNMSPacket() throws Exception {
Object packetInstance = packetDefaultConstructor.newInstance();
Object packetInstance;
if (v_1_17) {
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(PacketEvents.get().getByteBufUtil().newByteBuf(new byte[] {0, 0}));
packetInstance = packetConstructor.newInstance(packetDataSerializer);
}
else {
packetInstance = packetConstructor.newInstance();
}
WrappedPacketOutEntityHeadRotation wrappedPacketOutEntityHeadRotation = new WrappedPacketOutEntityHeadRotation(new NMSPacket(packetInstance));
wrappedPacketOutEntityHeadRotation.setYaw(getYaw());
wrappedPacketOutEntityHeadRotation.setEntityId(getEntityId());
wrappedPacketOutEntityHeadRotation.setYaw(getYaw());
return packetInstance;
}
}
@@ -37,6 +37,10 @@ public class WrappedPacketOutEntityMetadata extends WrappedPacketEntityAbstracti
public List<WrappedWatchableObject> getWatchableObjects() {
List<Object> nmsWatchableObjectList = readList(0);
//It's annotated as nullable on 1.17 NMS, so lets just handle it being null
if (nmsWatchableObjectList == null) {
return new ArrayList<>();
}
List<WrappedWatchableObject> wrappedWatchableObjects = new ArrayList<>(nmsWatchableObjectList.size());
for (Object watchableObject : nmsWatchableObjectList) {
wrappedWatchableObjects.add(new WrappedWatchableObject(new NMSPacket(watchableObject)));
@@ -38,7 +38,15 @@ public class WrappedWatchableObject extends WrappedPacket {
@Override
protected void load() {
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_19_3)) {
valueIndex = 2;
try {
googleOptionalClass = Class.forName("com.google.common.base.Optional");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
else if (version.isNewerThan(ServerVersion.v_1_8_8)) {
valueIndex = 1;
try {
googleOptionalClass = Class.forName("com.google.common.base.Optional");
@@ -49,17 +57,19 @@ public class WrappedWatchableObject extends WrappedPacket {
}
public int getIndex() {
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
if (version.isNewerThan(ServerVersion.v_1_8_8) && version.isOlderThan(ServerVersion.v_1_19_3)) {
Object dataWatcherObject = readAnyObject(0);
WrappedPacket wrappedDataWatcher = new WrappedPacket(new NMSPacket(dataWatcherObject));
return wrappedDataWatcher.readInt(0);
} else {
//1.19.3 changed back to this
return readInt(0);
}
}
public void setIndex(int index) {
if (version.isNewerThan(ServerVersion.v_1_8_8)) {
if (version.isNewerThan(ServerVersion.v_1_8_8) && version.isOlderThan(ServerVersion.v_1_19_3)) {
Object dataWatcherObject = readAnyObject(0);
WrappedPacket wrappedDataWatcher = new WrappedPacket(new NMSPacket(dataWatcherObject));
wrappedDataWatcher.writeInt(0, index);
@@ -69,11 +79,13 @@ public class WrappedWatchableObject extends WrappedPacket {
}
public boolean isDirty() {
return readBoolean(0);
return !version.isOlderThan(ServerVersion.v_1_19_3) || readBoolean(0);
}
public void setDirty(boolean dirty) {
writeBoolean(0, dirty);
if (version.isOlderThan(ServerVersion.v_1_19_3)) {
writeBoolean(0, dirty);
}
}
public Object getRawValue() {
@@ -18,16 +18,19 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.entitystatus;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import org.bukkit.entity.Entity;
import java.lang.reflect.Constructor;
public class WrappedPacketOutEntityStatus extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static boolean v_1_17;
private static Constructor<?> packetConstructor;
private byte status;
@@ -48,9 +51,15 @@ public class WrappedPacketOutEntityStatus extends WrappedPacketEntityAbstraction
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
try {
packetConstructor =
PacketTypeClasses.Play.Server.ENTITY_STATUS.getConstructor(NMSUtils.nmsEntityClass, byte.class);
if (v_1_17) {
packetConstructor = PacketTypeClasses.Play.Server.ENTITY_STATUS.getConstructor(NMSUtils.packetDataSerializerClass);
}
else {
packetConstructor =
PacketTypeClasses.Play.Server.ENTITY_STATUS.getConstructor();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -74,7 +83,17 @@ public class WrappedPacketOutEntityStatus extends WrappedPacketEntityAbstraction
@Override
public Object asNMSPacket() throws Exception {
Object nmsEntity = NMSUtils.getNMSEntity(getEntity());
return packetConstructor.newInstance(nmsEntity, getEntityStatus());
Object packetInstance;
if (v_1_17) {
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(PacketEvents.get().getByteBufUtil().newByteBuf(new byte[] {0, 0, 0, 0, 0}));
packetInstance = packetConstructor.newInstance(packetDataSerializer);
}
else {
packetInstance = packetConstructor.newInstance();
}
WrappedPacketOutEntityStatus entityStatus = new WrappedPacketOutEntityStatus(new NMSPacket(packetInstance));
entityStatus.setEntityId(getEntityId());
entityStatus.setEntityStatus(getEntityStatus());
return packetInstance;
}
}
@@ -18,10 +18,13 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.entityteleport;
import io.github.retrooper.packetevents.PacketEvents;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
import io.github.retrooper.packetevents.packetwrappers.api.helper.WrappedPacketEntityAbstraction;
import io.github.retrooper.packetevents.utils.nms.NMSUtils;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import io.github.retrooper.packetevents.utils.vector.Vector3d;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
@@ -30,6 +33,7 @@ import java.lang.reflect.Constructor;
public class WrappedPacketOutEntityTeleport extends WrappedPacketEntityAbstraction implements SendableWrapper {
private static final float rotationMultiplier = 256.0F / 360.0F;
private static boolean v_1_17;
private static boolean legacyVersionMode;
private static boolean ultraLegacyVersionMode;
private static Constructor<?> constructor;
@@ -90,6 +94,7 @@ public class WrappedPacketOutEntityTeleport extends WrappedPacketEntityAbstracti
@Override
protected void load() {
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
Class<?> packetClass = PacketTypeClasses.Play.Server.ENTITY_TELEPORT;
try {
constructor = packetClass.getConstructor(int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class, boolean.class);
@@ -102,7 +107,11 @@ public class WrappedPacketOutEntityTeleport extends WrappedPacketEntityAbstracti
legacyVersionMode = true;
} catch (NoSuchMethodException e2) {
try {
constructor = packetClass.getConstructor();
if (v_1_17) {
constructor = packetClass.getConstructor(NMSUtils.packetDataSerializerClass);
} else {
constructor = packetClass.getConstructor();
}
ultraLegacyVersionMode = false;
legacyVersionMode = false;
} catch (NoSuchMethodException e3) {
@@ -208,8 +217,22 @@ public class WrappedPacketOutEntityTeleport extends WrappedPacketEntityAbstracti
(byte) ((int) getYaw() * rotationMultiplier), (byte) (int) (getPitch() * rotationMultiplier), false);
} else {
//newer versions
Object instance = constructor.newInstance();
Object instance;
if (v_1_17) {
Object byteBuf = PacketEvents.get().getByteBufUtil().newByteBuf(new byte[]{
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0});
//4 bytes per bytebuf field
Object packetDataSerializer = NMSUtils.generatePacketDataSerializer(byteBuf);
instance = constructor.newInstance(packetDataSerializer);
} else {
instance = constructor.newInstance();
}
WrappedPacketOutEntityTeleport instanceWrapper = new WrappedPacketOutEntityTeleport(new NMSPacket(instance));
instanceWrapper.setEntityId(getEntityId());
instanceWrapper.setPosition(pos);
@@ -84,9 +84,9 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacketEntityAbs
public void setVelocity(Vector3d velocity) {
if (packet != null) {
writeInt(1, (int) (velocity.x));
writeInt(2, (int) (velocity.y));
writeInt(3, (int) (velocity.z));
writeInt(1, (int) (velocity.x * 8000.0));
writeInt(2, (int) (velocity.y * 8000.0));
writeInt(3, (int) (velocity.z * 8000.0));
}
else {
this.velocityX = velocity.x;
@@ -95,7 +95,6 @@ public final class WrappedPacketOutEntityVelocity extends WrappedPacketEntityAbs
}
}
//TODO Cut off at 1.8.1 and optimize the methods above.
@Deprecated
public double getVelocityX() {
if (packet != null) {
@@ -18,6 +18,7 @@
package io.github.retrooper.packetevents.packetwrappers.play.out.explosion;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.packetwrappers.api.SendableWrapper;
@@ -33,7 +34,8 @@ import java.util.ArrayList;
import java.util.List;
public class WrappedPacketOutExplosion extends WrappedPacket implements SendableWrapper {
private static Constructor<?> chunkPosConstructor, blockPosConstructor, packetConstructor, vec3dConstructor;
private static boolean v_1_8;
private static Constructor<?> chunkPosConstructor, packetConstructor;
private double x, y, z;
private float strength;
@@ -70,27 +72,16 @@ public class WrappedPacketOutExplosion extends WrappedPacket implements Sendable
@Override
protected void load() {
Class<?> chunkPosClass = NMSUtils.getNMSClassWithoutException("ChunkPosition");
Class<?> blockPosClass = NMSUtils.getNMSClassWithoutException("BlockPosition");
Class<?> packetClass = NMSUtils.getNMSClassWithoutException("PacketPlayOutExplosion");
Class<?> vec3DClass = NMSUtils.getNMSClassWithoutException("Vec3D");
v_1_8 = version.isNewerThanOrEquals(ServerVersion.v_1_8);
try {
packetConstructor = packetClass.getConstructor(double.class, double.class, double.class, float.class, List.class, vec3DClass);
vec3dConstructor = vec3DClass.getDeclaredConstructor(double.class, double.class, double.class);
Class<?> chunkPosClass = NMSUtils.getNMSClassWithoutException("ChunkPosition");
packetConstructor = PacketTypeClasses.Play.Server.EXPLOSION.getConstructor(double.class, double.class, double.class, float.class, List.class, NMSUtils.vec3DClass);
if (chunkPosClass != null) {
chunkPosConstructor = chunkPosClass.getConstructor(int.class, int.class, int.class);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
if (blockPosClass != null) {
blockPosConstructor = blockPosClass.getConstructor(int.class, int.class, int.class);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
//1.20.4 or newer
}
}
@@ -211,10 +202,9 @@ public class WrappedPacketOutExplosion extends WrappedPacket implements Sendable
if (packet != null) {
List<Object> nmsRecordsList = new ArrayList<>();
for (Vector3i record : records) {
Object[] arguments = {record.x, record.y, record.z};
Object position = null; //construct position
try {
position = version.isNewerThan(ServerVersion.v_1_7_10) ? blockPosConstructor.newInstance(arguments) : chunkPosConstructor.newInstance(arguments);
position = v_1_8 ? NMSUtils.generateNMSBlockPos(record) : chunkPosConstructor.newInstance(record.x, record.y, record.z);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
@@ -248,7 +238,6 @@ public class WrappedPacketOutExplosion extends WrappedPacket implements Sendable
}
}
//TODO Cut off at 1.8.1, and once you cut off, you can optimize the methods above. Also optimize the position part.
@Deprecated
public float getPlayerMotionX() {
if (packet != null) {
@@ -307,14 +296,13 @@ public class WrappedPacketOutExplosion extends WrappedPacket implements Sendable
public Object asNMSPacket() throws Exception {
List<Object> positions = new ArrayList<>();
for (Vector3i record : getRecords()) {
Object[] arguments = {record.x, record.y, record.z};
Object position = version.isNewerThan(ServerVersion.v_1_7_10) ? blockPosConstructor.newInstance(arguments)
: chunkPosConstructor.newInstance(arguments);
Object position = v_1_8 ? NMSUtils.generateNMSBlockPos(record)
: chunkPosConstructor.newInstance(record.x, record.y, record.z);
positions.add(position);
}
Vector3f velocity = getPlayerVelocity();
Vector3f pos = getPlayerVelocity();
Object vec = vec3dConstructor.newInstance(velocity.x, velocity.y, velocity.z);
Object vec = NMSUtils.generateVec3D(velocity);
return packetConstructor.newInstance(pos.x, pos.y, pos.z, getStrength(), positions, vec);
}
}
@@ -54,6 +54,7 @@ public class WrappedPacketOutGameStateChange extends WrappedPacket implements Se
@Override
protected void load() {
reasonClassType = SubclassUtil.getSubClass(PacketTypeClasses.Play.Server.GAME_STATE_CHANGE, 0);
net.minecraft.server.v1_8_R3.PacketPlayOutGameStateChange gsc;
if (reasonClassType != null) {
try {
reasonClassConstructor = reasonClassType.getConstructor(int.class);
@@ -140,7 +141,7 @@ public class WrappedPacketOutGameStateChange extends WrappedPacket implements Se
@Override
public Object asNMSPacket() throws Exception {
if (reasonClassType == null) {
if (reasonIntMode) {
if (valueFloatMode) {
return packetConstructor.newInstance(getReason(), (float) getValue());
} else {
@@ -42,10 +42,8 @@ public final class WrappedPacketOutKickDisconnect extends WrappedPacket implemen
@Override
protected void load() {
Class<?> packetClass = PacketTypeClasses.Play.Server.KICK_DISCONNECT;
try {
kickDisconnectConstructor = packetClass.getConstructor(NMSUtils.iChatBaseComponentClass);
kickDisconnectConstructor = PacketTypeClasses.Play.Server.KICK_DISCONNECT.getConstructor(NMSUtils.iChatBaseComponentClass);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
@@ -25,13 +25,16 @@ import io.github.retrooper.packetevents.utils.server.ServerVersion;
//TODO Make sendable and finish
public class WrappedPacketOutLogin extends WrappedPacketEntityAbstraction {
private static boolean v_1_13_2, v_1_17;
public WrappedPacketOutLogin(NMSPacket packet) {
super(packet);
}
@Override
protected void load() {
v_1_13_2 = version.isNewerThanOrEquals(ServerVersion.v_1_13_2);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
}
public boolean isHardcore() {
@@ -70,14 +73,34 @@ public class WrappedPacketOutLogin extends WrappedPacketEntityAbstraction {
public int getMaxPlayers() {
if (packet != null) {
if (version.isNewerThan(ServerVersion.v_1_13_1)) {
return readInt(1);
} else {
return readInt(2);
}
int index = v_1_13_2 && !v_1_17 ? 1 : 2;
return readInt(index);
} else {
//TODO Finish
return -1;
}
}
public int getPortalCooldown() {
if (packet != null) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
return readInt(4);
}
}
else {
//TODO unfinished
}
return 0;
}
public void setPortalCooldown(int portalCooldown) {
if (packet != null) {
if (version.isNewerThanOrEquals(ServerVersion.v_1_20)) {
writeInt(4, portalCooldown);
}
}
else {
//TODO unfinished
}
}
}
@@ -21,15 +21,19 @@ package io.github.retrooper.packetevents.packetwrappers.play.out.mapchunk;
import io.github.retrooper.packetevents.packettype.PacketTypeClasses;
import io.github.retrooper.packetevents.packetwrappers.NMSPacket;
import io.github.retrooper.packetevents.packetwrappers.WrappedPacket;
import io.github.retrooper.packetevents.utils.reflection.Reflection;
import io.github.retrooper.packetevents.utils.reflection.SubclassUtil;
import io.github.retrooper.packetevents.utils.server.ServerVersion;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.BitSet;
import java.util.Optional;
//TODO finish wrapper
public class WrappedPacketOutMapChunk extends WrappedPacket {
private Class<?> chunkMapClass;
private static boolean v_1_8_x, v_1_17, v_1_18;
private static Class<?> chunkMapClass, chunkPacketDataClass;
private Constructor<?> chunkMapConstructor;
private Object nmsChunkMap;
@@ -39,55 +43,82 @@ public class WrappedPacketOutMapChunk extends WrappedPacket {
@Override
protected void load() {
if (version.isNewerThan(ServerVersion.v_1_7_10) && version.isOlderThan(ServerVersion.v_1_9)) {
chunkMapClass = SubclassUtil.getSubClass(PacketTypeClasses.Play.Server.MAP_CHUNK, "ChunkMap");
v_1_8_x = version.isNewerThan(ServerVersion.v_1_7_10) && version.isOlderThan(ServerVersion.v_1_9);
v_1_17 = version.isNewerThanOrEquals(ServerVersion.v_1_17);
v_1_18 = version.isNewerThanOrEquals(ServerVersion.v_1_18);
if (v_1_8_x) {
chunkMapClass = SubclassUtil.getSubClass(PacketTypeClasses.Play.Server.MAP_CHUNK, 0);
try {
chunkMapConstructor = chunkMapClass.getConstructor();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
net.minecraft.server.v1_7_R4.PacketPlayOutMapChunk a0;
net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk a1;
net.minecraft.server.v1_9_R1.PacketPlayOutMapChunk a2;
net.minecraft.server.v1_9_R2.PacketPlayOutMapChunk a3;
net.minecraft.server.v1_12_R1.PacketPlayOutMapChunk a4;
net.minecraft.server.v1_13_R1.PacketPlayOutMapChunk a5;
net.minecraft.server.v1_13_R2.PacketPlayOutMapChunk a6;
net.minecraft.server.v1_16_R2.PacketPlayOutMapChunk a7;
chunkPacketDataClass = Reflection.getClassByNameWithoutException("net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData");
}
public int getChunkX() {
return readInt(0);
return readInt(v_1_17 && !v_1_18 ? 1 : 0);
}
public void setChunkX(int chunkX) {
writeInt(0, chunkX);
writeInt(v_1_17 && !v_1_18 ? 1 : 0, chunkX);
}
public int getChunkZ() {
return readInt(1);
return readInt(v_1_17 && !v_1_18 ? 2 : 1);
}
public void setChunkZ(int chunkZ) {
writeInt(1, chunkZ);
writeInt(v_1_17 && !v_1_18 ? 2 : 1, chunkZ);
}
public int getPrimaryBitMap() {
if (version.isNewerThan(ServerVersion.v_1_7_10) && version.isOlderThan(ServerVersion.v_1_9)) {
public Optional<BitSet> getBitSet() {
if (v_1_18) { // Bitsets were removed in 1.18
return Optional.empty();
}
if (v_1_17) {
return Optional.of(readObject(0, BitSet.class));
}
if (v_1_8_x) {
if (nmsChunkMap == null) {
nmsChunkMap = readObject(0, chunkMapClass);
}
WrappedPacket nmsChunkMapWrapper = new WrappedPacket(new NMSPacket(nmsChunkMap));
return nmsChunkMapWrapper.readInt(0);
return Optional.of(BitSet.valueOf(new long[]{nmsChunkMapWrapper.readInt(0)}));
} else {
return readInt(2);
return Optional.of(BitSet.valueOf(new long[]{readInt(2)}));
}
}
public void setPrimaryBitMap(int primaryBitMap) {
if (version.isNewerThan(ServerVersion.v_1_7_10) && version.isOlderThan(ServerVersion.v_1_9)) {
/**
* @param bitSet Bitset that can hold multiple integer values to support the expanded world height on
* 1.17 and newer servers. This is due to 1.17 needing to support up to 127 chunk sections
* (2032 blocks) and an integer only being able to hold 32 bits to represent 32 chunk sections
*/
public void setPrimaryBitMask(BitSet bitSet) {
if (v_1_18) return; // Bitsets were removed in 1.18
if (v_1_17) {
writeObject(0, bitSet);
return;
}
setPrimaryBitMask((int) bitSet.toLongArray()[0]);
}
/**
* @param primaryBitMask Integer that determines which chunk sections the server is sending
* @deprecated Possible lossy conversion on 1.17 servers that could result in the client only reading 32
* out of the total possible 127 chunk sections. Safe to use on 1.16 and below servers
*/
@Deprecated
public void setPrimaryBitMask(int primaryBitMask) {
if (v_1_18) return; // Bitsets were removed in 1.18
if (v_1_17) {
writeObject(0, BitSet.valueOf(new long[]{primaryBitMask}));
return;
}
if (v_1_8_x) {
if (nmsChunkMap == null) {
try {
nmsChunkMap = chunkMapConstructor.newInstance();
@@ -96,36 +127,50 @@ public class WrappedPacketOutMapChunk extends WrappedPacket {
}
}
WrappedPacket nmsChunkMapWrapper = new WrappedPacket(new NMSPacket(nmsChunkMap));
nmsChunkMapWrapper.writeInt(0, primaryBitMap);
nmsChunkMapWrapper.writeInt(0, primaryBitMask);
write(chunkMapClass, 0, nmsChunkMap);
} else {
writeInt(2, primaryBitMap);
writeInt(2, primaryBitMask);
}
}
public boolean isGroundUpContinuous() {
return readBoolean(0);
/**
* @return Whether the packet overwrites the entire chunk column or just the sections being sent
*/
public Optional<Boolean> isGroundUpContinuous() {
if (v_1_17) {
return Optional.empty();
}
return Optional.of(readBoolean(0));
}
/**
* @param groundUpContinuous Whether the packet overwrites the entire chunk column or just the sections being sent
*/
public void setGroundUpContinuous(boolean groundUpContinuous) {
if (v_1_17) {
return;
}
writeBoolean(0, groundUpContinuous);
}
public byte[] getCompressedData() {
if (version.isNewerThan(ServerVersion.v_1_7_10) && version.isOlderThan(ServerVersion.v_1_9)) {
if (v_1_8_x) {
if (nmsChunkMap == null) {
nmsChunkMap = readObject(0, chunkMapClass);
}
WrappedPacket nmsChunkMapWrapper = new WrappedPacket(new NMSPacket(nmsChunkMap));
return nmsChunkMapWrapper.readByteArray(0);
} else if (v_1_18) {
return new WrappedPacket(new NMSPacket(readObject(0, chunkPacketDataClass))).readByteArray(0);
} else {
return readByteArray(0);
}
}
public void setCompressedData(byte[] data) {
if (version.isNewerThan(ServerVersion.v_1_7_10) && version.isOlderThan(ServerVersion.v_1_9)) {
if (v_1_8_x) {
if (nmsChunkMap == null) {
try {
nmsChunkMap = chunkMapConstructor.newInstance();
@@ -136,9 +181,10 @@ public class WrappedPacketOutMapChunk extends WrappedPacket {
WrappedPacket nmsChunkMapWrapper = new WrappedPacket(new NMSPacket(nmsChunkMap));
nmsChunkMapWrapper.writeByteArray(0, data);
write(chunkMapClass, 0, nmsChunkMap);
} else if (v_1_18) {
new WrappedPacket(new NMSPacket(readObject(0, chunkPacketDataClass))).writeByteArray(0, data);
} else {
writeByteArray(0, data);
}
}
}
Loaded 100 of 164 files, more files were not shown because too many files have changed in this diff. Show more