Compare commits

...
305 Commits
Author SHA1 Message Date
Nassim Jahnke 17bda0fc29 4.10.2 Release 2024-05-10 13:24:40 +02:00
EnZaXD 1a22b371cd Handle bad heightmaps in 1.17->1.16.4 (#743) 2024-05-09 21:56:14 +02:00
EnZaXD 6292c5a5a5 Use backup tag remove method when rewriting trade list (#742) 2024-05-09 20:55:31 +02:00
Nassim Jahnke 6b616d8b07 Fixup banner handling 2024-05-09 19:44:03 +02:00
Nassim Jahnke fd43ca56d7 Properly write properties 2024-05-09 18:04:13 +02:00
Nassim Jahnke 91193cf602 Handle player head block entities
Fixes #741
2024-05-09 17:22:31 +02:00
EnZaXD 1680f9985d [ci skip] Use login/status packet enums in older protocols (#740) 2024-05-09 09:25:17 +02:00
EnZaXD e8602adf5b Fix red nether brick name in 1.11->1.10 (#739) 2024-05-07 19:35:18 +02:00
EnZaXD 7f0982e59c Fix item mappings with explicit data (0) (#738) 2024-05-07 18:54:38 +02:00
Nassim Jahnke 072b59060c Don't write null criteria for unknown advancements 2024-05-07 17:07:13 +02:00
EnZaXD 633b4b393b Remove alpha channel from particle colors in 1.20.5->.3 (#737) 2024-05-06 09:50:33 +02:00
Nassim Jahnke 34101ea8b8 4.10.1 Release
Definitely the first time I made this commit
2024-05-05 16:53:56 +02:00
Nassim Jahnke 093328db11 Handle missing mappings 2024-05-05 16:53:36 +02:00
Nassim Jahnke 5bd8786737 Update entity mapping usage 2024-05-05 12:22:17 +02:00
EnZaXD fedda03062 Use TagUtil#removeNamespaced in 1.19.4->.3 (#735) 2024-05-02 16:07:22 +02:00
EnZaXD 99f6356230 Make chat_types handling in 1.19 protocols optional (#733) 2024-05-02 15:59:51 +02:00
EnZaXD 9b8e65c59d Implement handleTranslate() for tags in TranslatableRewriter (#734) 2024-05-02 15:28:40 +02:00
Nassim JahnkeandKrakenied bd2eb42374 Add advancement criteria if possible in 1.20.2->1.20
Fixes #616

Co-authored-by: Krakenied <Krakenied1@gmail.com>
2024-05-01 11:31:03 +02:00
Nassim Jahnke e9db3f040f Check both namespaced and implicit key when replacing registries 2024-05-01 10:35:48 +02:00
Nassim Jahnke ce0e01abec Auto: Update copyright headers 2024-04-30 22:29:02 +02:00
Nassim Jahnke 025603027e Remove default components from trade list 2024-04-30 22:29:02 +02:00
EnZaXD 67ae00faeb Add support for different mapping types with same id (#731) 2024-04-30 18:29:45 +02:00
Nassim Jahnke 325e3f92ed Remove 1.19.4 registries without namespace as well 2024-04-29 23:12:37 +02:00
Nassim Jahnke 42897030f7 Fix entity effect reading below 1.20.2
Fixes #3811
2024-04-28 11:39:43 +02:00
Nassim Jahnke ddeaf921be Register listeners a tick later
Because 1.8 has task registration order reverse???
Fixes #730
2024-04-28 11:35:51 +02:00
Nassim Jahnke 06c30c2838 Add paperweight-mappings-namespace attribute 2024-04-28 03:52:25 +02:00
Gero bf7ed14506 Fix remapping of 1.20.5 CLICK_WINDOW_BUTTON 2024-04-27 21:31:49 +02:00
Gero c4d0c7ab8f Bump to 4.10.1-SNAPSHOT 2024-04-27 21:31:41 +02:00
Nassim Jahnke f1f337af27 Bump VV dependency 2024-04-26 15:25:19 +02:00
Nassim Jahnke e37fea42d4 4.10.0 Release 2024-04-26 15:15:57 +02:00
FlorianMichael 78a667c5b9 Add constructors to LegacyBlockItemRewriter to define item types 2024-04-26 15:15:24 +02:00
Nassim Jahnke 27dd2e39bd Merge branch 'refs/heads/dev' into preview
# Conflicts:
#	common/src/main/java/com/viaversion/viabackwards/api/data/BackwardsMappings.java
2024-04-26 14:32:00 +02:00
Nassim Jahnke b3115ea71d Fix some namespace parsing issues 2024-04-26 13:31:14 +02:00
Nassim Jahnke be742fc493 Fix 1.20.3->1.20.2 cloud particle handling 2024-04-26 13:19:09 +02:00
EnZaXD 100febf575 Rework legacy item/block mappings format (#728) 2024-04-26 09:18:42 +02:00
Nassim Jahnke cddf30b60f Read normal byte array type for cookie packet 2024-04-25 19:11:19 +02:00
EnZaXD c4c15fb047 Add EntityRewriterBase#getDisplayVisibilityMetaValue (#725) 2024-04-23 22:18:58 +02:00
EnZaXD ab11527c86 Reuse existing logger getter in BackwardsMappings (#726) 2024-04-23 22:18:45 +02:00
Nassim Jahnke 1d3a444fe0 Update version 2024-04-23 17:02:21 +02:00
Nassim Jahnke 82bb374edc Update version references 2024-04-23 11:26:31 +02:00
Nassim Jahnke a4147a24f1 Merge branch 'refs/heads/dev' into preview 2024-04-23 11:00:24 +02:00
EnZaXD 87f2a6ba7b Add mob spawn rewriter function for pre 1.11 (#724) 2024-04-23 10:45:12 +02:00
EnZaXD 948c615622 Replace LegacyEntityRewriter#getObjectTypeFromId with existing method (#723) 2024-04-22 23:30:15 +02:00
Nassim Jahnke 0996fc9270 Merge branch 'refs/heads/dev' into preview
# Conflicts:
#	common/src/main/java/com/viaversion/viabackwards/api/rewriters/EntityRewriterBase.java
#	common/src/main/java/com/viaversion/viabackwards/protocol/protocol1_20_3to1_20_5/rewriter/BlockItemPacketRewriter1_20_5.java
2024-04-21 23:43:33 +02:00
Nassim Jahnke 0cd46fdac9 Also to component rewriter methods 2024-04-21 23:37:00 +02:00
Nassim Jahnke 2a4bfb936f Add UserConnection param to item rewriter methods 2024-04-21 22:48:56 +02:00
Nassim Jahnke 3b9b3ab257 Use getFullItemMappings 2024-04-21 20:50:04 +02:00
FlorianMichael e52210a674 Update mappings 2024-04-21 10:11:17 +02:00
Nassim Jahnke 11286b2162 Fall back to keys without namespace in registry data 2024-04-20 12:13:06 +02:00
Gero 471d4acf20 Add missing dust_color_transition data remapping (changed in 24w03a) 2024-04-19 16:54:52 +02:00
Gero e5fff8fabc 1.20.5-rc2 2024-04-19 16:54:10 +02:00
Nassim Jahnke 23955e5385 Update particle format in biome registry data 2024-04-18 19:16:42 +02:00
Nassim Jahnke bf635cc6c5 1.20.5-rc1 2024-04-18 16:30:58 +02:00
Nassim Jahnke 5a49413dbc Merge branch 'refs/heads/dev' into preview 2024-04-18 16:26:20 +02:00
Nassim Jahnke c64e9acf35 Override getTagRewriter methods 2024-04-18 16:26:03 +02:00
Nassim Jahnke 00f773d150 Merge branch 'refs/heads/master' into dev 2024-04-18 16:19:39 +02:00
EnZaXD 1ac504afb9 Use correct constructor in MappedLegacyBlockItem (#721) 2024-04-17 08:46:48 +02:00
EnZaXD 09eda34051 Use VVs IdAndData class for block id conversions (#719) 2024-04-16 21:05:45 +02:00
EnZaXD 9cf5f98ed1 Replace incoming/outgoing usages with client/server bound (#720) 2024-04-16 21:00:20 +02:00
Nassim Jahnke 1e8cf198e7 Update missed call 2024-04-15 17:29:22 +02:00
Nassim Jahnke caa28df36d 1.20.5-pre2 2024-04-15 17:17:19 +02:00
Nassim Jahnke d2edf3fbfe 1.20.5-pre1 2024-04-10 17:41:19 +02:00
Nassim Jahnke 68807be880 Track banner patterns 2024-04-09 13:18:40 +02:00
Nassim Jahnke 7d6c330fa3 Handle entity effect particle color 2024-04-08 15:05:01 +02:00
Nassim Jahnke 3ea95a0d78 Update authors 2024-04-07 20:44:24 +02:00
FlorianMichael fe708ba0eb Fix chat command handling 2024-04-07 19:58:44 +02:00
Nassim Jahnke fccd5b3f3b Fix trade list handling 2024-04-07 13:41:51 +02:00
Nassim Jahnke 9f652ad24a Update VV usage 2024-04-06 21:33:41 +02:00
Nassim Jahnke f7dad9b5d7 Add StructuredEnchantmentRewriter, update translation mappings 2024-04-06 21:30:19 +02:00
Nassim Jahnke 1507f788ec 24w14a 2024-04-06 21:28:59 +02:00
Nassim Jahnke 41b04f9902 24w13a 2024-04-06 21:28:59 +02:00
Nassim Jahnke 9beaf71196 Handle new argument types 2024-04-06 21:28:59 +02:00
Nassim Jahnke 0c7aa1d037 Update mappings 2024-04-06 21:28:59 +02:00
Nassim Jahnke 7a7d2f1fa1 Handle lore and name in StructuredItemRewriter 2024-04-06 21:28:56 +02:00
Nassim Jahnke 37711d0079 Set rewritten item in metadata rewriter 2024-04-06 21:28:21 +02:00
Nassim Jahnke e1f2f151c9 24w11a 2024-04-06 21:28:21 +02:00
Nassim Jahnke a453163822 Some 24w10a changes 2024-04-06 21:28:21 +02:00
EnZaXD 1647b18233 Override nbtTagName() correctly (#717) 2024-04-05 20:36:03 +02:00
vadage c7dc80b71b Support config loading from input stream (#718) 2024-04-05 20:32:47 +02:00
EnZaXD 39d3265463 Update VV ItemRewriter API Usage (#716) 2024-04-04 09:48:19 +02:00
Nassim Jahnke 2b953556ec Update VV API usage 2024-04-01 14:20:15 +02:00
EnZaXD 4e5b6fe876 Fix minor inconsistencies in older protocols (#714) 2024-04-01 13:01:07 +02:00
EnZaXD 0e74527342 Update Via API usage (#713) 2024-03-31 15:14:33 +02:00
EnZaXD 75fddd0fb9 Allow platforms to disable dummy enchantment in LegacyEnchantmentRewriter (#710) 2024-03-28 14:32:13 +01:00
EnZaXD 0aacfe3bcb Add item handler methods to LegacyEnchantmentRewriter (#709) 2024-03-28 11:22:34 +01:00
EnZaXD 4547d5c702 Move methods in LegacyBlockItemRewriter and expose handleChunk method (#707) 2024-03-27 20:15:57 +01:00
EnZaXD b438484dc7 Keep original item data in LegacyBlockItemRewriter (#706) 2024-03-27 17:04:50 +01:00
EnZaXD ed52ef21ee Add calculation methods for block id and data (#704) 2024-03-27 16:49:14 +01:00
EnZaXD 9d1a5a05f5 Expose EntityRewriterBase#alwaysShowOriginalMobName (#705) 2024-03-27 16:48:35 +01:00
EnZaXD 4e856ef396 Various API changes to LegacyBlockItemRewriter (#703) 2024-03-27 13:27:19 +01:00
EnZaXD 082cc010b2 Update Via API usage (#702) 2024-03-24 22:10:06 +01:00
EnZaXD 59a621315b Allow platforms to use BackwardsMappingDataLoader (#701) 2024-03-24 12:14:51 +01:00
EnZaXD d8b7e7d9ff Update mapping data loader (#700) 2024-03-24 11:46:08 +01:00
Nassim Jahnke 51561d143c Merge branch 'master' into dev
# Conflicts:
#	.github/workflows/publish.yml
2024-03-22 20:55:44 +01:00
Nassim Jahnke 2ffa852c92 Update build dependencies 2024-03-22 20:48:31 +01:00
Nassim Jahnke ac86d891fe Check if id is present in EnchantmentRewriter
Closes #699
2024-03-17 19:58:05 +01:00
Nassim Jahnke 9d8aa9a232 Update mappings 2024-03-17 16:29:32 +01:00
Nassim Jahnke f3b26c5aa5 Fix 1.20.2->1.20 entity sound reading
Fixes ViaVersion/ViaVersion#3744
2024-03-14 14:41:49 +01:00
Nassim Jahnke d96cef7134 Merge branch 'master' into dev 2024-03-09 13:09:17 +01:00
Nassim Jahnke ced1a65230 Replace some generic CompoundTag get usages 2024-03-09 13:08:36 +01:00
Nassim Jahnke 6ad1dc4195 Merge branch 'master' into dev
# Conflicts:
#	gradle.properties
#	gradle/libs.versions.toml
2024-03-07 13:51:41 +01:00
Nassim Jahnke c6ea04fd33 Update ViaNBT 2024-03-07 13:37:42 +01:00
Nassim Jahnke 79a2881a02 4.9.2 Release 2024-03-05 17:51:04 +01:00
Nassim Jahnke 64e68830bc Create FUNDING.yml 2024-03-04 17:32:32 +01:00
EnZaXD ab742c794f Update description included in platforms (#694) 2024-03-04 17:26:59 +01:00
Nassim Jahnke 39e9d6dd04 Use new SoundEvent type 2024-03-01 14:23:13 +01:00
Nassim Jahnke 445d798a17 Partially implement mapped item handling 2024-02-29 20:30:46 +01:00
Nassim Jahnke 66896d2027 Update version 2024-02-29 14:28:48 +01:00
Nassim Jahnke 05b1a6bacd Start working on 24w09a 2024-02-29 12:41:39 +01:00
EnZaXD bf3834ab21 Tidy up fabric.mod.json file of fabric platform (#695) 2024-02-29 12:25:31 +01:00
EnZaXD 2f60c79ed8 Use equals for legacy custom payload channel handlers (#693) 2024-02-29 12:09:50 +01:00
EnZaXD 5bb3e8a1fc paste.gg -> mclo.gs (#689) 2024-02-21 16:13:12 +01:00
Nassim Jahnke 8f417b6caa Rename methods once again 2024-02-14 19:27:40 +01:00
Nassim Jahnke 96d6c0697e Fix compilation 2024-02-14 18:15:41 +01:00
Nassim Jahnke c112044b5a 24w07a 2024-02-14 17:39:31 +01:00
Nassim Jahnke 45c44c8f7e Update VV usage 2024-02-14 11:13:58 +01:00
Nassim Jahnke 5a3a82a83d Update VV usage 2024-02-13 19:03:56 +01:00
Nassim Jahnke bc03235f42 Merge branch 'master' into dev
# Conflicts:
#	common/src/main/java/com/viaversion/viabackwards/protocol/protocol1_16_4to1_17/packets/EntityPackets1_17.java
2024-02-12 11:08:17 +01:00
Nassim Jahnke 073488abcf Update template 2024-02-12 11:03:39 +01:00
Nassim Jahnke b60464296b Small cleanups 2024-02-12 11:02:55 +01:00
Nassim Jahnke 9241213fb5 Replace tag instanceof/unchecked casts with helper methods 2024-02-11 10:42:44 +01:00
Nassim Jahnke e9c3889c82 Add editorconfig 2024-02-11 10:39:06 +01:00
Nassim Jahnke f90861dbce Remap breeze wind charge 2024-02-08 16:19:17 +01:00
Nassim Jahnke 06f07d2b2c 24w06a 2024-02-07 19:07:34 +01:00
Nassim Jahnke fa1c3e1520 24w05b 2024-02-01 17:53:18 +01:00
EnZaXD dca8ecf1db Fix notes color from note block being wrong in 1.13->1.12 (#680)
Closes https://github.com/ViaVersion/ViaBackwards/issues/679
2024-02-01 16:28:40 +01:00
Nassim Jahnke 680d0642c9 Merge branch 'master' into dev
# Conflicts:
#	common/src/main/java/com/viaversion/viabackwards/protocol/protocol1_20_2to1_20_3/rewriter/BlockItemPacketRewriter1_20_3.java
2024-01-31 22:58:51 +01:00
Nassim Jahnke 170e5f224f Fix writable book handling in 1.16->1.15 2024-01-31 22:58:11 +01:00
Nassim Jahnke f6def0c97c 24w05a (mostly) 2024-01-31 18:06:46 +01:00
EnZaXD 4375a259dd Fix 1.17.1 -> 1.18 mappings loading (#676)
Closes https://github.com/ViaVersion/ViaBackwards/issues/568
2024-01-29 20:30:59 +01:00
Nassim Jahnke b3b4d0f618 Merge branch 'master' into dev
# Conflicts:
#	common/src/main/java/com/viaversion/viabackwards/protocol/protocol1_20_2to1_20_3/rewriter/BlockItemPacketRewriter1_20_3.java
2024-01-29 17:33:42 +01:00
Nassim Jahnke 8fc82cd331 Update book conversion error logging 2024-01-29 17:33:08 +01:00
EnZaXD de21548a8e Clean up more item type usage in ItemRewriter (#675) 2024-01-29 17:29:17 +01:00
Nassim Jahnke 8759f059b7 Ignore errors in book conversion 2024-01-29 10:17:50 +01:00
Nassim Jahnke 1f3555df4a Put books through component conversion in 1.20.3->1.20.2 2024-01-27 21:04:32 +01:00
Nassim Jahnke 9abfdfb8f9 Include config packets in Protocol generic types 2024-01-26 16:23:17 +01:00
Nassim Jahnke 8c2f80a632 Fix missed type removal from last commit 2024-01-26 14:38:55 +01:00
Nassim Jahnke 3e89641448 24w04a 2024-01-24 20:23:29 +01:00
Nassim Jahnke a2ddcae076 Merge branch 'master' into dev
# Conflicts:
#	.github/workflows/gradle.yml
2024-01-24 17:51:31 +01:00
Kichura b40f77fed3 Update JDK to 17, setup-java to v4 (#671) 2024-01-20 21:19:36 +01:00
Nassim Jahnke 8ffbc7047f Add cookie handling, TransferProvider for other platforms 2024-01-20 10:26:56 +01:00
Nassim Jahnke e6814a13a9 24w03b (probably) 2024-01-18 16:34:00 +01:00
Kichura 9fd0df824f Update supported Velocity version to 3.3 (#666) 2024-01-14 10:02:16 +01:00
EnZaXD 6b1f913b91 Fix VV API usage (#664) 2024-01-13 09:54:39 +01:00
Nassim Jahnke de42850dd1 Merge branch 'master' into dev
# Conflicts:
#	template/src/main/java/com/viaversion/viabackwards/template/protocol/rewriter/EntityPacketRewriter1_99.java
2024-01-12 10:33:40 +01:00
Nassim Jahnke 88df61605b Update VV usage 2024-01-09 20:59:26 +01:00
Nassim Jahnke 6c2d43d7f9 Handle 1.20->1.20.2 tags 2024-01-09 17:19:19 +01:00
Nassim Jahnke 62765d03ce Merge remote-tracking branch 'origin/master' into dev 2024-01-04 17:51:18 +01:00
Nassim Jahnke 2889daed61 Update license header 2024-01-01 12:38:33 +01:00
Nassim Jahnke 651bf052fc Update ViaNBT 2023-12-31 14:04:57 +01:00
Nassim Jahnke 59660a5bdc Merge branch 'master' into dev 2023-12-27 19:48:40 +01:00
Kichura fa18a572c0 Update setup-java to v4, Fix friendly names in CI steps (#660) 2023-12-27 19:47:31 +01:00
Nassim Jahnke 83fa0c613f Update copyright profile 2023-12-27 17:51:16 +01:00
Nassim Jahnke 5334f77d49 Finish up things 2023-12-27 17:30:47 +01:00
Nassim Jahnke 96293e6e66 Start working on mcstructs usage (missing TranslatableRewriter1_16) 2023-12-27 00:24:56 +01:00
Nassim Jahnke 19ec92c261 Merge remote-tracking branch 'origin/master' into dev 2023-12-26 21:51:03 +01:00
Nassim Jahnke 65faeb8574 Fix 1.20.3->1.20.2 configuration resource pack id 2023-12-26 21:49:34 +01:00
Nassim Jahnke 6ad4a29d30 Allow specifying unmapped data in legacy mappings 2023-12-20 12:10:15 +01:00
Nassim Jahnke ba725df33e 23w51b 2023-12-18 19:50:25 +01:00
Nassim Jahnke 4fe53f5ab8 Update the bane of my existence 2023-12-13 22:45:23 +01:00
Nassim Jahnke a390990178 Read correct method type in update score
Fixes #650
2023-12-13 12:04:43 +01:00
Nassim Jahnke e020dd69ef Fix tab complete tooltip reading in old versions
Fixes #648
2023-12-11 11:27:52 +01:00
Nassim Jahnke b09950dc64 Update Via usage 2023-12-10 12:15:35 +01:00
Nassim Jahnke 7b8fd2b061 Fix 1.17->1.16 map data type reading
Fixes #646
2023-12-09 14:59:43 +01:00
Nassim Jahnke 2d57e8c212 Clone tag instead of abusing tag conversion 2023-12-08 21:06:30 +01:00
Camden Cove dcc3824a8c Fix 1.13.1->1.13 item type in some cases (#645) 2023-12-08 12:05:52 +01:00
EnZaXD 2dd19c778b Handle chunk loading game state in 1.20.3 -> 1.20.2 (#643) 2023-12-08 09:37:20 +01:00
Nassim Jahnke e24a170e77 Fix reset score reading 2023-12-07 23:17:55 +01:00
Nassim Jahnke 3a69dda548 Bump version to 4.9.2-SNAPSHOT 2023-12-07 23:17:36 +01:00
Nassim Jahnke 77ecda3977 4.9.1 Release 2023-12-07 11:19:36 +01:00
Nassim Jahnke c44bc88d2d Convert chat type in disguised chat packet 2023-12-07 10:11:18 +01:00
Nassim Jahnke deede5347e Fix 1.13 map data type
Fixes #641
2023-12-07 09:54:30 +01:00
Nassim Jahnke 255536e9d0 Handle tags packet 2023-12-06 09:47:11 +01:00
Nassim Jahnke 8a2c18863c Fix map marker reading 2023-12-05 22:23:48 +01:00
Nassim Jahnke 375bb5a1b9 Bump version to 4.9.1-SNAPSHOT 2023-12-05 22:18:32 +01:00
Nassim Jahnke c739b54403 4.9.0 Release 2023-12-04 10:14:06 +01:00
Nassim Jahnke a0388cf541 Merge branch 'master' into dev 2023-12-04 10:13:46 +01:00
RK_01 3dd6e5043e Change gamemode data type in JOIN_GAME handlers (#639) 2023-12-03 18:35:47 +01:00
Nassim JahnkeandEnZaXD d30766a17a Fix ordering issue in login ack send on the server
Fixes 1.20.2+ Fabric servers with Fabric API

Co-authored-by: EnZaXD <60033407+FlorianMichael@users.noreply.github.com>
2023-11-30 18:39:41 +01:00
Nassim Jahnke f556a29d38 1.20.3-rc1 2023-11-30 17:13:05 +01:00
Nassim Jahnke 8a19fbdead Update translation mappings 2023-11-30 15:54:54 +01:00
Nassim Jahnke d4011f3646 1.20.3-pre3 2023-11-27 17:12:42 +01:00
EnZaXD 2bd687b19d Implemented ViaVersion's SignableCommandArgumentsProvider (#633) 2023-11-26 15:34:55 +01:00
Nassim Jahnke 4f4bff6898 Update mappings 2023-11-21 07:36:29 +01:00
Nassim Jahnke adac67b85c Handle new resource pack actions 2023-11-21 07:13:37 +01:00
Nassim Jahnke 0949ff4ba9 1.20.3-pre1 (maybe) 2023-11-20 19:09:05 +01:00
Nassim Jahnke 8f5683f764 23w46a (mostly) 2023-11-19 16:48:24 +01:00
Drex 995c0bf4c3 Implement keep blocks explosion types (#632) 2023-11-19 16:19:40 +01:00
Nassim Jahnke 0f77acdc9f Remove todos 2023-11-09 18:00:08 +10:00
Nassim Jahnke ac5fbdd7f4 Allow null mapped entity name 2023-11-09 17:58:10 +10:00
Nassim Jahnke fb7cd2d9e3 23w45a 2023-11-09 17:57:28 +10:00
Nassim Jahnke 5284a581b3 Handle new 1.20.2 map markers 2023-11-08 11:55:03 +10:00
Nassim Jahnke 8eca6bf0b2 Improve Gradle setup
Don't build full platform jars to reduce build time
2023-11-06 14:45:30 +10:00
Nassim Jahnke c13a89a29c Update Gradle wrapper 2023-11-05 11:56:20 +10:00
Nassim Jahnke bce716caa4 Don't expect enables features to always be sent
The client defaults to the vanilla registry, so it doesn't need to be sent
2023-11-05 11:50:33 +10:00
Nassim Jahnke 71f08b9e4e Add 1.20.3 translations, fix unlit bulb mappings 2023-10-26 17:44:17 +10:00
Nassim Jahnke 59fc7f6a1a 23w43a 2023-10-26 13:13:23 +10:00
RK_01 232180ee61 Fix identifier handling in old protocols (#624) 2023-10-24 09:55:13 +10:00
EnZaXD cfb97e1abe Mention ViaVersion addon in "Known issues" (#623) 2023-10-24 09:54:30 +10:00
RK_01 48907be813 Implement support for chat signing (#621) 2023-10-22 19:51:00 +10:00
EnZaXD ff87b1dc92 1.13.2 -> 1.14: Change bamboo mapping (#622) 2023-10-22 12:36:21 +10:00
Nassim Jahnke e68ddf42b0 Update VV usage 2023-10-21 13:41:39 +10:00
Nassim Jahnke 8a9d4bd971 Update VV usage 2023-10-20 12:46:29 +10:00
Nassim Jahnke 7f85d074af Update VV usage 2023-10-19 21:31:00 +10:00
Nassim Jahnke 4cd65dd956 23w42a (if the ci manages to find VV) 2023-10-19 11:50:31 +10:00
Nassim Jahnke 719bb11938 Update TranslatableRewriter 2023-10-18 14:56:44 +10:00
Дмитрий e419831e8a Big Dripleaf mappings change (#614) 2023-10-18 11:48:45 +10:00
Kichura d121745a0f Update Fabric dependencies (#605) 2023-10-16 15:17:17 +10:00
Nassim Jahnke 65158455cc Fix early sending of resource pack
Fixes #3476
2023-10-15 18:12:39 +10:00
Nassim Jahnke 0912e33358 Merge pull request #611 from SplotyCode/fix/scoreboatd 2023-10-13 21:20:00 +10:00
David Scandurra 02f595b109 ChatUtil: Append unwritten formatting in prefix mode 2023-10-12 23:03:18 +02:00
Nassim Jahnke f78d166acf 23w41a (probably) 2023-10-12 01:53:44 +10:00
Nassim Jahnke 2e0acf169b Actually track 1.20.2 entities
Fixes #609, #597
2023-10-11 16:43:32 +10:00
EnZaXD aa1f38674d Fix platform loading (#604) 2023-10-08 19:33:00 +10:00
Nassim Jahnke 9e883faa78 Update nbt lib usage 2023-10-08 18:56:56 +10:00
EnZaXD e27930b1d7 Allow platform implementation to define config path (#603) 2023-10-08 17:20:01 +10:00
Nassim Jahnke d46eb8719a Fix it again 2023-10-08 15:26:37 +10:00
EnZaXD d092c98897 Fix ViaBackwards#init previous platform check (#602) 2023-10-08 15:10:35 +10:00
EnZaXD 75680296e8 Updated Via API usage (#601) 2023-10-08 14:51:49 +10:00
EnZaXD 80696a1273 [ci skip] Note smithing table as not usable for <1.19.4 clients (#600) 2023-10-08 02:18:34 +00:00
Nassim Jahnke 54330702b1 23w40a 2023-10-06 22:36:03 +10:00
Nassim Jahnke f923648fe8 4.8.1 Release 2023-10-03 20:58:18 +10:00
Nassim Jahnke 92c160c43a Fix trade list sending
Forgot to remove cancellation from initial configuration testing
Fixes #594
2023-09-28 11:19:36 +10:00
Nassim Jahnke cc7df5a4fc Fix serverbound beacon secondary effect 2023-09-28 09:36:41 +10:00
Nassim Jahnke 8e6727c350 Handle changed custom potion effects tag 2023-09-27 14:58:03 +10:00
Nassim Jahnke e73eeeb434 Update branch check again 2023-09-26 10:48:42 +10:00
Brokkonaut 96650decae Fix packet id of player velocity packets (#593) 2023-09-26 10:47:57 +10:00
Nassim Jahnke 1d35b1cdb2 [ci skip] Fix branch check in publishing 2023-09-26 00:24:36 +10:00
Nassim Jahnke c6711919b1 Add separate client and server state handling 2023-09-25 18:34:03 +10:00
Nassim Jahnke 67f7a66ca5 Fix 1.20.2->1.20 if run on the backend 2023-09-25 10:54:52 +10:00
Nassim Jahnke 4cba8072c4 Fix implementation version 2023-09-24 23:56:29 +10:00
Nassim Jahnke cfbe287361 Bump version to 4.8.1-SNAPSHOT 2023-09-24 23:55:25 +10:00
Nassim Jahnke f254869c66 4.8.0 Release 2023-09-21 10:35:54 +10:00
Nassim Jahnke 57ca5f1bf5 Fix particle handling 2023-09-21 10:35:42 +10:00
Nassim Jahnke b69ebe6657 Send the config ack packet 2023-09-19 13:25:25 +10:00
Nassim Jahnke ea2fac0788 Handle configuration start
TODO: Check whether all the necessary data for the join game packet is always expected by the client or if we need to cache it from the initial login
2023-09-19 13:20:19 +10:00
Nassim Jahnke 2b2384acc1 Remove new trim patterns in 1.20->1.19
Fixes #570
2023-09-15 18:13:12 +10:00
SplotyCode 643c6b18dd Fix scoreboard component coversion (#586) 2023-09-08 12:22:16 +10:00
Nassim Jahnke 80438807cc 1.20.2-pre2 2023-09-08 09:33:31 +10:00
Nassim Jahnke 2f373adad4 [ci skip] Update Blossom 2023-09-06 11:30:10 +10:00
Nassim Jahnke e2546b8471 1.20.2-pre1 2023-09-06 00:59:17 +10:00
Nassim Jahnke 88fd52ac6e [ci skip] Update Gradle wrapper and checkout actions 2023-09-05 21:29:01 +10:00
Nassim Jahnke c13c3f17fc Fix scoreboard objective reading 2023-08-31 11:48:48 +10:00
Nassim Jahnke 3b9354c4f6 23w35a (untested) 2023-08-31 00:53:48 +10:00
Nassim Jahnke 83636ecf51 Fix 1.16->1.15 hover components in books
Fixes #572
2023-08-27 18:52:43 +10:00
Nassim Jahnke 082b61a956 [ci skip] Update Hangar publish plugin 2023-08-26 20:05:17 +10:00
Nassim Jahnke 108e96ec6d Move world data tracker into first join game handler 2023-08-18 01:36:37 +10:00
Nassim Jahnke 6dd5cb20d9 23w33a 2023-08-18 01:32:50 +10:00
EnZaXD 2a2a0d8a72 Adde1.9 protocols from ViaVersion to ViaBackwards (#580) 2023-08-14 11:06:59 +10:00
Nassim Jahnke 9c68b30865 Merge remote-tracking branch 'origin/master' into dev
# Conflicts:
#	.github/workflows/gradle.yml
2023-08-14 10:15:19 +10:00
EnZaXD e0b7426dc9 Remove unused chat-types setting from config.yml (#579) 2023-08-14 10:04:02 +10:00
EnZaXD 43e2b242c4 Fix 1.19.4 -> 1.19.3 precipitation reading (#578) 2023-08-14 10:02:52 +10:00
Nassim Jahnke 567725d996 Update README 2023-08-11 21:36:20 +10:00
Nassim Jahnke 4fa985f131 Also publish dev branch builds to Hangar 2023-08-11 20:34:24 +10:00
Nassim Jahnke 2e8d6bcc9f Include link to commit in autopublished changelog 2023-08-11 16:26:17 +10:00
Nassim Jahnke 95e3446e8c Add mappings for changed block states and sounds 2023-08-11 16:08:10 +10:00
Nassim Jahnke 725e505514 Also handle release versions on publish 2023-08-11 15:54:59 +10:00
Nassim Jahnke c053975535 Finish publish action 2023-08-11 12:16:42 +10:00
Nassim Jahnke 70725d4aaf Add Hangar publishing 2023-08-11 00:26:51 +10:00
Nassim Jahnke 0d147653f3 Fix spawn tracker mapping data check 2023-08-10 17:13:08 +10:00
Nassim Jahnke f4cc9d4730 Fix double register 2023-08-10 17:06:49 +10:00
Nassim Jahnke 406733b13a 23w32a 2023-08-10 16:55:03 +10:00
Nassim Jahnke 9df7debb7e Finish 23w31a 2023-08-06 13:17:31 +10:00
Nassim Jahnke e12d491b53 Start working on 23w31a 2023-08-05 14:12:45 +10:00
Kichura 4d4e739939 Friendly names in CI, Update Blossom. (#562) 2023-07-25 11:08:22 +10:00
Nassim Jahnke 2904ad54c6 Fix non item display rotation 2023-07-24 20:58:30 +10:00
Nassim Jahnke 92e5fe8a9b Update gradle wrapper 2023-07-11 23:34:47 +02:00
Nassim Jahnke bc0cb7702c Properly handle changed item display rotation 2023-07-03 20:16:52 +02:00
Nassim Jahnke 04d75264e0 Add required 1.18(.1) tag
Fixes #558
2023-06-15 10:10:32 +02:00
tahmid-23 4a308f9d81 Fix 1.19.3->1.19.1 entity sound packet (#555) 2023-06-15 09:56:59 +02:00
EnZaXD 4627142700 Emulate "trim_pattern" registry in 1.19.4 -> 1.20 if not present (#557) 2023-06-14 19:04:28 +02:00
Nassim Jahnke 817080b7a6 Extend correct item rewriter
Fixes #551
2023-06-10 10:14:40 +02:00
Nassim Jahnke 8f51ab2f6a Fix display rotation change 2023-06-09 12:28:08 +02:00
Nassim Jahnke 359cdb13eb Bump version to 4.7.1-SNAPSHOT 2023-06-09 12:19:34 +02:00
Nassim Jahnke 63a3908b53 4.7.0 Release 2023-06-07 11:36:14 +02:00
Nassim Jahnke ceb08c1e55 Update VV usage 2023-06-05 09:10:50 +02:00
Nassim Jahnke c468ec714c Handle servers not sending 1.16 expected tags
Fixes #548
2023-05-28 12:15:42 +02:00
Nassim Jahnke 4fb9fdab9b Add statistics handler to 1.19.4->1.19.3 protocol 2023-05-23 16:43:46 +02:00
Nassim Jahnke d271d3d687 1.20-pre3 2023-05-19 14:34:34 +02:00
Nassim Jahnke 9fa7af7c7b Update nbt file 2023-05-10 16:18:43 +02:00
Nassim Jahnke f591593992 1.20-pre1 2023-05-10 15:54:13 +02:00
Nassim Jahnke e74b5d661d 23w18a, maybe 2023-05-03 15:22:21 +02:00
Nassim Jahnke 483920b729 Sanity checks in item rewriting 2023-05-01 11:33:00 +02:00
Nassim Jahnke 73647ee4fb 23w17a 2023-04-26 19:06:30 +02:00
Nassim Jahnke 97f5ec322a 23w16a 2023-04-20 17:28:25 +02:00
Nassim Jahnke da35067e1d Handle optional block state entity meta 2023-04-18 13:39:59 +02:00
Kichura 65c8024ba7 Add ViaBackwards icon to Fabric (#543) 2023-04-15 14:14:40 +02:00
Nassim Jahnke 377f512f95 23w14a 2023-04-05 15:26:33 +02:00
RK_01 b174dd31b4 Fixed max player count value mapping (#541) 2023-03-31 09:40:18 +02:00
Nassim Jahnke 8eaadd0f18 23w13a 2023-03-29 16:34:17 +02:00
Nassim Jahnke ef1b062449 Handle changed sign nbt 2023-03-24 11:36:32 +01:00
Nassim Jahnke c1383baf14 23w12a 2023-03-22 19:41:00 +01:00
Nassim Jahnke 455e862089 Update mapping files 2023-03-20 10:32:27 +01:00
Nassim Jahnke 0d4257f228 Don't override getTranslatableRewriter in 1.13->1.12, 1.14->1.13 protocols
The method is used in item handling and would otherwise mess up the lore
2023-03-20 10:05:46 +01:00
Pantera (Mad_Daniel) 614207aeef Add remaining sound mappings 2023-03-18 18:24:41 +01:00
Nassim Jahnke 1b268ad4ec Use right type for component metadata 2023-03-18 13:56:53 +01:00
Nassim Jahnke 509055307a Handle 1.12 keybind components
Fixes #474
2023-03-18 13:55:16 +01:00
Nassim Jahnke 68e578a04e Handle translatables in 1.13.1 entity display names 2023-03-18 13:16:22 +01:00
Nassim Jahnke a07550363e Handle shifted 1.19.4 boat types 2023-03-18 12:27:46 +01:00
Nassim Jahnke eb6e9e016a Handle translatables in 1.14/1.15 entity display names 2023-03-18 12:23:14 +01:00
Nassim Jahnke 587a5e487f Improve 1.13->1.12 translatable handling 2023-03-18 10:02:23 +01:00
Nassim Jahnke efded25594 4.6.1 Release 2023-03-16 20:45:16 +01:00
Nassim Jahnke 11e71b1307 Fix #3252 2023-03-15 21:20:33 +01:00
riku6460 974b15243a Fix enchantments in 1.12 -> 1.13 (#533) 2023-03-14 20:01:25 +01:00
Nassim Jahnke e14da27093 Bump version to 4.6.1-SNAPSHOT 2023-03-14 20:01:14 +01:00
266 changed files with 8968 additions and 3390 deletions

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
[*]
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = false
tab_width = 4
[*.java]
ij_java_class_count_to_use_import_on_demand = 999999
ij_java_names_count_to_use_import_on_demand = 999999
ij_java_imports_layout = *,|,$*
ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true
[{*.json,*.yml}]
indent_size = 2
+2
View File
@@ -0,0 +1,2 @@
github: kennytv
patreon: kennytv
+2 -2
View File
@@ -21,11 +21,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:
+8 -9
View File
@@ -9,16 +9,15 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1
- name: Set up JDK 11
uses: actions/setup-java@v3
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 11
java-version: 17
check-latest: true
- name: Build with Gradle
run: ./gradlew build
- uses: actions/upload-artifact@v3
with:
name: artifact
path: build/libs
+27
View File
@@ -0,0 +1,27 @@
name: Publish to Hangar and Modrinth
on:
push:
branches:
- master
- dev
jobs:
publish:
if: github.repository_owner == 'ViaVersion'
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
check-latest: true
- name: Publish
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
run: ./gradlew build modrinth publishAllPublicationsToHangar --stacktrace
+1 -1
View File
@@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards&#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 ViaBackwards - https://github.com/ViaVersion/ViaBackwards&#10;Copyright (C) 2016-&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="viabackwards-gpl" />
</copyright>
</component>
+26 -16
View File
@@ -4,43 +4,53 @@
[![Build Status](https://github.com/ViaVersion/ViaBackwards/actions/workflows/gradle.yml/badge.svg?branch=master)](https://github.com/ViaVersion/ViaBackwards/actions)
[![Discord](https://img.shields.io/badge/chat-on%20discord-blue.svg)](https://viaversion.com/discord)
**Allows older Minecraft client versions to connect to newer server versions**
**Allows older Minecraft client versions to connect to newer server versions.**
Requires [ViaVersion](https://hangar.papermc.io/ViaVersion/ViaVersion) to be installed..
Supported Versions
-
**Green** = ViaVersion\
**Purple** = ViaBackwards addition
As a plugin, ViaBackwards runs on servers on releases 1.10-latest. Versions from the dev branch will also support the
latest snapshot. You can also use ViaBackwards in ViaFabric or ViaFabricPlus.
![supported_versions](https://i.imgur.com/KpLsMHj.png)
See [HERE](https://github.com/ViaVersion) for an overview of the different Via* projects.
Releases / Dev Builds
Releases/Dev Builds
-
**Requires [ViaVersion](https://www.spigotmc.org/resources/viaversion.19254/) to be installed**
You can find the latest dev builds here:\
**Jenkins:** https://ci.viaversion.com/view/ViaBackwards/
You can find releases in the following places:
**Spigot page:** https://www.spigotmc.org/resources/viabackwards.27448/
- **Hangar (for our plugins)**: https://hangar.papermc.io/ViaVersion/ViaBackwards
- **Modrinth (for our mods)**: https://modrinth.com/mod/viabackwards
- **GitHub**: https://github.com/ViaVersion/ViaBackwards/releases
**CurseForge page:** https://www.curseforge.com/minecraft/mc-mods/viabackwards
Dev builds for **all** of our projects are on our Jenkins server:
- **Jenkins**: https://ci.viaversion.com/view/ViaBackwards/
Known issues
-
* Custom 1.17+ min_y and height world values are not and will (most likely) never be supported => Clients older than 1.17 will not be able to see or interact with blocks below y=0 and above y=255
* < 1.17 clients on 1.17+ servers might experience inventory desyncs on certain inventory click actions
* 1.17+ min_y and height world values that are not 0/256 **are not supported**. Clients older than
1.17 will not be able to see or interact with blocks below y=0 and above y=255
* <1.17 clients on 1.17+ servers might experience inventory desyncs on certain inventory click actions
* Sound mappings are incomplete ([see here](https://github.com/ViaVersion/ViaBackwards/issues/326))
* <1.19.4 clients on 1.20+ servers won't be able to use the smithing table, this can be fixed by
installing [AxSmithing](https://github.com/ViaVersionAddons/AxSmithing)
Other Links
-
**Maven:** https://repo.viaversion.com
**Issue tracker:** https://github.com/ViaVersion/ViaBackwards/issues
**List of contributors:** https://github.com/ViaVersion/ViaBackwards/graphs/contributors
Building
-
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out
of the `build/libs` directory.
License
-
This project is licensed under the [GNU General Public License](LICENSE).
This project is licensed under the [GNU General Public License Version 3](LICENSE).
Special Thanks
-
+1 -1
View File
@@ -8,5 +8,5 @@ repositories {
dependencies {
// version must be manually kept in sync with the one in root project settings.gradle.kts
implementation("com.github.johnrengelman", "shadow", "8.1.0")
implementation("com.github.johnrengelman", "shadow", "8.1.1")
}
+27
View File
@@ -38,6 +38,33 @@ fun Project.latestCommitHash(): String {
return byteOut.toString(Charsets.UTF_8.name()).trim()
}
fun Project.latestCommitMessage(): String {
val byteOut = ByteArrayOutputStream()
exec {
commandLine = listOf("git", "log", "-1", "--pretty=%B")
standardOutput = byteOut
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
}
fun Project.branchName(): String {
val byteOut = ByteArrayOutputStream()
exec {
commandLine = listOf("git", "rev-parse", "--abbrev-ref", "HEAD")
standardOutput = byteOut
}
return byteOut.toString(Charsets.UTF_8.name()).trim()
}
fun Project.parseMinecraftSnapshotVersion(version: String): String? {
val separatorIndex = version.indexOf('-')
val lastSeparatorIndex = version.lastIndexOf('-')
if (separatorIndex == -1 || separatorIndex == lastSeparatorIndex) {
return null
}
return version.substring(separatorIndex + 1, lastSeparatorIndex)
}
fun JavaPluginExtension.javaTarget(version: Int) {
sourceCompatibility = JavaVersion.toVersion(version)
targetCompatibility = JavaVersion.toVersion(version)
@@ -1,12 +0,0 @@
import java.util.*
plugins {
id("vb.shadow-conventions")
}
tasks {
shadowJar {
archiveFileName.set("ViaBackwards-${project.name.substringAfter("viabackwards-").replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}-${project.version}.jar")
destinationDirectory.set(rootProject.layout.buildDirectory.dir("libs"))
}
}
+6 -10
View File
@@ -5,11 +5,13 @@ plugins {
allprojects {
group = "com.viaversion"
version = "4.6.0"
description = "Allow older clients to join newer server versions."
version = property("projectVersion") as String // from gradle.properties
description = "Allows older Minecraft client versions to connect to newer server versions."
}
val platforms = setOf(
val main = setOf(
projects.viabackwards,
projects.viabackwardsCommon,
projects.viabackwardsBukkit,
projects.viabackwardsBungee,
projects.viabackwardsFabric,
@@ -17,15 +19,9 @@ val platforms = setOf(
projects.viabackwardsVelocity
).map { it.dependencyProject }
// Would otherwise contain api/depdency modules if at some point needed
val special = setOf(
projects.viabackwards
).map { it.dependencyProject }
subprojects {
when (this) {
in platforms -> plugins.apply("vb.platform-conventions")
in special -> plugins.apply("vb.base-conventions")
in main -> plugins.apply("vb.shadow-conventions")
else -> plugins.apply("vb.standard-conventions")
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
dependencies {
implementation(projects.viabackwardsCommon)
compileOnlyApi(projects.viabackwardsCommon)
compileOnly(libs.paper) {
exclude("com.google.code.gson", "gson")
exclude("javax.persistence", "persistence-api")
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -23,41 +23,48 @@ import com.viaversion.viabackwards.listener.FireDamageListener;
import com.viaversion.viabackwards.listener.FireExtinguishListener;
import com.viaversion.viabackwards.listener.LecternInteractListener;
import com.viaversion.viabackwards.listener.PlayerItemDropListener;
import com.viaversion.viabackwards.protocol.protocol1_20to1_20_2.provider.AdvancementCriteriaProvider;
import com.viaversion.viabackwards.provider.BukkitAdvancementCriteriaProvider;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.bukkit.platform.BukkitViaLoader;
import java.io.File;
import org.bukkit.plugin.java.JavaPlugin;
public class BukkitPlugin extends JavaPlugin implements ViaBackwardsPlatform {
public BukkitPlugin() {
Via.getManager().addEnableListener(() -> init(getDataFolder()));
Via.getManager().addEnableListener(() -> init(new File(getDataFolder(), "config.yml")));
}
@Override
public void onEnable() {
if (Via.getManager().getInjector().lateProtocolVersionSetting()) {
// Enable in the next tick
Via.getPlatform().runSync(this::enable);
Via.getPlatform().runSync(this::enable, 1);
} else {
enable();
}
}
private void enable() {
BukkitViaLoader loader = (BukkitViaLoader) Via.getManager().getLoader();
int protocolVersion = Via.getAPI().getServerVersion().highestSupportedVersion();
if (protocolVersion >= ProtocolVersion.v1_17.getVersion()) {
loader.storeListener(new PlayerItemDropListener(this)).register();
final ProtocolVersion protocolVersion = Via.getAPI().getServerVersion().highestSupportedProtocolVersion();
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_17)) {
new PlayerItemDropListener(this).register();
}
if (protocolVersion >= ProtocolVersion.v1_16.getVersion()) {
loader.storeListener(new FireExtinguishListener(this)).register();
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_16)) {
new FireExtinguishListener(this).register();
}
if (protocolVersion >= ProtocolVersion.v1_14.getVersion()) {
loader.storeListener(new LecternInteractListener(this)).register();
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_14)) {
new LecternInteractListener(this).register();
}
if (protocolVersion >= ProtocolVersion.v1_12.getVersion()) {
loader.storeListener(new FireDamageListener(this)).register();
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_12)) {
new FireDamageListener(this).register();
}
final ViaProviders providers = Via.getManager().getProviders();
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_20_2)) {
providers.use(AdvancementCriteriaProvider.class, new BukkitAdvancementCriteriaProvider());
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -53,6 +53,7 @@ public class LecternInteractListener extends ViaBukkitListener {
// Open a book with the text of the lectern's writable book
ItemStack newBook = new ItemStack(Material.WRITTEN_BOOK);
BookMeta newBookMeta = (BookMeta) newBook.getItemMeta();
//noinspection deprecation
newBookMeta.setPages(meta.getPages());
newBookMeta.setAuthor("an upsidedown person");
newBookMeta.setTitle("buk");
@@ -1,7 +1,7 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -0,0 +1,34 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-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.viabackwards.provider;
import com.viaversion.viabackwards.protocol.protocol1_20to1_20_2.provider.AdvancementCriteriaProvider;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.advancement.Advancement;
public final class BukkitAdvancementCriteriaProvider extends AdvancementCriteriaProvider {
private static final String[] EMPTY_CRITERIA = new String[0];
@Override
public String[] getCriteria(final String key) {
final Advancement advancement = Bukkit.getAdvancement(NamespacedKey.fromString(key));
return advancement == null ? EMPTY_CRITERIA : advancement.getCriteria().toArray(EMPTY_CRITERIA);
}
}
+2 -2
View File
@@ -1,11 +1,11 @@
name: ViaBackwards
version: ${version}
description: Allow older Minecraft versions to connect to a newer server version.
description: ${description}
main: com.viaversion.viabackwards.BukkitPlugin
api-version: 1.13
folia-supported: true
authors: [Matsv, kennytv, Gerrygames, creeper123123321, ForceUpdate1]
authors: [Matsv, kennytv, Gerrygames, creeper123123321, ForceUpdate1, EnZaXD]
website: ${url}
depend: [ViaVersion]
+1 -1
View File
@@ -1,4 +1,4 @@
dependencies {
implementation(projects.viabackwardsCommon)
compileOnlyApi(projects.viabackwardsCommon)
compileOnly(libs.bungee)
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,14 +20,15 @@ package com.viaversion.viabackwards;
import com.viaversion.viabackwards.api.ViaBackwardsPlatform;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import net.md_5.bungee.api.plugin.Plugin;
import java.io.File;
public class BungeePlugin extends Plugin implements ViaBackwardsPlatform {
@Override
public void onLoad() {
Via.getManager().addEnableListener(() -> this.init(getDataFolder()));
Via.getManager().addEnableListener(() -> this.init(new File(getDataFolder(), "config.yml")));
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: ViaBackwards
main: com.viaversion.viabackwards.BungeePlugin
author: "Matsv, kennytv, Gerrygames, creeper123123321, ForceUpdate1"
author: "Matsv, kennytv, Gerrygames, creeper123123321, ForceUpdate1, EnZaXD"
version: ${version}
depends: [ViaVersion]
+10 -3
View File
@@ -1,10 +1,17 @@
plugins {
id("net.kyori.blossom")
id("org.jetbrains.gradle.plugin.idea-ext")
}
blossom {
replaceToken("\$VERSION", project.version)
replaceToken("\$IMPL_VERSION", "git-ViaBackwards-${project.version}:${rootProject.latestCommitHash()}")
sourceSets {
main {
blossom {
javaSources {
property("version", project.version.toString())
property("impl_version", "git-ViaBackwards-${project.version}:${rootProject.latestCommitHash()}")
}
}
}
}
dependencies {
@@ -17,7 +17,16 @@
*/
package com.viaversion.viabackwards.utils;
public class VersionInfo {
public final class VersionInfo {
public static final String VERSION = "$VERSION";
public static final String VERSION = "{{ version }}";
private static final String IMPLEMENTATION_VERSION = "{{ impl_version }}";
public static String getVersion() {
return VERSION;
}
public static String getImplementationVersion() {
return IMPLEMENTATION_VERSION;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -28,7 +28,7 @@ public final class ViaBackwards {
private static ViaBackwardsConfig config;
public static void init(ViaBackwardsPlatform platform, ViaBackwardsConfig config) {
Preconditions.checkArgument(platform != null, "ViaBackwards is already initialized");
Preconditions.checkArgument(ViaBackwards.platform == null, "ViaBackwards is already initialized");
ViaBackwards.platform = platform;
ViaBackwards.config = config;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,12 +19,11 @@ package com.viaversion.viabackwards;
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.HashMap;
import java.util.List;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ViaBackwardsConfig extends Config implements com.viaversion.viabackwards.api.ViaBackwardsConfig {
@@ -34,15 +33,14 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
private boolean alwaysShowOriginalMobName;
private boolean fix1_13FormattedInventoryTitles;
private boolean handlePingsAsInvAcknowledgements;
private Map<String, String> chatTypeFormats;
public ViaBackwardsConfig(File configFile) {
super(configFile);
}
@Override
public void reloadConfig() {
super.reloadConfig();
public void reload() {
super.reload();
loadFields();
}
@@ -53,7 +51,6 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
fix1_13FormattedInventoryTitles = getBoolean("fix-formatted-inventory-titles", true);
alwaysShowOriginalMobName = getBoolean("always-show-original-mob-name", true);
handlePingsAsInvAcknowledgements = getBoolean("handle-pings-as-inv-acknowledgements", false);
chatTypeFormats = get("chat-types-1_19_1", Map.class, new HashMap<String, String>());
}
@Override
@@ -87,13 +84,13 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
}
@Override
public @Nullable String chatTypeFormat(final String translationKey) {
return chatTypeFormats.get(translationKey);
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viabackwards/config.yml");
}
@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viabackwards/config.yml");
public InputStream getDefaultConfigInputStream() {
return getClass().getClassLoader().getResourceAsStream("assets/viabackwards/config.yml");
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -27,7 +27,7 @@ import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class BackwardsProtocol<CU extends ClientboundPacketType, CM extends ClientboundPacketType, SM extends ServerboundPacketType, SU extends ServerboundPacketType>
extends AbstractProtocol<CU, CM, SM, SU> {
extends AbstractProtocol<CU, CM, SM, SU> {
protected BackwardsProtocol() {
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -17,9 +17,9 @@
*/
package com.viaversion.viabackwards.api;
import org.checkerframework.checker.nullness.qual.Nullable;
import com.viaversion.viaversion.api.configuration.Config;
public interface ViaBackwardsConfig {
public interface ViaBackwardsConfig extends Config {
/**
* Mimics name and level of a custom enchant through the item's lore.
@@ -42,6 +42,11 @@ public interface ViaBackwardsConfig {
*/
boolean isFix1_13FacePlayer();
/**
* Converts the 1.13 face look-at packet for 1.12- players. Requires a bit of extra caching.
*
* @return true if enabled
*/
boolean fix1_13FormattedInventoryTitle();
/**
@@ -51,7 +56,11 @@ public interface ViaBackwardsConfig {
*/
boolean alwaysShowOriginalMobName();
/**
* Sends inventory acknowledgement packets to act as a replacement for ping packets for sub 1.17 clients.
* This only takes effect for ids in the short range. Useful for anticheat compatibility.
*
* @return true if enabled
*/
boolean handlePingsAsInvAcknowledgements();
@Nullable String chatTypeFormat(String translationKey);
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -49,26 +49,34 @@ import com.viaversion.viabackwards.protocol.protocol1_18_2to1_19.Protocol1_18_2T
import com.viaversion.viabackwards.protocol.protocol1_18to1_18_2.Protocol1_18To1_18_2;
import com.viaversion.viabackwards.protocol.protocol1_19_1to1_19_3.Protocol1_19_1To1_19_3;
import com.viaversion.viabackwards.protocol.protocol1_19_3to1_19_4.Protocol1_19_3To1_19_4;
import com.viaversion.viabackwards.protocol.protocol1_19_4to1_20.Protocol1_19_4To1_20;
import com.viaversion.viabackwards.protocol.protocol1_19to1_19_1.Protocol1_19To1_19_1;
import com.viaversion.viabackwards.protocol.protocol1_20_2to1_20_3.Protocol1_20_2To1_20_3;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.Protocol1_20_3To1_20_5;
import com.viaversion.viabackwards.protocol.protocol1_20to1_20_2.Protocol1_20To1_20_2;
import com.viaversion.viabackwards.protocol.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2To1_9_3_4;
import com.viaversion.viabackwards.protocol.protocol1_9_4to1_10.Protocol1_9_4To1_10;
import com.viaversion.viabackwards.protocol.protocol1_9to1_9_1.Protocol1_9To1_9_1;
import com.viaversion.viabackwards.utils.VersionInfo;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.ProtocolManager;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.update.Version;
import java.io.File;
import java.util.Arrays;
import java.util.logging.Logger;
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "4.6.0";
String IMPL_VERSION = "$IMPL_VERSION";
String MINIMUM_VV_VERSION = "4.10.2";
/**
* Initialize ViaBackwards.
*/
default void init(File dataFolder) {
ViaBackwardsConfig config = new ViaBackwardsConfig(new File(dataFolder, "config.yml"));
config.reloadConfig();
default void init(final File configFile) {
ViaBackwardsConfig config = new ViaBackwardsConfig(configFile);
config.reload();
Via.getManager().getConfigurationProvider().register(config);
ViaBackwards.init(this, config);
@@ -77,13 +85,15 @@ public interface ViaBackwardsPlatform {
return;
}
Via.getManager().getSubPlatforms().add(IMPL_VERSION);
Via.getManager().getSubPlatforms().add(VersionInfo.getImplementationVersion());
getLogger().info("Loading translations...");
TranslatableRewriter.loadTranslatables();
getLogger().info("Registering protocols...");
final ProtocolManager protocolManager = Via.getManager().getProtocolManager();
protocolManager.registerProtocol(new Protocol1_9To1_9_1(), ProtocolVersion.v1_9, ProtocolVersion.v1_9_1);
protocolManager.registerProtocol(new Protocol1_9_1_2To1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1, ProtocolVersion.v1_9_2), ProtocolVersion.v1_9_3);
protocolManager.registerProtocol(new Protocol1_9_4To1_10(), ProtocolVersion.v1_9_3, ProtocolVersion.v1_10);
protocolManager.registerProtocol(new Protocol1_10To1_11(), ProtocolVersion.v1_10, ProtocolVersion.v1_11);
@@ -123,6 +133,11 @@ public interface ViaBackwardsPlatform {
protocolManager.registerProtocol(new Protocol1_19To1_19_1(), ProtocolVersion.v1_19, ProtocolVersion.v1_19_1);
protocolManager.registerProtocol(new Protocol1_19_1To1_19_3(), ProtocolVersion.v1_19_1, ProtocolVersion.v1_19_3);
protocolManager.registerProtocol(new Protocol1_19_3To1_19_4(), ProtocolVersion.v1_19_3, ProtocolVersion.v1_19_4);
protocolManager.registerProtocol(new Protocol1_19_4To1_20(), ProtocolVersion.v1_19_4, ProtocolVersion.v1_20);
protocolManager.registerProtocol(new Protocol1_20To1_20_2(), ProtocolVersion.v1_20, ProtocolVersion.v1_20_2);
protocolManager.registerProtocol(new Protocol1_20_2To1_20_3(), ProtocolVersion.v1_20_2, ProtocolVersion.v1_20_3);
protocolManager.registerProtocol(new Protocol1_20_3To1_20_5(), ProtocolVersion.v1_20_3, ProtocolVersion.v1_20_5);
}
/**
@@ -136,7 +151,7 @@ public interface ViaBackwardsPlatform {
String vvVersion = Via.getPlatform().getPluginVersion();
if (vvVersion != null && new Version(vvVersion).compareTo(new Version(MINIMUM_VV_VERSION + "--")) < 0) {
getLogger().severe("================================");
getLogger().severe("YOUR VIAVERSION IS OUTDATED");
getLogger().severe("YOUR VIAVERSION IS OUTDATED (you are running " + vvVersion + ")");
getLogger().severe("PLEASE USE VIAVERSION " + MINIMUM_VV_VERSION + " OR NEWER");
getLogger().severe("LINK: https://ci.viaversion.com/");
getLogger().severe("VIABACKWARDS WILL NOW DISABLE");
@@ -0,0 +1,87 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-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.viabackwards.api.data;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
public class BackwardsMappingDataLoader extends MappingDataLoader {
public static final BackwardsMappingDataLoader INSTANCE = new BackwardsMappingDataLoader(BackwardsMappingDataLoader.class, "assets/viabackwards/data/");
public BackwardsMappingDataLoader(final Class<?> dataLoaderClass, final String dataPath) {
super(dataLoaderClass, dataPath);
}
/**
* Returns nbt data from the plugin folder or packed assets.
* If a file with the same name exists in the plugin folder, the data of the original packed tag will be merged with the file's tag.
*
* @param name name of the file
* @return nbt data from the plugin folder or packed assets
*/
public @Nullable CompoundTag loadNBTFromDir(final String name) {
final CompoundTag packedData = loadNBT(name);
final File file = new File(getDataFolder(), name);
if (!file.exists()) {
return packedData;
}
getLogger().info("Loading " + name + " from plugin folder");
try {
final CompoundTag fileData = MAPPINGS_READER.read(file.toPath(), false);
return mergeTags(packedData, fileData);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
private CompoundTag mergeTags(final CompoundTag original, final CompoundTag extra) {
for (final Map.Entry<String, Tag> entry : extra.entrySet()) {
if (entry.getValue() instanceof CompoundTag) {
// For compound tags, don't replace the entire tag
final CompoundTag originalEntry = original.getCompoundTag(entry.getKey());
if (originalEntry != null) {
mergeTags(originalEntry, (CompoundTag) entry.getValue());
continue;
}
}
original.put(entry.getKey(), entry.getValue());
}
return original;
}
@Override
public Logger getLogger() {
return ViaBackwards.getPlatform().getLogger();
}
@Override
public File getDataFolder() {
return ViaBackwards.getPlatform().getDataFolder();
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -22,10 +22,12 @@ import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.BiMappings;
import com.viaversion.viaversion.api.data.IdentityMappings;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectArrayMap;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
@@ -35,6 +37,7 @@ import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.util.Key;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -44,6 +47,7 @@ public class BackwardsMappings extends MappingDataBase {
protected Int2ObjectMap<MappedItem> backwardsItemMappings;
private Map<String, String> backwardsSoundMappings;
private Map<String, String> entityNames;
private Int2ObjectMap<String> enchantmentNames;
public BackwardsMappings(final String unmappedVersion, final String mappedVersion) {
this(unmappedVersion, mappedVersion, null);
@@ -57,19 +61,19 @@ public class BackwardsMappings extends MappingDataBase {
@Override
protected void loadExtras(final CompoundTag data) {
final CompoundTag itemNames = data.get("itemnames");
final CompoundTag itemNames = data.getCompoundTag("itemnames");
if (itemNames != null) {
Preconditions.checkNotNull(itemMappings);
backwardsItemMappings = new Int2ObjectOpenHashMap<>(itemNames.size());
final CompoundTag extraItemData = data.get("itemdata");
final CompoundTag extraItemData = data.getCompoundTag("itemdata");
for (final Map.Entry<String, Tag> entry : itemNames.entrySet()) {
final StringTag name = (StringTag) entry.getValue();
final int id = Integer.parseInt(entry.getKey());
Integer customModelData = null;
if (extraItemData != null && extraItemData.contains(entry.getKey())) {
final CompoundTag entryTag = extraItemData.get(entry.getKey());
final NumberTag customModelDataTag = entryTag.get("custom_model_data");
final CompoundTag entryTag = extraItemData.getCompoundTag(entry.getKey());
final NumberTag customModelDataTag = entryTag.getNumberTag("custom_model_data");
customModelData = customModelDataTag != null ? customModelDataTag.asInt() : null;
}
@@ -77,32 +81,50 @@ public class BackwardsMappings extends MappingDataBase {
}
}
final CompoundTag entityNames = data.get("entitynames");
if (entityNames != null) {
this.entityNames = new HashMap<>(entityNames.size());
for (final Map.Entry<String, Tag> entry : entityNames.entrySet()) {
final StringTag mappedTag = (StringTag) entry.getValue();
this.entityNames.put(entry.getKey(), mappedTag.getValue());
}
this.entityNames = loadNameByStringMappings(data, "entitynames");
this.enchantmentNames = loadNameByIdMappings(data, "enchantmentnames");
this.backwardsSoundMappings = loadNameByStringMappings(data, "soundnames");
}
private @Nullable Map<String, String> loadNameByStringMappings(final CompoundTag data, final String key) {
final CompoundTag nameMappings = data.getCompoundTag(key);
if (nameMappings == null) {
return null;
}
final CompoundTag soundNames = data.get("soundnames");
if (soundNames != null) {
backwardsSoundMappings = new HashMap<>(soundNames.size());
for (final Map.Entry<String, Tag> entry : soundNames.entrySet()) {
final StringTag mappedTag = (StringTag) entry.getValue();
backwardsSoundMappings.put(entry.getKey(), mappedTag.getValue());
}
final Map<String, String> map = new HashMap<>(nameMappings.size());
for (final Map.Entry<String, Tag> entry : nameMappings.entrySet()) {
final StringTag mappedTag = (StringTag) entry.getValue();
map.put(entry.getKey(), mappedTag.getValue());
}
return map;
}
private @Nullable Int2ObjectMap<String> loadNameByIdMappings(final CompoundTag data, final String key) {
final CompoundTag nameMappings = data.getCompoundTag(key);
if (nameMappings == null) {
return null;
}
final Int2ObjectMap<String> map = new Int2ObjectArrayMap<>(nameMappings.size());
for (final Map.Entry<String, Tag> entry : nameMappings.entrySet()) {
final StringTag mappedTag = (StringTag) entry.getValue();
map.put(Integer.parseInt(entry.getKey()), mappedTag.getValue());
}
return map;
}
@Override
protected @Nullable BiMappings loadBiMappings(final CompoundTag data, final String key) {
if (key.equals("items") && vvProtocolClass != null) {
final Mappings mappings = super.loadMappings(data, key);
Mappings mappings = super.loadMappings(data, key);
final MappingData mappingData = Via.getManager().getProtocolManager().getProtocol(vvProtocolClass).getMappingData();
if (mappingData != null && mappingData.getItemMappings() != null) {
return ItemMappings.of(mappings, mappingData.getItemMappings());
final BiMappings vvItemMappings = mappingData.getItemMappings();
if (mappings == null) {
mappings = new IdentityMappings(vvItemMappings.mappedSize(), vvItemMappings.size());
}
return ItemMappings.of(mappings, vvItemMappings);
}
}
return super.loadBiMappings(data, key);
@@ -142,13 +164,20 @@ public class BackwardsMappings extends MappingDataBase {
public @Nullable String mappedEntityName(final String entityName) {
if (entityNames == null) {
ViaBackwards.getPlatform().getLogger().severe("No entity mappings found when requesting them for " + entityName);
new Exception().printStackTrace();
getLogger().log(Level.SEVERE, "No entity mappings found when requesting them for " + entityName, new RuntimeException());
return null;
}
return entityNames.get(entityName);
}
public @Nullable String mappedEnchantmentName(final int enchantmentId) {
if (enchantmentNames == null) {
ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "No enchantment name mappings found when requesting " + enchantmentId, new RuntimeException());
return null;
}
return enchantmentNames.get(enchantmentId);
}
public @Nullable Int2ObjectMap<MappedItem> getBackwardsItemMappings() {
return backwardsItemMappings;
}
@@ -167,7 +196,7 @@ public class BackwardsMappings extends MappingDataBase {
}
@Override
protected @Nullable CompoundTag readNBTFile(final String name) {
return VBMappingDataLoader.loadNBTFromDir(name);
protected @Nullable CompoundTag readMappingsFile(final String name) {
return BackwardsMappingDataLoader.INSTANCE.loadNBTFromDir(name);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -17,13 +17,15 @@
*/
package com.viaversion.viabackwards.api.data;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.util.ComponentUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
public class MappedItem {
private final int id;
private final String jsonName;
private final Tag tagName;
private final Integer customModelData;
public MappedItem(final int id, final String name) {
@@ -32,18 +34,23 @@ public class MappedItem {
public MappedItem(final int id, final String name, @Nullable final Integer customModelData) {
this.id = id;
this.jsonName = ChatRewriter.legacyTextToJsonString("§f" + name, true);
this.jsonName = ComponentUtil.legacyToJsonString("§f" + name, true);
this.tagName = ComponentUtil.jsonStringToTag(jsonName);
this.customModelData = customModelData;
}
public int getId() {
public int id() {
return id;
}
public String getJsonName() {
public String jsonName() {
return jsonName;
}
public Tag tagName() {
return tagName;
}
public @Nullable Integer customModelData() {
return customModelData;
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -17,8 +17,8 @@
*/
package com.viaversion.viabackwards.api.data;
import com.viaversion.viabackwards.utils.Block;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.util.IdAndData;
import org.checkerframework.checker.nullness.qual.Nullable;
public class MappedLegacyBlockItem {
@@ -26,14 +26,18 @@ public class MappedLegacyBlockItem {
private final int id;
private final short data;
private final String name;
private final Block block;
private final IdAndData block;
private BlockEntityHandler blockEntityHandler;
public MappedLegacyBlockItem(int id, short data, @Nullable String name, boolean block) {
public MappedLegacyBlockItem(int id) {
this(id, (short) -1, null, Type.ITEM);
}
public MappedLegacyBlockItem(int id, short data, @Nullable String name, Type type) {
this.id = id;
this.data = data;
this.name = name != null ? "§f" + name : null;
this.block = block ? new Block(id, data) : null;
this.block = type != Type.ITEM ? data != -1 ? new IdAndData(id, data) : new IdAndData(id) : null;
}
public int getId() {
@@ -48,11 +52,7 @@ public class MappedLegacyBlockItem {
return name;
}
public boolean isBlock() {
return block != null;
}
public Block getBlock() {
public IdAndData getBlock() {
return block;
}
@@ -73,4 +73,21 @@ public class MappedLegacyBlockItem {
CompoundTag handleOrNewCompoundTag(int block, CompoundTag tag);
}
public enum Type {
ITEM("items"),
BLOCK_ITEM("block-items"),
BLOCK("blocks");
final String name;
Type(final String name) {
this.name = name;
}
public String getName() {
return name;
}
}
}
@@ -1,123 +0,0 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* 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.viabackwards.api.data;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viaversion.libs.gson.JsonIOException;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonSyntaxException;
import com.viaversion.viaversion.libs.opennbt.NBTIO;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.util.GsonUtil;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class VBMappingDataLoader {
public static @Nullable CompoundTag loadNBT(final String name) {
final InputStream resource = getResource(name);
if (resource == null) {
return null;
}
try (final InputStream stream = resource) {
return NBTIO.readTag(stream);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
/**
* Returns nbt data from the plugin folder or packed assets.
* If a file with the same name exists in the plugin folder, the data of the original packed tag will be merged with the file's tag.
*
* @param name name of the file
* @return nbt data from the plugin folder or packed assets
*/
public static @Nullable CompoundTag loadNBTFromDir(final String name) {
final CompoundTag packedData = loadNBT(name);
final File file = new File(ViaBackwards.getPlatform().getDataFolder(), name);
if (!file.exists()) {
return packedData;
}
ViaBackwards.getPlatform().getLogger().info("Loading " + name + " from plugin folder");
try {
final CompoundTag fileData = NBTIO.readFile(file, false, false);
return mergeTags(packedData, fileData);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
private static CompoundTag mergeTags(final CompoundTag original, final CompoundTag extra) {
for (final Map.Entry<String, Tag> entry : extra.entrySet()) {
if (entry.getValue() instanceof CompoundTag) {
// For compound tags, don't replace the entire tag
final CompoundTag originalEntry = original.get(entry.getKey());
if (originalEntry != null) {
mergeTags(originalEntry, (CompoundTag) entry.getValue());
continue;
}
}
original.put(entry.getKey(), entry.getValue());
}
return original;
}
public static JsonObject loadData(final String name) {
try (final InputStream stream = getResource(name)) {
if (stream == null) return null;
return GsonUtil.getGson().fromJson(new InputStreamReader(stream), JsonObject.class);
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
public static JsonObject loadFromDataDir(final String name) {
final File file = new File(ViaBackwards.getPlatform().getDataFolder(), name);
if (!file.exists()) {
return loadData(name);
}
// Load the file from the platform's directory if present
try (final FileReader reader = new FileReader(file)) {
return GsonUtil.getGson().fromJson(reader, JsonObject.class);
} catch (final JsonSyntaxException e) {
ViaBackwards.getPlatform().getLogger().warning(name + " is badly formatted!");
e.printStackTrace();
ViaBackwards.getPlatform().getLogger().warning("Falling back to resource's file!");
return loadData(name);
} catch (final IOException | JsonIOException e) {
e.printStackTrace();
}
return null;
}
public static @Nullable InputStream getResource(final String name) {
return VBMappingDataLoader.class.getClassLoader().getResourceAsStream("assets/viabackwards/data/" + name);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -18,10 +18,10 @@
package com.viaversion.viabackwards.api.entities.storage;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.util.ComponentUtil;
import java.util.Locale;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -30,7 +30,7 @@ public class EntityData {
private final int id;
private final int replacementId;
private final String key;
private NameVisibility nameVisibility = NameVisibility.NONE;
private ComponentType componentType = ComponentType.NONE;
private MetaCreator defaultMeta;
public EntityData(BackwardsProtocol<?, ?, ?, ?> protocol, EntityType type, int replacementId) {
@@ -45,12 +45,17 @@ public class EntityData {
}
public EntityData jsonName() {
this.nameVisibility = NameVisibility.JSON;
this.componentType = ComponentType.JSON;
return this;
}
public EntityData tagName() {
this.componentType = ComponentType.TAG;
return this;
}
public EntityData plainName() {
this.nameVisibility = NameVisibility.PLAIN;
this.componentType = ComponentType.PLAIN;
return this;
}
@@ -70,17 +75,22 @@ public class EntityData {
/**
* @return custom mobname, can be either a String or a JsonElement
*/
public @Nullable Object mobName() {
if (nameVisibility == NameVisibility.NONE) {
public @Nullable Object entityName() {
if (componentType == ComponentType.NONE) {
return null;
}
String name = protocol.getMappingData().mappedEntityName(key);
final String name = protocol.getMappingData().mappedEntityName(key);
if (name == null) {
ViaBackwards.getPlatform().getLogger().warning("Entity name for " + key + " not found in protocol " + protocol.getClass().getSimpleName());
name = key;
return null;
}
return nameVisibility == NameVisibility.JSON ? ChatRewriter.legacyTextToJson(name) : name;
if (componentType == ComponentType.JSON) {
return ComponentUtil.legacyToJson(name);
} else if (componentType == ComponentType.TAG) {
return new StringTag(name);
}
return name;
}
public int replacementId() {
@@ -102,11 +112,11 @@ public class EntityData {
@Override
public String toString() {
return "EntityData{" +
"id=" + id +
", mobName='" + key + '\'' +
", replacementId=" + replacementId +
", defaultMeta=" + defaultMeta +
'}';
"id=" + id +
", mobName='" + key + '\'' +
", replacementId=" + replacementId +
", defaultMeta=" + defaultMeta +
'}';
}
@FunctionalInterface
@@ -115,9 +125,10 @@ public class EntityData {
void createMeta(WrappedMetadata storage);
}
private enum NameVisibility {
private enum ComponentType {
PLAIN,
JSON,
TAG,
NONE
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -43,7 +43,7 @@ public class EntityPositionHandler {
public void cacheEntityPosition(PacketWrapper wrapper, boolean create, boolean relative) throws Exception {
cacheEntityPosition(wrapper,
wrapper.get(Type.DOUBLE, 0), wrapper.get(Type.DOUBLE, 1), wrapper.get(Type.DOUBLE, 2), create, relative);
wrapper.get(Type.DOUBLE, 0), wrapper.get(Type.DOUBLE, 1), wrapper.get(Type.DOUBLE, 2), create, relative);
}
public void cacheEntityPosition(PacketWrapper wrapper, double x, double y, double z, boolean create, boolean relative) throws Exception {
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,6 +19,7 @@ package com.viaversion.viabackwards.api.rewriters;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.MappedItem;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
@@ -29,29 +30,34 @@ import com.viaversion.viaversion.libs.opennbt.tag.builtin.ByteTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.Nullable;
public class ItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends BackwardsProtocol<C, ?, ?, S>> extends ItemRewriterBase<C, S, T> {
public class BackwardsItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends BackwardsProtocol<C, ?, ?, S>> extends BackwardsItemRewriterBase<C, S, T> {
public ItemRewriter(T protocol) {
super(protocol, true);
public BackwardsItemRewriter(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType) {
super(protocol, itemType, itemArrayType, true);
}
public BackwardsItemRewriter(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType, Type<Item> mappedItemType, Type<Item[]> mappedItemArrayType) {
super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, true);
}
@Override
public @Nullable Item handleItemToClient(@Nullable Item item) {
public @Nullable Item handleItemToClient(UserConnection connection, @Nullable Item item) {
if (item == null) {
return null;
}
CompoundTag display = item.tag() != null ? item.tag().get("display") : null;
CompoundTag display = item.tag() != null ? item.tag().getCompoundTag("display") : null;
if (protocol.getTranslatableRewriter() != null && display != null) {
// Handle name and lore components
StringTag name = display.get("Name");
StringTag name = display.getStringTag("Name");
if (name != null) {
String newValue = protocol.getTranslatableRewriter().processText(name.getValue()).toString();
String newValue = protocol.getTranslatableRewriter().processText(connection, name.getValue()).toString();
if (!newValue.equals(name.getValue())) {
saveStringTag(display, name, "Name");
}
@@ -59,14 +65,11 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
name.setValue(newValue);
}
ListTag lore = display.get("Lore");
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
if (lore != null) {
boolean changed = false;
for (Tag loreEntryTag : lore) {
if (!(loreEntryTag instanceof StringTag)) continue;
StringTag loreEntry = (StringTag) loreEntryTag;
String newValue = protocol.getTranslatableRewriter().processText(loreEntry.getValue()).toString();
for (StringTag loreEntry : lore) {
String newValue = protocol.getTranslatableRewriter().processText(connection, loreEntry.getValue()).toString();
if (!changed && !newValue.equals(loreEntry.getValue())) {
// Backup original lore before doing any modifications
changed = true;
@@ -78,10 +81,10 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
}
}
MappedItem data = protocol.getMappingData().getMappedItem(item.identifier());
MappedItem data = protocol.getMappingData() != null ? protocol.getMappingData().getMappedItem(item.identifier()) : null;
if (data == null) {
// Just rewrite the id
return super.handleItemToClient(item);
return super.handleItemToClient(connection, item);
}
if (item.tag() == null) {
@@ -89,12 +92,12 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
}
// Save original id, set remapped id
item.tag().put(nbtTagName + "|id", new IntTag(item.identifier()));
item.setIdentifier(data.getId());
item.tag().putInt(nbtTagName("id"), item.identifier());
item.setIdentifier(data.id());
// Add custom model data
if (data.customModelData() != null && !item.tag().contains("CustomModelData")) {
item.tag().put("CustomModelData", new IntTag(data.customModelData()));
item.tag().putInt("CustomModelData", data.customModelData());
}
// Set custom name - only done if there is no original one
@@ -102,28 +105,28 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
item.tag().put("display", display = new CompoundTag());
}
if (!display.contains("Name")) {
display.put("Name", new StringTag(data.getJsonName()));
display.put(nbtTagName + "|customName", new ByteTag());
display.put("Name", new StringTag(data.jsonName()));
display.put(nbtTagName("customName"), new ByteTag());
}
return item;
}
@Override
public @Nullable Item handleItemToServer(@Nullable Item item) {
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable Item item) {
if (item == null) return null;
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
if (item.tag() != null) {
IntTag originalId = item.tag().remove(nbtTagName + "|id");
if (originalId != null) {
item.setIdentifier(originalId.asInt());
Tag originalId = item.tag().remove(nbtTagName("id"));
if (originalId instanceof IntTag) {
item.setIdentifier(((NumberTag) originalId).asInt());
}
}
return item;
}
@Override
public void registerAdvancements(C packetType, Type<Item> type) {
public void registerAdvancements(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
@@ -132,11 +135,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
final int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.STRING);
}
wrapper.passthrough(Type.OPTIONAL_STRING); // Parent
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {
@@ -144,11 +143,13 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
final JsonElement description = wrapper.passthrough(Type.COMPONENT);
final TranslatableRewriter<C> translatableRewriter = protocol.getTranslatableRewriter();
if (translatableRewriter != null) {
translatableRewriter.processText(title);
translatableRewriter.processText(description);
translatableRewriter.processText(wrapper.user(), title);
translatableRewriter.processText(wrapper.user(), description);
}
handleItemToClient(wrapper.passthrough(type)); // Icon
final Item icon = handleItemToClient(wrapper.user(), wrapper.read(itemType()));
wrapper.write(mappedItemType(), icon);
wrapper.passthrough(Type.VAR_INT); // Frame type
int flags = wrapper.passthrough(Type.INT); // Flags
if ((flags & 1) != 0) {
@@ -169,4 +170,46 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
}
});
}
@Override
public void registerAdvancements1_20_3(final C packetType) {
// Insert translatable rewriter
protocol.registerClientbound(packetType, wrapper -> {
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
final int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
wrapper.passthrough(Type.OPTIONAL_STRING); // Parent
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {
final Tag title = wrapper.passthrough(Type.TAG);
final Tag description = wrapper.passthrough(Type.TAG);
final TranslatableRewriter<C> translatableRewriter = protocol.getTranslatableRewriter();
if (translatableRewriter != null) {
translatableRewriter.processTag(wrapper.user(), title);
translatableRewriter.processTag(wrapper.user(), description);
}
final Item icon = handleItemToClient(wrapper.user(), wrapper.read(itemType()));
wrapper.write(mappedItemType(), icon);
wrapper.passthrough(Type.VAR_INT); // Frame type
final int flags = wrapper.passthrough(Type.INT);
if ((flags & 1) != 0) {
wrapper.passthrough(Type.STRING); // Background texture
}
wrapper.passthrough(Type.FLOAT); // X
wrapper.passthrough(Type.FLOAT); // Y
}
final int requirements = wrapper.passthrough(Type.VAR_INT);
for (int array = 0; array < requirements; array++) {
wrapper.passthrough(Type.STRING_ARRAY);
}
wrapper.passthrough(Type.BOOLEAN); // Send telemetry
}
});
}
}
@@ -0,0 +1,147 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-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.viabackwards.api.rewriters;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.type.Type;
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.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import java.util.ArrayList;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class BackwardsItemRewriterBase<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends BackwardsProtocol<C, ?, ?, S>> extends ItemRewriter<C, S, T> {
protected final boolean jsonNameFormat;
protected BackwardsItemRewriterBase(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType, Type<Item> mappedItemType, Type<Item[]> mappedItemArrayType, boolean jsonFormat) {
super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType);
this.jsonNameFormat = jsonFormat;
}
protected BackwardsItemRewriterBase(T protocol, Type<Item> itemType, Type<Item[]> itemArrayType, boolean jsonNameFormat) {
this(protocol, itemType, itemArrayType, itemType, itemArrayType, jsonNameFormat);
}
@Override
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
restoreDisplayTag(item);
return item;
}
protected boolean hasBackupTag(CompoundTag tag, String tagName) {
return tag.contains(nbtTagName(tagName));
}
protected void saveStringTag(CompoundTag tag, StringTag original, String name) {
// Multiple places might try to backup data
String backupName = nbtTagName(name);
if (!tag.contains(backupName)) {
tag.putString(backupName, original.getValue());
}
}
protected void saveListTag(CompoundTag tag, ListTag<?> original, String name) {
// Multiple places might try to backup data
String backupName = nbtTagName(name);
if (!tag.contains(backupName)) {
tag.put(backupName, original.copy());
}
}
protected void saveGenericTagList(CompoundTag tag, List<Tag> original, String name) {
// List tags cannot contain tags of different types, so we have to store them a bit more awkwardly as an indexed compound tag
String backupName = nbtTagName(name);
if (!tag.contains(backupName)) {
CompoundTag output = new CompoundTag();
for (int i = 0; i < original.size(); i++) {
output.put(Integer.toString(i), original.get(i));
}
tag.put(backupName, output);
}
}
protected List<Tag> removeGenericTagList(CompoundTag tag, String name) {
String backupName = nbtTagName(name);
CompoundTag data = tag.getCompoundTag(backupName);
if (data == null) {
return null;
}
tag.remove(backupName);
return new ArrayList<>(data.values());
}
protected void restoreDisplayTag(Item item) {
if (item.tag() == null) return;
CompoundTag display = item.tag().getCompoundTag("display");
if (display != null) {
// Remove custom name / restore original name
if (display.remove(nbtTagName("customName")) != null) {
display.remove("Name");
} else {
restoreStringTag(display, "Name");
}
// Restore lore
restoreListTag(display, "Lore");
}
}
protected void restoreStringTag(CompoundTag tag, String tagName) {
Tag original = tag.remove(nbtTagName(tagName));
if (original instanceof StringTag) {
tag.putString(tagName, ((StringTag) original).getValue());
}
}
protected void restoreListTag(CompoundTag tag, String tagName) {
Tag original = tag.remove(nbtTagName(tagName));
if (original instanceof ListTag) {
tag.put(tagName, ((ListTag<?>) original).copy());
}
}
public <T extends Tag> @Nullable ListTag<T> removeListTag(CompoundTag tag, String tagName, Class<T> tagType) {
String backupName = nbtTagName(tagName);
ListTag<T> data = tag.getListTag(backupName, tagType);
if (data == null) {
return null;
}
tag.remove(backupName);
return data;
}
@Override
public String nbtTagName() {
return "VB|" + protocol.getClass().getSimpleName();
}
}
@@ -0,0 +1,186 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-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.viabackwards.api.rewriters;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.BackwardsMappings;
import com.viaversion.viabackwards.api.data.MappedItem;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import org.checkerframework.checker.nullness.qual.Nullable;
public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends BackwardsProtocol<C, ?, ?, S>> extends BackwardsItemRewriter<C, S, T> {
protected final StructuredEnchantmentRewriter enchantmentRewriter = new StructuredEnchantmentRewriter(this);
public BackwardsStructuredItemRewriter(final T protocol, final Type<Item> itemType, final Type<Item[]> itemArrayType) {
super(protocol, itemType, itemArrayType);
}
public BackwardsStructuredItemRewriter(final T protocol, final Type<Item> itemType, final Type<Item[]> itemArrayType, final Type<Item> mappedItemType, final Type<Item[]> mappedItemArrayType) {
super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType);
}
@Override
public @Nullable Item handleItemToClient(final UserConnection connection, @Nullable final Item item) {
if (item == null) {
return null;
}
final StructuredDataContainer data = item.structuredData();
data.setIdLookup(protocol, true);
if (protocol.getMappingData().getEnchantmentMappings() != null) {
enchantmentRewriter.handleToClient(item);
}
if (protocol.getTranslatableRewriter() != null) {
// Handle name and lore components
final StructuredData<Tag> customNameData = data.getNonEmpty(StructuredDataKey.CUSTOM_NAME);
if (customNameData != null) {
final Tag originalName = customNameData.value().copy();
protocol.getTranslatableRewriter().processTag(connection, customNameData.value());
if (!customNameData.value().equals(originalName)) {
saveTag(createCustomTag(item), originalName, "Name");
}
}
final StructuredData<Tag[]> loreData = data.getNonEmpty(StructuredDataKey.LORE);
if (loreData != null) {
for (final Tag tag : loreData.value()) {
protocol.getTranslatableRewriter().processTag(connection, tag);
}
}
}
final BackwardsMappings mappingData = protocol.getMappingData();
final MappedItem mappedItem = mappingData != null ? mappingData.getMappedItem(item.identifier()) : null;
if (mappedItem == null) {
// Just rewrite the id
if (mappingData != null && mappingData.getItemMappings() != null) {
item.setIdentifier(mappingData.getNewItemId(item.identifier()));
}
return item;
}
// Save original id, set remapped id
final CompoundTag tag = createCustomTag(item);
tag.putInt(nbtTagName("id"), item.identifier());
item.setIdentifier(mappedItem.id());
// Add custom model data
if (mappedItem.customModelData() != null && !data.contains(StructuredDataKey.CUSTOM_MODEL_DATA)) {
data.set(StructuredDataKey.CUSTOM_MODEL_DATA, mappedItem.customModelData());
}
// Set custom name - only done if there is no original one
if (!data.contains(StructuredDataKey.CUSTOM_NAME)) {
data.set(StructuredDataKey.CUSTOM_NAME, mappedItem.tagName());
tag.putBoolean(nbtTagName("customName"), true);
}
return item;
}
@Override
public @Nullable Item handleItemToServer(final UserConnection connection, @Nullable final Item item) {
if (item == null) {
return null;
}
final BackwardsMappings mappingData = protocol.getMappingData();
if (mappingData != null && mappingData.getItemMappings() != null) {
item.setIdentifier(mappingData.getOldItemId(item.identifier()));
}
final StructuredDataContainer data = item.structuredData();
data.setIdLookup(protocol, false);
if (protocol.getMappingData().getEnchantmentMappings() != null) {
enchantmentRewriter.handleToServer(item);
}
final CompoundTag tag = customTag(item);
if (tag != null) {
final Tag originalId = tag.remove(nbtTagName("id"));
if (originalId instanceof IntTag) {
item.setIdentifier(((NumberTag) originalId).asInt());
}
}
restoreDisplayTag(item);
return item;
}
protected @Nullable CompoundTag customTag(final Item item) {
final StructuredData<CompoundTag> customData = item.structuredData().getNonEmpty(StructuredDataKey.CUSTOM_DATA);
return customData != null ? customData.value() : null;
}
protected CompoundTag createCustomTag(final Item item) {
final StructuredDataContainer data = item.structuredData();
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
if (customData != null) {
return customData.value();
}
final CompoundTag tag = new CompoundTag();
data.set(StructuredDataKey.CUSTOM_DATA, tag);
return tag;
}
@Override
protected void restoreDisplayTag(final Item item) {
final StructuredDataContainer data = item.structuredData();
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
if (customData == null) {
return;
}
// Remove custom name
if (customData.value().remove(nbtTagName("customName")) != null) {
data.remove(StructuredDataKey.CUSTOM_NAME);
} else {
final Tag name = removeBackupTag(customData.value(), "Name");
if (name != null) {
data.set(StructuredDataKey.CUSTOM_NAME, name);
}
}
}
protected void saveTag(CompoundTag customData, Tag tag, String name) {
String backupName = nbtTagName(name);
if (!customData.contains(backupName)) {
customData.put(backupName, tag);
}
}
protected @Nullable Tag removeBackupTag(CompoundTag customData, String tagName) {
return customData.remove(nbtTagName(tagName));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -21,10 +21,9 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
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.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ShortTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -36,31 +35,31 @@ import java.util.Map;
*/
public class EnchantmentRewriter {
private final Map<String, String> enchantmentMappings = new HashMap<>();
private final ItemRewriter<?, ?, ?> itemRewriter;
protected final Map<String, String> enchantmentMappings = new HashMap<>();
protected final BackwardsItemRewriter<?, ?, ?> itemRewriter;
private final boolean jsonFormat;
public EnchantmentRewriter(ItemRewriter<?, ?, ?> itemRewriter, boolean jsonFormat) {
public EnchantmentRewriter(BackwardsItemRewriter<?, ?, ?> itemRewriter, boolean jsonFormat) {
this.itemRewriter = itemRewriter;
this.jsonFormat = jsonFormat;
}
public EnchantmentRewriter(ItemRewriter<?, ?, ?> itemRewriter) {
public EnchantmentRewriter(BackwardsItemRewriter<?, ?, ?> itemRewriter) {
this(itemRewriter, true);
}
public void registerEnchantment(String key, String replacementLore) {
enchantmentMappings.put(key, replacementLore);
enchantmentMappings.put(Key.stripMinecraftNamespace(key), replacementLore);
}
public void handleToClient(Item item) {
CompoundTag tag = item.tag();
if (tag == null) return;
if (tag.get("Enchantments") instanceof ListTag) {
if (tag.getListTag("Enchantments") != null) {
rewriteEnchantmentsToClient(tag, false);
}
if (tag.get("StoredEnchantments") instanceof ListTag) {
if (tag.getListTag("StoredEnchantments") != null) {
rewriteEnchantmentsToClient(tag, true);
}
}
@@ -69,27 +68,29 @@ public class EnchantmentRewriter {
CompoundTag tag = item.tag();
if (tag == null) return;
if (tag.contains(itemRewriter.getNbtTagName() + "|Enchantments")) {
if (tag.contains(itemRewriter.nbtTagName("Enchantments"))) {
rewriteEnchantmentsToServer(tag, false);
}
if (tag.contains(itemRewriter.getNbtTagName() + "|StoredEnchantments")) {
if (tag.contains(itemRewriter.nbtTagName("StoredEnchantments"))) {
rewriteEnchantmentsToServer(tag, true);
}
}
public void rewriteEnchantmentsToClient(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "Enchantments";
ListTag enchantments = tag.get(key);
List<Tag> loreToAdd = new ArrayList<>();
ListTag<CompoundTag> enchantments = tag.getListTag(key, CompoundTag.class);
List<StringTag> loreToAdd = new ArrayList<>();
boolean changed = false;
Iterator<Tag> iterator = enchantments.iterator();
Iterator<CompoundTag> iterator = enchantments.iterator();
while (iterator.hasNext()) {
CompoundTag enchantmentEntry = (CompoundTag) iterator.next();
Tag idTag = enchantmentEntry.get("id");
if (!(idTag instanceof StringTag)) continue;
CompoundTag enchantmentEntry = iterator.next();
StringTag idTag = enchantmentEntry.getStringTag("id");
if (idTag == null) {
continue;
}
String enchantmentId = ((StringTag) idTag).getValue();
String enchantmentId = Key.stripMinecraftNamespace(idTag.getValue());
String remappedName = enchantmentMappings.get(enchantmentId);
if (remappedName != null) {
if (!changed) {
@@ -100,10 +101,11 @@ public class EnchantmentRewriter {
iterator.remove();
int level = ((NumberTag) enchantmentEntry.get("lvl")).asInt();
NumberTag levelTag = enchantmentEntry.getNumberTag("lvl");
int level = levelTag != null ? levelTag.asInt() : 1;
String loreValue = remappedName + " " + getRomanNumber(level);
if (jsonFormat) {
loreValue = ChatRewriter.legacyTextToJsonString(loreValue);
loreValue = ComponentUtil.legacyToJsonString(loreValue);
}
loreToAdd.add(new StringTag(loreValue));
@@ -112,21 +114,21 @@ public class EnchantmentRewriter {
if (!loreToAdd.isEmpty()) {
// Add dummy enchant for the glow effect if there are no actual enchantments left
if (!storedEnchant && enchantments.size() == 0) {
if (!storedEnchant && enchantments.isEmpty()) {
CompoundTag dummyEnchantment = new CompoundTag();
dummyEnchantment.put("id", new StringTag());
dummyEnchantment.put("lvl", new ShortTag((short) 0));
dummyEnchantment.putString("id", "");
dummyEnchantment.putShort("lvl", (short) 0);
enchantments.add(dummyEnchantment);
}
CompoundTag display = tag.get("display");
CompoundTag display = tag.getCompoundTag("display");
if (display == null) {
tag.put("display", display = new CompoundTag());
}
ListTag loreTag = display.get("Lore");
ListTag<StringTag> loreTag = display.getListTag("Lore", StringTag.class);
if (loreTag == null) {
display.put("Lore", loreTag = new ListTag(StringTag.class));
display.put("Lore", loreTag = new ListTag<>(StringTag.class));
} else {
// Save original lore
itemRewriter.saveListTag(display, loreTag, "Lore");
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -90,6 +90,10 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
public PacketHandler getSpawnTrackerWithDataHandler1_19(EntityType fallingBlockType) {
return wrapper -> {
if (protocol.getMappingData() == null) {
return;
}
// Check against the UNMAPPED entity type
EntityType entityType = trackAndMapEntity(wrapper);
if (entityType == fallingBlockType) {
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -23,9 +23,10 @@ import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.entities.storage.EntityData;
import com.viaversion.viabackwards.api.entities.storage.WrappedMetadata;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.Int2IntMapMappings;
import com.viaversion.viaversion.api.data.entity.StoredEntityData;
import com.viaversion.viaversion.api.data.entity.TrackedEntity;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
@@ -35,7 +36,6 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.rewriter.meta.MetaHandlerEvent;
import java.util.List;
@@ -76,21 +76,22 @@ public abstract class EntityRewriterBase<C extends ClientboundPacketType, T exte
// Set the mapped entity name if there is no custom name set already
final EntityData entityData = entityDataForType(entity.entityType());
if (entityData != null && entityData.mobName() != null) {
final Object displayNameObject;
if (entityData != null && (displayNameObject = entityData.entityName()) != null) {
final Metadata displayName = getMeta(displayNameIndex, metadataList);
if (initialMetadata) {
if (displayName == null) {
// Add it as new metadata
metadataList.add(new Metadata(displayNameIndex, displayNameMetaType, entityData.mobName()));
metadataList.add(new Metadata(displayNameIndex, displayNameMetaType, displayNameObject));
addDisplayVisibilityMeta(metadataList);
} else if (displayName.getValue() == null || displayName.getValue().toString().isEmpty()) {
// Overwrite the existing null/empty display name
displayName.setValue(entityData.mobName());
displayName.setValue(displayNameObject);
addDisplayVisibilityMeta(metadataList);
}
} else if (displayName != null && (displayName.getValue() == null || displayName.getValue().toString().isEmpty())) {
// Overwrite null/empty display name
displayName.setValue(entityData.mobName());
displayName.setValue(displayNameObject);
addDisplayVisibilityMeta(metadataList);
}
}
@@ -102,12 +103,20 @@ public abstract class EntityRewriterBase<C extends ClientboundPacketType, T exte
}
private void addDisplayVisibilityMeta(List<Metadata> metadataList) {
if (ViaBackwards.getConfig().alwaysShowOriginalMobName()) {
if (alwaysShowOriginalMobName()) {
removeMeta(displayVisibilityIndex, metadataList);
metadataList.add(new Metadata(displayVisibilityIndex, displayVisibilityMetaType, true));
metadataList.add(new Metadata(displayVisibilityIndex, displayVisibilityMetaType, getDisplayVisibilityMetaValue()));
}
}
protected Object getDisplayVisibilityMetaValue() {
return true;
}
protected boolean alwaysShowOriginalMobName() {
return ViaBackwards.getConfig().alwaysShowOriginalMobName();
}
protected @Nullable Metadata getMeta(int metaIndex, List<Metadata> metadataList) {
for (Metadata metadata : metadataList) {
if (metadata.id() == metaIndex) {
@@ -153,43 +162,65 @@ public abstract class EntityRewriterBase<C extends ClientboundPacketType, T exte
return data;
}
/**
* Maps entity ids based on the enum constant's names.
*
* @param oldTypes entity types of the higher version
* @param newTypeClass entity types enum class of the lower version
* @param <E> new enum type
*/
@Override
public <E extends Enum<E> & EntityType> void mapTypes(EntityType[] oldTypes, Class<E> newTypeClass) {
if (typeMappings == null) {
typeMappings = Int2IntMapMappings.of();
}
for (EntityType oldType : oldTypes) {
try {
E newType = Enum.valueOf(newTypeClass, oldType.name());
typeMappings.setNewId(oldType.getId(), newType.getId());
} catch (IllegalArgumentException ignored) {
// Don't warn
}
}
}
public void registerMetaTypeHandler(@Nullable MetaType itemType, @Nullable MetaType blockType, @Nullable MetaType particleType, @Nullable MetaType optChatType) {
public void registerMetaTypeHandler(
@Nullable MetaType itemType,
@Nullable MetaType blockStateType,
@Nullable MetaType optionalBlockStateType,
@Nullable MetaType particleType,
@Nullable MetaType componentType,
@Nullable MetaType optionalComponentType
) {
filter().handler((event, meta) -> {
MetaType type = meta.metaType();
if (itemType != null && type == itemType) {
protocol.getItemRewriter().handleItemToClient(meta.value());
} else if (blockType != null && type == blockType) {
if (type == itemType) {
protocol.getItemRewriter().handleItemToClient(event.user(), meta.value());
} else if (type == blockStateType) {
int data = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
} else if (particleType != null && type == particleType) {
rewriteParticle(meta.value());
} else if (optChatType != null && type == optChatType) {
JsonElement text = meta.value();
if (text != null) {
protocol.getTranslatableRewriter().processText(text);
} else if (type == optionalBlockStateType) {
int data = meta.value();
if (data != 0) {
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
} else if (type == particleType) {
rewriteParticle(event.user(), meta.value());
} else if (type == optionalComponentType || type == componentType) {
JsonElement text = meta.value();
protocol.getTranslatableRewriter().processText(event.user(), text);
}
});
}
public void registerMetaTypeHandler1_20_3(
@Nullable MetaType itemType,
@Nullable MetaType blockStateType,
@Nullable MetaType optionalBlockStateType,
@Nullable MetaType particleType,
@Nullable MetaType particlesType,
@Nullable MetaType componentType,
@Nullable MetaType optionalComponentType
) {
filter().handler((event, meta) -> {
MetaType type = meta.metaType();
if (type == itemType) {
meta.setValue(protocol.getItemRewriter().handleItemToClient(event.user(), meta.value()));
} else if (type == blockStateType) {
int data = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
} else if (type == optionalBlockStateType) {
int data = meta.value();
if (data != 0) {
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
} else if (type == particleType) {
rewriteParticle(event.user(), meta.value());
} else if (type == particlesType) {
Particle[] particles = meta.value();
for (final Particle particle : particles) {
rewriteParticle(event.user(), particle);
}
} else if (type == optionalComponentType || type == componentType) {
protocol.getTranslatableRewriter().processTag(event.user(), meta.value());
}
});
}
@@ -1,112 +0,0 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* 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.viabackwards.api.rewriters;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
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.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class ItemRewriterBase<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends BackwardsProtocol<C, ?, ?, S>> extends ItemRewriter<C, S, T> {
protected final String nbtTagName;
protected final boolean jsonNameFormat;
protected ItemRewriterBase(T protocol, boolean jsonNameFormat) {
super(protocol);
this.jsonNameFormat = jsonNameFormat;
nbtTagName = "VB|" + protocol.getClass().getSimpleName();
}
@Override
public @Nullable Item handleItemToServer(@Nullable Item item) {
if (item == null) return null;
super.handleItemToServer(item);
restoreDisplayTag(item);
return item;
}
protected boolean hasBackupTag(CompoundTag displayTag, String tagName) {
return displayTag.contains(nbtTagName + "|o" + tagName);
}
protected void saveStringTag(CompoundTag displayTag, StringTag original, String name) {
// Multiple places might try to backup data
String backupName = nbtTagName + "|o" + name;
if (!displayTag.contains(backupName)) {
displayTag.put(backupName, new StringTag(original.getValue()));
}
}
protected void saveListTag(CompoundTag displayTag, ListTag original, String name) {
// Multiple places might try to backup data
String backupName = nbtTagName + "|o" + name;
if (!displayTag.contains(backupName)) {
// Clone all tag entries
ListTag listTag = new ListTag();
for (Tag tag : original.getValue()) {
listTag.add(tag.clone());
}
displayTag.put(backupName, listTag);
}
}
protected void restoreDisplayTag(Item item) {
if (item.tag() == null) return;
CompoundTag display = item.tag().get("display");
if (display != null) {
// Remove custom name / restore original name
if (display.remove(nbtTagName + "|customName") != null) {
display.remove("Name");
} else {
restoreStringTag(display, "Name");
}
// Restore lore
restoreListTag(display, "Lore");
}
}
protected void restoreStringTag(CompoundTag tag, String tagName) {
StringTag original = tag.remove(nbtTagName + "|o" + tagName);
if (original != null) {
tag.put(tagName, new StringTag(original.getValue()));
}
}
protected void restoreListTag(CompoundTag tag, String tagName) {
ListTag original = tag.remove(nbtTagName + "|o" + tagName);
if (original != null) {
tag.put(tagName, new ListTag(original.getValue()));
}
}
public String getNbtTagName() {
return nbtTagName;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,16 +20,21 @@ package com.viaversion.viabackwards.api.rewriters;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.MappedLegacyBlockItem;
import com.viaversion.viabackwards.api.data.VBMappingDataLoader;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.data.BlockColors;
import com.viaversion.viabackwards.utils.Block;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
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.minecraft.entities.EntityTypes1_12;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import com.viaversion.viaversion.libs.gson.JsonElement;
@@ -39,120 +44,207 @@ import com.viaversion.viaversion.libs.opennbt.tag.builtin.ByteTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ShortTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import com.viaversion.viaversion.util.IdAndData;
import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
T extends BackwardsProtocol<C, ?, ?, S>> extends ItemRewriterBase<C, S, T> {
T extends BackwardsProtocol<C, ?, ?, S>> extends BackwardsItemRewriterBase<C, S, T> {
private static final Map<String, Int2ObjectMap<MappedLegacyBlockItem>> LEGACY_MAPPINGS = new HashMap<>();
protected final Int2ObjectMap<MappedLegacyBlockItem> replacementData;
protected final Int2ObjectMap<MappedLegacyBlockItem> itemReplacements = new Int2ObjectOpenHashMap<>(8); // Raw id -> mapped data
protected final Int2ObjectMap<MappedLegacyBlockItem> blockReplacements = new Int2ObjectOpenHashMap<>(8); // Raw id -> mapped data
static {
JsonObject jsonObject = VBMappingDataLoader.loadFromDataDir("legacy-mappings.json");
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
Int2ObjectMap<MappedLegacyBlockItem> mappings = new Int2ObjectOpenHashMap<>(8);
LEGACY_MAPPINGS.put(entry.getKey(), mappings);
for (Map.Entry<String, JsonElement> dataEntry : entry.getValue().getAsJsonObject().entrySet()) {
JsonObject object = dataEntry.getValue().getAsJsonObject();
int id = object.getAsJsonPrimitive("id").getAsInt();
JsonPrimitive jsonData = object.getAsJsonPrimitive("data");
short data = jsonData != null ? jsonData.getAsShort() : 0;
String name = object.getAsJsonPrimitive("name").getAsString();
JsonPrimitive blockField = object.getAsJsonPrimitive("block");
boolean block = blockField != null && blockField.getAsBoolean();
protected LegacyBlockItemRewriter(T protocol, String name, Type<Item> itemType, Type<Item[]> itemArrayType, Type<Item> mappedItemType, Type<Item[]> mappedItemArrayType) {
super(protocol, itemType, itemArrayType, mappedItemType, mappedItemArrayType, false);
if (dataEntry.getKey().indexOf('-') != -1) {
// Range of ids
String[] split = dataEntry.getKey().split("-", 2);
int from = Integer.parseInt(split[0]);
int to = Integer.parseInt(split[1]);
Int2ObjectMap<MappedLegacyBlockItem> blockItemReplacements = new Int2ObjectOpenHashMap<>(8);
final JsonObject jsonObject = readMappingsFile("item-mappings-" + name + ".json");
addMappings(MappedLegacyBlockItem.Type.ITEM, jsonObject, itemReplacements);
addMappings(MappedLegacyBlockItem.Type.BLOCK_ITEM, jsonObject, blockItemReplacements);
addMappings(MappedLegacyBlockItem.Type.BLOCK, jsonObject, blockReplacements);
// Special block color handling
if (name.contains("%color%")) {
for (int i = from; i <= to; i++) {
mappings.put(i, new MappedLegacyBlockItem(id, data, name.replace("%color%", BlockColors.get(i - from)), block));
}
} else {
MappedLegacyBlockItem mappedBlockItem = new MappedLegacyBlockItem(id, data, name, block);
for (int i = from; i <= to; i++) {
mappings.put(i, mappedBlockItem);
}
}
} else {
mappings.put(Integer.parseInt(dataEntry.getKey()), new MappedLegacyBlockItem(id, data, name, block));
}
blockReplacements.putAll(blockItemReplacements);
itemReplacements.putAll(blockItemReplacements);
}
protected LegacyBlockItemRewriter(T protocol, String name, Type<Item> itemType, Type<Item[]> itemArrayType) {
this(protocol, name, itemType, itemArrayType, itemType, itemArrayType);
}
protected LegacyBlockItemRewriter(T protocol, String name) {
this(protocol, name, Type.ITEM1_8, Type.ITEM1_8_SHORT_ARRAY);
}
private void addMappings(MappedLegacyBlockItem.Type type, JsonObject object, Int2ObjectMap<MappedLegacyBlockItem> mappings) {
if (object.has(type.getName())) {
final JsonObject mappingsObject = object.getAsJsonObject(type.getName());
for (Map.Entry<String, JsonElement> dataEntry : mappingsObject.entrySet()) {
addMapping(dataEntry.getKey(), dataEntry.getValue().getAsJsonObject(), type, mappings);
}
}
}
protected LegacyBlockItemRewriter(T protocol) {
super(protocol, false);
replacementData = LEGACY_MAPPINGS.get(protocol.getClass().getSimpleName().split("To")[1].replace("_", "."));
private void addMapping(String key, JsonObject object, MappedLegacyBlockItem.Type type, Int2ObjectMap<MappedLegacyBlockItem> mappings) {
int id = object.getAsJsonPrimitive("id").getAsInt();
JsonPrimitive jsonData = object.getAsJsonPrimitive("data");
short data = jsonData != null ? jsonData.getAsShort() : 0;
String name = type != MappedLegacyBlockItem.Type.BLOCK ? object.getAsJsonPrimitive("name").getAsString() : null;
if (key.indexOf('-') == -1) {
int unmappedId;
int dataSeparatorIndex = key.indexOf(':');
if (dataSeparatorIndex != -1) {
// Include data
short unmappedData = Short.parseShort(key.substring(dataSeparatorIndex + 1));
unmappedId = Integer.parseInt(key.substring(0, dataSeparatorIndex));
unmappedId = IdAndData.toRawData(unmappedId, unmappedData);
} else {
unmappedId = IdAndData.toRawData(Integer.parseInt(key), -1);
}
mappings.put(unmappedId, new MappedLegacyBlockItem(id, data, name, type));
return;
}
// Range of ids
String[] split = key.split("-", 2);
int from = Integer.parseInt(split[0]);
int to = Integer.parseInt(split[1]);
// Special block color handling
if (name != null && name.contains("%color%")) {
for (int i = from; i <= to; i++) {
mappings.put(IdAndData.toRawData(i, -1), new MappedLegacyBlockItem(id, data, name.replace("%color%", BlockColors.get(i - from)), type));
}
} else {
MappedLegacyBlockItem mappedBlockItem = new MappedLegacyBlockItem(id, data, name, type);
for (int i = from; i <= to; i++) {
mappings.put(IdAndData.toRawData(i, -1), mappedBlockItem);
}
}
}
public void registerBlockChange(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION1_8); // 0 - Block Position
map(Type.VAR_INT); // 1 - Block
handler(wrapper -> {
int idx = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, handleBlockId(idx));
});
}
});
}
public void registerMultiBlockChange(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
record.setBlockId(handleBlockId(record.getBlockId()));
}
});
}
});
}
@Override
public @Nullable Item handleItemToClient(@Nullable Item item) {
public @Nullable Item handleItemToClient(UserConnection connection, @Nullable Item item) {
if (item == null) return null;
MappedLegacyBlockItem data = replacementData.get(item.identifier());
MappedLegacyBlockItem data = getMappedItem(item.identifier(), item.data());
if (data == null) {
// Just rewrite the id
return super.handleItemToClient(item);
return super.handleItemToClient(connection, item);
}
if (item.tag() == null) {
item.setTag(new CompoundTag());
}
short originalData = item.data();
item.tag().putInt(nbtTagName("id"), item.identifier());
item.setIdentifier(data.getId());
// Keep original data if mapped data is set to -1
if (data.getData() != -1) {
item.setData(data.getData());
item.tag().putShort(nbtTagName("data"), originalData);
}
// Set display name
if (data.getName() != null) {
if (item.tag() == null) {
item.setTag(new CompoundTag());
}
CompoundTag display = item.tag().get("display");
CompoundTag display = item.tag().getCompoundTag("display");
if (display == null) {
item.tag().put("display", display = new CompoundTag());
}
StringTag nameTag = display.get("Name");
StringTag nameTag = display.getStringTag("Name");
if (nameTag == null) {
display.put("Name", nameTag = new StringTag(data.getName()));
display.put(nbtTagName + "|customName", new ByteTag());
nameTag = new StringTag(data.getName());
display.put("Name", nameTag);
display.put(nbtTagName("customName"), new ByteTag());
}
// Handle colors
String value = nameTag.getValue();
if (value.contains("%vb_color%")) {
display.put("Name", new StringTag(value.replace("%vb_color%", BlockColors.get(originalData))));
display.putString("Name", value.replace("%vb_color%", BlockColors.get(originalData)));
}
}
return item;
}
public int handleBlockID(int idx) {
int type = idx >> 4;
int meta = idx & 15;
Block b = handleBlock(type, meta);
if (b == null) return idx;
return (b.getId() << 4 | (b.getData() & 15));
@Override
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable final Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
if (item.tag() != null) {
Tag originalId = item.tag().remove(nbtTagName("id"));
if (originalId instanceof IntTag) {
item.setIdentifier(((NumberTag) originalId).asInt());
}
Tag originalData = item.tag().remove(nbtTagName("data"));
if (originalData instanceof ShortTag) {
item.setData(((NumberTag) originalData).asShort());
}
}
return item;
}
public @Nullable Block handleBlock(int blockId, int data) {
MappedLegacyBlockItem settings = replacementData.get(blockId);
if (settings == null || !settings.isBlock()) return null;
public PacketHandler getFallingBlockHandler() {
return wrapper -> {
final Optional<EntityTypes1_12.ObjectType> type = EntityTypes1_12.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get() == EntityTypes1_12.ObjectType.FALLING_BLOCK) {
final int objectData = wrapper.get(Type.INT, 0);
Block block = settings.getBlock();
final IdAndData block = handleBlock(objectData & 4095, objectData >> 12 & 15);
if (block == null) return;
wrapper.set(Type.INT, 0, block.getId() | block.getData() << 12);
}
};
}
public @Nullable IdAndData handleBlock(int blockId, int data) {
MappedLegacyBlockItem settings = getMappedBlock(blockId, data);
if (settings == null) {
return null;
}
IdAndData block = settings.getBlock();
// For some blocks, the data can still be useful (:
if (block.getData() == -1) {
return block.withData(data);
@@ -160,21 +252,30 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
return block;
}
protected void handleChunk(Chunk chunk) {
public int handleBlockId(final int rawId) {
final int id = IdAndData.getId(rawId);
final int data = IdAndData.getData(rawId);
final IdAndData mappedBlock = handleBlock(id, data);
if (mappedBlock == null) return rawId;
return IdAndData.toRawData(mappedBlock.getId(), mappedBlock.getData());
}
public void handleChunk(Chunk chunk) {
// Map Block Entities
Map<Pos, CompoundTag> tags = new HashMap<>();
for (CompoundTag tag : chunk.getBlockEntities()) {
Tag xTag;
Tag yTag;
Tag zTag;
if ((xTag = tag.get("x")) == null || (yTag = tag.get("y")) == null || (zTag = tag.get("z")) == null) {
NumberTag xTag;
NumberTag yTag;
NumberTag zTag;
if ((xTag = tag.getNumberTag("x")) == null
|| (yTag = tag.getNumberTag("y")) == null
|| (zTag = tag.getNumberTag("z")) == null) {
continue;
}
Pos pos = new Pos(
((NumberTag) xTag).asInt() & 0xF,
((NumberTag) yTag).asInt(),
((NumberTag) zTag).asInt() & 0xF);
Pos pos = new Pos(xTag.asInt() & 0xF, yTag.asInt(), zTag.asInt() & 0xF);
tags.put(pos, tag);
// Handle given Block Entities
@@ -184,9 +285,8 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
if (section == null) continue;
int block = section.palette(PaletteType.BLOCKS).idAt(pos.getX(), pos.getY() & 0xF, pos.getZ());
int btype = block >> 4;
MappedLegacyBlockItem settings = replacementData.get(btype);
MappedLegacyBlockItem settings = getMappedBlock(block);
if (settings != null && settings.hasBlockEntityHandler()) {
settings.getBlockEntityHandler().handleOrNewCompoundTag(block, tag);
}
@@ -207,15 +307,15 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
int btype = block >> 4;
int meta = block & 0xF;
Block b = handleBlock(btype, meta);
IdAndData b = handleBlock(btype, meta);
if (b != null) {
palette.setIdByIndex(j, (b.getId() << 4) | (b.getData() & 0xF));
palette.setIdByIndex(j, IdAndData.toRawData(b.getId(), b.getData()));
}
// We already know that is has a handler
if (hasBlockEntityHandler) continue;
MappedLegacyBlockItem settings = replacementData.get(btype);
MappedLegacyBlockItem settings = getMappedBlock(block);
if (settings != null && settings.hasBlockEntityHandler()) {
hasBlockEntityHandler = true;
}
@@ -228,10 +328,8 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
int block = palette.idAt(x, y, z);
int btype = block >> 4;
int meta = block & 15;
MappedLegacyBlockItem settings = replacementData.get(btype);
MappedLegacyBlockItem settings = getMappedBlock(block);
if (settings == null || !settings.hasBlockEntityHandler()) continue;
Pos pos = new Pos(x, (y + (i << 4)), z);
@@ -240,9 +338,9 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
if (tags.containsKey(pos)) continue;
CompoundTag tag = new CompoundTag();
tag.put("x", new IntTag(x + (chunk.getX() << 4)));
tag.put("y", new IntTag(y + (i << 4)));
tag.put("z", new IntTag(z + (chunk.getZ() << 4)));
tag.putInt("x", x + (chunk.getX() << 4));
tag.putInt("y", y + (i << 4));
tag.putInt("z", z + (chunk.getZ() << 4));
settings.getBlockEntityHandler().handleOrNewCompoundTag(block, tag);
chunk.getBlockEntities().add(tag);
@@ -254,12 +352,33 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
protected CompoundTag getNamedTag(String text) {
CompoundTag tag = new CompoundTag();
tag.put("display", new CompoundTag());
CompoundTag displayTag = new CompoundTag();
tag.put("display", displayTag);
text = "§r" + text;
((CompoundTag) tag.get("display")).put("Name", new StringTag(jsonNameFormat ? ChatRewriter.legacyTextToJsonString(text) : text));
displayTag.putString("Name", jsonNameFormat ? ComponentUtil.legacyToJsonString(text) : text);
return tag;
}
private @Nullable MappedLegacyBlockItem getMappedBlock(int id, int data) {
MappedLegacyBlockItem mapping = blockReplacements.get(IdAndData.toRawData(id, data));
return mapping != null ? mapping : blockReplacements.get(IdAndData.toRawData(id, -1));
}
private @Nullable MappedLegacyBlockItem getMappedItem(int id, int data) {
MappedLegacyBlockItem mapping = itemReplacements.get(IdAndData.toRawData(id, data));
return mapping != null ? mapping : itemReplacements.get(IdAndData.toRawData(id, -1));
}
private @Nullable MappedLegacyBlockItem getMappedBlock(int rawId) {
int id = IdAndData.getId(rawId);
int data = IdAndData.getData(rawId);
return getMappedBlock(id, data);
}
protected JsonObject readMappingsFile(final String name) {
return BackwardsMappingDataLoader.INSTANCE.loadFromDataDir(name);
}
private static final class Pos {
private final int x;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -17,12 +17,12 @@
*/
package com.viaversion.viabackwards.api.rewriters;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ByteTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ShortTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import java.util.ArrayList;
@@ -36,30 +36,62 @@ public class LegacyEnchantmentRewriter {
private final Map<Short, String> enchantmentMappings = new HashMap<>();
private final String nbtTagName;
private final boolean dummyEnchantment;
private Set<Short> hideLevelForEnchants;
public LegacyEnchantmentRewriter(String nbtTagName) {
this(nbtTagName, true);
}
public LegacyEnchantmentRewriter(String nbtTagName, boolean dummyEnchantment) {
this.nbtTagName = nbtTagName;
this.dummyEnchantment = dummyEnchantment;
}
public void registerEnchantment(int id, String replacementLore) {
enchantmentMappings.put((short) id, replacementLore);
}
public void handleToClient(Item item) {
CompoundTag tag = item.tag();
if (tag == null) return;
if (tag.getListTag("ench") != null) {
rewriteEnchantmentsToClient(tag, false);
}
if (tag.getListTag("StoredEnchantments") != null) {
rewriteEnchantmentsToClient(tag, true);
}
}
public void handleToServer(Item item) {
CompoundTag tag = item.tag();
if (tag == null) return;
if (tag.contains(nbtTagName + "|ench")) {
rewriteEnchantmentsToServer(tag, false);
}
if (tag.contains(nbtTagName + "|StoredEnchantments")) {
rewriteEnchantmentsToServer(tag, true);
}
}
public void rewriteEnchantmentsToClient(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "ench";
ListTag enchantments = tag.get(key);
ListTag remappedEnchantments = new ListTag(CompoundTag.class);
List<Tag> lore = new ArrayList<>();
for (Tag enchantmentEntry : enchantments.clone()) {
Tag idTag = ((CompoundTag) enchantmentEntry).get("id");
ListTag<CompoundTag> enchantments = tag.getListTag(key, CompoundTag.class);
ListTag<CompoundTag> remappedEnchantments = new ListTag<>(CompoundTag.class);
List<StringTag> lore = new ArrayList<>();
for (CompoundTag enchantmentEntry : enchantments.copy()) {
NumberTag idTag = enchantmentEntry.getNumberTag("id");
if (idTag == null) continue;
short newId = ((NumberTag) idTag).asShort();
short newId = idTag.asShort();
String enchantmentName = enchantmentMappings.get(newId);
if (enchantmentName != null) {
enchantments.remove(enchantmentEntry);
short level = ((NumberTag) ((CompoundTag) enchantmentEntry).get("lvl")).asShort();
NumberTag levelTag = enchantmentEntry.getNumberTag("lvl");
short level = levelTag != null ? levelTag.asShort() : 1;
if (hideLevelForEnchants != null && hideLevelForEnchants.contains(newId)) {
lore.add(new StringTag(enchantmentName));
} else {
@@ -69,35 +101,34 @@ public class LegacyEnchantmentRewriter {
}
}
if (!lore.isEmpty()) {
if (!storedEnchant && enchantments.size() == 0) {
if (this.dummyEnchantment && !storedEnchant && enchantments.isEmpty()) {
CompoundTag dummyEnchantment = new CompoundTag();
dummyEnchantment.put("id", new ShortTag((short) 0));
dummyEnchantment.put("lvl", new ShortTag((short) 0));
enchantments.add(dummyEnchantment);
dummyEnchantment.putShort("id", (short) 0);
dummyEnchantment.putShort("lvl", (short) 0);
enchantments.add(dummyEnchantment);
tag.put(nbtTagName + "|dummyEnchant", new ByteTag());
IntTag hideFlags = tag.get("HideFlags");
NumberTag hideFlags = tag.getNumberTag("HideFlags");
if (hideFlags == null) {
hideFlags = new IntTag();
} else {
tag.put(nbtTagName + "|oldHideFlags", new IntTag(hideFlags.asByte()));
tag.putInt(nbtTagName + "|oldHideFlags", hideFlags.asByte());
}
int flags = hideFlags.asByte() | 1;
hideFlags.setValue(flags);
tag.put("HideFlags", hideFlags);
tag.putInt("HideFlags", flags);
}
tag.put(nbtTagName + "|" + key, remappedEnchantments);
CompoundTag display = tag.get("display");
CompoundTag display = tag.getCompoundTag("display");
if (display == null) {
tag.put("display", display = new CompoundTag());
}
ListTag loreTag = display.get("Lore");
ListTag<StringTag> loreTag = display.getListTag("Lore", StringTag.class);
if (loreTag == null) {
display.put("Lore", loreTag = new ListTag(StringTag.class));
display.put("Lore", loreTag = new ListTag<>(StringTag.class));
}
lore.addAll(loreTag.getValue());
@@ -107,39 +138,41 @@ public class LegacyEnchantmentRewriter {
public void rewriteEnchantmentsToServer(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "ench";
ListTag remappedEnchantments = tag.remove(nbtTagName + "|" + key);
ListTag enchantments = tag.get(key);
ListTag<CompoundTag> enchantments = tag.getListTag(key, CompoundTag.class);
if (enchantments == null) {
enchantments = new ListTag(CompoundTag.class);
enchantments = new ListTag<>(CompoundTag.class);
}
if (!storedEnchant && tag.remove(nbtTagName + "|dummyEnchant") != null) {
for (Tag enchantment : enchantments.clone()) {
short id = ((NumberTag) ((CompoundTag) enchantment).get("id")).asShort();
short level = ((NumberTag) ((CompoundTag) enchantment).get("lvl")).asShort();
for (CompoundTag enchantment : enchantments.copy()) {
NumberTag idTag = enchantment.getNumberTag("id");
NumberTag levelTag = enchantment.getNumberTag("lvl");
short id = idTag != null ? idTag.asShort() : 0;
short level = levelTag != null ? levelTag.asShort() : 0;
if (id == 0 && level == 0) {
enchantments.remove(enchantment);
}
}
IntTag hideFlags = tag.remove(nbtTagName + "|oldHideFlags");
if (hideFlags != null) {
tag.put("HideFlags", new IntTag(hideFlags.asByte()));
Tag hideFlags = tag.remove(nbtTagName + "|oldHideFlags");
if (hideFlags instanceof IntTag) {
tag.putInt("HideFlags", ((IntTag) hideFlags).asByte());
} else {
tag.remove("HideFlags");
}
}
CompoundTag display = tag.get("display");
CompoundTag display = tag.getCompoundTag("display");
// A few null checks just to be safe, though they shouldn't actually be
ListTag lore = display != null ? display.get("Lore") : null;
for (Tag enchantment : remappedEnchantments.clone()) {
ListTag<StringTag> lore = display != null ? display.getListTag("Lore", StringTag.class) : null;
ListTag<CompoundTag> remappedEnchantments = tag.remove(nbtTagName + "|" + key);
for (CompoundTag enchantment : remappedEnchantments.copy()) {
enchantments.add(enchantment);
if (lore != null && lore.size() != 0) {
if (lore != null && !lore.isEmpty()) {
lore.remove(lore.get(0));
}
}
if (lore != null && lore.size() == 0) {
if (lore != null && lore.isEmpty()) {
display.remove("Lore");
if (display.isEmpty()) {
tag.remove("display");
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -22,6 +22,7 @@ import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.entities.storage.EntityData;
import com.viaversion.viabackwards.api.entities.storage.EntityObjectData;
import com.viaversion.viabackwards.api.entities.storage.WrappedMetadata;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.ObjectType;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
@@ -32,7 +33,6 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -113,7 +113,7 @@ public abstract class LegacyEntityRewriter<C extends ClientboundPacketType, T ex
registerMetadataRewriter(packetType, null, metaType);
}
protected PacketHandler getMobSpawnRewriter(Type<List<Metadata>> metaType) {
protected PacketHandler getMobSpawnRewriter(Type<List<Metadata>> metaType, IdSetter idSetter) {
return wrapper -> {
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityType type = tracker(wrapper.user()).entityType(entityId);
@@ -123,7 +123,7 @@ public abstract class LegacyEntityRewriter<C extends ClientboundPacketType, T ex
EntityData entityData = entityDataForType(type);
if (entityData != null) {
wrapper.set(Type.VAR_INT, 1, entityData.replacementId());
idSetter.setId(wrapper, entityData.replacementId());
if (entityData.hasBaseMeta()) {
entityData.defaultMeta().createMeta(new WrappedMetadata(metadata));
}
@@ -131,8 +131,16 @@ public abstract class LegacyEntityRewriter<C extends ClientboundPacketType, T ex
};
}
public PacketHandler getMobSpawnRewriter(Type<List<Metadata>> metaType) {
return getMobSpawnRewriter(metaType, (wrapper, id) -> wrapper.set(Type.UNSIGNED_BYTE, 0, (short) id));
}
public PacketHandler getMobSpawnRewriter1_11(Type<List<Metadata>> metaType) {
return getMobSpawnRewriter(metaType, (wrapper, id) -> wrapper.set(Type.VAR_INT, 1, id));
}
protected PacketHandler getObjectTrackerHandler() {
return wrapper -> addTrackedEntity(wrapper, wrapper.get(Type.VAR_INT, 0), getObjectTypeFromId(wrapper.get(Type.BYTE, 0)));
return wrapper -> addTrackedEntity(wrapper, wrapper.get(Type.VAR_INT, 0), objectTypeFromId(wrapper.get(Type.BYTE, 0)));
}
protected PacketHandler getTrackerAndMetaHandler(Type<List<Metadata>> metaType, EntityType entityType) {
@@ -161,12 +169,14 @@ public abstract class LegacyEntityRewriter<C extends ClientboundPacketType, T ex
};
}
protected EntityType getObjectTypeFromId(int typeId) {
return typeFromId(typeId);
}
@Deprecated
protected void addTrackedEntity(PacketWrapper wrapper, int entityId, EntityType type) throws Exception {
tracker(wrapper.user()).addEntity(entityId, type);
}
@FunctionalInterface
protected interface IdSetter {
void setId(PacketWrapper wrapper, int id) throws Exception;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -37,9 +37,7 @@ public final class MapColorRewriter {
wrapper.passthrough(Type.BYTE); // X
wrapper.passthrough(Type.BYTE); // Z
wrapper.passthrough(Type.BYTE); // Direction
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.COMPONENT); // Display Name
}
wrapper.passthrough(Type.OPTIONAL_COMPONENT); // Display Name
}
short columns = wrapper.passthrough(Type.UNSIGNED_BYTE);
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -18,7 +18,10 @@
package com.viaversion.viabackwards.api.rewriters;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
@@ -27,12 +30,12 @@ public class SoundRewriter<C extends ClientboundPacketType> extends com.viaversi
private final BackwardsProtocol<C, ?, ?, ?> protocol;
public SoundRewriter(BackwardsProtocol<C, ?, ?, ?> protocol) {
public SoundRewriter(final BackwardsProtocol<C, ?, ?, ?> protocol) {
super(protocol);
this.protocol = protocol;
}
public void registerNamedSound(C packetType) {
public void registerNamedSound(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
@@ -42,7 +45,7 @@ public class SoundRewriter<C extends ClientboundPacketType> extends com.viaversi
});
}
public void registerStopSound(C packetType) {
public void registerStopSound(final C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
@@ -53,8 +56,8 @@ public class SoundRewriter<C extends ClientboundPacketType> extends com.viaversi
public PacketHandler getNamedSoundHandler() {
return wrapper -> {
String soundId = wrapper.get(Type.STRING, 0);
String mappedId = protocol.getMappingData().getMappedNamedSound(soundId);
final String soundId = wrapper.get(Type.STRING, 0);
final String mappedId = protocol.getMappingData().getMappedNamedSound(soundId);
if (mappedId == null) {
return;
}
@@ -69,15 +72,15 @@ public class SoundRewriter<C extends ClientboundPacketType> extends com.viaversi
public PacketHandler getStopSoundHandler() {
return wrapper -> {
byte flags = wrapper.passthrough(Type.BYTE);
final byte flags = wrapper.passthrough(Type.BYTE);
if ((flags & 0x02) == 0) return; // No sound specified
if ((flags & 0x01) != 0) {
wrapper.passthrough(Type.VAR_INT); // Source
}
String soundId = wrapper.read(Type.STRING);
String mappedId = protocol.getMappingData().getMappedNamedSound(soundId);
final String soundId = wrapper.read(Type.STRING);
final String mappedId = protocol.getMappingData().getMappedNamedSound(soundId);
if (mappedId == null) {
// No mapping found
wrapper.write(Type.STRING, soundId);
@@ -94,38 +97,41 @@ public class SoundRewriter<C extends ClientboundPacketType> extends com.viaversi
}
@Override
public void register1_19_3Sound(C packetType) {
public void register1_19_3Sound(final C packetType) {
protocol.registerClientbound(packetType, get1_19_3SoundHandler());
}
public PacketHandler get1_19_3SoundHandler() {
return wrapper -> {
final int soundId = wrapper.read(Type.VAR_INT);
if (soundId != 0) {
final int mappedId = idRewriter.rewrite(soundId - 1); // Normalize the id
if (mappedId == -1) {
wrapper.cancel();
return;
}
wrapper.write(Type.VAR_INT, mappedId + 1);
Holder<SoundEvent> soundEventHolder = wrapper.read(Type.SOUND_EVENT);
if (soundEventHolder.isDirect()) {
wrapper.write(Type.SOUND_EVENT, rewriteSoundEvent(wrapper, soundEventHolder));
return;
}
// Is followed by the resource loation
wrapper.write(Type.VAR_INT, 0);
String soundIdentifier = wrapper.read(Type.STRING);
final String mappedIdentifier = protocol.getMappingData().getMappedNamedSound(soundIdentifier);
if (mappedIdentifier != null) {
if (mappedIdentifier.isEmpty()) {
wrapper.cancel();
return;
}
soundIdentifier = mappedIdentifier;
final int mappedId = idRewriter.rewrite(soundEventHolder.id());
if (mappedId == -1) {
wrapper.cancel();
return;
}
wrapper.write(Type.STRING, soundIdentifier);
if (mappedId != soundEventHolder.id()) {
soundEventHolder = Holder.of(mappedId);
}
wrapper.write(Type.SOUND_EVENT, soundEventHolder);
};
}
public Holder<SoundEvent> rewriteSoundEvent(final PacketWrapper wrapper, final Holder<SoundEvent> soundEventHolder) {
final SoundEvent soundEvent = soundEventHolder.value();
final String mappedIdentifier = protocol.getMappingData().getMappedNamedSound(soundEvent.identifier());
if (mappedIdentifier != null) {
if (!mappedIdentifier.isEmpty()) {
return Holder.of(soundEvent.withIdentifier(mappedIdentifier));
}
wrapper.cancel();
}
return soundEventHolder;
}
}
@@ -0,0 +1,189 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-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.viabackwards.api.rewriters;
import com.viaversion.viabackwards.api.data.BackwardsMappings;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.minecraft.data.StructuredData;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.libs.fastutil.ints.Int2IntMap;
import com.viaversion.viaversion.libs.fastutil.ints.IntIntPair;
import com.viaversion.viaversion.libs.fastutil.objects.ObjectIterator;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ByteTag;
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.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.util.ComponentUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class StructuredEnchantmentRewriter {
protected final BackwardsItemRewriter<?, ?, ?> itemRewriter;
private boolean rewriteIds = true;
public StructuredEnchantmentRewriter(final BackwardsItemRewriter<?, ?, ?> itemRewriter) {
this.itemRewriter = itemRewriter;
}
public void handleToClient(final Item item) {
final StructuredDataContainer data = item.structuredData();
rewriteEnchantmentsToClient(data, StructuredDataKey.ENCHANTMENTS, false);
rewriteEnchantmentsToClient(data, StructuredDataKey.STORED_ENCHANTMENTS, true);
}
public void handleToServer(final Item item) {
final StructuredDataContainer data = item.structuredData();
final StructuredData<CompoundTag> customData = data.getNonEmpty(StructuredDataKey.CUSTOM_DATA);
if (customData == null) {
return;
}
final CompoundTag tag = customData.value();
if (tag.contains(itemRewriter.nbtTagName("enchantments"))) {
rewriteEnchantmentsToServer(data, tag, StructuredDataKey.ENCHANTMENTS, false);
}
if (tag.contains(itemRewriter.nbtTagName("stored_enchantments"))) {
rewriteEnchantmentsToServer(data, tag, StructuredDataKey.STORED_ENCHANTMENTS, true);
}
}
public void rewriteEnchantmentsToClient(final StructuredDataContainer data, final StructuredDataKey<Enchantments> key, final boolean storedEnchant) {
final StructuredData<Enchantments> enchantmentsData = data.getNonEmpty(key);
if (enchantmentsData == null) {
return;
}
final CompoundTag tag = data.computeIfAbsent(StructuredDataKey.CUSTOM_DATA, $ -> new CompoundTag()).value();
final Enchantments enchantments = enchantmentsData.value();
final List<Tag> loreToAdd = new ArrayList<>();
boolean changed = false;
final ObjectIterator<Int2IntMap.Entry> iterator = enchantments.enchantments().int2IntEntrySet().iterator();
final List<IntIntPair> updatedIds = new ArrayList<>();
while (iterator.hasNext()) {
final Int2IntMap.Entry entry = iterator.next();
final BackwardsMappings mappingData = itemRewriter.protocol().getMappingData();
final Mappings mappings = mappingData.getEnchantmentMappings();
final int mappedId = mappings.getNewId(entry.getIntKey());
if (mappedId != -1) {
if (rewriteIds) {
// Update the map after to iteration to preserve the current ids before possibly saving the original, avoid CME
updatedIds.add(IntIntPair.of(entry.getIntKey(), mappedId));
}
continue;
}
final String remappedName = mappingData.mappedEnchantmentName(entry.getIntKey());
if (remappedName != null) {
if (!changed) {
// Backup original before doing modifications
itemRewriter.saveListTag(tag, asTag(enchantments), key.identifier());
changed = true;
}
final int level = entry.getIntValue();
loreToAdd.add(ComponentUtil.jsonStringToTag(ComponentUtil.legacyToJsonString("§7" + remappedName + " " + EnchantmentRewriter.getRomanNumber(level), true)));
iterator.remove();
}
}
for (final IntIntPair pair : updatedIds) {
enchantments.add(pair.firstInt(), pair.secondInt());
}
if (loreToAdd.isEmpty()) {
// No removed enchantments
return;
}
// Add glint override if there are no enchantments left
if (!storedEnchant && enchantments.size() == 0) {
final StructuredData<Boolean> glintOverride = data.getNonEmpty(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE);
if (glintOverride != null) {
tag.putBoolean(itemRewriter.nbtTagName("glint"), glintOverride.value());
} else {
tag.putBoolean(itemRewriter.nbtTagName("noglint"), true);
}
data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, true);
}
// Save original lore
final StructuredData<Tag[]> loreData = data.getNonEmpty(StructuredDataKey.LORE);
if (loreData != null) {
final List<Tag> loreList = Arrays.asList(loreData.value());
itemRewriter.saveGenericTagList(tag, loreList, "lore");
loreToAdd.addAll(loreList);
} else {
tag.putBoolean(itemRewriter.nbtTagName("nolore"), true);
}
if (enchantments.showInTooltip()) {
tag.putBoolean(itemRewriter.nbtTagName("show_" + key.identifier()), true);
}
data.set(StructuredDataKey.LORE, loreToAdd.toArray(new Tag[0]));
}
private ListTag<CompoundTag> asTag(final Enchantments enchantments) {
final ListTag<CompoundTag> listTag = new ListTag<>(CompoundTag.class);
for (final Int2IntMap.Entry entry : enchantments.enchantments().int2IntEntrySet()) {
final CompoundTag enchantment = new CompoundTag();
enchantment.putInt("id", entry.getIntKey());
enchantment.putInt("lvl", entry.getIntValue());
listTag.add(enchantment);
}
return listTag;
}
public void rewriteEnchantmentsToServer(final StructuredDataContainer data, final CompoundTag tag, final StructuredDataKey<Enchantments> key, final boolean storedEnchant) {
final ListTag<CompoundTag> enchantmentsTag = itemRewriter.removeListTag(tag, key.identifier(), CompoundTag.class);
if (enchantmentsTag == null) {
return;
}
final Tag glintTag = tag.remove(itemRewriter.nbtTagName("glint"));
if (glintTag instanceof ByteTag) {
data.set(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE, ((NumberTag) glintTag).asBoolean());
} else if (tag.remove(itemRewriter.nbtTagName("noglint")) != null) {
data.remove(StructuredDataKey.ENCHANTMENT_GLINT_OVERRIDE);
}
final List<Tag> lore = itemRewriter.removeGenericTagList(tag, "lore");
if (lore != null) {
data.set(StructuredDataKey.LORE, lore.toArray(new Tag[0]));
} else if (tag.remove(itemRewriter.nbtTagName("nolore")) != null) {
data.remove(StructuredDataKey.LORE);
}
final Enchantments enchantments = new Enchantments(tag.remove(itemRewriter.nbtTagName("show_" + key.identifier())) != null);
for (final CompoundTag enchantment : enchantmentsTag) {
enchantments.add(enchantment.getInt("id"), enchantment.getInt("lvl"));
}
data.set(key, enchantments);
}
public void setRewriteIds(final boolean rewriteIds) {
this.rewriteIds = rewriteIds;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,13 +19,13 @@ package com.viaversion.viabackwards.api.rewriters;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.VBMappingDataLoader;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
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.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import java.util.HashMap;
import java.util.Map;
@@ -34,91 +34,51 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class TranslatableRewriter<C extends ClientboundPacketType> extends ComponentRewriter<C> {
private static final Map<String, Map<String, String>> TRANSLATABLES = new HashMap<>();
private final Map<String, String> newTranslatables;
private final Map<String, String> translatables;
public static void loadTranslatables() {
JsonObject jsonObject = VBMappingDataLoader.loadFromDataDir("translation-mappings.json");
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
Map<String, String> versionMappings = new HashMap<>();
final JsonObject jsonObject = BackwardsMappingDataLoader.INSTANCE.loadFromDataDir("translation-mappings.json");
for (final Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
final Map<String, String> versionMappings = new HashMap<>();
TRANSLATABLES.put(entry.getKey(), versionMappings);
for (Map.Entry<String, JsonElement> translationEntry : entry.getValue().getAsJsonObject().entrySet()) {
for (final Map.Entry<String, JsonElement> translationEntry : entry.getValue().getAsJsonObject().entrySet()) {
versionMappings.put(translationEntry.getKey(), translationEntry.getValue().getAsString());
}
}
}
public TranslatableRewriter(BackwardsProtocol<C, ?, ?, ?> protocol) {
this(protocol, protocol.getClass().getSimpleName().split("To")[1].replace("_", "."));
public TranslatableRewriter(final BackwardsProtocol<C, ?, ?, ?> protocol, final ReadType type) {
this(protocol, type, protocol.getClass().getSimpleName().split("To")[1].replace("_", "."));
}
public TranslatableRewriter(BackwardsProtocol<C, ?, ?, ?> protocol, String sectionIdentifier) {
super(protocol);
final Map<String, String> newTranslatables = TRANSLATABLES.get(sectionIdentifier);
if (newTranslatables == null) {
ViaBackwards.getPlatform().getLogger().warning("Error loading " + sectionIdentifier + " translatables!");
this.newTranslatables = new HashMap<>();
public TranslatableRewriter(final BackwardsProtocol<C, ?, ?, ?> protocol, final ReadType type, final String sectionIdentifier) {
super(protocol, type);
final Map<String, String> translatableMappings = TRANSLATABLES.get(sectionIdentifier);
if (translatableMappings == null) {
ViaBackwards.getPlatform().getLogger().warning("Missing " + sectionIdentifier + " translatables!");
this.translatables = new HashMap<>();
} else {
this.newTranslatables = newTranslatables;
this.translatables = translatableMappings;
}
}
public void registerPing() {
protocol.registerClientbound(State.LOGIN, 0x00, 0x00, wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
}
public void registerDisconnect(C packetType) {
protocol.registerClientbound(packetType, wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
}
public void registerLegacyOpenWindow(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // Id
map(Type.STRING); // Window Type
handler(wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
public void registerOpenWindow(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // Id
map(Type.VAR_INT); // Window Type
handler(wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
public void registerTabList(C packetType) {
protocol.registerClientbound(packetType, wrapper -> {
processText(wrapper.passthrough(Type.COMPONENT));
processText(wrapper.passthrough(Type.COMPONENT));
});
}
public void registerCombatKill(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT);
map(Type.INT);
handler(wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
}
});
}
@Override
protected void handleTranslate(JsonObject root, String translate) {
String newTranslate = mappedTranslationKey(translate);
protected void handleTranslate(final JsonObject root, final String translate) {
final String newTranslate = mappedTranslationKey(translate);
if (newTranslate != null) {
root.addProperty("translate", newTranslate);
}
}
@Override
protected void handleTranslate(final UserConnection connection, final CompoundTag parentTag, final StringTag translateTag) {
final String newTranslate = mappedTranslationKey(translateTag.getValue());
if (newTranslate != null) {
parentTag.put("translate", new StringTag(newTranslate));
}
}
public @Nullable String mappedTranslationKey(final String translationKey) {
return newTranslatables.get(translationKey);
return translatables.get(translationKey);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -26,17 +26,17 @@ import com.viaversion.viabackwards.protocol.protocol1_10to1_11.packets.EntityPac
import com.viaversion.viabackwards.protocol.protocol1_10to1_11.packets.PlayerPackets1_11;
import com.viaversion.viabackwards.protocol.protocol1_10to1_11.storage.WindowTracker;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_11Types;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_10To1_11 extends BackwardsProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
public static final BackwardsMappings MAPPINGS = new BackwardsMappings("1.11", "1.10");
private final EntityPackets1_11 entityPackets = new EntityPackets1_11(this); // Required for the item rewriter
private BlockItemPackets1_11 blockItemPackets;
private final EntityPackets1_11 entityPackets = new EntityPackets1_11(this);
private final BlockItemPackets1_11 blockItemPackets = new BlockItemPackets1_11(this);
public Protocol1_10To1_11() {
super(ClientboundPackets1_9_3.class, ClientboundPackets1_9_3.class, ServerboundPackets1_9_3.class, ServerboundPackets1_9_3.class);
@@ -44,9 +44,9 @@ public class Protocol1_10To1_11 extends BackwardsProtocol<ClientboundPackets1_9_
@Override
protected void registerPackets() {
(blockItemPackets = new BlockItemPackets1_11(this)).register();
blockItemPackets.register();
entityPackets.register();
new PlayerPackets1_11().register(this);
PlayerPackets1_11.register(this);
SoundRewriter<ClientboundPackets1_9_3> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerNamedSound(ClientboundPackets1_9_3.NAMED_SOUND);
@@ -55,12 +55,11 @@ public class Protocol1_10To1_11 extends BackwardsProtocol<ClientboundPackets1_9_
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
user.put(new ClientWorld());
}
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, Entity1_11Types.EntityType.PLAYER));
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, EntityTypes1_11.EntityType.PLAYER));
if (!user.has(WindowTracker.class)) {
user.put(new WindowTracker());
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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,7 +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.viabackwards.protocol.protocol1_10to1_11;
package com.viaversion.viabackwards.protocol.protocol1_10to1_11.data;
import com.viaversion.viaversion.libs.fastutil.ints.Int2IntMap;
import com.viaversion.viaversion.libs.fastutil.ints.Int2IntOpenHashMap;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -27,24 +27,20 @@ import com.viaversion.viabackwards.protocol.protocol1_10to1_11.storage.WindowTra
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.data.entity.StoredEntityData;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_11Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11;
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.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3;
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.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_11to1_10.EntityIdRewriter;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_11to1_10.rewriter.EntityIdRewriter;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.util.IdAndData;
import java.util.Arrays;
import java.util.Optional;
@@ -53,33 +49,33 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
private LegacyEnchantmentRewriter enchantmentRewriter;
public BlockItemPackets1_11(Protocol1_10To1_11 protocol) {
super(protocol);
super(protocol, "1.11");
}
@Override
protected void registerPackets() {
registerBlockChange(ClientboundPackets1_9_3.BLOCK_CHANGE);
registerMultiBlockChange(ClientboundPackets1_9_3.MULTI_BLOCK_CHANGE);
protocol.registerClientbound(ClientboundPackets1_9_3.SET_SLOT, new PacketHandlers() {
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM); // 2 - Slot Value
map(Type.ITEM1_8); // 2 - Slot Value
handler(itemToClientHandler(Type.ITEM));
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
// Handle Llama
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
if (isLlama(wrapper.user())) {
Optional<ChestedHorseStorage> horse = getChestedHorse(wrapper.user());
if (!horse.isPresent())
return;
ChestedHorseStorage storage = horse.get();
int currentSlot = wrapper.get(Type.SHORT, 0);
wrapper.set(Type.SHORT, 0, ((Integer) (currentSlot = getNewSlotId(storage, currentSlot))).shortValue());
wrapper.set(Type.ITEM, 0, getNewItem(storage, currentSlot, wrapper.get(Type.ITEM, 0)));
}
handler(wrapper -> {
if (isLlama(wrapper.user())) {
Optional<ChestedHorseStorage> horse = getChestedHorse(wrapper.user());
if (!horse.isPresent())
return;
ChestedHorseStorage storage = horse.get();
int currentSlot = wrapper.get(Type.SHORT, 0);
wrapper.set(Type.SHORT, 0, ((Integer) (currentSlot = getNewSlotId(storage, currentSlot))).shortValue());
wrapper.set(Type.ITEM1_8, 0, getNewItem(storage, currentSlot, wrapper.get(Type.ITEM1_8, 0)));
}
});
}
@@ -89,12 +85,12 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
@Override
public void register() {
map(Type.UNSIGNED_BYTE); // 0 - Window ID
map(Type.ITEM_ARRAY); // 1 - Window Values
map(Type.ITEM1_8_SHORT_ARRAY); // 1 - Window Values
handler(wrapper -> {
Item[] stacks = wrapper.get(Type.ITEM_ARRAY, 0);
Item[] stacks = wrapper.get(Type.ITEM1_8_SHORT_ARRAY, 0);
for (int i = 0; i < stacks.length; i++)
stacks[i] = handleItemToClient(stacks[i]);
stacks[i] = handleItemToClient(wrapper.user(), stacks[i]);
if (isLlama(wrapper.user())) {
Optional<ChestedHorseStorage> horse = getChestedHorse(wrapper.user());
@@ -107,32 +103,32 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
stacks[getNewSlotId(storage, i)] = stacks[i];
stacks[i] = getNewItem(storage, i, stacks[i]);
}
wrapper.set(Type.ITEM_ARRAY, 0, stacks);
wrapper.set(Type.ITEM1_8_SHORT_ARRAY, 0, stacks);
}
});
}
});
registerEntityEquipment(ClientboundPackets1_9_3.ENTITY_EQUIPMENT, Type.ITEM);
registerEntityEquipment(ClientboundPackets1_9_3.ENTITY_EQUIPMENT);
// Plugin message Packet -> Trading
// Plugin message -> Trading
protocol.registerClientbound(ClientboundPackets1_9_3.PLUGIN_MESSAGE, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // 0 - Channel
handler(wrapper -> {
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
if (wrapper.get(Type.STRING, 0).equals("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Input Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Second Item
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
@@ -152,9 +148,9 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM); // 5 - Clicked Item
map(Type.ITEM1_8); // 5 - Clicked Item
handler(itemToServerHandler(Type.ITEM));
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
// Llama slot
handler(wrapper -> {
@@ -172,62 +168,34 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
}
});
registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION, Type.ITEM);
registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION);
protocol.registerClientbound(ClientboundPackets1_9_3.CHUNK_DATA, wrapper -> {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); // Use the 1.10 Chunk type since nothing changed.
ChunkType1_9_3 type = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); // Use the 1.10 Chunk type since nothing changed.
Chunk chunk = wrapper.passthrough(type);
handleChunk(chunk);
// only patch it for signs for now
for (CompoundTag tag : chunk.getBlockEntities()) {
Tag idTag = tag.get("id");
if (!(idTag instanceof StringTag)) continue;
StringTag idTag = tag.getStringTag("id");
if (idTag == null) continue;
String id = (String) idTag.getValue();
String id = idTag.getValue();
if (id.equals("minecraft:sign")) {
((StringTag) idTag).setValue("Sign");
idTag.setValue("Sign");
}
}
});
protocol.registerClientbound(ClientboundPackets1_9_3.BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // 0 - Block Position
map(Type.VAR_INT); // 1 - Block
handler(wrapper -> {
int idx = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, handleBlockID(idx));
});
}
});
protocol.registerClientbound(ClientboundPackets1_9_3.MULTI_BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
record.setBlockId(handleBlockID(record.getBlockId()));
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_9_3.BLOCK_ENTITY_DATA, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // 0 - Position
map(Type.POSITION1_8); // 0 - Position
map(Type.UNSIGNED_BYTE); // 1 - Action
map(Type.NBT); // 2 - NBT
map(Type.NAMED_COMPOUND_TAG); // 2 - NBT
handler(wrapper -> {
// Remove on shulkerbox decleration
@@ -236,7 +204,7 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
}
// Handler Spawners
if (wrapper.get(Type.UNSIGNED_BYTE, 0) == 1) {
CompoundTag tag = wrapper.get(Type.NBT, 0);
CompoundTag tag = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
EntityIdRewriter.toClientSpawner(tag, true);
}
});
@@ -298,21 +266,21 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
});
protocol.getEntityRewriter().filter().handler((event, meta) -> {
if (meta.metaType().type().equals(Type.ITEM)) // Is Item
meta.setValue(handleItemToClient((Item) meta.getValue()));
if (meta.metaType().type().equals(Type.ITEM1_8)) // Is Item
meta.setValue(handleItemToClient(event.user(), (Item) meta.getValue()));
});
}
@Override
protected void registerRewrites() {
// Handle spawner block entity (map to itself with custom handler)
MappedLegacyBlockItem data = replacementData.computeIfAbsent(52, s -> new MappedLegacyBlockItem(52, (short) -1, null, false));
MappedLegacyBlockItem data = itemReplacements.computeIfAbsent(IdAndData.toRawData(52), s -> new MappedLegacyBlockItem(52));
data.setBlockEntityHandler((b, tag) -> {
EntityIdRewriter.toClientSpawner(tag, true);
return tag;
});
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName);
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName());
enchantmentRewriter.registerEnchantment(71, "§cCurse of Vanishing");
enchantmentRewriter.registerEnchantment(10, "§cCurse of Binding");
@@ -320,9 +288,9 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
}
@Override
public Item handleItemToClient(Item item) {
public Item handleItemToClient(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToClient(item);
super.handleItemToClient(connection, item);
CompoundTag tag = item.tag();
if (tag == null) return item;
@@ -330,19 +298,14 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
// Rewrite spawn eggs (id checks are done in the method itself)
EntityIdRewriter.toClientItem(item, true);
if (tag.get("ench") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, false);
}
if (tag.get("StoredEnchantments") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, true);
}
enchantmentRewriter.handleToClient(item);
return item;
}
@Override
public Item handleItemToServer(Item item) {
public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
CompoundTag tag = item.tag();
if (tag == null) return item;
@@ -350,12 +313,7 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
// Rewrite spawn eggs (id checks are done in the method itself)
EntityIdRewriter.toServerItem(item, true);
if (tag.contains(nbtTagName + "|ench")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, false);
}
if (tag.contains(nbtTagName + "|StoredEnchantments")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, true);
}
enchantmentRewriter.handleToServer(item);
return item;
}
@@ -364,7 +322,7 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
if (tracker.getInventory() != null && tracker.getInventory().equals("EntityHorse")) {
EntityTracker entTracker = user.getEntityTracker(Protocol1_10To1_11.class);
StoredEntityData entityData = entTracker.entityData(tracker.getEntityId());
return entityData != null && entityData.type().is(Entity1_11Types.EntityType.LIAMA);
return entityData != null && entityData.type().is(EntityTypes1_11.EntityType.LIAMA);
}
return false;
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -21,14 +21,12 @@ package com.viaversion.viabackwards.protocol.protocol1_10to1_11.packets;
import com.viaversion.viabackwards.api.entities.storage.EntityData;
import com.viaversion.viabackwards.api.entities.storage.WrappedMetadata;
import com.viaversion.viabackwards.api.rewriters.LegacyEntityRewriter;
import com.viaversion.viabackwards.protocol.protocol1_10to1_11.PotionSplashHandler;
import com.viaversion.viabackwards.protocol.protocol1_10to1_11.data.PotionSplashHandler;
import com.viaversion.viabackwards.protocol.protocol1_10to1_11.Protocol1_10To1_11;
import com.viaversion.viabackwards.protocol.protocol1_10to1_11.storage.ChestedHorseStorage;
import com.viaversion.viabackwards.utils.Block;
import com.viaversion.viaversion.api.data.entity.StoredEntityData;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_11Types;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_12Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_9;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@@ -36,7 +34,6 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_9;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import java.util.List;
import java.util.Optional;
public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_9_3, Protocol1_10To1_11> {
@@ -50,7 +47,7 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
public void register() {
map(Type.INT);
map(Type.POSITION);
map(Type.POSITION1_8);
map(Type.INT);
handler(wrapper -> {
int type = wrapper.get(Type.INT, 0);
@@ -84,28 +81,14 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
// Track Entity
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> Entity1_11Types.ObjectType.findById(id).orElse(null)));
handler(getObjectRewriter(id -> EntityTypes1_11.ObjectType.findById(id).orElse(null)));
// Handle FallingBlock blocks
handler(wrapper -> {
Optional<Entity1_12Types.ObjectType> type = Entity1_12Types.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get() == Entity1_12Types.ObjectType.FALLING_BLOCK) {
int objectData = wrapper.get(Type.INT, 0);
int objType = objectData & 4095;
int data = objectData >> 12 & 15;
Block block = protocol.getItemRewriter().handleBlock(objType, data);
if (block == null)
return;
wrapper.set(Type.INT, 0, block.getId() | block.getData() << 12);
}
});
handler(protocol.getItemRewriter().getFallingBlockHandler());
}
});
registerTracker(ClientboundPackets1_9_3.SPAWN_EXPERIENCE_ORB, Entity1_11Types.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, Entity1_11Types.EntityType.WEATHER);
registerTracker(ClientboundPackets1_9_3.SPAWN_EXPERIENCE_ORB, EntityTypes1_11.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, EntityTypes1_11.EntityType.WEATHER);
protocol.registerClientbound(ClientboundPackets1_9_3.SPAWN_MOB, new PacketHandlers() {
@Override
@@ -128,31 +111,20 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
handler(getTrackerHandler(Type.UNSIGNED_BYTE, 0));
// Rewrite entity type / metadata
handler(getMobSpawnRewriter(Types1_9.METADATA_LIST));
// Sub 1.11 clients will error if the list is empty
handler(wrapper -> {
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityType type = tracker(wrapper.user()).entityType(entityId);
List<Metadata> list = wrapper.get(Types1_9.METADATA_LIST, 0);
handleMetadata(wrapper.get(Type.VAR_INT, 0), list, wrapper.user());
EntityData entityData = entityDataForType(type);
if (entityData != null) {
wrapper.set(Type.UNSIGNED_BYTE, 0, (short) entityData.replacementId());
if (entityData.hasBaseMeta()) {
entityData.defaultMeta().createMeta(new WrappedMetadata(list));
}
}
// Sub 1.11 clients will error if the list is empty
if (list.isEmpty()) {
list.add(new Metadata(0, MetaType1_9.Byte, (byte) 0));
List<Metadata> metadata = wrapper.get(Types1_9.METADATA_LIST, 0);
if (metadata.isEmpty()) {
metadata.add(new Metadata(0, MetaType1_9.Byte, (byte) 0));
}
});
}
});
registerTracker(ClientboundPackets1_9_3.SPAWN_PAINTING, Entity1_11Types.EntityType.PAINTING);
registerJoinGame(ClientboundPackets1_9_3.JOIN_GAME, Entity1_11Types.EntityType.PLAYER);
registerTracker(ClientboundPackets1_9_3.SPAWN_PAINTING, EntityTypes1_11.EntityType.PAINTING);
registerJoinGame(ClientboundPackets1_9_3.JOIN_GAME, EntityTypes1_11.EntityType.PLAYER);
registerRespawn(ClientboundPackets1_9_3.RESPAWN);
protocol.registerClientbound(ClientboundPackets1_9_3.SPAWN_PLAYER, new PacketHandlers() {
@@ -167,7 +139,7 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
map(Type.BYTE); // 6 - Pitch
map(Types1_9.METADATA_LIST); // 7 - Metadata list
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, Entity1_11Types.EntityType.PLAYER));
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, EntityTypes1_11.EntityType.PLAYER));
handler(wrapper -> {
// Sub 1.11 clients will cry if the list is empty
List<Metadata> metadata = wrapper.get(Types1_9.METADATA_LIST, 0);
@@ -204,37 +176,37 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
protected void registerRewrites() {
// Guardian
mapEntityTypeWithData(Entity1_11Types.EntityType.ELDER_GUARDIAN, Entity1_11Types.EntityType.GUARDIAN);
mapEntityTypeWithData(EntityTypes1_11.EntityType.ELDER_GUARDIAN, EntityTypes1_11.EntityType.GUARDIAN);
// Skeletons
mapEntityTypeWithData(Entity1_11Types.EntityType.WITHER_SKELETON, Entity1_11Types.EntityType.SKELETON).spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(1)));
mapEntityTypeWithData(Entity1_11Types.EntityType.STRAY, Entity1_11Types.EntityType.SKELETON).plainName().spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(2)));
mapEntityTypeWithData(EntityTypes1_11.EntityType.WITHER_SKELETON, EntityTypes1_11.EntityType.SKELETON).spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(1)));
mapEntityTypeWithData(EntityTypes1_11.EntityType.STRAY, EntityTypes1_11.EntityType.SKELETON).plainName().spawnMetadata(storage -> storage.add(getSkeletonTypeMeta(2)));
// Zombies
mapEntityTypeWithData(Entity1_11Types.EntityType.HUSK, Entity1_11Types.EntityType.ZOMBIE).plainName().spawnMetadata(storage -> handleZombieType(storage, 6));
mapEntityTypeWithData(Entity1_11Types.EntityType.ZOMBIE_VILLAGER, Entity1_11Types.EntityType.ZOMBIE).spawnMetadata(storage -> handleZombieType(storage, 1));
mapEntityTypeWithData(EntityTypes1_11.EntityType.HUSK, EntityTypes1_11.EntityType.ZOMBIE).plainName().spawnMetadata(storage -> handleZombieType(storage, 6));
mapEntityTypeWithData(EntityTypes1_11.EntityType.ZOMBIE_VILLAGER, EntityTypes1_11.EntityType.ZOMBIE).spawnMetadata(storage -> handleZombieType(storage, 1));
// Horses
mapEntityTypeWithData(Entity1_11Types.EntityType.HORSE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(0))); // Nob able to ride the horse without having the MetaType sent.
mapEntityTypeWithData(Entity1_11Types.EntityType.DONKEY, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
mapEntityTypeWithData(Entity1_11Types.EntityType.MULE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(2)));
mapEntityTypeWithData(Entity1_11Types.EntityType.SKELETON_HORSE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(4)));
mapEntityTypeWithData(Entity1_11Types.EntityType.ZOMBIE_HORSE, Entity1_11Types.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(3)));
mapEntityTypeWithData(EntityTypes1_11.EntityType.HORSE, EntityTypes1_11.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(0))); // Nob able to ride the horse without having the MetaType sent.
mapEntityTypeWithData(EntityTypes1_11.EntityType.DONKEY, EntityTypes1_11.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
mapEntityTypeWithData(EntityTypes1_11.EntityType.MULE, EntityTypes1_11.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(2)));
mapEntityTypeWithData(EntityTypes1_11.EntityType.SKELETON_HORSE, EntityTypes1_11.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(4)));
mapEntityTypeWithData(EntityTypes1_11.EntityType.ZOMBIE_HORSE, EntityTypes1_11.EntityType.HORSE).spawnMetadata(storage -> storage.add(getHorseMetaType(3)));
// New mobs
mapEntityTypeWithData(Entity1_11Types.EntityType.EVOCATION_FANGS, Entity1_11Types.EntityType.SHULKER);
mapEntityTypeWithData(Entity1_11Types.EntityType.EVOCATION_ILLAGER, Entity1_11Types.EntityType.VILLAGER).plainName();
mapEntityTypeWithData(Entity1_11Types.EntityType.VEX, Entity1_11Types.EntityType.BAT).plainName();
mapEntityTypeWithData(Entity1_11Types.EntityType.VINDICATION_ILLAGER, Entity1_11Types.EntityType.VILLAGER).plainName().spawnMetadata(storage -> storage.add(new Metadata(13, MetaType1_9.VarInt, 4))); // Base Profession
mapEntityTypeWithData(Entity1_11Types.EntityType.LIAMA, Entity1_11Types.EntityType.HORSE).plainName().spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
mapEntityTypeWithData(Entity1_11Types.EntityType.LIAMA_SPIT, Entity1_11Types.EntityType.SNOWBALL);
mapEntityTypeWithData(EntityTypes1_11.EntityType.EVOCATION_FANGS, EntityTypes1_11.EntityType.SHULKER);
mapEntityTypeWithData(EntityTypes1_11.EntityType.EVOCATION_ILLAGER, EntityTypes1_11.EntityType.VILLAGER).plainName();
mapEntityTypeWithData(EntityTypes1_11.EntityType.VEX, EntityTypes1_11.EntityType.BAT).plainName();
mapEntityTypeWithData(EntityTypes1_11.EntityType.VINDICATION_ILLAGER, EntityTypes1_11.EntityType.VILLAGER).plainName().spawnMetadata(storage -> storage.add(new Metadata(13, MetaType1_9.VarInt, 4))); // Base Profession
mapEntityTypeWithData(EntityTypes1_11.EntityType.LIAMA, EntityTypes1_11.EntityType.HORSE).plainName().spawnMetadata(storage -> storage.add(getHorseMetaType(1)));
mapEntityTypeWithData(EntityTypes1_11.EntityType.LIAMA_SPIT, EntityTypes1_11.EntityType.SNOWBALL);
mapObjectType(Entity1_11Types.ObjectType.LIAMA_SPIT, Entity1_11Types.ObjectType.SNOWBALL, -1);
mapObjectType(EntityTypes1_11.ObjectType.LIAMA_SPIT, EntityTypes1_11.ObjectType.SNOWBALL, -1);
// Replace with endertorchthingies
mapObjectType(Entity1_11Types.ObjectType.EVOCATION_FANGS, Entity1_11Types.ObjectType.FALLING_BLOCK, 198 | 1 << 12);
mapObjectType(EntityTypes1_11.ObjectType.EVOCATION_FANGS, EntityTypes1_11.ObjectType.FALLING_BLOCK, 198 | 1 << 12);
// Handle ElderGuardian & target metadata
filter().filterFamily(Entity1_11Types.EntityType.GUARDIAN).index(12).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.GUARDIAN).index(12).handler((event, meta) -> {
boolean b = (boolean) meta.getValue();
int bitmask = b ? 0x02 : 0;
if (event.entityType() == Entity1_11Types.EntityType.ELDER_GUARDIAN) {
if (event.entityType() == EntityTypes1_11.EntityType.ELDER_GUARDIAN) {
bitmask |= 0x04;
}
@@ -242,12 +214,12 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Handle skeleton swing
filter().filterFamily(Entity1_11Types.EntityType.ABSTRACT_SKELETON).index(12).toIndex(13);
filter().type(EntityTypes1_11.EntityType.ABSTRACT_SKELETON).index(12).toIndex(13);
/*
ZOMBIE CHANGES
*/
filter().filterFamily(Entity1_11Types.EntityType.ZOMBIE).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.ZOMBIE).handler((event, meta) -> {
switch (meta.id()) {
case 13:
event.cancel();
@@ -267,18 +239,18 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Handle Evocation Illager
filter().type(Entity1_11Types.EntityType.EVOCATION_ILLAGER).index(12).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.EVOCATION_ILLAGER).index(12).handler((event, meta) -> {
event.setIndex(13);
meta.setTypeAndValue(MetaType1_9.VarInt, ((Byte) meta.getValue()).intValue()); // Change the profession for the states
});
// Handle Vex (Remove this field completely since the position is not updated correctly when idling for bats. Sad ):
filter().type(Entity1_11Types.EntityType.VEX).index(12).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.VEX).index(12).handler((event, meta) -> {
meta.setValue((byte) 0x00);
});
// Handle VindicationIllager
filter().type(Entity1_11Types.EntityType.VINDICATION_ILLAGER).index(12).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.VINDICATION_ILLAGER).index(12).handler((event, meta) -> {
event.setIndex(13);
meta.setTypeAndValue(MetaType1_9.VarInt, ((Number) meta.getValue()).intValue() == 1 ? 2 : 4);
});
@@ -288,7 +260,7 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
*/
// Handle horse flags
filter().filterFamily(Entity1_11Types.EntityType.ABSTRACT_HORSE).index(13).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.ABSTRACT_HORSE).index(13).handler((event, meta) -> {
StoredEntityData data = storedEntityData(event);
byte b = (byte) meta.getValue();
if (data.has(ChestedHorseStorage.class) && data.get(ChestedHorseStorage.class).isChested()) {
@@ -298,7 +270,7 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Create chested horse storage
filter().filterFamily(Entity1_11Types.EntityType.CHESTED_HORSE).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.CHESTED_HORSE).handler((event, meta) -> {
StoredEntityData data = storedEntityData(event);
if (!data.has(ChestedHorseStorage.class)) {
data.put(new ChestedHorseStorage());
@@ -306,10 +278,10 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Handle horse armor
filter().type(Entity1_11Types.EntityType.HORSE).index(16).toIndex(17);
filter().type(EntityTypes1_11.EntityType.HORSE).index(16).toIndex(17);
// Handle chested horse
filter().filterFamily(Entity1_11Types.EntityType.CHESTED_HORSE).index(15).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.CHESTED_HORSE).index(15).handler((event, meta) -> {
StoredEntityData data = storedEntityData(event);
ChestedHorseStorage storage = data.get(ChestedHorseStorage.class);
boolean b = (boolean) meta.getValue();
@@ -318,7 +290,7 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Get rid of Liama metadata
filter().type(Entity1_11Types.EntityType.LIAMA).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.LIAMA).handler((event, meta) -> {
StoredEntityData data = storedEntityData(event);
ChestedHorseStorage storage = data.get(ChestedHorseStorage.class);
@@ -341,17 +313,17 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Handle Horse (Correct owner)
filter().filterFamily(Entity1_11Types.EntityType.ABSTRACT_HORSE).index(14).toIndex(16);
filter().type(EntityTypes1_11.EntityType.ABSTRACT_HORSE).index(14).toIndex(16);
// Handle villager - Change non-existing profession
filter().type(Entity1_11Types.EntityType.VILLAGER).index(13).handler((event, meta) -> {
filter().type(EntityTypes1_11.EntityType.VILLAGER).index(13).handler((event, meta) -> {
if ((int) meta.getValue() == 5) {
meta.setValue(0);
}
});
// handle new Shulker color meta
filter().type(Entity1_11Types.EntityType.SHULKER).cancel(15);
filter().type(EntityTypes1_11.EntityType.SHULKER).cancel(15);
}
/*
@@ -393,11 +365,11 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
public EntityType typeFromId(int typeId) {
return Entity1_11Types.getTypeFromId(typeId, false);
return EntityTypes1_11.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(int typeId) {
return Entity1_11Types.getTypeFromId(typeId, true);
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_11.getTypeFromId(typeId, true);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -25,10 +25,9 @@ import com.viaversion.viaversion.api.protocol.remapper.ValueTransformer;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.util.ComponentUtil;
public class PlayerPackets1_11 {
private static final ValueTransformer<Short, Float> TO_NEW_FLOAT = new ValueTransformer<Short, Float>(Type.FLOAT) {
@@ -38,7 +37,7 @@ public class PlayerPackets1_11 {
}
};
public void register(Protocol1_10To1_11 protocol) {
public static void register(Protocol1_10To1_11 protocol) {
protocol.registerClientbound(ClientboundPackets1_9_3.TITLE, new PacketHandlers() {
@Override
public void register() {
@@ -53,8 +52,8 @@ public class PlayerPackets1_11 {
wrapper.clearPacket();
wrapper.setPacketType(ClientboundPackets1_9_3.CHAT_MESSAGE);
// https://bugs.mojang.com/browse/MC-119145to
String legacy = LegacyComponentSerializer.legacySection().serialize(GsonComponentSerializer.gson().deserialize(message.toString()));
// https://bugs.mojang.com/browse/MC-119145
String legacy = ComponentUtil.jsonToLegacy(message);
message = new JsonObject();
message.getAsJsonObject().addProperty("text", legacy);
@@ -81,7 +80,7 @@ public class PlayerPackets1_11 {
protocol.registerServerbound(ServerboundPackets1_9_3.PLAYER_BLOCK_PLACEMENT, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // 0 - Location
map(Type.POSITION1_8); // 0 - Location
map(Type.VAR_INT); // 1 - Face
map(Type.VAR_INT); // 2 - Hand
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -26,7 +26,8 @@ import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.packets.ChatPac
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.packets.EntityPackets1_12;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.packets.SoundPackets1_12;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_12Types;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_12;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.libs.gson.JsonElement;
@@ -34,7 +35,6 @@ import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.ClientboundPacke
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.ServerboundPackets1_12;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
public class Protocol1_11_1To1_12 extends BackwardsProtocol<ClientboundPackets1_12, ClientboundPackets1_9_3, ServerboundPackets1_12, ServerboundPackets1_9_3> {
@@ -58,7 +58,7 @@ public class Protocol1_11_1To1_12 extends BackwardsProtocol<ClientboundPackets1_
int action = wrapper.passthrough(Type.VAR_INT);
if (action >= 0 && action <= 2) {
JsonElement component = wrapper.read(Type.COMPONENT);
wrapper.write(Type.COMPONENT, Protocol1_9To1_8.fixJson(component.toString()));
wrapper.write(Type.COMPONENT, Protocol1_9To1_8.STRING_TO_JSON.transform(wrapper, component.toString()));
}
});
@@ -69,12 +69,11 @@ public class Protocol1_11_1To1_12 extends BackwardsProtocol<ClientboundPackets1_
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
user.put(new ClientWorld());
}
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, Entity1_12Types.EntityType.PLAYER));
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, EntityTypes1_12.EntityType.PLAYER));
user.put(new ShoulderTracker(user));
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -26,6 +26,7 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.util.Key;
public class ShoulderTracker extends StoredObject {
private int entityId;
@@ -39,7 +40,11 @@ public class ShoulderTracker extends StoredObject {
public void update() {
PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_12.CHAT_MESSAGE, null, getUser());
wrapper.write(Type.COMPONENT, Protocol1_9To1_8.fixJson(generateString()));
try {
wrapper.write(Type.COMPONENT, Protocol1_9To1_8.STRING_TO_JSON.transform(wrapper, generateString()));
} catch (final Exception e) {
throw new RuntimeException(e);
}
wrapper.write(Type.BYTE, (byte) 2);
try {
@@ -74,17 +79,15 @@ public class ShoulderTracker extends StoredObject {
}
private String getName(String current) {
if (current.startsWith("minecraft:")) {
current = current.substring(10);
}
current = Key.stripMinecraftNamespace(current);
String[] array = current.split("_");
StringBuilder builder = new StringBuilder();
for (String s : array) {
builder.append(s.substring(0, 1).toUpperCase())
.append(s.substring(1))
.append(" ");
.append(s.substring(1))
.append(" ");
}
return builder.toString();
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -21,21 +21,22 @@ package com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.packets;
import com.viaversion.viabackwards.api.rewriters.LegacyBlockItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.data.MapColorMapping;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
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.api.type.types.chunk.ChunkType1_9_3;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntArrayTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.LongArrayTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.ServerboundPackets1_12;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import java.util.Iterator;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -43,11 +44,14 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPackets1_12, ServerboundPackets1_9_3, Protocol1_11_1To1_12> {
public BlockItemPackets1_12(Protocol1_11_1To1_12 protocol) {
super(protocol);
super(protocol, "1.12");
}
@Override
protected void registerPackets() {
registerBlockChange(ClientboundPackets1_12.BLOCK_CHANGE);
registerMultiBlockChange(ClientboundPackets1_12.MULTI_BLOCK_CHANGE);
protocol.registerClientbound(ClientboundPackets1_12.MAP_DATA, new PacketHandlers() {
@Override
public void register() {
@@ -80,9 +84,9 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
}
});
registerSetSlot(ClientboundPackets1_12.SET_SLOT, Type.ITEM);
registerWindowItems(ClientboundPackets1_12.WINDOW_ITEMS, Type.ITEM_ARRAY);
registerEntityEquipment(ClientboundPackets1_12.ENTITY_EQUIPMENT, Type.ITEM);
registerSetSlot(ClientboundPackets1_12.SET_SLOT);
registerWindowItems(ClientboundPackets1_12.WINDOW_ITEMS);
registerEntityEquipment(ClientboundPackets1_12.ENTITY_EQUIPMENT);
// Plugin message Packet -> Trading
protocol.registerClientbound(ClientboundPackets1_12.PLUGIN_MESSAGE, new PacketHandlers() {
@@ -91,17 +95,17 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
map(Type.STRING); // 0 - Channel
handler(wrapper -> {
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
if (wrapper.get(Type.STRING, 0).equals("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Input Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem)
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Second Item
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
wrapper.passthrough(Type.INT); // Number of tools uses
@@ -120,7 +124,7 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
map(Type.BYTE); // 2 - Button
map(Type.SHORT); // 3 - Action number
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM); // 5 - Clicked Item
map(Type.ITEM1_8); // 5 - Clicked Item
handler(wrapper -> {
if (wrapper.get(Type.VAR_INT, 0) == 1) { // Shift click
@@ -128,7 +132,7 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
// Previously clients grab the item from the clicked slot *before* it has
// been moved however now they grab the slot item *after* it has been moved
// and send that in the packet.
wrapper.set(Type.ITEM, 0, null); // Set null item (probably will work)
wrapper.set(Type.ITEM1_8, 0, null); // Set null item (probably will work)
// Apologize (may happen in some cases, maybe if inventory is full?)
PacketWrapper confirm = wrapper.create(ServerboundPackets1_12.WINDOW_CONFIRMATION);
@@ -142,57 +146,29 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
return;
}
Item item = wrapper.get(Type.ITEM, 0);
handleItemToServer(item);
Item item = wrapper.get(Type.ITEM1_8, 0);
handleItemToServer(wrapper.user(), item);
});
}
});
registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION, Type.ITEM);
registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION);
protocol.registerClientbound(ClientboundPackets1_12.CHUNK_DATA, wrapper -> {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); // Use the 1.9.4 Chunk type since nothing changed.
ChunkType1_9_3 type = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment()); // Use the 1.9.4 Chunk type since nothing changed.
Chunk chunk = wrapper.passthrough(type);
handleChunk(chunk);
});
protocol.registerClientbound(ClientboundPackets1_12.BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // 0 - Block Position
map(Type.VAR_INT); // 1 - Block
handler(wrapper -> {
int idx = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, handleBlockID(idx));
});
}
});
protocol.registerClientbound(ClientboundPackets1_12.MULTI_BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // 0 - Chunk X
map(Type.INT); // 1 - Chunk Z
map(Type.BLOCK_CHANGE_RECORD_ARRAY);
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.get(Type.BLOCK_CHANGE_RECORD_ARRAY, 0)) {
record.setBlockId(handleBlockID(record.getBlockId()));
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_12.BLOCK_ENTITY_DATA, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // 0 - Position
map(Type.POSITION1_8); // 0 - Position
map(Type.UNSIGNED_BYTE); // 1 - Action
map(Type.NBT); // 2 - NBT
map(Type.NAMED_COMPOUND_TAG); // 2 - NBT
handler(wrapper -> {
// Remove bed color
@@ -203,8 +179,8 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
});
protocol.getEntityRewriter().filter().handler((event, meta) -> {
if (meta.metaType().type().equals(Type.ITEM)) // Is Item
meta.setValue(handleItemToClient((Item) meta.getValue()));
if (meta.metaType().type().equals(Type.ITEM1_8)) // Is Item
meta.setValue(handleItemToClient(event.user(), (Item) meta.getValue()));
});
protocol.registerServerbound(ServerboundPackets1_9_3.CLIENT_STATUS, new PacketHandlers() {
@@ -223,9 +199,9 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
}
@Override
public @Nullable Item handleItemToClient(Item item) {
public @Nullable Item handleItemToClient(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToClient(item);
super.handleItemToClient(connection, item);
if (item.tag() != null) {
CompoundTag backupTag = new CompoundTag();
@@ -258,9 +234,9 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
}
@Override
public @Nullable Item handleItemToServer(Item item) {
public @Nullable Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
if (item.tag() != null) {
Tag tag = item.tag().remove("Via|LongArrayTags");
@@ -276,7 +252,7 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
// Restore the removed long array tags
for (Map.Entry<String, Tag> entry : backupTag) {
if (entry.getValue() instanceof CompoundTag) {
CompoundTag nestedTag = compoundTag.get(entry.getKey());
CompoundTag nestedTag = compoundTag.getCompoundTag(entry.getKey());
handleNbtToServer(nestedTag, (CompoundTag) entry.getValue());
} else {
compoundTag.put(entry.getKey(), fromIntArrayTag((IntArrayTag) entry.getValue()));
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,6 +20,7 @@ package com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.packets;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.data.AdvancementTranslations;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.rewriter.RewriterBase;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonElement;
@@ -29,7 +30,24 @@ import com.viaversion.viaversion.rewriter.ComponentRewriter;
public class ChatPackets1_12 extends RewriterBase<Protocol1_11_1To1_12> {
private final ComponentRewriter<ClientboundPackets1_12> componentRewriter = new ComponentRewriter<ClientboundPackets1_12>() {
public static final ComponentRewriter<ClientboundPackets1_12> COMPONENT_REWRITER = new ComponentRewriter<ClientboundPackets1_12>(null, ComponentRewriter.ReadType.JSON) {
@Override
public void processText(UserConnection connection, JsonElement element) {
super.processText(connection, element);
if (element == null || !element.isJsonObject()) {
return;
}
JsonObject object = element.getAsJsonObject();
JsonElement keybind = object.remove("keybind");
if (keybind == null) {
return;
}
//TODO Add nicer text for the key, also use this component rewriter in more packets
object.addProperty("text", keybind.getAsString());
}
@Override
protected void handleTranslate(JsonObject object, String translate) {
String text = AdvancementTranslations.get(translate);
@@ -47,7 +65,7 @@ public class ChatPackets1_12 extends RewriterBase<Protocol1_11_1To1_12> {
protected void registerPackets() {
protocol.registerClientbound(ClientboundPackets1_12.CHAT_MESSAGE, wrapper -> {
JsonElement element = wrapper.passthrough(Type.COMPONENT);
componentRewriter.processText(element);
COMPONENT_REWRITER.processText(wrapper.user(), element);
});
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -22,20 +22,19 @@ import com.viaversion.viabackwards.api.rewriters.LegacyEntityRewriter;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.Protocol1_11_1To1_12;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.data.ParrotStorage;
import com.viaversion.viabackwards.protocol.protocol1_11_1to1_12.data.ShoulderTracker;
import com.viaversion.viabackwards.utils.Block;
import com.viaversion.viaversion.api.data.entity.StoredEntityData;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_12Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_12;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaType1_12;
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_12;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.ClientboundPackets1_12;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import java.util.Optional;
public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_12, Protocol1_11_1To1_12> {
@@ -60,29 +59,14 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
// Track Entity
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> Entity1_12Types.ObjectType.findById(id).orElse(null)));
handler(getObjectRewriter(id -> EntityTypes1_12.ObjectType.findById(id).orElse(null)));
// Handle FallingBlock blocks
handler(wrapper -> {
Optional<Entity1_12Types.ObjectType> type = Entity1_12Types.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get() == Entity1_12Types.ObjectType.FALLING_BLOCK) {
int objectData = wrapper.get(Type.INT, 0);
int objType = objectData & 4095;
int data = objectData >> 12 & 15;
Block block = protocol.getItemRewriter().handleBlock(objType, data);
if (block == null) {
return;
}
wrapper.set(Type.INT, 0, block.getId() | block.getData() << 12);
}
});
handler(protocol.getItemRewriter().getFallingBlockHandler());
}
});
registerTracker(ClientboundPackets1_12.SPAWN_EXPERIENCE_ORB, Entity1_12Types.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_12.SPAWN_GLOBAL_ENTITY, Entity1_12Types.EntityType.WEATHER);
registerTracker(ClientboundPackets1_12.SPAWN_EXPERIENCE_ORB, EntityTypes1_12.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_12.SPAWN_GLOBAL_ENTITY, EntityTypes1_12.EntityType.WEATHER);
protocol.registerClientbound(ClientboundPackets1_12.SPAWN_MOB, new PacketHandlers() {
@Override
@@ -105,11 +89,11 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
handler(getTrackerHandler());
// Rewrite entity type / metadata
handler(getMobSpawnRewriter(Types1_12.METADATA_LIST));
handler(getMobSpawnRewriter1_11(Types1_12.METADATA_LIST));
}
});
registerTracker(ClientboundPackets1_12.SPAWN_PAINTING, Entity1_12Types.EntityType.PAINTING);
registerTracker(ClientboundPackets1_12.SPAWN_PAINTING, EntityTypes1_12.EntityType.PAINTING);
protocol.registerClientbound(ClientboundPackets1_12.SPAWN_PLAYER, new PacketHandlers() {
@Override
@@ -123,7 +107,7 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
map(Type.BYTE); // 6 - Pitch
map(Types1_12.METADATA_LIST); // 7 - Metadata list
handler(getTrackerAndMetaHandler(Types1_12.METADATA_LIST, Entity1_12Types.EntityType.PLAYER));
handler(getTrackerAndMetaHandler(Types1_12.METADATA_LIST, EntityTypes1_12.EntityType.PLAYER));
}
});
@@ -134,7 +118,7 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
map(Type.UNSIGNED_BYTE); // 1 - Gamemode
map(Type.INT); // 2 - Dimension
handler(getTrackerHandler(Entity1_12Types.EntityType.PLAYER, Type.INT));
handler(getTrackerHandler(EntityTypes1_12.EntityType.PLAYER, Type.INT));
handler(getDimensionHandler(1));
@@ -202,14 +186,20 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
protected void registerRewrites() {
mapEntityTypeWithData(Entity1_12Types.EntityType.PARROT, Entity1_12Types.EntityType.BAT).plainName().spawnMetadata(storage -> storage.add(new Metadata(12, MetaType1_12.Byte, (byte) 0x00)));
mapEntityTypeWithData(Entity1_12Types.EntityType.ILLUSION_ILLAGER, Entity1_12Types.EntityType.EVOCATION_ILLAGER).plainName();
mapEntityTypeWithData(EntityTypes1_12.EntityType.PARROT, EntityTypes1_12.EntityType.BAT).plainName().spawnMetadata(storage -> storage.add(new Metadata(12, MetaType1_12.Byte, (byte) 0x00)));
mapEntityTypeWithData(EntityTypes1_12.EntityType.ILLUSION_ILLAGER, EntityTypes1_12.EntityType.EVOCATION_ILLAGER).plainName();
filter().handler((event, meta) -> {
if (meta.metaType() == MetaType1_12.Chat) {
ChatPackets1_12.COMPONENT_REWRITER.processText(event.user(), (JsonElement) meta.getValue());
}
});
// Handle Illager
filter().filterFamily(Entity1_12Types.EntityType.EVOCATION_ILLAGER).cancel(12);
filter().filterFamily(Entity1_12Types.EntityType.EVOCATION_ILLAGER).index(13).toIndex(12);
filter().type(EntityTypes1_12.EntityType.EVOCATION_ILLAGER).cancel(12);
filter().type(EntityTypes1_12.EntityType.EVOCATION_ILLAGER).index(13).toIndex(12);
filter().type(Entity1_12Types.EntityType.ILLUSION_ILLAGER).index(0).handler((event, meta) -> {
filter().type(EntityTypes1_12.EntityType.ILLUSION_ILLAGER).index(0).handler((event, meta) -> {
byte mask = (byte) meta.getValue();
if ((mask & 0x20) == 0x20) {
@@ -220,15 +210,15 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Create Parrot storage
filter().filterFamily(Entity1_12Types.EntityType.PARROT).handler((event, meta) -> {
filter().type(EntityTypes1_12.EntityType.PARROT).handler((event, meta) -> {
StoredEntityData data = storedEntityData(event);
if (!data.has(ParrotStorage.class)) {
data.put(new ParrotStorage());
}
});
// Parrot remove animal metadata
filter().type(Entity1_12Types.EntityType.PARROT).cancel(12); // Is baby
filter().type(Entity1_12Types.EntityType.PARROT).index(13).handler((event, meta) -> {
filter().type(EntityTypes1_12.EntityType.PARROT).cancel(12); // Is baby
filter().type(EntityTypes1_12.EntityType.PARROT).index(13).handler((event, meta) -> {
StoredEntityData data = storedEntityData(event);
ParrotStorage storage = data.get(ParrotStorage.class);
boolean isSitting = (((byte) meta.getValue()) & 0x01) == 0x01;
@@ -252,19 +242,19 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
event.cancel();
}
}); // Flags (Is sitting etc, might be useful in the future
filter().type(Entity1_12Types.EntityType.PARROT).cancel(14); // Owner
filter().type(Entity1_12Types.EntityType.PARROT).cancel(15); // Variant
filter().type(EntityTypes1_12.EntityType.PARROT).cancel(14); // Owner
filter().type(EntityTypes1_12.EntityType.PARROT).cancel(15); // Variant
// Left shoulder entity data
filter().type(Entity1_12Types.EntityType.PLAYER).index(15).handler((event, meta) -> {
filter().type(EntityTypes1_12.EntityType.PLAYER).index(15).handler((event, meta) -> {
CompoundTag tag = (CompoundTag) meta.getValue();
ShoulderTracker tracker = event.user().get(ShoulderTracker.class);
if (tag.isEmpty() && tracker.getLeftShoulder() != null) {
tracker.setLeftShoulder(null);
tracker.update();
} else if (tag.contains("id") && event.entityId() == tracker.getEntityId()) {
String id = (String) tag.get("id").getValue();
} else if (tag.getStringTag("id") != null && event.entityId() == tracker.getEntityId()) {
String id = tag.getStringTag("id").getValue();
if (tracker.getLeftShoulder() == null || !tracker.getLeftShoulder().equals(id)) {
tracker.setLeftShoulder(id);
tracker.update();
@@ -275,15 +265,15 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Right shoulder entity data
filter().type(Entity1_12Types.EntityType.PLAYER).index(16).handler((event, meta) -> {
filter().type(EntityTypes1_12.EntityType.PLAYER).index(16).handler((event, meta) -> {
CompoundTag tag = (CompoundTag) event.meta().getValue();
ShoulderTracker tracker = event.user().get(ShoulderTracker.class);
if (tag.isEmpty() && tracker.getRightShoulder() != null) {
tracker.setRightShoulder(null);
tracker.update();
} else if (tag.contains("id") && event.entityId() == tracker.getEntityId()) {
String id = (String) tag.get("id").getValue();
} else if (tag.getStringTag("id") != null && event.entityId() == tracker.getEntityId()) {
String id = tag.getStringTag("id").getValue();
if (tracker.getRightShoulder() == null || !tracker.getRightShoulder().equals(id)) {
tracker.setRightShoulder(id);
tracker.update();
@@ -296,11 +286,11 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
public EntityType typeFromId(int typeId) {
return Entity1_12Types.getTypeFromId(typeId, false);
return EntityTypes1_12.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
return Entity1_12Types.getTypeFromId(typeId, true);
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_12.getTypeFromId(typeId, true);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -22,11 +22,11 @@ import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.protocol.protocol1_11to1_11_1.packets.EntityPackets1_11_1;
import com.viaversion.viabackwards.protocol.protocol1_11to1_11_1.packets.ItemPackets1_11_1;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_11Types;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_11To1_11_1 extends BackwardsProtocol<ClientboundPackets1_9_3, ClientboundPackets1_9_3, ServerboundPackets1_9_3, ServerboundPackets1_9_3> {
@@ -45,12 +45,11 @@ public class Protocol1_11To1_11_1 extends BackwardsProtocol<ClientboundPackets1_
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
user.put(new ClientWorld());
}
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, Entity1_11Types.EntityType.PLAYER));
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, EntityTypes1_11.EntityType.PLAYER));
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,8 +20,8 @@ package com.viaversion.viabackwards.protocol.protocol1_11to1_11_1.packets;
import com.viaversion.viabackwards.api.rewriters.LegacyEntityRewriter;
import com.viaversion.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_11Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_9;
@@ -50,12 +50,12 @@ public class EntityPackets1_11_1 extends LegacyEntityRewriter<ClientboundPackets
// Track Entity
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> Entity1_11Types.ObjectType.findById(id).orElse(null)));
handler(getObjectRewriter(id -> EntityTypes1_11.ObjectType.findById(id).orElse(null)));
}
});
registerTracker(ClientboundPackets1_9_3.SPAWN_EXPERIENCE_ORB, Entity1_11Types.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, Entity1_11Types.EntityType.WEATHER);
registerTracker(ClientboundPackets1_9_3.SPAWN_EXPERIENCE_ORB, EntityTypes1_11.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_9_3.SPAWN_GLOBAL_ENTITY, EntityTypes1_11.EntityType.WEATHER);
protocol.registerClientbound(ClientboundPackets1_9_3.SPAWN_MOB, new PacketHandlers() {
@Override
@@ -78,12 +78,12 @@ public class EntityPackets1_11_1 extends LegacyEntityRewriter<ClientboundPackets
handler(getTrackerHandler());
// Rewrite entity type / metadata
handler(getMobSpawnRewriter(Types1_9.METADATA_LIST));
handler(getMobSpawnRewriter1_11(Types1_9.METADATA_LIST));
}
});
registerTracker(ClientboundPackets1_9_3.SPAWN_PAINTING, Entity1_11Types.EntityType.PAINTING);
registerJoinGame(ClientboundPackets1_9_3.JOIN_GAME, Entity1_11Types.EntityType.PLAYER);
registerTracker(ClientboundPackets1_9_3.SPAWN_PAINTING, EntityTypes1_11.EntityType.PAINTING);
registerJoinGame(ClientboundPackets1_9_3.JOIN_GAME, EntityTypes1_11.EntityType.PLAYER);
registerRespawn(ClientboundPackets1_9_3.RESPAWN);
protocol.registerClientbound(ClientboundPackets1_9_3.SPAWN_PLAYER, new PacketHandlers() {
@@ -98,7 +98,7 @@ public class EntityPackets1_11_1 extends LegacyEntityRewriter<ClientboundPackets
map(Type.BYTE); // 6 - Pitch
map(Types1_9.METADATA_LIST); // 7 - Metadata list
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, Entity1_11Types.EntityType.PLAYER));
handler(getTrackerAndMetaHandler(Types1_9.METADATA_LIST, EntityTypes1_11.EntityType.PLAYER));
}
});
@@ -109,19 +109,19 @@ public class EntityPackets1_11_1 extends LegacyEntityRewriter<ClientboundPackets
@Override
protected void registerRewrites() {
// Handle non-existing firework metadata (index 7 entity id for boosting)
filter().type(Entity1_11Types.EntityType.FIREWORK).cancel(7);
filter().type(EntityTypes1_11.EntityType.FIREWORK).cancel(7);
// Handle non-existing pig metadata (index 14 - boost time)
filter().type(Entity1_11Types.EntityType.PIG).cancel(14);
filter().type(EntityTypes1_11.EntityType.PIG).cancel(14);
}
@Override
public EntityType typeFromId(int typeId) {
return Entity1_11Types.getTypeFromId(typeId, false);
return EntityTypes1_11.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
return Entity1_11Types.getTypeFromId(typeId, true);
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_11.getTypeFromId(typeId, true);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -21,11 +21,10 @@ package com.viaversion.viabackwards.protocol.protocol1_11to1_11_1.packets;
import com.viaversion.viabackwards.api.rewriters.LegacyBlockItemRewriter;
import com.viaversion.viabackwards.api.rewriters.LegacyEnchantmentRewriter;
import com.viaversion.viabackwards.protocol.protocol1_11to1_11_1.Protocol1_11To1_11_1;
import com.viaversion.viaversion.api.connection.UserConnection;
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.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
@@ -34,14 +33,14 @@ public class ItemPackets1_11_1 extends LegacyBlockItemRewriter<ClientboundPacket
private LegacyEnchantmentRewriter enchantmentRewriter;
public ItemPackets1_11_1(Protocol1_11To1_11_1 protocol) {
super(protocol);
super(protocol, "1.11.1");
}
@Override
protected void registerPackets() {
registerSetSlot(ClientboundPackets1_9_3.SET_SLOT, Type.ITEM);
registerWindowItems(ClientboundPackets1_9_3.WINDOW_ITEMS, Type.ITEM_ARRAY);
registerEntityEquipment(ClientboundPackets1_9_3.ENTITY_EQUIPMENT, Type.ITEM);
registerSetSlot(ClientboundPackets1_9_3.SET_SLOT);
registerWindowItems(ClientboundPackets1_9_3.WINDOW_ITEMS);
registerEntityEquipment(ClientboundPackets1_9_3.ENTITY_EQUIPMENT);
// Plugin message Packet -> Trading
protocol.registerClientbound(ClientboundPackets1_9_3.PLUGIN_MESSAGE, new PacketHandlers() {
@@ -50,17 +49,17 @@ public class ItemPackets1_11_1 extends LegacyBlockItemRewriter<ClientboundPacket
map(Type.STRING); // 0 - Channel
handler(wrapper -> {
if (wrapper.get(Type.STRING, 0).equalsIgnoreCase("MC|TrList")) {
if (wrapper.get(Type.STRING, 0).equals("MC|TrList")) {
wrapper.passthrough(Type.INT); // Passthrough Window ID
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Input Item
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Output Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Input Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Output Item
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem) {
wrapper.write(Type.ITEM, handleItemToClient(wrapper.read(Type.ITEM))); // Second Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Second Item
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
@@ -72,54 +71,38 @@ public class ItemPackets1_11_1 extends LegacyBlockItemRewriter<ClientboundPacket
}
});
registerClickWindow(ServerboundPackets1_9_3.CLICK_WINDOW, Type.ITEM);
registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION, Type.ITEM);
registerClickWindow(ServerboundPackets1_9_3.CLICK_WINDOW);
registerCreativeInvAction(ServerboundPackets1_9_3.CREATIVE_INVENTORY_ACTION);
// Handle item metadata
protocol.getEntityRewriter().filter().handler((event, meta) -> {
if (meta.metaType().type().equals(Type.ITEM)) { // Is Item
meta.setValue(handleItemToClient((Item) meta.getValue()));
if (meta.metaType().type().equals(Type.ITEM1_8)) { // Is Item
meta.setValue(handleItemToClient(event.user(), (Item) meta.getValue()));
}
});
}
@Override
protected void registerRewrites() {
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName);
enchantmentRewriter = new LegacyEnchantmentRewriter(nbtTagName());
enchantmentRewriter.registerEnchantment(22, "§7Sweeping Edge");
}
@Override
public Item handleItemToClient(Item item) {
public Item handleItemToClient(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToClient(item);
super.handleItemToClient(connection, item);
CompoundTag tag = item.tag();
if (tag == null) return item;
if (tag.get("ench") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, false);
}
if (tag.get("StoredEnchantments") instanceof ListTag) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, true);
}
enchantmentRewriter.handleToClient(item);
return item;
}
@Override
public Item handleItemToServer(Item item) {
public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
CompoundTag tag = item.tag();
if (tag == null) return item;
if (tag.contains(nbtTagName + "|ench")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, false);
}
if (tag.contains(nbtTagName + "|StoredEnchantments")) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, true);
}
enchantmentRewriter.handleToServer(item);
return item;
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,6 +19,7 @@
package com.viaversion.viabackwards.protocol.protocol1_12_1to1_12_2;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.protocol.protocol1_12_1to1_12_2.storage.KeepAliveTracker;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viabackwards.protocol.protocol1_12_1to1_12_2;
package com.viaversion.viabackwards.protocol.protocol1_12_1to1_12_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -29,25 +29,49 @@ import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.packets.PlayerP
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.packets.SoundPackets1_13;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.BackwardsBlockStorage;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.NoteBlockStorage;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.PlayerPositionStorage1_13;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.TabCompleteStorage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_13Types;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_13;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonParser;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.util.ComponentUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
public class Protocol1_12_2To1_13 extends BackwardsProtocol<ClientboundPackets1_13, ClientboundPackets1_12_1, ServerboundPackets1_13, ServerboundPackets1_12_1> {
public static final BackwardsMappings MAPPINGS = new BackwardsMappings();
private final EntityPackets1_13 entityRewriter = new EntityPackets1_13(this);
private final BlockItemPackets1_13 blockItemPackets = new BlockItemPackets1_13(this);
private final TranslatableRewriter<ClientboundPackets1_13> translatableRewriter = new TranslatableRewriter<ClientboundPackets1_13>(this, ComponentRewriter.ReadType.JSON) {
@Override
protected void handleTranslate(JsonObject root, String translate) {
String mappedKey = mappedTranslationKey(translate);
if (mappedKey != null || (mappedKey = getMappingData().getTranslateMappings().get(translate)) != null) {
root.addProperty("translate", mappedKey);
}
}
};
private final TranslatableRewriter<ClientboundPackets1_13> translatableToLegacyRewriter = new TranslatableRewriter<ClientboundPackets1_13>(this, ComponentRewriter.ReadType.JSON) {
@Override
protected void handleTranslate(JsonObject root, String translate) {
String mappedKey = mappedTranslationKey(translate);
if (mappedKey != null || (mappedKey = getMappingData().getTranslateMappings().get(translate)) != null) {
root.addProperty("translate", Protocol1_13To1_12_2.MAPPINGS.getMojangTranslation().getOrDefault(mappedKey, mappedKey));
}
}
};
public Protocol1_12_2To1_13() {
super(ClientboundPackets1_13.class, ClientboundPackets1_12_1.class, ServerboundPackets1_13.class, ServerboundPackets1_12_1.class);
@@ -61,20 +85,11 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol<ClientboundPackets1_
Via.getManager().getProviders().register(BackwardsBlockEntityProvider.class, new BackwardsBlockEntityProvider());
});
TranslatableRewriter<ClientboundPackets1_13> translatableRewriter = new TranslatableRewriter<ClientboundPackets1_13>(this) {
@Override
protected void handleTranslate(JsonObject root, String translate) {
String newTranslate = mappedTranslationKey(translate);
if (newTranslate != null || (newTranslate = getMappingData().getTranslateMappings().get(translate)) != null) {
root.addProperty("translate", newTranslate);
}
}
};
translatableRewriter.registerPing();
translatableRewriter.registerBossBar(ClientboundPackets1_13.BOSSBAR);
translatableRewriter.registerComponentPacket(ClientboundPackets1_13.CHAT_MESSAGE);
translatableRewriter.registerLegacyOpenWindow(ClientboundPackets1_13.OPEN_WINDOW);
translatableRewriter.registerDisconnect(ClientboundPackets1_13.DISCONNECT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_13.DISCONNECT);
translatableRewriter.registerCombatEvent(ClientboundPackets1_13.COMBAT_EVENT);
translatableRewriter.registerTitle(ClientboundPackets1_13.TITLE);
translatableRewriter.registerTabList(ClientboundPackets1_13.TAB_LIST);
@@ -97,12 +112,11 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol<ClientboundPackets1_
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld(user));
user.put(new ClientWorld());
}
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, Entity1_13Types.EntityType.PLAYER));
user.addEntityTracker(this.getClass(), new EntityTrackerBase(user, EntityTypes1_13.EntityType.PLAYER));
user.put(new BackwardsBlockStorage());
user.put(new TabCompleteStorage());
@@ -110,6 +124,8 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol<ClientboundPackets1_
if (ViaBackwards.getConfig().isFix1_13FacePlayer() && !user.has(PlayerPositionStorage1_13.class)) {
user.put(new PlayerPositionStorage1_13());
}
user.put(new NoteBlockStorage());
}
@Override
@@ -126,4 +142,31 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol<ClientboundPackets1_
public BlockItemPackets1_13 getItemRewriter() {
return blockItemPackets;
}
// Don't override the parent method
public TranslatableRewriter<ClientboundPackets1_13> translatableRewriter() {
return translatableRewriter;
}
public String jsonToLegacy(UserConnection connection, String value) {
if (value.isEmpty()) {
return "";
}
try {
return jsonToLegacy(connection, JsonParser.parseString(value));
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public String jsonToLegacy(UserConnection connection, @Nullable JsonElement value) {
if (value == null || value.isJsonNull()) {
return "";
}
translatableToLegacyRewriter.processText(connection, value);
return ComponentUtil.jsonToLegacy(value);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,10 +20,9 @@ package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.block_entity_h
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
public class BannerHandler implements BackwardsBlockEntityHandler {
@@ -34,28 +33,26 @@ public class BannerHandler implements BackwardsBlockEntityHandler {
private static final int BANNER_STOP = 7109;
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
public CompoundTag transform(int blockId, CompoundTag tag) {
// Normal banners
if (blockId >= BANNER_START && blockId <= BANNER_STOP) {
int color = (blockId - BANNER_START) >> 4;
tag.put("Base", new IntTag((15 - color)));
tag.putInt("Base", 15 - color);
}
// Wall banners
else if (blockId >= WALL_BANNER_START && blockId <= WALL_BANNER_STOP) {
int color = (blockId - WALL_BANNER_START) >> 2;
tag.put("Base", new IntTag((15 - color)));
tag.putInt("Base", 15 - color);
} else {
ViaBackwards.getPlatform().getLogger().warning("Why does this block have the banner block entity? :(" + tag);
}
// Invert colors
Tag patternsTag = tag.get("Patterns");
if (patternsTag instanceof ListTag) {
for (Tag pattern : (ListTag) patternsTag) {
if (!(pattern instanceof CompoundTag)) continue;
IntTag c = ((CompoundTag) pattern).get("Color");
c.setValue(15 - c.asInt()); // Invert color id
ListTag<CompoundTag> patternsTag = tag.getListTag("Patterns", CompoundTag.class);
if (patternsTag != null) {
for (CompoundTag pattern : patternsTag) {
NumberTag colorTag = pattern.getNumberTag("Color");
pattern.putInt("Color", 15 - colorTag.asInt()); // Invert color id
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,18 +19,16 @@
package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
public class BedHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
public CompoundTag transform(int blockId, CompoundTag tag) {
int offset = blockId - 748;
int color = offset >> 4;
tag.put("color", new IntTag(color));
tag.putInt("color", color);
return tag;
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,12 +19,9 @@
package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.util.Pair;
public class FlowerPotHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
@@ -72,11 +69,11 @@ public class FlowerPotHandler implements BackwardsBlockEntityProvider.BackwardsB
// TODO THIS IS NEVER CALLED BECAUSE ITS NO LONGER A BLOCK ENTITY :(
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
public CompoundTag transform(int blockId, CompoundTag tag) {
Pair<String, Byte> item = getOrDefault(blockId);
tag.put("Item", new StringTag(item.key()));
tag.put("Data", new IntTag(item.value()));
tag.putString("Item", item.key());
tag.putInt("Data", item.value());
return tag;
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,23 +20,23 @@ package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.block_entity_h
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
public class PistonHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
private final Map<String, Integer> pistonIds = new HashMap<>();
private final Object2IntMap<String> pistonIds = new Object2IntOpenHashMap<>();
public PistonHandler() {
pistonIds.defaultReturnValue(-1);
if (Via.getConfig().isServersideBlockConnections()) {
Map<String, Integer> keyToId = ConnectionData.getKeyToId();
for (Map.Entry<String, Integer> entry : keyToId.entrySet()) {
@@ -47,7 +47,7 @@ public class PistonHandler implements BackwardsBlockEntityProvider.BackwardsBloc
addEntries(entry.getKey(), entry.getValue());
}
} else {
ListTag blockStates = MappingDataLoader.loadNBT("blockstates-1.13.nbt").get("blockstates");
ListTag<StringTag> blockStates = MappingDataLoader.INSTANCE.loadNBT("blockstates-1.13.nbt").getListTag("blockstates", StringTag.class);
for (int id = 0; id < blockStates.size(); id++) {
StringTag state = blockStates.get(id);
String key = state.getValue();
@@ -76,30 +76,30 @@ public class PistonHandler implements BackwardsBlockEntityProvider.BackwardsBloc
}
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
CompoundTag blockState = tag.get("blockState");
public CompoundTag transform(int blockId, CompoundTag tag) {
CompoundTag blockState = tag.getCompoundTag("blockState");
if (blockState == null) return tag;
String dataFromTag = getDataFromTag(blockState);
if (dataFromTag == null) return tag;
Integer id = pistonIds.get(dataFromTag);
if (id == null) {
int id = pistonIds.getInt(dataFromTag);
if (id == -1) {
//TODO see why this could be null and if this is bad
return tag;
}
tag.put("blockId", new IntTag(id >> 4));
tag.put("blockData", new IntTag(id & 15));
tag.putInt("blockId", id >> 4);
tag.putInt("blockData", id & 15);
return tag;
}
// The type hasn't actually been updated in the blockstorage, so we need to construct it
private String getDataFromTag(CompoundTag tag) {
StringTag name = tag.get("Name");
StringTag name = tag.getStringTag("Name");
if (name == null) return null;
CompoundTag properties = tag.get("Properties");
CompoundTag properties = tag.getCompoundTag("Properties");
if (properties == null) return name.getValue();
StringJoiner joiner = new StringJoiner(",", name.getValue() + "[", "]");
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,21 +19,19 @@
package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ByteTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
public class SkullHandler implements BackwardsBlockEntityHandler {
private static final int SKULL_START = 5447;
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
public CompoundTag transform(int blockId, CompoundTag tag) {
int diff = blockId - SKULL_START;
int pos = diff % 20;
byte type = (byte) Math.floor(diff / 20f);
// Set type
tag.put("SkullType", new ByteTag(type));
tag.putByte("SkullType", type);
// Remove wall skulls
if (pos < 4) {
@@ -41,7 +39,7 @@ public class SkullHandler implements BackwardsBlockEntityHandler {
}
// Add rotation for normal skulls
tag.put("Rot", new ByteTag((byte) ((pos - 4) & 255)));
tag.putByte("Rot", (byte) ((pos - 4) & 255));
return tag;
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,22 +20,18 @@ package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.block_entity_h
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.data.EntityNameRewrites;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
public class SpawnerHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
@Override
public CompoundTag transform(UserConnection user, int blockId, CompoundTag tag) {
Tag dataTag = tag.get("SpawnData");
if (dataTag instanceof CompoundTag) {
CompoundTag data = (CompoundTag) dataTag;
Tag idTag = data.get("id");
if (idTag instanceof StringTag) {
StringTag s = (StringTag) idTag;
s.setValue(EntityNameRewrites.rewrite(s.getValue()));
public CompoundTag transform(int blockId, CompoundTag tag) {
CompoundTag dataTag = tag.getCompoundTag("SpawnData");
if (dataTag != null) {
StringTag idTag = dataTag.getStringTag("id");
if (idTag != null) {
idTag.setValue(EntityNameRewrites.rewrite(idTag.getValue()));
}
}
return tag;
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -18,6 +18,7 @@
package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.data;
import com.viaversion.viaversion.util.Key;
import java.util.HashMap;
import java.util.Map;
@@ -42,15 +43,11 @@ public class EntityNameRewrites {
private static void reg(String past, String future) {
ENTITY_NAMES.put("minecraft:" + future, "minecraft:" + past);
ENTITY_NAMES.put(Key.namespaced(future), Key.namespaced(past));
}
public static String rewrite(String entName) {
String entityName = ENTITY_NAMES.get(entName);
if (entityName != null) {
return entityName;
}
entityName = ENTITY_NAMES.get("minecraft:" + entName);
String entityName = ENTITY_NAMES.get(Key.namespaced(entName));
if (entityName != null) {
return entityName;
} else
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -18,6 +18,7 @@
package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.data;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.NamedSoundRewriter;
import com.viaversion.viaversion.util.Key;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
@@ -37,9 +38,6 @@ public class NamedSoundMapping {
}
public static String getOldId(String sound1_13) {
if (sound1_13.startsWith("minecraft:")) {
sound1_13 = sound1_13.substring(10);
}
return SOUNDS.get(sound1_13);
return SOUNDS.get(Key.stripMinecraftNamespace(sound1_13));
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -19,10 +19,10 @@
package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.data;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import com.viaversion.viaversion.api.minecraft.Particle;
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.api.type.types.Particle;
import java.util.List;
public class ParticleMapping {
@@ -36,7 +36,7 @@ public class ParticleMapping {
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData<?>> data) {
return rewrite((int) data.get(0).getValue());
}
@@ -55,94 +55,94 @@ public class ParticleMapping {
};
particles = new ParticleData[]{
rewrite(16), // (0->16) minecraft:ambient_entity_effect -> mobSpellAmbient
rewrite(20), // (1->20) minecraft:angry_villager -> angryVillager
rewrite(35), // (2->35) minecraft:barrier -> barrier
rewrite(37, blockHandler),
// (3->37) minecraft:block -> blockcrack
rewrite(4), // (4->4) minecraft:bubble -> bubble
rewrite(29), // (5->29) minecraft:cloud -> cloud
rewrite(9), // (6->9) minecraft:crit -> crit
rewrite(44), // (7->44) minecraft:damage_indicator -> damageIndicator‌
rewrite(42), // (8->42) minecraft:dragon_breath -> dragonbreath
rewrite(19), // (9->19) minecraft:dripping_lava -> dripLava
rewrite(18), // (10->18) minecraft:dripping_water -> dripWater
rewrite(30, new ParticleHandler() {
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
float r = wrapper.read(Type.FLOAT);
float g = wrapper.read(Type.FLOAT);
float b = wrapper.read(Type.FLOAT);
float scale = wrapper.read(Type.FLOAT);
rewrite(16), // (0->16) minecraft:ambient_entity_effect -> mobSpellAmbient
rewrite(20), // (1->20) minecraft:angry_villager -> angryVillager
rewrite(35), // (2->35) minecraft:barrier -> barrier
rewrite(37, blockHandler),
// (3->37) minecraft:block -> blockcrack
rewrite(4), // (4->4) minecraft:bubble -> bubble
rewrite(29), // (5->29) minecraft:cloud -> cloud
rewrite(9), // (6->9) minecraft:crit -> crit
rewrite(44), // (7->44) minecraft:damage_indicator -> damageIndicator‌
rewrite(42), // (8->42) minecraft:dragon_breath -> dragonbreath
rewrite(19), // (9->19) minecraft:dripping_lava -> dripLava
rewrite(18), // (10->18) minecraft:dripping_water -> dripWater
rewrite(30, new ParticleHandler() {
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
float r = wrapper.read(Type.FLOAT);
float g = wrapper.read(Type.FLOAT);
float b = wrapper.read(Type.FLOAT);
float scale = wrapper.read(Type.FLOAT);
wrapper.set(Type.FLOAT, 3, r); // 5 - Offset X index=3
wrapper.set(Type.FLOAT, 4, g); // 6 - Offset Y index=4
wrapper.set(Type.FLOAT, 5, b); // 7 - Offset Z index=5
wrapper.set(Type.FLOAT, 6, scale); // 8 - Particle Data index=6
wrapper.set(Type.INT, 1, 0); // 9 - Particle Count index=1 enable rgb particle
wrapper.set(Type.FLOAT, 3, r); // 5 - Offset X index=3
wrapper.set(Type.FLOAT, 4, g); // 6 - Offset Y index=4
wrapper.set(Type.FLOAT, 5, b); // 7 - Offset Z index=5
wrapper.set(Type.FLOAT, 6, scale); // 8 - Particle Data index=6
wrapper.set(Type.INT, 1, 0); // 9 - Particle Count index=1 enable rgb particle
return null;
}
return null;
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
return null;
}
}), // (11->30) minecraft:dust -> reddust
rewrite(13), // (12->13) minecraft:effect -> spell
rewrite(41), // (13->41) minecraft:elder_guardian -> mobappearance
rewrite(10), // (14->10) minecraft:enchanted_hit -> magicCrit‌
rewrite(25), // (15->25) minecraft:enchant -> enchantmenttable
rewrite(43), // (16->43) minecraft:end_rod -> endRod
rewrite(15), // (17->15) minecraft:entity_effect -> mobSpell
rewrite(2), // (18->2) minecraft:explosion_emitter -> hugeexplosion
rewrite(1), // (19->1) minecraft:explosion -> largeexplode
rewrite(46, blockHandler),
// (20->46) minecraft:falling_dust -> fallingdust
rewrite(3), // (21->3) minecraft:firework -> fireworksSpark
rewrite(6), // (22->6) minecraft:fishing -> wake
rewrite(26), // (23->26) minecraft:flame -> flame
rewrite(21), // (24->21) minecraft:happy_villager -> happyVillager
rewrite(34), // (25->34) minecraft:heart -> heart
rewrite(14), // (26->14) minecraft:instant_effect -> instantSpell
rewrite(36, new ParticleHandler() {
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
return rewrite(protocol, wrapper.read(Type.FLAT_ITEM));
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData<?>> data) {
return null;
}
}), // (11->30) minecraft:dust -> reddust
rewrite(13), // (12->13) minecraft:effect -> spell
rewrite(41), // (13->41) minecraft:elder_guardian -> mobappearance
rewrite(10), // (14->10) minecraft:enchanted_hit -> magicCrit‌
rewrite(25), // (15->25) minecraft:enchant -> enchantmenttable
rewrite(43), // (16->43) minecraft:end_rod -> endRod
rewrite(15), // (17->15) minecraft:entity_effect -> mobSpell
rewrite(2), // (18->2) minecraft:explosion_emitter -> hugeexplosion
rewrite(1), // (19->1) minecraft:explosion -> largeexplode
rewrite(46, blockHandler),
// (20->46) minecraft:falling_dust -> fallingdust
rewrite(3), // (21->3) minecraft:firework -> fireworksSpark
rewrite(6), // (22->6) minecraft:fishing -> wake
rewrite(26), // (23->26) minecraft:flame -> flame
rewrite(21), // (24->21) minecraft:happy_villager -> happyVillager
rewrite(34), // (25->34) minecraft:heart -> heart
rewrite(14), // (26->14) minecraft:instant_effect -> instantSpell
rewrite(36, new ParticleHandler() {
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception {
return rewrite(protocol, wrapper.read(Type.ITEM1_13));
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
return rewrite(protocol, (Item) data.get(0).getValue());
}
@Override
public int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData<?>> data) {
return rewrite(protocol, (Item) data.get(0).getValue());
}
private int[] rewrite(Protocol1_12_2To1_13 protocol, Item newItem) {
Item item = protocol.getItemRewriter().handleItemToClient(newItem);
return new int[]{item.identifier(), item.data()};
}
}), // (27->36) minecraft:item -> iconcrack
rewrite(33), // (28->33) minecraft:item_slime -> slime
rewrite(31), // (29->31) minecraft:item_snowball -> snowballpoof
rewrite(12), // (30->12) minecraft:large_smoke -> largesmoke
rewrite(27), // (31->27) minecraft:lava -> lava
rewrite(22), // (32->22) minecraft:mycelium -> townaura
rewrite(23), // (33->23) minecraft:note -> note
rewrite(0), // (34->0) minecraft:poof -> explode
rewrite(24), // (35->24) minecraft:portal -> portal
rewrite(39), // (36->39) minecraft:rain -> droplet
rewrite(11), // (37->11) minecraft:smoke -> smoke
rewrite(48), // (38->48) minecraft:spit -> spit
rewrite(12), // (39->-1) minecraft:squid_ink -> squid_ink -> large_smoke
rewrite(45), // (40->45) minecraft:sweep_attack -> sweepAttack‌
rewrite(47), // (41->47) minecraft:totem_of_undying -> totem
rewrite(7), // (42->7) minecraft:underwater -> suspended‌
rewrite(5), // (43->5) minecraft:splash -> splash
rewrite(17), // (44->17) minecraft:witch -> witchMagic
rewrite(4), // (45->4) minecraft:bubble_pop -> bubble
rewrite(4), // (46->4) minecraft:current_down -> bubble
rewrite(4), // (47->4) minecraft:bubble_column_up -> bubble
rewrite(18), // (48->-1) minecraft:nautilus -> nautilus -> dripWater
rewrite(18), // (49->18) minecraft:dolphin -> dripWater
private int[] rewrite(Protocol1_12_2To1_13 protocol, Item newItem) {
Item item = protocol.getItemRewriter().handleItemToClient(null, newItem);
return new int[]{item.identifier(), item.data()};
}
}), // (27->36) minecraft:item -> iconcrack
rewrite(33), // (28->33) minecraft:item_slime -> slime
rewrite(31), // (29->31) minecraft:item_snowball -> snowballpoof
rewrite(12), // (30->12) minecraft:large_smoke -> largesmoke
rewrite(27), // (31->27) minecraft:lava -> lava
rewrite(22), // (32->22) minecraft:mycelium -> townaura
rewrite(23), // (33->23) minecraft:note -> note
rewrite(0), // (34->0) minecraft:poof -> explode
rewrite(24), // (35->24) minecraft:portal -> portal
rewrite(39), // (36->39) minecraft:rain -> droplet
rewrite(11), // (37->11) minecraft:smoke -> smoke
rewrite(48), // (38->48) minecraft:spit -> spit
rewrite(12), // (39->-1) minecraft:squid_ink -> squid_ink -> large_smoke
rewrite(45), // (40->45) minecraft:sweep_attack -> sweepAttack‌
rewrite(47), // (41->47) minecraft:totem_of_undying -> totem
rewrite(7), // (42->7) minecraft:underwater -> suspended‌
rewrite(5), // (43->5) minecraft:splash -> splash
rewrite(17), // (44->17) minecraft:witch -> witchMagic
rewrite(4), // (45->4) minecraft:bubble_pop -> bubble
rewrite(4), // (46->4) minecraft:current_down -> bubble
rewrite(4), // (47->4) minecraft:bubble_column_up -> bubble
rewrite(18), // (48->-1) minecraft:nautilus -> nautilus -> dripWater
rewrite(18), // (49->18) minecraft:dolphin -> dripWater
};
}
@@ -162,7 +162,7 @@ public class ParticleMapping {
int[] rewrite(Protocol1_12_2To1_13 protocol, PacketWrapper wrapper) throws Exception;
int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data);
int[] rewrite(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData<?>> data);
default boolean isBlockHandler() {
return false;
@@ -187,7 +187,7 @@ public class ParticleMapping {
return handler.rewrite(protocol, wrapper);
}
public int[] rewriteMeta(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData> data) {
public int[] rewriteMeta(Protocol1_12_2To1_13 protocol, List<Particle.ParticleData<?>> data) {
if (handler == null) return null;
return handler.rewrite(protocol, data);
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,14 +20,17 @@ package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.packets;
import com.google.common.primitives.Ints;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.api.rewriters.EnchantmentRewriter;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.block_entity_handlers.FlowerPotHandler;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.BackwardsBlockStorage;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.NoteBlockStorage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
@@ -37,25 +40,25 @@ 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.opennbt.conversion.ConverterRegistry;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_13;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ByteTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ShortTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.BlockIdData;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.data.SpawnEggRewriter;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.IdAndData;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -63,28 +66,28 @@ import java.util.Locale;
import java.util.Map;
import java.util.Optional;
public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewriters.ItemRewriter<ClientboundPackets1_13, ServerboundPackets1_12_1, Protocol1_12_2To1_13> {
public class BlockItemPackets1_13 extends BackwardsItemRewriter<ClientboundPackets1_13, ServerboundPackets1_12_1, Protocol1_12_2To1_13> {
private final Map<String, String> enchantmentMappings = new HashMap<>();
private final String extraNbtTag;
public BlockItemPackets1_13(Protocol1_12_2To1_13 protocol) {
super(protocol);
extraNbtTag = "VB|" + protocol.getClass().getSimpleName() + "|2";
super(protocol, null, null);
extraNbtTag = nbtTagName("2");
}
public static boolean isDamageable(int id) {
return id >= 256 && id <= 259 // iron shovel, pickaxe, axe, flint and steel
|| id == 261 // bow
|| id >= 267 && id <= 279 // iron sword, wooden+stone+diamond swords, shovels, pickaxes, axes
|| id >= 283 && id <= 286 // gold sword, shovel, pickaxe, axe
|| id >= 290 && id <= 294 // hoes
|| id >= 298 && id <= 317 // armors
|| id == 346 // fishing rod
|| id == 359 // shears
|| id == 398 // carrot on a stick
|| id == 442 // shield
|| id == 443; // elytra
|| id == 261 // bow
|| id >= 267 && id <= 279 // iron sword, wooden+stone+diamond swords, shovels, pickaxes, axes
|| id >= 283 && id <= 286 // gold sword, shovel, pickaxe, axe
|| id >= 290 && id <= 294 // hoes
|| id >= 298 && id <= 317 // armors
|| id == 346 // fishing rod
|| id == 359 // shears
|| id == 398 // carrot on a stick
|| id == 442 // shield
|| id == 443; // elytra
}
@Override
@@ -98,17 +101,17 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
if (SpawnEggRewriter.getEntityId(oldId).isPresent()) {
wrapper.write(Type.VAR_INT, 383 << 4);
wrapper.write(Type.VAR_INT, IdAndData.toRawData(383));
return;
}
wrapper.write(Type.VAR_INT, oldId >> 4);
wrapper.write(Type.VAR_INT, IdAndData.getId(oldId));
});
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_ACTION, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // Location
map(Type.POSITION1_8); // Location
map(Type.UNSIGNED_BYTE); // Action Id
map(Type.UNSIGNED_BYTE); // Action param
map(Type.VAR_INT); // Block Id - /!\ NOT BLOCK STATE ID
@@ -136,6 +139,17 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
else if (blockId >= 483 && blockId <= 498)
blockId = blockId - 483 + 219;
if (blockId == 25) { // Note block
final NoteBlockStorage noteBlockStorage = wrapper.user().get(NoteBlockStorage.class);
final Position position = wrapper.get(Type.POSITION1_8, 0);
final Pair<Integer, Integer> update = noteBlockStorage.getNoteBlockUpdate(position);
if (update != null) { // Use values from block state update
wrapper.set(Type.UNSIGNED_BYTE, 0, update.key().shortValue());
wrapper.set(Type.UNSIGNED_BYTE, 1, update.value().shortValue());
}
}
wrapper.set(Type.VAR_INT, 0, blockId);
});
}
@@ -144,9 +158,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_ENTITY_DATA, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // 0 - Position
map(Type.POSITION1_8); // 0 - Position
map(Type.UNSIGNED_BYTE); // 1 - Action
map(Type.NBT); // 2 - NBT Data
map(Type.NAMED_COMPOUND_TAG); // 2 - NBT Data
handler(wrapper -> {
BackwardsBlockEntityProvider provider = Via.getManager().getProviders().get(BackwardsBlockEntityProvider.class);
@@ -156,12 +170,12 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
wrapper.cancel();
}
wrapper.set(Type.NBT, 0,
provider.transform(
wrapper.user(),
wrapper.get(Type.POSITION, 0),
wrapper.get(Type.NBT, 0)
));
wrapper.set(Type.NAMED_COMPOUND_TAG, 0,
provider.transform(
wrapper.user(),
wrapper.get(Type.POSITION1_8, 0),
wrapper.get(Type.NAMED_COMPOUND_TAG, 0)
));
});
}
});
@@ -175,7 +189,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
blockStorage.getBlocks().entrySet().removeIf(entry -> {
Position position = entry.getKey();
return position.x() >= chunkMinX && position.z() >= chunkMinZ
&& position.x() <= chunkMaxX && position.z() <= chunkMaxZ;
&& position.x() <= chunkMaxX && position.z() <= chunkMaxZ;
});
});
@@ -183,11 +197,16 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
protocol.registerClientbound(ClientboundPackets1_13.BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION); // 0 - Position
map(Type.POSITION1_8); // 0 - Position
handler(wrapper -> {
int blockState = wrapper.read(Type.VAR_INT);
Position position = wrapper.get(Type.POSITION, 0);
Position position = wrapper.get(Type.POSITION1_8, 0);
// Note block special treatment
if (blockState >= 249 && blockState <= 748) { // Note block states id range
wrapper.user().get(NoteBlockStorage.class).storeNoteBlockUpdate(position, blockState);
}
// Store blocks
BackwardsBlockStorage storage = wrapper.user().get(BackwardsBlockStorage.class);
@@ -216,9 +235,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
int chunkZ = wrapper.get(Type.INT, 1);
int block = record.getBlockId();
Position position = new Position(
record.getSectionX() + (chunkX * 16),
record.getY(),
record.getSectionZ() + (chunkZ * 16));
record.getSectionX() + (chunkX * 16),
record.getY(),
record.getSectionZ() + (chunkZ * 16));
// Store if needed
storage.checkAndStore(position, block);
@@ -237,9 +256,14 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
@Override
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.FLAT_ITEM_ARRAY, Type.ITEM_ARRAY);
map(Type.ITEM1_13_SHORT_ARRAY, Type.ITEM1_8_SHORT_ARRAY);
handler(itemArrayHandler(Type.ITEM_ARRAY));
handler(wrapper -> {
final Item[] items = wrapper.get(Type.ITEM1_8_SHORT_ARRAY, 0);
for (Item item : items) {
handleItemToClient(wrapper.user(), item);
}
});
}
});
@@ -248,32 +272,32 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
public void register() {
map(Type.UNSIGNED_BYTE);
map(Type.SHORT);
map(Type.FLAT_ITEM, Type.ITEM);
map(Type.ITEM1_13, Type.ITEM1_8);
handler(itemToClientHandler(Type.ITEM));
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
}
});
protocol.registerClientbound(ClientboundPackets1_13.CHUNK_DATA, wrapper -> {
ClientWorld clientWorld = wrapper.user().get(ClientWorld.class);
Chunk1_9_3_4Type type_old = new Chunk1_9_3_4Type(clientWorld);
Chunk1_13Type type = new Chunk1_13Type(clientWorld);
ChunkType1_9_3 type_old = ChunkType1_9_3.forEnvironment(clientWorld.getEnvironment());
ChunkType1_13 type = ChunkType1_13.forEnvironment(clientWorld.getEnvironment());
Chunk chunk = wrapper.read(type);
// Handle Block Entities before block rewrite
BackwardsBlockEntityProvider provider = Via.getManager().getProviders().get(BackwardsBlockEntityProvider.class);
BackwardsBlockStorage storage = wrapper.user().get(BackwardsBlockStorage.class);
for (CompoundTag tag : chunk.getBlockEntities()) {
Tag idTag = tag.get("id");
StringTag idTag = tag.getStringTag("id");
if (idTag == null) continue;
String id = (String) idTag.getValue();
String id = idTag.getValue();
// Ignore if we don't handle it
if (!provider.isHandled(id)) continue;
int sectionIndex = ((NumberTag) tag.get("y")).asInt() >> 4;
int sectionIndex = tag.getNumberTag("y").asInt() >> 4;
if (sectionIndex < 0 || sectionIndex > 15) {
// 1.17 chunks
continue;
@@ -281,9 +305,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
ChunkSection section = chunk.getSections()[sectionIndex];
int x = ((NumberTag) tag.get("x")).asInt();
int y = ((NumberTag) tag.get("y")).asInt();
int z = ((NumberTag) tag.get("z")).asInt();
int x = tag.getNumberTag("x").asInt();
int y = tag.getNumberTag("y").asInt();
int z = tag.getNumberTag("z").asInt();
Position position = new Position(x, (short) y, z);
int block = section.palette(PaletteType.BLOCKS).idAt(x & 0xF, y & 0xF, z & 0xF);
@@ -309,9 +333,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
// Check if the block is a flower
if (FlowerPotHandler.isFlowah(block)) {
Position pos = new Position(
(x + (chunk.getX() << 4)),
(short) (y + (i << 4)),
(z + (chunk.getZ() << 4))
(x + (chunk.getX() << 4)),
(short) (y + (i << 4)),
(z + (chunk.getZ() << 4))
);
// Store block
storage.checkAndStore(pos, block);
@@ -370,7 +394,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
@Override
public void register() {
map(Type.INT); // Effect Id
map(Type.POSITION); // Location
map(Type.POSITION1_8); // Location
map(Type.INT); // Data
handler(wrapper -> {
int id = wrapper.get(Type.INT, 0);
@@ -400,9 +424,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
byte x = wrapper.read(Type.BYTE);
byte z = wrapper.read(Type.BYTE);
byte direction = wrapper.read(Type.BYTE);
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.COMPONENT);
}
wrapper.read(Type.OPTIONAL_COMPONENT);
if (type > 9) {
wrapper.set(Type.VAR_INT, 1, wrapper.get(Type.VAR_INT, 1) - 1);
continue;
@@ -420,9 +442,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
public void register() {
map(Type.VAR_INT);
map(Type.VAR_INT);
map(Type.FLAT_ITEM, Type.ITEM);
map(Type.ITEM1_13, Type.ITEM1_8);
handler(itemToClientHandler(Type.ITEM));
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
}
});
@@ -448,9 +470,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
@Override
public void register() {
map(Type.SHORT);
map(Type.ITEM, Type.FLAT_ITEM);
map(Type.ITEM1_8, Type.ITEM1_13);
handler(itemToServerHandler(Type.FLAT_ITEM));
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Type.ITEM1_13, 0)));
}
});
@@ -462,9 +484,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
map(Type.BYTE);
map(Type.SHORT);
map(Type.VAR_INT);
map(Type.ITEM, Type.FLAT_ITEM);
map(Type.ITEM1_8, Type.ITEM1_13);
handler(itemToServerHandler(Type.FLAT_ITEM));
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Type.ITEM1_13, 0)));
}
});
}
@@ -478,7 +500,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
@Override
public Item handleItemToClient(Item item) {
public Item handleItemToClient(UserConnection connection, Item item) {
if (item == null) return null;
// Custom mappings/super call moved down
@@ -491,14 +513,14 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
// Use tag to get original ID and data
Tag originalIdTag;
if (tag != null && (originalIdTag = tag.remove(extraNbtTag)) != null) {
if (tag != null && (originalIdTag = tag.remove(extraNbtTag)) instanceof NumberTag) {
rawId = ((NumberTag) originalIdTag).asInt();
gotRawIdFromTag = true;
}
if (rawId == null) {
// Look for custom mappings
super.handleItemToClient(item);
super.handleItemToClient(connection, item);
// Handle one-way special case
if (item.identifier() == -1) {
@@ -528,15 +550,15 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
if (tag != null) {
if (isDamageable(item.identifier())) {
Tag damageTag = tag.remove("Damage");
if (!gotRawIdFromTag && damageTag instanceof IntTag) {
item.setData((short) (int) damageTag.getValue());
if (!gotRawIdFromTag && damageTag instanceof NumberTag) {
item.setData(((NumberTag) damageTag).asShort());
}
}
if (item.identifier() == 358) { // map
Tag mapTag = tag.remove("map");
if (!gotRawIdFromTag && mapTag instanceof IntTag) {
item.setData((short) (int) mapTag.getValue());
if (!gotRawIdFromTag && mapTag instanceof NumberTag) {
item.setData(((NumberTag) mapTag).asShort());
}
}
@@ -544,12 +566,12 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
invertShieldAndBannerId(item, tag);
// Display Name now uses JSON
CompoundTag display = tag.get("display");
CompoundTag display = tag.getCompoundTag("display");
if (display != null) {
StringTag name = display.get("Name");
StringTag name = display.getStringTag("Name");
if (name != null) {
display.put(extraNbtTag + "|Name", new StringTag(name.getValue()));
name.setValue(ChatRewriter.jsonToLegacyText(name.getValue()));
display.putString(extraNbtTag + "|Name", name.getValue());
name.setValue(protocol.jsonToLegacy(connection, name.getValue()));
}
}
@@ -571,7 +593,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
if (!tag.contains("EntityTag")) {
CompoundTag entityTag = new CompoundTag();
entityTag.put("id", new StringTag(eggEntityId.get()));
entityTag.putString("id", eggEntityId.get());
tag.put("EntityTag", entityTag);
}
return 0x17f0000; // 383 << 16;
@@ -582,22 +604,21 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
private void rewriteCanPlaceToClient(CompoundTag tag, String tagName) {
// The tag was manually created incorrectly so ignore rewriting it
if (!(tag.get(tagName) instanceof ListTag)) return;
ListTag blockTag = tag.get(tagName);
ListTag<?> blockTag = tag.getListTag(tagName);
if (blockTag == null) return;
ListTag newCanPlaceOn = new ListTag(StringTag.class);
tag.put(extraNbtTag + "|" + tagName, ConverterRegistry.convertToTag(ConverterRegistry.convertToValue(blockTag)));
ListTag<StringTag> newCanPlaceOn = new ListTag<>(StringTag.class);
tag.put(extraNbtTag + "|" + tagName, blockTag.copy());
for (Tag oldTag : blockTag) {
Object value = oldTag.getValue();
String[] newValues = value instanceof String ?
BlockIdData.fallbackReverseMapping.get(((String) value).replace("minecraft:", "")) : null;
BlockIdData.fallbackReverseMapping.get(Key.stripMinecraftNamespace((String) value)) : null;
if (newValues != null) {
for (String newValue : newValues) {
newCanPlaceOn.add(new StringTag(newValue));
}
} else {
newCanPlaceOn.add(oldTag);
newCanPlaceOn.add(new StringTag(oldTag.getValue().toString()));
}
}
tag.put(tagName, newCanPlaceOn);
@@ -606,22 +627,21 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
//TODO un-ugly all of this
private void rewriteEnchantmentsToClient(CompoundTag tag, boolean storedEnch) {
String key = storedEnch ? "StoredEnchantments" : "Enchantments";
ListTag enchantments = tag.get(key);
ListTag<CompoundTag> enchantments = tag.getListTag(key, CompoundTag.class);
if (enchantments == null) return;
ListTag noMapped = new ListTag(CompoundTag.class);
ListTag newEnchantments = new ListTag(CompoundTag.class);
List<Tag> lore = new ArrayList<>();
ListTag<CompoundTag> noMapped = new ListTag<>(CompoundTag.class);
ListTag<CompoundTag> newEnchantments = new ListTag<>(CompoundTag.class);
List<StringTag> lore = new ArrayList<>();
boolean hasValidEnchants = false;
for (Tag enchantmentEntryTag : enchantments.clone()) {
CompoundTag enchantmentEntry = (CompoundTag) enchantmentEntryTag;
Tag idTag = enchantmentEntry.get("id");
if (!(idTag instanceof StringTag)) {
for (CompoundTag enchantmentEntry : enchantments.copy()) {
StringTag idTag = enchantmentEntry.getStringTag("id");
if (idTag == null) {
continue;
}
String newId = (String) idTag.getValue();
NumberTag levelTag = enchantmentEntry.get("lvl");
String newId = idTag.getValue();
NumberTag levelTag = enchantmentEntry.getNumberTag("lvl");
if (levelTag == null) {
continue;
}
@@ -634,7 +654,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
lore.add(new StringTag(mappedEnchantmentId + " " + EnchantmentRewriter.getRomanNumber(level)));
noMapped.add(enchantmentEntry);
} else if (!newId.isEmpty()) {
Short oldId = Protocol1_13To1_12_2.MAPPINGS.getOldEnchantmentsIds().inverse().get(newId);
Short oldId = Protocol1_13To1_12_2.MAPPINGS.getOldEnchantmentsIds().inverse().get(Key.stripMinecraftNamespace(newId));
if (oldId == null) {
if (!newId.startsWith("viaversion:legacy/")) {
// Custom enchant (?)
@@ -666,51 +686,50 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
CompoundTag newEntry = new CompoundTag();
newEntry.put("id", new ShortTag(oldId));
newEntry.put("lvl", new ShortTag(level));
newEntry.putShort("id", oldId);
newEntry.putShort("lvl", level);
newEnchantments.add(newEntry);
}
}
// Put here to hide empty enchantment from 1.14 rewrites
if (!storedEnch && !hasValidEnchants) {
IntTag hideFlags = tag.get("HideFlags");
NumberTag hideFlags = tag.getNumberTag("HideFlags");
if (hideFlags == null) {
hideFlags = new IntTag();
tag.put(extraNbtTag + "|DummyEnchant", new ByteTag());
} else {
tag.put(extraNbtTag + "|OldHideFlags", new IntTag(hideFlags.asByte()));
tag.putInt(extraNbtTag + "|OldHideFlags", hideFlags.asByte());
}
if (newEnchantments.size() == 0) {
if (newEnchantments.isEmpty()) {
CompoundTag enchEntry = new CompoundTag();
enchEntry.put("id", new ShortTag((short) 0));
enchEntry.put("lvl", new ShortTag((short) 0));
enchEntry.putShort("id", (short) 0);
enchEntry.putShort("lvl", (short) 0);
newEnchantments.add(enchEntry);
}
int value = hideFlags.asByte() | 1;
hideFlags.setValue(value);
tag.put("HideFlags", hideFlags);
tag.putInt("HideFlags", value);
}
if (noMapped.size() != 0) {
if (!noMapped.isEmpty()) {
tag.put(extraNbtTag + "|" + key, noMapped);
if (!lore.isEmpty()) {
CompoundTag display = tag.get("display");
CompoundTag display = tag.getCompoundTag("display");
if (display == null) {
tag.put("display", display = new CompoundTag());
}
ListTag loreTag = display.get("Lore");
ListTag<StringTag> loreTag = display.getListTag("Lore", StringTag.class);
if (loreTag == null) {
display.put("Lore", loreTag = new ListTag(StringTag.class));
display.put("Lore", loreTag = new ListTag<>(StringTag.class));
tag.put(extraNbtTag + "|DummyLore", new ByteTag());
} else if (loreTag.size() != 0) {
ListTag oldLore = new ListTag(StringTag.class);
for (Tag value : loreTag) {
oldLore.add(value.clone());
} else if (!loreTag.isEmpty()) {
ListTag<StringTag> oldLore = new ListTag<>(StringTag.class);
for (StringTag value : loreTag) {
oldLore.add(value.copy());
}
tag.put(extraNbtTag + "|OldLore", oldLore);
@@ -726,23 +745,23 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
@Override
public Item handleItemToServer(Item item) {
public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
CompoundTag tag = item.tag();
// Save original id
int originalId = (item.identifier() << 16 | item.data() & 0xFFFF);
int rawId = (item.identifier() << 4 | item.data() & 0xF);
int rawId = IdAndData.toRawData(item.identifier(), item.data());
// NBT Additions
if (isDamageable(item.identifier())) {
if (tag == null) item.setTag(tag = new CompoundTag());
tag.put("Damage", new IntTag(item.data()));
tag.putInt("Damage", item.data());
}
if (item.identifier() == 358) { // map
if (tag == null) item.setTag(tag = new CompoundTag());
tag.put("map", new IntTag(item.data()));
tag.putInt("map", item.data());
}
// NBT Changes
@@ -751,13 +770,12 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
invertShieldAndBannerId(item, tag);
// Display Name now uses JSON
Tag display = tag.get("display");
if (display instanceof CompoundTag) {
CompoundTag displayTag = (CompoundTag) display;
StringTag name = displayTag.get("Name");
CompoundTag display = tag.getCompoundTag("display");
if (display != null) {
StringTag name = display.getStringTag("Name");
if (name != null) {
StringTag via = displayTag.remove(extraNbtTag + "|Name");
name.setValue(via != null ? via.getValue() : ChatRewriter.legacyTextToJsonString(name.getValue()));
Tag via = display.remove(extraNbtTag + "|Name");
name.setValue(via instanceof StringTag ? ((StringTag) via).getValue() : ComponentUtil.legacyToJsonString(name.getValue()));
}
}
@@ -770,9 +788,9 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
// Handle SpawnEggs
if (item.identifier() == 383) {
CompoundTag entityTag = tag.get("EntityTag");
CompoundTag entityTag = tag.getCompoundTag("EntityTag");
StringTag identifier;
if (entityTag != null && (identifier = entityTag.get("id")) != null) {
if (entityTag != null && (identifier = entityTag.getStringTag("id")) != null) {
rawId = SpawnEggRewriter.getSpawnEggId(identifier.getValue());
if (rawId == -1) {
rawId = 25100288; // Bat fallback
@@ -795,7 +813,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
// Handle custom mappings
int identifier = item.identifier();
item.setIdentifier(rawId);
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
// Mapped with original data, we can return here
if (item.identifier() != rawId && item.identifier() != -1) return item;
@@ -806,14 +824,16 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
int newId = -1;
if (protocol.getMappingData().getItemMappings().inverse().getNewId(rawId) == -1) {
if (!isDamageable(item.identifier()) && item.identifier() != 358) { // Map
if (tag == null) item.setTag(tag = new CompoundTag());
tag.put(extraNbtTag, new IntTag(originalId)); // Data will be lost, saving original id
if (tag == null) {
item.setTag(tag = new CompoundTag());
}
tag.putInt(extraNbtTag, originalId); // Data will be lost, saving original id
}
if (item.identifier() == 229) { // purple shulker box
newId = 362; // directly set the new id -> base/colorless shulker box
} else if (item.identifier() == 31 && item.data() == 0) { // Shrub was removed
rawId = 32 << 4; // Dead Bush
rawId = IdAndData.toRawData(32); // Dead Bush
} else if (protocol.getMappingData().getItemMappings().inverse().getNewId(rawId & ~0xF) != -1) {
rawId &= ~0xF; // Remove data
} else {
@@ -834,15 +854,16 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
private void rewriteCanPlaceToServer(CompoundTag tag, String tagName) {
if (!(tag.get(tagName) instanceof ListTag)) return;
ListTag blockTag = tag.remove(extraNbtTag + "|" + tagName);
if (tag.getListTag(tagName) == null) return;
ListTag<?> blockTag = tag.remove(extraNbtTag + "|" + tagName);
if (blockTag != null) {
tag.put(tagName, ConverterRegistry.convertToTag(ConverterRegistry.convertToValue(blockTag)));
} else if ((blockTag = tag.get(tagName)) != null) {
ListTag newCanPlaceOn = new ListTag(StringTag.class);
tag.put(tagName, blockTag.copy());
} else if ((blockTag = tag.getListTag(tagName)) != null) {
ListTag<StringTag> newCanPlaceOn = new ListTag<>(StringTag.class);
for (Tag oldTag : blockTag) {
Object value = oldTag.getValue();
String oldId = value.toString().replace("minecraft:", "");
String oldId = Key.stripMinecraftNamespace(value.toString());
int key = Ints.tryParse(oldId);
String numberConverted = BlockIdData.numberIdToString.get(key);
if (numberConverted != null) {
@@ -865,15 +886,15 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
private void rewriteEnchantmentsToServer(CompoundTag tag, boolean storedEnch) {
String key = storedEnch ? "StoredEnchantments" : "Enchantments";
ListTag enchantments = tag.get(storedEnch ? key : "ench");
ListTag<CompoundTag> enchantments = tag.getListTag(storedEnch ? key : "ench", CompoundTag.class);
if (enchantments == null) return;
ListTag newEnchantments = new ListTag(CompoundTag.class);
ListTag<CompoundTag> newEnchantments = new ListTag<>(CompoundTag.class);
boolean dummyEnchant = false;
if (!storedEnch) {
IntTag hideFlags = tag.remove(extraNbtTag + "|OldHideFlags");
if (hideFlags != null) {
tag.put("HideFlags", new IntTag(hideFlags.asByte()));
Tag hideFlags = tag.remove(extraNbtTag + "|OldHideFlags");
if (hideFlags instanceof IntTag) {
tag.putInt("HideFlags", ((NumberTag) hideFlags).asByte());
dummyEnchant = true;
} else if (tag.remove(extraNbtTag + "|DummyEnchant") != null) {
tag.remove("HideFlags");
@@ -881,43 +902,48 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
}
for (Tag enchEntry : enchantments) {
for (CompoundTag entryTag : enchantments) {
NumberTag idTag = entryTag.getNumberTag("id");
NumberTag levelTag = entryTag.getNumberTag("lvl");
CompoundTag enchantmentEntry = new CompoundTag();
short oldId = ((NumberTag) ((CompoundTag) enchEntry).get("id")).asShort();
short level = ((NumberTag) ((CompoundTag) enchEntry).get("lvl")).asShort();
short oldId = idTag != null ? idTag.asShort() : 0;
short level = levelTag != null ? levelTag.asShort() : 0;
if (dummyEnchant && oldId == 0 && level == 0) {
continue; //Skip dummy enchatment
continue; // Skip dummy enchatment
}
String newId = Protocol1_13To1_12_2.MAPPINGS.getOldEnchantmentsIds().get(oldId);
if (newId == null) {
newId = "viaversion:legacy/" + oldId;
}
enchantmentEntry.put("id", new StringTag(newId));
enchantmentEntry.putString("id", newId);
enchantmentEntry.put("lvl", new ShortTag(level));
enchantmentEntry.putShort("lvl", level);
newEnchantments.add(enchantmentEntry);
}
ListTag noMapped = tag.remove(extraNbtTag + "|Enchantments");
ListTag<CompoundTag> noMapped = tag.getListTag(extraNbtTag + "|Enchantments", CompoundTag.class);
if (noMapped != null) {
for (Tag value : noMapped) {
for (CompoundTag value : noMapped) {
newEnchantments.add(value);
}
tag.remove(extraNbtTag + "|Enchantments");
}
CompoundTag display = tag.get("display");
CompoundTag display = tag.getCompoundTag("display");
if (display == null) {
tag.put("display", display = new CompoundTag());
}
ListTag oldLore = tag.remove(extraNbtTag + "|OldLore");
ListTag<StringTag> oldLore = tag.getListTag(extraNbtTag + "|OldLore", StringTag.class);
if (oldLore != null) {
ListTag lore = display.get("Lore");
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
if (lore == null) {
tag.put("Lore", lore = new ListTag());
tag.put("Lore", lore = new ListTag<>(StringTag.class));
}
lore.setValue(oldLore.getValue());
tag.remove(extraNbtTag + "|OldLore");
} else if (tag.remove(extraNbtTag + "|DummyLore") != null) {
display.remove("Lore");
if (display.isEmpty()) {
@@ -934,24 +960,19 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
private void invertShieldAndBannerId(Item item, CompoundTag tag) {
if (item.identifier() != 442 && item.identifier() != 425) return;
Tag blockEntityTag = tag.get("BlockEntityTag");
if (!(blockEntityTag instanceof CompoundTag)) return;
CompoundTag blockEntityTag = tag.getCompoundTag("BlockEntityTag");
if (blockEntityTag == null) return;
CompoundTag blockEntityCompoundTag = (CompoundTag) blockEntityTag;
Tag base = blockEntityCompoundTag.get("Base");
if (base instanceof IntTag) {
IntTag baseTag = (IntTag) base;
baseTag.setValue(15 - baseTag.asInt()); // invert color id
NumberTag base = blockEntityTag.getNumberTag("Base");
if (base != null) {
blockEntityTag.putInt("Base", 15 - base.asInt()); // Invert color id
}
Tag patterns = blockEntityCompoundTag.get("Patterns");
if (patterns instanceof ListTag) {
ListTag patternsTag = (ListTag) patterns;
for (Tag pattern : patternsTag) {
if (!(pattern instanceof CompoundTag)) continue;
IntTag colorTag = ((CompoundTag) pattern).get("Color");
colorTag.setValue(15 - colorTag.asInt()); // Invert color id
ListTag<CompoundTag> patterns = blockEntityTag.getListTag("Patterns", CompoundTag.class);
if (patterns != null) {
for (CompoundTag pattern : patterns) {
NumberTag colorTag = pattern.getNumberTag("Color");
pattern.putInt("Color", 15 - colorTag.asInt()); // Invert color id
}
}
}
@@ -965,21 +986,21 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
// Remove the flowerpot
PacketWrapper blockUpdateRemove = PacketWrapper.create(ClientboundPackets1_12_1.BLOCK_CHANGE, user);
blockUpdateRemove.write(Type.POSITION, position);
blockUpdateRemove.write(Type.POSITION1_8, position);
blockUpdateRemove.write(Type.VAR_INT, 0);
blockUpdateRemove.scheduleSend(Protocol1_12_2To1_13.class);
// Create the flowerpot
PacketWrapper blockCreate = PacketWrapper.create(ClientboundPackets1_12_1.BLOCK_CHANGE, user);
blockCreate.write(Type.POSITION, position);
blockCreate.write(Type.POSITION1_8, position);
blockCreate.write(Type.VAR_INT, Protocol1_12_2To1_13.MAPPINGS.getNewBlockStateId(blockState));
blockCreate.scheduleSend(Protocol1_12_2To1_13.class);
// Send a block entity update
PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_12_1.BLOCK_ENTITY_DATA, user);
wrapper.write(Type.POSITION, position);
wrapper.write(Type.POSITION1_8, position);
wrapper.write(Type.UNSIGNED_BYTE, (short) 5);
wrapper.write(Type.NBT, nbt);
wrapper.write(Type.NAMED_COMPOUND_TAG, nbt);
wrapper.scheduleSend(Protocol1_12_2To1_13.class);
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -25,21 +25,22 @@ import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.data.EntityType
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.data.PaintingMapping;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.data.ParticleMapping;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.BackwardsBlockStorage;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.NoteBlockStorage;
import com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage.PlayerPositionStorage1_13;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_13Types;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_13;
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_12;
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.Particle;
import com.viaversion.viaversion.api.type.types.version.Types1_12;
import com.viaversion.viaversion.api.type.types.version.Types1_13;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import java.util.Optional;
@@ -88,16 +89,16 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
handler(getObjectTrackerHandler());
handler(wrapper -> {
Optional<Entity1_13Types.ObjectType> optionalType = Entity1_13Types.ObjectType.findById(wrapper.get(Type.BYTE, 0));
Optional<EntityTypes1_13.ObjectType> optionalType = EntityTypes1_13.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (!optionalType.isPresent()) return;
Entity1_13Types.ObjectType type = optionalType.get();
if (type == Entity1_13Types.ObjectType.FALLING_BLOCK) {
EntityTypes1_13.ObjectType type = optionalType.get();
if (type == EntityTypes1_13.ObjectType.FALLING_BLOCK) {
int blockState = wrapper.get(Type.INT, 0);
int combined = Protocol1_12_2To1_13.MAPPINGS.getNewBlockStateId(blockState);
combined = ((combined >> 4) & 0xFFF) | ((combined & 0xF) << 12);
wrapper.set(Type.INT, 0, combined);
} else if (type == Entity1_13Types.ObjectType.ITEM_FRAME) {
} else if (type == EntityTypes1_13.ObjectType.ITEM_FRAME) {
int data = wrapper.get(Type.INT, 0);
switch (data) {
case 3:
@@ -111,15 +112,15 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
break;
}
wrapper.set(Type.INT, 0, data);
} else if (type == Entity1_13Types.ObjectType.TRIDENT) {
wrapper.set(Type.BYTE, 0, (byte) Entity1_13Types.ObjectType.TIPPED_ARROW.getId());
} else if (type == EntityTypes1_13.ObjectType.TRIDENT) {
wrapper.set(Type.BYTE, 0, (byte) EntityTypes1_13.ObjectType.TIPPED_ARROW.getId());
}
});
}
});
registerTracker(ClientboundPackets1_13.SPAWN_EXPERIENCE_ORB, Entity1_13Types.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_13.SPAWN_GLOBAL_ENTITY, Entity1_13Types.EntityType.LIGHTNING_BOLT);
registerTracker(ClientboundPackets1_13.SPAWN_EXPERIENCE_ORB, EntityTypes1_13.EntityType.EXPERIENCE_ORB);
registerTracker(ClientboundPackets1_13.SPAWN_GLOBAL_ENTITY, EntityTypes1_13.EntityType.LIGHTNING_BOLT);
protocol.registerClientbound(ClientboundPackets1_13.SPAWN_MOB, new PacketHandlers() {
@Override
@@ -140,7 +141,7 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
handler(wrapper -> {
int type = wrapper.get(Type.VAR_INT, 1);
EntityType entityType = Entity1_13Types.getTypeFromId(type, false);
EntityType entityType = EntityTypes1_13.getTypeFromId(type, false);
tracker(wrapper.user()).addEntity(wrapper.get(Type.VAR_INT, 0), entityType);
int oldId = EntityTypeMapping.getOldId(type);
@@ -154,7 +155,7 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Rewrite entity type / metadata
handler(getMobSpawnRewriter(Types1_12.METADATA_LIST));
handler(getMobSpawnRewriter1_11(Types1_12.METADATA_LIST));
}
});
@@ -170,7 +171,7 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
map(Type.BYTE);
map(Types1_13.METADATA_LIST, Types1_12.METADATA_LIST);
handler(getTrackerAndMetaHandler(Types1_12.METADATA_LIST, Entity1_13Types.EntityType.PLAYER));
handler(getTrackerAndMetaHandler(Types1_12.METADATA_LIST, EntityTypes1_13.EntityType.PLAYER));
}
});
@@ -180,7 +181,7 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
map(Type.VAR_INT);
map(Type.UUID);
handler(getTrackerHandler(Entity1_13Types.EntityType.PAINTING, Type.VAR_INT));
handler(getTrackerHandler(EntityTypes1_13.EntityType.PAINTING, Type.VAR_INT));
handler(wrapper -> {
int motive = wrapper.read(Type.VAR_INT);
String title = PaintingMapping.getStringId(motive);
@@ -189,7 +190,7 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
}
});
registerJoinGame(ClientboundPackets1_13.JOIN_GAME, Entity1_13Types.EntityType.PLAYER);
registerJoinGame(ClientboundPackets1_13.JOIN_GAME, EntityTypes1_13.EntityType.PLAYER);
protocol.registerClientbound(ClientboundPackets1_13.RESPAWN, new PacketHandlers() {
@Override
@@ -197,7 +198,10 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
map(Type.INT); // 0 - Dimension ID
handler(getDimensionHandler(0));
handler(wrapper -> wrapper.user().get(BackwardsBlockStorage.class).clear());
handler(wrapper -> {
wrapper.user().get(BackwardsBlockStorage.class).clear();
wrapper.user().get(NoteBlockStorage.class).clear();
});
}
});
@@ -227,8 +231,8 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
//TODO properly cache and calculate head position?
EntityPositionHandler.writeFacingDegrees(positionAndLook, positionStorage.getX(),
anchor == 1 ? positionStorage.getY() + 1.62 : positionStorage.getY(),
positionStorage.getZ(), x, y, z);
anchor == 1 ? positionStorage.getY() + 1.62 : positionStorage.getY(),
positionStorage.getZ(), x, y, z);
positionAndLook.write(Type.BYTE, (byte) 7); // bitfield, 0=absolute, 1=relative - x,y,z relative, yaw,pitch absolute
positionAndLook.write(Type.VAR_INT, -1);
@@ -254,97 +258,82 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
protected void registerRewrites() {
// Rewrite new Entity 'drowned'
mapEntityTypeWithData(Entity1_13Types.EntityType.DROWNED, Entity1_13Types.EntityType.ZOMBIE_VILLAGER).plainName();
mapEntityTypeWithData(EntityTypes1_13.EntityType.DROWNED, EntityTypes1_13.EntityType.ZOMBIE_VILLAGER).plainName();
// Fishy
mapEntityTypeWithData(Entity1_13Types.EntityType.COD, Entity1_13Types.EntityType.SQUID).plainName();
mapEntityTypeWithData(Entity1_13Types.EntityType.SALMON, Entity1_13Types.EntityType.SQUID).plainName();
mapEntityTypeWithData(Entity1_13Types.EntityType.PUFFERFISH, Entity1_13Types.EntityType.SQUID).plainName();
mapEntityTypeWithData(Entity1_13Types.EntityType.TROPICAL_FISH, Entity1_13Types.EntityType.SQUID).plainName();
mapEntityTypeWithData(EntityTypes1_13.EntityType.COD, EntityTypes1_13.EntityType.SQUID).plainName();
mapEntityTypeWithData(EntityTypes1_13.EntityType.SALMON, EntityTypes1_13.EntityType.SQUID).plainName();
mapEntityTypeWithData(EntityTypes1_13.EntityType.PUFFERFISH, EntityTypes1_13.EntityType.SQUID).plainName();
mapEntityTypeWithData(EntityTypes1_13.EntityType.TROPICAL_FISH, EntityTypes1_13.EntityType.SQUID).plainName();
// Phantom
mapEntityTypeWithData(Entity1_13Types.EntityType.PHANTOM, Entity1_13Types.EntityType.PARROT).plainName().spawnMetadata(storage -> {
mapEntityTypeWithData(EntityTypes1_13.EntityType.PHANTOM, EntityTypes1_13.EntityType.PARROT).plainName().spawnMetadata(storage -> {
// The phantom is grey/blue so let's do yellow/blue
storage.add(new Metadata(15, MetaType1_12.VarInt, 3));
});
// Dolphin
mapEntityTypeWithData(Entity1_13Types.EntityType.DOLPHIN, Entity1_13Types.EntityType.SQUID).plainName();
mapEntityTypeWithData(EntityTypes1_13.EntityType.DOLPHIN, EntityTypes1_13.EntityType.SQUID).plainName();
// Turtle
mapEntityTypeWithData(Entity1_13Types.EntityType.TURTLE, Entity1_13Types.EntityType.OCELOT).plainName();
mapEntityTypeWithData(EntityTypes1_13.EntityType.TURTLE, EntityTypes1_13.EntityType.OCELOT).plainName();
// Rewrite Meta types
filter().handler((event, meta) -> {
int typeId = meta.metaType().typeId();
// Rewrite optional chat to string
if (typeId == 5) {
// Json -> Legacy is done below
meta.setTypeAndValue(MetaType1_12.String, meta.getValue() != null ? meta.getValue().toString() : "");
}
// Rewrite items
else if (typeId == 6) {
if (typeId == 4) {
JsonElement element = meta.value();
protocol.translatableRewriter().processText(event.user(), element);
meta.setMetaType(MetaType1_12.Chat);
} else if (typeId == 5) {
// Rewrite optional chat to string
JsonElement element = meta.value();
meta.setTypeAndValue(MetaType1_12.String, protocol.jsonToLegacy(event.user(), element));
} else if (typeId == 6) {
Item item = (Item) meta.getValue();
meta.setTypeAndValue(MetaType1_12.Slot, protocol.getItemRewriter().handleItemToClient(item));
}
// Discontinue particles
else if (typeId == 15) {
meta.setTypeAndValue(MetaType1_12.Slot, protocol.getItemRewriter().handleItemToClient(event.user(), item));
} else if (typeId == 15) {
// Discontinue particles
event.cancel();
}
// Rewrite to 1.12 ids
else if (typeId > 5) {
meta.setMetaType(MetaType1_12.byId(
typeId - 1
));
}
});
// Rewrite Custom Name from Chat to String
filter().filterFamily(Entity1_13Types.EntityType.ENTITY).index(2).handler((event, meta) -> {
String value = meta.getValue().toString();
if (!value.isEmpty()) {
meta.setValue(ChatRewriter.jsonToLegacyText(value));
} else {
meta.setMetaType(MetaType1_12.byId(typeId > 5 ? typeId - 1 : typeId));
}
});
// Handle zombie metadata
filter().filterFamily(Entity1_13Types.EntityType.ZOMBIE).removeIndex(15);
filter().type(EntityTypes1_13.EntityType.ZOMBIE).removeIndex(15);
// Handle turtle metadata (Remove them all for now)
filter().type(Entity1_13Types.EntityType.TURTLE).cancel(13); // Home pos
filter().type(Entity1_13Types.EntityType.TURTLE).cancel(14); // Has egg
filter().type(Entity1_13Types.EntityType.TURTLE).cancel(15); // Laying egg
filter().type(Entity1_13Types.EntityType.TURTLE).cancel(16); // Travel pos
filter().type(Entity1_13Types.EntityType.TURTLE).cancel(17); // Going home
filter().type(Entity1_13Types.EntityType.TURTLE).cancel(18); // Traveling
filter().type(EntityTypes1_13.EntityType.TURTLE).cancel(13); // Home pos
filter().type(EntityTypes1_13.EntityType.TURTLE).cancel(14); // Has egg
filter().type(EntityTypes1_13.EntityType.TURTLE).cancel(15); // Laying egg
filter().type(EntityTypes1_13.EntityType.TURTLE).cancel(16); // Travel pos
filter().type(EntityTypes1_13.EntityType.TURTLE).cancel(17); // Going home
filter().type(EntityTypes1_13.EntityType.TURTLE).cancel(18); // Traveling
// Remove additional fish meta
filter().filterFamily(Entity1_13Types.EntityType.ABSTRACT_FISHES).cancel(12);
filter().filterFamily(Entity1_13Types.EntityType.ABSTRACT_FISHES).cancel(13);
filter().type(EntityTypes1_13.EntityType.ABSTRACT_FISHES).cancel(12);
filter().type(EntityTypes1_13.EntityType.ABSTRACT_FISHES).cancel(13);
// Remove phantom size
filter().type(Entity1_13Types.EntityType.PHANTOM).cancel(12);
filter().type(EntityTypes1_13.EntityType.PHANTOM).cancel(12);
// Remove boat splash timer
filter().type(Entity1_13Types.EntityType.BOAT).cancel(12);
filter().type(EntityTypes1_13.EntityType.BOAT).cancel(12);
// Remove Trident special loyalty level
filter().type(Entity1_13Types.EntityType.TRIDENT).cancel(7);
filter().type(EntityTypes1_13.EntityType.TRIDENT).cancel(7);
// Handle new wolf colors
filter().type(Entity1_13Types.EntityType.WOLF).index(17).handler((event, meta) -> {
filter().type(EntityTypes1_13.EntityType.WOLF).index(17).handler((event, meta) -> {
meta.setValue(15 - (int) meta.getValue());
});
// Rewrite AreaEffectCloud
filter().type(Entity1_13Types.EntityType.AREA_EFFECT_CLOUD).index(9).handler((event, meta) -> {
filter().type(EntityTypes1_13.EntityType.AREA_EFFECT_CLOUD).index(9).handler((event, meta) -> {
Particle particle = (Particle) meta.getValue();
ParticleMapping.ParticleData data = ParticleMapping.getMapping(particle.getId());
ParticleMapping.ParticleData data = ParticleMapping.getMapping(particle.id());
int firstArg = 0;
int secondArg = 0;
@@ -369,12 +358,12 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
public EntityType typeFromId(int typeId) {
return Entity1_13Types.getTypeFromId(typeId, false);
return EntityTypes1_13.getTypeFromId(typeId, false);
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
return Entity1_13Types.getTypeFromId(typeId, true);
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_13.getTypeFromId(typeId, true);
}
@Override
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -28,21 +28,23 @@ import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.rewriter.RewriterBase;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.util.Key;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
@@ -57,17 +59,15 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
@Override
protected void registerPackets() {
// Login Plugin Request
protocol.registerClientbound(State.LOGIN, 0x04, -1, new PacketHandlers() {
protocol.registerClientbound(State.LOGIN, ClientboundLoginPackets.CUSTOM_QUERY.getId(), -1, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
packetWrapper.cancel();
packetWrapper.create(0x02, new PacketHandler() { // Plugin response
@Override
public void handle(PacketWrapper newWrapper) throws Exception {
newWrapper.write(Type.VAR_INT, packetWrapper.read(Type.VAR_INT)); // Packet id
newWrapper.write(Type.BOOLEAN, false); // Success
}
// Plugin response
packetWrapper.create(ServerboundLoginPackets.CUSTOM_QUERY_ANSWER.getId(), wrapper -> {
wrapper.write(Type.VAR_INT, packetWrapper.read(Type.VAR_INT)); // Packet id
wrapper.write(Type.BOOLEAN, false); // Success
}).sendToServer(Protocol1_12_2To1_13.class);
});
}
@@ -82,17 +82,17 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
//Input Item
Item input = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, protocol.getItemRewriter().handleItemToClient(input));
Item input = wrapper.read(Type.ITEM1_13);
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(wrapper.user(), input));
//Output Item
Item output = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, protocol.getItemRewriter().handleItemToClient(output));
Item output = wrapper.read(Type.ITEM1_13);
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(wrapper.user(), output));
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); //Has second item
if (secondItem) {
//Second Item
Item second = wrapper.read(Type.FLAT_ITEM);
wrapper.write(Type.ITEM, protocol.getItemRewriter().handleItemToClient(second));
Item second = wrapper.read(Type.ITEM1_13);
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(wrapper.user(), second));
}
wrapper.passthrough(Type.BOOLEAN); //Trade disabled
@@ -103,7 +103,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
String oldChannel = InventoryPackets.getOldPluginChannelId(channel);
if (oldChannel == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring outgoing plugin message with channel: " + channel);
ViaBackwards.getPlatform().getLogger().warning("Ignoring clientbound plugin message with channel: " + channel);
}
wrapper.cancel();
return;
@@ -118,7 +118,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
if (rewritten != null) {
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in outgoing REGISTER: " + s);
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in clientbound " + oldChannel + ": " + s);
}
}
wrapper.write(Type.REMAINING_BYTES, Joiner.on('\0').join(rewrittenChannels).getBytes(StandardCharsets.UTF_8));
@@ -202,13 +202,9 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
handler(wrapper -> {
byte mode = wrapper.get(Type.BYTE, 0);
if (mode == 0 || mode == 2) {
String value = wrapper.read(Type.COMPONENT).toString();
value = ChatRewriter.jsonToLegacyText(value);
if (value.length() > 32) {
value = value.substring(0, 32);
}
wrapper.write(Type.STRING, value);
JsonElement value = wrapper.read(Type.COMPONENT);
String legacyValue = protocol.jsonToLegacy(wrapper.user(), value);
wrapper.write(Type.STRING, ChatUtil.fromLegacy(legacyValue, 'f', 32));
int type = wrapper.read(Type.VAR_INT);
wrapper.write(Type.STRING, type == 1 ? "hearts" : "integer");
}
@@ -225,12 +221,8 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
byte action = wrapper.get(Type.BYTE, 0);
if (action == 0 || action == 2) {
JsonElement displayName = wrapper.read(Type.COMPONENT);
String legacyTextDisplayName = displayName == null || displayName.isJsonNull() ? "" : ChatRewriter.jsonToLegacyText(displayName.toString());
legacyTextDisplayName = ChatUtil.removeUnusedColor(legacyTextDisplayName, 'f');
if (legacyTextDisplayName.length() > 32) {
legacyTextDisplayName = legacyTextDisplayName.substring(0, 32);
}
wrapper.write(Type.STRING, legacyTextDisplayName);
String legacyTextDisplayName = protocol.jsonToLegacy(wrapper.user(), displayName);
wrapper.write(Type.STRING, ChatUtil.fromLegacy(legacyTextDisplayName, 'f', 32));
byte flags = wrapper.read(Type.BYTE);
String nameTagVisibility = wrapper.read(Type.STRING);
@@ -244,22 +236,14 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
JsonElement prefixComponent = wrapper.read(Type.COMPONENT);
JsonElement suffixComponent = wrapper.read(Type.COMPONENT);
String prefix = prefixComponent == null || prefixComponent.isJsonNull() ? "" : ChatRewriter.jsonToLegacyText(prefixComponent.toString());
String prefix = protocol.jsonToLegacy(wrapper.user(), prefixComponent);
if (ViaBackwards.getConfig().addTeamColorTo1_13Prefix()) {
prefix += "§" + (colour > -1 && colour <= 15 ? Integer.toHexString(colour) : "r");
}
String suffix = protocol.jsonToLegacy(wrapper.user(), suffixComponent);
prefix = ChatUtil.removeUnusedColor(prefix, 'f', true);
if (prefix.length() > 16) prefix = prefix.substring(0, 16);
if (prefix.endsWith("§")) prefix = prefix.substring(0, prefix.length() - 1);
String suffix = suffixComponent == null || suffixComponent.isJsonNull() ? "" : ChatRewriter.jsonToLegacyText(suffixComponent.toString());
suffix = ChatUtil.removeUnusedColor(suffix, '\0'); // Don't remove white coloring
if (suffix.length() > 16) suffix = suffix.substring(0, 16);
if (suffix.endsWith("§")) suffix = suffix.substring(0, suffix.length() - 1);
wrapper.write(Type.STRING, prefix);
wrapper.write(Type.STRING, suffix);
wrapper.write(Type.STRING, ChatUtil.fromLegacyPrefix(prefix, 'f', 16));
wrapper.write(Type.STRING, ChatUtil.fromLegacy(suffix, '\0', 16));
wrapper.write(Type.BYTE, flags);
wrapper.write(Type.STRING, nameTagVisibility);
@@ -336,10 +320,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
for (int i = 0; i < count; i++) {
String match = wrapper.read(Type.STRING);
wrapper.write(Type.STRING, (start == 0 && !storage.isLastAssumeCommand() ? "/" : "") + match);
// Ignore tooltip
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.STRING);
}
wrapper.read(Type.OPTIONAL_COMPONENT); // Remove tooltip
}
});
@@ -349,7 +330,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
String command = wrapper.read(Type.STRING);
boolean assumeCommand = wrapper.read(Type.BOOLEAN);
wrapper.read(Type.OPTIONAL_POSITION);
wrapper.read(Type.OPTIONAL_POSITION1_8);
if (!assumeCommand && !command.startsWith("/")) {
// Complete usernames for non-commands
@@ -399,8 +380,8 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
case "MC|BSign":
case "MC|BEdit":
wrapper.setPacketType(ServerboundPackets1_13.EDIT_BOOK);
Item book = wrapper.read(Type.ITEM);
wrapper.write(Type.FLAT_ITEM, protocol.getItemRewriter().handleItemToServer(book));
Item book = wrapper.read(Type.ITEM1_8);
wrapper.write(Type.ITEM1_13, protocol.getItemRewriter().handleItemToServer(wrapper.user(), book));
boolean signing = channel.equals("MC|BSign");
wrapper.write(Type.BOOLEAN, signing);
break;
@@ -412,7 +393,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
if (type == 0) {
//Information from https://wiki.vg/index.php?title=Plugin_channels&oldid=14089
//The Notchain client only uses this for command block minecarts and uses MC|AutoCmd for blocks, but the Notchian server still accepts it for either.
//Maybe older versions used this and we need to implement this? The issues is that we would have to save the command block types
//Maybe older versions used this and we need to implement this? The issue is that we would have to save the command block types
wrapper.setPacketType(ServerboundPackets1_13.UPDATE_COMMAND_BLOCK);
wrapper.cancel();
ViaBackwards.getPlatform().getLogger().warning("Client send MC|AdvCmd custom payload to update command block, weird!");
@@ -433,7 +414,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
int y = wrapper.read(Type.INT);
int z = wrapper.read(Type.INT);
wrapper.write(Type.POSITION, new Position(x, (short) y, z));
wrapper.write(Type.POSITION1_8, new Position(x, (short) y, z));
wrapper.passthrough(Type.STRING); //Command
@@ -456,7 +437,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
int x = wrapper.read(Type.INT);
int y = wrapper.read(Type.INT);
int z = wrapper.read(Type.INT);
wrapper.write(Type.POSITION, new Position(x, (short) y, z));
wrapper.write(Type.POSITION1_8, new Position(x, (short) y, z));
wrapper.write(Type.VAR_INT, wrapper.read(Type.BYTE) - 1);
String mode = wrapper.read(Type.STRING);
int modeId = mode.equals("SAVE") ? 0 : mode.equals("LOAD") ? 1 : mode.equals("CORNER") ? 2 : 3;
@@ -511,7 +492,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
String newChannel = InventoryPackets.getNewPluginChannelId(channel);
if (newChannel == null) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring incoming plugin message with channel: " + channel);
ViaBackwards.getPlatform().getLogger().warning("Ignoring serverbound plugin message with channel: " + channel);
}
wrapper.cancel();
return;
@@ -526,7 +507,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
if (rewritten != null) {
rewrittenChannels.add(rewritten);
} else if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in incoming REGISTER: " + s);
ViaBackwards.getPlatform().getLogger().warning("Ignoring plugin channel in serverbound " + Key.stripMinecraftNamespace(newChannel).toUpperCase(Locale.ROOT) + ": " + s);
}
}
if (!rewrittenChannels.isEmpty()) {
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -29,9 +29,7 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.platform.providers.Provider;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import java.util.HashMap;
import java.util.Map;
@@ -65,12 +63,12 @@ public class BackwardsBlockEntityProvider implements Provider {
* @param tag The block entity tag
*/
public CompoundTag transform(UserConnection user, Position position, CompoundTag tag) throws Exception {
final Tag idTag = tag.get("id");
if (!(idTag instanceof StringTag)) {
final StringTag idTag = tag.getStringTag("id");
if (idTag == null) {
return tag;
}
String id = (String) idTag.getValue();
String id = idTag.getValue();
BackwardsBlockEntityHandler handler = handlers.get(id);
if (handler == null) {
return tag;
@@ -82,7 +80,7 @@ public class BackwardsBlockEntityProvider implements Provider {
return tag;
}
return handler.transform(user, blockId, tag);
return handler.transform(blockId, tag);
}
/**
@@ -94,15 +92,17 @@ public class BackwardsBlockEntityProvider implements Provider {
*/
public CompoundTag transform(UserConnection user, Position position, String id) throws Exception {
CompoundTag tag = new CompoundTag();
tag.put("id", new StringTag(id));
tag.put("x", new IntTag(Math.toIntExact(position.x())));
tag.put("y", new IntTag(Math.toIntExact(position.y())));
tag.put("z", new IntTag(Math.toIntExact(position.z())));
tag.putString("id", id);
tag.putInt("x", Math.toIntExact(position.x()));
tag.putInt("y", Math.toIntExact(position.y()));
tag.putInt("z", Math.toIntExact(position.z()));
return this.transform(user, position, tag);
}
@FunctionalInterface
public interface BackwardsBlockEntityHandler {
CompoundTag transform(UserConnection user, int blockId, CompoundTag tag);
CompoundTag transform(int blockId, CompoundTag tag);
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -24,6 +24,7 @@ import com.viaversion.viaversion.libs.fastutil.ints.IntOpenHashSet;
import com.viaversion.viaversion.libs.fastutil.ints.IntSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.checkerframework.checker.nullness.qual.Nullable;
public class BackwardsBlockStorage implements StorableObject {
// This BlockStorage is very exclusive (;
@@ -77,11 +78,7 @@ public class BackwardsBlockStorage implements StorableObject {
blocks.put(position, block);
}
public boolean isWelcome(int block) {
return WHITELIST.contains(block);
}
public Integer get(Position position) {
public @Nullable Integer get(Position position) {
return blocks.get(position);
}
@@ -0,0 +1,50 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-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.viabackwards.protocol.protocol1_12_2to1_13.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
import com.viaversion.viaversion.util.Pair;
public class NoteBlockStorage implements StorableObject {
private static final int MAX_NOTE_ID = 24;
private final Object2IntMap<Position> noteBlockUpdates = new Object2IntOpenHashMap<>();
public void storeNoteBlockUpdate(final Position position, final int blockStateId) {
noteBlockUpdates.put(position, blockStateId);
}
public Pair<Integer, Integer> getNoteBlockUpdate(final Position position) {
if (!noteBlockUpdates.containsKey(position)) {
return null;
}
int relativeBlockState = noteBlockUpdates.removeInt(position) - 249;
relativeBlockState = relativeBlockState / 2; // Get rid of powered state
return new Pair<>(relativeBlockState / MAX_NOTE_ID + 1, relativeBlockState % MAX_NOTE_ID + 1);
}
public void clear() {
noteBlockUpdates.clear();
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
@@ -20,7 +20,4 @@ package com.viaversion.viabackwards.protocol.protocol1_12_2to1_13.storage;
import com.viaversion.viabackwards.api.entities.storage.PlayerPositionStorage;
public class PlayerPositionStorage1_13 extends PlayerPositionStorage {
public PlayerPositionStorage1_13() {
}
}
@@ -1,6 +1,6 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2023 ViaVersion and contributors
* Copyright (C) 2016-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
Loaded 100 of 266 files, more files were not shown because too many files have changed in this diff. Show more