198 Commits
Author SHA1 Message Date
FlorianMichael b34cc42a65 4.0.0 Release 2024-06-16 18:10:25 +02:00
FlorianMichael 7b1f0a8737 Rename build-logic submodule 2024-06-15 21:14:47 +02:00
FlorianMichael a171e4013b Only accept correct byte type in custom payload 1.8->1.7 2024-06-11 15:38:34 +02:00
FlorianMichael 3e3561c18f Update VV API usage 2024-06-11 15:36:03 +02:00
FlorianMichael 0097a97ab0 Add note for J8 builds 2024-06-06 05:20:24 +02:00
FlorianMichael 6e583a0c8e Remove missing bungee/sponge references 2024-06-06 05:11:00 +02:00
FlorianMichael 780b981c68 Fixup hologram handling 1.8->1.7
Closes https://github.com/ViaVersion/ViaRewind/issues/509
2024-06-06 05:07:47 +02:00
FlorianMichael 5df933f0e2 Fix 1.7->1.8 player action rewriting 2024-06-03 03:02:45 +02:00
FlorianMichael 750a98cb06 Fixup position reading 2024-06-02 17:50:56 +02:00
FlorianMichael 1ebfa0a715 Update Gradle Wrapper 2024-06-01 17:41:58 +02:00
Nassim Jahnke dc82de8ba2 Move Sponge and Bungee modules to separate plugins 2024-05-30 22:45:53 +02:00
Nassim Jahnke 9ecdaa30bf Use unsigned byte for facing direction in player action 2024-05-30 11:33:49 +02:00
FlorianMichael ee69005318 Delete temporary fix for shulker box window titles
Properly fixed by https://github.com/ViaVersion/ViaBackwards/pull/761
2024-05-28 18:11:08 +02:00
FlorianMichael 740a6d9b96 Finish up v5 migration
Also:
- Reduces the amount of anonymous classes
- Removes usages of PacketWrapper#create with raw ids
2024-05-22 23:36:51 +02:00
Nassim Jahnke b1d680468b Update VV API usage 2024-05-22 12:11:11 +02:00
FlorianMichael 64c18af7b6 Update Via API usage 2024-05-18 21:33:21 +02:00
FlorianMichael 6728a8a809 Port to upstream changes (hopefully) 2024-05-15 00:08:22 +02:00
FlorianMichael 0cb70b0a04 Rename protocol packages and classes 2024-05-11 15:18:21 +02:00
FlorianMichael 2f7f108cd8 Bump version to 4.0.0-SNAPSHOT 2024-05-11 15:12:41 +02:00
FlorianMichael c595c654aa 3.1.2 Release 2024-05-10 13:19:10 +02:00
FlorianMichael c0d1cabb12 Fix bow animation not working in 1.9->1.8
Closes https://github.com/ViaVersion/ViaRewind/issues/516
2024-05-10 00:29:41 +02:00
FlorianMichael 51e81c7bb1 Fix mappings and update project description
Closes https://github.com/ViaVersion/ViaRewind/issues/514
2024-05-10 00:08:00 +02:00
FlorianMichael 6bdaa54ce8 Use 1.9.0 sounds for name<->id conversion
1.9.1 added a new sound so mapping files were previously wrong
2024-05-09 01:03:39 +02:00
FlorianMichael 65ac2f37f2 Don't throw metadata away in 1.8->1.7
Closes https://github.com/ViaVersion/ViaRewind/issues/512
2024-05-09 00:25:13 +02:00
FlorianMichael b08bb90cef Fix packet send usages 2024-05-08 21:31:47 +02:00
FlorianMichael 89e76d369b Fix destroy entities handling in 1.7->1.8
Split into multiple packets since 1.8 can handle a larger list of entities than 1.7 can, causing NegativeArraySizeException's to appear on some servers.
2024-05-07 00:09:24 +02:00
FlorianMichael ed8cc47c7a Bump version to 3.1.2-SNAPSHOT 2024-05-06 23:51:55 +02:00
FlorianMichael d988fdc849 3.1.1 Release 2024-05-05 16:45:42 +02:00
FlorianMichael a0ff53fb9d Don't handle entity properties for holograms 2024-04-30 19:08:19 +02:00
FlorianMichael 1d1dd7dc66 Catch exceptions in custom payload handling
Closes https://github.com/ViaVersion/ViaRewind/issues/192
2024-04-29 02:25:21 +02:00
FlorianMichael cb4ef9ffa8 Fix mob spawner entity data translation in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/126
2024-04-29 02:05:15 +02:00
FlorianMichael 459f403541 Map END_GATEWAY to END_PORTAL in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/150
2024-04-29 01:54:46 +02:00
FlorianMichael 465962b939 Clear enchantments on screen close 2024-04-29 01:42:51 +02:00
FlorianMichael 2fad493eac Rewrite enchantment window properties in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/485
2024-04-29 01:38:29 +02:00
FlorianMichael fb8ea8c4f8 Merge remote-tracking branch 'origin/master' 2024-04-29 00:33:00 +02:00
FlorianMichael 9713e5a8a4 Update mapping files 2024-04-29 00:32:30 +02:00
Nassim Jahnke 7cee59f548 Set paperweight-mappings-namespace manifest attribute 2024-04-28 12:34:56 +02:00
FlorianMichael c7e638fc70 Fix 1.8->1.9 window items translation 2024-04-27 13:58:42 +02:00
FlorianMichael a4b445cf1f Use correct method to remove vehicle in 1.8->1.9
Closes https://github.com/ViaVersion/ViaRewind/issues/505
2024-04-27 13:10:02 +02:00
FlorianMichael 6859f6125c Bump version to 3.1.1-SNAPSHOT 2024-04-27 12:58:07 +02:00
FlorianMichael d85e043325 3.1.0 Release 2024-04-26 15:32:46 +02:00
FlorianMichael 967adaa607 Update item mappings
Adds support for https://github.com/ViaVersion/ViaBackwards/pull/728 as well as missing blockstate mappings from before the rewrite.
2024-04-26 00:27:44 +02:00
FlorianMichael e233b0fa09 Fix and clean hologram emulation 2024-04-24 18:10:29 +02:00
FlorianMichael 2e52a396d3 Migrate 1.7->1.8 as well 2024-04-24 16:57:00 +02:00
FlorianMichael 93731be764 Add new config options for /offhand, also some cleanup 2024-04-23 23:49:43 +02:00
FlorianMichael 8a5d826fd3 Tidy up a few things and fixed tons of bugs 2024-04-23 22:29:37 +02:00
FlorianMichael d5fa0ff8e8 Migrate 1.8->1.9 and removed tons of outdated code 2024-04-23 20:35:27 +02:00
FlorianMichael 823b00930e Merge remote-tracking branch 'refs/remotes/origin/dev' into refactor/viabackwards
# Conflicts:
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/packets/BlockItemPackets1_8.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/rewriter/ReplacementItemRewriter1_7_6_10.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/metadata/MetadataRewriter.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/packets/InventoryPackets.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/rewriter/ReplacementItemRewriter1_8.java
2024-04-22 11:46:53 +02:00
Nassim Jahnke da449f2a9e Add UserConnection param to item rewriter methods 2024-04-21 22:48:30 +02:00
FlorianMichael 8835ee4ed2 Update metadata rewriter 2024-04-09 16:00:48 +02:00
FlorianMichael 3ef9dbec1f Merge branch 'refs/heads/dev' into refactor/viabackwards
# Conflicts:
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_8to1_9/metadata/MetadataRewriter.java
2024-04-09 15:59:31 +02:00
FlorianMichael b2a78d6dd2 Merge remote-tracking branch 'refs/remotes/origin/master' into dev 2024-04-09 15:57:56 +02:00
FlorianMichael 1aaba348d2 Update build script 2024-04-09 15:56:46 +02:00
FlorianMichael 4d5c4e6223 Removed non-existent meta type 2024-04-09 15:53:42 +02:00
FlorianMichael d08739839e Fix universal module name 2024-04-09 15:51:35 +02:00
FlorianMichael e891696387 Start with porting protocol code 2024-04-09 15:47:45 +02:00
vadage 08cb78f065 Support config loading from input stream (#502)
* Support config loading from input stream

* Fix formatting issue to be consistent with spaces
2024-04-05 20:38:35 +02:00
FlorianMichael 819a4d8bb3 More work 2024-03-29 18:13:05 +01:00
FlorianMichael aa5696e586 Overall improvements to README.md 2024-03-29 13:00:02 +01:00
FlorianMichael 3c9232949a Rename classes to match VB 2024-03-29 12:47:38 +01:00
FlorianMichael a43ad2b737 Prepare entity rewriter migration 2024-03-29 12:41:17 +01:00
FlorianMichael 7e5e8fd2c1 Fix enchantments in 1.7->1.8 2024-03-28 18:08:24 +01:00
FlorianMichael 7fc2530693 Compile from repository server 2024-03-28 11:46:11 +01:00
FlorianMichael e104df51b0 Drop format reset 2024-03-28 10:44:32 +01:00
FlorianMichael 6d237cc337 Deprecate and move classes 2024-03-27 20:34:23 +01:00
FlorianMichael a982ac8c38 Move particle class 2024-03-27 20:26:28 +01:00
FlorianMichael 8494976e4f Port 1.8 -> 1.9 item rewriter as well 2024-03-27 20:02:50 +01:00
FlorianMichael 7b2ad249da Use EnchantmentRewriter base (probably) 2024-03-27 18:22:31 +01:00
FlorianMichael 5f73bee3c5 Start with using ViaBackwards API 2024-03-27 18:04:04 +01:00
FlorianMichael 709f918272 Generate item mappings 2024-03-27 13:55:39 +01:00
FlorianMichael dca9854486 Removed support status from README 2024-03-27 13:54:44 +01:00
FlorianMichael d93dce88d8 So it begins... 2024-03-27 11:12:37 +01:00
FlorianMichael 5ae0f29f42 Fixed version range 2024-03-25 17:35:55 +01:00
FlorianMichael eae4a3ac09 Renamed universal artifact to viarewind, fixed platform name in Via dumps 2024-03-25 17:34:07 +01:00
FlorianMichael 5e1ae7ac0f Back to VV dev 2024-03-24 13:06:13 +01:00
FlorianMichael 2422588db5 Remove viafabricplus from dependency list 2024-03-24 13:01:43 +01:00
FlorianMichael 0a1707f1d0 Fix up again 2024-03-23 13:18:47 +01:00
FlorianMichael c6d6128c5e Update publishing plugin usage 2024-03-23 13:11:40 +01:00
FlorianMichael 8f2072d2af [ci skip] Removed unused import 2024-03-23 12:32:59 +01:00
FlorianMichael 42fbcfb26a Gradle 8.7 2024-03-23 12:31:27 +01:00
FlorianMichael a9568d388f Update Hangar publish plugin 2024-03-23 12:29:42 +01:00
FlorianMichael 36ea0fecc6 Fixed compile error 2024-03-09 14:11:41 +01:00
FlorianMichael 6a26bbdf84 Back to VV master 2024-03-09 14:09:30 +01:00
FlorianMichael 45deefdea3 Update ViaNBT API usage 2024-03-09 14:04:37 +01:00
FlorianMichael 476c5f2077 Updated Via API usage 2024-03-09 13:51:19 +01:00
FlorianMichael aaddfb186b Fixed API usage 2024-03-05 21:02:35 +01:00
FlorianMichael 5407bf9922 Bump version to 3.0.7-24w09a-SNAPSHOT 2024-03-05 20:13:44 +01:00
FlorianMichael 8aea3e43aa Bump version to 3.0.7-SNAPSHOT 2024-03-05 20:11:38 +01:00
FlorianMichael 38e59d7cb5 3.0.6 2024-03-05 19:55:56 +01:00
FlorianMichael 66851feaff [ci skip] Create FUNDING.yml 2024-03-05 13:46:58 +01:00
FlorianMichael 2474f2f347 Merge remote-tracking branch 'origin/master' 2024-03-04 22:18:51 +01:00
FlorianMichael 3322b77afb Merge dev changes into master 2024-03-04 22:18:39 +01:00
FlorianMichael fc7b10e4aa Merge remote-tracking branch 'origin/dev' 2024-03-04 22:15:27 +01:00
FlorianMichael 000c414418 Change dev branch version to 3.0.6-24w07a-SNAPSHOT 2024-03-04 22:13:44 +01:00
FlorianMichael 26b9a83f5a Fixed api usages 2024-02-29 15:25:04 +01:00
FlorianMichael 37a671dfa1 Simplified entity rewriter 2024-02-29 15:21:01 +01:00
FlorianMichael 6a1c89676c Fixed painting rotations in 1.7 -> 1.8 2024-02-29 14:51:56 +01:00
FlorianMichael f0706eca23 Cleaned up token replacement 2024-02-29 14:22:15 +01:00
FlorianMichael 0610ed53ab Finished ReplacementEntityTracker rewrite for now (?) 2024-02-29 14:10:11 +01:00
FlorianMichael dbe26e0ecc Move some classes 2024-02-29 14:04:17 +01:00
FlorianMichael 62606d604e Random code cleanup 2024-02-29 14:01:44 +01:00
FlorianMichael 7254e1ce42 [ci skip] Removed debug code 2024-02-29 13:53:32 +01:00
FlorianMichael b3b6bb325f Proper include of project description 2024-02-29 13:33:21 +01:00
FlorianMichael a0eb8aee24 Mark VR as library for ModMenu 2024-02-29 12:25:16 +01:00
FlorianMichael 630e0224e6 Use equals in legacy custom payload channel comparisons 2024-02-29 12:23:12 +01:00
EnZaXD 224cc121d7 Merge pull request #488 from Kichura/master
paste.gg -> mclo.gs
2024-02-18 23:12:57 +01:00
Kichura a6d9b601d1 paste.gg -> mclo.gs. 2024-02-18 23:10:28 +01:00
FlorianMichael 97044dbe2c Back to VV master 2024-02-18 22:43:35 +01:00
FlorianMichael bb5610c072 Added ViaRewindPlatform#getDataFolder to match VV/VB style 2024-02-18 22:27:08 +01:00
FlorianMichael 57997b25cf Sync fabric.mod.json description with project description 2024-02-18 22:18:33 +01:00
FlorianMichael fc85a00d8c Updated mcVersions in gradle.properties 2024-02-14 20:41:47 +01:00
FlorianMichael f6ceeba636 Updated Via API usage 2024-02-14 20:39:57 +01:00
FlorianMichael 66c810c284 Merge remote-tracking branch 'origin/master' into dev 2024-01-26 15:28:48 +01:00
EnZaXD 3422d90882 Merge pull request #481 from Kichura/master
Update JDK to 17, Cache to v4
2024-01-20 21:24:04 +01:00
Kichura 1f4ab995c5 Update JDK to 17, Cache to v4. 2024-01-20 21:13:17 +01:00
EnZaXD 6a726a289d Merge pull request #479 from ItsClairton/master
fix: Add missing creeper metadata
2024-01-19 14:04:00 +01:00
Clairton (Aiko - W11) 4abe3fb7e8 Add missing creeper metadata, index 18 2024-01-18 00:17:13 -03:00
EnZaXD db93bbbc3e Merge pull request #476 from Kichura/master
Update Velocity to 3.3
2024-01-14 17:25:20 +01:00
Kichura dd220ccf7f Update Velocity to 3.3. 2024-01-14 13:09:37 +01:00
FlorianMichael 0a20ead08b Compile against dev branch of VV again ™️ 2024-01-13 06:37:57 +01:00
FlorianMichael 1eb0d1672e Merge branch 'master' into dev 2024-01-13 06:36:29 +01:00
FlorianMichael f0969b5515 Fixed Via API usage 2024-01-13 06:35:20 +01:00
FlorianMichael 05dea07d99 Delete a lot unused code 2024-01-02 18:53:03 +01:00
FlorianMichael 4d3e5264bc Read names 2024-01-02 18:49:13 +01:00
FlorianMichael fba5a1c7d1 Compile against master branch of VV 2024-01-02 18:21:14 +01:00
EnZaXD 171d33525f Merge pull request #473 from ViaVersion/master
Update dev branch for master changes
2024-01-02 18:20:45 +01:00
FlorianMichael 8d35b00fd7 2024 2024-01-01 00:47:57 +01:00
FlorianMichael 572551b670 Fixed 1.8 -> 1.9 explosion packet translation being broken.
Closes https://github.com/ViaVersion/ViaRewind/issues/471
2023-12-28 00:27:33 +01:00
FlorianMichael 531e564d0b Use correct version for serializing the json component 2023-12-27 20:09:35 +01:00
FlorianMichael 81840dc643 Updated Via API usage 2023-12-27 20:03:00 +01:00
FlorianMichael a9f0b72adc Merge remote-tracking branch 'origin/master' 2023-12-27 17:55:23 +01:00
FlorianMichael e1b9c76063 Updated copyright profile 2023-12-27 17:54:52 +01:00
Kichura 2da271ffe7 [ci skip] Update checkout and setup-java to v4. (#470) 2023-12-27 17:26:33 +01:00
Kichura f27b4f0df6 Add description for ViaRewind. (#468)
This properly describes on what viarewind is for when viewing it in Mod Menu.
2023-12-23 11:51:37 +01:00
SplotyCode cf64b7ffcc Fix 1.9->1.8 use item (#466) 2023-12-21 10:19:12 +01:00
FlorianMichael 6829af6cb7 Bump version to 3.0.6-SNAPSHOT 2023-12-13 23:21:04 +01:00
FlorianMichael 8892110810 3.0.5 Release 2023-12-05 19:26:15 +01:00
EnZaXD c1cd560b06 1.20.3-pre1 2023-11-20 19:43:14 +01:00
EnZaXD cd74482278 23w46a 2023-11-20 14:04:17 +01:00
FlorianMichael 7cb97dcfd1 Fixed Bulk Chunk 1.7 <-> 1.8 skylight reading 2023-11-07 21:02:56 +01:00
FlorianMichael 69363c8bd5 Merge remote-tracking branch 'origin/dev' into dev 2023-11-05 19:40:01 +01:00
FlorianMichael b1c9616364 Added armor stand interaction rewriting 2023-11-05 19:39:48 +01:00
EnZaXD 5c4d928426 23w44a Via 2023-11-03 20:16:04 +01:00
SplotyCode dfebb916bb Added cooldown api in 1.7 -> 1.8 (#463)
* Cooldown api

* Small cleanup

* Remove unnecessary method
2023-11-01 05:16:04 +01:00
FlorianMichael ab4b9277e4 Hotfix for NPE in spectator emulation
Fixed https://github.com/ViaVersion/ViaRewind/issues/462
2023-10-30 20:27:44 +01:00
FlorianMichael d8b36666d5 Cleaned entity tracker code 2023-10-29 02:29:19 +02:00
FlorianMichael 784a444283 Track player ids correctly 2023-10-27 00:00:43 +02:00
FlorianMichael b1f153ea0a fixed yStance 2023-10-26 23:01:11 +02:00
FlorianMichael 8f48781268 Bump version to 3.0.4-SNAPSHOT 2023-10-26 22:12:46 +02:00
FlorianMichael c2f19c6528 Replaced deprecated API usage 2023-10-26 22:12:23 +02:00
FlorianMichael b0e7a20c86 Implemented hologram rewriting
Fixed https://github.com/ViaVersion/ViaRewind/issues/97
Probably fixed https://github.com/ViaVersion/ViaRewind/issues/458
Probably fixed https://github.com/ViaVersion/ViaRewind/issues/457
2023-10-26 22:05:27 +02:00
FlorianMichael ebed6dd715 Merge branch 'dev' into abstraction 2023-10-26 16:05:24 +02:00
FlorianMichael 21c0a4e304 23w43a 2023-10-26 16:01:04 +02:00
FlorianMichael 2650e7ae44 Updated chunk reading and writing to work with Via again 2023-10-20 12:05:42 +02:00
FlorianMichael 15c434cb42 Removed unused field and fixed player id tracking 2023-10-19 22:22:29 +02:00
FlorianMichael 7bd0a0b85d Apply API changes to new abstraction 2023-10-19 18:33:07 +02:00
FlorianMichael 2c8f431377 Merge remote-tracking branch 'origin/dev' into abstraction
# Conflicts:
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/Protocol1_7_6_10To1_8.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/emulator/EndermiteModel.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/emulator/GuardianModel.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/emulator/RabbitModel.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/model/VirtualHologramEntity.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/packets/EntityPackets.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/packets/PlayerPackets.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/packets/SpawnPackets.java
#	common/src/main/java/com/viaversion/viarewind/protocol/protocol1_7_6_10to1_8/storage/EntityTracker.java
2023-10-19 18:30:21 +02:00
FlorianMichael 5ed1d3a4d3 Updated Via API usage 2023-10-19 18:20:46 +02:00
FlorianMichael b85d305fe1 It compiles ™️ 2023-10-19 18:11:03 +02:00
FlorianMichael 0a55b0a35b Correctly rewrite block ids in chunk packets 2023-10-11 04:05:12 +02:00
FlorianMichael 3650a08752 Show version in Item replacements 2023-10-11 01:08:35 +02:00
FlorianMichael 14a314d167 Added abstraction types for position rewriting in 1.7 -> 1.8, cleanup of SpawnPackets, added groups for Via types. 2023-10-10 13:34:18 +02:00
FlorianMichael dc2babd173 Merge remote-tracking branch 'origin/dev' into dev 2023-10-10 06:13:58 +02:00
FlorianMichael 9bb731037b Fixed https://github.com/ViaVersion/ViaRewind/issues/283 2023-10-10 06:13:34 +02:00
Kichura 68bc76cfba Depend on newer fabric loader, Recommend newer ViaFabric (#459)
* Depend on newer fabric loader.

Fabric loader 0.4.0 is too ancient and very likely will not work properly with the current viarewind build.

* Recommend atleast viafabric 0.4.10 or higher.

Having "*" for viafabric included is not a great idea as then all copies are accepted including unsupported ones.
2023-10-09 01:42:30 +02:00
FlorianMichael 1f651a67c7 Bump version to 3.0.3-SNAPSHOT 2023-10-09 01:35:26 +02:00
FlorianMichael 2d3e495f85 Fixed metadata issues, added new config options to emulate world border, cleaned protocol code. 2023-10-09 01:28:58 +02:00
FlorianMichael 7689769e26 Fixed merge conflict. 2023-10-08 22:56:38 +02:00
FlorianMichael 990a5bafe1 Merge remote-tracking branch 'origin/1.7-particle-data-fix' into dev
# Conflicts:
#	core/src/main/java/de/gerrygames/viarewind/protocol/protocol1_7_6_10to1_8/packets/WorldPackets.java
2023-10-08 22:53:24 +02:00
FlorianMichael bdef039008 Fixed loading on Bukkit 2023-10-08 20:49:40 +02:00
FlorianMichael f516528e77 Rewrote entity packet translations 2023-10-08 12:42:21 +02:00
FlorianMichael ad85d1c4fd 1.7 -> 1.8: deleted Ticker system 2023-10-08 12:21:20 +02:00
FlorianMichael 15769e5ee3 Initial rewrite of entity emulation system
Don't buffer Entity Metadata
2023-10-08 12:08:40 +02:00
FlorianMichael a7e865ee6d Allow platform implementation to define config path 2023-10-08 08:59:52 +02:00
FlorianMichael 4a0a4bb40c Fabric is also a thing! 2023-10-08 07:18:10 +02:00
FlorianMichael 16d308610e Updated all platform implementations 2023-10-08 07:15:58 +02:00
FlorianMichael b5825462bf Fixed 1.7 -> 1.8 metadata rewriting not working 2023-10-08 06:22:42 +02:00
FlorianMichael fe123b13b7 Load 1.8 -> 1.9 item replacements 2023-10-08 06:16:56 +02:00
FlorianMichael 3fa305f637 Refactor ItemRewriter and replacement system 2023-10-08 06:15:51 +02:00
FlorianMichael 5a0e57a4a0 Added more exception handling to Metadata rewriter (1.7 -> 1.8) 2023-10-08 03:35:24 +02:00
FlorianMichael 76dcad78ce Start with rewriting Replacement system 2023-10-08 03:13:49 +02:00
FlorianMichael bff3a99f2d Rewrote chunk handling (1.7 -> 1.8) completely. 2023-10-08 02:22:54 +02:00
FlorianMichael f95a2db7f5 Small code cleanup. 2023-10-08 01:38:39 +02:00
FlorianMichael 5a126695c3 Bump version to 3.0.2-SNAPSHOT 2023-10-07 23:02:10 +02:00
FlorianMichael e84a9b619f Cleaned up Compression handling 2023-10-07 21:39:20 +02:00
FlorianMichael 684e6d1377 Cleaned up Protocol 1.7.2 -> 1.7.6 2023-10-07 20:59:53 +02:00
FlorianMichael f1988765ba Don't allow platform to be initialized twice. 2023-10-07 20:33:12 +02:00
FlorianMichael df28363692 Mention ViaProxy instead of ViaFabricPlus in README file. 2023-10-07 20:29:36 +02:00
FlorianMichael eb6e7b17b8 Merge remote-tracking branch 'origin/master' into dev 2023-10-07 20:22:20 +02:00
Nassim Jahnke 85c2816808 Fix branch check on headless ci 2023-09-26 10:51:32 +10:00
Nassim Jahnke f7a2f22bed [ci skip] Fix branch check in publishing 2023-09-26 00:27:47 +10:00
FlorianMichael 1cce662f36 Move util to correct package 2023-09-23 03:29:59 +02:00
FlorianMichael bf359bb81e Improved Hologram detection method in ArmorStandReplacement 2023-09-23 03:20:44 +02:00
FlorianMichael 925484c45e Apply checkstyle, build javadoc and source jar file 2023-09-22 23:09:33 +02:00
FlorianMichael 916cb9bae0 Fixed compile error 2023-09-21 20:24:18 +02:00
Terrence S 3892a02ce3 Make overall formatting more consistent plus a few spelling fixes and minor changes (#455) 2023-09-21 20:18:53 +02:00
FlorianMichael c2bf1a6231 Bump version to 3.0.1-SNAPSHOT 2023-09-21 20:11:42 +02:00
ShinyDialga 2b791879d3 Fix data values for BLOCK_CRACK and BLOCK_DUST particles for 1.7 players 2021-03-22 22:22:25 -05:00
170 changed files with 9181 additions and 11410 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
github: FlorianMichael
custom: ['https://florianmichael.de/donate', 'https://viaversion.com/donate', 'https://creeper123123321.github.io/#donate']
+5 -5
View File
@@ -23,11 +23,11 @@ body:
attributes:
label: Console Error
description: |
If you encounter warnings/errors in your console, **paste them with https://paste.gg/ and put the paste link here**.
If you encounter warnings/errors in your console, **paste them with https://mclo.gs/ and put the paste link here**.
If the error is small/less than 10 lines, you may put it directly into this field.
value: |
```
Put the paste.gg link or text here.
Put the mclo.gs link or text here.
```
placeholder: Please do not remove the grave accents; simply replace the line of text in the middle.
validations:
@@ -71,9 +71,9 @@ body:
attributes:
label: Additional Server Info
description: |
Do you use a proxy (eg. BungeeCord)? What software do you use and what plugins?
Do you use a proxy (eg. Velocity)? What software do you use and what plugins?
placeholder: |
Example: "I also use BungeeCord with the following plugins: x, y, z"
Example: "I also use Velocity with the following plugins: x, y, z"
validations:
required: false
@@ -82,7 +82,7 @@ body:
label: Checklist
description: Make sure you have followed each of the steps outlined here.
options:
- label: Via plugins are only running on **EITHER** the backend servers (e.g. Paper) **OR** the proxy (e.g. BungeeCord), **not on both**.
- label: Via plugins are only running on **EITHER** the backend servers (e.g. Paper) **OR** the proxy (e.g. Velocity), **not on both**.
required: true
- label: I have included a ViaVersion dump.
required: true
+5 -5
View File
@@ -6,17 +6,17 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 8
uses: actions/setup-java@v3
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 8
java-version: 17
check-latest: true
- name: Cache Dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
+4 -4
View File
@@ -11,14 +11,14 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 8
uses: actions/setup-java@v3
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 8
java-version: 17
check-latest: true
- name: Publish
env:
+1 -1
View File
@@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind&#10;Copyright (C) &amp;#36;originalComment.match(&quot;Copyright \(C\) (\d+)&quot;, 1, &quot;-&quot;)&amp;#36;today.year ViaVersion and contributors&#10;&#10;This program is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;(at your option) any later version.&#10;&#10;This program is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10;&#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." />
<option name="notice" value="This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind&#10;Copyright (C) 2018-&amp;#36;today.year ViaVersion and contributors&#10;&#10;This program is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;(at your option) any later version.&#10;&#10;This program is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10;&#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." />
<option name="myName" value="viarewind-gpl" />
</copyright>
</component>
+25 -9
View File
@@ -1,22 +1,27 @@
# ViaRewind
[![Latest Release](https://img.shields.io/github/v/release/ViaVersion/ViaRewind)](https://github.com/ViaVersion/ViaRewind/releases)
[![Build Status](https://github.com/ViaVersion/ViaRewind/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/ViaVersion/ViaRewind/actions)
[![Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://viaversion.com/discord)
**ViaVersion addon to allow 1.8.x and 1.7.x clients on newer server versions.** <br>
**ViaBackwards addon to allow 1.8.x and 1.7.x clients on newer server versions.** <br>
Runs on 1.9-latest servers or 1.8 clients and lower.
**On Fabric, use either [ViaFabric](https://modrinth.com/mod/viafabric) or [ViaFabricPlus](https://modrinth.com/mod/viafabricplus). To override the included version**
**You can override the included version in [ViaFabric](https://modrinth.com/mod/viafabric) or [ViaProxy](https://github.com/ViaVersion/ViaProxy):**
- in **ViaFabric**, put ViaRewind into the `mods` folder
- in **ViaFabricPlus**, put ViaRewind into the `ViaFabricPlus/jars` folder
- in **ViaProxy**, put ViaRewind into the `jars` folder
**Depending on the platform and version, this also requires [ViaVersion](https://modrinth.com/mod/viaversion) and [ViaBackwards](https://modrinth.com/mod/viabackwards).**
Note: when using ViaFabric <= 1.16.5 or J8 ViaProxy builds, you need [J8 ViaRewind](https://ci.viaversion.com/view/ViaRewind/job/ViaRewind-Java8/) builds.
Support Status
**Requires [ViaVersion](https://hangar.papermc.io/ViaVersion/ViaVersion) and [ViaBackwards](https://hangar.papermc.io/ViaVersion/ViaBackwards) to be installed..**
Releases/Dev Builds
-
While ViaRewind will keep getting updates to function with changes to ViaVersion or ViaBackwards, it will likely not receive many bug fixes or additional features anymore.
You can find releases in the following places:
- **Hangar (for our plugins)**: https://hangar.papermc.io/ViaVersion/ViaRewind
- **Modrinth (for our mods)**: https://modrinth.com/mod/viarewind
- **GitHub**: https://github.com/ViaVersion/ViaRewind/releases
Releases / Dev Builds
-
Dev builds for **all** of our projects are on our Jenkins server:
- **Jenkins**: https://ci.viaversion.com/view/ViaRewind/
@@ -27,4 +32,15 @@ Other Links
**Issue tracker:** https://github.com/ViaVersion/ViaRewind/issues
**List of contributors:** https://github.com/ViaVersion/ViaRewind/graphs/contributors
**List of contributors:** https://github.com/ViaVersion/ViaRewind/graphs/contributors
Building
-
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out
of the `universal/build/libs` directory.
You need JDK 17 or newer to build ViaRewind.
License
-
This project is licensed under the [GNU General Public License Version 3](LICENSE).
File renamed without changes.
@@ -4,31 +4,24 @@ plugins {
}
repositories {
mavenLocal()
maven {
url = uri("https://repo.viaversion.com")
}
maven {
url = uri("https://repo.maven.apache.org/maven2/")
}
maven {
url = uri("https://hub.spigotmc.org/nexus/content/repositories/snapshots/")
}
maven {
url = uri("https://oss.sonatype.org/content/repositories/snapshots")
}
maven {
url = uri("https://maven.fabricmc.net/")
}
maven {
url = uri("https://repo.spongepowered.org/repository/maven-public/")
}
maven {
url = uri("https://nexus.velocitypowered.com/repository/maven-public/")
}
@@ -36,24 +29,29 @@ repositories {
dependencies {
compileOnly "com.viaversion:viaversion:${project.viaversion_version}"
compileOnly "com.viaversion:viabackwards:${project.viabackwards_version}"
compileOnly "io.netty:netty-all:${project.netty_version}"
compileOnly "com.google.guava:guava:${project.guava_version}"
}
archivesBaseName = project.maven_name
group = project.maven_group
version = project.maven_version
base {
archivesName = project.maven_name
group = project.maven_group
version = project.maven_version
description = "ViaBackwards addon to allow 1.8.x and 1.7.x clients on newer server versions."
}
java.sourceCompatibility = JavaVersion.VERSION_1_8
java.sourceCompatibility = JavaVersion.VERSION_17
tasks {
// Variable replacements
processResources {
inputs.property "version", project.version
for (final def file in ["plugin.yml", "bungee.yml", "META-INF/sponge_plugins.json", "fabric.mod.json"]) {
for (final def file in ["plugin.yml", "fabric.mod.json"]) {
filesMatching(file) {
expand "version": version
expand(
"version": project.version,
"description": project.description
)
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,20 +15,17 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind;
import com.viaversion.viarewind.api.ViaRewindPlatform;
import com.viaversion.viaversion.api.Via;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
public class BukkitPlugin extends JavaPlugin implements ViaRewindPlatform {
@Override
public void onEnable() {
ViaRewindConfig conf = new ViaRewindConfig(new File(getDataFolder(), "config.yml"));
conf.reloadConfig();
this.init(conf);
public BukkitPlugin() {
Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml")));
}
}
+5 -7
View File
@@ -1,12 +1,10 @@
name: ViaRewind
version: ${version}
main: com.viaversion.viarewind.BukkitPlugin
authors: [FlorianMichael/EnZaXD, Gerrygames, creeper123321123]
version: ${version}
description: ${description}
website: https://viaversion.com/rewind
api-version: 1.13
folia-supported: true
authors: [Gerrygames, FlorianMichael/EnZaXD, creeper123321123]
website: https://viaversion.com/rewind
load: STARTUP
depend: [ViaVersion]
softdepend: [ViaBackwards]
depend: [ViaVersion, ViaBackwards]
-9
View File
@@ -1,9 +0,0 @@
plugins {
id "com.viaversion.java-conventions"
}
dependencies {
api project(":viarewind-common")
compileOnly(annotationProcessor("net.md-5:bungeecord-api:1.16-R0.5-SNAPSHOT"))
}
-1
View File
@@ -1 +0,0 @@
maven_name=viarewind-bungee
-7
View File
@@ -1,7 +0,0 @@
name: ViaRewind
main: com.viaversion.viarewind.BungeePlugin
authors: [Gerrygames, FlorianMichael/EnZaXD, creeper123321123]
version: ${version}
depends: [ViaVersion]
softdepends: [ViaBackwards]
website: https://viaversion.com/rewind
+1 -1
View File
@@ -13,7 +13,7 @@ sourceSets {
main {
classTokenReplacer {
property("\${version}", rootProject.maven_version)
property("\${impl_version}", "git-${project.name}-${rootProject.maven_version}:${project.latestCommitHash()}")
property("\${impl_version}", "git-ViaRewind-${rootProject.maven_version}:${project.latestCommitHash()}")
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,9 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind;
import com.google.common.base.Preconditions;
import com.viaversion.viarewind.api.ViaRewindConfig;
import com.viaversion.viarewind.api.ViaRewindPlatform;
@@ -27,6 +27,8 @@ public class ViaRewind {
private static ViaRewindConfig config;
public static void init(ViaRewindPlatform platform, ViaRewindConfig config) {
Preconditions.checkArgument(ViaRewind.platform == null, "ViaRewind is already initialized");
ViaRewind.platform = platform;
ViaRewind.config = config;
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,56 +15,116 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind;
import com.viaversion.viaversion.util.Config;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
public class ViaRewindConfig extends Config implements com.viaversion.viarewind.api.ViaRewindConfig {
public ViaRewindConfig(File configFile) {
super(configFile);
reloadConfig();
private CooldownIndicator cooldownIndicator;
private boolean replaceAdventureMode;
private boolean replaceParticles;
private int maxBookPages;
private int maxBookPageSize;
private boolean emulateWorldBorder;
private boolean alwaysShowOriginalMobName;
private String worldBorderParticle;
private boolean enableOffhand;
private String offhandCommand;
public ViaRewindConfig(File configFile, Logger logger) {
super(configFile, logger);
}
@Override
@Override
public void reload() {
super.reload();
loadFields();
}
private void loadFields() {
cooldownIndicator = CooldownIndicator.valueOf(getString("cooldown-indicator", "TITLE").toUpperCase());
replaceAdventureMode = getBoolean("replace-adventure", false);
replaceParticles = getBoolean("replace-particles", false);
maxBookPages = getInt("max-book-pages", 100);
maxBookPageSize = getInt("max-book-page-length", 5000);
emulateWorldBorder = getBoolean("emulate-world-border", true);
alwaysShowOriginalMobName = getBoolean("always-show-original-mob-name", true);
worldBorderParticle = getString("world-border-particle", "fireworksSpark");
enableOffhand = getBoolean("enable-offhand", true);
offhandCommand = getString("offhand-command", "/offhand");
}
@Override
public CooldownIndicator getCooldownIndicator() {
return CooldownIndicator.valueOf(getString("cooldown-indicator", "TITLE").toUpperCase());
return cooldownIndicator;
}
@Override
public boolean isReplaceAdventureMode() {
return getBoolean("replace-adventure", false);
return replaceAdventureMode;
}
@Override
public boolean isReplaceParticles() {
return getBoolean("replace-particles", false);
return replaceParticles;
}
@Override
public int getMaxBookPages() {
return getInt("max-book-pages", 100);
return maxBookPages;
}
@Override
public int getMaxBookPageSize() {
return getInt("max-book-page-length", 5000);
return maxBookPageSize;
}
@Override
@Override
public boolean isEmulateWorldBorder() {
return emulateWorldBorder;
}
@Override
public boolean alwaysShowOriginalMobName() {
return alwaysShowOriginalMobName;
}
@Override
public String getWorldBorderParticle() {
return worldBorderParticle;
}
@Override
public boolean isEnableOffhand() {
return enableOffhand;
}
@Override
public String getOffhandCommand() {
return offhandCommand;
}
@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viarewind/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> map) {
public InputStream getDefaultConfigInputStream() {
return getClass().getClassLoader().getResourceAsStream("assets/viarewind/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> map) {
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,13 +15,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api;
import com.viaversion.viaversion.api.configuration.Config;
/**
* This class is used to get the platform specific config
*/
public interface ViaRewindConfig {
public interface ViaRewindConfig extends Config {
enum CooldownIndicator {
TITLE, ACTION_BAR, BOSS_BAR, DISABLED
@@ -67,4 +68,39 @@ public interface ViaRewindConfig {
* @return the max amount of characters
*/
int getMaxBookPageSize();
/**
* Whether to emulate the 1.8+ world border for 1.7.x clients
*
* @return true if enabled
*/
boolean isEmulateWorldBorder();
/**
* Always shows the original mob's name instead of only when hovering over them with the cursor.
*
* @return true if enabled
*/
boolean alwaysShowOriginalMobName();
/**
* The particle to show the world border for the 1.8+ world border for 1.7.x clients
*
* @return the particle name (see <a href="https://wiki.vg/index.php?title=Protocol&oldid=7368#Particle_2">Particle registry for Packet</a>)
*/
String getWorldBorderParticle();
/**
* If enabled, 1.8 players on 1.9+ servers can use /offhand to switch items between their main hand and offhand.
*
* @return true if enabled
*/
boolean isEnableOffhand();
/**
* Allows to define the offhand command
*
* @return the offhand command
*/
String getOffhandCommand();
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,17 +15,18 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api;
import com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10.Protocol1_7_2_5To1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.ViaRewindConfig;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.Protocol1_7_6_10To1_7_2_5;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.ProtocolManager;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import java.io.File;
import java.util.logging.Logger;
/**
@@ -39,16 +40,21 @@ public interface ViaRewindPlatform {
/**
* Initialize ViaRewind
*/
default void init(ViaRewindConfig config) {
default void init(final File configFile) {
ViaRewindConfig config = new ViaRewindConfig(configFile, getLogger());
config.reload();
Via.getManager().getConfigurationProvider().register(config);
ViaRewind.init(this, config);
Via.getManager().getSubPlatforms().add(IMPL_VERSION);
getLogger().info("Registering protocols...");
final ProtocolManager protocolManager = Via.getManager().getProtocolManager();
protocolManager.registerProtocol(new Protocol1_7_6_10To1_7_2_5(), ProtocolVersion.v1_7_2, ProtocolVersion.v1_7_6);
protocolManager.registerProtocol(new Protocol1_8To1_7_6_10(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_8);
protocolManager.registerProtocol(new Protocol1_8To1_9(), ProtocolVersion.v1_8, ProtocolVersion.v1_9);
protocolManager.registerProtocol(new Protocol1_7_6_10To1_8(), ProtocolVersion.v1_7_6, ProtocolVersion.v1_8);
protocolManager.registerProtocol(new Protocol1_7_2_5To1_7_6_10(), ProtocolVersion.v1_7_1, ProtocolVersion.v1_7_6);
protocolManager.registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_8, ProtocolVersion.v1_9);
}
/**
@@ -57,4 +63,11 @@ public interface ViaRewindPlatform {
* @return the logger
*/
Logger getLogger();
/**
* Returns ViaRewind's data folder.
*
* @return data folder
*/
File getDataFolder();
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,28 +15,27 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.data;
package com.viaversion.viarewind.replacement;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import java.util.logging.Logger;
import java.util.List;
public class RewindMappingData extends BackwardsMappingData {
public interface EntityReplacement {
public RewindMappingData(String unmappedVersion, String mappedVersion) {
super(unmappedVersion, mappedVersion);
}
int getEntityId();
@Override
protected Logger getLogger() {
return ViaRewind.getPlatform().getLogger();
}
void setLocation(double x, double y, double z);
void relMove(double x, double y, double z);
void setYawPitch(float yaw, float pitch);
void setHeadYaw(float yaw);
void spawn();
void despawn();
void updateMetadata(List<Metadata> metadataList);
@Override
protected CompoundTag readMappingsFile(String name) {
return RewindMappingDataLoader.INSTANCE.loadNBTFromDir(name);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,20 +15,30 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.data;
package com.viaversion.viarewind;
import com.viaversion.viarewind.api.ViaRewindPlatform;
import net.md_5.bungee.api.plugin.Plugin;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
import com.viaversion.viarewind.ViaRewind;
import java.io.File;
import java.util.logging.Logger;
public class BungeePlugin extends Plugin implements ViaRewindPlatform {
public class RewindMappingDataLoader extends BackwardsMappingDataLoader {
@Override
public void onEnable() {
ViaRewindConfig conf = new ViaRewindConfig(new File(getDataFolder(), "config.yml"));
conf.reloadConfig();
this.init(conf);
}
public static final RewindMappingDataLoader INSTANCE = new RewindMappingDataLoader();
public RewindMappingDataLoader() {
super(RewindMappingDataLoader.class, "assets/viarewind/data/");
}
@Override
public Logger getLogger() {
return ViaRewind.getPlatform().getLogger();
}
@Override
public File getDataFolder() {
return ViaRewind.getPlatform().getDataFolder();
}
}
@@ -0,0 +1,77 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.minecraft;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray;
public class ExtendedBlockStorage {
private final byte[] blockLSBArray = new byte[4096];
private final NibbleArray blockMetadataArray = new NibbleArray(this.blockLSBArray.length);
private final NibbleArray blockLightArray = new NibbleArray(this.blockLSBArray.length);
private NibbleArray blockMSBArray;
private NibbleArray skyLightArray;
public ExtendedBlockStorage(final boolean skylight) {
if (skylight) {
this.skyLightArray = new NibbleArray(this.blockLSBArray.length);
}
}
public void setBlockId(final int x, final int y, final int z, final int value) {
this.blockLSBArray[ChunkSection.index(x, y, z)] = (byte) (value & 255);
if (value > 255) {
this.getOrCreateBlockMSBArray().set(x, y, z, (value & 0xF00) >> 8);
} else if (this.blockMSBArray != null) {
this.blockMSBArray.set(x, y, z, 0);
}
}
public void setBlockMetadata(final int x, final int y, final int z, final int value) {
this.blockMetadataArray.set(x, y, z, value);
}
public boolean hasBlockMSBArray() {
return this.blockMSBArray != null;
}
public byte[] getBlockLSBArray() {
return this.blockLSBArray;
}
public NibbleArray getOrCreateBlockMSBArray() {
if (this.blockMSBArray == null) {
return this.blockMSBArray = new NibbleArray(this.blockLSBArray.length);
}
return this.blockMSBArray;
}
public NibbleArray getBlockMetadataArray() {
return this.blockMetadataArray;
}
public NibbleArray getBlockLightArray() {
return this.blockLightArray;
}
public NibbleArray getSkyLightArray() {
return this.skyLightArray;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,39 +15,41 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft.entitydata;
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
public enum MetaType1_7_6_10 implements MetaType {
Byte(0, Type.BYTE),
Short(1, Type.SHORT),
Int(2, Type.INT),
Float(3, Type.FLOAT),
String(4, Type.STRING),
Slot(5, Types1_7_6_10.COMPRESSED_NBT_ITEM),
Position(6, Type.VECTOR),
NonExistent(-1, Type.NOTHING);
public enum EntityDataTypes1_7_6_10 implements EntityDataType {
BYTE(0, Types.BYTE),
SHORT(1, Types.SHORT),
INT(2, Types.INT),
FLOAT(3, Types.FLOAT),
STRING(4, Types.STRING),
ITEM(5, RewindTypes.COMPRESSED_NBT_ITEM),
POSITION(6, Types.VECTOR);
private final int typeID;
private final Type type;
private final Type<?> type;
public static MetaType1_7_6_10 byId(int id) {
return values()[id];
}
MetaType1_7_6_10(int typeID, Type type) {
EntityDataTypes1_7_6_10(int typeID, Type<?> type) {
this.typeID = typeID;
this.type = type;
}
public static EntityDataTypes1_7_6_10 byId(int id) {
return values()[id];
}
@Override
public int typeId() {
return this.typeID;
}
public Type type() {
@Override
public Type<?> type() {
return this.type;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.utils.math;
package com.viaversion.viarewind.api.minecraft.math;
public class AABB {
Vector3d min;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.utils.math;
package com.viaversion.viarewind.api.minecraft.math;
public class Ray3d {
Vector3d start;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.utils.math;
package com.viaversion.viarewind.api.minecraft.math;
public class RayTracing {
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,17 +15,18 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.minecraft.math;
package com.viaversion.viarewind.protocol.protocol1_8to1_9.util;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.EntityTracker;
import com.viaversion.viarewind.protocol.v1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viarewind.protocol.v1_9to1_8.storage.EntityTracker1_9;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Vector;
@Deprecated // ?????????
public class RelativeMoveUtil {
public static Vector[] calculateRelativeMoves(UserConnection user, int entityId, int relX, int relY, int relZ) {
EntityTracker tracker = user.get(EntityTracker.class);
EntityTracker1_9 tracker = user.getEntityTracker(Protocol1_9To1_8.class);
int x;
int y;
@@ -82,13 +83,13 @@ public class RelativeMoveUtil {
sentRelY = relY1 + relY2;
sentRelZ = relZ1 + relZ2;
moves = new Vector[] {new Vector(relX1, relY1, relZ1), new Vector(relX2, relY2, relZ2)};
moves = new Vector[]{new Vector(relX1, relY1, relZ1), new Vector(relX2, relY2, relZ2)};
} else {
sentRelX = Math.round(relX / 128f);
sentRelY = Math.round(relY / 128f);
sentRelZ = Math.round(relZ / 128f);
moves = new Vector[] {new Vector(sentRelX, sentRelY, sentRelZ)};
moves = new Vector[]{new Vector(sentRelX, sentRelY, sentRelZ)};
}
x = x + relX - sentRelX * 128;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.utils.math;
package com.viaversion.viarewind.api.minecraft.math;
import java.util.Objects;
@@ -80,6 +79,7 @@ public class Vector3d {
return this;
}
@Override
public Vector3d clone() {
return new Vector3d(this.x, this.y, this.z);
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.netty;
package com.viaversion.viarewind.api.minecraft.netty;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerAdapter;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.netty;
package com.viaversion.viarewind.api.minecraft.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
@@ -0,0 +1,42 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.rewriter;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.LegacyBlockItemRewriter;
import com.viaversion.viarewind.api.data.RewindMappingDataLoader;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.libs.gson.JsonObject;
public class VRBlockItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType, T extends BackwardsProtocol<C, ?, ?, S>> extends LegacyBlockItemRewriter<C, S, T> {
protected VRBlockItemRewriter(T protocol, String name) {
super(protocol, name);
}
@Override
protected JsonObject readMappingsFile(String name) {
return RewindMappingDataLoader.INSTANCE.loadFromDataDir(name);
}
@Override
public String nbtTagName() {
return "VR|" + protocol.getClass().getSimpleName();
}
}
@@ -0,0 +1,71 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.rewriter;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.LegacyEntityRewriter;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityDataType;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
public abstract class VREntityRewriter<C extends ClientboundPacketType, T extends BackwardsProtocol<C, ?, ?, ?>> extends LegacyEntityRewriter<C, T> {
public VREntityRewriter(T protocol) {
super(protocol, EntityDataTypes1_8.STRING, EntityDataTypes1_8.BYTE);
}
public VREntityRewriter(T protocol, EntityDataType displayType, EntityDataType displayVisibilityType) {
super(protocol, displayType, displayVisibilityType);
}
protected void registerJoinGame1_8(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
protected void register() {
map(Types.INT); // Entity id
map(Types.UNSIGNED_BYTE); // Game mode
map(Types.BYTE); // Dimension
handler(playerTrackerHandler());
handler(wrapper -> wrapper.user().get(ClientWorld.class).setEnvironment(wrapper.get(Types.BYTE, 0)));
}
});
}
protected void untrackEntities(final UserConnection connection, final int[] entities) {
final EntityTrackerBase tracker = tracker(connection);
for (int entityId : entities) {
tracker.removeEntity(entityId);
}
}
@Override
protected Object getDisplayVisibilityMetaValue() {
return (byte) 1;
}
@Override
protected boolean alwaysShowOriginalMobName() {
return ViaRewind.getConfig().alwaysShowOriginalMobName();
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,8 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
package com.viaversion.viarewind.api.type;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
@@ -28,7 +27,7 @@ public class IntArrayType extends Type<int[]> {
}
@Override
public int[] read(ByteBuf byteBuf) throws Exception {
public int[] read(ByteBuf byteBuf) {
byte size = byteBuf.readByte();
int[] array = new int[size];
for (byte i = 0; i < size; i++) {
@@ -38,7 +37,7 @@ public class IntArrayType extends Type<int[]> {
}
@Override
public void write(ByteBuf byteBuf, int[] array) throws Exception {
public void write(ByteBuf byteBuf, int[] array) {
byteBuf.writeByte(array.length);
for (int i : array) byteBuf.writeInt(i);
}
@@ -0,0 +1,53 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.type;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
import java.util.function.IntFunction;
public class PositionVarYType<T extends Number> extends Type<BlockPosition> {
private final Type<T> yType;
private final IntFunction<T> toY;
public PositionVarYType(final Type<T> yType, final IntFunction<T> toY) {
super(BlockPosition.class);
this.yType = yType;
this.toY = toY;
}
@Override
public BlockPosition read(ByteBuf buffer) {
final int x = buffer.readInt();
final int y = yType.read(buffer).intValue();
final int z = buffer.readInt();
return new BlockPosition(x, y, z);
}
@Override
public void write(ByteBuf buffer, BlockPosition value) {
buffer.writeInt(value.x());
yType.write(buffer, this.toY.apply(value.y()));
buffer.writeInt(value.z());
}
}
@@ -0,0 +1,50 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.type;
import com.viaversion.viarewind.api.type.item.NBTType;
import com.viaversion.viarewind.api.type.item.ItemArrayType;
import com.viaversion.viarewind.api.type.item.ItemType;
import com.viaversion.viarewind.api.type.entitydata.EntityDataListType;
import com.viaversion.viarewind.api.type.entitydata.EntityDataType;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.nbt.tag.CompoundTag;
import java.util.List;
/**
* Safe to use before protocol loading
*/
public class RewindTypes {
public static final Type<int[]> INT_ARRAY = new IntArrayType(); // Integer array with byte as length indicator
public static final Type<BlockPosition> SHORT_POSITION = new PositionVarYType<>(Types.SHORT, value -> (short) value);
public static final Type<BlockPosition> INT_POSITION = new PositionVarYType<>(Types.INT, value -> value);
public static final Type<BlockPosition> BYTE_POSITION = new PositionVarYType<>(Types.BYTE, value -> (byte) value);
public static final Type<BlockPosition> U_BYTE_POSITION = new PositionVarYType<>(Types.UNSIGNED_BYTE, value -> (short) value);
public static final Type<CompoundTag> COMPRESSED_NBT = new NBTType();
public static final Type<Item> COMPRESSED_NBT_ITEM = new ItemType();
public static final Type<Item[]> COMPRESSED_NBT_ITEM_ARRAY = new ItemArrayType();
}
@@ -0,0 +1,102 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.type.chunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Pair;
import io.netty.buffer.ByteBuf;
import java.io.ByteArrayOutputStream;
import java.util.zip.Deflater;
public class BulkChunkType1_7_6 extends Type<Chunk[]> {
public static final BulkChunkType1_7_6 TYPE = new BulkChunkType1_7_6();
public BulkChunkType1_7_6() {
super(Chunk[].class);
}
@Override
public Chunk[] read(ByteBuf byteBuf) {
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/ChunkBulk1_7_6Type.java
}
@Override
public void write(ByteBuf byteBuf, Chunk[] chunks) {
final int chunkCount = chunks.length;
final ByteArrayOutputStream output = new ByteArrayOutputStream();
final int[] chunkX = new int[chunkCount];
final int[] chunkZ = new int[chunkCount];
final short[] primaryBitMask = new short[chunkCount];
final short[] additionalBitMask = new short[chunkCount];
for (int i = 0; i < chunkCount; i++) {
final Chunk chunk = chunks[i];
Pair<byte[], Short> chunkData;
try {
chunkData = ChunkType1_7_6.serialize(chunk);
output.write(chunkData.key());
} catch (Exception e) {
throw new RuntimeException("Unable to serialize chunk", e);
}
chunkX[i] = chunk.getX();
chunkZ[i] = chunk.getZ();
primaryBitMask[i] = (short) chunk.getBitmask();
additionalBitMask[i] = chunkData.value();
}
final byte[] data = output.toByteArray();
final Deflater deflater = new Deflater();
byte[] compressedData;
int compressedSize;
try {
deflater.setInput(data, 0, data.length);
deflater.finish();
compressedData = new byte[data.length];
compressedSize = deflater.deflate(compressedData);
} finally {
deflater.end();
}
byteBuf.writeShort(chunkCount);
byteBuf.writeInt(compressedSize);
boolean skyLight = false;
for (Chunk chunk : chunks) {
for (ChunkSection section : chunk.getSections()) {
if (section != null && section.getLight().hasSkyLight()) {
skyLight = true;
break;
}
}
}
byteBuf.writeBoolean(skyLight); // hasSkyLight
byteBuf.writeBytes(compressedData, 0, compressedSize);
for (int i = 0; i < chunkCount; i++) {
byteBuf.writeInt(chunkX[i]);
byteBuf.writeInt(chunkZ[i]);
byteBuf.writeShort(primaryBitMask[i]);
byteBuf.writeShort(additionalBitMask[i]);
}
}
}
@@ -0,0 +1,139 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.type.chunk;
import com.viaversion.viarewind.api.minecraft.ExtendedBlockStorage;
import com.viaversion.viaversion.api.minecraft.chunks.*;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Pair;
import io.netty.buffer.ByteBuf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.Deflater;
public class ChunkType1_7_6 extends Type<Chunk> {
public static final ChunkType1_7_6 TYPE = new ChunkType1_7_6();
public ChunkType1_7_6() {
super(Chunk.class);
}
@Override
public Chunk read(ByteBuf byteBuf) {
throw new UnsupportedOperationException(); // Not needed, see https://github.com/ViaVersion/ViaLegacy/blob/main/src/main/java/net/raphimc/vialegacy/protocols/release/protocol1_8to1_7_6_10/types/Chunk1_7_6Type.java
}
@Override
public void write(ByteBuf output, Chunk chunk) {
Pair<byte[], Short> chunkData;
try {
chunkData = serialize(chunk);
} catch (IOException e) {
throw new RuntimeException("Unable to serialize chunk", e);
}
final byte[] data = chunkData.key();
final short additionalBitMask = chunkData.value();
final Deflater deflater = new Deflater();
byte[] compressedData;
int compressedSize;
try {
deflater.setInput(data, 0, data.length);
deflater.finish();
compressedData = new byte[data.length];
compressedSize = deflater.deflate(compressedData);
} finally {
deflater.end();
}
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
output.writeBoolean(chunk.isFullChunk());
output.writeShort(chunk.getBitmask());
output.writeShort(additionalBitMask);
output.writeInt(compressedSize);
output.writeBytes(compressedData, 0, compressedSize);
}
public static Pair<byte[], Short> serialize(final Chunk chunk) throws IOException {
final ExtendedBlockStorage[] storageArrays = new ExtendedBlockStorage[16];
for (int i = 0; i < storageArrays.length; i++) {
final ChunkSection section = chunk.getSections()[i];
if (section != null) {
final ExtendedBlockStorage storage = storageArrays[i] = new ExtendedBlockStorage(section.getLight().hasSkyLight());
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < 16; y++) {
final int flatBlock = section.palette(PaletteType.BLOCKS).idAt(x, y, z);
storage.setBlockId(x, y, z, flatBlock >> 4);
storage.setBlockMetadata(x, y, z, flatBlock & 15);
}
}
}
storage.getBlockLightArray().setHandle(section.getLight().getBlockLight());
if (section.getLight().hasSkyLight()) {
storage.getSkyLightArray().setHandle(section.getLight().getSkyLight());
}
}
}
final ByteArrayOutputStream output = new ByteArrayOutputStream();
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockLSBArray());
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockMetadataArray().getHandle());
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0) {
output.write(storageArrays[i].getBlockLightArray().getHandle());
}
}
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].getSkyLightArray() != null) {
output.write(storageArrays[i].getSkyLightArray().getHandle());
}
}
short additionalBitMask = 0;
for (int i = 0; i < storageArrays.length; i++) {
if ((chunk.getBitmask() & 1 << i) != 0 && storageArrays[i].hasBlockMSBArray()) {
additionalBitMask |= (short) (1 << i);
output.write(storageArrays[i].getOrCreateBlockMSBArray().getHandle());
}
}
if (chunk.isFullChunk() && chunk.getBiomeData() != null) {
for (int biome : chunk.getBiomeData()) {
output.write(biome);
}
}
return new Pair<>(output.toByteArray(), additionalBitMask);
}
}
@@ -0,0 +1,62 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.api.type.entitydata;
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataListTypeTemplate;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
public class EntityDataListType extends EntityDataListTypeTemplate {
private final Type<EntityData> type;
public EntityDataListType(Type<EntityData> type) {
this.type = type;
}
@Override
public List<EntityData> read(ByteBuf buffer) {
ArrayList<EntityData> entityData = new ArrayList<>();
EntityData data;
do {
data = type.read(buffer);
if (data != null) {
entityData.add(data);
}
} while (data != null);
return entityData;
}
@Override
public void write(ByteBuf buffer, List<EntityData> entityData) {
for (EntityData meta : entityData) {
type.write(buffer, meta);
}
if (entityData.isEmpty()) {
type.write(buffer, new EntityData(0, EntityDataTypes1_7_6_10.BYTE, (byte) 0));
}
buffer.writeByte(127);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,31 +15,31 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.entitydata;
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.types.minecraft.MetaTypeTemplate;
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.type.types.entitydata.EntityDataTypeTemplate;
import io.netty.buffer.ByteBuf;
public class MetadataType extends MetaTypeTemplate {
public class EntityDataType extends EntityDataTypeTemplate {
@Override
public Metadata read(ByteBuf buffer) throws Exception {
public EntityData read(ByteBuf buffer) {
byte item = buffer.readByte();
if (item == 127) {
return null;
} else {
int typeID = (item & 224) >> 5;
MetaType1_7_6_10 type = MetaType1_7_6_10.byId(typeID);
EntityDataTypes1_7_6_10 type = EntityDataTypes1_7_6_10.byId(typeID);
int id = item & 31;
return new Metadata(id, type, type.type().read(buffer));
return new EntityData(id, type, type.type().read(buffer));
}
}
@Override
public void write(ByteBuf buffer, Metadata meta) throws Exception {
int item = (meta.metaType().typeId() << 5 | meta.id() & 31) & 255;
public void write(ByteBuf buffer, EntityData meta) {
int item = (meta.dataType().typeId() << 5 | meta.id() & 31) & 255;
buffer.writeByte(item);
meta.metaType().type().write(buffer, meta.getValue());
meta.dataType().type().write(buffer, meta.getValue());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,37 +15,36 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.item;
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import io.netty.buffer.ByteBuf;
public class ItemArrayType extends Type<Item[]> {
private final boolean compressed;
public ItemArrayType(boolean compressed) {
public ItemArrayType() {
super(Item[].class);
this.compressed = compressed;
}
@Override
public Item[] read(ByteBuf buffer) throws Exception {
int amount = Type.SHORT.readPrimitive(buffer);
public Item[] read(ByteBuf buffer) {
int amount = Types.SHORT.readPrimitive(buffer);
Item[] items = new Item[amount];
for(int i = 0; i < amount; ++i) {
items[i] = (compressed ? Types1_7_6_10.COMPRESSED_NBT_ITEM : Types1_7_6_10.ITEM).read(buffer);
for (int i = 0; i < amount; ++i) {
items[i] = RewindTypes.COMPRESSED_NBT_ITEM.read(buffer);
}
return items;
}
@Override
public void write(ByteBuf buffer, Item[] items) throws Exception {
Type.SHORT.writePrimitive(buffer, (short)items.length);
public void write(ByteBuf buffer, Item[] items) {
Types.SHORT.writePrimitive(buffer, (short) items.length);
for (Item item : items) {
(compressed ? Types1_7_6_10.COMPRESSED_NBT_ITEM : Types1_7_6_10.ITEM).write(buffer, item);
RewindTypes.COMPRESSED_NBT_ITEM.write(buffer, item);
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,25 +15,22 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.api.type.item;
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class ItemType extends Type<Item> {
private final boolean compressed;
public ItemType(boolean compressed) {
public ItemType() {
super(Item.class);
this.compressed = compressed;
}
@Override
public Item read(ByteBuf buffer) throws Exception {
int readerIndex = buffer.readerIndex();
public Item read(ByteBuf buffer) {
short id = buffer.readShort();
if (id < 0) {
return null;
@@ -42,19 +39,19 @@ public class ItemType extends Type<Item> {
item.setIdentifier(id);
item.setAmount(buffer.readByte());
item.setData(buffer.readShort());
item.setTag((compressed ? Types1_7_6_10.COMPRESSED_NBT : Types1_7_6_10.NBT).read(buffer));
item.setTag(RewindTypes.COMPRESSED_NBT.read(buffer));
return item;
}
@Override
public void write(ByteBuf buffer, Item item) throws Exception {
public void write(ByteBuf buffer, Item item) {
if (item == null) {
buffer.writeShort(-1);
} else {
buffer.writeShort(item.identifier());
buffer.writeByte(item.amount());
buffer.writeShort(item.data());
(compressed ? Types1_7_6_10.COMPRESSED_NBT : Types1_7_6_10.NBT).write(buffer, item.tag());
RewindTypes.COMPRESSED_NBT.write(buffer, item.tag());
}
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,12 +15,11 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
package com.viaversion.viarewind.api.type.item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.NBTIO;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.io.NBTIO;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
@@ -29,13 +28,13 @@ import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class CompressedNBTType extends Type<CompoundTag> {
public CompressedNBTType() {
public class NBTType extends Type<CompoundTag> {
public NBTType() {
super(CompoundTag.class);
}
@Override
public CompoundTag read(ByteBuf buffer) throws IOException {
public CompoundTag read(ByteBuf buffer) {
short length = buffer.readShort();
if (length <= 0) {
return null;
@@ -44,12 +43,14 @@ public class CompressedNBTType extends Type<CompoundTag> {
ByteBuf compressed = buffer.readSlice(length);
try (GZIPInputStream gzipStream = new GZIPInputStream(new ByteBufInputStream(compressed))) {
return NBTIO.readTag(gzipStream);
return NBTIO.reader(CompoundTag.class).named().read(gzipStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void write(ByteBuf buffer, CompoundTag nbt) throws Exception {
public void write(ByteBuf buffer, CompoundTag nbt) {
if (nbt == null) {
buffer.writeShort(-1);
return;
@@ -58,7 +59,9 @@ public class CompressedNBTType extends Type<CompoundTag> {
ByteBuf compressedBuf = buffer.alloc().buffer();
try {
try (GZIPOutputStream gzipStream = new GZIPOutputStream(new ByteBufOutputStream(compressedBuf))) {
NBTIO.writeTag(gzipStream, nbt);
NBTIO.writer().named().write(gzipStream, nbt);
} catch (IOException e) {
throw new RuntimeException(e);
}
buffer.writeShort(compressedBuf.readableBytes());
@@ -0,0 +1,15 @@
package com.viaversion.viarewind.api.type.version;
import com.viaversion.viarewind.api.type.entitydata.EntityDataListType;
import com.viaversion.viarewind.api.type.entitydata.EntityDataType;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.type.Type;
import java.util.List;
public class Types1_7_6_10 {
public static final Type<EntityData> ENTITY_DATA = new EntityDataType();
public static final Type<List<EntityData>> ENTITY_DATA_LIST = new EntityDataListType(ENTITY_DATA);
}
@@ -1,120 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_2_5to1_7_6_10;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ServerboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Protocol1_7_2_5To1_7_6_10 extends AbstractProtocol<ClientboundPackets1_7, ClientboundPackets1_7, ServerboundPackets1_7, ServerboundPackets1_7> {
public static final ValueTransformer<String, String> REMOVE_DASHES = new ValueTransformer<String, String>(Type.STRING) {
@Override
public String transform(PacketWrapper packetWrapper, String s) {
return s.replace("-", "");
}
};
public Protocol1_7_2_5To1_7_6_10() {
super(ClientboundPackets1_7.class, ClientboundPackets1_7.class, ServerboundPackets1_7.class, ServerboundPackets1_7.class);
}
@Override
protected void registerPackets() {
//Login Success
this.registerClientbound(State.LOGIN, 0x02, 0x02, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING, REMOVE_DASHES);
map(Type.STRING);
}
});
//Spawn Player
this.registerClientbound(ClientboundPackets1_7.SPAWN_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.STRING, REMOVE_DASHES);
map(Type.STRING);
handler(packetWrapper -> {
int size = packetWrapper.read(Type.VAR_INT);
for (int i = 0; i < size * 3; i++) packetWrapper.read(Type.STRING);
});
map(Type.INT);
map(Type.INT);
map(Type.INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.SHORT);
map(Types1_7_6_10.METADATA_LIST);
}
});
//Teams
this.registerClientbound(ClientboundPackets1_7.TEAMS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
map(Type.BYTE);
handler(packetWrapper -> {
byte mode = packetWrapper.get(Type.BYTE, 0);
if (mode == 0 || mode == 2) {
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.BYTE);
}
if (mode == 0 || mode == 3 || mode == 4) {
List<String> entryList = new ArrayList<>();
int size = packetWrapper.read(Type.SHORT);
for (int i = 0; i < size; i++) {
entryList.add(packetWrapper.read(Type.STRING));
}
entryList = entryList.stream()
.map(it -> it.length() > 16 ? it.substring(0, 16) : it)
.distinct()
.collect(Collectors.toList());
packetWrapper.write(Type.SHORT, (short) entryList.size());
for (String entry : entryList) {
packetWrapper.write(Type.STRING, entry);
}
}
});
}
});
}
@Override
public void init(UserConnection userConnection) {
}
}
@@ -1,99 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_7 implements ClientboundPacketType {
KEEP_ALIVE, // 0x00
JOIN_GAME, // 0x01
CHAT_MESSAGE, // 0x02
TIME_UPDATE, // 0x03
ENTITY_EQUIPMENT, // 0x04
SPAWN_POSITION, // 0x05
UPDATE_HEALTH, // 0x06
RESPAWN, // 0x07
PLAYER_POSITION, // 0x08
HELD_ITEM_CHANGE, // 0x09
USE_BED, // 0x0A
ENTITY_ANIMATION, // 0x0B
SPAWN_PLAYER, // 0x0C
COLLECT_ITEM, // 0x0D
SPAWN_ENTITY, // 0x0E
SPAWN_MOB, // 0x0F
SPAWN_PAINTING, // 0x10
SPAWN_EXPERIENCE_ORB, // 0x11
ENTITY_VELOCITY, // 0x12
DESTROY_ENTITIES, // 0x13
ENTITY_MOVEMENT, // 0x14
ENTITY_POSITION, // 0x15
ENTITY_ROTATION, // 0x16
ENTITY_POSITION_AND_ROTATION, // 0x17
ENTITY_TELEPORT, // 0x18
ENTITY_HEAD_LOOK, // 0x19
ENTITY_STATUS, // 0x1A
ATTACH_ENTITY, // 0x1B
ENTITY_METADATA, // 0x1C
ENTITY_EFFECT, // 0x1D
REMOVE_ENTITY_EFFECT, // 0x1E
SET_EXPERIENCE, // 0x1F
ENTITY_PROPERTIES, // 0x20
CHUNK_DATA, // 0x21
MULTI_BLOCK_CHANGE, // 0x22
BLOCK_CHANGE, // 0x23
BLOCK_ACTION, // 0x24
BLOCK_BREAK_ANIMATION, // 0x25
MAP_BULK_CHUNK, // 0x26
EXPLOSION, // 0x27
EFFECT, // 0x28
NAMED_SOUND, // 0x29
SPAWN_PARTICLE, // 0x2A
GAME_EVENT, // 0x2B
SPAWN_GLOBAL_ENTITY, // 0x2C
OPEN_WINDOW, // 0x2D
CLOSE_WINDOW, // 0x2E
SET_SLOT, // 0x2F
WINDOW_ITEMS, // 0x30
WINDOW_PROPERTY, // 0x31
WINDOW_CONFIRMATION, // 0x32
UPDATE_SIGN, // 0x33
MAP_DATA, // 0x34
BLOCK_ENTITY_DATA, // 0x35
OPEN_SIGN_EDITOR, // 0x36
STATISTICS, // 0x37
PLAYER_INFO, // 0x38
PLAYER_ABILITIES, // 0x39
TAB_COMPLETE, // 0x3A
SCOREBOARD_OBJECTIVE, // 0x3B
UPDATE_SCORE, // 0x3C
DISPLAY_SCOREBOARD, // 0x3D
TEAMS, // 0x3E
PLUGIN_MESSAGE, // 0x3F
DISCONNECT; // 0x40
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -1,129 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets.*;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.CompressionHandlerProvider;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.*;
import com.viaversion.viarewind.utils.Ticker;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_7_6_10To1_8 extends AbstractProtocol<ClientboundPackets1_8, ClientboundPackets1_7,
ServerboundPackets1_8, ServerboundPackets1_7> {
public Protocol1_7_6_10To1_8() {
super(ClientboundPackets1_8.class, ClientboundPackets1_7.class, ServerboundPackets1_8.class, ServerboundPackets1_7.class);
}
@Override
protected void registerPackets() {
EntityPackets.register(this);
InventoryPackets.register(this);
PlayerPackets.register(this);
ScoreboardPackets.register(this);
SpawnPackets.register(this);
WorldPackets.register(this);
this.registerClientbound(ClientboundPackets1_8.KEEP_ALIVE, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT);
}
});
this.cancelClientbound(ClientboundPackets1_8.SET_COMPRESSION); // unused
this.registerServerbound(ServerboundPackets1_7.KEEP_ALIVE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT, Type.VAR_INT);
}
});
//Encryption Request
this.registerClientbound(State.LOGIN, 0x01, 0x01, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); //Server ID
map(Type.BYTE_ARRAY_PRIMITIVE, Type.SHORT_BYTE_ARRAY); // Public key
map(Type.BYTE_ARRAY_PRIMITIVE, Type.SHORT_BYTE_ARRAY); // Verification token
}
});
//Set Compression
this.registerClientbound(State.LOGIN, 0x03, 0x03, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
Via.getManager().getProviders().get(CompressionHandlerProvider.class)
.handleSetCompression(packetWrapper.user(), packetWrapper.read(Type.VAR_INT));
packetWrapper.cancel();
});
}
});
//Encryption Response
this.registerServerbound(State.LOGIN, 0x01, 0x01, new PacketHandlers() {
@Override
public void register() {
map(Type.SHORT_BYTE_ARRAY, Type.BYTE_ARRAY_PRIMITIVE); // Shared secret
map(Type.SHORT_BYTE_ARRAY, Type.BYTE_ARRAY_PRIMITIVE); // Verification token
}
});
}
@Override
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
Via.getManager().getProviders().get(CompressionHandlerProvider.class)
.handleTransform(packetWrapper.user());
super.transform(direction, state, packetWrapper);
}
@Override
public void init(UserConnection userConnection) {
Ticker.init();
userConnection.put(new Windows(userConnection));
userConnection.put(new EntityTracker(userConnection));
userConnection.put(new PlayerPosition(userConnection));
userConnection.put(new GameProfileStorage(userConnection));
userConnection.put(new Scoreboard(userConnection));
userConnection.put(new CompressionSendStorage(userConnection));
userConnection.put(new WorldBorder(userConnection));
userConnection.put(new PlayerAbilities(userConnection));
userConnection.put(new ClientWorld(userConnection));
}
@Override
public void register(ViaProviders providers) {
providers.register(CompressionHandlerProvider.class, new CompressionHandlerProvider());
}
}
@@ -1,155 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.chunks;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items.ReplacementRegistry1_7_6_10to1_8;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.CustomByteType;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import java.io.ByteArrayOutputStream;
import java.util.zip.DeflaterOutputStream;
public class ChunkPacketTransformer {
private static byte[] transformChunkData(byte[] data, int primaryBitMask, boolean skyLight, boolean groundUp) throws Exception {
ByteBuf inputData = Unpooled.wrappedBuffer(data);
ByteBuf finalBuf = ByteBufAllocator.DEFAULT.buffer();
try {
ChunkSection[] sections = new ChunkSection[16];
for (int i = 0; i < 16; i++) {
if ((primaryBitMask & 1 << i) == 0) continue;
sections[i] = Types1_8.CHUNK_SECTION.read(inputData);
}
for (int i = 0; i < 16; i++) {
if ((primaryBitMask & 1 << i) == 0) continue;
ChunkSection section = sections[i];
DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int k = 0; k < palette.size(); k++) {
int blockData = palette.idByIndex(k);
blockData = ReplacementRegistry1_7_6_10to1_8.replace(blockData);
palette.setIdByIndex(k, blockData);
}
}
for (int i = 0; i < 16; i++) {
if ((primaryBitMask & 1 << i) == 0) continue;
ChunkSection section = sections[i];
DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < 4096; j++) {
int raw = palette.idAt(j);
finalBuf.writeByte(raw >> 4);
}
}
for (int i = 0; i < 16; i++) {
if ((primaryBitMask & 1 << i) == 0) continue;
ChunkSection section = sections[i];
DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < 4096; j += 2) {
int meta0 = palette.idAt(j) & 0xF;
int meta1 = palette.idAt(j + 1) & 0xF;
finalBuf.writeByte(meta1 << 4 | meta0);
}
}
int columnCount = Integer.bitCount(primaryBitMask);
// Block light
finalBuf.writeBytes(inputData, 2048 * columnCount);
// Skylight
if (skyLight) {
finalBuf.writeBytes(inputData, 2048 * columnCount);
}
if (groundUp && inputData.isReadable(256)) {
finalBuf.writeBytes(inputData, 256);
}
return Type.REMAINING_BYTES.read(finalBuf);
} finally {
finalBuf.release();
}
}
private static int calcSize(int i, boolean hasSkyLight, boolean hasBiome) {
int blocks = i * 2 * 16 * 16 * 16;
int blockLight = i * 16 * 16 * 16 / 2;
int skyLight = hasSkyLight ? i * 16 * 16 * 16 / 2 : 0;
int biome = hasBiome ? 256 : 0;
return blocks + blockLight + skyLight + biome;
}
public static void transformChunkBulk(PacketWrapper packetWrapper) throws Exception {
boolean skyLightSent = packetWrapper.read(Type.BOOLEAN);
int columnCount = packetWrapper.read(Type.VAR_INT);
int[] chunkX = new int[columnCount];
int[] chunkZ = new int[columnCount];
int[] primaryBitMask = new int[columnCount];
byte[][] data = new byte[columnCount][];
for (int i = 0; i < columnCount; i++) {
chunkX[i] = packetWrapper.read(Type.INT);
chunkZ[i] = packetWrapper.read(Type.INT);
primaryBitMask[i] = packetWrapper.read(Type.UNSIGNED_SHORT);
}
for (int i = 0; i < columnCount; i++) {
int size = calcSize(Integer.bitCount(primaryBitMask[i]), skyLightSent, true);
CustomByteType customByteType = new CustomByteType(size);
data[i] = transformChunkData(packetWrapper.read(customByteType), primaryBitMask[i], skyLightSent, true);
}
ByteArrayOutputStream compressedData = new ByteArrayOutputStream();
// todo compression level config
try (DeflaterOutputStream deflaterStream = new DeflaterOutputStream(compressedData)) {
for (int i = 0; i < columnCount; ++i) {
deflaterStream.write(data[i]);
}
}
packetWrapper.write(Type.SHORT, (short) columnCount);
packetWrapper.write(Type.INT, compressedData.size());
packetWrapper.write(Type.BOOLEAN, skyLightSent);
CustomByteType customByteType = new CustomByteType(compressedData.size());
packetWrapper.write(customByteType, compressedData.toByteArray());
for (int i = 0; i < columnCount; i++) {
packetWrapper.write(Type.INT, chunkX[i]);
packetWrapper.write(Type.INT, chunkZ[i]);
packetWrapper.write(Type.SHORT, (short) primaryBitMask[i]);
packetWrapper.write(Type.SHORT, (short) 0);
}
}
}
@@ -1,121 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.chunks;
import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray;
public class ExtendedBlockStorage {
private final int yBase;
private byte[] blockLSBArray;
private NibbleArray blockMSBArray;
private NibbleArray blockMetadataArray;
private NibbleArray blocklightArray;
private NibbleArray skylightArray;
public ExtendedBlockStorage(int paramInt, boolean paramBoolean) {
this.yBase = paramInt;
this.blockLSBArray = new byte[4096];
this.blockMetadataArray = new NibbleArray(this.blockLSBArray.length);
this.blocklightArray = new NibbleArray(this.blockLSBArray.length);
if (paramBoolean) {
this.skylightArray = new NibbleArray(this.blockLSBArray.length);
}
}
public int getExtBlockMetadata(int paramInt1, int paramInt2, int paramInt3) {
return this.blockMetadataArray.get(paramInt1, paramInt2, paramInt3);
}
public void setExtBlockMetadata(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
this.blockMetadataArray.set(paramInt1, paramInt2, paramInt3, paramInt4);
}
public int getYLocation() {
return this.yBase;
}
public void setExtSkylightValue(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
this.skylightArray.set(paramInt1, paramInt2, paramInt3, paramInt4);
}
public int getExtSkylightValue(int paramInt1, int paramInt2, int paramInt3) {
return this.skylightArray.get(paramInt1, paramInt2, paramInt3);
}
public void setExtBlocklightValue(int paramInt1, int paramInt2, int paramInt3, int paramInt4) {
this.blocklightArray.set(paramInt1, paramInt2, paramInt3, paramInt4);
}
public int getExtBlocklightValue(int paramInt1, int paramInt2, int paramInt3) {
return this.blocklightArray.get(paramInt1, paramInt2, paramInt3);
}
public byte[] getBlockLSBArray() {
return this.blockLSBArray;
}
public boolean isEmpty() {
return this.blockMSBArray==null;
}
public void clearMSBArray() {
this.blockMSBArray = null;
}
public NibbleArray getBlockMSBArray() {
return this.blockMSBArray;
}
public NibbleArray getMetadataArray() {
return this.blockMetadataArray;
}
public NibbleArray getBlocklightArray() {
return this.blocklightArray;
}
public NibbleArray getSkylightArray() {
return this.skylightArray;
}
public void setBlockLSBArray(byte[] paramArrayOfByte) {
this.blockLSBArray = paramArrayOfByte;
}
public void setBlockMSBArray(NibbleArray paramNibbleArray) {
this.blockMSBArray = paramNibbleArray;
}
public void setBlockMetadataArray(NibbleArray paramNibbleArray) {
this.blockMetadataArray = paramNibbleArray;
}
public void setBlocklightArray(NibbleArray paramNibbleArray) {
this.blocklightArray = paramNibbleArray;
}
public void setSkylightArray(NibbleArray paramNibbleArray) {
this.skylightArray = paramNibbleArray;
}
public NibbleArray createBlockMSBArray() {
this.blockMSBArray = new NibbleArray(this.blockLSBArray.length);
return this.blockMSBArray;
}
}
@@ -1,280 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.utils.math.AABB;
import com.viaversion.viarewind.utils.math.Vector3d;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.MetaType1_7_6_10;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.ArrayList;
import java.util.List;
public class ArmorStandReplacement extends EntityReplacement1_7to1_8 {
private final int entityId;
private final List<Metadata> datawatcher = new ArrayList<>();
private int[] entityIds = null;
private double locX, locY, locZ;
private State currentState = null;
private boolean invisible = false;
private boolean nameTagVisible = false;
private String name = null;
private float yaw, pitch;
private float headYaw;
private boolean small = false;
private boolean marker = false;
public int getEntityId() {
return this.entityId;
}
private enum State {
HOLOGRAM, ZOMBIE
}
public ArmorStandReplacement(int entityId, UserConnection user) {
super(user);
this.entityId = entityId;
}
public void setLocation(double x, double y, double z) {
if (x != this.locX || y != this.locY || z != this.locZ) {
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation(false);
}
}
public void relMove(double x, double y, double z) {
if (x == 0.0 && y == 0.0 && z == 0.0) return;
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation(false);
}
public void setYawPitch(float yaw, float pitch) {
if (this.yaw != yaw && this.pitch != pitch || this.headYaw != yaw) {
this.yaw = yaw;
this.headYaw = yaw;
this.pitch = pitch;
updateLocation(false);
}
}
public void setHeadYaw(float yaw) {
if (this.headYaw != yaw) {
this.headYaw = yaw;
updateLocation(false);
}
}
public void updateMetadata(List<Metadata> metadataList) {
for (Metadata metadata : metadataList) {
datawatcher.removeIf(m -> m.id() == metadata.id());
datawatcher.add(metadata);
}
updateState();
}
public void updateState() {
byte flags = 0;
byte armorStandFlags = 0;
for (Metadata metadata : datawatcher) {
if (metadata.id() == 0 && metadata.metaType() == MetaType1_8.Byte) {
flags = ((Number) metadata.getValue()).byteValue();
} else if (metadata.id() == 2 && metadata.metaType() == MetaType1_8.String) {
name = metadata.getValue().toString();
if (name != null && name.equals("")) name = null;
} else if (metadata.id() == 10 && metadata.metaType() == MetaType1_8.Byte) {
armorStandFlags = ((Number) metadata.getValue()).byteValue();
} else if (metadata.id() == 3 && metadata.metaType() == MetaType1_8.Byte) {
nameTagVisible = ((Number) metadata.getValue()).byteValue() != 0;
}
}
invisible = (flags & 0x20) != 0;
small = (armorStandFlags & 0x01) != 0;
marker = (armorStandFlags & 0x10) != 0;
State prevState = currentState;
if (invisible && marker) {
currentState = State.HOLOGRAM;
} else {
currentState = State.ZOMBIE;
}
if (currentState != prevState) {
despawn();
spawn();
} else {
updateMetadata();
updateLocation(false);
}
}
public void updateLocation(boolean remount) {
if (entityIds == null) return;
if (currentState == State.ZOMBIE) {
updateZombieLocation();
} else if (currentState == State.HOLOGRAM) {
updateHologramLocation(remount);
}
}
private void updateZombieLocation() {
sendTeleportWithHead(entityId, locX, locY, locZ, yaw, pitch, headYaw);
}
private void updateHologramLocation(boolean remount) {
if(remount) {
PacketWrapper detach = PacketWrapper.create(ClientboundPackets1_7.ATTACH_ENTITY, null, user);
detach.write(Type.INT, entityIds[1]);
detach.write(Type.INT, -1);
detach.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(detach, Protocol1_7_6_10To1_8.class, true, true);
}
// Don't ask me where this offset is coming from
sendTeleport(entityIds[0], locX, (locY + (marker ? 54.85 : small ? 56 : 57)), locZ, 0, 0); // Skull
if(remount) {
sendTeleport(entityIds[1], locX, locY + 56.75, locZ, 0, 0); // Horse
PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7.ATTACH_ENTITY, null, user);
attach.write(Type.INT, entityIds[1]);
attach.write(Type.INT, entityIds[0]);
attach.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(attach, Protocol1_7_6_10To1_8.class, true, true);
}
}
public void updateMetadata() {
if (entityIds == null) return;
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_METADATA, null, user);
if (currentState == State.ZOMBIE) {
writeZombieMeta(metadataPacket);
} else if (currentState == State.HOLOGRAM) {
writeHologramMeta(metadataPacket);
} else {
return;
}
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10To1_8.class, true, true);
}
private void writeZombieMeta(PacketWrapper metadataPacket) {
metadataPacket.write(Type.INT, entityIds[0]);
List<Metadata> metadataList = new ArrayList<>();
for (Metadata metadata : datawatcher) {
if (metadata.id() < 0 || metadata.id() > 9) continue;
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
}
if (small) metadataList.add(new Metadata(12, MetaType1_8.Byte, (byte) 1));
MetadataRewriter.transform(Entity1_10Types.EntityType.ZOMBIE, metadataList);
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
}
private void writeHologramMeta(PacketWrapper metadataPacket) {
metadataPacket.write(Type.INT, entityIds[1]);
List<Metadata> metadataList = new ArrayList<>();
metadataList.add(new Metadata(12, MetaType1_7_6_10.Int, -1700000));
metadataList.add(new Metadata(10, MetaType1_7_6_10.String, name));
metadataList.add(new Metadata(11, MetaType1_7_6_10.Byte, (byte) 1));
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
}
public void spawn() {
if (entityIds != null) despawn();
if (currentState == State.ZOMBIE) {
spawnZombie();
} else if (currentState == State.HOLOGRAM) {
spawnHologram();
}
updateMetadata();
updateLocation(true);
}
private void spawnZombie() {
sendSpawn(entityId, 54, locX, locY, locZ);
entityIds = new int[] {entityId};
}
private void spawnHologram() {
int[] entityIds = {entityId, additionalEntityId()};
PacketWrapper spawnSkull = PacketWrapper.create(ClientboundPackets1_7.SPAWN_ENTITY, null, user);
spawnSkull.write(Type.VAR_INT, entityIds[0]);
spawnSkull.write(Type.BYTE, (byte) 66);
spawnSkull.write(Type.INT, (int) (locX * 32.0));
spawnSkull.write(Type.INT, (int) (locY * 32.0));
spawnSkull.write(Type.INT, (int) (locZ * 32.0));
spawnSkull.write(Type.BYTE, (byte) 0);
spawnSkull.write(Type.BYTE, (byte) 0);
spawnSkull.write(Type.INT, 0);
PacketUtil.sendPacket(spawnSkull, Protocol1_7_6_10To1_8.class, true, true);
sendSpawn(entityIds[1], 100, locX, locY, locZ); // Horse
this.entityIds = entityIds;
}
private int additionalEntityId() {
return Integer.MAX_VALUE - 16000 - entityId;
}
public AABB getBoundingBox() {
double w = this.small ? 0.25 : 0.5;
double h = this.small ? 0.9875 : 1.975;
Vector3d min = new Vector3d(this.locX - w / 2, this.locY, this.locZ - w / 2);
Vector3d max = new Vector3d(this.locX + w / 2, this.locY + h, this.locZ + w / 2);
return new AABB(min, max);
}
public void despawn() {
if (entityIds == null) return;
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES, null, user);
despawn.write(Type.BYTE, (byte) entityIds.length);
for (int id : entityIds) {
despawn.write(Type.INT, id);
}
entityIds = null;
PacketUtil.sendPacket(despawn, Protocol1_7_6_10To1_8.class, true, true);
}
}
@@ -1,121 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.ArrayList;
import java.util.List;
public class EndermiteReplacement extends EntityReplacement1_7to1_8 {
private final int entityId;
private final List<Metadata> datawatcher = new ArrayList<>();
private double locX, locY, locZ;
private float yaw, pitch;
private float headYaw;
public EndermiteReplacement(int entityId, UserConnection user) {
super(user);
this.entityId = entityId;
spawn();
}
public void setLocation(double x, double y, double z) {
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation();
}
public void relMove(double x, double y, double z) {
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation();
}
public void setYawPitch(float yaw, float pitch) {
if (this.yaw != yaw || this.pitch != pitch) {
this.yaw = yaw;
this.pitch = pitch;
updateLocation();
}
}
public void setHeadYaw(float yaw) {
if (this.headYaw != yaw) {
this.headYaw = yaw;
updateLocation();
}
}
public void updateMetadata(List<Metadata> metadataList) {
for (Metadata metadata : metadataList) {
datawatcher.removeIf(m -> m.id() == metadata.id());
datawatcher.add(metadata);
}
updateMetadata();
}
public void updateLocation() {
sendTeleportWithHead(entityId, locX, locY, locZ, yaw, pitch, headYaw);
}
public void updateMetadata() {
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_METADATA, user);
metadataPacket.write(Type.INT, entityId);
List<Metadata> metadataList = new ArrayList<>();
for (Metadata metadata : datawatcher) {
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
}
MetadataRewriter.transform(Entity1_10Types.EntityType.SQUID, metadataList);
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10To1_8.class);
}
@Override
public void spawn() {
sendSpawn(entityId, 60, locX, locY, locZ);
}
@Override
public void despawn() {
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES, null, user);
despawn.write(Types1_7_6_10.INT_ARRAY, new int[]{entityId});
PacketUtil.sendPacket(despawn, Protocol1_7_6_10To1_8.class, true, true);
}
public int getEntityId() {
return this.entityId;
}
}
@@ -1,80 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.ArrayList;
public abstract class EntityReplacement1_7to1_8 implements EntityReplacement {
protected final UserConnection user;
public EntityReplacement1_7to1_8(UserConnection user) {
this.user = user;
}
protected void sendTeleportWithHead(int entityId, double locX, double locY, double locZ, float yaw, float pitch, float headYaw) {
sendTeleport(entityId, locX, locY, locZ, yaw, pitch);
sendHeadYaw(entityId, headYaw);
}
protected void sendTeleport(int entityId, double locX, double locY, double locZ, float yaw, float pitch) {
PacketWrapper teleport = PacketWrapper.create(ClientboundPackets1_7.ENTITY_TELEPORT, null, user);
teleport.write(Type.INT, entityId);
teleport.write(Type.INT, (int) (locX * 32.0));
teleport.write(Type.INT, (int) (locY * 32.0));
teleport.write(Type.INT, (int) (locZ * 32.0));
teleport.write(Type.BYTE, (byte) ((yaw / 360f) * 256));
teleport.write(Type.BYTE, (byte) ((pitch / 360f) * 256));
PacketUtil.sendPacket(teleport, Protocol1_7_6_10To1_8.class, true, true);
}
protected void sendHeadYaw(int entityId, float headYaw) {
PacketWrapper head = PacketWrapper.create(ClientboundPackets1_7.ENTITY_HEAD_LOOK, null, user);
head.write(Type.INT, entityId);
head.write(Type.BYTE, (byte) ((headYaw / 360f) * 256));
PacketUtil.sendPacket(head, Protocol1_7_6_10To1_8.class, true, true);
}
protected void sendSpawn(int entityId, int type, double locX, double locY, double locZ) {
PacketWrapper spawn = PacketWrapper.create(ClientboundPackets1_7.SPAWN_MOB, null, user);
spawn.write(Type.VAR_INT, entityId);
spawn.write(Type.UNSIGNED_BYTE, (short) type); // type
spawn.write(Type.INT, (int) (locX * 32.0));
spawn.write(Type.INT, (int) (locY * 32.0));
spawn.write(Type.INT, (int) (locZ * 32.0));
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.SHORT, (short) 0);
spawn.write(Type.SHORT, (short) 0);
spawn.write(Type.SHORT, (short) 0);
spawn.write(Types1_7_6_10.METADATA_LIST, new ArrayList<>());
PacketUtil.sendPacket(spawn, Protocol1_7_6_10To1_8.class, true, true);
}
}
@@ -1,122 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.ArrayList;
import java.util.List;
public class GuardianReplacement extends EntityReplacement1_7to1_8 {
private final int entityId;
private final List<Metadata> datawatcher = new ArrayList<>();
private double locX, locY, locZ;
private float yaw, pitch;
private float headYaw;
public GuardianReplacement(int entityId, UserConnection user) {
super(user);
this.entityId = entityId;
spawn();
}
public void setLocation(double x, double y, double z) {
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation();
}
public void relMove(double x, double y, double z) {
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation();
}
public void setYawPitch(float yaw, float pitch) {
if (this.yaw != yaw || this.pitch != pitch) {
this.yaw = yaw;
this.pitch = pitch;
updateLocation();
}
}
public void setHeadYaw(float yaw) {
if (this.headYaw != yaw) {
this.headYaw = yaw;
updateLocation();
}
}
public void updateMetadata(List<Metadata> metadataList) {
for (Metadata metadata : metadataList) {
datawatcher.removeIf(m -> m.id() == metadata.id());
datawatcher.add(metadata);
}
updateMetadata();
}
public void updateLocation() {
sendTeleportWithHead(entityId, locX, locY, locZ, yaw, pitch, headYaw);
}
public void updateMetadata() {
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_METADATA, null, user);
metadataPacket.write(Type.INT, entityId);
List<Metadata> metadataList = new ArrayList<>();
for (Metadata metadata : datawatcher) {
if (metadata.id() == 16 || metadata.id() == 17) continue;
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
}
MetadataRewriter.transform(Entity1_10Types.EntityType.SQUID, metadataList);
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10To1_8.class);
}
@Override
public void spawn() {
sendSpawn(entityId, 94, locX, locY, locZ);
}
@Override
public void despawn() {
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES, null, user);
despawn.write(Types1_7_6_10.INT_ARRAY, new int[]{entityId});
PacketUtil.sendPacket(despawn, Protocol1_7_6_10To1_8.class, true, true);
}
public int getEntityId() {
return this.entityId;
}
}
@@ -1,121 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.ArrayList;
import java.util.List;
public class RabbitReplacement extends EntityReplacement1_7to1_8 {
private final int entityId;
private final List<Metadata> datawatcher = new ArrayList<>();
private double locX, locY, locZ;
private float yaw, pitch;
private float headYaw;
public RabbitReplacement(int entityId, UserConnection user) {
super(user);
this.entityId = entityId;
spawn();
}
public void setLocation(double x, double y, double z) {
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation();
}
public void relMove(double x, double y, double z) {
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation();
}
public void setYawPitch(float yaw, float pitch) {
if (this.yaw != yaw || this.pitch != pitch) {
this.yaw = yaw;
this.pitch = pitch;
updateLocation();
}
}
public void setHeadYaw(float yaw) {
if (this.headYaw != yaw) {
this.headYaw = yaw;
updateLocation();
}
}
public void updateMetadata(List<Metadata> metadataList) {
for (Metadata metadata : metadataList) {
datawatcher.removeIf(m -> m.id() == metadata.id());
datawatcher.add(metadata);
}
updateMetadata();
}
public void updateLocation() {
sendTeleportWithHead(entityId, locX, locY, locZ, yaw, pitch, headYaw);
}
public void updateMetadata() {
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_METADATA, null, user);
metadataPacket.write(Type.INT, entityId);
List<Metadata> metadataList = new ArrayList<>();
for (Metadata metadata : datawatcher) {
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
}
MetadataRewriter.transform(Entity1_10Types.EntityType.CHICKEN, metadataList);
metadataPacket.write(Types1_7_6_10.METADATA_LIST, metadataList);
PacketUtil.sendPacket(metadataPacket, Protocol1_7_6_10To1_8.class, true, true);
}
@Override
public void spawn() {
sendSpawn(entityId, 93, locX, locY, locZ); // Chicken
}
@Override
public void despawn() {
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES, null, user);
despawn.write(Types1_7_6_10.INT_ARRAY, new int[]{entityId});
PacketUtil.sendPacket(despawn, Protocol1_7_6_10To1_8.class, true, true);
}
public int getEntityId() {
return this.entityId;
}
}
@@ -1,136 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viarewind.utils.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.*;
import java.util.ArrayList;
import java.util.List;
public class ItemRewriter {
public static Item toClient(Item item) {
if (item==null) return null;
CompoundTag tag = item.tag();
if (tag==null) item.setTag(tag = new CompoundTag());
CompoundTag viaVersionTag = new CompoundTag();
tag.put("ViaRewind1_7_6_10to1_8", viaVersionTag);
viaVersionTag.put("id", new ShortTag((short) item.identifier()));
viaVersionTag.put("data", new ShortTag(item.data()));
CompoundTag display = tag.get("display");
if (display!=null && display.contains("Name")) {
viaVersionTag.put("displayName", new StringTag((String) display.get("Name").getValue()));
}
if (display!=null && display.contains("Lore")) {
viaVersionTag.put("lore", new ListTag(((ListTag)display.get("Lore")).getValue()));
}
if (tag.contains("ench") || tag.contains("StoredEnchantments")) {
ListTag enchTag = tag.contains("ench") ? tag.get("ench") : tag.get("StoredEnchantments");
List<Tag> lore = new ArrayList<>();
for (Tag ench : new ArrayList<>(enchTag.getValue())) {
short id = ((NumberTag) ((CompoundTag)ench).get("id")).asShort();
short lvl = ((NumberTag) ((CompoundTag)ench).get("lvl")).asShort();
String s;
if (id==8) {
s = "§r§7Depth Strider ";
} else {
continue;
}
enchTag.remove(ench);
s += Enchantments.ENCHANTMENTS.getOrDefault(lvl, "enchantment.level." + lvl);
lore.add(new StringTag(s));
}
if (!lore.isEmpty()) {
if (display==null) {
tag.put("display", display = new CompoundTag());
viaVersionTag.put("noDisplay", new ByteTag());
}
ListTag loreTag = display.get("Lore");
if (loreTag==null) display.put("Lore", loreTag = new ListTag(StringTag.class));
lore.addAll(loreTag.getValue());
loreTag.setValue(lore);
}
}
if (item.identifier()==387 && tag.contains("pages")) {
ListTag pages = tag.get("pages");
ListTag oldPages = new ListTag(StringTag.class);
viaVersionTag.put("pages", oldPages);
for (int i = 0; i<pages.size(); i++) {
StringTag page = pages.get(i);
String value = page.getValue();
oldPages.add(new StringTag(value));
value = ChatUtil.jsonToLegacy(value);
page.setValue(value);
}
}
ReplacementRegistry1_7_6_10to1_8.replace(item);
if (viaVersionTag.size()==2 && (short)viaVersionTag.get("id").getValue()==item.identifier() && (short)viaVersionTag.get("data").getValue()==item.data()) {
item.tag().remove("ViaRewind1_7_6_10to1_8");
if (item.tag().isEmpty()) item.setTag(null);
}
return item;
}
public static Item toServer(Item item) {
if (item==null) return null;
CompoundTag tag = item.tag();
if (tag==null || !item.tag().contains("ViaRewind1_7_6_10to1_8")) return item;
CompoundTag viaVersionTag = tag.remove("ViaRewind1_7_6_10to1_8");
item.setIdentifier((short) viaVersionTag.get("id").getValue());
item.setData((Short) viaVersionTag.get("data").getValue());
if (viaVersionTag.contains("noDisplay")) tag.remove("display");
if (viaVersionTag.contains("displayName")) {
CompoundTag display = tag.get("display");
if (display==null) tag.put("display", display = new CompoundTag());
StringTag name = display.get("Name");
if (name==null) display.put("Name", new StringTag((String) viaVersionTag.get("displayName").getValue()));
else name.setValue((String) viaVersionTag.get("displayName").getValue());
} else if (tag.contains("display")) {
((CompoundTag)tag.get("display")).remove("Name");
}
if (item.identifier()==387) {
ListTag oldPages = viaVersionTag.get("pages");
tag.remove("pages");
tag.put("pages", oldPages);
}
return item;
}
}
@@ -1,123 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items;
import com.viaversion.viarewind.replacement.Replacement;
import com.viaversion.viarewind.storage.BlockState;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viarewind.replacement.ReplacementRegistry;
public class ReplacementRegistry1_7_6_10to1_8 {
private static final ReplacementRegistry registry = new ReplacementRegistry();
static {
registry.registerBlock(176, new Replacement(63));
registry.registerBlock(177, new Replacement(68));
registry.registerBlock(193, new Replacement(64));
registry.registerBlock(194, new Replacement(64));
registry.registerBlock(195, new Replacement(64));
registry.registerBlock(196, new Replacement(64));
registry.registerBlock(197, new Replacement(64));
registry.registerBlock(77, 5, new Replacement(69, 6));
registry.registerBlock(77, 13, new Replacement(69, 14));
registry.registerBlock(77, 0, new Replacement(69, 0));
registry.registerBlock(77, 8, new Replacement(69, 8));
registry.registerBlock(143, 5, new Replacement(69, 6));
registry.registerBlock(143, 13, new Replacement(69, 14));
registry.registerBlock(143, 0, new Replacement(69, 0));
registry.registerBlock(143, 8, new Replacement(69, 8));
registry.registerBlock(178, new Replacement(151));
registry.registerBlock(182, 0, new Replacement(44, 1));
registry.registerBlock(182, 8, new Replacement(44, 9));
registry.registerItem(425, new Replacement(323, "Banner"));
registry.registerItem(409, new Replacement(406, "Prismarine Shard"));
registry.registerItem(410, new Replacement(406, "Prismarine Crystal"));
registry.registerItem(416, new Replacement(280, "Armor Stand"));
registry.registerItem(423, new Replacement(363, "Raw Mutton"));
registry.registerItem(424, new Replacement(364, "Cooked Mutton"));
registry.registerItem(411, new Replacement(365, "Raw Rabbit"));
registry.registerItem(412, new Replacement(366, "Cooked Rabbit"));
registry.registerItem(413, new Replacement(282, "Rabbit Stew"));
registry.registerItem(414, new Replacement(375, "Rabbit's Foot"));
registry.registerItem(415, new Replacement(334, "Rabbit Hide"));
registry.registerItem(373, 8203, new Replacement(373, 0, "Potion of Leaping"));
registry.registerItem(373, 8235, new Replacement(373, 0, "Potion of Leaping"));
registry.registerItem(373, 8267, new Replacement(373, 0, "Potion of Leaping"));
registry.registerItem(373, 16395, new Replacement(373, 0, "Splash Potion of Leaping"));
registry.registerItem(373, 16427, new Replacement(373, 0, "Splash Potion of Leaping"));
registry.registerItem(373, 16459, new Replacement(373, 0, "Splash Potion of Leaping"));
registry.registerItem(383, 30, new Replacement(383, "Spawn ArmorStand"));
registry.registerItem(383, 67, new Replacement(383, "Spawn Endermite"));
registry.registerItem(383, 68, new Replacement(383, "Spawn Guardian"));
registry.registerItem(383, 101, new Replacement(383, "Spawn Rabbit"));
registry.registerItem(19, 1, new Replacement(19, 0, "Wet Sponge"));
registry.registerItem(182, new Replacement(44, 1, "Red Sandstone Slab"));
registry.registerItemBlock(166, new Replacement(20, "Barrier"));
registry.registerItemBlock(167, new Replacement(96, "Iron Trapdoor"));
registry.registerItemBlock(1, 1, new Replacement(1, 0, "Granite"));
registry.registerItemBlock(1, 2, new Replacement(1, 0, "Polished Granite"));
registry.registerItemBlock(1, 3, new Replacement(1, 0, "Diorite"));
registry.registerItemBlock(1, 4, new Replacement(1, 0, "Polished Diorite"));
registry.registerItemBlock(1, 5, new Replacement(1, 0, "Andesite"));
registry.registerItemBlock(1, 6, new Replacement(1, 0, "Polished Andesite"));
registry.registerItemBlock(168, 0, new Replacement(1, 0, "Prismarine"));
registry.registerItemBlock(168, 1, new Replacement(98, 0, "Prismarine Bricks"));
registry.registerItemBlock(168, 2, new Replacement(98, 1, "Dark Prismarine"));
registry.registerItemBlock(169, new Replacement(89, "Sea Lantern"));
registry.registerItemBlock(165, new Replacement(95, 5, "Slime Block"));
registry.registerItemBlock(179, 0, new Replacement(24, "Red Sandstone"));
registry.registerItemBlock(179, 1, new Replacement(24, "Chiseled Red Sandstone"));
registry.registerItemBlock(179, 2, new Replacement(24, "Smooth Sandstone"));
registry.registerItemBlock(181, new Replacement(43, 1, "Double Red Sandstone Slab"));
registry.registerItemBlock(180, new Replacement(128, "Red Sandstone Stairs"));
registry.registerItemBlock(188, new Replacement(85, "Spruce Fence"));
registry.registerItemBlock(189, new Replacement(85, "Birch Fence"));
registry.registerItemBlock(190, new Replacement(85, "Jungle Fence"));
registry.registerItemBlock(191, new Replacement(85, "Dark Oak Fence"));
registry.registerItemBlock(192, new Replacement(85, "Acacia Fence"));
registry.registerItemBlock(183, new Replacement(107, "Spruce Fence Gate"));
registry.registerItemBlock(184, new Replacement(107, "Birch Fence Gate"));
registry.registerItemBlock(185, new Replacement(107, "Jungle Fence Gate"));
registry.registerItemBlock(186, new Replacement(107, "Dark Oak Fence Gate"));
registry.registerItemBlock(187, new Replacement(107, "Acacia Fence Gate"));
registry.registerItemBlock(427, new Replacement(324, "Spruce Door"));
registry.registerItemBlock(428, new Replacement(324, "Birch Door"));
registry.registerItemBlock(429, new Replacement(324, "Jungle Door"));
registry.registerItemBlock(430, new Replacement(324, "Dark Oak Door"));
registry.registerItemBlock(431, new Replacement(324, "Acacia Door"));
registry.registerItemBlock(157, new Replacement(28, "Activator Rail"));
}
public static Item replace(Item item) {
return registry.replace(item);
}
public static int replace(int raw) {
int data = BlockState.extractData(raw);
Replacement replace = registry.replace(BlockState.extractId(raw), data);
return replace != null ? BlockState.stateToRaw(replace.getId(), replace.replaceData(data)) : raw;
}
public static Replacement getReplacement(int id, int data) {
return registry.replace(id, data);
}
}
@@ -1,60 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata;
import com.viaversion.viarewind.protocol.protocol1_8to1_7_6_10.metadata.MetaIndex1_8To1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.Optional;
public class MetaIndex1_7_6_10to1_8 {
private static final HashMap<Pair<Entity1_10Types.EntityType, Integer>, MetaIndex1_8To1_7_6_10> metadataRewrites = new HashMap<>();
static {
for (MetaIndex1_8To1_7_6_10 index : MetaIndex1_8To1_7_6_10.values())
metadataRewrites.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
}
private static Optional<MetaIndex1_8To1_7_6_10> getIndex(Entity1_10Types.EntityType type, int index) {
Pair pair = new Pair<>(type, index);
if (metadataRewrites.containsKey(pair)) {
return Optional.of(metadataRewrites.get(pair));
}
return Optional.empty();
}
public static MetaIndex1_8To1_7_6_10 searchIndex(Entity1_10Types.EntityType type, int index) {
Entity1_10Types.EntityType currentType = type;
do {
Optional<MetaIndex1_8To1_7_6_10> optMeta = getIndex(currentType, index);
if (optMeta.isPresent()) {
return optMeta.get();
}
currentType = currentType.getParent();
} while (currentType != null);
return null;
}
}
@@ -1,110 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
import com.viaversion.viarewind.protocol.protocol1_8to1_7_6_10.metadata.MetaIndex1_8To1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.MetaType1_7_6_10;
import java.util.ArrayList;
import java.util.List;
public class MetadataRewriter {
public static void transform(Entity1_10Types.EntityType type, List<Metadata> list) {
for (Metadata entry : new ArrayList<>(list)) {
MetaIndex1_8To1_7_6_10 metaIndex = MetaIndex1_7_6_10to1_8.searchIndex(type, entry.id());
try {
if (metaIndex == null) throw new Exception("Could not find valid metadata");
if (metaIndex.getOldType() == MetaType1_7_6_10.NonExistent) {
list.remove(entry);
continue;
}
Object value = entry.getValue();
if (!metaIndex.getNewType().type().getOutputClass().isAssignableFrom(value.getClass())) {
list.remove(entry);
continue;
}
entry.setMetaTypeUnsafe(metaIndex.getOldType());
entry.setId(metaIndex.getIndex());
switch (metaIndex.getOldType()) {
case Int:
if (metaIndex.getNewType() == MetaType1_8.Byte) {
entry.setValue(((Byte) value).intValue());
if (metaIndex == MetaIndex1_8To1_7_6_10.ENTITY_AGEABLE_AGE) {
if ((Integer) entry.getValue() < 0) {
entry.setValue(-25000);
}
}
}
if (metaIndex.getNewType() == MetaType1_8.Short) {
entry.setValue(((Short) value).intValue());
}
if (metaIndex.getNewType() == MetaType1_8.Int) {
entry.setValue(value);
}
break;
case Byte:
if (metaIndex.getNewType() == MetaType1_8.Int) {
entry.setValue(((Integer) value).byteValue());
}
if (metaIndex.getNewType() == MetaType1_8.Byte) {
if (metaIndex == MetaIndex1_8To1_7_6_10.ITEM_FRAME_ROTATION) {
value = ((Integer) ((Byte) value / 2)).byteValue();
}
entry.setValue(value);
}
if (metaIndex == MetaIndex1_8To1_7_6_10.HUMAN_SKIN_FLAGS) {
byte flags = (byte) value;
boolean cape = (flags & 0x01) != 0;
flags = (byte) (cape ? 0x00 : 0x02);
entry.setValue(flags);
}
break;
case Slot:
entry.setValue(ItemRewriter.toClient((Item) value));
break;
case Float:
entry.setValue(value);
break;
case Short:
entry.setValue(value);
break;
case String:
entry.setValue(value);
break;
case Position:
entry.setValue(value);
break;
default:
ViaRewind.getPlatform().getLogger().warning("[Out] Unhandled MetaDataType: " + metaIndex.getNewType());
list.remove(entry);
break;
}
} catch (Exception e) {
list.remove(entry);
}
}
}
}
@@ -1,368 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.List;
import java.util.UUID;
public class EntityPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
/* OUTGOING */
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_EQUIPMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.SHORT); //Slot
map(Type.ITEM, Types1_7_6_10.COMPRESSED_NBT_ITEM); //Item
handler(packetWrapper -> {
Item item = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
ItemRewriter.toClient(item);
packetWrapper.set(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0, item);
});
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
int id = packetWrapper.get(Type.INT, 0);
int limit = tracker.getPlayerId() == id ? 3 : 4;
if (packetWrapper.get(Type.SHORT, 0) > limit) packetWrapper.cancel();
});
handler(packetWrapper -> {
short slot = packetWrapper.get(Type.SHORT, 0);
if (packetWrapper.isCancelled()) return;
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
UUID uuid = tracker.getPlayerUUID(packetWrapper.get(Type.INT, 0));
if (uuid == null) return;
Item item = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
tracker.setPlayerEquipment(uuid, item, slot);
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
GameProfileStorage.GameProfile profile = storage.get(uuid);
if (profile != null && profile.gamemode == 3) packetWrapper.cancel();
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.USE_BED, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.UNSIGNED_BYTE, (short) position.y());
packetWrapper.write(Type.INT, position.z());
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.COLLECT_ITEM, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Collected Entity ID
map(Type.VAR_INT, Type.INT); //Collector Entity ID
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_VELOCITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.SHORT); //velX
map(Type.SHORT); //velY
map(Type.SHORT); //velZ
}
});
protocol.registerClientbound(ClientboundPackets1_8.DESTROY_ENTITIES, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int[] entityIds = packetWrapper.read(Type.VAR_INT_ARRAY_PRIMITIVE);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
for (int entityId : entityIds) tracker.removeEntity(entityId);
List<List<Integer>> parts = Lists.partition(Ints.asList(entityIds), Byte.MAX_VALUE);
for (int i = 0; i < parts.size() - 1; i++) {
PacketWrapper destroy = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES,
packetWrapper.user());
destroy.write(Types1_7_6_10.INT_ARRAY, parts.get(i).stream()
.mapToInt(Integer::intValue).toArray());
PacketUtil.sendPacket(destroy, Protocol1_7_6_10To1_8.class);
}
packetWrapper.write(Types1_7_6_10.INT_ARRAY, parts.get(parts.size() - 1).stream()
.mapToInt(Integer::intValue).toArray());
}); //Entity Id Array
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_MOVEMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.BYTE); //x
map(Type.BYTE); //y
map(Type.BYTE); //z
map(Type.BOOLEAN, Type.NOTHING);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int x = packetWrapper.get(Type.BYTE, 0);
int y = packetWrapper.get(Type.BYTE, 1);
int z = packetWrapper.get(Type.BYTE, 2);
replacement.relMove(x / 32.0, y / 32.0, z / 32.0);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.BYTE); //yaw
map(Type.BYTE); //pitch
map(Type.BOOLEAN, Type.NOTHING);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int yaw = packetWrapper.get(Type.BYTE, 0);
int pitch = packetWrapper.get(Type.BYTE, 1);
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_POSITION_AND_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.BYTE); //x
map(Type.BYTE); //y
map(Type.BYTE); //z
map(Type.BYTE); //yaw
map(Type.BYTE); //pitch
map(Type.BOOLEAN, Type.NOTHING);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int x = packetWrapper.get(Type.BYTE, 0);
int y = packetWrapper.get(Type.BYTE, 1);
int z = packetWrapper.get(Type.BYTE, 2);
int yaw = packetWrapper.get(Type.BYTE, 3);
int pitch = packetWrapper.get(Type.BYTE, 4);
replacement.relMove(x / 32.0, y / 32.0, z / 32.0);
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_TELEPORT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.INT); //x
map(Type.INT); //y
map(Type.INT); //z
map(Type.BYTE); //yaw
map(Type.BYTE); //pitch
map(Type.BOOLEAN, Type.NOTHING);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
Entity1_10Types.EntityType type = tracker.getClientEntityTypes().get(entityId);
if (type == Entity1_10Types.EntityType.MINECART_ABSTRACT) {
int y = packetWrapper.get(Type.INT, 2);
y += 12;
packetWrapper.set(Type.INT, 2, y);
}
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int x = packetWrapper.get(Type.INT, 1);
int y = packetWrapper.get(Type.INT, 2);
int z = packetWrapper.get(Type.INT, 3);
int yaw = packetWrapper.get(Type.BYTE, 0);
int pitch = packetWrapper.get(Type.BYTE, 1);
replacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_HEAD_LOOK, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.BYTE); //Head yaw
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int yaw = packetWrapper.get(Type.BYTE, 0);
replacement.setHeadYaw(yaw * 360f / 256);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ATTACH_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.INT);
map(Type.BOOLEAN);
handler(packetWrapper -> {
boolean leash = packetWrapper.get(Type.BOOLEAN, 0);
if (leash) return;
int passenger = packetWrapper.get(Type.INT, 0);
int vehicle = packetWrapper.get(Type.INT, 1);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.setPassenger(vehicle, passenger);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_METADATA, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST); //Metadata
handler(wrapper -> {
List<Metadata> metadataList = wrapper.get(Types1_7_6_10.METADATA_LIST, 0);
int entityId = wrapper.get(Type.INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
if (tracker.getClientEntityTypes().containsKey(entityId)) {
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
wrapper.cancel();
replacement.updateMetadata(metadataList);
} else {
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
if (metadataList.isEmpty()) wrapper.cancel();
}
} else {
tracker.addMetadataToBuffer(entityId, metadataList);
wrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.BYTE); //Effect Id
map(Type.BYTE); //Amplifier
map(Type.VAR_INT, Type.SHORT); //Duration
map(Type.BYTE, Type.NOTHING); //Hide Particles
}
});
protocol.registerClientbound(ClientboundPackets1_8.REMOVE_ENTITY_EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
map(Type.BYTE); //Effect Id
}
});
protocol.registerClientbound(ClientboundPackets1_8.ENTITY_PROPERTIES, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT, Type.INT); //Entity Id
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
if (tracker.getEntityReplacement(entityId) != null) {
packetWrapper.cancel();
return;
}
int amount = packetWrapper.passthrough(Type.INT);
for (int i = 0; i < amount; i++) {
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.DOUBLE);
int modifierlength = packetWrapper.read(Type.VAR_INT);
packetWrapper.write(Type.SHORT, (short) modifierlength);
for (int j = 0; j < modifierlength; j++) {
packetWrapper.passthrough(Type.UUID);
packetWrapper.passthrough(Type.DOUBLE);
packetWrapper.passthrough(Type.BYTE);
}
}
});
}
});
protocol.cancelClientbound(ClientboundPackets1_8.UPDATE_ENTITY_NBT);
}
}
@@ -1,263 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.Windows;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ServerboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.UUID;
public class InventoryPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
/* OUTGOING */
protocol.registerClientbound(ClientboundPackets1_8.OPEN_WINDOW, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
short windowId = packetWrapper.passthrough(Type.UNSIGNED_BYTE);
String windowType = packetWrapper.read(Type.STRING);
short windowtypeId = (short) Windows.getInventoryType(windowType);
packetWrapper.user().get(Windows.class).types.put(windowId, windowtypeId);
packetWrapper.write(Type.UNSIGNED_BYTE, windowtypeId);
JsonElement titleComponent = packetWrapper.read(Type.COMPONENT); //Title
String title = ChatUtil.jsonToLegacy(titleComponent);
title = ChatUtil.removeUnusedColor(title, '8');
if (title.length() > 32) {
title = title.substring(0, 32);
}
packetWrapper.write(Type.STRING, title); //Window title
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
packetWrapper.write(Type.BOOLEAN, true);
if (windowtypeId == 11) packetWrapper.passthrough(Type.INT); //Entity Id
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.CLOSE_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
packetWrapper.user().get(Windows.class).remove(windowsId);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SET_SLOT, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
short windowId = packetWrapper.read(Type.UNSIGNED_BYTE); //Window Id
short windowType = packetWrapper.user().get(Windows.class).get(windowId);
packetWrapper.write(Type.UNSIGNED_BYTE, windowId);
short slot = packetWrapper.read(Type.SHORT);
if (windowType == 4) {
if (slot == 1) {
packetWrapper.cancel();
return;
} else if (slot >= 2) {
slot -= 1;
}
}
packetWrapper.write(Type.SHORT, slot); //Slot
});
map(Type.ITEM, Types1_7_6_10.COMPRESSED_NBT_ITEM); //Item
handler(packetWrapper -> {
Item item = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
ItemRewriter.toClient(item);
packetWrapper.set(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0, item);
});
handler(packetWrapper -> {
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
if (windowId != 0) return;
short slot = packetWrapper.get(Type.SHORT, 0);
if (slot < 5 || slot > 8) return;
Item item = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
UUID myId = packetWrapper.user().getProtocolInfo().getUuid();
tracker.setPlayerEquipment(myId, item, 8 - slot);
if (tracker.getGamemode() == 3) packetWrapper.cancel();
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.WINDOW_ITEMS, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
short windowId = packetWrapper.read(Type.UNSIGNED_BYTE); //Window Id
short windowType = packetWrapper.user().get(Windows.class).get(windowId);
packetWrapper.write(Type.UNSIGNED_BYTE, windowId);
Item[] items = packetWrapper.read(Type.ITEM_ARRAY);
if (windowType == 4) {
Item[] old = items;
items = new Item[old.length - 1];
items[0] = old[0];
System.arraycopy(old, 2, items, 1, old.length - 3);
}
for (int i = 0; i < items.length; i++) items[i] = ItemRewriter.toClient(items[i]);
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM_ARRAY, items); //Items
});
handler(packetWrapper -> {
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
if (windowId != 0) return;
Item[] items = packetWrapper.get(Types1_7_6_10.COMPRESSED_NBT_ITEM_ARRAY, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
UUID myId = packetWrapper.user().getProtocolInfo().getUuid();
for (int i = 5; i < 9; i++) {
tracker.setPlayerEquipment(myId, items[i], 8 - i);
if (tracker.getGamemode() == 3) items[i] = null;
}
if (tracker.getGamemode() == 3) {
GameProfileStorage.GameProfile profile = packetWrapper.user().get(GameProfileStorage.class).get(myId);
if (profile != null) items[5] = profile.getSkull();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.WINDOW_PROPERTY, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.SHORT);
map(Type.SHORT);
handler(packetWrapper -> {
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
Windows windows = packetWrapper.user().get(Windows.class);
short windowType = windows.get(windowId);
short property = packetWrapper.get(Type.SHORT, 0);
short value = packetWrapper.get(Type.SHORT, 1);
if (windowType == -1) return;
if (windowType == 2) { //Furnace
Windows.Furnace furnace = windows.furnace.computeIfAbsent(windowId, x -> new Windows.Furnace());
if (property == 0 || property == 1) {
if (property == 0) {
furnace.setFuelLeft(value);
} else {
furnace.setMaxFuel(value);
}
if (furnace.getMaxFuel() == 0) {
packetWrapper.cancel();
return;
}
value = (short) (200 * furnace.getFuelLeft() / furnace.getMaxFuel());
packetWrapper.set(Type.SHORT, 0, (short) 1);
packetWrapper.set(Type.SHORT, 1, value);
} else if (property == 2 || property == 3) {
if (property == 2) {
furnace.setProgress(value);
} else {
furnace.setMaxProgress(value);
}
if (furnace.getMaxProgress() == 0) {
packetWrapper.cancel();
return;
}
value = (short) (200 * furnace.getProgress() / furnace.getMaxProgress());
packetWrapper.set(Type.SHORT, 0, (short) 0);
packetWrapper.set(Type.SHORT, 1, value);
}
} else if (windowType == 4) { //Enchanting Table
if (property > 2) {
packetWrapper.cancel();
}
} else if (windowType == 8) {
windows.levelCost = value;
windows.anvilId = windowId;
}
});
}
});
/* INCOMING */
protocol.registerServerbound(ServerboundPackets1_7.CLOSE_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
packetWrapper.user().get(Windows.class).remove(windowsId);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.CLICK_WINDOW, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
short windowId = packetWrapper.read(Type.BYTE); //Window Id
packetWrapper.write(Type.UNSIGNED_BYTE, windowId);
short windowType = packetWrapper.user().get(Windows.class).get(windowId);
short slot = packetWrapper.read(Type.SHORT);
if (windowType == 4) {
if (slot > 0) {
slot += 1;
}
}
packetWrapper.write(Type.SHORT, slot);
});
map(Type.BYTE); //Button
map(Type.SHORT); //Action Number
map(Type.BYTE); //Mode
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM);
handler(packetWrapper -> {
Item item = packetWrapper.get(Type.ITEM, 0);
ItemRewriter.toServer(item);
packetWrapper.set(Type.ITEM, 0, item);
});
}
});
//Creative Inventory Action
protocol.registerServerbound(ServerboundPackets1_7.CREATIVE_INVENTORY_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.SHORT); //Slot
map(Types1_7_6_10.COMPRESSED_NBT_ITEM, Type.ITEM); //Item
handler(packetWrapper -> {
Item item = packetWrapper.get(Type.ITEM, 0);
ItemRewriter.toServer(item);
packetWrapper.set(Type.ITEM, 0, item);
});
}
});
}
}
@@ -1,940 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.ArmorStandReplacement;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider.TitleRenderProvider;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.*;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.utils.math.AABB;
import com.viaversion.viarewind.utils.math.Ray3d;
import com.viaversion.viarewind.utils.math.RayTracing;
import com.viaversion.viarewind.utils.math.Vector3d;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ServerboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items.ItemRewriter;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.gson.JsonParser;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;
public class PlayerPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
/* OUTGOING */
protocol.registerClientbound(ClientboundPackets1_8.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); //Entiy Id
map(Type.UNSIGNED_BYTE); //Gamemode
map(Type.BYTE); //Dimension
map(Type.UNSIGNED_BYTE); //Difficulty
map(Type.UNSIGNED_BYTE); //Max players
map(Type.STRING); //Level Type
map(Type.BOOLEAN, Type.NOTHING);//Reduced Debug Info
handler(packetWrapper -> {
if (!ViaRewind.getConfig().isReplaceAdventureMode()) return;
if (packetWrapper.get(Type.UNSIGNED_BYTE, 0) == 2) {
packetWrapper.set(Type.UNSIGNED_BYTE, 0, (short) 0);
}
});
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.setGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 0));
tracker.setPlayerId(packetWrapper.get(Type.INT, 0));
tracker.getClientEntityTypes().put(tracker.getPlayerId(), Entity1_10Types.EntityType.ENTITY_HUMAN);
tracker.setDimension(packetWrapper.get(Type.BYTE, 0));
tracker.addPlayer(tracker.getPlayerId(), packetWrapper.user().getProtocolInfo().getUuid());
});
handler(packetWrapper -> {
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
world.setEnvironment(packetWrapper.get(Type.BYTE, 0));
});
handler(wrapper -> {
// Reset on Velocity server change
wrapper.user().put(new Scoreboard(wrapper.user()));
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.CHAT_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.COMPONENT); //Chat Message
handler(packetWrapper -> {
int position = packetWrapper.read(Type.BYTE);
if (position == 2) packetWrapper.cancel();
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_POSITION, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.INT, position.y());
packetWrapper.write(Type.INT, position.z());
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_HEALTH, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT); //Health
map(Type.VAR_INT, Type.SHORT); //Food
map(Type.FLOAT); //Food Saturation
}
});
protocol.registerClientbound(ClientboundPackets1_8.RESPAWN, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.UNSIGNED_BYTE);
map(Type.UNSIGNED_BYTE);
map(Type.STRING);
handler(packetWrapper -> {
if (!ViaRewind.getConfig().isReplaceAdventureMode()) return;
if (packetWrapper.get(Type.UNSIGNED_BYTE, 1) == 2) {
packetWrapper.set(Type.UNSIGNED_BYTE, 1, (short) 0);
}
});
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.setGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 1));
if (tracker.getDimension() != packetWrapper.get(Type.INT, 0)) {
tracker.setDimension(packetWrapper.get(Type.INT, 0));
tracker.clearEntities();
tracker.getClientEntityTypes().put(tracker.getPlayerId(), Entity1_10Types.EntityType.ENTITY_HUMAN);
}
});
handler(packetWrapper -> {
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
world.setEnvironment(packetWrapper.get(Type.INT, 0));
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE); //x
map(Type.DOUBLE); //y
map(Type.DOUBLE); //z
map(Type.FLOAT); //yaw
map(Type.FLOAT); //pitch
handler(packetWrapper -> {
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
playerPosition.setPositionPacketReceived(true);
int flags = packetWrapper.read(Type.BYTE);
if ((flags & 0x01) == 0x01) {
double x = packetWrapper.get(Type.DOUBLE, 0);
x += playerPosition.getPosX();
packetWrapper.set(Type.DOUBLE, 0, x);
}
double y = packetWrapper.get(Type.DOUBLE, 1);
if ((flags & 0x02) == 0x02) {
y += playerPosition.getPosY();
}
playerPosition.setReceivedPosY(y);
y += 1.62F;
packetWrapper.set(Type.DOUBLE, 1, y);
if ((flags & 0x04) == 0x04) {
double z = packetWrapper.get(Type.DOUBLE, 2);
z += playerPosition.getPosZ();
packetWrapper.set(Type.DOUBLE, 2, z);
}
if ((flags & 0x08) == 0x08) {
float yaw = packetWrapper.get(Type.FLOAT, 0);
yaw += playerPosition.getYaw();
packetWrapper.set(Type.FLOAT, 0, yaw);
}
if ((flags & 0x10) == 0x10) {
float pitch = packetWrapper.get(Type.FLOAT, 1);
pitch += playerPosition.getPitch();
packetWrapper.set(Type.FLOAT, 1, pitch);
}
});
handler(packetWrapper -> {
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
packetWrapper.write(Type.BOOLEAN, playerPosition.isOnGround());
});
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
if (tracker.getSpectating() != tracker.getPlayerId()) {
packetWrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SET_EXPERIENCE, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT); //Experience bar
map(Type.VAR_INT, Type.SHORT); //Level
map(Type.VAR_INT, Type.SHORT); //Total Experience
}
});
protocol.registerClientbound(ClientboundPackets1_8.GAME_EVENT, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.FLOAT);
handler(packetWrapper -> {
int mode = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
if (mode != 3) return;
int gamemode = packetWrapper.get(Type.FLOAT, 0).intValue();
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
if (gamemode == 3 || tracker.getGamemode() == 3) {
UUID myId = packetWrapper.user().getProtocolInfo().getUuid();
Item[] equipment = new Item[4];
if (gamemode == 3) {
GameProfileStorage.GameProfile profile = packetWrapper.user().get(GameProfileStorage.class).get(myId);
equipment[3] = profile.getSkull();
} else {
for (int i = 0; i < equipment.length; i++) {
equipment[i] = tracker.getPlayerEquipment(myId, i);
}
}
for (int i = 0; i < equipment.length; i++) {
PacketWrapper setSlot = PacketWrapper.create(ClientboundPackets1_7.SET_SLOT, packetWrapper.user());
setSlot.write(Type.BYTE, (byte) 0);
setSlot.write(Type.SHORT, (short) (8 - i));
setSlot.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, equipment[i]);
PacketUtil.sendPacket(setSlot, Protocol1_7_6_10To1_8.class);
}
}
});
handler(packetWrapper -> {
int mode = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
if (mode == 3) {
int gamemode = packetWrapper.get(Type.FLOAT, 0).intValue();
if (gamemode == 2 && ViaRewind.getConfig().isReplaceAdventureMode()) {
gamemode = 0;
packetWrapper.set(Type.FLOAT, 0, 0.0f);
}
packetWrapper.user().get(EntityTracker.class).setGamemode(gamemode);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.OPEN_SIGN_EDITOR, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.INT, position.y());
packetWrapper.write(Type.INT, position.z());
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_INFO, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
int action = packetWrapper.read(Type.VAR_INT);
int count = packetWrapper.read(Type.VAR_INT);
GameProfileStorage gameProfileStorage = packetWrapper.user().get(GameProfileStorage.class);
for (int i = 0; i < count; i++) {
UUID uuid = packetWrapper.read(Type.UUID);
if (action == 0) {
String name = packetWrapper.read(Type.STRING);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null) gameProfile = gameProfileStorage.put(uuid, name);
int propertyCount = packetWrapper.read(Type.VAR_INT);
while (propertyCount-- > 0) {
String propertyName = packetWrapper.read(Type.STRING);
String propertyValue = packetWrapper.read(Type.STRING);
String propertySignature = packetWrapper.read(Type.OPTIONAL_STRING);
gameProfile.properties.add(new GameProfileStorage.Property(propertyName, propertyValue, propertySignature));
}
int gamemode = packetWrapper.read(Type.VAR_INT);
int ping = packetWrapper.read(Type.VAR_INT);
gameProfile.ping = ping;
gameProfile.gamemode = gamemode;
JsonElement displayName = packetWrapper.read(Type.OPTIONAL_COMPONENT);
if (displayName != null) {
gameProfile.setDisplayName(ChatUtil.jsonToLegacy(displayName));
}
PacketWrapper packet = PacketWrapper.create(0x38, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, true);
packet.write(Type.SHORT, (short) ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
} else if (action == 1) {
int gamemode = packetWrapper.read(Type.VAR_INT);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null || gameProfile.gamemode == gamemode) continue;
if (gamemode == 3 || gameProfile.gamemode == 3) {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
int entityId = tracker.getPlayerEntityId(uuid);
boolean isOwnPlayer = entityId == tracker.getPlayerId();
if (entityId != -1) {
// Weirdly, PlayerEntity has only 4 slots instead of 5
Item[] equipment = new Item[isOwnPlayer ? 4 : 5];
if (gamemode == 3) {
equipment[isOwnPlayer ? 3 : 4] = gameProfile.getSkull();
} else {
for (int j = 0; j < equipment.length; j++) {
equipment[j] = tracker.getPlayerEquipment(uuid, j);
}
}
for (short slot = 0; slot < equipment.length; slot++) {
PacketWrapper equipmentPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_EQUIPMENT, packetWrapper.user());
equipmentPacket.write(Type.INT, entityId);
equipmentPacket.write(Type.SHORT, slot);
equipmentPacket.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, equipment[slot]);
PacketUtil.sendPacket(equipmentPacket, Protocol1_7_6_10To1_8.class);
}
}
}
gameProfile.gamemode = gamemode;
} else if (action == 2) {
int ping = packetWrapper.read(Type.VAR_INT);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null) continue;
PacketWrapper packet = PacketWrapper.create(0x38, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, false);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
gameProfile.ping = ping;
packet = PacketWrapper.create(0x38, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, true);
packet.write(Type.SHORT, (short) ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
} else if (action == 3) {
JsonElement displayNameComponent = packetWrapper.read(Type.OPTIONAL_COMPONENT);
String displayName = displayNameComponent != null ? ChatUtil.jsonToLegacy(displayNameComponent) : null;
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null || gameProfile.displayName == null && displayName == null) continue;
PacketWrapper packet = PacketWrapper.create(0x38, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, false);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
if (gameProfile.displayName == null && displayName != null || gameProfile.displayName != null && displayName == null || !gameProfile.displayName.equals(displayName)) {
gameProfile.setDisplayName(displayName);
}
packet = PacketWrapper.create(0x38, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, true);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
} else if (action == 4) {
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.remove(uuid);
if (gameProfile == null) continue;
PacketWrapper packet = PacketWrapper.create(0x38, null, packetWrapper.user());
packet.write(Type.STRING, gameProfile.getDisplayName());
packet.write(Type.BOOLEAN, false);
packet.write(Type.SHORT, (short) gameProfile.ping);
PacketUtil.sendPacket(packet, Protocol1_7_6_10To1_8.class);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLAYER_ABILITIES, new PacketHandlers() {
@Override
public void register() {
map(Type.BYTE);
map(Type.FLOAT);
map(Type.FLOAT);
handler(packetWrapper -> {
byte flags = packetWrapper.get(Type.BYTE, 0);
float flySpeed = packetWrapper.get(Type.FLOAT, 0);
float walkSpeed = packetWrapper.get(Type.FLOAT, 1);
PlayerAbilities abilities = packetWrapper.user().get(PlayerAbilities.class);
abilities.setInvincible((flags & 8) == 8);
abilities.setAllowFly((flags & 4) == 4);
abilities.setFlying((flags & 2) == 2);
abilities.setCreative((flags & 1) == 1);
abilities.setFlySpeed(flySpeed);
abilities.setWalkSpeed(walkSpeed);
if (abilities.isSprinting() && abilities.isFlying()) {
packetWrapper.set(Type.FLOAT, 0, abilities.getFlySpeed() * 2.0f);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String channel = packetWrapper.get(Type.STRING, 0);
if (channel.equalsIgnoreCase("MC|TrList")) {
packetWrapper.passthrough(Type.INT); //Window Id
int size;
if (packetWrapper.isReadable(Type.BYTE, 0)) {
size = packetWrapper.passthrough(Type.BYTE);
} else {
size = packetWrapper.passthrough(Type.UNSIGNED_BYTE);
}
for (int i = 0; i < size; i++) {
Item item = ItemRewriter.toClient(packetWrapper.read(Type.ITEM));
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 1
item = ItemRewriter.toClient(packetWrapper.read(Type.ITEM));
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 3
boolean has3Items = packetWrapper.passthrough(Type.BOOLEAN);
if (has3Items) {
item = ItemRewriter.toClient(packetWrapper.read(Type.ITEM));
packetWrapper.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, item); //Buy Item 2
}
packetWrapper.passthrough(Type.BOOLEAN); //Unavailable
packetWrapper.read(Type.INT); //Uses
packetWrapper.read(Type.INT); //Max Uses
}
} else if (channel.equalsIgnoreCase("MC|Brand")) {
packetWrapper.write(Type.REMAINING_BYTES, packetWrapper.read(Type.STRING).getBytes(StandardCharsets.UTF_8));
}
packetWrapper.cancel();
packetWrapper.setId(-1);
ByteBuf newPacketBuf = Unpooled.buffer();
packetWrapper.writeToBuffer(newPacketBuf);
PacketWrapper newWrapper = PacketWrapper.create(0x3F, newPacketBuf, packetWrapper.user());
newWrapper.passthrough(Type.STRING);
if (newPacketBuf.readableBytes() <= Short.MAX_VALUE) {
newWrapper.write(Type.SHORT, (short) newPacketBuf.readableBytes());
newWrapper.send(Protocol1_7_6_10To1_8.class);
}
});
}
});
//Camera
protocol.registerClientbound(ClientboundPackets1_8.CAMERA, null, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
int entityId = packetWrapper.read(Type.VAR_INT);
int spectating = tracker.getSpectating();
if (spectating != entityId) {
tracker.setSpectating(entityId);
}
});
}
});
//Title
protocol.registerClientbound(ClientboundPackets1_8.TITLE, null, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
TitleRenderProvider titleRenderProvider = Via.getManager().getProviders().get(TitleRenderProvider.class);
if (titleRenderProvider == null) return;
int action = packetWrapper.read(Type.VAR_INT);
UUID uuid = packetWrapper.user().getProtocolInfo().getUuid();
switch (action) {
case 0:
titleRenderProvider.setTitle(uuid, packetWrapper.read(Type.STRING));
break;
case 1:
titleRenderProvider.setSubTitle(uuid, packetWrapper.read(Type.STRING));
break;
case 2:
titleRenderProvider.setTimings(uuid, packetWrapper.read(Type.INT), packetWrapper.read(Type.INT), packetWrapper.read(Type.INT));
break;
case 3:
titleRenderProvider.clear(uuid);
break;
case 4:
titleRenderProvider.reset(uuid);
break;
}
});
}
});
//Player List Header And Footer
protocol.cancelClientbound(ClientboundPackets1_8.TAB_LIST);
//Resource Pack Send
protocol.registerClientbound(ClientboundPackets1_8.RESOURCE_PACK, ClientboundPackets1_7.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
create(Type.STRING, "MC|RPack");
handler(packetWrapper -> {
ByteBuf buf = ByteBufAllocator.DEFAULT.buffer();
try {
// Url
Type.STRING.write(buf, packetWrapper.read(Type.STRING));
packetWrapper.write(Type.SHORT_BYTE_ARRAY, Type.REMAINING_BYTES.read(buf));
} finally {
buf.release();
}
});
map(Type.STRING, Type.NOTHING); // Hash
}
});
/* INCOMING */
protocol.registerServerbound(ServerboundPackets1_7.CHAT_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String msg = packetWrapper.get(Type.STRING, 0);
int gamemode = packetWrapper.user().get(EntityTracker.class).getGamemode();
if (gamemode == 3 && msg.toLowerCase().startsWith("/stp ")) {
String username = msg.split(" ")[1];
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
GameProfileStorage.GameProfile profile = storage.get(username, true);
if (profile != null && profile.uuid != null) {
packetWrapper.cancel();
PacketWrapper teleportPacket = PacketWrapper.create(0x18, null, packetWrapper.user());
teleportPacket.write(Type.UUID, profile.uuid);
PacketUtil.sendToServer(teleportPacket, Protocol1_7_6_10To1_8.class, true, true);
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.INTERACT_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.INT, Type.VAR_INT);
map(Type.BYTE, Type.VAR_INT);
handler(packetWrapper -> {
int mode = packetWrapper.get(Type.VAR_INT, 1);
if (mode != 0) return;
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (!(replacement instanceof ArmorStandReplacement)) return;
ArmorStandReplacement armorStand = (ArmorStandReplacement) replacement;
AABB boundingBox = armorStand.getBoundingBox();
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
Vector3d pos = new Vector3d(playerPosition.getPosX(), playerPosition.getPosY() + 1.8, playerPosition.getPosZ());
double yaw = Math.toRadians(playerPosition.getYaw());
double pitch = Math.toRadians(playerPosition.getPitch());
Vector3d dir = new Vector3d(-Math.cos(pitch) * Math.sin(yaw), -Math.sin(pitch), Math.cos(pitch) * Math.cos(yaw));
Ray3d ray = new Ray3d(pos, dir);
Vector3d intersection = RayTracing.trace(ray, boundingBox, 5.0);
if (intersection == null) return;
intersection.substract(boundingBox.getMin());
mode = 2;
packetWrapper.set(Type.VAR_INT, 1, mode);
packetWrapper.write(Type.FLOAT, (float) intersection.getX());
packetWrapper.write(Type.FLOAT, (float) intersection.getY());
packetWrapper.write(Type.FLOAT, (float) intersection.getZ());
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_MOVEMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.BOOLEAN);
handler(packetWrapper -> {
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE); //X
map(Type.DOUBLE); //Y
map(Type.DOUBLE, Type.NOTHING);
map(Type.DOUBLE); //Z
map(Type.BOOLEAN); //OnGround
handler(packetWrapper -> {
double x = packetWrapper.get(Type.DOUBLE, 0);
double feetY = packetWrapper.get(Type.DOUBLE, 1);
double z = packetWrapper.get(Type.DOUBLE, 2);
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
playerPosition.setPos(x, feetY, z);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.BOOLEAN);
handler(packetWrapper -> {
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
playerPosition.setYaw(packetWrapper.get(Type.FLOAT, 0));
playerPosition.setPitch(packetWrapper.get(Type.FLOAT, 1));
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_POSITION_AND_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE); //X
map(Type.DOUBLE); //Y
map(Type.DOUBLE, Type.NOTHING);
map(Type.DOUBLE); //Z
map(Type.FLOAT); //Yaw
map(Type.FLOAT); //Pitch
map(Type.BOOLEAN); //OnGround
handler(packetWrapper -> {
double x = packetWrapper.get(Type.DOUBLE, 0);
double feetY = packetWrapper.get(Type.DOUBLE, 1);
double z = packetWrapper.get(Type.DOUBLE, 2);
float yaw = packetWrapper.get(Type.FLOAT, 0);
float pitch = packetWrapper.get(Type.FLOAT, 1);
PlayerPosition playerPosition = packetWrapper.user().get(PlayerPosition.class);
playerPosition.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
playerPosition.setPos(x, feetY, z);
playerPosition.setYaw(yaw);
playerPosition.setPitch(pitch);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_DIGGING, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); //Status
handler(packetWrapper -> {
int x = packetWrapper.read(Type.INT);
int y = packetWrapper.read(Type.UNSIGNED_BYTE);
int z = packetWrapper.read(Type.INT);
packetWrapper.write(Type.POSITION, new Position(x, y, z));
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_BLOCK_PLACEMENT, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int x = packetWrapper.read(Type.INT);
int y = packetWrapper.read(Type.UNSIGNED_BYTE);
int z = packetWrapper.read(Type.INT);
packetWrapper.write(Type.POSITION, new Position(x, y, z));
packetWrapper.passthrough(Type.BYTE); //Direction
Item item = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM);
item = ItemRewriter.toServer(item);
packetWrapper.write(Type.ITEM, item);
for (int i = 0; i < 3; i++) {
packetWrapper.passthrough(Type.BYTE);
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.ANIMATION, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int entityId = packetWrapper.read(Type.INT);
int animation = packetWrapper.read(Type.BYTE); //Animation
if (animation == 1) return;
packetWrapper.cancel();
//1.7 vanilla client is not sending this packet with animation!=1
switch (animation) {
case 104:
animation = 0;
break;
case 105:
animation = 1;
break;
case 3:
animation = 2;
break;
default:
return;
}
PacketWrapper entityAction = PacketWrapper.create(0x0B, null, packetWrapper.user());
entityAction.write(Type.VAR_INT, entityId);
entityAction.write(Type.VAR_INT, animation);
entityAction.write(Type.VAR_INT, 0);
PacketUtil.sendPacket(entityAction, Protocol1_7_6_10To1_8.class, true, true);
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.ENTITY_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.INT, Type.VAR_INT); //Entity Id
handler(packetWrapper -> packetWrapper.write(Type.VAR_INT, packetWrapper.read(Type.BYTE) - 1)); //Action Id
map(Type.INT, Type.VAR_INT); //Action Paramter
handler(packetWrapper -> {
int action = packetWrapper.get(Type.VAR_INT, 1);
if (action == 3 || action == 4) {
PlayerAbilities abilities = packetWrapper.user().get(PlayerAbilities.class);
abilities.setSprinting(action == 3);
PacketWrapper abilitiesPacket = PacketWrapper.create(0x39, null, packetWrapper.user());
abilitiesPacket.write(Type.BYTE, abilities.getFlags());
abilitiesPacket.write(Type.FLOAT, abilities.isSprinting() ? abilities.getFlySpeed() * 2.0f : abilities.getFlySpeed());
abilitiesPacket.write(Type.FLOAT, abilities.getWalkSpeed());
PacketUtil.sendPacket(abilitiesPacket, Protocol1_7_6_10To1_8.class);
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.STEER_VEHICLE, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT); //Sideways
map(Type.FLOAT); //Forwards
handler(packetWrapper -> {
boolean jump = packetWrapper.read(Type.BOOLEAN);
boolean unmount = packetWrapper.read(Type.BOOLEAN);
short flags = 0;
if (jump) flags += 0x01;
if (unmount) flags += 0x02;
packetWrapper.write(Type.UNSIGNED_BYTE, flags);
if (unmount) {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
if (tracker.getSpectating() != tracker.getPlayerId()) {
PacketWrapper sneakPacket = PacketWrapper.create(0x0B, null, packetWrapper.user());
sneakPacket.write(Type.VAR_INT, tracker.getPlayerId());
sneakPacket.write(Type.VAR_INT, 0); //Start sneaking
sneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketWrapper unsneakPacket = PacketWrapper.create(0x0B, null, packetWrapper.user());
unsneakPacket.write(Type.VAR_INT, tracker.getPlayerId());
unsneakPacket.write(Type.VAR_INT, 1); //Stop sneaking
unsneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketUtil.sendToServer(sneakPacket, Protocol1_7_6_10To1_8.class);
}
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.UPDATE_SIGN, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int x = packetWrapper.read(Type.INT);
int y = packetWrapper.read(Type.SHORT);
int z = packetWrapper.read(Type.INT);
packetWrapper.write(Type.POSITION, new Position(x, y, z));
for (int i = 0; i < 4; i++) {
String line = packetWrapper.read(Type.STRING);
line = ChatUtil.legacyToJson(line);
packetWrapper.write(Type.COMPONENT, JsonParser.parseString(line));
}
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLAYER_ABILITIES, new PacketHandlers() {
@Override
public void register() {
map(Type.BYTE);
map(Type.FLOAT);
map(Type.FLOAT);
handler(packetWrapper -> {
PlayerAbilities abilities = packetWrapper.user().get(PlayerAbilities.class);
if (abilities.isAllowFly()) {
byte flags = packetWrapper.get(Type.BYTE, 0);
abilities.setFlying((flags & 2) == 2);
}
packetWrapper.set(Type.FLOAT, 0, abilities.getFlySpeed());
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.TAB_COMPLETE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
create(Type.OPTIONAL_POSITION, null);
handler(packetWrapper -> {
String msg = packetWrapper.get(Type.STRING, 0);
if (msg.toLowerCase().startsWith("/stp ")) {
packetWrapper.cancel();
String[] args = msg.split(" ");
if (args.length <= 2) {
String prefix = args.length == 1 ? "" : args[1];
GameProfileStorage storage = packetWrapper.user().get(GameProfileStorage.class);
List<GameProfileStorage.GameProfile> profiles = storage.getAllWithPrefix(prefix, true);
PacketWrapper tabComplete = PacketWrapper.create(0x3A, null, packetWrapper.user());
tabComplete.write(Type.VAR_INT, profiles.size());
for (GameProfileStorage.GameProfile profile : profiles) {
tabComplete.write(Type.STRING, profile.name);
}
PacketUtil.sendPacket(tabComplete, Protocol1_7_6_10To1_8.class);
}
}
});
}
});
//Client Settings
protocol.registerServerbound(ServerboundPackets1_7.CLIENT_SETTINGS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
map(Type.BYTE);
map(Type.BYTE);
map(Type.BOOLEAN);
map(Type.BYTE, Type.NOTHING);
handler(packetWrapper -> {
boolean cape = packetWrapper.read(Type.BOOLEAN);
packetWrapper.write(Type.UNSIGNED_BYTE, (short) (cape ? 127 : 126));
});
}
});
protocol.registerServerbound(ServerboundPackets1_7.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
map(Type.SHORT, Type.NOTHING); // Length
handler(packetWrapper -> {
String channel = packetWrapper.get(Type.STRING, 0);
switch (channel) {
case "MC|TrSel": {
packetWrapper.passthrough(Type.INT);
packetWrapper.read(Type.REMAINING_BYTES); // unused data ???
break;
}
case "MC|ItemName": {
byte[] data = packetWrapper.read(Type.REMAINING_BYTES);
String name = new String(data, StandardCharsets.UTF_8);
packetWrapper.write(Type.STRING, name);
Windows windows = packetWrapper.user().get(Windows.class);
PacketWrapper updateCost = PacketWrapper.create(0x31, null, packetWrapper.user());
updateCost.write(Type.UNSIGNED_BYTE, windows.anvilId);
updateCost.write(Type.SHORT, (short) 0);
updateCost.write(Type.SHORT, windows.levelCost);
PacketUtil.sendPacket(updateCost, Protocol1_7_6_10To1_8.class, true, true);
break;
}
case "MC|BEdit":
case "MC|BSign": {
Item book = packetWrapper.read(Types1_7_6_10.COMPRESSED_NBT_ITEM);
CompoundTag tag = book.tag();
if (tag != null && tag.contains("pages")) {
ListTag pages = tag.get("pages");
for (int i = 0; i < pages.size(); i++) {
StringTag page = pages.get(i);
String value = page.getValue();
value = ChatUtil.legacyToJson(value);
page.setValue(value);
}
}
packetWrapper.write(Type.ITEM, book);
break;
}
case "MC|Brand": {
packetWrapper.write(Type.STRING, new String(packetWrapper.read(Type.REMAINING_BYTES), StandardCharsets.UTF_8));
break;
}
}
});
}
});
}
}
@@ -1,262 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.Scoreboard;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.util.ChatColorUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class ScoreboardPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
/* OUTGOING */
//Scoreboard Objective
protocol.registerClientbound(ClientboundPackets1_8.SCOREBOARD_OBJECTIVE, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
String name = packetWrapper.passthrough(Type.STRING);
if (name.length() > 16) {
packetWrapper.set(Type.STRING, 0, name = name.substring(0, 16));
}
byte mode = packetWrapper.read(Type.BYTE);
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
if (mode == 0) {
if (scoreboard.objectiveExists(name)) {
packetWrapper.cancel();
return;
}
scoreboard.addObjective(name);
} else if (mode == 1) {
if (!scoreboard.objectiveExists(name)) {
packetWrapper.cancel();
return;
}
if (scoreboard.getColorIndependentSidebar() != null) {
String username = packetWrapper.user().getProtocolInfo().getUsername();
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
if (color.isPresent()) {
String sidebar = scoreboard.getColorDependentSidebar().get(color.get());
if (name.equals(sidebar)) {
PacketWrapper sidebarPacket = PacketWrapper.create(0x3D, null, packetWrapper.user());
sidebarPacket.write(Type.BYTE, (byte) 1);
sidebarPacket.write(Type.STRING, scoreboard.getColorIndependentSidebar());
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10To1_8.class);
}
}
}
scoreboard.removeObjective(name);
} else if (mode == 2) {
if (!scoreboard.objectiveExists(name)) {
packetWrapper.cancel();
return;
}
}
if (mode == 0 || mode == 2) {
String displayName = packetWrapper.passthrough(Type.STRING);
if (displayName.length() > 32) {
packetWrapper.set(Type.STRING, 1, displayName.substring(0, 32));
}
packetWrapper.read(Type.STRING);
} else {
packetWrapper.write(Type.STRING, "");
}
packetWrapper.write(Type.BYTE, mode);
});
}
});
//Update Score
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SCORE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // Name
map(Type.VAR_INT, Type.BYTE); // Mode
handler(packetWrapper -> {
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
String name = packetWrapper.get(Type.STRING, 0);
byte mode = packetWrapper.get(Type.BYTE, 0);
if (mode == 1) {
name = scoreboard.removeTeamForScore(name);
} else {
name = scoreboard.sendTeamForScore(name);
}
if (name.length() > 16) {
name = ChatColorUtil.stripColor(name);
if (name.length() > 16) {
name = name.substring(0, 16);
}
}
packetWrapper.set(Type.STRING, 0, name);
String objective = packetWrapper.read(Type.STRING);
if (objective.length() > 16) {
objective = objective.substring(0, 16);
}
if (mode != 1) {
int score = packetWrapper.read(Type.VAR_INT);
packetWrapper.write(Type.STRING, objective);
packetWrapper.write(Type.INT, score);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.DISPLAY_SCOREBOARD, new PacketHandlers() {
@Override
public void register() {
map(Type.BYTE); // Position
map(Type.STRING); // Score name
handler(packetWrapper -> {
byte position = packetWrapper.get(Type.BYTE, 0);
String name = packetWrapper.get(Type.STRING, 0);
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
if (position > 2) { // team specific sidebar
byte receiverTeamColor = (byte) (position - 3);
scoreboard.getColorDependentSidebar().put(receiverTeamColor, name);
String username = packetWrapper.user().getProtocolInfo().getUsername();
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
if (color.isPresent() && color.get() == receiverTeamColor) {
position = 1;
} else {
position = -1;
}
} else if (position == 1) { // team independent sidebar
scoreboard.setColorIndependentSidebar(name);
String username = packetWrapper.user().getProtocolInfo().getUsername();
Optional<Byte> color = scoreboard.getPlayerTeamColor(username);
if (color.isPresent() && scoreboard.getColorDependentSidebar().containsKey(color.get())) {
position = -1;
}
}
if (position == -1) {
packetWrapper.cancel();
return;
}
packetWrapper.set(Type.BYTE, 0, position);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.TEAMS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String team = packetWrapper.get(Type.STRING, 0);
if (team == null) {
packetWrapper.cancel();
return;
}
byte mode = packetWrapper.passthrough(Type.BYTE);
Scoreboard scoreboard = packetWrapper.user().get(Scoreboard.class);
if (mode != 0 && !scoreboard.teamExists(team)) {
packetWrapper.cancel();
return;
} else if (mode == 0 && scoreboard.teamExists(team)) {
scoreboard.removeTeam(team);
PacketWrapper remove = PacketWrapper.create(0x3E, null, packetWrapper.user());
remove.write(Type.STRING, team);
remove.write(Type.BYTE, (byte) 1);
PacketUtil.sendPacket(remove, Protocol1_7_6_10To1_8.class, true, true);
}
if (mode == 0) {
scoreboard.addTeam(team);
} else if (mode == 1) {
scoreboard.removeTeam(team);
}
if (mode == 0 || mode == 2) {
packetWrapper.passthrough(Type.STRING); // Display name
packetWrapper.passthrough(Type.STRING); // prefix
packetWrapper.passthrough(Type.STRING); // suffix
packetWrapper.passthrough(Type.BYTE); // friendly fire
packetWrapper.read(Type.STRING); // name tag visibility
byte color = packetWrapper.read(Type.BYTE);
if (mode == 2 && scoreboard.getTeamColor(team).get() != color) {
String username = packetWrapper.user().getProtocolInfo().getUsername();
String sidebar = scoreboard.getColorDependentSidebar().get(color);
PacketWrapper sidebarPacket = packetWrapper.create(0x3D);
sidebarPacket.write(Type.BYTE, (byte) 1);
sidebarPacket.write(Type.STRING, sidebar == null ? "" : sidebar);
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10To1_8.class);
}
scoreboard.setTeamColor(team, color);
}
if (mode == 0 || mode == 3 || mode == 4) {
byte color = scoreboard.getTeamColor(team).get();
String[] entries = packetWrapper.read(Type.STRING_ARRAY);
List<String> entryList = new ArrayList<>();
for (int i = 0; i < entries.length; i++) {
String entry = entries[i];
String username = packetWrapper.user().getProtocolInfo().getUsername();
if (mode == 4) {
if (!scoreboard.isPlayerInTeam(entry, team)) continue;
scoreboard.removePlayerFromTeam(entry, team);
if (entry.equals(username)) {
PacketWrapper sidebarPacket = packetWrapper.create(0x3D);
sidebarPacket.write(Type.BYTE, (byte) 1);
sidebarPacket.write(Type.STRING, scoreboard.getColorIndependentSidebar() == null ? "" : scoreboard.getColorIndependentSidebar());
PacketUtil.sendPacket(sidebarPacket, Protocol1_7_6_10To1_8.class);
}
} else {
scoreboard.addPlayerToTeam(entry, team);
if (entry.equals(username) && scoreboard.getColorDependentSidebar().containsKey(color)) {
PacketWrapper displayObjective = packetWrapper.create(0x3D);
displayObjective.write(Type.BYTE, (byte) 1);
displayObjective.write(Type.STRING, scoreboard.getColorDependentSidebar().get(color));
PacketUtil.sendPacket(displayObjective, Protocol1_7_6_10To1_8.class);
}
}
entryList.add(entry);
}
packetWrapper.write(Type.SHORT, (short) entryList.size());
for (String entry : entryList) {
packetWrapper.write(Type.STRING, entry);
}
}
});
}
});
}
}
@@ -1,321 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.ArmorStandReplacement;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.EndermiteReplacement;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.GuardianReplacement;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.entityreplacements.RabbitReplacement;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.EntityTracker;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.GameProfileStorage;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viarewind.replacement.Replacement;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items.ReplacementRegistry1_7_6_10to1_8;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
import java.util.List;
import java.util.UUID;
public class SpawnPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
/* OUTGOING */
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
handler(packetWrapper -> {
UUID uuid = packetWrapper.read(Type.UUID);
packetWrapper.write(Type.STRING, uuid.toString());
GameProfileStorage gameProfileStorage = packetWrapper.user().get(GameProfileStorage.class);
GameProfileStorage.GameProfile gameProfile = gameProfileStorage.get(uuid);
if (gameProfile == null) {
packetWrapper.write(Type.STRING, "");
packetWrapper.write(Type.VAR_INT, 0);
} else {
packetWrapper.write(Type.STRING, gameProfile.name.length() > 16 ? gameProfile.name.substring(0, 16) : gameProfile.name);
packetWrapper.write(Type.VAR_INT, gameProfile.properties.size());
for (GameProfileStorage.Property property : gameProfile.properties) {
packetWrapper.write(Type.STRING, property.name);
packetWrapper.write(Type.STRING, property.value);
packetWrapper.write(Type.STRING, property.signature == null ? "" : property.signature);
}
}
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
if (gameProfile != null && gameProfile.gamemode == 3) {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
for (short i = 0; i < 5; i++) {
PacketWrapper equipmentPacket = PacketWrapper.create(ClientboundPackets1_7.ENTITY_EQUIPMENT, packetWrapper.user());
equipmentPacket.write(Type.INT, entityId);
equipmentPacket.write(Type.SHORT, i);
equipmentPacket.write(Types1_7_6_10.COMPRESSED_NBT_ITEM, i == 4 ? gameProfile.getSkull() :null);
PacketUtil.sendPacket(equipmentPacket, Protocol1_7_6_10To1_8.class);
}
}
tracker.addPlayer(packetWrapper.get(Type.VAR_INT, 0), uuid);
});
map(Type.INT);
map(Type.INT);
map(Type.INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.SHORT);
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST);
handler(packetWrapper -> {
List<Metadata> metadata = packetWrapper.get(Types1_7_6_10.METADATA_LIST, 0); //Metadata
MetadataRewriter.transform(Entity1_10Types.EntityType.PLAYER, metadata);
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PLAYER);
tracker.sendMetadataBuffer(entityId);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.INT);
map(Type.INT);
map(Type.INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.INT);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
byte typeId = packetWrapper.get(Type.BYTE, 0);
int x = packetWrapper.get(Type.INT, 0);
int y = packetWrapper.get(Type.INT, 1);
int z = packetWrapper.get(Type.INT, 2);
byte pitch = packetWrapper.get(Type.BYTE, 1);
byte yaw = packetWrapper.get(Type.BYTE, 2);
if (typeId == 71) {
switch (yaw) {
case -128:
z += 32;
yaw = 0;
break;
case -64:
x -= 32;
yaw = -64;
break;
case 0:
z -= 32;
yaw = -128;
break;
case 64:
x += 32;
yaw = 64;
break;
}
} else if (typeId == 78) {
packetWrapper.cancel();
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
ArmorStandReplacement armorStand = new ArmorStandReplacement(entityId, packetWrapper.user());
armorStand.setLocation(x / 32.0, y / 32.0, z / 32.0);
armorStand.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
armorStand.setHeadYaw(yaw * 360f / 256);
tracker.addEntityReplacement(armorStand);
} else if (typeId == 10) {
y += 12;
}
packetWrapper.set(Type.BYTE, 0, typeId);
packetWrapper.set(Type.INT, 0, x);
packetWrapper.set(Type.INT, 1, y);
packetWrapper.set(Type.INT, 2, z);
packetWrapper.set(Type.BYTE, 1, pitch);
packetWrapper.set(Type.BYTE, 2, yaw);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
Entity1_10Types.EntityType type = Entity1_10Types.getTypeFromId(typeId, true);
tracker.getClientEntityTypes().put(entityId, type);
tracker.sendMetadataBuffer(entityId);
int data = packetWrapper.get(Type.INT, 3);
if (type != null && type.isOrHasParent(Entity1_10Types.EntityType.FALLING_BLOCK)) {
int blockId = data & 0xFFF;
int blockData = data >> 12 & 0xF;
Replacement replace = ReplacementRegistry1_7_6_10to1_8.getReplacement(blockId, blockData);
if (replace != null) {
blockId = replace.getId();
blockData = replace.replaceData(blockData);
}
packetWrapper.set(Type.INT, 3, data = (blockId | blockData << 16));
}
if (data > 0) {
packetWrapper.passthrough(Type.SHORT);
packetWrapper.passthrough(Type.SHORT);
packetWrapper.passthrough(Type.SHORT);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_MOB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.UNSIGNED_BYTE);
map(Type.INT);
map(Type.INT);
map(Type.INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.BYTE);
map(Type.SHORT);
map(Type.SHORT);
map(Type.SHORT);
map(Types1_8.METADATA_LIST, Types1_7_6_10.METADATA_LIST);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
int x = packetWrapper.get(Type.INT, 0);
int y = packetWrapper.get(Type.INT, 1);
int z = packetWrapper.get(Type.INT, 2);
byte pitch = packetWrapper.get(Type.BYTE, 1);
byte yaw = packetWrapper.get(Type.BYTE, 0);
byte headYaw = packetWrapper.get(Type.BYTE, 2);
if (typeId == 30 || typeId == 68 || typeId == 67 || typeId == 101) {
packetWrapper.cancel();
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = null;
if (typeId == 30) {
replacement = new ArmorStandReplacement(entityId, packetWrapper.user());
} else if (typeId == 68) {
replacement = new GuardianReplacement(entityId, packetWrapper.user());
} else if (typeId == 67) {
replacement = new EndermiteReplacement(entityId, packetWrapper.user());
} else if (typeId == 101){
replacement = new RabbitReplacement(entityId, packetWrapper.user());
}
replacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
replacement.setHeadYaw(headYaw * 360f / 256);
tracker.addEntityReplacement(replacement);
} else if (typeId == 255 || typeId == -1) {
packetWrapper.cancel();
}
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.getTypeFromId(typeId, false));
tracker.sendMetadataBuffer(entityId);
});
handler(wrapper -> {
List<Metadata> metadataList = wrapper.get(Types1_7_6_10.METADATA_LIST, 0);
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
if (tracker.getEntityReplacement(entityId) != null) {
tracker.getEntityReplacement(entityId).updateMetadata(metadataList);
} else if (tracker.getClientEntityTypes().containsKey(entityId)) {
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
} else {
wrapper.cancel();
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PAINTING, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); //Entity Id
map(Type.STRING); //Title
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.INT, position.y());
packetWrapper.write(Type.INT, position.z());
});
map(Type.UNSIGNED_BYTE, Type.INT); //Rotation
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PAINTING);
tracker.sendMetadataBuffer(entityId);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_EXPERIENCE_ORB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.INT);
map(Type.INT);
map(Type.INT);
map(Type.SHORT);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.EXPERIENCE_ORB);
tracker.sendMetadataBuffer(entityId);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_GLOBAL_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.INT);
map(Type.INT);
map(Type.INT);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.LIGHTNING);
tracker.sendMetadataBuffer(entityId);
});
}
});
}
}
@@ -1,345 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.packets;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.chunks.ChunkPacketTransformer;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.WorldBorder;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.items.ReplacementRegistry1_7_6_10to1_8;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.CustomByteType;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.types.Chunk1_8Type;
import com.viaversion.viaversion.util.ChatColorUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Chunk1_7_10Type;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Particle;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.Types1_7_6_10;
public class WorldPackets {
public static void register(Protocol1_7_6_10To1_8 protocol) {
/* OUTGOING */
protocol.registerClientbound(ClientboundPackets1_8.CHUNK_DATA, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
Chunk chunk = packetWrapper.read(new Chunk1_8Type(world));
packetWrapper.write(new Chunk1_7_10Type(world), chunk);
for (ChunkSection section : chunk.getSections()) {
if (section == null) continue;
DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int i = 0; i < palette.size(); i++) {
int block = palette.idByIndex(i);
int replacedBlock = ReplacementRegistry1_7_6_10to1_8.replace(block);
palette.setIdByIndex(i, replacedBlock);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.MULTI_BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.INT);
handler(packetWrapper -> {
final BlockChangeRecord[] records = packetWrapper.read(Type.BLOCK_CHANGE_RECORD_ARRAY);
packetWrapper.write(Type.SHORT, (short) records.length);
packetWrapper.write(Type.INT, records.length * 4);
for (BlockChangeRecord record : records) {
short data = (short) (record.getSectionX() << 12 | record.getSectionZ() << 8 | record.getY());
packetWrapper.write(Type.SHORT, data);
int replacedBlock = ReplacementRegistry1_7_6_10to1_8.replace(record.getBlockId());
packetWrapper.write(Type.SHORT, (short) replacedBlock);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.UNSIGNED_BYTE, (short) position.y());
packetWrapper.write(Type.INT, position.z());
});
handler(packetWrapper -> {
int data = packetWrapper.read(Type.VAR_INT);
data = ReplacementRegistry1_7_6_10to1_8.replace(data);
packetWrapper.write(Type.VAR_INT, data >> 4);
packetWrapper.write(Type.UNSIGNED_BYTE, (short) (data & 0xF));
}); //Block Data
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ACTION, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.SHORT, (short) position.y());
packetWrapper.write(Type.INT, position.z());
});
map(Type.UNSIGNED_BYTE);
map(Type.UNSIGNED_BYTE);
map(Type.VAR_INT);
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_BREAK_ANIMATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); //Entity Id
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.INT, position.y());
packetWrapper.write(Type.INT, position.z());
});
map(Type.BYTE); //Progress
}
});
protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, new PacketHandlers() {
@Override
public void register() {
handler(ChunkPacketTransformer::transformChunkBulk);
}
});
//Effect
protocol.registerClientbound(ClientboundPackets1_8.EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.BYTE, (byte) position.y());
packetWrapper.write(Type.INT, position.z());
});
map(Type.INT);
map(Type.BOOLEAN);
}
});
protocol.registerClientbound(ClientboundPackets1_8.SPAWN_PARTICLE, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int particleId = packetWrapper.read(Type.INT);
Particle particle = Particle.find(particleId);
if (particle == null) particle = Particle.CRIT;
packetWrapper.write(Type.STRING, particle.name);
packetWrapper.read(Type.BOOLEAN);
});
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.INT);
handler(packetWrapper -> {
String name = packetWrapper.get(Type.STRING, 0);
Particle particle = Particle.find(name);
if (particle == Particle.ICON_CRACK || particle == Particle.BLOCK_CRACK || particle == Particle.BLOCK_DUST) {
int id = packetWrapper.read(Type.VAR_INT);
int data = particle == Particle.ICON_CRACK ? packetWrapper.read(Type.VAR_INT) : 0;
if (id >= 256 && id <= 422 || id >= 2256 && id <= 2267) { //item
particle = Particle.ICON_CRACK;
} else if (id >= 0 && id <= 164 || id >= 170 && id <= 175) {
if (particle == Particle.ICON_CRACK) particle = Particle.BLOCK_CRACK;
} else {
packetWrapper.cancel();
return;
}
name = particle.name + "_" + id + "_" + data;
}
packetWrapper.set(Type.STRING, 0, name);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.UPDATE_SIGN, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.SHORT, (short) position.y());
packetWrapper.write(Type.INT, position.z());
});
handler(packetWrapper -> {
for (int i = 0; i < 4; i++) {
String line = packetWrapper.read(Type.STRING);
line = ChatUtil.jsonToLegacy(line);
line = ChatUtil.removeUnusedColor(line, '0');
if (line.length() > 15) {
line = ChatColorUtil.stripColor(line);
if (line.length() > 15) line = line.substring(0, 15);
}
packetWrapper.write(Type.STRING, line);
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.MAP_DATA, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
int id = packetWrapper.read(Type.VAR_INT);
byte scale = packetWrapper.read(Type.BYTE);
int count = packetWrapper.read(Type.VAR_INT);
byte[] icons = new byte[count * 4];
for (int i = 0; i < count; i++) {
int j = packetWrapper.read(Type.BYTE);
icons[i * 4] = (byte) (j >> 4 & 0xF);
icons[i * 4 + 1] = packetWrapper.read(Type.BYTE);
icons[i * 4 + 2] = packetWrapper.read(Type.BYTE);
icons[i * 4 + 3] = (byte) (j & 0xF);
}
short columns = packetWrapper.read(Type.UNSIGNED_BYTE);
if (columns > 0) {
short rows = packetWrapper.read(Type.UNSIGNED_BYTE);
short x = packetWrapper.read(Type.UNSIGNED_BYTE);
short z = packetWrapper.read(Type.UNSIGNED_BYTE);
byte[] data = packetWrapper.read(Type.BYTE_ARRAY_PRIMITIVE);
for (int column = 0; column < columns; column++) {
byte[] columnData = new byte[rows + 3];
columnData[0] = 0;
columnData[1] = (byte) (x + column);
columnData[2] = (byte) z;
for (int i = 0; i < rows; i++) {
columnData[i + 3] = data[column + i * columns];
}
PacketWrapper columnUpdate = PacketWrapper.create(0x34, null, packetWrapper.user());
columnUpdate.write(Type.VAR_INT, id);
columnUpdate.write(Type.SHORT, (short) columnData.length);
columnUpdate.write(new CustomByteType(columnData.length), columnData);
PacketUtil.sendPacket(columnUpdate, Protocol1_7_6_10To1_8.class, true, true);
}
}
if (count > 0) {
byte[] iconData = new byte[count * 3 + 1];
iconData[0] = 1;
for (int i = 0; i < count; i++) {
iconData[i * 3 + 1] = (byte) (icons[i * 4] << 4 | icons[i * 4 + 3] & 0xF);
iconData[i * 3 + 2] = icons[i * 4 + 1];
iconData[i * 3 + 3] = icons[i * 4 + 2];
}
PacketWrapper iconUpdate = PacketWrapper.create(0x34, null, packetWrapper.user());
iconUpdate.write(Type.VAR_INT, id);
iconUpdate.write(Type.SHORT, (short) iconData.length);
CustomByteType customByteType = new CustomByteType(iconData.length);
iconUpdate.write(customByteType, iconData);
PacketUtil.sendPacket(iconUpdate, Protocol1_7_6_10To1_8.class, true, true);
}
PacketWrapper scaleUpdate = PacketWrapper.create(0x34, null, packetWrapper.user());
scaleUpdate.write(Type.VAR_INT, id);
scaleUpdate.write(Type.SHORT, (short) 2);
scaleUpdate.write(new CustomByteType(2), new byte[]{2, scale});
PacketUtil.sendPacket(scaleUpdate, Protocol1_7_6_10To1_8.class, true, true);
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.BLOCK_ENTITY_DATA, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
Position position = packetWrapper.read(Type.POSITION);
packetWrapper.write(Type.INT, position.x());
packetWrapper.write(Type.SHORT, (short) position.y());
packetWrapper.write(Type.INT, position.z());
});
map(Type.UNSIGNED_BYTE); //Action
map(Type.NBT, Types1_7_6_10.COMPRESSED_NBT);
}
});
protocol.cancelClientbound(ClientboundPackets1_8.SERVER_DIFFICULTY);
protocol.cancelClientbound(ClientboundPackets1_8.COMBAT_EVENT);
protocol.registerClientbound(ClientboundPackets1_8.WORLD_BORDER, null, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int action = packetWrapper.read(Type.VAR_INT);
WorldBorder worldBorder = packetWrapper.user().get(WorldBorder.class);
if (action == 0) {
worldBorder.setSize(packetWrapper.read(Type.DOUBLE));
} else if (action == 1) {
worldBorder.lerpSize(packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.VAR_LONG));
} else if (action == 2) {
worldBorder.setCenter(packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE));
} else if (action == 3) {
worldBorder.init(
packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE),
packetWrapper.read(Type.DOUBLE), packetWrapper.read(Type.DOUBLE),
packetWrapper.read(Type.VAR_LONG),
packetWrapper.read(Type.VAR_INT),
packetWrapper.read(Type.VAR_INT), packetWrapper.read(Type.VAR_INT)
);
} else if (action == 4) {
worldBorder.setWarningTime(packetWrapper.read(Type.VAR_INT));
} else if (action == 5) {
worldBorder.setWarningBlocks(packetWrapper.read(Type.VAR_INT));
}
packetWrapper.cancel();
});
}
});
}
}
@@ -1,176 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.provider;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage.CompressionSendStorage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.platform.providers.Provider;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viarewind.netty.EmptyChannelHandler;
import com.viaversion.viarewind.netty.ForwardMessageToByteEncoder;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.MessageToByteEncoder;
import io.netty.handler.codec.MessageToMessageDecoder;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
public class CompressionHandlerProvider implements Provider {
public void handleSetCompression(UserConnection user, int threshold) {
ChannelPipeline pipeline = user.getChannel().pipeline();
if (user.isClientSide()) {
pipeline.addBefore(Via.getManager().getInjector().getEncoderName(), "compress", getEncoder(threshold));
pipeline.addBefore(Via.getManager().getInjector().getDecoderName(), "decompress", getDecoder(threshold));
} else {
CompressionSendStorage storage = user.get(CompressionSendStorage.class);
storage.setRemoveCompression(true);
}
}
public void handleTransform(UserConnection user) {
CompressionSendStorage storage = user.get(CompressionSendStorage.class);
if (storage.isRemoveCompression()) {
ChannelPipeline pipeline = user.getChannel().pipeline();
String compressor = null;
String decompressor = null;
if (pipeline.get("compress") != null) {
compressor = "compress";
decompressor = "decompress";
} else if (pipeline.get("compression-encoder") != null) { // Velocity
compressor = "compression-encoder";
decompressor = "compression-decoder";
}
if (compressor != null) { // We can neutralize the effect of compressor to the client
pipeline.replace(decompressor, decompressor, new EmptyChannelHandler());
pipeline.replace(compressor, compressor, new ForwardMessageToByteEncoder());
} else {
throw new IllegalStateException("Couldn't remove compression for 1.7!");
}
storage.setRemoveCompression(false);
}
}
protected ChannelHandler getEncoder(int threshold) {
return new Compressor(threshold);
}
protected ChannelHandler getDecoder(int threshold) {
return new Decompressor(threshold);
}
private static class Decompressor extends MessageToMessageDecoder<ByteBuf> {
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
private final Inflater inflater;
private final int threshold;
public Decompressor(int var1) {
this.threshold = var1;
this.inflater = new Inflater();
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
if (!in.isReadable()) return;
int outLength = Type.VAR_INT.readPrimitive(in);
if (outLength == 0) {
out.add(in.readBytes(in.readableBytes()));
return;
}
if (outLength < this.threshold) {
throw new DecoderException("Badly compressed packet - size of " + outLength + " is below server threshold of " + this.threshold);
} else if (outLength > 2097152) {
throw new DecoderException("Badly compressed packet - size of " + outLength + " is larger than protocol maximum of " + 2097152);
}
ByteBuf temp = in;
if (!in.hasArray()) {
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
} else {
in.retain();
}
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer(outLength, outLength);
try {
this.inflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
output.writerIndex(output.writerIndex() + this.inflater.inflate(
output.array(), output.arrayOffset(), outLength));
out.add(output.retain());
} finally {
output.release();
temp.release();
this.inflater.reset();
}
}
}
private static class Compressor extends MessageToByteEncoder<ByteBuf> {
// https://github.com/Gerrygames/ClientViaVersion/blob/master/src/main/java/de/gerrygames/the5zig/clientviaversion/netty/CompressionEncoder.java
private final Deflater deflater;
private final int threshold;
public Compressor(int var1) {
this.threshold = var1;
this.deflater = new Deflater();
}
protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) throws Exception {
int frameLength = in.readableBytes();
if (frameLength < this.threshold) {
out.writeByte(0); // varint
out.writeBytes(in);
return;
}
Type.VAR_INT.writePrimitive(out, frameLength);
ByteBuf temp = in;
if (!in.hasArray()) {
temp = ByteBufAllocator.DEFAULT.heapBuffer().writeBytes(in);
} else {
in.retain();
}
ByteBuf output = ByteBufAllocator.DEFAULT.heapBuffer();
try {
this.deflater.setInput(temp.array(), temp.arrayOffset() + temp.readerIndex(), temp.readableBytes());
deflater.finish();
while (!deflater.finished()) {
output.ensureWritable(4096);
output.writerIndex(output.writerIndex() + this.deflater.deflate(output.array(),
output.arrayOffset() + output.writerIndex(), output.writableBytes()));
}
out.writeBytes(output);
} finally {
output.release();
temp.release();
this.deflater.reset();
}
}
}
}
@@ -1,258 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.metadata.MetadataRewriter;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.ClientEntityIdChangeListener;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class EntityTracker extends StoredObject implements ClientEntityIdChangeListener {
private final Map<Integer, Entity1_10Types.EntityType> clientEntityTypes = new ConcurrentHashMap();
private final Map<Integer, List<Metadata>> metadataBuffer = new ConcurrentHashMap();
private final Map<Integer, Integer> vehicles = new ConcurrentHashMap<>();
private final Map<Integer, EntityReplacement> entityReplacements = new ConcurrentHashMap<>();
private final Map<Integer, UUID> playersByEntityId = new HashMap<>();
private final Map<UUID, Integer> playersByUniqueId = new HashMap<>();
private final Map<UUID, Item[]> playerEquipment = new HashMap<>();
private int gamemode = 0;
private int playerId = -1;
private int spectating = -1;
private int dimension = 0;
public EntityTracker(UserConnection user) {
super(user);
}
public void removeEntity(int entityId) {
clientEntityTypes.remove(entityId);
if (entityReplacements.containsKey(entityId)) {
entityReplacements.remove(entityId).despawn();
}
if (playersByEntityId.containsKey(entityId)) {
UUID playerId = playersByEntityId.remove(entityId);
playersByUniqueId.remove(playerId);
playerEquipment.remove(playerId);
}
}
public void addPlayer(Integer entityId, UUID uuid) {
playersByUniqueId.put(uuid, entityId);
playersByEntityId.put(entityId, uuid);
}
public UUID getPlayerUUID(int entityId) {
return playersByEntityId.get(entityId);
}
public int getPlayerEntityId(UUID uuid) {
return playersByUniqueId.getOrDefault(uuid, -1);
}
public Item getPlayerEquipment(UUID uuid, int slot) {
Item[] items = playerEquipment.get(uuid);
if (items == null || slot < 0 || slot >= items.length) return null;
return items[slot];
}
public void setPlayerEquipment(UUID uuid, Item equipment, int slot) {
// Please note that when referring to the client player, it has an Item[4] array
Item[] items = playerEquipment.computeIfAbsent(uuid, it -> new Item[5]);
if (slot < 0 || slot >= items.length) return;
items[slot] = equipment;
}
public Map<Integer, Entity1_10Types.EntityType> getClientEntityTypes() {
return this.clientEntityTypes;
}
public void addMetadataToBuffer(int entityID, List<Metadata> metadataList) {
if (this.metadataBuffer.containsKey(entityID)) {
this.metadataBuffer.get(entityID).addAll(metadataList);
} else if (!metadataList.isEmpty()) {
this.metadataBuffer.put(entityID, metadataList);
}
}
public void addEntityReplacement(EntityReplacement entityReplacement) {
entityReplacements.put(entityReplacement.getEntityId(), entityReplacement);
}
public EntityReplacement getEntityReplacement(int entityId) {
return entityReplacements.get(entityId);
}
public List<Metadata> getBufferedMetadata(int entityId) {
return metadataBuffer.get(entityId);
}
public void sendMetadataBuffer(int entityId) {
if (!this.metadataBuffer.containsKey(entityId)) return;
if (entityReplacements.containsKey(entityId)) {
entityReplacements.get(entityId).updateMetadata(this.metadataBuffer.remove(entityId));
} else {
Entity1_10Types.EntityType type = this.getClientEntityTypes().get(entityId);
PacketWrapper wrapper = PacketWrapper.create(0x1C, null, this.getUser());
wrapper.write(Type.VAR_INT, entityId);
wrapper.write(Types1_8.METADATA_LIST, this.metadataBuffer.get(entityId));
MetadataRewriter.transform(type, this.metadataBuffer.get(entityId));
if (!this.metadataBuffer.get(entityId).isEmpty()) {
PacketUtil.sendPacket(wrapper, Protocol1_7_6_10To1_8.class);
}
this.metadataBuffer.remove(entityId);
}
}
public int getVehicle(int passengerId) {
for (Map.Entry<Integer, Integer> vehicle : vehicles.entrySet()) {
if (vehicle.getValue()==passengerId) return vehicle.getValue();
}
return -1;
}
public int getPassenger(int vehicleId) {
return vehicles.getOrDefault(vehicleId, -1);
}
public void setPassenger(int vehicleId, int passengerId) {
if (vehicleId==this.spectating && this.spectating!=this.playerId) {
try {
PacketWrapper sneakPacket = PacketWrapper.create(0x0B, null, getUser());
sneakPacket.write(Type.VAR_INT, playerId);
sneakPacket.write(Type.VAR_INT, 0); //Start sneaking
sneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketWrapper unsneakPacket = PacketWrapper.create(0x0B, null, getUser());
unsneakPacket.write(Type.VAR_INT, playerId);
unsneakPacket.write(Type.VAR_INT, 1); //Stop sneaking
unsneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketUtil.sendToServer(sneakPacket, Protocol1_7_6_10To1_8.class, true, true);
setSpectating(playerId);
} catch (Exception ex) {ex.printStackTrace();}
}
if (vehicleId==-1) {
int oldVehicleId = getVehicle(passengerId);
vehicles.remove(oldVehicleId);
} else if (passengerId==-1) {
vehicles.remove(vehicleId);
} else {
vehicles.put(vehicleId, passengerId);
}
}
public int getSpectating() {
return spectating;
}
public boolean setSpectating(int spectating) {
if (spectating!=this.playerId && getPassenger(spectating)!=-1) {
PacketWrapper sneakPacket = PacketWrapper.create(0x0B, null, getUser());
sneakPacket.write(Type.VAR_INT, playerId);
sneakPacket.write(Type.VAR_INT, 0); //Start sneaking
sneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketWrapper unsneakPacket = PacketWrapper.create(0x0B, null, getUser());
unsneakPacket.write(Type.VAR_INT, playerId);
unsneakPacket.write(Type.VAR_INT, 1); //Stop sneaking
unsneakPacket.write(Type.VAR_INT, 0); //Action Parameter
PacketUtil.sendToServer(sneakPacket, Protocol1_7_6_10To1_8.class, true, true);
setSpectating(this.playerId);
return false; //Entity has Passenger
}
if (this.spectating!=spectating && this.spectating!=this.playerId) {
PacketWrapper unmount = PacketWrapper.create(0x1B, null, this.getUser());
unmount.write(Type.INT, this.playerId);
unmount.write(Type.INT, -1);
unmount.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(unmount, Protocol1_7_6_10To1_8.class);
}
this.spectating = spectating;
if (spectating!=this.playerId) {
PacketWrapper mount = PacketWrapper.create(0x1B, null, this.getUser());
mount.write(Type.INT, this.playerId);
mount.write(Type.INT, this.spectating);
mount.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(mount, Protocol1_7_6_10To1_8.class);
}
return true;
}
public int getGamemode() {
return gamemode;
}
public void setGamemode(int gamemode) {
this.gamemode = gamemode;
}
public int getPlayerId() {
return playerId;
}
public void setPlayerId(int playerId) {
this.playerId = this.spectating = playerId;
}
public void clearEntities() {
clientEntityTypes.clear();
entityReplacements.clear();
vehicles.clear();
metadataBuffer.clear();
}
public int getDimension() {
return dimension;
}
public void setDimension(int dimension) {
this.dimension = dimension;
}
@Override
public void setClientEntityId(int playerEntityId) {
if (this.spectating == this.playerId) {
this.spectating = playerEntityId;
}
clientEntityTypes.remove(this.playerId);
this.playerId = playerEntityId;
clientEntityTypes.put(this.playerId, Entity1_10Types.EntityType.ENTITY_HUMAN);
}
}
@@ -1,132 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
public class PlayerAbilities extends StoredObject {
private boolean sprinting, allowFly, flying, invincible, creative;
private float flySpeed, walkSpeed;
public PlayerAbilities(UserConnection user) {
super(user);
}
public byte getFlags() {
byte flags = 0;
if (invincible) flags |= 8;
if (allowFly) flags |= 4;
if (flying) flags |= 2;
if (creative) flags |= 1;
return flags;
}
public boolean isSprinting() {
return this.sprinting;
}
public boolean isAllowFly() {
return this.allowFly;
}
public boolean isFlying() {
return this.flying;
}
public boolean isInvincible() {
return this.invincible;
}
public boolean isCreative() {
return this.creative;
}
public float getFlySpeed() {
return this.flySpeed;
}
public float getWalkSpeed() {
return this.walkSpeed;
}
public void setSprinting(boolean sprinting) {
this.sprinting = sprinting;
}
public void setAllowFly(boolean allowFly) {
this.allowFly = allowFly;
}
public void setFlying(boolean flying) {
this.flying = flying;
}
public void setInvincible(boolean invincible) {
this.invincible = invincible;
}
public void setCreative(boolean creative) {
this.creative = creative;
}
public void setFlySpeed(float flySpeed) {
this.flySpeed = flySpeed;
}
public void setWalkSpeed(float walkSpeed) {
this.walkSpeed = walkSpeed;
}
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof PlayerAbilities))
return false;
final PlayerAbilities other = (PlayerAbilities) o;
if (!other.canEqual(this)) return false;
if (this.isSprinting() != other.isSprinting()) return false;
if (this.isAllowFly() != other.isAllowFly()) return false;
if (this.isFlying() != other.isFlying()) return false;
if (this.isInvincible() != other.isInvincible()) return false;
if (this.isCreative() != other.isCreative()) return false;
if (Float.compare(this.getFlySpeed(), other.getFlySpeed()) != 0) return false;
return Float.compare(this.getWalkSpeed(), other.getWalkSpeed()) == 0;
}
protected boolean canEqual(final Object other) {
return other instanceof PlayerAbilities;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + (this.isSprinting() ? 79 : 97);
result = result * PRIME + (this.isAllowFly() ? 79 : 97);
result = result * PRIME + (this.isFlying() ? 79 : 97);
result = result * PRIME + (this.isInvincible() ? 79 : 97);
result = result * PRIME + (this.isCreative() ? 79 : 97);
result = result * PRIME + Float.floatToIntBits(this.getFlySpeed());
result = result * PRIME + Float.floatToIntBits(this.getWalkSpeed());
return result;
}
public String toString() {
return "PlayerAbilities(sprinting=" + this.isSprinting() + ", allowFly=" + this.isAllowFly() + ", flying=" + this.isFlying() + ", invincible=" + this.isInvincible() + ", creative=" + this.isCreative() + ", flySpeed=" + this.getFlySpeed() + ", walkSpeed=" + this.getWalkSpeed() + ")";
}
}
@@ -1,149 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import java.util.HashMap;
public class Windows extends StoredObject {
public HashMap<Short, Short> types = new HashMap<>();
public HashMap<Short, Furnace> furnace = new HashMap<>();
public short levelCost = 0;
public short anvilId = -1;
public Windows(UserConnection user) {
super(user);
}
public short get(short windowId) {
return types.getOrDefault(windowId, (short)-1);
}
public void remove(short windowId) {
types.remove(windowId);
furnace.remove(windowId);
}
public static int getInventoryType(String name) {
switch(name) {
case "minecraft:container":
return 0;
case "minecraft:chest":
return 0;
case "minecraft:crafting_table":
return 1;
case "minecraft:furnace":
return 2;
case "minecraft:dispenser":
return 3;
case "minecraft:enchanting_table":
return 4;
case "minecraft:brewing_stand":
return 5;
case "minecraft:villager":
return 6;
case "minecraft:beacon":
return 7;
case "minecraft:anvil":
return 8;
case "minecraft:hopper":
return 9;
case "minecraft:dropper":
return 10;
case "EntityHorse":
return 11;
default:
throw new IllegalArgumentException("Unknown type " + name);
}
}
public static class Furnace {
private short fuelLeft = 0;
private short maxFuel = 0;
private short progress = 0;
private short maxProgress = 200;
public Furnace() {
}
public short getFuelLeft() {
return this.fuelLeft;
}
public short getMaxFuel() {
return this.maxFuel;
}
public short getProgress() {
return this.progress;
}
public short getMaxProgress() {
return this.maxProgress;
}
public void setFuelLeft(short fuelLeft) {
this.fuelLeft = fuelLeft;
}
public void setMaxFuel(short maxFuel) {
this.maxFuel = maxFuel;
}
public void setProgress(short progress) {
this.progress = progress;
}
public void setMaxProgress(short maxProgress) {
this.maxProgress = maxProgress;
}
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof Furnace))
return false;
final Furnace other = (Furnace) o;
if (!other.canEqual(this)) return false;
if (this.getFuelLeft() != other.getFuelLeft()) return false;
if (this.getMaxFuel() != other.getMaxFuel()) return false;
if (this.getProgress() != other.getProgress()) return false;
return this.getMaxProgress() == other.getMaxProgress();
}
protected boolean canEqual(final Object other) {
return other instanceof Furnace;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.getFuelLeft();
result = result * PRIME + this.getMaxFuel();
result = result * PRIME + this.getProgress();
result = result * PRIME + this.getMaxProgress();
return result;
}
public String toString() {
return "Windows.Furnace(fuelLeft=" + this.getFuelLeft() + ", maxFuel=" + this.getMaxFuel() + ", progress=" + this.getProgress() + ", maxProgress=" + this.getMaxProgress() + ")";
}
}
}
@@ -1,210 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.storage;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.utils.Tickable;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.Protocol1_7_6_10To1_8;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
public class WorldBorder extends StoredObject implements Tickable {
private double x, z;
private double oldDiameter, newDiameter;
private long lerpTime;
private long lerpStartTime;
private int portalTeleportBoundary;
private int warningTime, warningBlocks;
private boolean init = false;
private static final int VIEW_DISTANCE = 16;
public WorldBorder(UserConnection user) {
super(user);
}
@Override
public void tick() {
if (!isInit()) {
return;
}
sendPackets();
}
private enum Side {
NORTH(0, -1),
EAST(1, 0),
SOUTH(0, 1),
WEST(-1, 0),
;
private final int modX;
private final int modZ;
Side(int modX, int modZ) {
this.modX = modX;
this.modZ = modZ;
}
}
private void sendPackets() {
PlayerPosition position = getUser().get(PlayerPosition.class);
double radius = getSize() / 2.0;
for (Side side : Side.values()) {
double d;
double pos;
double center;
if (side.modX!=0) {
pos = position.getPosZ();
center = z;
d = Math.abs(x + radius * side.modX - position.getPosX());
} else {
center = x;
pos = position.getPosX();
d = Math.abs(z + radius * side.modZ - position.getPosZ());
}
if (d >= VIEW_DISTANCE) continue;
double r = Math.sqrt(VIEW_DISTANCE * VIEW_DISTANCE - d * d);
double minH = Math.ceil(pos - r);
double maxH = Math.floor(pos + r);
double minV = Math.ceil(position.getPosY() - r);
double maxV = Math.floor(position.getPosY() + r);
if (minH<center-radius) minH = Math.ceil(center-radius);
if (maxH>center+radius) maxH = Math.floor(center+radius);
if (minV<0.0) minV = 0.0;
double centerH = (minH+maxH) / 2.0;
double centerV = (minV+maxV) / 2.0;
int a = (int) Math.floor((maxH-minH) * (maxV-minV) * 0.5);
double b = 2.5;
PacketWrapper particles = PacketWrapper.create(0x2A, null, getUser());
particles.write(Type.STRING, "fireworksSpark");
particles.write(Type.FLOAT, (float)(side.modX!=0 ? x + (radius * side.modX) : centerH));
particles.write(Type.FLOAT, (float)centerV);
particles.write(Type.FLOAT, (float)(side.modX==0 ? z + (radius * side.modZ) : centerH));
particles.write(Type.FLOAT, (float)(side.modX!=0 ? 0f : (maxH-minH) / b));
particles.write(Type.FLOAT, (float)((maxV-minV) / b));
particles.write(Type.FLOAT, (float)(side.modX==0 ? 0f : (maxH-minH) / b));
particles.write(Type.FLOAT, 0f);
particles.write(Type.INT, a);
PacketUtil.sendPacket(particles, Protocol1_7_6_10To1_8.class, true, true);
}
}
private boolean isInit() {
return init;
}
public void init(double x, double z, double oldDiameter, double newDiameter, long lerpTime, int portalTeleportBoundary, int warningTime, int warningBlocks) {
this.x = x;
this.z = z;
this.oldDiameter = oldDiameter;
this.newDiameter = newDiameter;
this.lerpTime = lerpTime;
this.portalTeleportBoundary = portalTeleportBoundary;
this.warningTime = warningTime;
this.warningBlocks = warningBlocks;
init = true;
}
public double getX() {
return x;
}
public double getZ() {
return z;
}
public void setCenter(double x, double z) {
this.x = x;
this.z = z;
}
public double getOldDiameter() {
return oldDiameter;
}
public double getNewDiameter() {
return newDiameter;
}
public long getLerpTime() {
return lerpTime;
}
public void lerpSize(double oldDiameter, double newDiameter, long lerpTime) {
this.oldDiameter = oldDiameter;
this.newDiameter = newDiameter;
this.lerpTime = lerpTime;
this.lerpStartTime = System.currentTimeMillis();
}
public void setSize(double size) {
this.oldDiameter = size;
this.newDiameter = size;
this.lerpTime = 0;
}
public double getSize() {
if (lerpTime==0) return newDiameter;
long time = System.currentTimeMillis() - lerpStartTime;
double percent = ((double)(time) / (double)(lerpTime));
if (percent>1.0d) percent = 1.0d;
else if (percent<0.0d) percent = 0.0d;
return oldDiameter + (newDiameter-oldDiameter) * percent;
}
public int getPortalTeleportBoundary() {
return portalTeleportBoundary;
}
public void setPortalTeleportBoundary(int portalTeleportBoundary) {
this.portalTeleportBoundary = portalTeleportBoundary;
}
public int getWarningTime() {
return warningTime;
}
public void setWarningTime(int warningTime) {
this.warningTime = warningTime;
}
public int getWarningBlocks() {
return warningBlocks;
}
public void setWarningBlocks(int warningBlocks) {
this.warningBlocks = warningBlocks;
}
}
@@ -1,108 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viaversion.api.minecraft.Environment;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.type.PartialType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import io.netty.buffer.ByteBuf;
import java.io.ByteArrayOutputStream;
import java.util.zip.DeflaterOutputStream;
public class Chunk1_7_10Type extends PartialType<Chunk, ClientWorld> {
public Chunk1_7_10Type(ClientWorld param) {
super(param, Chunk.class);
}
@Override
public Chunk read(ByteBuf byteBuf, ClientWorld clientWorld) throws Exception {
throw new UnsupportedOperationException();
}
@Override
public void write(ByteBuf output, ClientWorld clientWorld, Chunk chunk) throws Exception {
output.writeInt(chunk.getX());
output.writeInt(chunk.getZ());
output.writeBoolean(chunk.isFullChunk());
output.writeShort(chunk.getBitmask());
output.writeShort(0);
ByteBuf dataToCompress = output.alloc().buffer();
try {
for (int i = 0; i < chunk.getSections().length; i++) {
if ((chunk.getBitmask() & 1 << i) == 0) continue;
ChunkSection section = chunk.getSections()[i];
DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < 4096; j++) {
int block = palette.idAt(j);
dataToCompress.writeByte(block >> 4);
}
}
for (int i = 0; i < chunk.getSections().length; i++) {
if ((chunk.getBitmask() & 1 << i) == 0) continue;
ChunkSection section = chunk.getSections()[i];
DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int j = 0; j < 4096; j += 2) {
int data0 = palette.idAt(j) & 0xF;
int data1 = palette.idAt(j + 1) & 0xF;
dataToCompress.writeByte((data1 << 4) | data0);
}
}
for (int i = 0; i < chunk.getSections().length; i++) {
if ((chunk.getBitmask() & 1 << i) == 0) continue;
chunk.getSections()[i].getLight().writeBlockLight(dataToCompress);
}
boolean skyLight = clientWorld != null && clientWorld.getEnvironment() == Environment.NORMAL;
if (skyLight) {
for (int i = 0; i < chunk.getSections().length; i++) {
if ((chunk.getBitmask() & 1 << i) == 0) continue;
chunk.getSections()[i].getLight().writeSkyLight(dataToCompress);
}
}
if (chunk.isFullChunk() && chunk.isBiomeData()) {
for (int biome : chunk.getBiomeData()) {
dataToCompress.writeByte(biome);
}
}
ByteArrayOutputStream compressedStream = new ByteArrayOutputStream();
// todo config for compression level
try (DeflaterOutputStream compressorStream = new DeflaterOutputStream(compressedStream)) {
compressorStream.write(Type.REMAINING_BYTES.read(dataToCompress));
}
output.writeInt(compressedStream.size());
output.writeBytes(compressedStream.toByteArray());
} finally {
dataToCompress.release();
}
}
}
@@ -1,46 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viaversion.api.type.PartialType;
import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf;
public class CustomStringType extends PartialType<String[], Integer> {
public CustomStringType(Integer param) {
super(param, String[].class);
}
public String[] read(ByteBuf buffer, Integer size) throws Exception {
if (buffer.readableBytes() < size/4) {
throw new RuntimeException("Readable bytes does not match expected!");
} else {
String[] array = new String[size];
for (int i = 0; i<size; i++) {
array[i] = Type.STRING.read(buffer);
}
return array;
}
}
public void write(ByteBuf buffer, Integer size, String[] strings) throws Exception {
for (String s : strings) Type.STRING.write(buffer, s);
}
}
@@ -1,56 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListTypeTemplate;
import io.netty.buffer.ByteBuf;
import java.util.ArrayList;
import java.util.List;
public class MetadataListType extends MetaListTypeTemplate {
private final MetadataType metadataType = new MetadataType();
@Override
public List<Metadata> read(ByteBuf buffer) throws Exception {
ArrayList<Metadata> list = new ArrayList<>();
Metadata m;
do {
m = Types1_7_6_10.METADATA.read(buffer);
if (m != null) {
list.add(m);
}
} while(m != null);
return list;
}
@Override
public void write(ByteBuf buffer, List<Metadata> metadata) throws Exception {
for (Metadata meta : metadata) {
Types1_7_6_10.METADATA.write(buffer, meta);
}
if (metadata.isEmpty()) {
Types1_7_6_10.METADATA.write(buffer, new Metadata(0, MetaType1_7_6_10.Byte, (byte)0));
}
buffer.writeByte(127);
}
}
@@ -1,67 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.NBTIO;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import java.io.*;
public class NBTType extends Type<CompoundTag> {
public NBTType() {
super(CompoundTag.class);
}
@Override
public CompoundTag read(ByteBuf buffer) {
short length = buffer.readShort();
if (length < 0) {return null;}
ByteBufInputStream byteBufInputStream = new ByteBufInputStream(buffer);
DataInputStream dataInputStream = new DataInputStream(byteBufInputStream);
try {
return NBTIO.readTag((DataInput) dataInputStream);
} catch (Throwable throwable) {throwable.printStackTrace();}
finally {
try {
dataInputStream.close();
} catch (IOException e) {e.printStackTrace();}
}
return null;
}
@Override
public void write(ByteBuf buffer, CompoundTag nbt) throws Exception {
if (nbt == null) {
buffer.writeShort(-1);
} else {
ByteBuf buf = buffer.alloc().buffer();
ByteBufOutputStream bytebufStream = new ByteBufOutputStream(buf);
DataOutputStream dataOutputStream = new DataOutputStream(bytebufStream);
NBTIO.writeTag((DataOutput) dataOutputStream, nbt);
dataOutputStream.close();
buffer.writeShort(buf.readableBytes());
buffer.writeBytes(buf);
buf.release();
}
}
}
@@ -1,41 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import java.util.List;
public class Types1_7_6_10 {
public static final Type<CompoundTag> COMPRESSED_NBT = new CompressedNBTType();
public static final Type<Item[]> ITEM_ARRAY = new ItemArrayType(false);
public static final Type<Item[]> COMPRESSED_NBT_ITEM_ARRAY = new ItemArrayType(true);
public static final Type<Item> ITEM = new ItemType(false);
public static final Type<Item> COMPRESSED_NBT_ITEM = new ItemType(true);
public static final Type<List<Metadata>> METADATA_LIST = new MetadataListType();
public static final Type<Metadata> METADATA = new MetadataType();
public static final Type<CompoundTag> NBT = new NBTType();
/**
* An int array prefixed with byte representing the size
*/
public static final Type<int[]> INT_ARRAY = new IntArrayType();
}
@@ -1,184 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_7_6_10.metadata;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types.MetaType1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.Optional;
public enum MetaIndex1_8To1_7_6_10 {
ENTITY_FLAGS(Entity1_10Types.EntityType.ENTITY, 0, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ENTITY_AIR(Entity1_10Types.EntityType.ENTITY, 1, MetaType1_7_6_10.Short, MetaType1_8.Short),
ENTITY_NAME_TAG(Entity1_10Types.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 2, MetaType1_8.String),
ENTITY_NAME_TAG_VISIBILITY(Entity1_10Types.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 3, MetaType1_8.Byte),
ENTITY_SILENT(Entity1_10Types.EntityType.ENTITY, -1, MetaType1_7_6_10.NonExistent, 4, MetaType1_8.Byte),
ENTITY_LIVING_HEALTH(Entity1_10Types.EntityType.ENTITY_LIVING, 6, MetaType1_7_6_10.Float, MetaType1_8.Float),
ENTITY_LIVING_POTION_EFFECT_COLOR(Entity1_10Types.EntityType.ENTITY_LIVING, 7, MetaType1_7_6_10.Int, MetaType1_8.Int),
ENTITY_LIVING_IS_POTION_EFFECT_AMBIENT(Entity1_10Types.EntityType.ENTITY_LIVING, 8, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ENTITY_LIVING_ARROWS(Entity1_10Types.EntityType.ENTITY_LIVING, 9, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ENTITY_LIVING_NAME_TAG(Entity1_10Types.EntityType.ENTITY_LIVING, 10, MetaType1_7_6_10.String, 2, MetaType1_8.String),
ENTITY_LIVING_NAME_TAG_VISIBILITY(Entity1_10Types.EntityType.ENTITY_LIVING, 11, MetaType1_7_6_10.Byte, 3, MetaType1_8.Byte),
ENTITY_LIVING_AI(Entity1_10Types.EntityType.ENTITY_LIVING, -1, MetaType1_7_6_10.NonExistent, 15, MetaType1_8.Byte),
ENTITY_AGEABLE_AGE(Entity1_10Types.EntityType.ENTITY_AGEABLE, 12, MetaType1_7_6_10.Int, MetaType1_8.Byte),
ARMOR_STAND_FLAGS(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 10, MetaType1_8.Byte),
ARMOR_STAND_HEAD_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 11, MetaType1_8.Rotation),
ARMOR_STAND_BODY_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 12, MetaType1_8.Rotation),
ARMOR_STAND_LEFT_ARM_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 13, MetaType1_8.Rotation),
ARMOR_STAND_RIGHT_ARM_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 14, MetaType1_8.Rotation),
ARMOR_STAND_LEFT_LEG_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 15, MetaType1_8.Rotation),
ARMOR_STAND_RIGHT_LEG_POSITION(Entity1_10Types.EntityType.ARMOR_STAND, -1, MetaType1_7_6_10.NonExistent, 16, MetaType1_8.Rotation),
HUMAN_SKIN_FLAGS(Entity1_10Types.EntityType.ENTITY_HUMAN, 16, MetaType1_7_6_10.Byte, 10, MetaType1_8.Byte),
HUMAN_UNUSED(Entity1_10Types.EntityType.ENTITY_HUMAN, -1, MetaType1_7_6_10.NonExistent, 16, MetaType1_8.Byte),
HUMAN_ABSORPTION_HEATS(Entity1_10Types.EntityType.ENTITY_HUMAN, 17, MetaType1_7_6_10.Float, MetaType1_8.Float),
HUMAN_SCORE(Entity1_10Types.EntityType.ENTITY_HUMAN, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
HORSE_FLAGS(Entity1_10Types.EntityType.HORSE, 16, MetaType1_7_6_10.Int, MetaType1_8.Int),
HORSE_TYPE(Entity1_10Types.EntityType.HORSE, 19, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
HORSE_COLOR(Entity1_10Types.EntityType.HORSE, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
HORSE_OWNER(Entity1_10Types.EntityType.HORSE, 21, MetaType1_7_6_10.String, MetaType1_8.String),
HORSE_ARMOR(Entity1_10Types.EntityType.HORSE, 22, MetaType1_7_6_10.Int, MetaType1_8.Int),
BAT_HANGING(Entity1_10Types.EntityType.BAT, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
TAMEABLE_FLAGS(Entity1_10Types.EntityType.ENTITY_TAMEABLE_ANIMAL, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
TAMEABLE_OWNER(Entity1_10Types.EntityType.ENTITY_TAMEABLE_ANIMAL, 17, MetaType1_7_6_10.String, MetaType1_8.String),
OCELOT_TYPE(Entity1_10Types.EntityType.OCELOT, 18, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WOLF_FLAGS(Entity1_10Types.EntityType.WOLF, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WOLF_HEALTH(Entity1_10Types.EntityType.WOLF, 18, MetaType1_7_6_10.Float, MetaType1_8.Float),
WOLF_BEGGING(Entity1_10Types.EntityType.WOLF, 19, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WOLF_COLLAR_COLOR(Entity1_10Types.EntityType.WOLF, 20, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
PIG_SADDLE(Entity1_10Types.EntityType.PIG, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
SHEEP_COLOR_OR_SHEARED(Entity1_10Types.EntityType.SHEEP, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
VILLAGER_TYPE(Entity1_10Types.EntityType.VILLAGER, 16, MetaType1_7_6_10.Int, MetaType1_8.Int),
ENDERMAN_CARRIED_BLOCK(Entity1_10Types.EntityType.ENDERMAN, 16, MetaType1_7_6_10.NonExistent, MetaType1_8.Short),
ENDERMAN_CARRIED_BLOCK_DATA(Entity1_10Types.EntityType.ENDERMAN, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
ENDERMAN_IS_SCREAMING(Entity1_10Types.EntityType.ENDERMAN, 18, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ZOMBIE_CHILD(Entity1_10Types.EntityType.ZOMBIE, 12, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ZOMBIE_VILLAGER(Entity1_10Types.EntityType.ZOMBIE, 13, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ZOMBIE_CONVERTING(Entity1_10Types.EntityType.ZOMBIE, 14, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
BLAZE_ON_FIRE(Entity1_10Types.EntityType.BLAZE, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
SPIDER_CLIMBING(Entity1_10Types.EntityType.SPIDER, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
CREEPER_STATE(Entity1_10Types.EntityType.CREEPER, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
CREEPER_POWERED(Entity1_10Types.EntityType.CREEPER, 17, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
GHAST_STATE(Entity1_10Types.EntityType.GHAST, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
GHAST_IS_POWERED(Entity1_10Types.EntityType.GHAST, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
SLIME_SIZE(Entity1_10Types.EntityType.SLIME, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
SKELETON_TYPE(Entity1_10Types.EntityType.SKELETON, 13, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WITCH_AGRESSIVE(Entity1_10Types.EntityType.WITCH, 21, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
IRON_GOLEM_IS_PLAYER_CREATED(Entity1_10Types.EntityType.IRON_GOLEM, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
WITHER_WATCHED_TAGRET_1(Entity1_10Types.EntityType.WITHER, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
WITHER_WATCHED_TAGRET_2(Entity1_10Types.EntityType.WITHER, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
WITHER_WATCHED_TAGRET_3(Entity1_10Types.EntityType.WITHER, 19, MetaType1_7_6_10.Int, MetaType1_8.Int),
WITHER_INVULNERABLE_TIME(Entity1_10Types.EntityType.WITHER, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
GUARDIAN_FLAGS(Entity1_10Types.EntityType.GUARDIAN, 16, MetaType1_7_6_10.NonExistent, MetaType1_8.Byte),
GUARDIAN_TARGET(Entity1_10Types.EntityType.GUARDIAN, 17, MetaType1_7_6_10.NonExistent, MetaType1_8.Int),
BOAT_TIME_SINCE_HIT(Entity1_10Types.EntityType.BOAT, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
BOAT_FORWARD_DIRECTION(Entity1_10Types.EntityType.BOAT, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
BOAT_DAMAGE_TAKEN(Entity1_10Types.EntityType.BOAT, 19, MetaType1_7_6_10.Float, MetaType1_8.Float),
MINECART_SHAKING_POWER(Entity1_10Types.EntityType.MINECART_ABSTRACT, 17, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_SHAKING_DIRECTION(Entity1_10Types.EntityType.MINECART_ABSTRACT, 18, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_DAMAGE_TAKEN(Entity1_10Types.EntityType.MINECART_ABSTRACT, 19, MetaType1_7_6_10.Float, MetaType1_8.Float),
MINECART_BLOCK_INSIDE(Entity1_10Types.EntityType.MINECART_ABSTRACT, 20, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_BLOCK_Y(Entity1_10Types.EntityType.MINECART_ABSTRACT, 21, MetaType1_7_6_10.Int, MetaType1_8.Int),
MINECART_SHOW_BLOCK(Entity1_10Types.EntityType.MINECART_ABSTRACT, 22, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
FURNACE_MINECART_IS_POWERED(Entity1_10Types.EntityType.MINECART_FURNACE, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
ITEM_ITEM(Entity1_10Types.EntityType.DROPPED_ITEM, 10, MetaType1_7_6_10.Slot, MetaType1_8.Slot),
ARROW_IS_CRITICAL(Entity1_10Types.EntityType.ARROW, 16, MetaType1_7_6_10.Byte, MetaType1_8.Byte),
FIREWORK_INFO(Entity1_10Types.EntityType.FIREWORK, 8, MetaType1_7_6_10.Slot, MetaType1_8.Slot),
ITEM_FRAME_ITEM(Entity1_10Types.EntityType.ITEM_FRAME, 2, MetaType1_7_6_10.Slot, 8, MetaType1_8.Slot),
ITEM_FRAME_ROTATION(Entity1_10Types.EntityType.ITEM_FRAME, 3, MetaType1_7_6_10.Byte, 9, MetaType1_8.Byte),
ENDER_CRYSTAL_HEALTH(Entity1_10Types.EntityType.ENDER_CRYSTAL, 8, MetaType1_7_6_10.Int, 9, MetaType1_8.Int),
;
private static final HashMap<Pair<Entity1_10Types.EntityType, Integer>, MetaIndex1_8To1_7_6_10> metadataRewrites = new HashMap<>();
static {
for (MetaIndex1_8To1_7_6_10 index : MetaIndex1_8To1_7_6_10.values())
metadataRewrites.put(new Pair<>(index.getClazz(), index.getIndex()), index);
}
private final Entity1_10Types.EntityType clazz;
private final int newIndex;
private final MetaType1_8 newType;
private final MetaType1_7_6_10 oldType;
private final int index;
MetaIndex1_8To1_7_6_10(Entity1_10Types.EntityType type, int index, MetaType1_7_6_10 oldType, MetaType1_8 newType) {
this.clazz = type;
this.index = index;
this.newIndex = index;
this.oldType = oldType;
this.newType = newType;
}
MetaIndex1_8To1_7_6_10(Entity1_10Types.EntityType type, int index, MetaType1_7_6_10 oldType, int newIndex, MetaType1_8 newType) {
this.clazz = type;
this.index = index;
this.oldType = oldType;
this.newIndex = newIndex;
this.newType = newType;
}
private static Optional<MetaIndex1_8To1_7_6_10> getIndex(Entity1_10Types.EntityType type, int index) {
Pair pair = new Pair<>(type, index);
if (metadataRewrites.containsKey(pair)) {
return Optional.of(metadataRewrites.get(pair));
}
return Optional.empty();
}
public Entity1_10Types.EntityType getClazz() {
return clazz;
}
public int getNewIndex() {
return newIndex;
}
public MetaType1_8 getNewType() {
return newType;
}
public MetaType1_7_6_10 getOldType() {
return oldType;
}
public int getIndex() {
return index;
}
public static MetaIndex1_8To1_7_6_10 searchIndex(Entity1_10Types.EntityType type, int index) {
Entity1_10Types.EntityType currentType = type;
do {
Optional<MetaIndex1_8To1_7_6_10> optMeta = getIndex(currentType, index);
if (optMeta.isPresent()) {
return optMeta.get();
}
currentType = currentType.getParent();
} while (currentType != null);
return null;
}
}
@@ -1,94 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.packets.*;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.*;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.packets.*;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.*;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import com.viaversion.viarewind.utils.Ticker;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
public class Protocol1_8To1_9 extends AbstractProtocol<ClientboundPackets1_9, ClientboundPackets1_8, ServerboundPackets1_9, ServerboundPackets1_8> {
public Queue<PacketWrapper> animationsToSend = new ConcurrentLinkedQueue<>();
public static final Set<String> VALID_ATTRIBUTES = new HashSet<>();
public static final ValueTransformer<Double, Integer> TO_OLD_INT = new ValueTransformer<Double, Integer>(Type.INT) {
public Integer transform(PacketWrapper wrapper, Double inputValue) {
return (int) (inputValue * 32.0D);
}
};
public static final ValueTransformer<Float, Byte> DEGREES_TO_ANGLE = new ValueTransformer<Float, Byte>(Type.BYTE) {
@Override
public Byte transform(PacketWrapper packetWrapper, Float degrees) throws Exception {
return (byte) ((degrees / 360F) * 256);
}
};
static {
VALID_ATTRIBUTES.add("generic.maxHealth");
VALID_ATTRIBUTES.add("generic.followRange");
VALID_ATTRIBUTES.add("generic.knockbackResistance");
VALID_ATTRIBUTES.add("generic.movementSpeed");
VALID_ATTRIBUTES.add("generic.attackDamage");
VALID_ATTRIBUTES.add("horse.jumpStrength");
VALID_ATTRIBUTES.add("zombie.spawnReinforcements");
}
public Protocol1_8To1_9() {
super(ClientboundPackets1_9.class, ClientboundPackets1_8.class, ServerboundPackets1_9.class, ServerboundPackets1_8.class);
}
@Override
protected void registerPackets() {
EntityPackets.register(this);
InventoryPackets.register(this);
PlayerPackets.register(this);
ScoreboardPackets.register(this);
SpawnPackets.register(this);
WorldPackets.register(this);
}
@Override
public void init(UserConnection userConnection) {
Ticker.init();
userConnection.put(new Windows(userConnection));
userConnection.put(new EntityTracker(userConnection));
userConnection.put(new Levitation(userConnection));
userConnection.put(new PlayerPosition(userConnection));
userConnection.put(new Cooldown(userConnection));
userConnection.put(new BlockPlaceDestroyTracker(userConnection));
userConnection.put(new BossBarStorage(userConnection));
userConnection.put(new ClientWorld(userConnection));
}
}
@@ -1,98 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.entityreplacement;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.ArrayList;
import java.util.List;
public abstract class EntityReplacement1_8to1_9 implements EntityReplacement {
protected final UserConnection user;
protected EntityReplacement1_8to1_9(UserConnection user) {
this.user = user;
}
protected void sendTeleportWithHead(int entityId, double locX, double locY, double locZ, float yaw, float pitch, float headYaw) {
sendTeleport(entityId, locX, locY, locZ, yaw, pitch);
sendHeadYaw(entityId, headYaw);
}
protected void sendTeleport(int entityId, double locX, double locY, double locZ, float yaw, float pitch) {
PacketWrapper teleport = PacketWrapper.create(ClientboundPackets1_8.ENTITY_TELEPORT, null, user);
teleport.write(Type.VAR_INT, entityId);
teleport.write(Type.INT, (int) (locX * 32.0));
teleport.write(Type.INT, (int) (locY * 32.0));
teleport.write(Type.INT, (int) (locZ * 32.0));
teleport.write(Type.BYTE, (byte) ((yaw / 360f) * 256));
teleport.write(Type.BYTE, (byte) ((pitch / 360f) * 256));
teleport.write(Type.BOOLEAN, true);
PacketUtil.sendPacket(teleport, Protocol1_8To1_9.class, true, true);
}
protected void sendHeadYaw(int entityId, float headYaw) {
PacketWrapper head = PacketWrapper.create(ClientboundPackets1_8.ENTITY_HEAD_LOOK, null, user);
head.write(Type.VAR_INT, entityId);
head.write(Type.BYTE, (byte) ((headYaw / 360f) * 256));
PacketUtil.sendPacket(head, Protocol1_8To1_9.class, true, true);
}
protected void sendSpawn(int entityId, int type) {
PacketWrapper spawn = PacketWrapper.create(ClientboundPackets1_8.SPAWN_MOB, null, user);
spawn.write(Type.VAR_INT, entityId);
spawn.write(Type.UNSIGNED_BYTE, (short) type);
spawn.write(Type.INT, 0);
spawn.write(Type.INT, 0);
spawn.write(Type.INT, 0);
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.SHORT, (short) 0);
spawn.write(Type.SHORT, (short) 0);
spawn.write(Type.SHORT, (short) 0);
List<Metadata> list = new ArrayList<>();
spawn.write(Types1_8.METADATA_LIST, list);
PacketUtil.sendPacket(spawn, Protocol1_8To1_9.class, true, true);
}
protected void sendSpawnEntity(int entityId, int type) {
PacketWrapper spawn = PacketWrapper.create(ClientboundPackets1_8.SPAWN_ENTITY, null, user);
spawn.write(Type.VAR_INT, entityId);
spawn.write(Type.BYTE, (byte) type);
spawn.write(Type.INT, 0);
spawn.write(Type.INT, 0);
spawn.write(Type.INT, 0);
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.BYTE, (byte) 0);
spawn.write(Type.INT, 0);
PacketUtil.sendPacket(spawn, Protocol1_8To1_9.class, true, true);
}
}
@@ -1,97 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.entityreplacement;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.ArrayList;
import java.util.List;
public class ShulkerBulletReplacement extends EntityReplacement1_8to1_9 {
private final int entityId;
private final List<Metadata> datawatcher = new ArrayList<>();
private double locX, locY, locZ;
private float yaw, pitch;
private float headYaw;
public ShulkerBulletReplacement(int entityId, UserConnection user) {
super(user);
this.entityId = entityId;
spawn();
}
public void setLocation(double x, double y, double z) {
if (x != this.locX || y != this.locY || z != this.locZ) {
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation();
}
}
public void relMove(double x, double y, double z) {
if (x == 0.0 && y == 0.0 && z == 0.0) return;
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation();
}
public void setYawPitch(float yaw, float pitch) {
if (this.yaw != yaw && this.pitch != pitch) {
this.yaw = yaw;
this.pitch = pitch;
updateLocation();
}
}
public void setHeadYaw(float yaw) {
this.headYaw = yaw;
}
public void updateMetadata(List<Metadata> metadataList) {
}
public void updateLocation() {
sendTeleportWithHead(entityId, locX, locY, locZ, yaw, pitch, headYaw);
}
@Override
public void spawn() {
sendSpawnEntity(entityId, 66);
}
@Override
public void despawn() {
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_8.DESTROY_ENTITIES, null, user);
despawn.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{entityId});
PacketUtil.sendPacket(despawn, Protocol1_8To1_9.class, true, true);
}
public int getEntityId() {
return this.entityId;
}
}
@@ -1,115 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.entityreplacement;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_9;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.ClientboundPackets1_7;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
import java.util.ArrayList;
import java.util.List;
public class ShulkerReplacement extends EntityReplacement1_8to1_9 {
private final int entityId;
private final List<Metadata> datawatcher = new ArrayList<>();
private double locX, locY, locZ;
public ShulkerReplacement(int entityId, UserConnection user) {
super(user);
this.entityId = entityId;
spawn();
}
public void setLocation(double x, double y, double z) {
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation();
}
public void relMove(double x, double y, double z) {
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation();
}
public void setYawPitch(float yaw, float pitch) {
}
public void setHeadYaw(float yaw) {
}
public void updateMetadata(List<Metadata> metadataList) {
for (Metadata metadata : metadataList) {
datawatcher.removeIf(m -> m.id() == metadata.id());
datawatcher.add(metadata);
}
updateMetadata();
}
public void updateLocation() {
sendTeleport(entityId, locX, locY, locZ, 0, 0);
}
public void updateMetadata() {
PacketWrapper metadataPacket = PacketWrapper.create(ClientboundPackets1_8.ENTITY_METADATA, null, user);
metadataPacket.write(Type.VAR_INT, entityId);
List<Metadata> metadataList = new ArrayList<>();
for (Metadata metadata : datawatcher) {
if (metadata.id() == 11 || metadata.id() == 12 || metadata.id() == 13) continue;
metadataList.add(new Metadata(metadata.id(), metadata.metaType(), metadata.getValue()));
}
metadataList.add(new Metadata(11, MetaType1_9.VarInt, 2));
MetadataRewriter.transform(Entity1_10Types.EntityType.MAGMA_CUBE, metadataList);
metadataPacket.write(Types1_8.METADATA_LIST, metadataList);
PacketUtil.sendPacket(metadataPacket, Protocol1_8To1_9.class);
}
@Override
public void spawn() {
sendSpawn(entityId, 62);
// Old clients don't like empty metadata
}
@Override
public void despawn() {
PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7.DESTROY_ENTITIES, null, user);
despawn.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{entityId});
PacketUtil.sendPacket(despawn, Protocol1_8To1_9.class, true, true);
}
public int getEntityId() {
return this.entityId;
}
}
@@ -1,310 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.items;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.*;
import com.viaversion.viarewind.utils.Enchantments;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.viaversion.viaversion.protocols.protocol1_9to1_8.ItemRewriter.potionNameFromDamage;
@SuppressWarnings({"MismatchedQueryAndUpdateOfCollection", "unused"})
public class ItemRewriter {
private static Map<String, Integer> ENTTIY_NAME_TO_ID;
private static Map<Integer, String> ENTTIY_ID_TO_NAME;
private static Map<String, Integer> POTION_NAME_TO_ID;
private static Map<Integer, String> POTION_ID_TO_NAME;
private static final Map<String, String> POTION_NAME_INDEX = new HashMap<>();
static {
for (Field field : ItemRewriter.class.getDeclaredFields()) {
try {
Field other = com.viaversion.viaversion.protocols.protocol1_9to1_8.ItemRewriter.class.getDeclaredField(field.getName());
other.setAccessible(true);
field.setAccessible(true);
field.set(null, other.get(null));
} catch (Exception ignored) {}
}
POTION_NAME_TO_ID.put("luck", 8203);
POTION_NAME_INDEX.put("water", "§rWater Bottle");
POTION_NAME_INDEX.put("mundane", "§rMundane Potion");
POTION_NAME_INDEX.put("thick", "§rThick Potion");
POTION_NAME_INDEX.put("awkward", "§rAwkward Potion");
POTION_NAME_INDEX.put("water_splash", "§rSplash Water Bottle");
POTION_NAME_INDEX.put("mundane_splash", "§rMundane Splash Potion");
POTION_NAME_INDEX.put("thick_splash", "§rThick Splash Potion");
POTION_NAME_INDEX.put("awkward_splash", "§rAwkward Splash Potion");
POTION_NAME_INDEX.put("water_lingering", "§rLingering Water Bottle");
POTION_NAME_INDEX.put("mundane_lingering", "§rMundane Lingering Potion");
POTION_NAME_INDEX.put("thick_lingering", "§rThick Lingering Potion");
POTION_NAME_INDEX.put("awkward_lingering", "§rAwkward Lingering Potion");
POTION_NAME_INDEX.put("night_vision_lingering", "§rLingering Potion of Night Vision");
POTION_NAME_INDEX.put("long_night_vision_lingering", "§rLingering Potion of Night Vision");
POTION_NAME_INDEX.put("invisibility_lingering", "§rLingering Potion of Invisibility");
POTION_NAME_INDEX.put("long_invisibility_lingering", "§rLingering Potion of Invisibility");
POTION_NAME_INDEX.put("leaping_lingering", "§rLingering Potion of Leaping");
POTION_NAME_INDEX.put("long_leaping_lingering", "§rLingering Potion of Leaping");
POTION_NAME_INDEX.put("strong_leaping_lingering", "§rLingering Potion of Leaping");
POTION_NAME_INDEX.put("fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
POTION_NAME_INDEX.put("long_fire_resistance_lingering", "§rLingering Potion of Fire Resistance");
POTION_NAME_INDEX.put("swiftness_lingering", "§rLingering Potion of Swiftness");
POTION_NAME_INDEX.put("long_swiftness_lingering", "§rLingering Potion of Swiftness");
POTION_NAME_INDEX.put("strong_swiftness_lingering", "§rLingering Potion of Swiftness");
POTION_NAME_INDEX.put("slowness_lingering", "§rLingering Potion of Slowness");
POTION_NAME_INDEX.put("long_slowness_lingering", "§rLingering Potion of Slowness");
POTION_NAME_INDEX.put("water_breathing_lingering", "§rLingering Potion of Water Breathing");
POTION_NAME_INDEX.put("long_water_breathing_lingering", "§rLingering Potion of Water Breathing");
POTION_NAME_INDEX.put("healing_lingering", "§rLingering Potion of Healing");
POTION_NAME_INDEX.put("strong_healing_lingering", "§rLingering Potion of Healing");
POTION_NAME_INDEX.put("harming_lingering", "§rLingering Potion of Harming");
POTION_NAME_INDEX.put("strong_harming_lingering", "§rLingering Potion of Harming");
POTION_NAME_INDEX.put("poison_lingering", "§rLingering Potion of Poisen");
POTION_NAME_INDEX.put("long_poison_lingering", "§rLingering Potion of Poisen");
POTION_NAME_INDEX.put("strong_poison_lingering", "§rLingering Potion of Poisen");
POTION_NAME_INDEX.put("regeneration_lingering", "§rLingering Potion of Regeneration");
POTION_NAME_INDEX.put("long_regeneration_lingering", "§rLingering Potion of Regeneration");
POTION_NAME_INDEX.put("strong_regeneration_lingering", "§rLingering Potion of Regeneration");
POTION_NAME_INDEX.put("strength_lingering", "§rLingering Potion of Strength");
POTION_NAME_INDEX.put("long_strength_lingering", "§rLingering Potion of Strength");
POTION_NAME_INDEX.put("strong_strength_lingering", "§rLingering Potion of Strength");
POTION_NAME_INDEX.put("weakness_lingering", "§rLingering Potion of Weakness");
POTION_NAME_INDEX.put("long_weakness_lingering", "§rLingering Potion of Weakness");
POTION_NAME_INDEX.put("luck_lingering", "§rLingering Potion of Luck");
POTION_NAME_INDEX.put("luck", "§rPotion of Luck");
POTION_NAME_INDEX.put("luck_splash", "§rSplash Potion of Luck");
}
public static Item toClient(Item item) {
if (item==null) return null;
CompoundTag tag = item.tag();
if (tag==null) item.setTag(tag = new CompoundTag());
CompoundTag viaVersionTag = new CompoundTag();
tag.put("ViaRewind1_8to1_9", viaVersionTag);
viaVersionTag.put("id", new ShortTag((short) item.identifier()));
viaVersionTag.put("data", new ShortTag(item.data()));
CompoundTag display = tag.get("display");
if (display!=null && display.contains("Name")) {
viaVersionTag.put("displayName", new StringTag((String) display.get("Name").getValue()));
}
if (display!=null && display.contains("Lore")) {
viaVersionTag.put("lore", new ListTag(((ListTag)display.get("Lore")).getValue()));
}
if (tag.contains("ench") || tag.contains("StoredEnchantments")) {
ListTag enchTag = tag.contains("ench") ? tag.get("ench") : tag.get("StoredEnchantments");
List<Tag> lore = new ArrayList<>();
for (Tag ench : new ArrayList<>(enchTag.getValue())) {
short id = ((NumberTag) ((CompoundTag)ench).get("id")).asShort();
short lvl = ((NumberTag) ((CompoundTag)ench).get("lvl")).asShort();
String s;
if (id==70) {
s = "§r§7Mending ";
} else if (id==9) {
s = "§r§7Frost Walker ";
} else {
continue;
}
enchTag.remove(ench);
s += Enchantments.ENCHANTMENTS.getOrDefault(lvl, "enchantment.level." + lvl);
lore.add(new StringTag(s));
}
if (!lore.isEmpty()) {
if (display==null) {
tag.put("display", display = new CompoundTag());
viaVersionTag.put("noDisplay", new ByteTag());
}
ListTag loreTag = display.get("Lore");
if (loreTag==null) display.put("Lore", loreTag = new ListTag(StringTag.class));
lore.addAll(loreTag.getValue());
loreTag.setValue(lore);
}
}
if (item.data()!=0 && tag.contains("Unbreakable")) {
ByteTag unbreakable = tag.get("Unbreakable");
if (unbreakable.asByte()!=0) {
viaVersionTag.put("Unbreakable", new ByteTag(unbreakable.asByte()));
tag.remove("Unbreakable");
if (display==null) {
tag.put("display", display = new CompoundTag());
viaVersionTag.put("noDisplay", new ByteTag());
}
ListTag loreTag = display.get("Lore");
if (loreTag==null) display.put("Lore", loreTag = new ListTag(StringTag.class));
loreTag.add(new StringTag("§9Unbreakable"));
}
}
if (tag.contains("AttributeModifiers")) {
viaVersionTag.put("AttributeModifiers", tag.get("AttributeModifiers").clone());
}
if (item.identifier()==383 && item.data()==0) {
int data = 0;
if (tag.contains("EntityTag")) {
CompoundTag entityTag = tag.get("EntityTag");
if (entityTag.contains("id")) {
StringTag id = entityTag.get("id");
if (ENTTIY_NAME_TO_ID.containsKey(id.getValue())) {
data = ENTTIY_NAME_TO_ID.get(id.getValue());
} else if (display==null) {
tag.put("display", display = new CompoundTag());
viaVersionTag.put("noDisplay", new ByteTag());
display.put("Name", new StringTag("§rSpawn " + id.getValue()));
}
}
}
item.setData((short)data);
}
ReplacementRegistry1_8to1_9.replace(item);
if (item.identifier()==373 || item.identifier()==438 || item.identifier()==441) {
int data = 0;
if (tag.contains("Potion")) {
StringTag potion = tag.get("Potion");
String potionName = potion.getValue().replace("minecraft:", "");
if (POTION_NAME_TO_ID.containsKey(potionName)) {
data = POTION_NAME_TO_ID.get(potionName);
}
if (item.identifier()==438) potionName += "_splash";
else if (item.identifier()==441) potionName += "_lingering";
if ((display==null || !display.contains("Name")) && POTION_NAME_INDEX.containsKey(potionName)) {
if (display==null) {
tag.put("display", display = new CompoundTag());
viaVersionTag.put("noDisplay", new ByteTag());
}
display.put("Name", new StringTag(POTION_NAME_INDEX.get(potionName)));
}
}
if (item.identifier()==438 || item.identifier()==441) {
item.setIdentifier(373);
data += 8192;
}
item.setData((short)data);
}
if (tag.contains("AttributeModifiers")) {
ListTag attributes = tag.get("AttributeModifiers");
for (int i = 0; i<attributes.size(); i++) {
CompoundTag attribute = attributes.get(i);
String name = (String) attribute.get("AttributeName").getValue();
if (!Protocol1_8To1_9.VALID_ATTRIBUTES.contains(name)) {
attributes.remove(attribute);
i--;
}
}
}
if (viaVersionTag.size()==2 && (short)viaVersionTag.get("id").getValue()==item.identifier() && (short)viaVersionTag.get("data").getValue()==item.data()) {
item.tag().remove("ViaRewind1_8to1_9");
if (item.tag().isEmpty()) item.setTag(null);
}
return item;
}
public static Item toServer(Item item) {
if (item==null) return null;
CompoundTag tag = item.tag();
if (item.identifier() == 383 && item.data() != 0) {
if (tag == null) item.setTag(tag = new CompoundTag());
if (!tag.contains("EntityTag") && ENTTIY_ID_TO_NAME.containsKey((int) item.data())) {
CompoundTag entityTag = new CompoundTag();
entityTag.put("id", new StringTag(ENTTIY_ID_TO_NAME.get((int) item.data())));
tag.put("EntityTag", entityTag);
}
item.setData((short) 0);
}
if (item.identifier() == 373 && (tag==null || !tag.contains("Potion"))) {
if (tag == null) item.setTag(tag = new CompoundTag());
if (item.data() >= 16384) {
item.setIdentifier(438);
item.setData((short) (item.data() - 8192));
}
String name = item.data() == 8192 ? "water" : potionNameFromDamage(item.data());
tag.put("Potion", new StringTag("minecraft:" + name));
item.setData((short) 0);
}
if (tag==null || !item.tag().contains("ViaRewind1_8to1_9")) return item;
CompoundTag viaVersionTag = tag.remove("ViaRewind1_8to1_9");
item.setIdentifier((short) viaVersionTag.get("id").getValue());
item.setData((Short) viaVersionTag.get("data").getValue());
if (viaVersionTag.contains("noDisplay")) tag.remove("display");
if (viaVersionTag.contains("Unbreakable")) {
tag.put("Unbreakable", viaVersionTag.get("Unbreakable").clone());
}
if (viaVersionTag.contains("displayName")) {
CompoundTag display = tag.get("display");
if (display==null) tag.put("display", display = new CompoundTag());
StringTag name = display.get("Name");
if (name==null) display.put("Name", new StringTag((String) viaVersionTag.get("displayName").getValue()));
else name.setValue((String) viaVersionTag.get("displayName").getValue());
} else if (tag.contains("display")) {
((CompoundTag)tag.get("display")).remove("Name");
}
if (viaVersionTag.contains("lore")) {
CompoundTag display = tag.get("display");
if (display==null) tag.put("display", display = new CompoundTag());
ListTag lore = display.get("Lore");
if (lore==null) display.put("Lore", new ListTag((List<Tag>) viaVersionTag.get("lore").getValue()));
else lore.setValue((List<Tag>) viaVersionTag.get("lore").getValue());
} else if (tag.contains("display")) {
((CompoundTag)tag.get("display")).remove("Lore");
}
tag.remove("AttributeModifiers");
if (viaVersionTag.contains("AttributeModifiers")) {
tag.put("AttributeModifiers", viaVersionTag.get("AttributeModifiers"));
}
return item;
}
}
@@ -1,105 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.items;
import com.viaversion.viarewind.replacement.Replacement;
import com.viaversion.viarewind.replacement.ReplacementRegistry;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viarewind.storage.BlockState;
public class ReplacementRegistry1_8to1_9 {
private static final ReplacementRegistry registry = new ReplacementRegistry();
static {
registry.registerItem(198, new Replacement(50, 0, "End Rod"));
registry.registerItem(434, new Replacement(391, "Beetroot"));
registry.registerItem(435, new Replacement(361, "Beetroot Seeds"));
registry.registerItem(436, new Replacement(282, "Beetroot Soup"));
registry.registerItem(432, new Replacement(322, "Chorus Fruit"));
registry.registerItem(433, new Replacement(393, "Popped Chorus Fruit"));
registry.registerItem(437, new Replacement(373, "Dragons Breath"));
registry.registerItem(443, new Replacement(299, "Elytra"));
registry.registerItem(426, new Replacement(410, "End Crystal"));
registry.registerItem(442, new Replacement(425, "Shield"));
registry.registerItem(439, new Replacement(262, "Spectral Arrow"));
registry.registerItem(440, new Replacement(262, "Tipped Arrow"));
registry.registerItem(444, new Replacement(333, "Spruce Boat"));
registry.registerItem(445, new Replacement(333, "Birch Boat"));
registry.registerItem(446, new Replacement(333, "Jungle Boat"));
registry.registerItem(447, new Replacement(333, "Acacia Boat"));
registry.registerItem(448, new Replacement(333, "Dark Oak Boat"));
registry.registerItem(204, new Replacement(43, 7, "Purpur Double Slab"));
registry.registerItem(205, new Replacement(44, 7, "Purpur Slab"));
registry.registerBlock(209, new Replacement(119));
registry.registerBlock(198, 0, new Replacement(50, 5));
registry.registerBlock(198, 1, new Replacement(50, 5));
registry.registerBlock(198, 2, new Replacement(50, 4));
registry.registerBlock(198, 3, new Replacement(50, 3));
registry.registerBlock(198, 4, new Replacement(50, 2));
registry.registerBlock(198, 5, new Replacement(50, 1));
registry.registerBlock(204, new Replacement(43, 7));
registry.registerBlock(205, 0, new Replacement(44, 7));
registry.registerBlock(205, 8, new Replacement(44, 15));
registry.registerBlock(207, new Replacement(141));
registry.registerBlock(137, new Replacement(137, 0));
registry.registerItemBlock(199, new Replacement(35, 10, "Chorus Plant"));
registry.registerItemBlock(200, new Replacement(35, 2, "Chorus Flower"));
registry.registerItemBlock(201, new Replacement(155, 0, "Purpur Block"));
registry.registerItemBlock(202, new Replacement(155, 2, "Purpur Pillar"));
registry.registerItemBlock(203, 0, new Replacement(156, 0, "Purpur Stairs"));
registry.registerItemBlock(203, 1, new Replacement(156, 1, "Purpur Stairs"));
registry.registerItemBlock(203, 2, new Replacement(156, 2, "Purpur Stairs"));
registry.registerItemBlock(203, 3, new Replacement(156, 3, "Purpur Stairs"));
registry.registerItemBlock(203, 4, new Replacement(156, 4, "Purpur Stairs"));
registry.registerItemBlock(203, 5, new Replacement(156, 5, "Purpur Stairs"));
registry.registerItemBlock(203, 6, new Replacement(156, 6, "Purpur Stairs"));
registry.registerItemBlock(203, 7, new Replacement(156, 7, "Purpur Stairs"));
registry.registerItemBlock(203, 8, new Replacement(156, 8, "Purpur Stairs"));
registry.registerItemBlock(206, new Replacement(121, 0, "Endstone Bricks"));
registry.registerItemBlock(207, new Replacement(141, "Beetroot Block"));
registry.registerItemBlock(208, new Replacement(2, 0, "Grass Path"));
registry.registerItemBlock(209, new Replacement(90, "End Gateway"));
registry.registerItemBlock(210, new Replacement(137, 0, "Repeating Command Block"));
registry.registerItemBlock(211, new Replacement(137, 0, "Chain Command Block"));
registry.registerItemBlock(212, new Replacement(79, 0, "Frosted Ice"));
registry.registerItemBlock(214, new Replacement(87, 0, "Nether Wart Block"));
registry.registerItemBlock(215, new Replacement(112, 0, "Red Nether Brick"));
registry.registerItemBlock(217, new Replacement(166, 0, "Structure Void"));
registry.registerItemBlock(255, new Replacement(137, 0, "Structure Block"));
registry.registerItemBlock(397, 5, new Replacement(397, 0, "Dragon Head"));
}
public static Item replace(Item item) {
return registry.replace(item);
}
public static int replace(int raw) {
int data = BlockState.extractData(raw);
Replacement replace = registry.replace(BlockState.extractId(raw), data);
if (replace == null) return raw;
return BlockState.stateToRaw(replace.getId(), replace.replaceData(data));
}
public static Replacement getReplacement(int id, int data) {
return registry.replace(id, data);
}
}
@@ -1,61 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.metadata;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.metadata.MetaIndex;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.Optional;
public class MetaIndex1_8to1_9 {
private static final HashMap<Pair<Entity1_10Types.EntityType, Integer>, MetaIndex> metadataRewrites = new HashMap<>();
static {
for (MetaIndex index : MetaIndex.values())
metadataRewrites.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
}
private static Optional<MetaIndex> getIndex(Entity1_10Types.EntityType type, int index) {
Pair pair = new Pair<>(type, index);
if (metadataRewrites.containsKey(pair)) {
return Optional.of(metadataRewrites.get(pair));
}
return Optional.empty();
}
public static MetaIndex searchIndex(Entity1_10Types.EntityType type, int index) {
Entity1_10Types.EntityType currentType = type;
do {
Optional<MetaIndex> optMeta = getIndex(currentType, index);
if (optMeta.isPresent()) {
return optMeta.get();
}
currentType = currentType.getParent();
} while (currentType != null);
return null;
}
}
@@ -1,124 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.metadata;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
import com.viaversion.viaversion.api.minecraft.EulerAngle;
import com.viaversion.viaversion.api.minecraft.Vector;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.metadata.MetaIndex;
import com.viaversion.viarewind.ViaRewind;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MetadataRewriter {
public static void transform(Entity1_10Types.EntityType type, List<Metadata> list) {
for (Metadata entry : new ArrayList<>(list)) {
MetaIndex metaIndex = MetaIndex1_8to1_9.searchIndex(type, entry.id());
try {
if (metaIndex != null) {
if (metaIndex.getOldType() == MetaType1_8.NonExistent || metaIndex.getNewType()==null) {
list.remove(entry);
continue;
}
Object value = entry.getValue();
entry.setMetaTypeUnsafe(metaIndex.getOldType());
entry.setId(metaIndex.getIndex());
switch (metaIndex.getNewType()) {
case Byte:
if (metaIndex.getOldType() == MetaType1_8.Byte) {
entry.setValue(value);
}
if (metaIndex.getOldType() == MetaType1_8.Int) {
entry.setValue(((Byte) value).intValue());
}
break;
case OptUUID:
if (metaIndex.getOldType()!=MetaType1_8.String) {
list.remove(entry);
break;
}
UUID owner = (UUID) value;
if (owner == null) entry.setValue("");
else entry.setValue(owner.toString());
break;
case BlockID:
list.remove(entry);
list.add(new Metadata(metaIndex.getIndex(), MetaType1_8.Short, ((Integer) value).shortValue()));
break;
case VarInt:
if (metaIndex.getOldType() == MetaType1_8.Byte) {
entry.setValue(((Integer) value).byteValue());
}
if (metaIndex.getOldType() == MetaType1_8.Short) {
entry.setValue(((Integer) value).shortValue());
}
if (metaIndex.getOldType() == MetaType1_8.Int) {
entry.setValue(value);
}
break;
case Float:
entry.setValue(value);
break;
case String:
entry.setValue(value);
break;
case Boolean:
if (metaIndex == MetaIndex.AGEABLE_AGE) entry.setValue((byte)((Boolean) value ? -1 : 0));
else entry.setValue((byte)((Boolean) value ? 1 : 0));
break;
case Slot:
entry.setValue(ItemRewriter.toClient((Item) value));
break;
case Position:
Vector vector = (Vector) value;
entry.setValue(vector);
break;
case Vector3F:
EulerAngle angle = (EulerAngle) value;
entry.setValue(angle);
break;
case Chat:
entry.setValue(value);
break;
default:
ViaRewind.getPlatform().getLogger().warning("[Out] Unhandled MetaDataType: " + metaIndex.getNewType());
list.remove(entry);
break;
}
if (!metaIndex.getOldType().type().getOutputClass().isAssignableFrom(entry.getValue().getClass())) {
list.remove(entry);
}
} else {
throw new Exception("Could not find valid metadata");
}
} catch (Exception e) {
list.remove(entry);
}
}
}
}
@@ -1,490 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.packets;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.Cooldown;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.EntityTracker;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.Levitation;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.PlayerPosition;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viaversion.api.minecraft.Vector;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.api.type.types.version.Types1_9;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import com.viaversion.viaversion.util.Pair;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.util.RelativeMoveUtil;
import com.viaversion.viarewind.utils.PacketUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class EntityPackets {
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
/* OUTGOING */
//Entity Status
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_STATUS, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
handler(packetWrapper -> {
byte status = packetWrapper.read(Type.BYTE);
if (status > 23) {
packetWrapper.cancel();
return;
}
packetWrapper.write(Type.BYTE, status);
});
}
});
//Entity Relative Move
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
int relX = packetWrapper.read(Type.SHORT);
int relY = packetWrapper.read(Type.SHORT);
int relZ = packetWrapper.read(Type.SHORT);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
replacement.relMove(relX / 4096.0, relY / 4096.0, relZ / 4096.0);
return;
}
Vector[] moves = RelativeMoveUtil.calculateRelativeMoves(packetWrapper.user(), entityId, relX, relY, relZ);
packetWrapper.write(Type.BYTE, (byte) moves[0].blockX());
packetWrapper.write(Type.BYTE, (byte) moves[0].blockY());
packetWrapper.write(Type.BYTE, (byte) moves[0].blockZ());
boolean onGround = packetWrapper.passthrough(Type.BOOLEAN);
if (moves.length > 1) {
PacketWrapper secondPacket = PacketWrapper.create(0x15, null, packetWrapper.user());
secondPacket.write(Type.VAR_INT, packetWrapper.get(Type.VAR_INT, 0));
secondPacket.write(Type.BYTE, (byte) moves[1].blockX());
secondPacket.write(Type.BYTE, (byte) moves[1].blockY());
secondPacket.write(Type.BYTE, (byte) moves[1].blockZ());
secondPacket.write(Type.BOOLEAN, onGround);
PacketUtil.sendPacket(secondPacket, Protocol1_8To1_9.class);
}
});
}
});
//Entity Relative Move And Look
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_POSITION_AND_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
int relX = packetWrapper.read(Type.SHORT);
int relY = packetWrapper.read(Type.SHORT);
int relZ = packetWrapper.read(Type.SHORT);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
replacement.relMove(relX / 4096.0, relY / 4096.0, relZ / 4096.0);
replacement.setYawPitch(packetWrapper.read(Type.BYTE) * 360f / 256, packetWrapper.read(Type.BYTE) * 360f / 256);
return;
}
Vector[] moves = RelativeMoveUtil.calculateRelativeMoves(packetWrapper.user(), entityId, relX, relY, relZ);
packetWrapper.write(Type.BYTE, (byte) moves[0].blockX());
packetWrapper.write(Type.BYTE, (byte) moves[0].blockY());
packetWrapper.write(Type.BYTE, (byte) moves[0].blockZ());
byte yaw = packetWrapper.passthrough(Type.BYTE);
byte pitch = packetWrapper.passthrough(Type.BYTE);
boolean onGround = packetWrapper.passthrough(Type.BOOLEAN);
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
if (type == Entity1_10Types.EntityType.BOAT) {
yaw -= 64;
packetWrapper.set(Type.BYTE, 3, yaw);
}
if (moves.length > 1) {
PacketWrapper secondPacket = PacketWrapper.create(0x17, null, packetWrapper.user());
secondPacket.write(Type.VAR_INT, packetWrapper.get(Type.VAR_INT, 0));
secondPacket.write(Type.BYTE, (byte) moves[1].blockX());
secondPacket.write(Type.BYTE, (byte) moves[1].blockY());
secondPacket.write(Type.BYTE, (byte) moves[1].blockZ());
secondPacket.write(Type.BYTE, yaw);
secondPacket.write(Type.BYTE, pitch);
secondPacket.write(Type.BOOLEAN, onGround);
PacketUtil.sendPacket(secondPacket, Protocol1_8To1_9.class);
}
});
}
});
//Entity Look
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.BOOLEAN);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int yaw = packetWrapper.get(Type.BYTE, 0);
int pitch = packetWrapper.get(Type.BYTE, 1);
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
if (type == Entity1_10Types.EntityType.BOAT) {
byte yaw = packetWrapper.get(Type.BYTE, 0);
yaw -= 64;
packetWrapper.set(Type.BYTE, 0, yaw);
}
});
}
});
//Entity
//Vehicle Move -> Entity Teleport
protocol.registerClientbound(ClientboundPackets1_9.VEHICLE_MOVE, ClientboundPackets1_8.ENTITY_TELEPORT, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
int vehicle = tracker.getVehicle(tracker.getPlayerId());
if (vehicle == -1) packetWrapper.cancel();
packetWrapper.write(Type.VAR_INT, vehicle);
});
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.FLOAT, Protocol1_8To1_9.DEGREES_TO_ANGLE);
map(Type.FLOAT, Protocol1_8To1_9.DEGREES_TO_ANGLE);
handler(packetWrapper -> {
if (packetWrapper.isCancelled()) return;
PlayerPosition position = packetWrapper.user().get(PlayerPosition.class);
double x = packetWrapper.get(Type.INT, 0) / 32d;
double y = packetWrapper.get(Type.INT, 1) / 32d;
double z = packetWrapper.get(Type.INT, 2) / 32d;
position.setPos(x, y, z);
});
create(Type.BOOLEAN, true);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
if (type == Entity1_10Types.EntityType.BOAT) {
byte yaw = packetWrapper.get(Type.BYTE, 1);
yaw -= 64;
packetWrapper.set(Type.BYTE, 0, yaw);
int y = packetWrapper.get(Type.INT, 1);
y += 10;
packetWrapper.set(Type.INT, 1, y);
}
});
}
});
//Use Bed
//Destroy Entities
protocol.registerClientbound(ClientboundPackets1_9.DESTROY_ENTITIES, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT_ARRAY_PRIMITIVE);
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
for (int entityId : packetWrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0))
tracker.removeEntity(entityId);
});
}
});
//Remove Entity Effect
protocol.registerClientbound(ClientboundPackets1_9.REMOVE_ENTITY_EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
handler(packetWrapper -> {
int id = packetWrapper.get(Type.BYTE, 0);
if (id > 23) packetWrapper.cancel();
if (id == 25) {
if (packetWrapper.get(Type.VAR_INT, 0) != packetWrapper.user().get(EntityTracker.class).getPlayerId())
return;
Levitation levitation = packetWrapper.user().get(Levitation.class);
levitation.setActive(false);
}
});
}
});
//Entity Head Look
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_HEAD_LOOK, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int yaw = packetWrapper.get(Type.BYTE, 0);
replacement.setHeadYaw(yaw * 360f / 256);
}
});
}
});
//Entity Metadata
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_METADATA, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Types1_9.METADATA_LIST, Types1_8.METADATA_LIST);
handler(wrapper -> {
List<Metadata> metadataList = wrapper.get(Types1_8.METADATA_LIST, 0);
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
if (tracker.getClientEntityTypes().containsKey(entityId)) {
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
if (metadataList.isEmpty()) wrapper.cancel();
} else {
tracker.addMetadataToBuffer(entityId, metadataList);
wrapper.cancel();
}
});
}
});
//Attach Entity
protocol.registerClientbound(ClientboundPackets1_9.ATTACH_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.INT);
create(Type.BOOLEAN, true);
}
});
//Entity Velocity
//Entity Equipment
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_EQUIPMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
handler(packetWrapper -> {
// todo check if this is correct for the own player
int slot = packetWrapper.read(Type.VAR_INT);
if (slot == 1) {
packetWrapper.cancel();
} else if (slot > 1) {
slot -= 1;
}
packetWrapper.write(Type.SHORT, (short) slot);
});
map(Type.ITEM);
handler(packetWrapper -> packetWrapper.set(Type.ITEM, 0, ItemRewriter.toClient(packetWrapper.get(Type.ITEM, 0))));
}
});
//Set Passengers
protocol.registerClientbound(ClientboundPackets1_9.SET_PASSENGERS, null, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
EntityTracker entityTracker = packetWrapper.user().get(EntityTracker.class);
int vehicle = packetWrapper.read(Type.VAR_INT);
int count = packetWrapper.read(Type.VAR_INT);
ArrayList<Integer> passengers = new ArrayList<>();
for (int i = 0; i < count; i++) passengers.add(packetWrapper.read(Type.VAR_INT));
List<Integer> oldPassengers = entityTracker.getPassengers(vehicle);
entityTracker.setPassengers(vehicle, passengers);
if (!oldPassengers.isEmpty()) {
for (Integer passenger : oldPassengers) {
PacketWrapper detach = PacketWrapper.create(0x1B, null, packetWrapper.user());
detach.write(Type.INT, passenger);
detach.write(Type.INT, -1);
detach.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(detach, Protocol1_8To1_9.class);
}
}
for (int i = 0; i < count; i++) {
int v = i == 0 ? vehicle : passengers.get(i - 1);
int p = passengers.get(i);
PacketWrapper attach = PacketWrapper.create(0x1B, null, packetWrapper.user());
attach.write(Type.INT, p);
attach.write(Type.INT, v);
attach.write(Type.BOOLEAN, false);
PacketUtil.sendPacket(attach, Protocol1_8To1_9.class);
}
});
}
});
//Collect Item
//Entity Teleport
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_TELEPORT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.BOOLEAN);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
Entity1_10Types.EntityType type = packetWrapper.user().get(EntityTracker.class).getClientEntityTypes().get(entityId);
if (type == Entity1_10Types.EntityType.BOAT) {
byte yaw = packetWrapper.get(Type.BYTE, 1);
yaw -= 64;
packetWrapper.set(Type.BYTE, 0, yaw);
int y = packetWrapper.get(Type.INT, 1);
y += 10;
packetWrapper.set(Type.INT, 1, y);
}
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
packetWrapper.user().get(EntityTracker.class).resetEntityOffset(entityId);
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
EntityReplacement replacement = tracker.getEntityReplacement(entityId);
if (replacement != null) {
packetWrapper.cancel();
int x = packetWrapper.get(Type.INT, 0);
int y = packetWrapper.get(Type.INT, 1);
int z = packetWrapper.get(Type.INT, 2);
int yaw = packetWrapper.get(Type.BYTE, 0);
int pitch = packetWrapper.get(Type.BYTE, 1);
replacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
replacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
}
});
}
});
//Entity Properties
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_PROPERTIES, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.INT);
handler(packetWrapper -> {
boolean player = packetWrapper.get(Type.VAR_INT, 0) == packetWrapper.user().get(EntityTracker.class).getPlayerId();
int size = packetWrapper.get(Type.INT, 0);
int removed = 0;
for (int i = 0; i < size; i++) {
String key = packetWrapper.read(Type.STRING);
boolean skip = !Protocol1_8To1_9.VALID_ATTRIBUTES.contains(key);
double value = packetWrapper.read(Type.DOUBLE);
int modifiersize = packetWrapper.read(Type.VAR_INT);
if (!skip) {
packetWrapper.write(Type.STRING, key);
packetWrapper.write(Type.DOUBLE, value);
packetWrapper.write(Type.VAR_INT, modifiersize);
} else {
removed++;
}
ArrayList<Pair<Byte, Double>> modifiers = new ArrayList<>();
for (int j = 0; j < modifiersize; j++) {
UUID uuid = packetWrapper.read(Type.UUID);
double amount = packetWrapper.read(Type.DOUBLE);
byte operation = packetWrapper.read(Type.BYTE);
modifiers.add(new Pair<>(operation, amount));
if (skip) continue;
packetWrapper.write(Type.UUID, uuid);
packetWrapper.write(Type.DOUBLE, amount);
packetWrapper.write(Type.BYTE, operation);
}
if (player && key.equals("generic.attackSpeed")) {
packetWrapper.user().get(Cooldown.class).setAttackSpeed(value, modifiers);
}
}
packetWrapper.set(Type.INT, 0, size - removed);
});
}
});
//Entity Effect
protocol.registerClientbound(ClientboundPackets1_9.ENTITY_EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.VAR_INT);
map(Type.BYTE);
handler(packetWrapper -> {
int id = packetWrapper.get(Type.BYTE, 0);
if (id > 23) packetWrapper.cancel();
if (id == 25) {
if (packetWrapper.get(Type.VAR_INT, 0) != packetWrapper.user().get(EntityTracker.class).getPlayerId())
return;
Levitation levitation = packetWrapper.user().get(Levitation.class);
levitation.setActive(true);
levitation.setAmplifier(packetWrapper.get(Type.BYTE, 1));
}
});
}
});
}
}
@@ -1,199 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.packets;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.Windows;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonParser;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
public class InventoryPackets {
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
/* OUTGOING */
//Confirm Transaction
//Close Window
protocol.registerClientbound(ClientboundPackets1_9.CLOSE_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
packetWrapper.user().get(Windows.class).remove(windowsId);
});
}
});
//Open Window
protocol.registerClientbound(ClientboundPackets1_9.OPEN_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.STRING);
map(Type.COMPONENT);
map(Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
String type = packetWrapper.get(Type.STRING, 0);
if (type.equals("EntityHorse")) packetWrapper.passthrough(Type.INT);
});
handler(packetWrapper -> {
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
String windowType = packetWrapper.get(Type.STRING, 0);
packetWrapper.user().get(Windows.class).put(windowId, windowType);
});
handler(packetWrapper -> {
String type = packetWrapper.get(Type.STRING, 0);
if (type.equalsIgnoreCase("minecraft:shulker_box")) {
packetWrapper.set(Type.STRING, 0, type = "minecraft:container");
}
String name = packetWrapper.get(Type.COMPONENT, 0).toString();
if (name.equalsIgnoreCase("{\"translate\":\"container.shulkerBox\"}")) {
packetWrapper.set(Type.COMPONENT, 0, JsonParser.parseString("{\"text\":\"Shulker Box\"}"));
}
});
}
});
//Window Items
protocol.registerClientbound(ClientboundPackets1_9.WINDOW_ITEMS, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
Item[] items = packetWrapper.read(Type.ITEM_ARRAY);
for (int i = 0; i < items.length; i++) {
items[i] = ItemRewriter.toClient(items[i]);
}
if (windowId == 0 && items.length == 46) {
Item[] old = items;
items = new Item[45];
System.arraycopy(old, 0, items, 0, 45);
} else {
String type = packetWrapper.user().get(Windows.class).get(windowId);
if (type != null && type.equalsIgnoreCase("minecraft:brewing_stand")) {
System.arraycopy(items, 0, packetWrapper.user().get(Windows.class).getBrewingItems(windowId), 0, 4);
Windows.updateBrewingStand(packetWrapper.user(), items[4], windowId);
Item[] old = items;
items = new Item[old.length - 1];
System.arraycopy(old, 0, items, 0, 4);
System.arraycopy(old, 5, items, 4, old.length - 5);
}
}
packetWrapper.write(Type.ITEM_ARRAY, items);
});
}
});
//Window Property
//Set Slot
protocol.registerClientbound(ClientboundPackets1_9.SET_SLOT, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.SHORT);
map(Type.ITEM);
handler(packetWrapper -> {
packetWrapper.set(Type.ITEM, 0, ItemRewriter.toClient(packetWrapper.get(Type.ITEM, 0)));
byte windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0).byteValue();
short slot = packetWrapper.get(Type.SHORT, 0);
if (windowId == 0 && slot == 45) {
packetWrapper.cancel();
return;
}
String type = packetWrapper.user().get(Windows.class).get(windowId);
if (type == null) return;
if (type.equalsIgnoreCase("minecraft:brewing_stand")) {
if (slot > 4) {
packetWrapper.set(Type.SHORT, 0, slot -= 1);
} else if (slot == 4) {
packetWrapper.cancel();
Windows.updateBrewingStand(packetWrapper.user(), packetWrapper.get(Type.ITEM, 0), windowId);
} else {
packetWrapper.user().get(Windows.class).getBrewingItems(windowId)[slot] = packetWrapper.get(Type.ITEM, 0);
}
}
});
}
});
/* INCMOING */
//Close Window
protocol.registerServerbound(ServerboundPackets1_8.CLOSE_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
short windowsId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
packetWrapper.user().get(Windows.class).remove(windowsId);
});
}
});
//Click Window
protocol.registerServerbound(ServerboundPackets1_8.CLICK_WINDOW, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.SHORT);
map(Type.BYTE);
map(Type.SHORT);
map(Type.BYTE, Type.VAR_INT);
map(Type.ITEM);
handler(packetWrapper -> packetWrapper.set(Type.ITEM, 0, ItemRewriter.toServer(packetWrapper.get(Type.ITEM, 0))));
handler(packetWrapper -> {
short windowId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
Windows windows = packetWrapper.user().get(Windows.class);
String type = windows.get(windowId);
if (type == null) return;
if (type.equalsIgnoreCase("minecraft:brewing_stand")) {
short slot = packetWrapper.get(Type.SHORT, 0);
if (slot > 3) {
packetWrapper.set(Type.SHORT, 0, slot += 1);
}
}
});
}
});
//Creative Inventory Action
protocol.registerServerbound(ServerboundPackets1_8.CREATIVE_INVENTORY_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.SHORT);
map(Type.ITEM);
handler(packetWrapper -> packetWrapper.set(Type.ITEM, 0, ItemRewriter.toServer(packetWrapper.get(Type.ITEM, 0))));
}
});
//Enchant Item
}
}
@@ -1,644 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.packets;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.*;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.*;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_8;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.items.ItemRewriter;
import com.viaversion.viarewind.utils.ChatUtil;
import com.viaversion.viarewind.utils.PacketUtil;
import java.util.ArrayList;
import java.util.UUID;
public class PlayerPackets {
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
/* OUTGOING */
//Animation
//Statistics
//Boss Bar
protocol.registerClientbound(ClientboundPackets1_9.BOSSBAR, null, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
UUID uuid = packetWrapper.read(Type.UUID);
int action = packetWrapper.read(Type.VAR_INT);
BossBarStorage bossBarStorage = packetWrapper.user().get(BossBarStorage.class);
if (action == 0) {
bossBarStorage.add(uuid, ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT)), packetWrapper.read(Type.FLOAT));
packetWrapper.read(Type.VAR_INT);
packetWrapper.read(Type.VAR_INT);
packetWrapper.read(Type.UNSIGNED_BYTE);
} else if (action == 1) {
bossBarStorage.remove(uuid);
} else if (action == 2) {
bossBarStorage.updateHealth(uuid, packetWrapper.read(Type.FLOAT));
} else if (action == 3) {
String title = ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT));
bossBarStorage.updateTitle(uuid, title);
}
});
}
});
//Tab-Complete
//Chat Message
//Set Cooldown
protocol.cancelClientbound(ClientboundPackets1_9.COOLDOWN);
//Custom Payload
protocol.registerClientbound(ClientboundPackets1_9.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String channel = packetWrapper.get(Type.STRING, 0);
if (channel.equalsIgnoreCase("MC|TrList")) {
packetWrapper.passthrough(Type.INT); //Window Id
int size;
if (packetWrapper.isReadable(Type.BYTE, 0)) {
size = packetWrapper.passthrough(Type.BYTE);
} else {
size = packetWrapper.passthrough(Type.UNSIGNED_BYTE);
}
for (int i = 0; i < size; i++) {
packetWrapper.write(Type.ITEM, ItemRewriter.toClient(packetWrapper.read(Type.ITEM))); //Buy Item 1
packetWrapper.write(Type.ITEM, ItemRewriter.toClient(packetWrapper.read(Type.ITEM))); //Buy Item 3
boolean has3Items = packetWrapper.passthrough(Type.BOOLEAN);
if (has3Items) {
packetWrapper.write(Type.ITEM, ItemRewriter.toClient(packetWrapper.read(Type.ITEM))); //Buy Item 2
}
packetWrapper.passthrough(Type.BOOLEAN); //Unavailable
packetWrapper.passthrough(Type.INT); //Uses
packetWrapper.passthrough(Type.INT); //Max Uses
}
} else if (channel.equalsIgnoreCase("MC|BOpen")) {
packetWrapper.read(Type.VAR_INT);
}
});
}
});
//Disconnect
//Change Game State
protocol.registerClientbound(ClientboundPackets1_9.GAME_EVENT, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.FLOAT);
handler(packetWrapper -> {
int reason = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
if (reason == 3)
packetWrapper.user().get(EntityTracker.class).setPlayerGamemode(packetWrapper.get(Type.FLOAT, 0).intValue());
});
}
});
//Join Game
protocol.registerClientbound(ClientboundPackets1_9.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.UNSIGNED_BYTE);
map(Type.BYTE);
map(Type.UNSIGNED_BYTE);
map(Type.UNSIGNED_BYTE);
map(Type.STRING);
map(Type.BOOLEAN);
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.setPlayerId(packetWrapper.get(Type.INT, 0));
tracker.setPlayerGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 0));
tracker.getClientEntityTypes().put(tracker.getPlayerId(), Entity1_10Types.EntityType.ENTITY_HUMAN);
});
handler(packetWrapper -> {
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
world.setEnvironment(packetWrapper.get(Type.BYTE, 0));
});
}
});
//Open Sign Editor
//Player Abilities
//Player List Item
//Player Position And Look
protocol.registerClientbound(ClientboundPackets1_9.PLAYER_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.BYTE);
handler(packetWrapper -> {
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
int teleportId = packetWrapper.read(Type.VAR_INT);
pos.setConfirmId(teleportId);
byte flags = packetWrapper.get(Type.BYTE, 0);
double x = packetWrapper.get(Type.DOUBLE, 0);
double y = packetWrapper.get(Type.DOUBLE, 1);
double z = packetWrapper.get(Type.DOUBLE, 2);
float yaw = packetWrapper.get(Type.FLOAT, 0);
float pitch = packetWrapper.get(Type.FLOAT, 1);
packetWrapper.set(Type.BYTE, 0, (byte) 0);
if (flags != 0) {
if ((flags & 0x01) != 0) {
x += pos.getPosX();
packetWrapper.set(Type.DOUBLE, 0, x);
}
if ((flags & 0x02) != 0) {
y += pos.getPosY();
packetWrapper.set(Type.DOUBLE, 1, y);
}
if ((flags & 0x04) != 0) {
z += pos.getPosZ();
packetWrapper.set(Type.DOUBLE, 2, z);
}
if ((flags & 0x08) != 0) {
yaw += pos.getYaw();
packetWrapper.set(Type.FLOAT, 0, yaw);
}
if ((flags & 0x10) != 0) {
pitch += pos.getPitch();
packetWrapper.set(Type.FLOAT, 1, pitch);
}
}
pos.setPos(x, y, z);
pos.setYaw(yaw);
pos.setPitch(pitch);
});
}
});
//Resource Pack Send
//Respawn
protocol.registerClientbound(ClientboundPackets1_9.RESPAWN, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.UNSIGNED_BYTE);
map(Type.UNSIGNED_BYTE);
map(Type.STRING);
handler(packetWrapper -> packetWrapper.user().get(EntityTracker.class).setPlayerGamemode(packetWrapper.get(Type.UNSIGNED_BYTE, 1)));
handler(packetWrapper -> {
packetWrapper.user().get(BossBarStorage.class).updateLocation();
packetWrapper.user().get(BossBarStorage.class).changeWorld();
});
handler(packetWrapper -> {
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
world.setEnvironment(packetWrapper.get(Type.INT, 0));
});
}
});
//Camera
//Held Item Change
//Set Experience
//Update Health
//Spawn Position
//Title
//Player List Header And Footer
/* INCMOING */
//Chat Message
protocol.registerServerbound(ServerboundPackets1_8.CHAT_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String msg = packetWrapper.get(Type.STRING, 0);
if (msg.toLowerCase().startsWith("/offhand")) {
packetWrapper.cancel();
PacketWrapper swapItems = PacketWrapper.create(0x13, null, packetWrapper.user());
swapItems.write(Type.VAR_INT, 6);
swapItems.write(Type.POSITION, new Position(0, 0, 0));
swapItems.write(Type.BYTE, (byte) 255);
PacketUtil.sendToServer(swapItems, Protocol1_8To1_9.class, true, true);
}
});
}
});
//Confirm Transaction
//Use Entity
protocol.registerServerbound(ServerboundPackets1_8.INTERACT_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.VAR_INT);
handler(packetWrapper -> {
int type = packetWrapper.get(Type.VAR_INT, 1);
if (type == 2) {
packetWrapper.passthrough(Type.FLOAT);
packetWrapper.passthrough(Type.FLOAT);
packetWrapper.passthrough(Type.FLOAT);
}
if (type == 2 || type == 0) {
packetWrapper.write(Type.VAR_INT, 0);
}
});
}
});
//Player
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_MOVEMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.BOOLEAN);
handler(packetWrapper -> {
//Sending any queued animations.
PacketWrapper animation = null;
while((animation = ((Protocol1_8To1_9)protocol).animationsToSend.poll()) != null) {
PacketUtil.sendToServer(animation, Protocol1_8To1_9.class, true, true);
}
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
int playerId = tracker.getPlayerId();
if (tracker.isInsideVehicle(playerId)) packetWrapper.cancel();
});
}
});
//Player Position
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_POSITION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.BOOLEAN);
handler(packetWrapper -> {
//Sending any queued animations.
PacketWrapper animation = null;
while((animation = ((Protocol1_8To1_9)protocol).animationsToSend.poll()) != null) {
PacketUtil.sendToServer(animation, Protocol1_8To1_9.class,
true, true);
}
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
if (pos.getConfirmId() != -1) return;
pos.setPos(packetWrapper.get(Type.DOUBLE, 0), packetWrapper.get(Type.DOUBLE, 1),
packetWrapper.get(Type.DOUBLE, 2));
pos.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
});
handler(packetWrapper -> packetWrapper.user().get(BossBarStorage.class).updateLocation());
}
});
//Player Look
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.BOOLEAN);
handler(packetWrapper -> {
//Sending any queued animations.
PacketWrapper animation = null;
while((animation = ((Protocol1_8To1_9)protocol).animationsToSend.poll()) != null) {
PacketUtil.sendToServer(animation, Protocol1_8To1_9.class, true, true);
}
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
if (pos.getConfirmId() != -1) return;
pos.setYaw(packetWrapper.get(Type.FLOAT, 0));
pos.setPitch(packetWrapper.get(Type.FLOAT, 1));
pos.setOnGround(packetWrapper.get(Type.BOOLEAN, 0));
});
handler(packetWrapper -> packetWrapper.user().get(BossBarStorage.class).updateLocation());
}
});
//Player Position And Look
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_POSITION_AND_ROTATION, new PacketHandlers() {
@Override
public void register() {
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.DOUBLE);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.BOOLEAN);
handler(packetWrapper -> {
//Sending any queued animations.
PacketWrapper animation = null;
while((animation = ((Protocol1_8To1_9)protocol).animationsToSend.poll()) != null) {
PacketUtil.sendToServer(animation, Protocol1_8To1_9.class, true, true);
}
double x = packetWrapper.get(Type.DOUBLE, 0);
double y = packetWrapper.get(Type.DOUBLE, 1);
double z = packetWrapper.get(Type.DOUBLE, 2);
float yaw = packetWrapper.get(Type.FLOAT, 0);
float pitch = packetWrapper.get(Type.FLOAT, 1);
boolean onGround = packetWrapper.get(Type.BOOLEAN, 0);
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
if (pos.getConfirmId() != -1) {
if (pos.getPosX() == x && pos.getPosY() == y && pos.getPosZ() == z
&& pos.getYaw() == yaw && pos.getPitch() == pitch) {
PacketWrapper confirmTeleport = packetWrapper.create(0x00);
confirmTeleport.write(Type.VAR_INT, pos.getConfirmId());
PacketUtil.sendToServer(confirmTeleport,
Protocol1_8To1_9.class, true, true);
pos.setConfirmId(-1);
}
} else {
pos.setPos(x, y, z);
pos.setYaw(yaw);
pos.setPitch(pitch);
pos.setOnGround(onGround);
packetWrapper.user().get(BossBarStorage.class).updateLocation();
}
});
}
});
//Player Digging
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_DIGGING, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.POSITION);
handler(packetWrapper -> {
int state = packetWrapper.get(Type.VAR_INT, 0);
if (state == 0) {
packetWrapper.user().get(BlockPlaceDestroyTracker.class).setMining(true);
} else if (state == 2) {
BlockPlaceDestroyTracker tracker = packetWrapper.user().get(BlockPlaceDestroyTracker.class);
tracker.setMining(false);
tracker.setLastMining(System.currentTimeMillis() + 100);
packetWrapper.user().get(Cooldown.class).setLastHit(0);
} else if (state == 1) {
BlockPlaceDestroyTracker tracker = packetWrapper.user().get(BlockPlaceDestroyTracker.class);
tracker.setMining(false);
tracker.setLastMining(0);
packetWrapper.user().get(Cooldown.class).hit();
}
});
}
});
//Player Block Placement
protocol.registerServerbound(ServerboundPackets1_8.PLAYER_BLOCK_PLACEMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION);
map(Type.BYTE, Type.VAR_INT);
map(Type.ITEM, Type.NOTHING);
create(Type.VAR_INT, 0); //Main Hand
map(Type.BYTE, Type.UNSIGNED_BYTE);
map(Type.BYTE, Type.UNSIGNED_BYTE);
map(Type.BYTE, Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
if (packetWrapper.get(Type.VAR_INT, 0) == -1) {
packetWrapper.cancel();
PacketWrapper useItem = PacketWrapper.create(0x1D, null, packetWrapper.user());
useItem.write(Type.VAR_INT, 0);
PacketUtil.sendToServer(useItem, Protocol1_8To1_9.class, true, true);
}
});
handler(packetWrapper -> {
if (packetWrapper.get(Type.VAR_INT, 0) != -1) {
packetWrapper.user().get(BlockPlaceDestroyTracker.class).place();
}
});
}
});
//Held Item Change
protocol.registerServerbound(ServerboundPackets1_8.HELD_ITEM_CHANGE, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> packetWrapper.user().get(Cooldown.class).hit());
}
});
//Animation
protocol.registerServerbound(ServerboundPackets1_8.ANIMATION, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
/* We have to add ArmAnimation to a queue to be sent on PacketPlayInFlying. In 1.9,
* PacketPlayInArmAnimation is sent after PacketPlayInUseEntity, not before like it used to be.
* However, all packets are sent before PacketPlayInFlying. We'd just do a normal delay, but
* it would cause the packet to be sent after PacketPlayInFlying, potentially false flagging
* anticheats that check for this behavior from clients. Since all packets are sent before
* PacketPlayInFlying, if we queue it to be sent right before PacketPlayInFlying is processed,
* we can be certain it will be sent after PacketPlayInUseEntity */
packetWrapper.cancel();
final PacketWrapper delayedPacket = PacketWrapper.create(0x1A,
null, packetWrapper.user());
delayedPacket.write(Type.VAR_INT, 0); //Main Hand
((Protocol1_8To1_9)protocol).animationsToSend.add(delayedPacket);
});
handler(packetWrapper -> {
packetWrapper.user().get(BlockPlaceDestroyTracker.class).updateMining();
packetWrapper.user().get(Cooldown.class).hit();
});
}
});
//Entity Action
protocol.registerServerbound(ServerboundPackets1_8.ENTITY_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.VAR_INT);
map(Type.VAR_INT);
handler(packetWrapper -> {
int action = packetWrapper.get(Type.VAR_INT, 1);
if (action == 6) {
packetWrapper.set(Type.VAR_INT, 1, 7);
} else if (action == 0) {
PlayerPosition pos = packetWrapper.user().get(PlayerPosition.class);
if (!pos.isOnGround()) {
PacketWrapper elytra = PacketWrapper.create(0x14, null, packetWrapper.user());
elytra.write(Type.VAR_INT, packetWrapper.get(Type.VAR_INT, 0));
elytra.write(Type.VAR_INT, 8);
elytra.write(Type.VAR_INT, 0);
PacketUtil.sendToServer(elytra, Protocol1_8To1_9.class, true, false);
}
}
});
}
});
//Steer Vehicle
protocol.registerServerbound(ServerboundPackets1_8.STEER_VEHICLE, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
int playerId = tracker.getPlayerId();
int vehicle = tracker.getVehicle(playerId);
if (vehicle != -1 && tracker.getClientEntityTypes().get(vehicle) == Entity1_10Types.EntityType.BOAT) {
PacketWrapper steerBoat = PacketWrapper.create(0x11, null, packetWrapper.user());
float left = packetWrapper.get(Type.FLOAT, 0);
float forward = packetWrapper.get(Type.FLOAT, 1);
steerBoat.write(Type.BOOLEAN, forward != 0.0f || left < 0.0f);
steerBoat.write(Type.BOOLEAN, forward != 0.0f || left > 0.0f);
PacketUtil.sendToServer(steerBoat, Protocol1_8To1_9.class);
}
});
}
});
//Update Sign
protocol.registerServerbound(ServerboundPackets1_8.UPDATE_SIGN, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION);
handler(packetWrapper -> {
for (int i = 0; i < 4; i++) {
packetWrapper.write(Type.STRING, ChatUtil.jsonToLegacy(packetWrapper.read(Type.COMPONENT)));
}
});
}
});
//Player Abilities
//Tab Complete
protocol.registerServerbound(ServerboundPackets1_8.TAB_COMPLETE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> packetWrapper.write(Type.BOOLEAN, false));
map(Type.OPTIONAL_POSITION);
}
});
//Client Settings
protocol.registerServerbound(ServerboundPackets1_8.CLIENT_SETTINGS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
map(Type.BYTE);
map(Type.BYTE, Type.VAR_INT);
map(Type.BOOLEAN);
map(Type.UNSIGNED_BYTE);
create(Type.VAR_INT, 1);
handler(packetWrapper -> {
short flags = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
PacketWrapper updateSkin = PacketWrapper.create(0x1C, null, packetWrapper.user());
updateSkin.write(Type.VAR_INT, packetWrapper.user().get(EntityTracker.class).getPlayerId());
ArrayList<Metadata> metadata = new ArrayList<>();
metadata.add(new Metadata(10, MetaType1_8.Byte, (byte) flags));
updateSkin.write(Types1_8.METADATA_LIST, metadata);
PacketUtil.sendPacket(updateSkin, Protocol1_8To1_9.class);
});
}
});
//Client Status
//Custom Payload
protocol.registerServerbound(ServerboundPackets1_8.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String channel = packetWrapper.get(Type.STRING, 0);
if (channel.equalsIgnoreCase("MC|BEdit") || channel.equalsIgnoreCase("MC|BSign")) {
Item book = packetWrapper.passthrough(Type.ITEM);
book.setIdentifier(386);
CompoundTag tag = book.tag();
if (tag.contains("pages")) {
ListTag pages = tag.get("pages");
if (pages.size() > ViaRewind.getConfig().getMaxBookPages()) {
packetWrapper.user().disconnect("Too many book pages");
return;
}
for (int i = 0; i < pages.size(); i++) {
StringTag page = pages.get(i);
String value = page.getValue();
if (value.length() > ViaRewind.getConfig().getMaxBookPageSize()) {
packetWrapper.user().disconnect("Book page too large");
return;
}
value = ChatUtil.jsonToLegacy(value);
page.setValue(value);
}
}
} else if (channel.equalsIgnoreCase("MC|AdvCdm")) {
packetWrapper.set(Type.STRING, 0, channel = "MC|AdvCmd");
}
});
}
});
//Spectate
//Resource Pack Status
}
}
@@ -1,65 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.packets;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
public class ScoreboardPackets {
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
/* OUTGOING */
//Display Scoreboard
//Scoreboard Objective
//Scoreboard Team
protocol.registerClientbound(ClientboundPackets1_9.TEAMS, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
map(Type.BYTE);
handler(packetWrapper -> {
byte mode = packetWrapper.get(Type.BYTE, 0);
if (mode == 0 || mode == 2) {
packetWrapper.passthrough(Type.STRING); //Display Name
packetWrapper.passthrough(Type.STRING); //Prefix
packetWrapper.passthrough(Type.STRING); //Suffix
packetWrapper.passthrough(Type.BYTE); //Friendly Flags
packetWrapper.passthrough(Type.STRING); //Name Tag Visibility
packetWrapper.read(Type.STRING); //Skip Collision Rule
packetWrapper.passthrough(Type.BYTE); //Friendly Flags
}
if (mode == 0 || mode == 3 || mode == 4) {
packetWrapper.passthrough(Type.STRING_ARRAY);
}
});
}
});
//Update Score
}
}
@@ -1,281 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.packets;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viarewind.replacement.Replacement;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.entityreplacement.ShulkerBulletReplacement;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.entityreplacement.ShulkerReplacement;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.storage.EntityTracker;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.api.type.types.version.Types1_9;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.items.ReplacementRegistry1_8to1_9;
import com.viaversion.viarewind.utils.PacketUtil;
import java.util.List;
public class SpawnPackets {
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
/* OUTGOING */
//Spawn Object
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.UUID, Type.NOTHING);
map(Type.BYTE);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.INT);
handler(packetWrapper -> {
final int entityId = packetWrapper.get(Type.VAR_INT, 0);
final int typeId = packetWrapper.get(Type.BYTE, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
final Entity1_10Types.EntityType type = Entity1_10Types.getTypeFromId(typeId, true);
//cancel AREA_EFFECT_CLOUD = 3, SPECTRAL_ARROW = 91, DRAGON_FIREBALL = 93
if (typeId == 3 || typeId == 91 || typeId == 92 || typeId == 93) {
packetWrapper.cancel();
return;
}
if (type == null) {
ViaRewind.getPlatform().getLogger().warning("[ViaRewind] Unhandled Spawn Object Type: " + typeId);
packetWrapper.cancel();
return;
}
int x = packetWrapper.get(Type.INT, 0);
int y = packetWrapper.get(Type.INT, 1);
int z = packetWrapper.get(Type.INT, 2);
if (type.is(Entity1_10Types.EntityType.BOAT)) {
byte yaw = packetWrapper.get(Type.BYTE, 1);
yaw -= 64;
packetWrapper.set(Type.BYTE, 1, yaw);
y += 10;
packetWrapper.set(Type.INT, 1, y);
} else if (type.is(Entity1_10Types.EntityType.SHULKER_BULLET)) {
packetWrapper.cancel();
ShulkerBulletReplacement shulkerBulletReplacement = new ShulkerBulletReplacement(entityId, packetWrapper.user());
shulkerBulletReplacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
tracker.addEntityReplacement(shulkerBulletReplacement);
return;
}
int data = packetWrapper.get(Type.INT, 3);
//Rewrite Object Data
if (type.isOrHasParent(Entity1_10Types.EntityType.ARROW) && data != 0) {
packetWrapper.set(Type.INT, 3, --data);
}
if (type.is(Entity1_10Types.EntityType.FALLING_BLOCK)) {
int blockId = data & 0xFFF;
int blockData = data >> 12 & 0xF;
Replacement replace = ReplacementRegistry1_8to1_9.getReplacement(blockId, blockData);
if (replace != null) {
packetWrapper.set(Type.INT, 3, replace.getId() | replace.replaceData(data) << 12);
}
}
if (data > 0) {
packetWrapper.passthrough(Type.SHORT);
packetWrapper.passthrough(Type.SHORT);
packetWrapper.passthrough(Type.SHORT);
} else {
short vX = packetWrapper.read(Type.SHORT);
short vY = packetWrapper.read(Type.SHORT);
short vZ = packetWrapper.read(Type.SHORT);
PacketWrapper velocityPacket = PacketWrapper.create(0x12, null, packetWrapper.user());
velocityPacket.write(Type.VAR_INT, entityId);
velocityPacket.write(Type.SHORT, vX);
velocityPacket.write(Type.SHORT, vY);
velocityPacket.write(Type.SHORT, vZ);
PacketUtil.sendPacket(velocityPacket, Protocol1_8To1_9.class);
}
tracker.getClientEntityTypes().put(entityId, type);
tracker.sendMetadataBuffer(entityId);
});
}
});
//Spawn Experience Orb
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_EXPERIENCE_ORB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.SHORT);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.EXPERIENCE_ORB);
tracker.sendMetadataBuffer(entityId);
});
}
});
//Spawn Global Entity
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_GLOBAL_ENTITY, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.LIGHTNING);
tracker.sendMetadataBuffer(entityId);
});
}
});
//Spawn Mob
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_MOB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.UUID, Type.NOTHING);
map(Type.UNSIGNED_BYTE);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.BYTE);
map(Type.BYTE);
map(Type.BYTE);
map(Type.SHORT);
map(Type.SHORT);
map(Type.SHORT);
map(Types1_9.METADATA_LIST, Types1_8.METADATA_LIST);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
int x = packetWrapper.get(Type.INT, 0);
int y = packetWrapper.get(Type.INT, 1);
int z = packetWrapper.get(Type.INT, 2);
byte pitch = packetWrapper.get(Type.BYTE, 1);
byte yaw = packetWrapper.get(Type.BYTE, 0);
byte headYaw = packetWrapper.get(Type.BYTE, 2);
if (typeId == 69) {
packetWrapper.cancel();
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
ShulkerReplacement shulkerReplacement = new ShulkerReplacement(entityId, packetWrapper.user());
shulkerReplacement.setLocation(x / 32.0, y / 32.0, z / 32.0);
shulkerReplacement.setYawPitch(yaw * 360f / 256, pitch * 360f / 256);
shulkerReplacement.setHeadYaw(headYaw * 360f / 256);
tracker.addEntityReplacement(shulkerReplacement);
} else if (typeId == -1 || typeId == 255) {
packetWrapper.cancel();
}
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
int typeId = packetWrapper.get(Type.UNSIGNED_BYTE, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.getTypeFromId(typeId, false));
tracker.sendMetadataBuffer(entityId);
});
handler(wrapper -> {
List<Metadata> metadataList = wrapper.get(Types1_8.METADATA_LIST, 0);
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = wrapper.user().get(EntityTracker.class);
EntityReplacement replacement;
if ((replacement = tracker.getEntityReplacement(entityId)) != null) {
replacement.updateMetadata(metadataList);
} else if (tracker.getClientEntityTypes().containsKey(entityId)) {
MetadataRewriter.transform(tracker.getClientEntityTypes().get(entityId), metadataList);
} else {
wrapper.cancel();
}
});
}
});
//Spawn Painting
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_PAINTING, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.UUID, Type.NOTHING);
map(Type.STRING);
map(Type.POSITION);
map(Type.BYTE, Type.UNSIGNED_BYTE);
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PAINTING);
tracker.sendMetadataBuffer(entityId);
});
}
});
//Spawn Player
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.UUID);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.DOUBLE, Protocol1_8To1_9.TO_OLD_INT);
map(Type.BYTE);
map(Type.BYTE);
handler(packetWrapper -> packetWrapper.write(Type.SHORT, (short) 0));
map(Types1_9.METADATA_LIST, Types1_8.METADATA_LIST);
this.handler(wrapper -> {
List<Metadata> metadataList = wrapper.get(Types1_8.METADATA_LIST, 0);
MetadataRewriter.transform(Entity1_10Types.EntityType.PLAYER, metadataList);
});
handler(packetWrapper -> {
int entityId = packetWrapper.get(Type.VAR_INT, 0);
EntityTracker tracker = packetWrapper.user().get(EntityTracker.class);
tracker.getClientEntityTypes().put(entityId, Entity1_10Types.EntityType.PLAYER);
tracker.sendMetadataBuffer(entityId);
});
}
});
}
}
@@ -1,348 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.packets;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.items.ReplacementRegistry1_8to1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.sound.Effect;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.sound.SoundRemapper;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.Environment;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.chunks.BaseChunk;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ServerboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.types.Chunk1_9_1_2Type;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.types.Chunk1_8Type;
import java.util.ArrayList;
public class WorldPackets {
public static void register(Protocol<ClientboundPackets1_9, ClientboundPackets1_8,
ServerboundPackets1_9, ServerboundPackets1_8> protocol) {
/* OUTGOING */
//Block Break Animation
//Update Block Entity
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_ENTITY_DATA, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION);
map(Type.UNSIGNED_BYTE);
map(Type.NBT);
handler(packetWrapper -> {
CompoundTag tag = packetWrapper.get(Type.NBT, 0);
if (tag != null && tag.contains("SpawnData")) {
CompoundTag spawnData = tag.get("SpawnData");
if (spawnData.contains("id")) {
String entity = (String) spawnData.get("id").getValue();
tag.remove("SpawnData");
tag.put("entityId", new StringTag(entity));
}
}
});
}
});
//Block Action
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION);
map(Type.UNSIGNED_BYTE);
map(Type.UNSIGNED_BYTE);
map(Type.VAR_INT);
handler(packetWrapper -> {
int block = packetWrapper.get(Type.VAR_INT, 0);
if (block >= 219 && block <= 234) {
packetWrapper.set(Type.VAR_INT, 0, block = 130);
}
});
}
});
//Block Change
protocol.registerClientbound(ClientboundPackets1_9.BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION);
map(Type.VAR_INT);
handler(packetWrapper -> {
int combined = packetWrapper.get(Type.VAR_INT, 0);
int replacedCombined = ReplacementRegistry1_8to1_9.replace(combined);
packetWrapper.set(Type.VAR_INT, 0, replacedCombined);
});
}
});
//Server Difficulty
//Multi Block Change
protocol.registerClientbound(ClientboundPackets1_9.MULTI_BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.INT);
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(packetWrapper -> {
for (BlockChangeRecord record : packetWrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
int replacedCombined = ReplacementRegistry1_8to1_9.replace(record.getBlockId());
record.setBlockId(replacedCombined);
}
});
}
});
//Named Sound Effect
protocol.registerClientbound(ClientboundPackets1_9.NAMED_SOUND, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING);
handler(packetWrapper -> {
String name = packetWrapper.get(Type.STRING, 0);
name = SoundRemapper.getOldName(name);
if (name == null) {
packetWrapper.cancel();
} else {
packetWrapper.set(Type.STRING, 0, name);
}
});
map(Type.VAR_INT, Type.NOTHING);
map(Type.INT);
map(Type.INT);
map(Type.INT);
map(Type.FLOAT);
map(Type.UNSIGNED_BYTE);
}
});
//Explosion
protocol.registerClientbound(ClientboundPackets1_9.EXPLOSION, new PacketHandlers() {
@Override
public void register() {
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
handler(packetWrapper -> {
int count = packetWrapper.read(Type.INT);
packetWrapper.write(Type.INT, count);
for (int i = 0; i < count; i++) {
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
packetWrapper.passthrough(Type.UNSIGNED_BYTE);
}
});
map(Type.FLOAT);
map(Type.FLOAT);
map(Type.FLOAT);
}
});
//Unload Chunk
protocol.registerClientbound(ClientboundPackets1_9.UNLOAD_CHUNK, ClientboundPackets1_8.CHUNK_DATA, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int chunkX = packetWrapper.read(Type.INT);
int chunkZ = packetWrapper.read(Type.INT);
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
packetWrapper.write(new Chunk1_8Type(world), new BaseChunk(chunkX, chunkZ, true, false, 0, new ChunkSection[16], null, new ArrayList<>()));
});
}
});
//Chunk Data
protocol.registerClientbound(ClientboundPackets1_9.CHUNK_DATA, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
ClientWorld world = packetWrapper.user().get(ClientWorld.class);
Chunk chunk = packetWrapper.read(new Chunk1_9_1_2Type(world));
for (ChunkSection section : chunk.getSections()) {
if (section == null) continue;
DataPalette palette = section.palette(PaletteType.BLOCKS);
for (int i = 0; i < palette.size(); i++) {
int block = palette.idByIndex(i);
int replacedBlock = ReplacementRegistry1_8to1_9.replace(block);
palette.setIdByIndex(i, replacedBlock);
}
}
if (chunk.isFullChunk() && chunk.getBitmask() == 0) { //This would be an unload packet for 1.8 clients. Just set one air section
boolean skylight = world.getEnvironment() == Environment.NORMAL;
ChunkSection[] sections = new ChunkSection[16];
ChunkSection section = new ChunkSectionImpl(true);
sections[0] = section;
section.palette(PaletteType.BLOCKS).addId(0);
if (skylight) section.getLight().setSkyLight(new byte[2048]);
chunk = new BaseChunk(chunk.getX(), chunk.getZ(), true, false, 1, sections, chunk.getBiomeData(), chunk.getBlockEntities());
}
packetWrapper.write(new Chunk1_8Type(world), chunk);
final UserConnection user = packetWrapper.user();
chunk.getBlockEntities().forEach(nbt -> {
if (!nbt.contains("x") || !nbt.contains("y") || !nbt.contains("z") || !nbt.contains("id"))
return;
Position position = new Position((int) nbt.get("x").getValue(), (int) nbt.get("y").getValue(), (int) nbt.get("z").getValue());
String id = (String) nbt.get("id").getValue();
short action;
switch (id) {
case "minecraft:mob_spawner":
action = 1;
break;
case "minecraft:command_block":
action = 2;
break;
case "minecraft:beacon":
action = 3;
break;
case "minecraft:skull":
action = 4;
break;
case "minecraft:flower_pot":
action = 5;
break;
case "minecraft:banner":
action = 6;
break;
default:
return;
}
PacketWrapper updateTileEntity = PacketWrapper.create(0x09, null, user);
updateTileEntity.write(Type.POSITION, position);
updateTileEntity.write(Type.UNSIGNED_BYTE, action);
updateTileEntity.write(Type.NBT, nbt);
PacketUtil.sendPacket(updateTileEntity, Protocol1_8To1_9.class, false, false);
});
});
}
});
//Effect
protocol.registerClientbound(ClientboundPackets1_9.EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
map(Type.POSITION);
map(Type.INT);
map(Type.BOOLEAN);
handler(packetWrapper -> {
int id = packetWrapper.get(Type.INT, 0);
id = Effect.getOldId(id);
if (id == -1) {
packetWrapper.cancel();
return;
}
packetWrapper.set(Type.INT, 0, id);
if (id == 2001) {
int replacedBlock = ReplacementRegistry1_8to1_9.replace(packetWrapper.get(Type.INT, 1));
packetWrapper.set(Type.INT, 1, replacedBlock);
}
});
}
});
//Particle
protocol.registerClientbound(ClientboundPackets1_9.SPAWN_PARTICLE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
handler(packetWrapper -> {
int type = packetWrapper.get(Type.INT, 0);
if (type > 41 && !ViaRewind.getConfig().isReplaceParticles()) {
packetWrapper.cancel();
return;
}
if (type == 42) { // Dragon Breath
packetWrapper.set(Type.INT, 0, 24); // Portal
} else if (type == 43) { // End Rod
packetWrapper.set(Type.INT, 0, 3); // Firework Spark
} else if (type == 44) { // Damage Indicator
packetWrapper.set(Type.INT, 0, 34); // Heart
} else if (type == 45) { // Sweep Attack
packetWrapper.set(Type.INT, 0, 1); // Large Explosion
}
});
}
});
//Map
protocol.registerClientbound(ClientboundPackets1_9.MAP_DATA, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.BYTE);
map(Type.BOOLEAN, Type.NOTHING);
}
});
//Combat Event
//World Border
//Update Time
//Update Sign
//Sound Effects
protocol.registerClientbound(ClientboundPackets1_9.SOUND, ClientboundPackets1_8.NAMED_SOUND, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int soundId = packetWrapper.read(Type.VAR_INT);
String sound = SoundRemapper.oldNameFromId(soundId);
if (sound == null) {
packetWrapper.cancel();
} else {
packetWrapper.write(Type.STRING, sound);
}
});
handler(packetWrapper -> packetWrapper.read(Type.VAR_INT));
map(Type.INT);
map(Type.INT);
map(Type.INT);
map(Type.FLOAT);
map(Type.UNSIGNED_BYTE);
}
});
}
}
@@ -1,885 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.sound;
import java.util.HashMap;
public class SoundRemapper {
private static final HashMap<Integer, String> sounds1_9 = new HashMap<>();
private static final HashMap<String, String> sound1_9to1_8 = new HashMap<>();
private static int id;
private static void register1_9Sound(String sound1_9) {
sounds1_9.put(id++, sound1_9);
}
private static void registerSoundRemapping(String sound1_9, String sound1_8) {
sound1_9to1_8.put(sound1_9, sound1_8);
}
public static String oldNameFromId(int id) {
String sound1_9 = sounds1_9.get(id);
if (sound1_9==null) return null;
return getOldName(sound1_9);
}
public static String getOldName(String sound1_9) {
return sound1_9to1_8.getOrDefault(sound1_9, sound1_9);
}
static {
registerSoundRemapping("entity.zombie_horse.ambient", "mob.horse.zombie.idle");
registerSoundRemapping("block.note.snare", "note.snare");
registerSoundRemapping("block.wood_button.click_off", "random.wood_click");
registerSoundRemapping("block.wood_button.click_on", "random.wood_click");
registerSoundRemapping("block.gravel.break", "dig.gravel");
registerSoundRemapping("block.gravel.place", "dig.gravel");
registerSoundRemapping("entity.arrow.hit", "random.bowhit");
registerSoundRemapping("block.tripwire.detach", "random.bowhit");
registerSoundRemapping("entity.splash_potion.break", "dig.glass");
registerSoundRemapping("block.glass.break", "dig.glass");
registerSoundRemapping("entity.zombie.ambient", "mob.zombie.say");
registerSoundRemapping("entity.zombie_villager.ambient", "mob.zombie.say");
registerSoundRemapping("entity.pig.death", "mob.pig.death");
registerSoundRemapping("entity.mule.hurt", "mob.horse.donkey.hit");
registerSoundRemapping("entity.donkey.hurt", "mob.horse.donkey.hit");
registerSoundRemapping("entity.endermen.ambient", "mob.endermen.idle");
registerSoundRemapping("block.portal.ambient", "portal.portal");
registerSoundRemapping("entity.generic.burn", "random.fizz");
registerSoundRemapping("block.fire.extinguish", "random.fizz");
registerSoundRemapping("block.redstone_torch.burnout", "random.fizz");
registerSoundRemapping("block.lava.extinguish", "random.fizz");
registerSoundRemapping("entity.generic.extinguish_fire", "random.fizz");
registerSoundRemapping("block.note.harp", "note.harp");
registerSoundRemapping("block.snow.hit", "step.snow");
registerSoundRemapping("block.snow.fall", "step.snow");
registerSoundRemapping("block.snow.step", "step.snow");
registerSoundRemapping("entity.arrow.hit_player", "random.successful_hit");
registerSoundRemapping("entity.zombie_pig.hurt", "mob.zombiepig.zpighurt");
registerSoundRemapping("entity.wolf.howl", "mob.wolf.howl");
registerSoundRemapping("entity.firework.launch", "fireworks.launch");
registerSoundRemapping("entity.cow.hurt", "mob.cow.hurt");
registerSoundRemapping("entity.cow.death", "mob.cow.hurt");
registerSoundRemapping("entity.firework.large_blast", "fireworks.largeBlast");
registerSoundRemapping("entity.blaze.hurt", "mob.blaze.hit");
registerSoundRemapping("entity.villager.death", "mob.villager.death");
registerSoundRemapping("entity.blaze.death", "mob.blaze.death");
registerSoundRemapping("entity.zombie_horse.death", "mob.horse.zombie.death");
registerSoundRemapping("entity.silverfish.death", "mob.silverfish.kill");
registerSoundRemapping("entity.endermite.death", "mob.silverfish.kill");
registerSoundRemapping("record.ward", "records.ward");
registerSoundRemapping("entity.wolf.pant", "mob.wolf.panting");
registerSoundRemapping("block.metal.break", "dig.stone");
registerSoundRemapping("block.metal.place", "dig.stone");
registerSoundRemapping("entity.armorstand.place", "dig.stone");
registerSoundRemapping("block.stone.break", "dig.stone");
registerSoundRemapping("block.stone.place", "dig.stone");
registerSoundRemapping("block.anvil.break", "dig.stone");
registerSoundRemapping("block.glass.place", "dig.stone");
registerSoundRemapping("entity.endermen.stare", "mob.endermen.stare");
registerSoundRemapping("entity.small_magmacube.hurt", "mob.slime.small");
registerSoundRemapping("block.slime.fall", "mob.slime.small");
registerSoundRemapping("entity.small_slime.death", "mob.slime.small");
registerSoundRemapping("block.slime.step", "mob.slime.small");
registerSoundRemapping("entity.small_magmacube.death", "mob.slime.small");
registerSoundRemapping("entity.small_slime.hurt", "mob.slime.small");
registerSoundRemapping("block.slime.hit", "mob.slime.small");
registerSoundRemapping("music.nether", "music.game.nether");
registerSoundRemapping("entity.ghast.death", "mob.ghast.death");
registerSoundRemapping("entity.guardian.attack", "mob.guardian.attack");
registerSoundRemapping("block.dispenser.fail", "random.click");
registerSoundRemapping("block.comparator.click", "random.click");
registerSoundRemapping("block.stone_button.click_on", "random.click");
registerSoundRemapping("block.stone_button.click_off", "random.click");
registerSoundRemapping("block.tripwire.click_on", "random.click");
registerSoundRemapping("block.dispenser.dispense", "random.click");
registerSoundRemapping("ui.button.click", "random.click");
registerSoundRemapping("block.lever.click", "random.click");
registerSoundRemapping("block.tripwire.attach", "random.click");
registerSoundRemapping("block.stone_pressureplate.click_on", "random.click");
registerSoundRemapping("block.wood_pressureplate.click_off", "random.click");
registerSoundRemapping("block.stone_pressureplate.click_off", "random.click");
registerSoundRemapping("block.metal_pressureplate.click_off", "random.click");
registerSoundRemapping("block.tripwire.click_off", "random.click");
registerSoundRemapping("block.metal_pressureplate.click_on", "random.click");
registerSoundRemapping("block.wood_pressureplate.click_on", "random.click");
registerSoundRemapping("entity.zombie_pig.ambient", "mob.zombiepig.zpig");
registerSoundRemapping("music.dragon", "music.game.end.dragon");
registerSoundRemapping("entity.firework.twinkle_far", "fireworks.twinkle_far");
registerSoundRemapping("entity.elder_guardian.ambient_land", "mob.guardian.land.idle");
registerSoundRemapping("entity.guardian.ambient_land", "mob.guardian.land.idle");
registerSoundRemapping("block.grass.break", "dig.grass");
registerSoundRemapping("block.grass.place", "dig.grass");
registerSoundRemapping("entity.skeleton.step", "mob.skeleton.step");
registerSoundRemapping("entity.wither.death", "mob.wither.death");
registerSoundRemapping("entity.wolf.hurt", "mob.wolf.hurt");
registerSoundRemapping("entity.pig.saddle", "mob.horse.leather");
registerSoundRemapping("entity.horse.saddle", "mob.horse.leather");
registerSoundRemapping("entity.bat.loop", "mob.bat.loop");
registerSoundRemapping("entity.ghast.hurt", "mob.ghast.scream");
registerSoundRemapping("entity.creeper.death", "mob.creeper.death");
registerSoundRemapping("entity.horse.gallop", "mob.horse.gallop");
registerSoundRemapping("entity.wither.spawn", "mob.wither.spawn");
registerSoundRemapping("entity.endermen.hurt", "mob.endermen.hit");
registerSoundRemapping("entity.creeper.hurt", "mob.creeper.say");
registerSoundRemapping("entity.horse.step_wood", "mob.horse.wood");
registerSoundRemapping("entity.rabbit.death", "mob.rabbit.death");
registerSoundRemapping("entity.zombie_villager.converted", "mob.zombie.unfect");
registerSoundRemapping("block.anvil.use", "random.anvil_use");
registerSoundRemapping("block.enderchest.close", "random.chestclosed");
registerSoundRemapping("entity.mooshroom.shear", "mob.sheep.shear");
registerSoundRemapping("entity.sheep.shear", "mob.sheep.shear");
registerSoundRemapping("entity.item.pickup", "random.pop");
registerSoundRemapping("entity.bat.death", "mob.bat.death");
registerSoundRemapping("block.wood.place", "dig.wood");
registerSoundRemapping("block.wood.break", "dig.wood");
registerSoundRemapping("block.ladder.place", "dig.wood");
registerSoundRemapping("entity.armorstand.fall", "dig.wood");
registerSoundRemapping("block.ladder.break", "dig.wood");
registerSoundRemapping("record.chirp", "records.chirp");
registerSoundRemapping("entity.mule.death", "mob.horse.donkey.death");
registerSoundRemapping("entity.donkey.death", "mob.horse.donkey.death");
registerSoundRemapping("entity.firework.blast", "fireworks.blast");
registerSoundRemapping("entity.zombie_pig.angry", "mob.zombiepig.zpigangry");
registerSoundRemapping("entity.guardian.flop", "mob.guardian.flop");
registerSoundRemapping("entity.villager.yes", "mob.villager.yes");
registerSoundRemapping("entity.ghast.warn", "mob.ghast.charge");
registerSoundRemapping("entity.tnt.primed", "creeper.primed");
registerSoundRemapping("entity.creeper.primed", "creeper.primed");
registerSoundRemapping("block.sand.place", "dig.sand");
registerSoundRemapping("block.sand.break", "dig.sand");
registerSoundRemapping("entity.chicken.ambient", "mob.chicken.say");
registerSoundRemapping("record.13", "records.13");
registerSoundRemapping("record.11", "records.11");
registerSoundRemapping("entity.elder_guardian.death", "mob.guardian.elder.death");
registerSoundRemapping("entity.firework.twinkle", "fireworks.twinkle");
registerSoundRemapping("entity.skeleton_horse.death", "mob.horse.skeleton.death");
registerSoundRemapping("weather.rain", "ambient.weather.rain");
registerSoundRemapping("weather.rain.above", "ambient.weather.rain");
registerSoundRemapping("block.portal.trigger", "portal.trigger");
registerSoundRemapping("block.enderchest.open", "random.chestopen");
registerSoundRemapping("entity.horse.land", "mob.horse.land");
registerSoundRemapping("entity.endermite.step", "mob.silverfish.step");
registerSoundRemapping("entity.silverfish.step", "mob.silverfish.step");
registerSoundRemapping("entity.bat.takeoff", "mob.bat.takeoff");
registerSoundRemapping("entity.villager.no", "mob.villager.no");
registerSoundRemapping("entity.irongolem.step", "mob.irongolem.walk");
registerSoundRemapping("block.note.hat", "note.hat");
registerSoundRemapping("entity.zombie.attack_iron_door", "mob.zombie.metal");
registerSoundRemapping("entity.villager.trading", "mob.villager.haggle");
registerSoundRemapping("item.firecharge.use", "mob.ghast.fireball");
registerSoundRemapping("entity.ghast.shoot", "mob.ghast.fireball");
registerSoundRemapping("entity.enderdragon.shoot", "mob.ghast.fireball");
registerSoundRemapping("entity.blaze.shoot", "mob.ghast.fireball");
registerSoundRemapping("music.credits", "music.game.end.credits");
registerSoundRemapping("entity.irongolem.death", "mob.irongolem.death");
registerSoundRemapping("entity.item.break", "random.break");
registerSoundRemapping("item.shield.break", "random.break");
registerSoundRemapping("record.mellohi", "records.mellohi");
registerSoundRemapping("entity.zombie_villager.cure", "mob.zombie.remedy");
registerSoundRemapping("entity.enderpearl.throw", "random.bow");
registerSoundRemapping("block.dispenser.launch", "random.bow");
registerSoundRemapping("entity.skeleton.shoot", "random.bow");
registerSoundRemapping("entity.endereye.launch", "random.bow");
registerSoundRemapping("entity.firework.shoot", "random.bow");
registerSoundRemapping("entity.experience_bottle.throw", "random.bow");
registerSoundRemapping("entity.snowman.shoot", "random.bow");
registerSoundRemapping("entity.arrow.shoot", "random.bow");
registerSoundRemapping("entity.egg.throw", "random.bow");
registerSoundRemapping("entity.snowball.throw", "random.bow");
registerSoundRemapping("entity.bobber.throw", "random.bow");
registerSoundRemapping("entity.lingeringpotion.throw", "random.bow");
registerSoundRemapping("entity.splash_potion.throw", "random.bow");
registerSoundRemapping("entity.villager.ambient", "mob.villager.idle");
registerSoundRemapping("block.cloth.hit", "step.cloth");
registerSoundRemapping("block.cloth.step", "step.cloth");
registerSoundRemapping("block.cloth.fall", "step.cloth");
registerSoundRemapping("entity.silverfish.hurt", "mob.silverfish.hit");
registerSoundRemapping("entity.endermite.hurt", "mob.silverfish.hit");
registerSoundRemapping("music.game", "music.game");
registerSoundRemapping("block.lava.ambient", "liquid.lava");
registerSoundRemapping("record.mall", "records.mall");
registerSoundRemapping("entity.blaze.burn", "fire.fire");
registerSoundRemapping("block.fire.ambient", "fire.fire");
registerSoundRemapping("entity.zombie.attack_door_wood", "mob.zombie.wood");
registerSoundRemapping("entity.chicken.step", "mob.chicken.step");
registerSoundRemapping("record.stal", "records.stal");
registerSoundRemapping("entity.elder_guardian.hurt_land", "mob.guardian.land.hit");
registerSoundRemapping("entity.guardian.hurt_land", "mob.guardian.land.hit");
registerSoundRemapping("entity.chicken.egg", "mob.chicken.plop");
registerSoundRemapping("entity.donkey.chest", "mob.chicken.plop");
registerSoundRemapping("entity.enderdragon.flap", "mob.enderdragon.wings");
registerSoundRemapping("block.grass.step", "step.grass");
registerSoundRemapping("block.grass.fall", "step.grass");
registerSoundRemapping("block.grass.hit", "step.grass");
registerSoundRemapping("entity.horse.breathe", "mob.horse.breathe");
registerSoundRemapping("entity.mule.ambient", "mob.horse.donkey.idle");
registerSoundRemapping("entity.donkey.ambient", "mob.horse.donkey.idle");
registerSoundRemapping("record.far", "records.far");
registerSoundRemapping("entity.spider.step", "mob.spider.step");
registerSoundRemapping("entity.cow.ambient", "mob.cow.say");
registerSoundRemapping("entity.horse.jump", "mob.horse.jump");
registerSoundRemapping("entity.horse.step", "mob.horse.soft");
registerSoundRemapping("entity.guardian.hurt", "mob.guardian.hit");
registerSoundRemapping("entity.enderdragon.death", "mob.enderdragon.end");
registerSoundRemapping("entity.zombie_villager.step", "mob.zombie.step");
registerSoundRemapping("entity.zombie.step", "mob.zombie.step");
registerSoundRemapping("entity.enderdragon.ambient", "mob.enderdragon.growl");
registerSoundRemapping("entity.enderdragon.growl", "mob.enderdragon.growl");
registerSoundRemapping("entity.wolf.shake", "mob.wolf.shake");
registerSoundRemapping("entity.endermen.death", "mob.endermen.death");
registerSoundRemapping("block.anvil.place", "random.anvil_land");
registerSoundRemapping("block.anvil.land", "random.anvil_land");
registerSoundRemapping("entity.minecart.inside", "minecart.inside");
registerSoundRemapping("entity.slime.squish", "mob.slime.big");
registerSoundRemapping("entity.magmacube.hurt", "mob.slime.big");
registerSoundRemapping("entity.magmacube.death", "mob.slime.big");
registerSoundRemapping("block.slime.break", "mob.slime.big");
registerSoundRemapping("block.slime.place", "mob.slime.big");
registerSoundRemapping("entity.slime.jump", "mob.slime.big");
registerSoundRemapping("entity.slime.hurt", "mob.slime.big");
registerSoundRemapping("entity.slime.death", "mob.slime.big");
registerSoundRemapping("block.water.ambient", "liquid.water");
registerSoundRemapping("entity.pig.hurt", "mob.pig.say");
registerSoundRemapping("entity.pig.ambient", "mob.pig.say");
registerSoundRemapping("entity.wither.shoot", "mob.wither.shoot");
registerSoundRemapping("record.blocks", "records.blocks");
registerSoundRemapping("item.firecharge.use", "item.fireCharge.use");
registerSoundRemapping("entity.ghast.shoot", "item.fireCharge.use");
registerSoundRemapping("entity.enderdragon.shoot", "item.fireCharge.use");
registerSoundRemapping("entity.blaze.shoot", "item.fireCharge.use");
registerSoundRemapping("block.sand.hit", "step.sand");
registerSoundRemapping("block.sand.step", "step.sand");
registerSoundRemapping("block.sand.fall", "step.sand");
registerSoundRemapping("music.creative", "music.game.creative");
registerSoundRemapping("entity.irongolem.hurt", "mob.irongolem.hit");
registerSoundRemapping("entity.horse.death", "mob.horse.death");
registerSoundRemapping("entity.bat.hurt", "mob.bat.hurt");
registerSoundRemapping("entity.ghast.scream", "mob.ghast.affectionate_scream");
registerSoundRemapping("entity.elder_guardian.ambient", "mob.guardian.elder.idle");
registerSoundRemapping("entity.zombie_pig.death", "mob.zombiepig.zpigdeath");
registerSoundRemapping("entity.lightning.thunder", "ambient.weather.thunder");
registerSoundRemapping("entity.minecart.riding", "minecart.base");
registerSoundRemapping("block.ladder.step", "step.ladder");
registerSoundRemapping("block.ladder.fall", "step.ladder");
registerSoundRemapping("block.ladder.hit", "step.ladder");
registerSoundRemapping("entity.donkey.angry", "mob.horse.donkey.angry");
registerSoundRemapping("ambient.cave", "ambient.cave.cave");
registerSoundRemapping("record.wait", "records.wait");
registerSoundRemapping("entity.firework.blast_far", "fireworks.blast_far");
registerSoundRemapping("entity.generic.drink", "random.drink");
registerSoundRemapping("music.menu", "music.menu");
registerSoundRemapping("entity.cat.hiss", "mob.cat.hiss");
registerSoundRemapping("block.note.basedrum", "note.bd");
registerSoundRemapping("entity.spider.ambient", "mob.spider.say");
registerSoundRemapping("entity.spider.hurt", "mob.spider.say");
registerSoundRemapping("block.stone.fall", "step.stone");
registerSoundRemapping("block.anvil.fall", "step.stone");
registerSoundRemapping("block.metal.step", "step.stone");
registerSoundRemapping("block.stone.hit", "step.stone");
registerSoundRemapping("block.glass.fall", "step.stone");
registerSoundRemapping("block.stone.step", "step.stone");
registerSoundRemapping("block.anvil.step", "step.stone");
registerSoundRemapping("block.metal.hit", "step.stone");
registerSoundRemapping("block.glass.step", "step.stone");
registerSoundRemapping("block.metal.fall", "step.stone");
registerSoundRemapping("block.glass.hit", "step.stone");
registerSoundRemapping("block.anvil.hit", "step.stone");
registerSoundRemapping("entity.player.levelup", "random.levelup");
registerSoundRemapping("block.lava.pop", "liquid.lavapop");
registerSoundRemapping("entity.sheep.hurt", "mob.sheep.say");
registerSoundRemapping("entity.sheep.death", "mob.sheep.say");
registerSoundRemapping("entity.sheep.ambient", "mob.sheep.say");
registerSoundRemapping("entity.skeleton.ambient", "mob.skeleton.say");
registerSoundRemapping("entity.blaze.ambient", "mob.blaze.breathe");
registerSoundRemapping("entity.bat.ambient", "mob.bat.idle");
registerSoundRemapping("entity.magmacube.squish", "mob.magmacube.big");
registerSoundRemapping("entity.horse.ambient", "mob.horse.idle");
registerSoundRemapping("entity.zombie_horse.hurt", "mob.horse.zombie.hit");
registerSoundRemapping("entity.irongolem.attack", "mob.irongolem.throw");
registerSoundRemapping("block.cloth.break", "dig.cloth");
registerSoundRemapping("block.cloth.place", "dig.cloth");
registerSoundRemapping("block.gravel.fall", "step.gravel");
registerSoundRemapping("block.gravel.step", "step.gravel");
registerSoundRemapping("block.gravel.hit", "step.gravel");
registerSoundRemapping("entity.endermite.ambient", "mob.silverfish.say");
registerSoundRemapping("entity.silverfish.ambient", "mob.silverfish.say");
registerSoundRemapping("entity.cat.purr", "mob.cat.purr");
registerSoundRemapping("entity.zombie.infect", "mob.zombie.infect");
registerSoundRemapping("entity.generic.eat", "random.eat");
registerSoundRemapping("entity.wolf.ambient", "mob.wolf.bark");
registerSoundRemapping("entity.tnt.primed", "game.tnt.primed");
registerSoundRemapping("entity.creeper.primed", "game.tnt.primed");
registerSoundRemapping("entity.sheep.step", "mob.sheep.step");
registerSoundRemapping("entity.zombie_villager.death", "mob.zombie.death");
registerSoundRemapping("entity.zombie.death", "mob.zombie.death");
registerSoundRemapping("entity.shulker.teleport", "mob.endermen.portal");
registerSoundRemapping("item.chorus_fruit.teleport", "mob.endermen.portal");
registerSoundRemapping("entity.endermen.teleport", "mob.endermen.portal");
registerSoundRemapping("entity.horse.angry", "mob.horse.angry");
registerSoundRemapping("entity.wolf.growl", "mob.wolf.growl");
registerSoundRemapping("block.snow.break", "dig.snow");
registerSoundRemapping("block.snow.place", "dig.snow");
registerSoundRemapping("block.piston.extend", "tile.piston.out");
registerSoundRemapping("entity.player.burp", "random.burp");
registerSoundRemapping("entity.cow.step", "mob.cow.step");
registerSoundRemapping("entity.wither.hurt", "mob.wither.hurt");
registerSoundRemapping("entity.guardian.death_land", "mob.guardian.land.death");
registerSoundRemapping("entity.elder_guardian.death_land", "mob.guardian.land.death");
registerSoundRemapping("music.end", "music.game.end");
registerSoundRemapping("entity.chicken.hurt", "mob.chicken.hurt");
registerSoundRemapping("entity.chicken.death", "mob.chicken.hurt");
registerSoundRemapping("entity.wolf.step", "mob.wolf.step");
registerSoundRemapping("entity.wolf.death", "mob.wolf.death");
registerSoundRemapping("entity.wolf.whine", "mob.wolf.whine");
registerSoundRemapping("block.note.pling", "note.pling");
registerSoundRemapping("entity.rabbit.hurt", "mob.rabbit.hurt");
registerSoundRemapping("entity.cat.purreow", "mob.cat.purreow");
registerSoundRemapping("entity.firework.large_blast_far", "fireworks.largeBlast_far");
registerSoundRemapping("entity.skeleton.hurt", "mob.skeleton.hurt");
registerSoundRemapping("entity.spider.death", "mob.spider.death");
registerSoundRemapping("block.anvil.destroy", "random.anvil_break");
registerSoundRemapping("record.cat", "records.cat");
registerSoundRemapping("entity.wither.ambient", "mob.wither.idle");
registerSoundRemapping("entity.elder_guardian.hurt", "mob.guardian.elder.hit");
registerSoundRemapping("entity.endermen.scream", "mob.endermen.scream");
registerSoundRemapping("entity.cat.death", "mob.cat.hitt");
registerSoundRemapping("entity.cat.hurt", "mob.cat.hitt");
registerSoundRemapping("entity.small_magmacube.squish", "mob.magmacube.small");
registerSoundRemapping("item.flintandsteel.use", "fire.ignite");
registerSoundRemapping("entity.enderdragon.hurt", "mob.enderdragon.hit");
registerSoundRemapping("entity.zombie.hurt", "mob.zombie.hurt");
registerSoundRemapping("entity.zombie_villager.hurt", "mob.zombie.hurt");
registerSoundRemapping("entity.enderdragon_fireball.explode", "random.explode");
registerSoundRemapping("entity.generic.explode", "random.explode");
registerSoundRemapping("entity.lightning.impact", "random.explode");
registerSoundRemapping("block.end_gateway.spawn", "random.explode");
registerSoundRemapping("entity.slime.attack", "mob.slime.attack");
registerSoundRemapping("entity.magmacube.jump", "mob.magmacube.jump");
registerSoundRemapping("entity.bobber.splash", "random.splash");
registerSoundRemapping("entity.skeleton_horse.hurt", "mob.horse.skeleton.hit");
registerSoundRemapping("entity.rabbit.jump", "mob.rabbit.hop");
registerSoundRemapping("entity.ghast.ambient", "mob.ghast.moan");
registerSoundRemapping("entity.elder_guardian.curse", "mob.guardian.curse");
registerSoundRemapping("entity.splash_potion.break", "game.potion.smash");
registerSoundRemapping("block.glass.break", "game.potion.smash");
registerSoundRemapping("block.note.bass", "note.bassattack");
registerSoundRemapping("block.dispenser.fail", "gui.button.press");
registerSoundRemapping("block.comparator.click", "gui.button.press");
registerSoundRemapping("block.stone_button.click_on", "gui.button.press");
registerSoundRemapping("block.stone_button.click_off", "gui.button.press");
registerSoundRemapping("block.tripwire.click_on", "gui.button.press");
registerSoundRemapping("block.dispenser.dispense", "gui.button.press");
registerSoundRemapping("ui.button.click", "gui.button.press");
registerSoundRemapping("block.lever.click", "gui.button.press");
registerSoundRemapping("block.tripwire.attach", "gui.button.press");
registerSoundRemapping("block.stone_pressureplate.click_on", "gui.button.press");
registerSoundRemapping("block.wood_pressureplate.click_off", "gui.button.press");
registerSoundRemapping("block.stone_pressureplate.click_off", "gui.button.press");
registerSoundRemapping("block.metal_pressureplate.click_off", "gui.button.press");
registerSoundRemapping("block.tripwire.click_off", "gui.button.press");
registerSoundRemapping("block.metal_pressureplate.click_on", "gui.button.press");
registerSoundRemapping("block.wood_pressureplate.click_on", "gui.button.press");
registerSoundRemapping("entity.experience_orb.touch", "random.orb");
registerSoundRemapping("entity.experience_orb.pickup", "random.orb");
registerSoundRemapping("entity.wither.break_block", "mob.zombie.woodbreak");
registerSoundRemapping("entity.zombie.break_door_wood", "mob.zombie.woodbreak");
registerSoundRemapping("entity.horse.armor", "mob.horse.armor");
registerSoundRemapping("entity.rabbit.ambient", "mob.rabbit.idle");
registerSoundRemapping("block.piston.contract", "tile.piston.in");
registerSoundRemapping("entity.cat.ambient", "mob.cat.meow");
registerSoundRemapping("entity.pig.step", "mob.pig.step");
registerSoundRemapping("record.strad", "records.strad");
registerSoundRemapping("block.wood.hit", "step.wood");
registerSoundRemapping("block.wood.fall", "step.wood");
registerSoundRemapping("block.wood.step", "step.wood");
registerSoundRemapping("block.portal.travel", "portal.travel");
registerSoundRemapping("entity.guardian.death", "mob.guardian.death");
registerSoundRemapping("entity.skeleton.death", "mob.skeleton.death");
registerSoundRemapping("entity.horse.hurt", "mob.horse.hit");
registerSoundRemapping("entity.villager.hurt", "mob.villager.hit");
registerSoundRemapping("entity.skeleton_horse.ambient", "mob.horse.skeleton.idle");
registerSoundRemapping("block.chest.open", "random.chestopen");
registerSoundRemapping("block.chest.close", "random.chestclosed");
registerSoundRemapping("entity.player.hurt_on_fire", "game.player.hurt");
registerSoundRemapping("entity.player.hurt_drown", "game.player.hurt");
registerSoundRemapping("entity.generic.swim", "game.neutral.swim");
registerSoundRemapping("entity.hostile.swim", "game.hostile.swim");
registerSoundRemapping("entity.player.swim", "game.player.swim");
registerSoundRemapping("entity.player.splash", "game.player.swim.splash");
registerSoundRemapping("entity.hostile.splash", "game.hostile.swim.splash");
registerSoundRemapping("entity.generic.splash", "game.neutral.swim.splash");
registerSoundRemapping("entity.generic.death", "game.neutral.die");
registerSoundRemapping("entity.hostile.hurt", "game.hostile.hurt");
registerSoundRemapping("entity.player.hurt", "game.player.hurt");
registerSoundRemapping("entity.hostile.death", "game.hostile.die");
registerSoundRemapping("entity.generic.hurt", "game.neutral.hurt");
registerSoundRemapping("entity.player.death", "game.player.die");
registerSoundRemapping("entity.player.big_fall", "game.player.hurt.fall.big");
registerSoundRemapping("entity.generic.big_fall", "game.neutral.hurt.fall.big");
registerSoundRemapping("entity.hostile.big_fall", "game.hostile.hurt.fall.big");
registerSoundRemapping("entity.hostile.small_fall", "game.hostile.hurt.fall.small");
registerSoundRemapping("entity.player.small_fall", "game.player.hurt.fall.small");
registerSoundRemapping("entity.generic.small_fall", "game.neutral.hurt.fall.small");
register1_9Sound("ambient.cave");
register1_9Sound("block.anvil.break");
register1_9Sound("block.anvil.destroy");
register1_9Sound("block.anvil.fall");
register1_9Sound("block.anvil.hit");
register1_9Sound("block.anvil.land");
register1_9Sound("block.anvil.place");
register1_9Sound("block.anvil.step");
register1_9Sound("block.anvil.use");
register1_9Sound("block.brewing_stand.brew");
register1_9Sound("block.chest.close");
register1_9Sound("block.chest.locked");
register1_9Sound("block.chest.open");
register1_9Sound("block.chorus_flower.death");
register1_9Sound("block.chorus_flower.grow");
register1_9Sound("block.cloth.break");
register1_9Sound("block.cloth.fall");
register1_9Sound("block.cloth.hit");
register1_9Sound("block.cloth.place");
register1_9Sound("block.cloth.step");
register1_9Sound("block.comparator.click");
register1_9Sound("block.dispenser.dispense");
register1_9Sound("block.dispenser.fail");
register1_9Sound("block.dispenser.launch");
register1_9Sound("block.end_gateway.spawn");
register1_9Sound("block.enderchest.close");
register1_9Sound("block.enderchest.open");
register1_9Sound("block.fence_gate.close");
register1_9Sound("block.fence_gate.open");
register1_9Sound("block.fire.ambient");
register1_9Sound("block.fire.extinguish");
register1_9Sound("block.furnace.fire_crackle");
register1_9Sound("block.glass.break");
register1_9Sound("block.glass.fall");
register1_9Sound("block.glass.hit");
register1_9Sound("block.glass.place");
register1_9Sound("block.glass.step");
register1_9Sound("block.grass.break");
register1_9Sound("block.grass.fall");
register1_9Sound("block.grass.hit");
register1_9Sound("block.grass.place");
register1_9Sound("block.grass.step");
register1_9Sound("block.gravel.break");
register1_9Sound("block.gravel.fall");
register1_9Sound("block.gravel.hit");
register1_9Sound("block.gravel.place");
register1_9Sound("block.gravel.step");
register1_9Sound("block.iron_door.close");
register1_9Sound("block.iron_door.open");
register1_9Sound("block.iron_trapdoor.close");
register1_9Sound("block.iron_trapdoor.open");
register1_9Sound("block.ladder.break");
register1_9Sound("block.ladder.fall");
register1_9Sound("block.ladder.hit");
register1_9Sound("block.ladder.place");
register1_9Sound("block.ladder.step");
register1_9Sound("block.lava.ambient");
register1_9Sound("block.lava.extinguish");
register1_9Sound("block.lava.pop");
register1_9Sound("block.lever.click");
register1_9Sound("block.metal.break");
register1_9Sound("block.metal.fall");
register1_9Sound("block.metal.hit");
register1_9Sound("block.metal.place");
register1_9Sound("block.metal.step");
register1_9Sound("block.metal_pressureplate.click_off");
register1_9Sound("block.metal_pressureplate.click_on");
register1_9Sound("block.note.basedrum");
register1_9Sound("block.note.bass");
register1_9Sound("block.note.harp");
register1_9Sound("block.note.hat");
register1_9Sound("block.note.pling");
register1_9Sound("block.note.snare");
register1_9Sound("block.piston.contract");
register1_9Sound("block.piston.extend");
register1_9Sound("block.portal.ambient");
register1_9Sound("block.portal.travel");
register1_9Sound("block.portal.trigger");
register1_9Sound("block.redstone_torch.burnout");
register1_9Sound("block.sand.break");
register1_9Sound("block.sand.fall");
register1_9Sound("block.sand.hit");
register1_9Sound("block.sand.place");
register1_9Sound("block.sand.step");
register1_9Sound("block.slime.break");
register1_9Sound("block.slime.fall");
register1_9Sound("block.slime.hit");
register1_9Sound("block.slime.place");
register1_9Sound("block.slime.step");
register1_9Sound("block.snow.break");
register1_9Sound("block.snow.fall");
register1_9Sound("block.snow.hit");
register1_9Sound("block.snow.place");
register1_9Sound("block.snow.step");
register1_9Sound("block.stone.break");
register1_9Sound("block.stone.fall");
register1_9Sound("block.stone.hit");
register1_9Sound("block.stone.place");
register1_9Sound("block.stone.step");
register1_9Sound("block.stone_button.click_off");
register1_9Sound("block.stone_button.click_on");
register1_9Sound("block.stone_pressureplate.click_off");
register1_9Sound("block.stone_pressureplate.click_on");
register1_9Sound("block.tripwire.attach");
register1_9Sound("block.tripwire.click_off");
register1_9Sound("block.tripwire.click_on");
register1_9Sound("block.tripwire.detach");
register1_9Sound("block.water.ambient");
register1_9Sound("block.waterlily.place");
register1_9Sound("block.wood.break");
register1_9Sound("block.wood.fall");
register1_9Sound("block.wood.hit");
register1_9Sound("block.wood.place");
register1_9Sound("block.wood.step");
register1_9Sound("block.wood_button.click_off");
register1_9Sound("block.wood_button.click_on");
register1_9Sound("block.wood_pressureplate.click_off");
register1_9Sound("block.wood_pressureplate.click_on");
register1_9Sound("block.wooden_door.close");
register1_9Sound("block.wooden_door.open");
register1_9Sound("block.wooden_trapdoor.close");
register1_9Sound("block.wooden_trapdoor.open");
register1_9Sound("enchant.thorns.hit");
register1_9Sound("entity.armorstand.break");
register1_9Sound("entity.armorstand.fall");
register1_9Sound("entity.armorstand.hit");
register1_9Sound("entity.armorstand.place");
register1_9Sound("entity.arrow.hit");
register1_9Sound("entity.arrow.hit_player");
register1_9Sound("entity.arrow.shoot");
register1_9Sound("entity.bat.ambient");
register1_9Sound("entity.bat.death");
register1_9Sound("entity.bat.hurt");
register1_9Sound("entity.bat.loop");
register1_9Sound("entity.bat.takeoff");
register1_9Sound("entity.blaze.ambient");
register1_9Sound("entity.blaze.burn");
register1_9Sound("entity.blaze.death");
register1_9Sound("entity.blaze.hurt");
register1_9Sound("entity.blaze.shoot");
register1_9Sound("entity.bobber.splash");
register1_9Sound("entity.bobber.throw");
register1_9Sound("entity.cat.ambient");
register1_9Sound("entity.cat.death");
register1_9Sound("entity.cat.hiss");
register1_9Sound("entity.cat.hurt");
register1_9Sound("entity.cat.purr");
register1_9Sound("entity.cat.purreow");
register1_9Sound("entity.chicken.ambient");
register1_9Sound("entity.chicken.death");
register1_9Sound("entity.chicken.egg");
register1_9Sound("entity.chicken.hurt");
register1_9Sound("entity.chicken.step");
register1_9Sound("entity.cow.ambient");
register1_9Sound("entity.cow.death");
register1_9Sound("entity.cow.hurt");
register1_9Sound("entity.cow.milk");
register1_9Sound("entity.cow.step");
register1_9Sound("entity.creeper.death");
register1_9Sound("entity.creeper.hurt");
register1_9Sound("entity.creeper.primed");
register1_9Sound("entity.donkey.ambient");
register1_9Sound("entity.donkey.angry");
register1_9Sound("entity.donkey.chest");
register1_9Sound("entity.donkey.death");
register1_9Sound("entity.donkey.hurt");
register1_9Sound("entity.egg.throw");
register1_9Sound("entity.elder_guardian.ambient");
register1_9Sound("entity.elder_guardian.ambient_land");
register1_9Sound("entity.elder_guardian.curse");
register1_9Sound("entity.elder_guardian.death");
register1_9Sound("entity.elder_guardian.death_land");
register1_9Sound("entity.elder_guardian.hurt");
register1_9Sound("entity.elder_guardian.hurt_land");
register1_9Sound("entity.enderdragon.ambient");
register1_9Sound("entity.enderdragon.death");
register1_9Sound("entity.enderdragon.flap");
register1_9Sound("entity.enderdragon.growl");
register1_9Sound("entity.enderdragon.hurt");
register1_9Sound("entity.enderdragon.shoot");
register1_9Sound("entity.enderdragon_fireball.explode");
register1_9Sound("entity.endereye.launch");
register1_9Sound("entity.endermen.ambient");
register1_9Sound("entity.endermen.death");
register1_9Sound("entity.endermen.hurt");
register1_9Sound("entity.endermen.scream");
register1_9Sound("entity.endermen.stare");
register1_9Sound("entity.endermen.teleport");
register1_9Sound("entity.endermite.ambient");
register1_9Sound("entity.endermite.death");
register1_9Sound("entity.endermite.hurt");
register1_9Sound("entity.endermite.step");
register1_9Sound("entity.enderpearl.throw");
register1_9Sound("entity.experience_bottle.throw");
register1_9Sound("entity.experience_orb.pickup");
register1_9Sound("entity.experience_orb.touch");
register1_9Sound("entity.firework.blast");
register1_9Sound("entity.firework.blast_far");
register1_9Sound("entity.firework.large_blast");
register1_9Sound("entity.firework.large_blast_far");
register1_9Sound("entity.firework.launch");
register1_9Sound("entity.firework.shoot");
register1_9Sound("entity.firework.twinkle");
register1_9Sound("entity.firework.twinkle_far");
register1_9Sound("entity.generic.big_fall");
register1_9Sound("entity.generic.burn");
register1_9Sound("entity.generic.death");
register1_9Sound("entity.generic.drink");
register1_9Sound("entity.generic.eat");
register1_9Sound("entity.generic.explode");
register1_9Sound("entity.generic.extinguish_fire");
register1_9Sound("entity.generic.hurt");
register1_9Sound("entity.generic.small_fall");
register1_9Sound("entity.generic.splash");
register1_9Sound("entity.generic.swim");
register1_9Sound("entity.ghast.ambient");
register1_9Sound("entity.ghast.death");
register1_9Sound("entity.ghast.hurt");
register1_9Sound("entity.ghast.scream");
register1_9Sound("entity.ghast.shoot");
register1_9Sound("entity.ghast.warn");
register1_9Sound("entity.guardian.ambient");
register1_9Sound("entity.guardian.ambient_land");
register1_9Sound("entity.guardian.attack");
register1_9Sound("entity.guardian.death");
register1_9Sound("entity.guardian.death_land");
register1_9Sound("entity.guardian.flop");
register1_9Sound("entity.guardian.hurt");
register1_9Sound("entity.guardian.hurt_land");
register1_9Sound("entity.horse.ambient");
register1_9Sound("entity.horse.angry");
register1_9Sound("entity.horse.armor");
register1_9Sound("entity.horse.breathe");
register1_9Sound("entity.horse.death");
register1_9Sound("entity.horse.eat");
register1_9Sound("entity.horse.gallop");
register1_9Sound("entity.horse.hurt");
register1_9Sound("entity.horse.jump");
register1_9Sound("entity.horse.land");
register1_9Sound("entity.horse.saddle");
register1_9Sound("entity.horse.step");
register1_9Sound("entity.horse.step_wood");
register1_9Sound("entity.hostile.big_fall");
register1_9Sound("entity.hostile.death");
register1_9Sound("entity.hostile.hurt");
register1_9Sound("entity.hostile.small_fall");
register1_9Sound("entity.hostile.splash");
register1_9Sound("entity.hostile.swim");
register1_9Sound("entity.irongolem.attack");
register1_9Sound("entity.irongolem.death");
register1_9Sound("entity.irongolem.hurt");
register1_9Sound("entity.irongolem.step");
register1_9Sound("entity.item.break");
register1_9Sound("entity.item.pickup");
register1_9Sound("entity.itemframe.add_item");
register1_9Sound("entity.itemframe.break");
register1_9Sound("entity.itemframe.place");
register1_9Sound("entity.itemframe.remove_item");
register1_9Sound("entity.itemframe.rotate_item");
register1_9Sound("entity.leashknot.break");
register1_9Sound("entity.leashknot.place");
register1_9Sound("entity.lightning.impact");
register1_9Sound("entity.lightning.thunder");
register1_9Sound("entity.lingeringpotion.throw");
register1_9Sound("entity.magmacube.death");
register1_9Sound("entity.magmacube.hurt");
register1_9Sound("entity.magmacube.jump");
register1_9Sound("entity.magmacube.squish");
register1_9Sound("entity.minecart.inside");
register1_9Sound("entity.minecart.riding");
register1_9Sound("entity.mooshroom.shear");
register1_9Sound("entity.mule.ambient");
register1_9Sound("entity.mule.death");
register1_9Sound("entity.mule.hurt");
register1_9Sound("entity.painting.break");
register1_9Sound("entity.painting.place");
register1_9Sound("entity.pig.ambient");
register1_9Sound("entity.pig.death");
register1_9Sound("entity.pig.hurt");
register1_9Sound("entity.pig.saddle");
register1_9Sound("entity.pig.step");
register1_9Sound("entity.player.attack.crit");
register1_9Sound("entity.player.attack.knockback");
register1_9Sound("entity.player.attack.nodamage");
register1_9Sound("entity.player.attack.strong");
register1_9Sound("entity.player.attack.sweep");
register1_9Sound("entity.player.attack.weak");
register1_9Sound("entity.player.big_fall");
register1_9Sound("entity.player.breath");
register1_9Sound("entity.player.burp");
register1_9Sound("entity.player.death");
register1_9Sound("entity.player.hurt");
register1_9Sound("entity.player.levelup");
register1_9Sound("entity.player.small_fall");
register1_9Sound("entity.player.splash");
register1_9Sound("entity.player.swim");
register1_9Sound("entity.rabbit.ambient");
register1_9Sound("entity.rabbit.attack");
register1_9Sound("entity.rabbit.death");
register1_9Sound("entity.rabbit.hurt");
register1_9Sound("entity.rabbit.jump");
register1_9Sound("entity.sheep.ambient");
register1_9Sound("entity.sheep.death");
register1_9Sound("entity.sheep.hurt");
register1_9Sound("entity.sheep.shear");
register1_9Sound("entity.sheep.step");
register1_9Sound("entity.shulker.ambient");
register1_9Sound("entity.shulker.close");
register1_9Sound("entity.shulker.death");
register1_9Sound("entity.shulker.hurt");
register1_9Sound("entity.shulker.hurt_closed");
register1_9Sound("entity.shulker.open");
register1_9Sound("entity.shulker.shoot");
register1_9Sound("entity.shulker.teleport");
register1_9Sound("entity.shulker_bullet.hit");
register1_9Sound("entity.shulker_bullet.hurt");
register1_9Sound("entity.silverfish.ambient");
register1_9Sound("entity.silverfish.death");
register1_9Sound("entity.silverfish.hurt");
register1_9Sound("entity.silverfish.step");
register1_9Sound("entity.skeleton.ambient");
register1_9Sound("entity.skeleton.death");
register1_9Sound("entity.skeleton.hurt");
register1_9Sound("entity.skeleton.shoot");
register1_9Sound("entity.skeleton.step");
register1_9Sound("entity.skeleton_horse.ambient");
register1_9Sound("entity.skeleton_horse.death");
register1_9Sound("entity.skeleton_horse.hurt");
register1_9Sound("entity.slime.attack");
register1_9Sound("entity.slime.death");
register1_9Sound("entity.slime.hurt");
register1_9Sound("entity.slime.jump");
register1_9Sound("entity.slime.squish");
register1_9Sound("entity.small_magmacube.death");
register1_9Sound("entity.small_magmacube.hurt");
register1_9Sound("entity.small_magmacube.squish");
register1_9Sound("entity.small_slime.death");
register1_9Sound("entity.small_slime.hurt");
register1_9Sound("entity.small_slime.jump");
register1_9Sound("entity.small_slime.squish");
register1_9Sound("entity.snowball.throw");
register1_9Sound("entity.snowman.ambient");
register1_9Sound("entity.snowman.death");
register1_9Sound("entity.snowman.hurt");
register1_9Sound("entity.snowman.shoot");
register1_9Sound("entity.spider.ambient");
register1_9Sound("entity.spider.death");
register1_9Sound("entity.spider.hurt");
register1_9Sound("entity.spider.step");
register1_9Sound("entity.splash_potion.break");
register1_9Sound("entity.splash_potion.throw");
register1_9Sound("entity.squid.ambient");
register1_9Sound("entity.squid.death");
register1_9Sound("entity.squid.hurt");
register1_9Sound("entity.tnt.primed");
register1_9Sound("entity.villager.ambient");
register1_9Sound("entity.villager.death");
register1_9Sound("entity.villager.hurt");
register1_9Sound("entity.villager.no");
register1_9Sound("entity.villager.trading");
register1_9Sound("entity.villager.yes");
register1_9Sound("entity.witch.ambient");
register1_9Sound("entity.witch.death");
register1_9Sound("entity.witch.drink");
register1_9Sound("entity.witch.hurt");
register1_9Sound("entity.witch.throw");
register1_9Sound("entity.wither.ambient");
register1_9Sound("entity.wither.break_block");
register1_9Sound("entity.wither.death");
register1_9Sound("entity.wither.hurt");
register1_9Sound("entity.wither.shoot");
register1_9Sound("entity.wither.spawn");
register1_9Sound("entity.wolf.ambient");
register1_9Sound("entity.wolf.death");
register1_9Sound("entity.wolf.growl");
register1_9Sound("entity.wolf.howl");
register1_9Sound("entity.wolf.hurt");
register1_9Sound("entity.wolf.pant");
register1_9Sound("entity.wolf.shake");
register1_9Sound("entity.wolf.step");
register1_9Sound("entity.wolf.whine");
register1_9Sound("entity.zombie.ambient");
register1_9Sound("entity.zombie.attack_door_wood");
register1_9Sound("entity.zombie.attack_iron_door");
register1_9Sound("entity.zombie.break_door_wood");
register1_9Sound("entity.zombie.death");
register1_9Sound("entity.zombie.hurt");
register1_9Sound("entity.zombie.infect");
register1_9Sound("entity.zombie.step");
register1_9Sound("entity.zombie_horse.ambient");
register1_9Sound("entity.zombie_horse.death");
register1_9Sound("entity.zombie_horse.hurt");
register1_9Sound("entity.zombie_pig.ambient");
register1_9Sound("entity.zombie_pig.angry");
register1_9Sound("entity.zombie_pig.death");
register1_9Sound("entity.zombie_pig.hurt");
register1_9Sound("entity.zombie_villager.ambient");
register1_9Sound("entity.zombie_villager.converted");
register1_9Sound("entity.zombie_villager.cure");
register1_9Sound("entity.zombie_villager.death");
register1_9Sound("entity.zombie_villager.hurt");
register1_9Sound("entity.zombie_villager.step");
register1_9Sound("item.armor.equip_chain");
register1_9Sound("item.armor.equip_diamond");
register1_9Sound("item.armor.equip_generic");
register1_9Sound("item.armor.equip_gold");
register1_9Sound("item.armor.equip_iron");
register1_9Sound("item.armor.equip_leather");
register1_9Sound("item.bottle.fill");
register1_9Sound("item.bottle.fill_dragonbreath");
register1_9Sound("item.bucket.empty");
register1_9Sound("item.bucket.empty_lava");
register1_9Sound("item.bucket.fill");
register1_9Sound("item.bucket.fill_lava");
register1_9Sound("item.chorus_fruit.teleport");
register1_9Sound("item.firecharge.use");
register1_9Sound("item.flintandsteel.use");
register1_9Sound("item.hoe.till");
register1_9Sound("item.shield.block");
register1_9Sound("item.shield.break");
register1_9Sound("item.shovel.flatten");
register1_9Sound("music.creative");
register1_9Sound("music.credits");
register1_9Sound("music.dragon");
register1_9Sound("music.end");
register1_9Sound("music.game");
register1_9Sound("music.menu");
register1_9Sound("music.nether");
register1_9Sound("record.11");
register1_9Sound("record.13");
register1_9Sound("record.blocks");
register1_9Sound("record.cat");
register1_9Sound("record.chirp");
register1_9Sound("record.far");
register1_9Sound("record.mall");
register1_9Sound("record.mellohi");
register1_9Sound("record.stal");
register1_9Sound("record.strad");
register1_9Sound("record.wait");
register1_9Sound("record.ward");
register1_9Sound("ui.button.click");
register1_9Sound("weather.rain");
register1_9Sound("weather.rain.above");
}
}
@@ -1,232 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.storage;
import com.viaversion.viarewind.api.ViaRewindConfig;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.utils.Tickable;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonPrimitive;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.util.Pair;
import com.viaversion.viarewind.ViaRewind;
import java.util.ArrayList;
import java.util.UUID;
public class Cooldown extends StoredObject implements Tickable {
private double attackSpeed = 4.0;
private long lastHit = 0;
private final ViaRewindConfig.CooldownIndicator cooldownIndicator;
private UUID bossUUID;
private boolean lastSend;
public Cooldown(final UserConnection user) {
super(user);
ViaRewindConfig.CooldownIndicator indicator;
try {
indicator = ViaRewind.getConfig().getCooldownIndicator();
} catch (IllegalArgumentException e) {
ViaRewind.getPlatform().getLogger().warning("Invalid cooldown-indicator setting");
indicator = ViaRewindConfig.CooldownIndicator.DISABLED;
}
this.cooldownIndicator = indicator;
}
@Override
public void tick() {
if (!hasCooldown()) {
if (lastSend) {
hide();
lastSend = false;
}
return;
}
BlockPlaceDestroyTracker tracker = getUser().get(BlockPlaceDestroyTracker.class);
if (tracker.isMining()) {
lastHit = 0;
if (lastSend) {
hide();
lastSend = false;
}
return;
}
showCooldown();
lastSend = true;
}
private void showCooldown() {
if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.TITLE) {
sendTitle("", getTitle(), 0, 2, 5);
} else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.ACTION_BAR) {
sendActionBar(getTitle());
} else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.BOSS_BAR) {
sendBossBar((float) getCooldown());
}
}
private void hide() {
if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.ACTION_BAR) {
sendActionBar("§r");
} else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.TITLE) {
hideTitle();
} else if (cooldownIndicator == ViaRewindConfig.CooldownIndicator.BOSS_BAR) {
hideBossBar();
}
}
private void hideBossBar() {
if (bossUUID == null) return;
PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, null, getUser());
wrapper.write(Type.UUID, bossUUID);
wrapper.write(Type.VAR_INT, 1);
PacketUtil.sendPacket(wrapper, Protocol1_8To1_9.class, false, true);
bossUUID = null;
}
private void sendBossBar(float cooldown) {
PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_9.BOSSBAR, getUser());
if (bossUUID == null) {
bossUUID = UUID.randomUUID();
wrapper.write(Type.UUID, bossUUID);
wrapper.write(Type.VAR_INT, 0);
wrapper.write(Type.COMPONENT, new JsonPrimitive(" "));
wrapper.write(Type.FLOAT, cooldown);
wrapper.write(Type.VAR_INT, 0);
wrapper.write(Type.VAR_INT, 0);
wrapper.write(Type.UNSIGNED_BYTE, (short) 0);
} else {
wrapper.write(Type.UUID, bossUUID);
wrapper.write(Type.VAR_INT, 2);
wrapper.write(Type.FLOAT, cooldown);
}
PacketUtil.sendPacket(wrapper, Protocol1_8To1_9.class, false, true);
}
private void hideTitle() {
PacketWrapper hide = PacketWrapper.create(ClientboundPackets1_8.TITLE, null, getUser());
hide.write(Type.VAR_INT, 3);
PacketUtil.sendPacket(hide, Protocol1_8To1_9.class);
}
private void sendTitle(String title, String subTitle, int fadeIn, int stay, int fadeOut) {
PacketWrapper timePacket = PacketWrapper.create(ClientboundPackets1_8.TITLE, null, getUser());
timePacket.write(Type.VAR_INT, 2);
timePacket.write(Type.INT, fadeIn);
timePacket.write(Type.INT, stay);
timePacket.write(Type.INT, fadeOut);
PacketWrapper titlePacket = PacketWrapper.create(ClientboundPackets1_8.TITLE, getUser());
titlePacket.write(Type.VAR_INT, 0);
titlePacket.write(Type.COMPONENT, new JsonPrimitive(title));
PacketWrapper subtitlePacket = PacketWrapper.create(ClientboundPackets1_8.TITLE, getUser());
subtitlePacket.write(Type.VAR_INT, 1);
subtitlePacket.write(Type.COMPONENT, new JsonPrimitive(subTitle));
PacketUtil.sendPacket(titlePacket, Protocol1_8To1_9.class);
PacketUtil.sendPacket(subtitlePacket, Protocol1_8To1_9.class);
PacketUtil.sendPacket(timePacket, Protocol1_8To1_9.class);
}
private void sendActionBar(String bar) {
PacketWrapper actionBarPacket = PacketWrapper.create(ClientboundPackets1_8.CHAT_MESSAGE, getUser());
actionBarPacket.write(Type.COMPONENT, new JsonPrimitive(bar));
actionBarPacket.write(Type.BYTE, (byte) 2);
PacketUtil.sendPacket(actionBarPacket, Protocol1_8To1_9.class);
}
public boolean hasCooldown() {
long time = System.currentTimeMillis() - lastHit;
double cooldown = restrain(((double) time) * attackSpeed / 1000d, 0, 1.5);
return cooldown > 0.1 && cooldown < 1.1;
}
public double getCooldown() {
long time = System.currentTimeMillis() - lastHit;
return restrain(((double) time) * attackSpeed / 1000d, 0, 1);
}
private double restrain(double x, double a, double b) {
if (x < a) return a;
return Math.min(x, b);
}
private static final int max = 10;
private String getTitle() {
String symbol = cooldownIndicator == ViaRewindConfig.CooldownIndicator.ACTION_BAR ? "■" : "˙";
double cooldown = getCooldown();
int green = (int) Math.floor(((double) max) * cooldown);
int grey = max - green;
StringBuilder builder = new StringBuilder("§8");
while (green-- > 0) builder.append(symbol);
builder.append("§7");
while (grey-- > 0) builder.append(symbol);
return builder.toString();
}
public double getAttackSpeed() {
return attackSpeed;
}
public void setAttackSpeed(double attackSpeed) {
this.attackSpeed = attackSpeed;
}
public void setAttackSpeed(double base, ArrayList<Pair<Byte, Double>> modifiers) {
attackSpeed = base;
for (int j = 0; j < modifiers.size(); j++) {
if (modifiers.get(j).key() == 0) {
attackSpeed += modifiers.get(j).value();
modifiers.remove(j--);
}
}
for (int j = 0; j < modifiers.size(); j++) {
if (modifiers.get(j).key() == 1) {
attackSpeed += base * modifiers.get(j).value();
modifiers.remove(j--);
}
}
for (int j = 0; j < modifiers.size(); j++) {
if (modifiers.get(j).key() == 2) {
attackSpeed *= (1.0 + modifiers.get(j).value());
modifiers.remove(j--);
}
}
}
public void hit() {
lastHit = System.currentTimeMillis();
}
public void setLastHit(long lastHit) {
this.lastHit = lastHit;
}
}
@@ -1,183 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.storage;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.metadata.MetadataRewriter;
import com.viaversion.viarewind.replacement.EntityReplacement;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.ClientEntityIdChangeListener;
import com.viaversion.viaversion.api.minecraft.Vector;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_10Types;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_8;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class EntityTracker extends StoredObject implements ClientEntityIdChangeListener {
private final Map<Integer, List<Integer>> vehicleMap = new ConcurrentHashMap<>();
private final Map<Integer, Entity1_10Types.EntityType> clientEntityTypes = new ConcurrentHashMap<>();
private final Map<Integer, List<Metadata>> metadataBuffer = new ConcurrentHashMap<>();
private final Map<Integer, EntityReplacement> entityReplacements = new ConcurrentHashMap<>();
private final Map<Integer, Vector> entityOffsets = new ConcurrentHashMap<>();
private int playerId;
private int playerGamemode = 0;
public EntityTracker(UserConnection user) {
super(user);
}
public void setPlayerId(int entityId) {
playerId = entityId;
}
public int getPlayerId() {
return playerId;
}
public int getPlayerGamemode() {
return playerGamemode;
}
public void setPlayerGamemode(int playerGamemode) {
this.playerGamemode = playerGamemode;
}
public void removeEntity(int entityId) {
vehicleMap.remove(entityId);
vehicleMap.forEach((vehicle, passengers) -> passengers.remove((Integer) entityId));
vehicleMap.entrySet().removeIf(entry -> entry.getValue().isEmpty());
clientEntityTypes.remove(entityId);
entityOffsets.remove(entityId);
if (entityReplacements.containsKey(entityId)) {
entityReplacements.remove(entityId).despawn();
}
}
public void resetEntityOffset(int entityId) {
entityOffsets.remove(entityId);
}
public Vector getEntityOffset(int entityId) {
return entityOffsets.get(entityId);
}
public void addToEntityOffset(int entityId, short relX, short relY, short relZ) {
entityOffsets.compute(entityId, (key, offset) -> {
if (offset == null) {
return new Vector(relX, relY, relZ);
} else {
return new Vector(offset.blockX() + relX, offset.blockY() + relY, offset.blockZ() + relZ);
}
});
}
public void setEntityOffset(int entityId, short relX, short relY, short relZ) {
entityOffsets.compute(entityId, (key, offset) -> new Vector(relX, relY, relZ));
}
public void setEntityOffset(int entityId, Vector offset) {
entityOffsets.put(entityId, offset);
}
public List<Integer> getPassengers(int entityId) {
return vehicleMap.getOrDefault(entityId, new ArrayList<>());
}
public void setPassengers(int entityId, List<Integer> passengers) {
vehicleMap.put(entityId, passengers);
}
public void addEntityReplacement(EntityReplacement entityReplacement) {
entityReplacements.put(entityReplacement.getEntityId(), entityReplacement);
}
public EntityReplacement getEntityReplacement(int entityId) {
return entityReplacements.get(entityId);
}
public Map<Integer, Entity1_10Types.EntityType> getClientEntityTypes() {
return this.clientEntityTypes;
}
public void addMetadataToBuffer(int entityID, List<Metadata> metadataList) {
if (this.metadataBuffer.containsKey(entityID)) {
this.metadataBuffer.get(entityID).addAll(metadataList);
} else if (!metadataList.isEmpty()) {
this.metadataBuffer.put(entityID, metadataList);
}
}
public List<Metadata> getBufferedMetadata(int entityId) {
return metadataBuffer.get(entityId);
}
public boolean isInsideVehicle(int entityId) {
for (List<Integer> vehicle : vehicleMap.values()) {
if (vehicle.contains(entityId)) return true;
}
return false;
}
public int getVehicle(int passenger) {
for (Map.Entry<Integer, List<Integer>> vehicle : vehicleMap.entrySet()) {
if (vehicle.getValue().contains(passenger)) return vehicle.getKey();
}
return -1;
}
public boolean isPassenger(int vehicle, int passenger) {
return vehicleMap.containsKey(vehicle) && vehicleMap.get(vehicle).contains(passenger);
}
public void sendMetadataBuffer(int entityId) {
if (!this.metadataBuffer.containsKey(entityId)) return;
if (entityReplacements.containsKey(entityId)) {
entityReplacements.get(entityId).updateMetadata(this.metadataBuffer.remove(entityId));
} else {
PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_8.ENTITY_METADATA, this.getUser());
wrapper.write(Type.VAR_INT, entityId);
wrapper.write(Types1_8.METADATA_LIST, this.metadataBuffer.get(entityId));
MetadataRewriter.transform(this.getClientEntityTypes().get(entityId), this.metadataBuffer.get(entityId));
if (!this.metadataBuffer.get(entityId).isEmpty()) {
try {
wrapper.send(Protocol1_8To1_9.class);
} catch (Exception ex) {
ex.printStackTrace();
}
}
this.metadataBuffer.remove(entityId);
}
}
@Override
public void setClientEntityId(int playerEntityId) {
clientEntityTypes.remove(this.playerId);
this.playerId = playerEntityId;
clientEntityTypes.put(this.playerId, Entity1_10Types.EntityType.ENTITY_HUMAN);
}
}
@@ -1,59 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.storage;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viarewind.utils.Tickable;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
public class Levitation extends StoredObject implements Tickable {
private int amplifier;
private volatile boolean active = false;
public Levitation(UserConnection user) {
super(user);
}
@Override
public void tick() {
if (!active) {
return;
}
int vY = (amplifier+1) * 360;
PacketWrapper packet = PacketWrapper.create(0x12, null, Levitation.this.getUser());
packet.write(Type.VAR_INT, getUser().get(EntityTracker.class).getPlayerId());
packet.write(Type.SHORT, (short)0);
packet.write(Type.SHORT, (short)vY);
packet.write(Type.SHORT, (short)0);
PacketUtil.sendPacket(packet, Protocol1_8To1_9.class);
}
public void setActive(boolean active) {
this.active = active;
}
public void setAmplifier(int amplifier) {
this.amplifier = amplifier;
}
}
@@ -1,133 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.storage;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
public class PlayerPosition extends StoredObject {
private double posX, posY, posZ;
private float yaw, pitch;
private boolean onGround;
private int confirmId = -1;
public PlayerPosition(UserConnection user) {
super(user);
}
public void setPos(double x, double y, double z) {
this.posX = x;
this.posY = y;
this.posZ = z;
}
public void setYaw(float yaw) {
this.yaw = yaw % 360f;
}
public void setPitch(float pitch) {
this.pitch = pitch % 360f;
}
public double getPosX() {
return this.posX;
}
public double getPosY() {
return this.posY;
}
public double getPosZ() {
return this.posZ;
}
public float getYaw() {
return this.yaw;
}
public float getPitch() {
return this.pitch;
}
public boolean isOnGround() {
return this.onGround;
}
public int getConfirmId() {
return this.confirmId;
}
public void setPosX(double posX) {
this.posX = posX;
}
public void setPosY(double posY) {
this.posY = posY;
}
public void setPosZ(double posZ) {
this.posZ = posZ;
}
public void setOnGround(boolean onGround) {
this.onGround = onGround;
}
public void setConfirmId(int confirmId) {
this.confirmId = confirmId;
}
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof PlayerPosition)) return false;
final PlayerPosition other = (PlayerPosition) o;
if (!other.canEqual(this)) return false;
if (Double.compare(this.getPosX(), other.getPosX()) != 0) return false;
if (Double.compare(this.getPosY(), other.getPosY()) != 0) return false;
if (Double.compare(this.getPosZ(), other.getPosZ()) != 0) return false;
if (Float.compare(this.getYaw(), other.getYaw()) != 0) return false;
if (Float.compare(this.getPitch(), other.getPitch()) != 0) return false;
if (this.isOnGround() != other.isOnGround()) return false;
return this.getConfirmId() == other.getConfirmId();
}
protected boolean canEqual(final Object other) {
return other instanceof PlayerPosition;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final long $posX = Double.doubleToLongBits(this.getPosX());
result = result * PRIME + (int) ($posX >>> 32 ^ $posX);
final long $posY = Double.doubleToLongBits(this.getPosY());
result = result * PRIME + (int) ($posY >>> 32 ^ $posY);
final long $posZ = Double.doubleToLongBits(this.getPosZ());
result = result * PRIME + (int) ($posZ >>> 32 ^ $posZ);
result = result * PRIME + Float.floatToIntBits(this.getYaw());
result = result * PRIME + Float.floatToIntBits(this.getPitch());
result = result * PRIME + (this.isOnGround() ? 79 : 97);
result = result * PRIME + this.getConfirmId();
return result;
}
public String toString() {
return "PlayerPosition(posX=" + this.getPosX() + ", posY=" + this.getPosY() + ", posZ=" + this.getPosZ() + ", yaw=" + this.getYaw() + ", pitch=" + this.getPitch() + ", onGround=" + this.isOnGround() + ", confirmId=" + this.getConfirmId() + ")";
}
}
@@ -1,90 +0,0 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 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 com.viaversion.viarewind.protocol.protocol1_8to1_9.storage;
import com.viaversion.viarewind.protocol.protocol1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viarewind.utils.PacketUtil;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.DataItem;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.kyori.adventure.text.Component;
import com.viaversion.viaversion.libs.kyori.adventure.text.format.NamedTextColor;
import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import java.util.HashMap;
public class Windows extends StoredObject {
private final HashMap<Short, String> types = new HashMap<>();
private final HashMap<Short, Item[]> brewingItems = new HashMap<>();
public Windows(UserConnection user) {
super(user);
}
public String get(short windowId) {
return types.get(windowId);
}
public void put(short windowId, String type) {
types.put(windowId, type);
}
public void remove(short windowId) {
types.remove(windowId);
brewingItems.remove(windowId);
}
public Item[] getBrewingItems(short windowId) {
return brewingItems.computeIfAbsent(windowId, key -> new Item[] {
new DataItem(),
new DataItem(),
new DataItem(),
new DataItem()
});
}
public static void updateBrewingStand(UserConnection user, Item blazePowder, short windowId) {
if (blazePowder != null && blazePowder.identifier() != 377) return;
int amount = blazePowder == null ? 0 : blazePowder.amount();
PacketWrapper openWindow = PacketWrapper.create(ClientboundPackets1_8.OPEN_WINDOW, user);
openWindow.write(Type.UNSIGNED_BYTE, windowId);
openWindow.write(Type.STRING, "minecraft:brewing_stand");
Component title = Component.empty()
.append(Component.translatable("container.brewing"))
.append(Component.text(": ", NamedTextColor.DARK_GRAY))
.append(Component.text(amount + " ", NamedTextColor.DARK_RED))
.append(Component.translatable("item.blazePowder.name", NamedTextColor.DARK_RED));
openWindow.write(Type.COMPONENT, GsonComponentSerializer.colorDownsamplingGson().serializeToTree(title));
openWindow.write(Type.UNSIGNED_BYTE, (short) 420);
PacketUtil.sendPacket(openWindow, Protocol1_8To1_9.class);
Item[] items = user.get(Windows.class).getBrewingItems(windowId);
for (int i = 0; i < items.length; i++) {
PacketWrapper setSlot = PacketWrapper.create(ClientboundPackets1_8.SET_SLOT, user);
setSlot.write(Type.UNSIGNED_BYTE, windowId);
setSlot.write(Type.SHORT, (short) i);
setSlot.write(Type.ITEM, items[i]);
PacketUtil.sendPacket(setSlot, Protocol1_8To1_9.class);
}
}
}
@@ -0,0 +1,116 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5;
import com.viaversion.viarewind.api.type.version.Types1_7_6_10;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ServerboundPackets1_7_2_5;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class Protocol1_7_6_10To1_7_2_5 extends AbstractProtocol<ClientboundPackets1_7_2_5, ClientboundPackets1_7_2_5, ServerboundPackets1_7_2_5, ServerboundPackets1_7_2_5> {
public static final ValueTransformer<String, String> REMOVE_DASHES = new ValueTransformer<>(Types.STRING) {
@Override
public String transform(PacketWrapper wrapper, String s) {
return s.replace("-", "");
}
};
public Protocol1_7_6_10To1_7_2_5() {
super(ClientboundPackets1_7_2_5.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class, ServerboundPackets1_7_2_5.class);
}
@Override
protected void registerPackets() {
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), new PacketHandlers() {
@Override
public void register() {
map(Types.STRING, REMOVE_DASHES); // Uuid
map(Types.STRING); // Name
}
});
this.registerClientbound(ClientboundPackets1_7_2_5.ADD_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // Entity id
map(Types.STRING, REMOVE_DASHES); // Uuid
map(Types.STRING); // Name
handler(wrapper -> {
final int size = wrapper.read(Types.VAR_INT); // Data count
for (int i = 0; i < size; i++) {
wrapper.read(Types.STRING); // Data name
wrapper.read(Types.STRING); // Data value
wrapper.read(Types.STRING); // Data signature
}
});
map(Types.INT); // X
map(Types.INT); // Y
map(Types.INT); // Z
map(Types.BYTE); // Yaw
map(Types.BYTE); // Pitch
map(Types.SHORT); // Item in hand
map(Types1_7_6_10.ENTITY_DATA_LIST); // Entity data
}
});
this.registerClientbound(ClientboundPackets1_7_2_5.SET_PLAYER_TEAM, new PacketHandlers() {
@Override
public void register() {
map(Types.STRING); // Team name
map(Types.BYTE); // Mode
handler(wrapper -> {
final byte mode = wrapper.get(Types.BYTE, 0);
if (mode == 0 || mode == 2) { // Team is created or information is updated
wrapper.passthrough(Types.STRING); // Team display name
wrapper.passthrough(Types.STRING); // Team prefix
wrapper.passthrough(Types.STRING); // Team suffix
wrapper.passthrough(Types.BYTE); // Friendly fire
}
if (mode == 0 || mode == 3 || mode == 4) { // Team is created, player is added or player is removed
List<String> entryList = new ArrayList<>();
final int size = wrapper.read(Types.SHORT);
for (int i = 0; i < size; i++) {
entryList.add(wrapper.read(Types.STRING));
}
entryList = entryList.stream()
.map(it -> it.length() > 16 ? it.substring(0, 16) : it) // trim to 16 characters
.distinct() // remove duplicates
.collect(Collectors.toList());
wrapper.write(Types.SHORT, (short) entryList.size());
for (String entry : entryList) {
wrapper.write(Types.STRING, entry);
}
}
});
}
});
}
}
@@ -0,0 +1,98 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_7_2_5 implements ClientboundPacketType {
KEEP_ALIVE, // 0x00
LOGIN, // 0x01
CHAT, // 0x02
SET_TIME, // 0x03
SET_EQUIPPED_ITEM, // 0x04
SET_DEFAULT_SPAWN_POSITION, // 0x05
SET_HEALTH, // 0x06
RESPAWN, // 0x07
PLAYER_POSITION, // 0x08
SET_CARRIED_ITEM, // 0x09
PLAYER_SLEEP, // 0x0A
ANIMATE, // 0x0B
ADD_PLAYER, // 0x0C
TAKE_ITEM_ENTITY, // 0x0D
ADD_ENTITY, // 0x0E
ADD_MOB, // 0x0F
ADD_PAINTING, // 0x10
ADD_EXPERIENCE_ORB, // 0x11
SET_ENTITY_MOTION, // 0x12
REMOVE_ENTITIES, // 0x13
MOVE_ENTITY, // 0x14
MOVE_ENTITY_POS, // 0x15
MOVE_ENTITY_ROT, // 0x16
MOVE_ENTITY_POS_ROT, // 0x17
TELEPORT_ENTITY, // 0x18
ROTATE_HEAD, // 0x19
ENTITY_EVENT, // 0x1A
SET_ENTITY_LINK, // 0x1B
SET_ENTITY_DATA, // 0x1C
UPDATE_MOB_EFFECT, // 0x1D
REMOVE_MOB_EFFECT, // 0x1E
SET_EXPERIENCE, // 0x1F
UPDATE_ATTRIBUTES, // 0x20
LEVEL_CHUNK, // 0x21
CHUNK_BLOCKS_UPDATE, // 0x22
BLOCK_UPDATE, // 0x23
BLOCK_EVENT, // 0x24
BLOCK_DESTRUCTION, // 0x25
MAP_BULK_CHUNK, // 0x26
EXPLODE, // 0x27
LEVEL_EVENT, // 0x28
CUSTOM_SOUND, // 0x29
LEVEL_PARTICLES, // 0x2A
GAME_EVENT, // 0x2B
ADD_GLOBAL_ENTITY, // 0x2C
OPEN_SCREEN, // 0x2D
CONTAINER_CLOSE, // 0x2E
CONTAINER_SET_SLOT, // 0x2F
CONTAINER_SET_CONTENT, // 0x30
CONTAINER_SET_DATA, // 0x31
CONTAINER_ACK, // 0x32
UPDATE_SIGN, // 0x33
MAP_ITEM_DATA, // 0x34
BLOCK_ENTITY_DATA, // 0x35
OPEN_SIGN_EDITOR, // 0x36
AWARD_STATS, // 0x37
PLAYER_INFO, // 0x38
PLAYER_ABILITIES, // 0x39
COMMAND_SUGGESTIONS, // 0x3A
SET_OBJECTIVE, // 0x3B
SET_SCORE, // 0x3C
SET_DISPLAY_OBJECTIVE, // 0x3D
SET_PLAYER_TEAM, // 0x3E
CUSTOM_PAYLOAD, // 0x3F
DISCONNECT; // 0x40
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,36 +15,35 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8;
package com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
public enum ServerboundPackets1_7 implements ServerboundPacketType {
public enum ServerboundPackets1_7_2_5 implements ServerboundPacketType {
KEEP_ALIVE, // 0x00
CHAT_MESSAGE, // 0x01
INTERACT_ENTITY, // 0x02
PLAYER_MOVEMENT, // 0x03
PLAYER_POSITION, // 0x04
PLAYER_ROTATION, // 0x05
PLAYER_POSITION_AND_ROTATION, // 0x06
PLAYER_DIGGING, // 0x07
PLAYER_BLOCK_PLACEMENT, // 0x08
HELD_ITEM_CHANGE, // 0x09
ANIMATION, // 0x0A
ENTITY_ACTION, // 0x0B
STEER_VEHICLE, // 0x0C
CLOSE_WINDOW, // 0x0D
CLICK_WINDOW, // 0x0E
WINDOW_CONFIRMATION, // 0x0F
CREATIVE_INVENTORY_ACTION, // 0x10
CLICK_WINDOW_BUTTON, // 0x11
UPDATE_SIGN, // 0x12
CHAT, // 0x01
INTERACT, // 0x02
MOVE_PLAYER_STATUS_ONLY, // 0x03
MOVE_PLAYER_POS, // 0x04
MOVE_PLAYER_ROT, // 0x05
MOVE_PLAYER_POS_ROT, // 0x06
PLAYER_ACTION, // 0x07
USE_ITEM_ON, // 0x08
SET_CARRIED_ITEM, // 0x09
SWING, // 0x0A
PLAYER_COMMAND, // 0x0B
PLAYER_INPUT, // 0x0C
CONTAINER_CLOSE, // 0x0D
CONTAINER_CLICK, // 0x0E
CONTAINER_ACK, // 0x0F
SET_CREATIVE_MODE_SLOT, // 0x10
CONTAINER_BUTTON_CLICK, // 0x11
SIGN_UPDATE, // 0x12
PLAYER_ABILITIES, // 0x13
TAB_COMPLETE, // 0x14
CLIENT_SETTINGS, // 0x15
CLIENT_STATUS, // 0x16
PLUGIN_MESSAGE; // 0x17
COMMAND_SUGGESTION, // 0x14
CLIENT_INFORMATION, // 0x15
CLIENT_COMMAND, // 0x16
CUSTOM_PAYLOAD; // 0x17
@Override
public int getId() {
@@ -0,0 +1,162 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.protocol.v1_8to1_7_6_10;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viarewind.ViaRewind;
import com.viaversion.viarewind.api.data.RewindMappingData;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ServerboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.EntityPacketRewriter1_8;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.*;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.CompressionHandlerProvider;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.provider.compression.TrackingCompressionHandlerProvider;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.*;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.task.WorldBorderUpdateTask;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.exception.CancelException;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ServerboundPackets1_8;
import java.util.concurrent.TimeUnit;
public class Protocol1_8To1_7_6_10 extends BackwardsProtocol<ClientboundPackets1_8, ClientboundPackets1_7_2_5, ServerboundPackets1_8, ServerboundPackets1_7_2_5> {
public static final RewindMappingData MAPPINGS = new RewindMappingData("1.8", "1.7.10");
private final BlockItemPacketRewriter1_8 itemRewriter = new BlockItemPacketRewriter1_8(this);
private final EntityPacketRewriter1_8 entityRewriter = new EntityPacketRewriter1_8(this);
public Protocol1_8To1_7_6_10() {
super(ClientboundPackets1_8.class, ClientboundPackets1_7_2_5.class, ServerboundPackets1_8.class, ServerboundPackets1_7_2_5.class);
}
@Override
protected void registerPackets() {
itemRewriter.register();
entityRewriter.register();
PlayerPacketRewriter1_8.register(this);
ScoreboardPacketRewriter1_8.register(this);
WorldPacketRewriter1_8.register(this);
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO.getId(), ClientboundLoginPackets.HELLO.getId(), new PacketHandlers() {
@Override
public void register() {
map(Types.STRING); // server hash
map(Types.BYTE_ARRAY_PRIMITIVE, Types.SHORT_BYTE_ARRAY); // public key
map(Types.BYTE_ARRAY_PRIMITIVE, Types.SHORT_BYTE_ARRAY); // verification token
}
});
this.registerClientbound(State.LOGIN, ClientboundLoginPackets.LOGIN_COMPRESSION.getId(), ClientboundLoginPackets.LOGIN_COMPRESSION.getId(), new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> {
final int threshold = wrapper.read(Types.VAR_INT);
Via.getManager().getProviders().get(CompressionHandlerProvider.class).onHandleLoginCompressionPacket(wrapper.user(), threshold);
wrapper.cancel();
});
}
});
this.cancelClientbound(ClientboundPackets1_8.SET_COMPRESSION); // unused
this.registerClientbound(ClientboundPackets1_8.KEEP_ALIVE, new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT, Types.INT); // id
}
});
this.registerServerbound(State.LOGIN, ServerboundLoginPackets.ENCRYPTION_KEY.getId(), ServerboundLoginPackets.ENCRYPTION_KEY.getId(), new PacketHandlers() {
@Override
public void register() {
map(Types.SHORT_BYTE_ARRAY, Types.BYTE_ARRAY_PRIMITIVE); // shared secret
map(Types.SHORT_BYTE_ARRAY, Types.BYTE_ARRAY_PRIMITIVE); // verification token
}
});
this.registerServerbound(ServerboundPackets1_7_2_5.KEEP_ALIVE, new PacketHandlers() {
@Override
public void register() {
map(Types.INT, Types.VAR_INT); // id
}
});
}
@Override
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws CancelException {
Via.getManager().getProviders().get(CompressionHandlerProvider.class).onTransformPacket(packetWrapper.user());
super.transform(direction, state, packetWrapper);
}
@Override
public void init(UserConnection connection) {
connection.addEntityTracker(this.getClass(), new EntityTracker1_8(connection));
connection.put(new InventoryTracker(connection));
connection.put(new PlayerSessionStorage(connection));
connection.put(new GameProfileStorage(connection));
connection.put(new ScoreboardTracker(connection));
connection.put(new CompressionStatusTracker(connection));
connection.put(new WorldBorderEmulator(connection));
if (!connection.has(ClientWorld.class)) {
connection.put(new ClientWorld());
}
}
@Override
public void register(ViaProviders providers) {
providers.register(CompressionHandlerProvider.class, new TrackingCompressionHandlerProvider());
if (ViaRewind.getConfig().isEmulateWorldBorder()) {
Via.getManager().getScheduler().scheduleRepeating(new WorldBorderUpdateTask(), 0L, 50L, TimeUnit.MILLISECONDS);
}
}
@Override
public RewindMappingData getMappingData() {
return MAPPINGS;
}
@Override
public BlockItemPacketRewriter1_8 getItemRewriter() {
return itemRewriter;
}
@Override
public EntityPacketRewriter1_8 getEntityRewriter() {
return entityRewriter;
}
@Override
public boolean hasMappingDataToLoad() {
return true;
}
}
@@ -0,0 +1,219 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data;
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
import com.viaversion.viaversion.util.Pair;
import java.util.HashMap;
import java.util.Optional;
import static com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8.EntityType.*;
public enum EntityDataIndex1_7_6_10 {
ENTITY_FLAGS(ENTITY, 0, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
ENTITY_AIR(ENTITY, 1, EntityDataTypes1_7_6_10.SHORT, EntityDataTypes1_8.SHORT),
ENTITY_NAME_TAG(ENTITY, -1, null, 2, EntityDataTypes1_8.STRING),
ENTITY_NAME_TAG_VISIBILITY(ENTITY, -1, null, 3, EntityDataTypes1_8.BYTE),
ENTITY_SILENT(ENTITY, -1, null, 4, EntityDataTypes1_8.BYTE),
LIVING_ENTITY_BASE_HEALTH(LIVING_ENTITY_BASE, 6, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
LIVING_ENTITY_BASE_POTION_EFFECT_COLOR(LIVING_ENTITY_BASE, 7, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
LIVING_ENTITY_BASE_IS_POTION_EFFECT_AMBIENT(LIVING_ENTITY_BASE, 8, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
LIVING_ENTITY_BASE_ARROWS(LIVING_ENTITY_BASE, 9, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
LIVING_ENTITY_BASE_NAME_TAG(LIVING_ENTITY_BASE, 10, EntityDataTypes1_7_6_10.STRING, 2, EntityDataTypes1_8.STRING),
LIVING_ENTITY_BASE_NAME_TAG_VISIBILITY(LIVING_ENTITY_BASE, 11, EntityDataTypes1_7_6_10.BYTE, 3, EntityDataTypes1_8.BYTE),
LIVING_ENTITY_AI(LIVING_ENTITY, -1, null, 15, EntityDataTypes1_8.BYTE),
ABSTRACT_AGEABLE_AGE(ABSTRACT_AGEABLE, 12, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.BYTE),
ARMOR_STAND_FLAGS(ARMOR_STAND, -1, null, 10, EntityDataTypes1_8.BYTE),
ARMOR_STAND_HEAD_POSITION(ARMOR_STAND, -1, null, 11, EntityDataTypes1_8.ROTATIONS),
ARMOR_STAND_BODY_POSITION(ARMOR_STAND, -1, null, 12, EntityDataTypes1_8.ROTATIONS),
ARMOR_STAND_LEFT_ARM_POSITION(ARMOR_STAND, -1, null, 13, EntityDataTypes1_8.ROTATIONS),
ARMOR_STAND_RIGHT_ARM_POSITION(ARMOR_STAND, -1, null, 14, EntityDataTypes1_8.ROTATIONS),
ARMOR_STAND_LEFT_LEG_POSITION(ARMOR_STAND, -1, null, 15, EntityDataTypes1_8.ROTATIONS),
ARMOR_STAND_RIGHT_LEG_POSITION(ARMOR_STAND, -1, null, 16, EntityDataTypes1_8.ROTATIONS),
PLAYER_SKIN_FLAGS(PLAYER, 16, EntityDataTypes1_7_6_10.BYTE, 10, EntityDataTypes1_8.BYTE),
PLAYER_UNUSED(PLAYER, -1, null, 16, EntityDataTypes1_8.BYTE),
PLAYER_ABSORPTION_HEATS(PLAYER, 17, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
PLAYER_SCORE(PLAYER, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
HORSE_FLAGS(HORSE, 16, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
HORSE_TYPE(HORSE, 19, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
HORSE_COLOR(HORSE, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
HORSE_OWNER(HORSE, 21, EntityDataTypes1_7_6_10.STRING, EntityDataTypes1_8.STRING),
HORSE_ARMOR(HORSE, 22, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
BAT_HANGING(BAT, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
TAMABLE_ANIMAL_FLAGS(TAMABLE_ANIMAL, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
TAMABLE_ANIMAL_OWNER(TAMABLE_ANIMAL, 17, EntityDataTypes1_7_6_10.STRING, EntityDataTypes1_8.STRING),
OCELOT_TYPE(OCELOT, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
WOLF_FLAGS(WOLF, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
WOLF_HEALTH(WOLF, 18, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
WOLF_BEGGING(WOLF, 19, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
WOLF_COLLAR_COLOR(WOLF, 20, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
PIG_SADDLE(PIG, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
SHEEP_COLOR_OR_SHEARED(SHEEP, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
VILLAGER_TYPE(VILLAGER, 16, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
ENDERMAN_CARRIED_BLOCK(ENDERMAN, 16, null, EntityDataTypes1_8.SHORT),
ENDERMAN_CARRIED_BLOCK_DATA(ENDERMAN, 17, null, EntityDataTypes1_8.BYTE),
ENDERMAN_IS_SCREAMING(ENDERMAN, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
ZOMBIE_CHILD(ZOMBIE, 12, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
ZOMBIE_VILLAGER(ZOMBIE, 13, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
ZOMBIE_CONVERTING(ZOMBIE, 14, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
BLAZE_ON_FIRE(BLAZE, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
SPIDER_CLIMBING(SPIDER, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
CREEPER_STATE(CREEPER, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
CREEPER_POWERED(CREEPER, 17, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
CREEPER_IGNITED(CREEPER, 18, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
GHAST_STATE(GHAST, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
GHAST_IS_POWERED(GHAST, 17, null, EntityDataTypes1_8.BYTE),
SLIME_SIZE(SLIME, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
SKELETON_TYPE(SKELETON, 13, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
WITCH_AGGRESSIVE(WITCH, 21, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
IRON_GOLEM_IS_PLAYER_CREATED(IRON_GOLEM, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
WITHER_WATCHED_TARGET_1(WITHER, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
WITHER_WATCHED_TARGET_2(WITHER, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
WITHER_WATCHED_TARGET_3(WITHER, 19, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
WITHER_INVULNERABLE_TIME(WITHER, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
GUARDIAN_FLAGS(GUARDIAN, 16, null, EntityDataTypes1_8.BYTE),
GUARDIAN_TARGET(GUARDIAN, 17, null, EntityDataTypes1_8.INT),
BOAT_TIME_SINCE_HIT(BOAT, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
BOAT_FORWARD_DIRECTION(BOAT, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
BOAT_DAMAGE_TAKEN(BOAT, 19, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
ABSTRACT_MINECART_SHAKING_POWER(ABSTRACT_MINECART, 17, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
ABSTRACT_MINECART_SHAKING_DIRECTION(ABSTRACT_MINECART, 18, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
ABSTRACT_MINECART_DAMAGE_TAKEN(ABSTRACT_MINECART, 19, EntityDataTypes1_7_6_10.FLOAT, EntityDataTypes1_8.FLOAT),
ABSTRACT_MINECART_BLOCK_INSIDE(ABSTRACT_MINECART, 20, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
ABSTRACT_MINECART_BLOCK_Y(ABSTRACT_MINECART, 21, EntityDataTypes1_7_6_10.INT, EntityDataTypes1_8.INT),
ABSTRACT_MINECART_SHOW_BLOCK(ABSTRACT_MINECART, 22, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
FURNACE_MINECART_IS_POWERED(FURNACE_MINECART, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
ITEM_ITEM(ITEM, 10, EntityDataTypes1_7_6_10.ITEM, EntityDataTypes1_8.ITEM),
ARROW_IS_CRITICAL(ARROW, 16, EntityDataTypes1_7_6_10.BYTE, EntityDataTypes1_8.BYTE),
FIREWORK_ROCKET_INFO(FIREWORK_ROCKET, 8, EntityDataTypes1_7_6_10.ITEM, EntityDataTypes1_8.ITEM),
ITEM_FRAME_ITEM(ITEM_FRAME, 2, EntityDataTypes1_7_6_10.ITEM, 8, EntityDataTypes1_8.ITEM),
ITEM_FRAME_ROTATION(ITEM_FRAME, 3, EntityDataTypes1_7_6_10.BYTE, 9, EntityDataTypes1_8.BYTE),
END_CRYSTAL_HEALTH(END_CRYSTAL, 8, EntityDataTypes1_7_6_10.INT, 9, EntityDataTypes1_8.INT);
private static final HashMap<Pair<EntityTypes1_8.EntityType, Integer>, EntityDataIndex1_7_6_10> ENTITY_DATA_REWRITES = new HashMap<>();
static {
for (EntityDataIndex1_7_6_10 index : EntityDataIndex1_7_6_10.values()) {
ENTITY_DATA_REWRITES.put(new Pair<>(index.getClazz(), index.getNewIndex()), index);
}
}
private final EntityTypes1_8.EntityType clazz;
private final int newIndex;
private final EntityDataTypes1_8 newType;
private final EntityDataTypes1_7_6_10 oldType;
private final int index;
EntityDataIndex1_7_6_10(EntityTypes1_8.EntityType type, int index, EntityDataTypes1_7_6_10 oldType, EntityDataTypes1_8 newType) {
this.clazz = type;
this.index = index;
this.newIndex = index;
this.oldType = oldType;
this.newType = newType;
}
EntityDataIndex1_7_6_10(EntityTypes1_8.EntityType type, int index, EntityDataTypes1_7_6_10 oldType, int newIndex, EntityDataTypes1_8 newType) {
this.clazz = type;
this.index = index;
this.oldType = oldType;
this.newIndex = newIndex;
this.newType = newType;
}
private static Optional<EntityDataIndex1_7_6_10> getIndex(EntityType type, int index) {
Pair<EntityType, Integer> pair = new Pair<>(type, index);
if (ENTITY_DATA_REWRITES.containsKey(pair)) {
return Optional.of(ENTITY_DATA_REWRITES.get(pair));
}
return Optional.empty();
}
public EntityTypes1_8.EntityType getClazz() {
return clazz;
}
public int getNewIndex() {
return newIndex;
}
public EntityDataTypes1_8 getNewType() {
return newType;
}
public EntityDataTypes1_7_6_10 getOldType() {
return oldType;
}
public int getIndex() {
return index;
}
public static EntityDataIndex1_7_6_10 searchIndex(EntityType type, int index) {
EntityType currentType = type;
do {
Optional<EntityDataIndex1_7_6_10> optMeta = getIndex(currentType, index);
if (optMeta.isPresent()) {
return optMeta.get();
}
currentType = currentType.getParent();
} while (currentType != null);
return null;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2018-2024 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
@@ -15,12 +15,11 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viarewind.protocol.protocol1_7_6_10to1_8.types;
package com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data;
import java.util.HashMap;
public enum Particle {
public enum Particles1_8 {
EXPLOSION_NORMAL("explode"),
EXPLOSION_LARGE("largeexplode"),
EXPLOSION_HUGE("hugeexplosion"),
@@ -66,33 +65,32 @@ public enum Particle {
public final String name;
public final int extra;
private static final HashMap<String, Particle> particleMap = new HashMap();
private static final HashMap<String, Particles1_8> particleMap = new HashMap<>();
Particle(String name) {
Particles1_8(String name) {
this(name, 0);
}
Particle(String name, int extra) {
Particles1_8(String name, int extra) {
this.name = name;
this.extra = extra;
}
public static Particle find(String part) {
public static Particles1_8 find(String part) {
return particleMap.get(part);
}
public static Particle find(int id) {
if (id<0) return null;
Particle[] values = Particle.values();
return id>=values.length ? null : values[id];
public static Particles1_8 find(int id) {
if (id < 0) return null;
Particles1_8[] values = Particles1_8.values();
return id >= values.length ? null : values[id];
}
static {
Particle[] particles = values();
Particles1_8[] particles = values();
for (Particle particle : particles) {
for (Particles1_8 particle : particles) {
particleMap.put(particle.name, particle);
}
}
}
@@ -0,0 +1,325 @@
/*
* This file is part of ViaRewind - https://github.com/ViaVersion/ViaRewind
* Copyright (C) 2018-2024 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 com.viaversion.viarewind.protocol.v1_8to1_7_6_10.data;
import com.viaversion.viarewind.api.type.version.Types1_7_6_10;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.rewriter.EntityPacketRewriter1_8;
import com.viaversion.viarewind.api.minecraft.math.AABB;
import com.viaversion.viarewind.api.minecraft.math.Vector3d;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_8;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_8;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.data.entity.TrackedEntityImpl;
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEvent;
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEventImpl;
import java.util.ArrayList;
import java.util.List;
public class VirtualHologramEntity {
private final List<EntityData> entityDataTracker = new ArrayList<>();
private double locX, locY, locZ;
private final UserConnection user;
private final int entityId;
private int[] entityIds = null;
private State currentState = null;
private String name = null;
private float yaw, pitch;
private float headYaw;
private boolean small = false;
private boolean marker = false;
public VirtualHologramEntity(final UserConnection user, final int entityId) {
this.user = user;
this.entityId = entityId;
}
public void setPosition(final double x, final double y, final double z) {
if (x == this.locX && y == this.locY && z == this.locZ) return;
this.locX = x;
this.locY = y;
this.locZ = z;
updateLocation(false);
}
public void setRelativePosition(final double x, final double y, final double z) {
if (x == 0.0 && y == 0.0 && z == 0.0) return;
this.locX += x;
this.locY += y;
this.locZ += z;
updateLocation(false);
}
public void setRotation(final float yaw, final float pitch) {
if (this.yaw == yaw || this.headYaw == yaw || this.pitch == pitch) return;
this.yaw = yaw;
this.headYaw = yaw;
this.pitch = pitch;
updateLocation(false);
}
public void setHeadYaw(float yaw) {
if (this.headYaw == yaw) return;
this.headYaw = yaw;
updateLocation(false);
}
public void syncState(final EntityPacketRewriter1_8 entityRewriter, final List<EntityData> entityDataList) {
// Merge entity data updates into current tracker
for (EntityData entityData : entityDataList) {
entityDataTracker.removeIf(m -> m.id() == entityData.id());
entityDataTracker.add(entityData);
}
// Filter armor stand data to calculate emulation
byte flags = 0;
byte armorStandFlags = 0;
for (EntityData entityData : entityDataTracker) {
if (entityData.id() == 0 && entityData.dataType() == EntityDataTypes1_8.BYTE) {
flags = ((Number) entityData.getValue()).byteValue();
} else if (entityData.id() == 2 && entityData.dataType() == EntityDataTypes1_8.STRING) {
name = entityData.getValue().toString();
if (name != null && name.isEmpty()) name = null;
} else if (entityData.id() == 10 && entityData.dataType() == EntityDataTypes1_8.BYTE) {
armorStandFlags = ((Number) entityData.getValue()).byteValue();
}
}
final boolean invisible = (flags & 0x20) != 0;
small = (armorStandFlags & 0x01) != 0;
marker = (armorStandFlags & 0x10) != 0;
State prevState = currentState;
if (invisible && name != null) {
currentState = State.HOLOGRAM;
} else {
currentState = State.ZOMBIE;
}
if (currentState != prevState) {
deleteEntity();
sendSpawnPacket(entityRewriter);
} else {
sendEntityDataUpdate(entityRewriter);
updateLocation(false);
}
}
private void updateLocation(final boolean remount) {
if (entityIds == null) {
return;
}
if (currentState == State.ZOMBIE) {
teleportEntity(entityId, locX, locY, locZ, yaw, pitch);
final PacketWrapper entityHeadLook = PacketWrapper.create(ClientboundPackets1_7_2_5.ROTATE_HEAD, user);
entityHeadLook.write(Types.INT, entityId);
entityHeadLook.write(Types.BYTE, (byte) ((headYaw / 360f) * 256));
entityHeadLook.send(Protocol1_8To1_7_6_10.class);
} else if (currentState == State.HOLOGRAM) {
if (remount) {
PacketWrapper detach = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_LINK, user);
detach.write(Types.INT, entityIds[1]);
detach.write(Types.INT, -1);
detach.write(Types.BOOLEAN, false);
detach.send(Protocol1_8To1_7_6_10.class);
}
// Don't ask me where this offset is coming from
teleportEntity(entityIds[0], locX, (locY + (marker ? 54.85 : small ? 56 : 57) - 0.16), locZ, 0, 0); // Skull
if (remount) {
teleportEntity(entityIds[1], locX, locY + 56.75, locZ, 0, 0); // Horse
PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_LINK, null, user);
attach.write(Types.INT, entityIds[1]);
attach.write(Types.INT, entityIds[0]);
attach.write(Types.BOOLEAN, false);
attach.send(Protocol1_8To1_7_6_10.class);
}
}
}
protected void teleportEntity(final int entityId, final double x, final double y, final double z, final float yaw, final float pitch) {
final PacketWrapper entityTeleport = PacketWrapper.create(ClientboundPackets1_7_2_5.TELEPORT_ENTITY, user);
entityTeleport.write(Types.INT, entityId); // entity id
entityTeleport.write(Types.INT, (int) (x * 32.0)); // x
entityTeleport.write(Types.INT, (int) (y * 32.0)); // y
entityTeleport.write(Types.INT, (int) (z * 32.0)); // z
entityTeleport.write(Types.BYTE, (byte) ((yaw / 360f) * 256)); // yaw
entityTeleport.write(Types.BYTE, (byte) ((pitch / 360f) * 256)); // pitch
entityTeleport.send(Protocol1_8To1_7_6_10.class);
}
protected void spawnEntity(final int entityId, final int type, final double locX, final double locY, final double locZ) {
final PacketWrapper addMob = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_MOB, user);
addMob.write(Types.VAR_INT, entityId); // Entity id
addMob.write(Types.UNSIGNED_BYTE, (short) type); // Entity type
addMob.write(Types.INT, (int) (locX * 32.0)); // X
addMob.write(Types.INT, (int) (locY * 32.0)); // Y
addMob.write(Types.INT, (int) (locZ * 32.0)); // Z
addMob.write(Types.BYTE, (byte) 0); // Yaw
addMob.write(Types.BYTE, (byte) 0); // Pitch
addMob.write(Types.BYTE, (byte) 0); // Head pitch
addMob.write(Types.SHORT, (short) 0); // Velocity x
addMob.write(Types.SHORT, (short) 0); // Velocity y
addMob.write(Types.SHORT, (short) 0); // Velocity z
addMob.write(Types1_7_6_10.ENTITY_DATA_LIST, new ArrayList<>()); // Entity data
addMob.send(Protocol1_8To1_7_6_10.class);
}
public void sendEntityDataUpdate(final EntityPacketRewriter1_8 entityRewriter) {
if (entityIds == null) {
return;
}
final PacketWrapper setEntityData = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_DATA, user);
if (currentState == State.ZOMBIE) {
writeZombieMeta(entityRewriter, setEntityData);
} else if (currentState == State.HOLOGRAM) {
writeHologramMeta(setEntityData);
} else {
return;
}
setEntityData.send(Protocol1_8To1_7_6_10.class);
}
private void writeZombieMeta(final EntityPacketRewriter1_8 entityRewriter, PacketWrapper wrapper) {
wrapper.write(Types.INT, entityIds[0]);
// Filter entity data sent by the server and convert them together with our custom entity data
final List<EntityData> entityDataList = new ArrayList<>();
for (EntityData entityData : entityDataTracker) {
// Remove non existent entityData
if (entityData.id() < 0 || entityData.id() > 9) {
continue;
}
entityDataList.add(new EntityData(entityData.id(), entityData.dataType(), entityData.getValue()));
}
if (small) {
entityDataList.add(new EntityData(12, EntityDataTypes1_8.BYTE, (byte) 1));
}
// Push entity data from the server through entity data conversion 1.7->1.8
for (EntityData entityData : entityDataList.toArray(new EntityData[0])) {
final EntityDataHandlerEvent event = new EntityDataHandlerEventImpl(wrapper.user(), new TrackedEntityImpl(EntityTypes1_8.EntityType.ZOMBIE), -1, entityData, entityDataList);
try {
entityRewriter.handleEntityData(event, entityData);
} catch (Exception e) {
entityDataList.remove(entityData);
break;
}
if (event.cancelled()) {
entityDataList.remove(entityData);
break;
}
}
wrapper.write(Types1_7_6_10.ENTITY_DATA_LIST, entityDataList);
}
private void writeHologramMeta(PacketWrapper wrapper) {
wrapper.write(Types.INT, entityIds[1]);
// Directly write 1.7 entity data here since we are making them up
final List<EntityData> entityDataList = new ArrayList<>();
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.ABSTRACT_AGEABLE_AGE.getIndex(), EntityDataTypes1_7_6_10.INT, -1700000));
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.LIVING_ENTITY_BASE_NAME_TAG.getIndex(), EntityDataTypes1_7_6_10.STRING, name));
entityDataList.add(new EntityData(EntityDataIndex1_7_6_10.LIVING_ENTITY_BASE_NAME_TAG_VISIBILITY.getIndex(), EntityDataTypes1_7_6_10.BYTE, (byte) 1));
wrapper.write(Types1_7_6_10.ENTITY_DATA_LIST, entityDataList);
}
public void sendSpawnPacket(final EntityPacketRewriter1_8 entityRewriter) {
if (entityIds != null) {
deleteEntity();
}
if (currentState == State.ZOMBIE) {
spawnEntity(entityId, EntityTypes1_8.EntityType.ZOMBIE.getId(), locX, locY, locZ);
entityIds = new int[]{entityId};
} else if (currentState == State.HOLOGRAM) {
final int[] entityIds = { entityId, additionalEntityId() };
final PacketWrapper spawnSkull = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_ENTITY, user);
spawnSkull.write(Types.VAR_INT, entityIds[0]);
spawnSkull.write(Types.BYTE, (byte) 66);
spawnSkull.write(Types.INT, (int) (locX * 32.0));
spawnSkull.write(Types.INT, (int) (locY * 32.0));
spawnSkull.write(Types.INT, (int) (locZ * 32.0));
spawnSkull.write(Types.BYTE, (byte) 0);
spawnSkull.write(Types.BYTE, (byte) 0);
spawnSkull.write(Types.INT, 0);
spawnSkull.send(Protocol1_8To1_7_6_10.class);
spawnEntity(entityIds[1], EntityTypes1_8.EntityType.HORSE.getId(), locX, locY, locZ); // Horse
this.entityIds = entityIds;
}
sendEntityDataUpdate(entityRewriter);
updateLocation(true);
}
public AABB getBoundingBox() {
final double width = this.small ? 0.25 : 0.5;
final double height = this.small ? 0.9875 : 1.975;
final Vector3d min = new Vector3d(this.locX - width / 2, this.locY, this.locZ - width / 2);
final Vector3d max = new Vector3d(this.locX + width / 2, this.locY + height, this.locZ + width / 2);
return new AABB(min, max);
}
private int additionalEntityId() {
return Integer.MAX_VALUE - 16000 - entityId;
}
public void deleteEntity() {
if (entityIds == null) {
return;
}
final PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7_2_5.REMOVE_ENTITIES, user);
despawn.write(Types.BYTE, (byte) entityIds.length);
for (int id : entityIds) {
despawn.write(Types.INT, id);
}
entityIds = null;
despawn.send(Protocol1_8To1_7_6_10.class);
}
private enum State {
HOLOGRAM, ZOMBIE
}
}
Loaded 100 of 170 files, more files were not shown because too many files have changed in this diff. Show more