Compare commits

..
132 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 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
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 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
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 f6def0c97c 24w05a (mostly) 2024-01-31 18:06:46 +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 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
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
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 62765d03ce Merge remote-tracking branch 'origin/master' into dev 2024-01-04 17:51:18 +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 19ec92c261 Merge remote-tracking branch 'origin/master' into dev 2023-12-26 21:51:03 +01:00
Nassim Jahnke ba725df33e 23w51b 2023-12-18 19:50:25 +01:00
135 changed files with 3420 additions and 1528 deletions

No files matched your search

+4 -1
View File
@@ -10,4 +10,7 @@ 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
ij_java_generate_final_parameters = true
[{*.json,*.yml}]
indent_size = 2
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/wrapper-validation-action@v2
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
+4 -2
View File
@@ -10,8 +10,10 @@ jobs:
if: github.repository_owner == 'ViaVersion'
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: gradle/wrapper-validation-action@v1
- 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:
@@ -23,11 +23,13 @@ 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 org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import org.bukkit.plugin.java.JavaPlugin;
public class BukkitPlugin extends JavaPlugin implements ViaBackwardsPlatform {
@@ -39,26 +41,31 @@ public class BukkitPlugin extends JavaPlugin implements ViaBackwardsPlatform {
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() {
int protocolVersion = Via.getAPI().getServerVersion().highestSupportedVersion();
if (protocolVersion >= ProtocolVersion.v1_17.getVersion()) {
final ProtocolVersion protocolVersion = Via.getAPI().getServerVersion().highestSupportedProtocolVersion();
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_17)) {
new PlayerItemDropListener(this).register();
}
if (protocolVersion >= ProtocolVersion.v1_16.getVersion()) {
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_16)) {
new FireExtinguishListener(this).register();
}
if (protocolVersion >= ProtocolVersion.v1_14.getVersion()) {
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_14)) {
new LecternInteractListener(this).register();
}
if (protocolVersion >= ProtocolVersion.v1_12.getVersion()) {
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());
}
}
@Override
@@ -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);
}
}
+1 -1
View File
@@ -5,7 +5,7 @@ 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,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]
@@ -19,6 +19,7 @@ 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.List;
@@ -87,6 +88,11 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
return getClass().getClassLoader().getResource("assets/viabackwards/config.yml");
}
@Override
public InputStream getDefaultConfigInputStream() {
return getClass().getClassLoader().getResourceAsStream("assets/viabackwards/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> map) {
}
@@ -52,6 +52,7 @@ import com.viaversion.viabackwards.protocol.protocol1_19_3to1_19_4.Protocol1_19_
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;
@@ -67,7 +68,7 @@ import java.util.logging.Logger;
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "4.9.3";
String MINIMUM_VV_VERSION = "4.10.2";
/**
* Initialize ViaBackwards.
@@ -92,7 +93,7 @@ public interface ViaBackwardsPlatform {
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.getVersion(), ProtocolVersion.v1_9_2.getVersion()), ProtocolVersion.v1_9_3.getVersion());
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);
@@ -136,6 +137,7 @@ public interface ViaBackwardsPlatform {
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);
}
/**
@@ -149,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();
}
}
@@ -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);
}
}
@@ -17,6 +17,7 @@
*/
package com.viaversion.viabackwards.api.data;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.util.ComponentUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -24,6 +25,7 @@ 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) {
@@ -33,17 +35,22 @@ public class MappedItem {
public MappedItem(final int id, final String name, @Nullable final Integer customModelData) {
this.id = id;
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;
}
@@ -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,126 +0,0 @@
/*
* 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.libs.gson.JsonIOException;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonSyntaxException;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.libs.opennbt.tag.io.NBTIO;
import com.viaversion.viaversion.libs.opennbt.tag.io.TagReader;
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 {
private static final TagReader<CompoundTag> TAG_READER = NBTIO.reader(CompoundTag.class).named();
public static @Nullable CompoundTag loadNBT(final String name) {
final InputStream resource = getResource(name);
if (resource == null) {
return null;
}
try (final InputStream stream = resource) {
return TAG_READER.read(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 = TAG_READER.read(file.toPath(), 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);
}
}
@@ -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;
@@ -34,15 +35,19 @@ 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, Type<Item> itemType, Type<Item[]> itemArrayType) {
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;
}
@@ -52,7 +57,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
// Handle name and lore components
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");
}
@@ -60,16 +65,11 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
name.setValue(newValue);
}
ListTag lore = display.getListTag("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;
@@ -84,7 +84,7 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
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) {
@@ -92,8 +92,8 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
}
// Save original id, set remapped id
item.tag().putInt(nbtTagName + "|id", 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")) {
@@ -105,19 +105,19 @@ 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) {
Tag originalId = item.tag().remove(nbtTagName + "|id");
Tag originalId = item.tag().remove(nbtTagName("id"));
if (originalId instanceof IntTag) {
item.setIdentifier(((NumberTag) originalId).asInt());
}
@@ -135,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)) {
@@ -147,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(getItemType())); // 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) {
@@ -181,11 +179,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)) {
@@ -193,11 +187,13 @@ public class ItemRewriter<C extends ClientboundPacketType, S extends Serverbound
final Tag description = wrapper.passthrough(Type.TAG);
final TranslatableRewriter<C> translatableRewriter = protocol.getTranslatableRewriter();
if (translatableRewriter != null) {
translatableRewriter.processTag(title);
translatableRewriter.processTag(description);
translatableRewriter.processTag(wrapper.user(), title);
translatableRewriter.processTag(wrapper.user(), description);
}
handleItemToClient(wrapper.passthrough(Type.ITEM1_20_2)); // Icon
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) {
@@ -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));
}
}
@@ -22,8 +22,8 @@ import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Key;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -35,21 +35,21 @@ 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) {
@@ -68,26 +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.getListTag(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();
CompoundTag enchantmentEntry = iterator.next();
StringTag idTag = enchantmentEntry.getStringTag("id");
if (idTag == null) {
continue;
}
String enchantmentId = idTag.getValue();
String enchantmentId = Key.stripMinecraftNamespace(idTag.getValue());
String remappedName = enchantmentMappings.get(enchantmentId);
if (remappedName != null) {
if (!changed) {
@@ -123,9 +126,9 @@ public class EnchantmentRewriter {
tag.put("display", display = new CompoundTag());
}
ListTag loreTag = display.getListTag("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");
@@ -23,10 +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;
@@ -103,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) {
@@ -154,28 +162,6 @@ 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 blockStateType,
@@ -187,7 +173,7 @@ public abstract class EntityRewriterBase<C extends ClientboundPacketType, T exte
filter().handler((event, meta) -> {
MetaType type = meta.metaType();
if (type == itemType) {
protocol.getItemRewriter().handleItemToClient(meta.value());
protocol.getItemRewriter().handleItemToClient(event.user(), meta.value());
} else if (type == blockStateType) {
int data = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
@@ -197,13 +183,44 @@ public abstract class EntityRewriterBase<C extends ClientboundPacketType, T exte
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
} else if (type == particleType) {
rewriteParticle(meta.value());
rewriteParticle(event.user(), meta.value());
} else if (type == optionalComponentType || type == componentType) {
JsonElement text = meta.value();
if (text != null) {
protocol.getTranslatableRewriter().processText(text);
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,113 +0,0 @@
/*
* 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.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 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, Type<Item> itemType, Type<Item[]> itemArrayType, boolean jsonNameFormat) {
super(protocol, itemType, itemArrayType);
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.putString(backupName, 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.copy());
}
displayTag.put(backupName, listTag);
}
}
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 + "|o" + tagName);
if (original instanceof StringTag) {
tag.putString(tagName, ((StringTag) original).getValue());
}
}
protected void restoreListTag(CompoundTag tag, String tagName) {
Tag original = tag.remove(nbtTagName + "|o" + tagName);
if (original instanceof ListTag) {
tag.put(tagName, new ListTag(((ListTag) original).getValue()));
}
}
public String getNbtTagName() {
return nbtTagName;
}
}
@@ -20,16 +20,20 @@ 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;
@@ -38,37 +42,59 @@ import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonPrimitive;
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.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; // Raw id -> mapped data
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()) {
addMapping(dataEntry.getKey(), dataEntry.getValue().getAsJsonObject(), mappings);
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);
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);
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);
}
}
}
private static void addMapping(String key, JsonObject object, Int2ObjectMap<MappedLegacyBlockItem> mappings) {
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 = object.getAsJsonPrimitive("name").getAsString();
JsonPrimitive blockField = object.getAsJsonPrimitive("block");
boolean block = blockField != null && blockField.getAsBoolean();
String name = type != MappedLegacyBlockItem.Type.BLOCK ? object.getAsJsonPrimitive("name").getAsString() : null;
if (key.indexOf('-') == -1) {
int unmappedId;
@@ -77,12 +103,12 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
// Include data
short unmappedData = Short.parseShort(key.substring(dataSeparatorIndex + 1));
unmappedId = Integer.parseInt(key.substring(0, dataSeparatorIndex));
unmappedId = (unmappedId << 4) | (unmappedData & 15);
unmappedId = IdAndData.toRawData(unmappedId, unmappedData);
} else {
unmappedId = Integer.parseInt(key) << 4;
unmappedId = IdAndData.toRawData(Integer.parseInt(key), -1);
}
mappings.put(unmappedId, new MappedLegacyBlockItem(id, data, name, block));
mappings.put(unmappedId, new MappedLegacyBlockItem(id, data, name, type));
return;
}
@@ -92,46 +118,74 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
int to = Integer.parseInt(split[1]);
// Special block color handling
if (name.contains("%color%")) {
if (name != null && name.contains("%color%")) {
for (int i = from; i <= to; i++) {
mappings.put(i << 4, new MappedLegacyBlockItem(id, data, name.replace("%color%", BlockColors.get(i - from)), block));
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, block);
MappedLegacyBlockItem mappedBlockItem = new MappedLegacyBlockItem(id, data, name, type);
for (int i = from; i <= to; i++) {
mappings.put(i << 4, mappedBlockItem);
mappings.put(IdAndData.toRawData(i, -1), mappedBlockItem);
}
}
}
protected LegacyBlockItemRewriter(T protocol) {
super(protocol, Type.ITEM1_8, Type.ITEM1_8_SHORT_ARRAY, false);
replacementData = LEGACY_MAPPINGS.get(protocol.getClass().getSimpleName().split("To")[1].replace("_", "."));
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 = getMappedBlockItem(item.identifier(), item.data());
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().getCompoundTag("display");
if (display == null) {
item.tag().put("display", display = new CompoundTag());
@@ -141,7 +195,7 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
if (nameTag == null) {
nameTag = new StringTag(data.getName());
display.put("Name", nameTag);
display.put(nbtTagName + "|customName", new ByteTag());
display.put(nbtTagName("customName"), new ByteTag());
}
// Handle colors
@@ -153,21 +207,44 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
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 = getMappedBlockItem(blockId, data);
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);
@@ -175,17 +252,17 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
return block;
}
private @Nullable MappedLegacyBlockItem getMappedBlockItem(int id, int data) {
MappedLegacyBlockItem mapping = replacementData.get((id << 4) | (data & 15));
return mapping != null || data == 0 ? mapping : replacementData.get(id << 4);
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());
}
private @Nullable MappedLegacyBlockItem getMappedBlockItem(int rawId) {
MappedLegacyBlockItem mapping = replacementData.get(rawId);
return mapping != null ? mapping : replacementData.get(rawId & ~15);
}
protected void handleChunk(Chunk chunk) {
public void handleChunk(Chunk chunk) {
// Map Block Entities
Map<Pos, CompoundTag> tags = new HashMap<>();
for (CompoundTag tag : chunk.getBlockEntities()) {
@@ -209,7 +286,7 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
int block = section.palette(PaletteType.BLOCKS).idAt(pos.getX(), pos.getY() & 0xF, pos.getZ());
MappedLegacyBlockItem settings = getMappedBlockItem(block);
MappedLegacyBlockItem settings = getMappedBlock(block);
if (settings != null && settings.hasBlockEntityHandler()) {
settings.getBlockEntityHandler().handleOrNewCompoundTag(block, tag);
}
@@ -230,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 = getMappedBlockItem(block);
MappedLegacyBlockItem settings = getMappedBlock(block);
if (settings != null && settings.hasBlockEntityHandler()) {
hasBlockEntityHandler = true;
}
@@ -252,7 +329,7 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
for (int z = 0; z < 16; z++) {
int block = palette.idAt(x, y, z);
MappedLegacyBlockItem settings = getMappedBlockItem(block);
MappedLegacyBlockItem settings = getMappedBlock(block);
if (settings == null || !settings.hasBlockEntityHandler()) continue;
Pos pos = new Pos(x, (y + (i << 4)), z);
@@ -282,6 +359,26 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
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;
@@ -17,6 +17,7 @@
*/
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;
@@ -35,35 +36,61 @@ 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.getListTag(key);
ListTag remappedEnchantments = new ListTag(CompoundTag.class);
List<Tag> lore = new ArrayList<>();
for (Tag enchantmentEntry : enchantments.copy()) {
if (!(enchantmentEntry instanceof CompoundTag)) {
continue;
}
CompoundTag entryTag = (CompoundTag) enchantmentEntry;
NumberTag idTag = entryTag.getNumberTag("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 = idTag.asShort();
String enchantmentName = enchantmentMappings.get(newId);
if (enchantmentName != null) {
enchantments.remove(enchantmentEntry);
NumberTag levelTag = entryTag.getNumberTag("lvl");
NumberTag levelTag = enchantmentEntry.getNumberTag("lvl");
short level = levelTag != null ? levelTag.asShort() : 1;
if (hideLevelForEnchants != null && hideLevelForEnchants.contains(newId)) {
lore.add(new StringTag(enchantmentName));
@@ -74,12 +101,12 @@ public class LegacyEnchantmentRewriter {
}
}
if (!lore.isEmpty()) {
if (!storedEnchant && enchantments.isEmpty()) {
if (this.dummyEnchantment && !storedEnchant && enchantments.isEmpty()) {
CompoundTag dummyEnchantment = new CompoundTag();
dummyEnchantment.putShort("id", (short) 0);
dummyEnchantment.putShort("lvl", (short) 0);
enchantments.add(dummyEnchantment);
enchantments.add(dummyEnchantment);
tag.put(nbtTagName + "|dummyEnchant", new ByteTag());
NumberTag hideFlags = tag.getNumberTag("HideFlags");
@@ -99,9 +126,9 @@ public class LegacyEnchantmentRewriter {
if (display == null) {
tag.put("display", display = new CompoundTag());
}
ListTag loreTag = display.getListTag("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());
@@ -111,21 +138,15 @@ public class LegacyEnchantmentRewriter {
public void rewriteEnchantmentsToServer(CompoundTag tag, boolean storedEnchant) {
String key = storedEnchant ? "StoredEnchantments" : "ench";
ListTag remappedEnchantments = tag.remove(nbtTagName + "|" + key);
ListTag enchantments = tag.getListTag(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.copy()) {
if (!(enchantment instanceof CompoundTag)) {
continue;
}
CompoundTag entryTag = (CompoundTag) enchantment;
NumberTag idTag = entryTag.getNumberTag("id");
NumberTag levelTag = entryTag.getNumberTag("lvl");
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) {
@@ -143,8 +164,9 @@ public class LegacyEnchantmentRewriter {
CompoundTag display = tag.getCompoundTag("display");
// A few null checks just to be safe, though they shouldn't actually be
ListTag lore = display != null ? display.getListTag("Lore") : null;
for (Tag enchantment : remappedEnchantments.copy()) {
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.isEmpty()) {
lore.remove(lore.get(0));
@@ -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;
}
}
@@ -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;
}
}
@@ -19,10 +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.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,7 +37,7 @@ public class TranslatableRewriter<C extends ClientboundPacketType> extends Compo
private final Map<String, String> translatables;
public static void loadTranslatables() {
final JsonObject jsonObject = VBMappingDataLoader.loadFromDataDir("translation-mappings.json");
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);
@@ -67,6 +70,14 @@ public class TranslatableRewriter<C extends ClientboundPacketType> extends Compo
}
}
@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 translatables.get(translationKey);
}
@@ -35,8 +35,8 @@ import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPac
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,7 +55,6 @@ 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());
}
@@ -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;
@@ -27,7 +27,6 @@ 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.EntityTypes1_11;
@@ -38,9 +37,10 @@ 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.StringTag;
import com.viaversion.viaversion.protocols.protocol1_11to1_10.EntityIdRewriter;
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.util.IdAndData;
import java.util.Arrays;
import java.util.Optional;
@@ -49,11 +49,14 @@ 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() {
@@ -61,7 +64,7 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
map(Type.SHORT); // 1 - Slot ID
map(Type.ITEM1_8); // 2 - Slot Value
handler(itemToClientHandler(Type.ITEM1_8));
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
// Handle Llama
handler(wrapper -> {
@@ -87,7 +90,7 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
handler(wrapper -> {
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());
@@ -120,12 +123,12 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // Input Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // 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.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // Second Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Second Item
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
@@ -147,7 +150,7 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
map(Type.VAR_INT); // 4 - Mode
map(Type.ITEM1_8); // 5 - Clicked Item
handler(itemToServerHandler(Type.ITEM1_8));
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
// Llama slot
handler(wrapper -> {
@@ -187,34 +190,6 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
}
});
protocol.registerClientbound(ClientboundPackets1_9_3.BLOCK_CHANGE, 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));
});
}
});
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() {
@@ -292,20 +267,20 @@ public class BlockItemPackets1_11 extends LegacyBlockItemRewriter<ClientboundPac
protocol.getEntityRewriter().filter().handler((event, meta) -> {
if (meta.metaType().type().equals(Type.ITEM1_8)) // Is Item
meta.setValue(handleItemToClient((Item) meta.getValue()));
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 << 4, 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");
@@ -313,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;
@@ -323,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.getListTag("ench") != null) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, false);
}
if (tag.getListTag("StoredEnchantments") != null) {
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;
@@ -343,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.getListTag(nbtTagName + "|ench") != null) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, false);
}
if (tag.getListTag(nbtTagName + "|StoredEnchantments") != null) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, true);
}
enchantmentRewriter.handleToServer(item);
return item;
}
@@ -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.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_11;
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_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> {
@@ -86,21 +83,7 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> EntityTypes1_11.ObjectType.findById(id).orElse(null)));
// Handle FallingBlock blocks
handler(wrapper -> {
Optional<EntityTypes1_12.ObjectType> type = EntityTypes1_12.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get() == EntityTypes1_12.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());
}
});
@@ -128,24 +111,13 @@ 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));
}
});
}
@@ -397,7 +369,7 @@ public class EntityPackets1_11 extends LegacyEntityRewriter<ClientboundPackets1_
}
@Override
protected EntityType getObjectTypeFromId(int typeId) {
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_11.getTypeFromId(typeId, true);
}
}
@@ -37,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() {
@@ -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,7 +69,6 @@ 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());
}
@@ -40,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 {
@@ -21,6 +21,7 @@ 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;
@@ -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() {
@@ -96,12 +100,12 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // Input Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // 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.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // 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
@@ -143,7 +147,7 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
}
Item item = wrapper.get(Type.ITEM1_8, 0);
handleItemToServer(item);
handleItemToServer(wrapper.user(), item);
});
}
});
@@ -159,34 +163,6 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
handleChunk(chunk);
});
protocol.registerClientbound(ClientboundPackets1_12.BLOCK_CHANGE, 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));
});
}
});
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() {
@@ -204,7 +180,7 @@ public class BlockItemPackets1_12 extends LegacyBlockItemRewriter<ClientboundPac
protocol.getEntityRewriter().filter().handler((event, meta) -> {
if (meta.metaType().type().equals(Type.ITEM1_8)) // Is Item
meta.setValue(handleItemToClient((Item) meta.getValue()));
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");
@@ -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;
@@ -31,8 +32,8 @@ public class ChatPackets1_12 extends RewriterBase<Protocol1_11_1To1_12> {
public static final ComponentRewriter<ClientboundPackets1_12> COMPONENT_REWRITER = new ComponentRewriter<ClientboundPackets1_12>(null, ComponentRewriter.ReadType.JSON) {
@Override
public void processText(JsonElement element) {
super.processText(element);
public void processText(UserConnection connection, JsonElement element) {
super.processText(connection, element);
if (element == null || !element.isJsonObject()) {
return;
}
@@ -64,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);
COMPONENT_REWRITER.processText(element);
COMPONENT_REWRITER.processText(wrapper.user(), element);
});
}
}
@@ -22,7 +22,6 @@ 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.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_12;
@@ -36,7 +35,6 @@ 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> {
@@ -63,22 +61,7 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
handler(getObjectTrackerHandler());
handler(getObjectRewriter(id -> EntityTypes1_12.ObjectType.findById(id).orElse(null)));
// Handle FallingBlock blocks
handler(wrapper -> {
Optional<EntityTypes1_12.ObjectType> type = EntityTypes1_12.ObjectType.findById(wrapper.get(Type.BYTE, 0));
if (type.isPresent() && type.get() == EntityTypes1_12.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());
}
});
@@ -106,7 +89,7 @@ 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));
}
});
@@ -208,7 +191,7 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
filter().handler((event, meta) -> {
if (meta.metaType() == MetaType1_12.Chat) {
ChatPackets1_12.COMPONENT_REWRITER.processText((JsonElement) meta.getValue());
ChatPackets1_12.COMPONENT_REWRITER.processText(event.user(), (JsonElement) meta.getValue());
}
});
@@ -307,7 +290,7 @@ public class EntityPackets1_12 extends LegacyEntityRewriter<ClientboundPackets1_
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_12.getTypeFromId(typeId, true);
}
}
@@ -45,7 +45,6 @@ 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());
}
@@ -78,7 +78,7 @@ 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));
}
});
@@ -121,7 +121,7 @@ public class EntityPackets1_11_1 extends LegacyEntityRewriter<ClientboundPackets
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_11.getTypeFromId(typeId, true);
}
}
@@ -21,10 +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.protocols.protocol1_9_3to1_9_1_2.ClientboundPackets1_9_3;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
@@ -33,7 +33,7 @@ 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
@@ -54,12 +54,12 @@ public class ItemPackets1_11_1 extends LegacyBlockItemRewriter<ClientboundPacket
int size = wrapper.passthrough(Type.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // Input Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // 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.ITEM1_8, handleItemToClient(wrapper.read(Type.ITEM1_8))); // Second Item
wrapper.write(Type.ITEM1_8, handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_8))); // Second Item
}
wrapper.passthrough(Type.BOOLEAN); // Trade disabled
@@ -77,48 +77,32 @@ public class ItemPackets1_11_1 extends LegacyBlockItemRewriter<ClientboundPacket
// Handle item metadata
protocol.getEntityRewriter().filter().handler((event, meta) -> {
if (meta.metaType().type().equals(Type.ITEM1_8)) { // Is Item
meta.setValue(handleItemToClient((Item) meta.getValue()));
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.getListTag("ench") != null) {
enchantmentRewriter.rewriteEnchantmentsToClient(tag, false);
}
if (tag.getListTag("StoredEnchantments") != null) {
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.getListTag(nbtTagName + "|ench") != null) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, false);
}
if (tag.getListTag(nbtTagName + "|StoredEnchantments") != null) {
enchantmentRewriter.rewriteEnchantmentsToServer(tag, true);
}
enchantmentRewriter.handleToServer(item);
return item;
}
}
@@ -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;
@@ -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;
@@ -112,7 +112,6 @@ 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());
}
@@ -149,25 +148,25 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol<ClientboundPackets1_
return translatableRewriter;
}
public String jsonToLegacy(String value) {
public String jsonToLegacy(UserConnection connection, String value) {
if (value.isEmpty()) {
return "";
}
try {
return jsonToLegacy(JsonParser.parseString(value));
return jsonToLegacy(connection, JsonParser.parseString(value));
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public String jsonToLegacy(@Nullable JsonElement value) {
public String jsonToLegacy(UserConnection connection, @Nullable JsonElement value) {
if (value == null || value.isJsonNull()) {
return "";
}
translatableToLegacyRewriter.processText(value);
translatableToLegacyRewriter.processText(connection, value);
return ComponentUtil.jsonToLegacy(value);
}
}
@@ -48,14 +48,11 @@ public class BannerHandler implements BackwardsBlockEntityHandler {
}
// Invert colors
ListTag patternsTag = tag.getListTag("Patterns");
ListTag<CompoundTag> patternsTag = tag.getListTag("Patterns", CompoundTag.class);
if (patternsTag != null) {
for (Tag pattern : patternsTag) {
if (!(pattern instanceof CompoundTag)) continue;
CompoundTag patternTag = (CompoundTag) pattern;
NumberTag colorTag = patternTag.getNumberTag("Color");
patternTag.putInt("Color", 15 - colorTag.asInt()); // Invert color id
for (CompoundTag pattern : patternsTag) {
NumberTag colorTag = pattern.getNumberTag("Color");
pattern.putInt("Color", 15 - colorTag.asInt()); // Invert color id
}
}
@@ -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();
@@ -117,7 +117,7 @@ public class ParticleMapping {
}
private int[] rewrite(Protocol1_12_2To1_13 protocol, Item newItem) {
Item item = protocol.getItemRewriter().handleItemToClient(newItem);
Item item = protocol.getItemRewriter().handleItemToClient(null, newItem);
return new int[]{item.identifier(), item.data()};
}
}), // (27->36) minecraft:item -> iconcrack
@@ -20,6 +20,7 @@ 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;
@@ -55,6 +56,7 @@ import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_
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.util.ComponentUtil;
import com.viaversion.viaversion.util.IdAndData;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair;
import java.util.ArrayList;
@@ -64,14 +66,14 @@ 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, null, null);
extraNbtTag = "VB|" + protocol.getClass().getSimpleName() + "|2";
extraNbtTag = nbtTagName("2");
}
public static boolean isDamageable(int id) {
@@ -99,11 +101,11 @@ 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() {
@@ -256,7 +258,12 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
map(Type.UNSIGNED_BYTE);
map(Type.ITEM1_13_SHORT_ARRAY, Type.ITEM1_8_SHORT_ARRAY);
handler(itemArrayToClientHandler(Type.ITEM1_8_SHORT_ARRAY));
handler(wrapper -> {
final Item[] items = wrapper.get(Type.ITEM1_8_SHORT_ARRAY, 0);
for (Item item : items) {
handleItemToClient(wrapper.user(), item);
}
});
}
});
@@ -267,7 +274,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
map(Type.SHORT);
map(Type.ITEM1_13, Type.ITEM1_8);
handler(itemToClientHandler(Type.ITEM1_8));
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
}
});
@@ -437,7 +444,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
map(Type.VAR_INT);
map(Type.ITEM1_13, Type.ITEM1_8);
handler(itemToClientHandler(Type.ITEM1_8));
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Type.ITEM1_8, 0)));
}
});
@@ -465,7 +472,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
map(Type.SHORT);
map(Type.ITEM1_8, Type.ITEM1_13);
handler(itemToServerHandler(Type.ITEM1_13));
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Type.ITEM1_13, 0)));
}
});
@@ -479,7 +486,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
map(Type.VAR_INT);
map(Type.ITEM1_8, Type.ITEM1_13);
handler(itemToServerHandler(Type.ITEM1_13));
handler(wrapper -> handleItemToServer(wrapper.user(), wrapper.get(Type.ITEM1_13, 0)));
}
});
}
@@ -493,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
@@ -513,7 +520,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
if (rawId == null) {
// Look for custom mappings
super.handleItemToClient(item);
super.handleItemToClient(connection, item);
// Handle one-way special case
if (item.identifier() == -1) {
@@ -564,7 +571,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
StringTag name = display.getStringTag("Name");
if (name != null) {
display.putString(extraNbtTag + "|Name", name.getValue());
name.setValue(protocol.jsonToLegacy(name.getValue()));
name.setValue(protocol.jsonToLegacy(connection, name.getValue()));
}
}
@@ -597,10 +604,10 @@ 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
ListTag blockTag = tag.getListTag(tagName);
ListTag<?> blockTag = tag.getListTag(tagName);
if (blockTag == null) return;
ListTag newCanPlaceOn = new ListTag(StringTag.class);
ListTag<StringTag> newCanPlaceOn = new ListTag<>(StringTag.class);
tag.put(extraNbtTag + "|" + tagName, blockTag.copy());
for (Tag oldTag : blockTag) {
Object value = oldTag.getValue();
@@ -611,7 +618,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
newCanPlaceOn.add(new StringTag(newValue));
}
} else {
newCanPlaceOn.add(oldTag);
newCanPlaceOn.add(new StringTag(oldTag.getValue().toString()));
}
}
tag.put(tagName, newCanPlaceOn);
@@ -620,19 +627,14 @@ 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.getListTag(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.copy()) {
if (!(enchantmentEntryTag instanceof CompoundTag)) {
continue;
}
CompoundTag enchantmentEntry = (CompoundTag) enchantmentEntryTag;
for (CompoundTag enchantmentEntry : enchantments.copy()) {
StringTag idTag = enchantmentEntry.getStringTag("id");
if (idTag == null) {
continue;
@@ -720,13 +722,13 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
tag.put("display", display = new CompoundTag());
}
ListTag loreTag = display.getListTag("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.isEmpty()) {
ListTag oldLore = new ListTag(StringTag.class);
for (Tag value : loreTag) {
ListTag<StringTag> oldLore = new ListTag<>(StringTag.class);
for (StringTag value : loreTag) {
oldLore.add(value.copy());
}
tag.put(extraNbtTag + "|OldLore", oldLore);
@@ -743,14 +745,14 @@ 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())) {
@@ -811,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;
@@ -831,7 +833,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
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 {
@@ -854,11 +856,11 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
private void rewriteCanPlaceToServer(CompoundTag tag, String tagName) {
if (tag.getListTag(tagName) == null) return;
ListTag blockTag = tag.remove(extraNbtTag + "|" + tagName);
ListTag<?> blockTag = tag.remove(extraNbtTag + "|" + tagName);
if (blockTag != null) {
tag.put(tagName, blockTag.copy());
} else if ((blockTag = tag.getListTag(tagName)) != null) {
ListTag newCanPlaceOn = new ListTag(StringTag.class);
ListTag<StringTag> newCanPlaceOn = new ListTag<>(StringTag.class);
for (Tag oldTag : blockTag) {
Object value = oldTag.getValue();
String oldId = Key.stripMinecraftNamespace(value.toString());
@@ -884,10 +886,10 @@ 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.getListTag(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) {
Tag hideFlags = tag.remove(extraNbtTag + "|OldHideFlags");
@@ -900,12 +902,7 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
}
}
for (Tag enchEntry : enchantments) {
if (!(enchEntry instanceof CompoundTag)) {
continue;
}
CompoundTag entryTag = (CompoundTag) enchEntry;
for (CompoundTag entryTag : enchantments) {
NumberTag idTag = entryTag.getNumberTag("id");
NumberTag levelTag = entryTag.getNumberTag("lvl");
CompoundTag enchantmentEntry = new CompoundTag();
@@ -925,11 +922,12 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
newEnchantments.add(enchantmentEntry);
}
Tag noMapped = tag.remove(extraNbtTag + "|Enchantments");
if (noMapped instanceof ListTag) {
for (Tag value : ((ListTag) noMapped)) {
ListTag<CompoundTag> noMapped = tag.getListTag(extraNbtTag + "|Enchantments", CompoundTag.class);
if (noMapped != null) {
for (CompoundTag value : noMapped) {
newEnchantments.add(value);
}
tag.remove(extraNbtTag + "|Enchantments");
}
CompoundTag display = tag.getCompoundTag("display");
@@ -937,14 +935,15 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
tag.put("display", display = new CompoundTag());
}
Tag oldLore = tag.remove(extraNbtTag + "|OldLore");
if (oldLore instanceof ListTag) {
ListTag lore = display.getListTag("Lore");
ListTag<StringTag> oldLore = tag.getListTag(extraNbtTag + "|OldLore", StringTag.class);
if (oldLore != null) {
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(((ListTag) oldLore).getValue());
lore.setValue(oldLore.getValue());
tag.remove(extraNbtTag + "|OldLore");
} else if (tag.remove(extraNbtTag + "|DummyLore") != null) {
display.remove("Lore");
if (display.isEmpty()) {
@@ -969,14 +968,11 @@ public class BlockItemPackets1_13 extends com.viaversion.viabackwards.api.rewrit
blockEntityTag.putInt("Base", 15 - base.asInt()); // Invert color id
}
ListTag patterns = blockEntityTag.getListTag("Patterns");
ListTag<CompoundTag> patterns = blockEntityTag.getListTag("Patterns", CompoundTag.class);
if (patterns != null) {
for (Tag pattern : patterns) {
if (!(pattern instanceof CompoundTag)) continue;
CompoundTag patternTag = (CompoundTag) pattern;
NumberTag colorTag = patternTag.getNumberTag("Color");
patternTag.putInt("Color", 15 - colorTag.asInt()); // Invert color id
for (CompoundTag pattern : patterns) {
NumberTag colorTag = pattern.getNumberTag("Color");
pattern.putInt("Color", 15 - colorTag.asInt()); // Invert color id
}
}
}
@@ -155,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));
}
});
@@ -283,15 +283,15 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
int typeId = meta.metaType().typeId();
if (typeId == 4) {
JsonElement element = meta.value();
protocol.translatableRewriter().processText(element);
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(element));
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));
meta.setTypeAndValue(MetaType1_12.Slot, protocol.getItemRewriter().handleItemToClient(event.user(), item));
} else if (typeId == 15) {
// Discontinue particles
event.cancel();
@@ -333,7 +333,7 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
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;
@@ -362,7 +362,7 @@ public class EntityPackets1_13 extends LegacyEntityRewriter<ClientboundPackets1_
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_13.getTypeFromId(typeId, true);
}
@@ -28,20 +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.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;
@@ -56,13 +59,13 @@ 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();
// Plugin response
packetWrapper.create(0x02, wrapper -> {
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);
@@ -80,16 +83,16 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
for (int i = 0; i < size; i++) {
//Input Item
Item input = wrapper.read(Type.ITEM1_13);
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(input));
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(wrapper.user(), input));
//Output Item
Item output = wrapper.read(Type.ITEM1_13);
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(output));
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.ITEM1_13);
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(second));
wrapper.write(Type.ITEM1_8, protocol.getItemRewriter().handleItemToClient(wrapper.user(), second));
}
wrapper.passthrough(Type.BOOLEAN); //Trade disabled
@@ -100,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;
@@ -115,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));
@@ -200,7 +203,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
byte mode = wrapper.get(Type.BYTE, 0);
if (mode == 0 || mode == 2) {
JsonElement value = wrapper.read(Type.COMPONENT);
String legacyValue = protocol.jsonToLegacy(value);
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");
@@ -218,7 +221,7 @@ 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 = protocol.jsonToLegacy(displayName);
String legacyTextDisplayName = protocol.jsonToLegacy(wrapper.user(), displayName);
wrapper.write(Type.STRING, ChatUtil.fromLegacy(legacyTextDisplayName, 'f', 32));
byte flags = wrapper.read(Type.BYTE);
@@ -233,11 +236,11 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
JsonElement prefixComponent = wrapper.read(Type.COMPONENT);
JsonElement suffixComponent = wrapper.read(Type.COMPONENT);
String prefix = protocol.jsonToLegacy(prefixComponent);
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(suffixComponent);
String suffix = protocol.jsonToLegacy(wrapper.user(), suffixComponent);
wrapper.write(Type.STRING, ChatUtil.fromLegacyPrefix(prefix, 'f', 16));
wrapper.write(Type.STRING, ChatUtil.fromLegacy(suffix, '\0', 16));
@@ -378,7 +381,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
case "MC|BEdit":
wrapper.setPacketType(ServerboundPackets1_13.EDIT_BOOK);
Item book = wrapper.read(Type.ITEM1_8);
wrapper.write(Type.ITEM1_13, protocol.getItemRewriter().handleItemToServer(book));
wrapper.write(Type.ITEM1_13, protocol.getItemRewriter().handleItemToServer(wrapper.user(), book));
boolean signing = channel.equals("MC|BSign");
wrapper.write(Type.BOOLEAN, signing);
break;
@@ -489,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;
@@ -504,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()) {
@@ -52,10 +52,7 @@ public class Protocol1_13_1To1_13_2 extends BackwardsProtocol<ClientboundPackets
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)) {
@@ -162,7 +162,6 @@ public class Protocol1_13_2To1_14 extends BackwardsProtocol<ClientboundPackets1_
@Override
public void init(UserConnection user) {
// Register ClientWorld
if (!user.has(ClientWorld.class)) {
user.put(new ClientWorld());
}
@@ -19,10 +19,12 @@ package com.viaversion.viabackwards.protocol.protocol1_13_2to1_14.packets;
import com.google.common.collect.ImmutableSet;
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_13_2to1_14.Protocol1_13_2To1_14;
import com.viaversion.viabackwards.protocol.protocol1_13_2to1_14.storage.ChunkLightStorage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.Environment;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
@@ -46,7 +48,6 @@ import com.viaversion.viaversion.libs.gson.JsonObject;
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_13to1_12_2.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
@@ -59,7 +60,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewriters.ItemRewriter<ClientboundPackets1_14, ServerboundPackets1_13, Protocol1_13_2To1_14> {
public class BlockItemPackets1_14 extends BackwardsItemRewriter<ClientboundPackets1_14, ServerboundPackets1_13, Protocol1_13_2To1_14> {
private EnchantmentRewriter enchantmentRewriter;
@@ -69,7 +70,7 @@ public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewrit
@Override
protected void registerPackets() {
protocol.registerServerbound(ServerboundPackets1_13.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.passthrough(Type.ITEM1_13_2)));
protocol.registerServerbound(ServerboundPackets1_13.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)));
protocol.registerClientbound(ClientboundPackets1_14.OPEN_WINDOW, wrapper -> {
int windowId = wrapper.read(Type.VAR_INT);
@@ -185,20 +186,20 @@ public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewrit
for (int i = 0; i < size; i++) {
// Input Item
Item input = wrapper.read(Type.ITEM1_13_2);
input = handleItemToClient(input);
input = handleItemToClient(wrapper.user(), input);
wrapper.write(Type.ITEM1_13_2, input);
// Output Item
Item output = wrapper.read(Type.ITEM1_13_2);
output = handleItemToClient(output);
output = handleItemToClient(wrapper.user(), output);
wrapper.write(Type.ITEM1_13_2, output);
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); // Has second item
if (secondItem) {
// Second Item
Item second = wrapper.read(Type.ITEM1_13_2);
second = handleItemToClient(second);
second = handleItemToClient(wrapper.user(), second);
wrapper.write(Type.ITEM1_13_2, second);
}
@@ -228,7 +229,7 @@ public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewrit
map(Type.VAR_INT); // 1 - Slot ID
map(Type.ITEM1_13_2); // 2 - Item
handler(itemToClientHandler(Type.ITEM1_13_2));
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Type.ITEM1_13_2, 0)));
handler(wrapper -> {
int entityId = wrapper.get(Type.VAR_INT, 0);
@@ -465,25 +466,22 @@ public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewrit
}
@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);
// Lore now uses JSON
CompoundTag tag = item.tag();
CompoundTag display;
if (tag != null && (display = tag.getCompoundTag("display")) != null) {
ListTag lore = display.getListTag("Lore");
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
if (lore != null) {
saveListTag(display, lore, "Lore");
for (Tag loreEntry : lore) {
if (!(loreEntry instanceof StringTag)) continue;
StringTag loreEntryTag = (StringTag) loreEntry;
String value = loreEntryTag.getValue();
for (StringTag loreEntry : lore) {
String value = loreEntry.getValue();
if (value != null && !value.isEmpty()) {
loreEntryTag.setValue(ComponentUtil.jsonToLegacy(value));
loreEntry.setValue(ComponentUtil.jsonToLegacy(value));
}
}
}
@@ -494,7 +492,7 @@ public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewrit
}
@Override
public Item handleItemToServer(Item item) {
public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
// Lore now uses JSON
@@ -502,13 +500,10 @@ public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewrit
CompoundTag display;
if (tag != null && (display = tag.getCompoundTag("display")) != null) {
// Transform to json if no backup tag is found (else process that in the super method)
ListTag lore = display.getListTag("Lore");
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
if (lore != null && !hasBackupTag(display, "Lore")) {
for (Tag loreEntry : lore) {
if (loreEntry instanceof StringTag) {
StringTag loreEntryTag = (StringTag) loreEntry;
loreEntryTag.setValue(ComponentUtil.legacyToJsonString(loreEntryTag.getValue()));
}
for (StringTag loreEntry : lore) {
loreEntry.setValue(ComponentUtil.legacyToJsonString(loreEntry.getValue()));
}
}
}
@@ -516,7 +511,7 @@ public class BlockItemPackets1_14 extends com.viaversion.viabackwards.api.rewrit
enchantmentRewriter.handleToServer(item);
// Call this last to check for the backup lore above
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
return item;
}
}
@@ -223,7 +223,7 @@ public class EntityPackets1_14 extends LegacyEntityRewriter<ClientboundPackets1_
});
// Handle entity type & metadata
handler(getMobSpawnRewriter(Types1_13_2.METADATA_LIST));
handler(getMobSpawnRewriter1_11(Types1_13_2.METADATA_LIST));
}
});
@@ -331,16 +331,6 @@ public class EntityPackets1_14 extends LegacyEntityRewriter<ClientboundPackets1_
@Override
protected void registerRewrites() {
mapTypes(EntityTypes1_14.values(), EntityTypes1_13.EntityType.class);
mapEntityTypeWithData(EntityTypes1_14.CAT, EntityTypes1_14.OCELOT).jsonName();
mapEntityTypeWithData(EntityTypes1_14.TRADER_LLAMA, EntityTypes1_14.LLAMA).jsonName();
mapEntityTypeWithData(EntityTypes1_14.FOX, EntityTypes1_14.WOLF).jsonName();
mapEntityTypeWithData(EntityTypes1_14.PANDA, EntityTypes1_14.POLAR_BEAR).jsonName();
mapEntityTypeWithData(EntityTypes1_14.PILLAGER, EntityTypes1_14.VILLAGER).jsonName();
mapEntityTypeWithData(EntityTypes1_14.WANDERING_TRADER, EntityTypes1_14.VILLAGER).jsonName();
mapEntityTypeWithData(EntityTypes1_14.RAVAGER, EntityTypes1_14.COW).jsonName();
filter().handler((event, meta) -> {
int typeId = meta.metaType().typeId();
if (typeId <= 15) {
@@ -383,7 +373,7 @@ public class EntityPackets1_14 extends LegacyEntityRewriter<ClientboundPackets1_
});
filter().type(EntityTypes1_14.AREA_EFFECT_CLOUD).index(10).handler((event, meta) -> {
rewriteParticle((Particle) meta.getValue());
rewriteParticle(event.user(), (Particle) meta.getValue());
});
filter().type(EntityTypes1_14.FIREWORK_ROCKET).index(8).handler((event, meta) -> {
@@ -499,6 +489,19 @@ public class EntityPackets1_14 extends LegacyEntityRewriter<ClientboundPackets1_
}
}
@Override
public void onMappingDataLoaded() {
mapTypes();
mapEntityTypeWithData(EntityTypes1_14.CAT, EntityTypes1_14.OCELOT).jsonName();
mapEntityTypeWithData(EntityTypes1_14.TRADER_LLAMA, EntityTypes1_14.LLAMA).jsonName();
mapEntityTypeWithData(EntityTypes1_14.FOX, EntityTypes1_14.WOLF).jsonName();
mapEntityTypeWithData(EntityTypes1_14.PANDA, EntityTypes1_14.POLAR_BEAR).jsonName();
mapEntityTypeWithData(EntityTypes1_14.PILLAGER, EntityTypes1_14.VILLAGER).jsonName();
mapEntityTypeWithData(EntityTypes1_14.WANDERING_TRADER, EntityTypes1_14.VILLAGER).jsonName();
mapEntityTypeWithData(EntityTypes1_14.RAVAGER, EntityTypes1_14.COW).jsonName();
}
@Override
public EntityType typeFromId(int typeId) {
return EntityTypes1_14.getTypeFromId(typeId);
@@ -51,6 +51,7 @@ public class Protocol1_13To1_13_1 extends BackwardsProtocol<ClientboundPackets1_
private final EntityPackets1_13_1 entityRewriter = new EntityPackets1_13_1(this);
private final InventoryPackets1_13_1 itemRewriter = new InventoryPackets1_13_1(this);
private final TranslatableRewriter<ClientboundPackets1_13> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_13> tagRewriter = new TagRewriter<>(this);
public Protocol1_13To1_13_1() {
super(ClientboundPackets1_13.class, ClientboundPackets1_13.class, ServerboundPackets1_13.class, ServerboundPackets1_13.class);
@@ -91,7 +92,7 @@ public class Protocol1_13To1_13_1 extends BackwardsProtocol<ClientboundPackets1_
map(Type.ITEM1_13);
map(Type.BOOLEAN);
handler(wrapper -> {
itemRewriter.handleItemToServer(wrapper.get(Type.ITEM1_13, 0));
itemRewriter.handleItemToServer(wrapper.user(), wrapper.get(Type.ITEM1_13, 0));
wrapper.write(Type.VAR_INT, 0);
});
}
@@ -104,7 +105,7 @@ public class Protocol1_13To1_13_1 extends BackwardsProtocol<ClientboundPackets1_
map(Type.STRING); // Window Type
handler(wrapper -> {
JsonElement title = wrapper.passthrough(Type.COMPONENT);
translatableRewriter.processText(title);
translatableRewriter.processText(wrapper.user(), title);
if (ViaBackwards.getConfig().fix1_13FormattedInventoryTitle()) {
if (title.isJsonObject() && title.getAsJsonObject().size() == 1
@@ -150,7 +151,7 @@ public class Protocol1_13To1_13_1 extends BackwardsProtocol<ClientboundPackets1_
handler(wrapper -> {
int action = wrapper.get(Type.VAR_INT, 0);
if (action == 0 || action == 3) {
translatableRewriter.processText(wrapper.passthrough(Type.COMPONENT));
translatableRewriter.processText(wrapper.user(), wrapper.passthrough(Type.COMPONENT));
if (action == 0) {
wrapper.passthrough(Type.FLOAT);
wrapper.passthrough(Type.VAR_INT);
@@ -170,17 +171,14 @@ public class Protocol1_13To1_13_1 extends BackwardsProtocol<ClientboundPackets1_
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)) {
wrapper.passthrough(Type.COMPONENT); // Title
wrapper.passthrough(Type.COMPONENT); // Description
Item icon = wrapper.passthrough(Type.ITEM1_13);
itemRewriter.handleItemToClient(icon);
itemRewriter.handleItemToClient(wrapper.user(), icon);
wrapper.passthrough(Type.VAR_INT); // Frame type
int flags = wrapper.passthrough(Type.INT); // Flags
if ((flags & 1) != 0)
@@ -198,7 +196,7 @@ public class Protocol1_13To1_13_1 extends BackwardsProtocol<ClientboundPackets1_
}
});
new TagRewriter<>(this).register(ClientboundPackets1_13.TAGS, RegistryType.ITEM);
tagRewriter.register(ClientboundPackets1_13.TAGS, RegistryType.ITEM);
new StatisticsRewriter<>(this).register(ClientboundPackets1_13.STATISTICS);
}
@@ -229,4 +227,9 @@ public class Protocol1_13To1_13_1 extends BackwardsProtocol<ClientboundPackets1_
public TranslatableRewriter<ClientboundPackets1_13> translatableRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_13> getTagRewriter() {
return tagRewriter;
}
}
@@ -133,16 +133,16 @@ public class EntityPackets1_13_1 extends LegacyEntityRewriter<ClientboundPackets
// Rewrite items & blocks
filter().handler((event, meta) -> {
if (meta.metaType() == Types1_13.META_TYPES.itemType) {
protocol.getItemRewriter().handleItemToClient((Item) meta.getValue());
protocol.getItemRewriter().handleItemToClient(event.user(), (Item) meta.getValue());
} else if (meta.metaType() == Types1_13.META_TYPES.blockStateType) {
// Convert to new block id
int data = (int) meta.getValue();
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
} else if (meta.metaType() == Types1_13.META_TYPES.particleType) {
rewriteParticle((Particle) meta.getValue());
rewriteParticle(event.user(), (Particle) meta.getValue());
} else if (meta.metaType() == Types1_13.META_TYPES.optionalComponentType || meta.metaType() == Types1_13.META_TYPES.componentType) {
JsonElement element = meta.value();
protocol.translatableRewriter().processText(element);
protocol.translatableRewriter().processText(event.user(), element);
}
});
@@ -168,7 +168,7 @@ public class EntityPackets1_13_1 extends LegacyEntityRewriter<ClientboundPackets
}
@Override
protected EntityType getObjectTypeFromId(final int typeId) {
public EntityType objectTypeFromId(int typeId) {
return EntityTypes1_13.getTypeFromId(typeId, true);
}
}
@@ -45,16 +45,16 @@ public class InventoryPackets1_13_1 extends ItemRewriter<ClientboundPackets1_13,
for (int i = 0; i < size; i++) {
//Input Item
Item input = wrapper.passthrough(Type.ITEM1_13);
handleItemToClient(input);
handleItemToClient(wrapper.user(), input);
//Output Item
Item output = wrapper.passthrough(Type.ITEM1_13);
handleItemToClient(output);
handleItemToClient(wrapper.user(), output);
boolean secondItem = wrapper.passthrough(Type.BOOLEAN); //Has second item
if (secondItem) {
//Second Item
Item second = wrapper.passthrough(Type.ITEM1_13);
handleItemToClient(second);
handleItemToClient(wrapper.user(), second);
}
wrapper.passthrough(Type.BOOLEAN); //Trade disabled
@@ -45,6 +45,7 @@ public class Protocol1_14_4To1_15 extends BackwardsProtocol<ClientboundPackets1_
private final EntityPackets1_15 entityRewriter = new EntityPackets1_15(this);
private final BlockItemPackets1_15 blockItemPackets = new BlockItemPackets1_15(this);
private final TranslatableRewriter<ClientboundPackets1_15> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_15> tagRewriter = new TagRewriter<>(this);
public Protocol1_14_4To1_15() {
super(ClientboundPackets1_15.class, ClientboundPackets1_14_4.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class);
@@ -94,7 +95,7 @@ public class Protocol1_14_4To1_15 extends BackwardsProtocol<ClientboundPackets1_
}
});
new TagRewriter<>(this).register(ClientboundPackets1_15.TAGS, RegistryType.ENTITY);
tagRewriter.register(ClientboundPackets1_15.TAGS, RegistryType.ENTITY);
new StatisticsRewriter<>(this).register(ClientboundPackets1_15.STATISTICS);
}
@@ -120,6 +121,11 @@ public class Protocol1_14_4To1_15 extends BackwardsProtocol<ClientboundPackets1_
return blockItemPackets;
}
@Override
public TagRewriter<ClientboundPackets1_15> getTagRewriter() {
return tagRewriter;
}
@Override
public TranslatableRewriter<ClientboundPackets1_15> getTranslatableRewriter() {
return translatableRewriter;
@@ -17,6 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_14_4to1_15.packets;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_14_4to1_15.Protocol1_14_4To1_15;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
@@ -32,7 +33,7 @@ import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.ClientboundPacke
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
public class BlockItemPackets1_15 extends com.viaversion.viabackwards.api.rewriters.ItemRewriter<ClientboundPackets1_15, ServerboundPackets1_14, Protocol1_14_4To1_15> {
public class BlockItemPackets1_15 extends BackwardsItemRewriter<ClientboundPackets1_15, ServerboundPackets1_14, Protocol1_14_4To1_15> {
public BlockItemPackets1_15(Protocol1_14_4To1_15 protocol) {
super(protocol, Type.ITEM1_13_2, Type.ITEM1_13_2_SHORT_ARRAY);
@@ -44,7 +45,7 @@ public class BlockItemPackets1_15 extends com.viaversion.viabackwards.api.rewrit
new RecipeRewriter<>(protocol).register(ClientboundPackets1_15.DECLARE_RECIPES);
protocol.registerServerbound(ServerboundPackets1_14.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.passthrough(Type.ITEM1_13_2)));
protocol.registerServerbound(ServerboundPackets1_14.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)));
registerSetCooldown(ClientboundPackets1_15.COOLDOWN);
registerWindowItems(ClientboundPackets1_15.WINDOW_ITEMS);
@@ -122,7 +123,7 @@ public class BlockItemPackets1_15 extends com.viaversion.viabackwards.api.rewrit
int data = wrapper.passthrough(Type.VAR_INT);
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (id == 32) {
Item item = handleItemToClient(wrapper.read(Type.ITEM1_13_2));
Item item = handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_13_2));
wrapper.write(Type.ITEM1_13_2, item);
}
@@ -36,6 +36,8 @@ import com.viaversion.viaversion.api.type.Type;
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.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ClientboundStatusPackets;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
@@ -51,6 +53,7 @@ public class Protocol1_15_2To1_16 extends BackwardsProtocol<ClientboundPackets1_
private final EntityPackets1_16 entityRewriter = new EntityPackets1_16(this);
private final BlockItemPackets1_16 blockItemPackets = new BlockItemPackets1_16(this);
private final TranslatableRewriter1_16 translatableRewriter = new TranslatableRewriter1_16(this);
private final TagRewriter<ClientboundPackets1_16> tagRewriter = new TagRewriter<>(this);
public Protocol1_15_2To1_16() {
super(ClientboundPackets1_16.class, ClientboundPackets1_15.class, ServerboundPackets1_16.class, ServerboundPackets1_14.class);
@@ -69,20 +72,20 @@ public class Protocol1_15_2To1_16 extends BackwardsProtocol<ClientboundPackets1_
new CommandRewriter1_16(this).registerDeclareCommands(ClientboundPackets1_16.DECLARE_COMMANDS);
registerClientbound(State.STATUS, 0x00, 0x00, wrapper -> {
registerClientbound(State.STATUS, ClientboundStatusPackets.STATUS_RESPONSE.getId(), ClientboundStatusPackets.STATUS_RESPONSE.getId(), wrapper -> {
String original = wrapper.passthrough(Type.STRING);
JsonObject object = GsonUtil.getGson().fromJson(original, JsonObject.class);
JsonElement description = object.get("description");
if (description == null) return;
translatableRewriter.processText(description);
translatableRewriter.processText(wrapper.user(), description);
wrapper.set(Type.STRING, 0, object.toString());
});
registerClientbound(ClientboundPackets1_16.CHAT_MESSAGE, new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> translatableRewriter.processText(wrapper.passthrough(Type.COMPONENT)));
handler(wrapper -> translatableRewriter.processText(wrapper.user(), wrapper.passthrough(Type.COMPONENT)));
map(Type.BYTE);
read(Type.UUID); // Sender
}
@@ -93,7 +96,7 @@ public class Protocol1_15_2To1_16 extends BackwardsProtocol<ClientboundPackets1_
public void register() {
map(Type.VAR_INT); // Window Id
map(Type.VAR_INT); // Window Type
handler(wrapper -> translatableRewriter.processText(wrapper.passthrough(Type.COMPONENT)));
handler(wrapper -> translatableRewriter.processText(wrapper.user(), wrapper.passthrough(Type.COMPONENT)));
handler(wrapper -> {
int windowType = wrapper.get(Type.VAR_INT, 1);
if (windowType == 20) { // Smithing table
@@ -112,13 +115,13 @@ public class Protocol1_15_2To1_16 extends BackwardsProtocol<ClientboundPackets1_
soundRewriter.registerStopSound(ClientboundPackets1_16.STOP_SOUND);
// Login success
registerClientbound(State.LOGIN, 0x02, 0x02, wrapper -> {
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE.getId(), ClientboundLoginPackets.GAME_PROFILE.getId(), wrapper -> {
// Transform uuid to plain string
UUID uuid = wrapper.read(Type.UUID);
wrapper.write(Type.STRING, uuid.toString());
});
new TagRewriter<>(this).register(ClientboundPackets1_16.TAGS, RegistryType.ENTITY);
tagRewriter.register(ClientboundPackets1_16.TAGS, RegistryType.ENTITY);
new StatisticsRewriter<>(this).register(ClientboundPackets1_16.STATISTICS);
@@ -192,4 +195,9 @@ public class Protocol1_15_2To1_16 extends BackwardsProtocol<ClientboundPackets1_
public BlockItemPackets1_16 getItemRewriter() {
return blockItemPackets;
}
@Override
public TagRewriter<ClientboundPackets1_16> getTagRewriter() {
return tagRewriter;
}
}
@@ -19,11 +19,13 @@ package com.viaversion.viabackwards.protocol.protocol1_15_2to1_16.chat;
import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter;
import com.viaversion.viabackwards.protocol.protocol1_15_2to1_16.Protocol1_15_2To1_16;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.libs.gson.JsonElement;
import com.viaversion.viaversion.libs.gson.JsonObject;
import com.viaversion.viaversion.libs.gson.JsonPrimitive;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.SerializerVersion;
public class TranslatableRewriter1_16 extends TranslatableRewriter<ClientboundPackets1_16> {
@@ -51,8 +53,8 @@ public class TranslatableRewriter1_16 extends TranslatableRewriter<ClientboundPa
}
@Override
public void processText(JsonElement value) {
super.processText(value);
public void processText(UserConnection connection, JsonElement value) {
super.processText(connection, value);
if (value == null || !value.isJsonObject()) return;
@@ -74,7 +76,7 @@ public class TranslatableRewriter1_16 extends TranslatableRewriter<ClientboundPa
}
// show_text as chat component json, show_entity and show_item serialized as snbt
JsonObject convertedObject = (JsonObject) ComponentUtil.convertJson(object, ComponentUtil.SerializerVersion.V1_16, ComponentUtil.SerializerVersion.V1_15);
JsonObject convertedObject = (JsonObject) ComponentUtil.convertJson(object, SerializerVersion.V1_16, SerializerVersion.V1_15);
object.add("hoverEvent", convertedObject.getAsJsonObject("hoverEvent"));
}
@@ -19,6 +19,7 @@ package com.viaversion.viabackwards.protocol.protocol1_15_2to1_16.data;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.data.AttributeMappings;
import java.util.HashMap;
import java.util.Map;
@@ -32,12 +33,12 @@ public class BackwardsMappings extends com.viaversion.viabackwards.api.data.Back
@Override
protected void loadExtras(final CompoundTag data) {
super.loadExtras(data);
for (Map.Entry<String, String> entry : Protocol1_16To1_15_2.MAPPINGS.getAttributeMappings().entrySet()) {
for (Map.Entry<String, String> entry : AttributeMappings.attributeIdentifierMappings().entrySet()) {
attributeMappings.put(entry.getValue(), entry.getKey());
}
}
public Map<String, String> getAttributeMappings() {
public Map<String, String> attributeIdentifierMappings() {
return attributeMappings;
}
}
@@ -18,11 +18,13 @@
package com.viaversion.viabackwards.protocol.protocol1_15_2to1_16.packets;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.api.rewriters.EnchantmentRewriter;
import com.viaversion.viabackwards.api.rewriters.MapColorRewriter;
import com.viaversion.viabackwards.protocol.protocol1_15_2to1_16.Protocol1_15_2To1_16;
import com.viaversion.viabackwards.protocol.protocol1_15_2to1_16.data.MapColorRewrites;
import com.viaversion.viabackwards.protocol.protocol1_16_1to1_16_2.storage.BiomeStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
@@ -55,7 +57,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
public class BlockItemPackets1_16 extends com.viaversion.viabackwards.api.rewriters.ItemRewriter<ClientboundPackets1_16, ServerboundPackets1_14, Protocol1_15_2To1_16> {
public class BlockItemPackets1_16 extends BackwardsItemRewriter<ClientboundPackets1_16, ServerboundPackets1_14, Protocol1_15_2To1_16> {
private EnchantmentRewriter enchantmentRewriter;
@@ -111,7 +113,7 @@ public class BlockItemPackets1_16 extends com.viaversion.viabackwards.api.rewrit
byte slot;
do {
slot = wrapper.read(Type.BYTE);
Item item = handleItemToClient(wrapper.read(Type.ITEM1_13_2));
Item item = handleItemToClient(wrapper.user(), wrapper.read(Type.ITEM1_13_2));
int rawSlot = slot & 0x7F;
equipmentData.add(new EquipmentData(rawSlot, item));
} while ((slot & 0xFFFFFF80) != 0);
@@ -171,7 +173,7 @@ public class BlockItemPackets1_16 extends com.viaversion.viabackwards.api.rewrit
}
if (chunk.isBiomeData()) {
if (wrapper.user().getProtocolInfo().getServerProtocolVersion() >= ProtocolVersion.v1_16_2.getVersion()) {
if (wrapper.user().getProtocolInfo().serverProtocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_16_2)) {
BiomeStorage biomeStorage = wrapper.user().get(BiomeStorage.class);
for (int i = 0; i < 1024; i++) {
int biome = chunk.getBiomeData()[i];
@@ -248,7 +250,7 @@ public class BlockItemPackets1_16 extends com.viaversion.viabackwards.api.rewrit
registerClickWindow(ServerboundPackets1_14.CLICK_WINDOW);
registerCreativeInvAction(ServerboundPackets1_14.CREATIVE_INVENTORY_ACTION);
protocol.registerServerbound(ServerboundPackets1_14.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.passthrough(Type.ITEM1_13_2)));
protocol.registerServerbound(ServerboundPackets1_14.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)));
}
private void handleBlockEntity(CompoundTag tag) {
@@ -290,10 +292,10 @@ public class BlockItemPackets1_16 extends com.viaversion.viabackwards.api.rewrit
}
@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 (item.identifier() == 771 && tag != null) {
@@ -309,16 +311,11 @@ public class BlockItemPackets1_16 extends com.viaversion.viabackwards.api.rewrit
// Handle hover event changes in written book pages
if (item.identifier() == 759 && tag != null) {
ListTag pagesTag = tag.getListTag("pages");
ListTag<StringTag> pagesTag = tag.getListTag("pages", StringTag.class);
if (pagesTag != null) {
for (Tag page : pagesTag) {
if (!(page instanceof StringTag)) {
continue;
}
StringTag pageTag = (StringTag) page;
JsonElement jsonElement = protocol.getTranslatableRewriter().processText(pageTag.getValue());
pageTag.setValue(jsonElement.toString());
for (StringTag page : pagesTag) {
JsonElement jsonElement = protocol.getTranslatableRewriter().processText(connection, page.getValue());
page.setValue(jsonElement.toString());
}
}
}
@@ -329,11 +326,11 @@ public class BlockItemPackets1_16 extends com.viaversion.viabackwards.api.rewrit
}
@Override
public Item handleItemToServer(Item item) {
public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
int identifier = item.identifier();
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
CompoundTag tag = item.tag();
if (identifier == 771 && tag != null) {
@@ -26,7 +26,6 @@ import com.viaversion.viaversion.api.data.entity.StoredEntityData;
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.entities.EntityTypes1_15;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_16;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
@@ -48,6 +47,7 @@ public class EntityPackets1_16 extends EntityRewriter<ClientboundPackets1_16, Pr
private final ValueTransformer<String, Integer> dimensionTransformer = new ValueTransformer<String, Integer>(Type.STRING, Type.INT) {
@Override
public Integer transform(PacketWrapper wrapper, String input) {
input = Key.namespaced(input);
switch (input) {
case "minecraft:the_nether":
return -1;
@@ -119,7 +119,7 @@ public class EntityPackets1_16 extends EntityRewriter<ClientboundPackets1_16, Pr
// Send a dummy respawn with a different dimension if the world name was different and the same dimension was used
if (clientWorld.getEnvironment() != null && dimension == clientWorld.getEnvironment().id()
&& (wrapper.user().isClientSide() || Via.getPlatform().isProxy()
|| wrapper.user().getProtocolInfo().getProtocolVersion() <= ProtocolVersion.v1_12_2.getVersion() // Hotfix for https://github.com/ViaVersion/ViaBackwards/issues/381
|| wrapper.user().getProtocolInfo().protocolVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) // Hotfix for https://github.com/ViaVersion/ViaBackwards/issues/381
|| !nextWorldName.equals(worldNameTracker.getWorldName()))) {
PacketWrapper packet = wrapper.create(ClientboundPackets1_15.RESPAWN);
packet.write(Type.INT, dimension == 0 ? -1 : 0);
@@ -190,7 +190,7 @@ public class EntityPackets1_16 extends EntityRewriter<ClientboundPackets1_16, Pr
int size = wrapper.passthrough(Type.INT);
for (int i = 0; i < size; i++) {
String attributeIdentifier = wrapper.read(Type.STRING);
String oldKey = protocol.getMappingData().getAttributeMappings().get(attributeIdentifier);
String oldKey = protocol.getMappingData().attributeIdentifierMappings().get(attributeIdentifier);
wrapper.write(Type.STRING, oldKey != null ? oldKey : Key.stripMinecraftNamespace(attributeIdentifier));
wrapper.passthrough(Type.DOUBLE);
@@ -203,36 +203,31 @@ public class EntityPackets1_16 extends EntityRewriter<ClientboundPackets1_16, Pr
}
});
protocol.registerClientbound(ClientboundPackets1_16.PLAYER_INFO, new PacketHandlers() {
@Override
public void register() {
handler(packetWrapper -> {
int action = packetWrapper.passthrough(Type.VAR_INT);
int playerCount = packetWrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < playerCount; i++) {
packetWrapper.passthrough(Type.UUID);
if (action == 0) { // Add
packetWrapper.passthrough(Type.STRING);
int properties = packetWrapper.passthrough(Type.VAR_INT);
for (int j = 0; j < properties; j++) {
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.STRING);
packetWrapper.passthrough(Type.OPTIONAL_STRING);
}
packetWrapper.passthrough(Type.VAR_INT);
packetWrapper.passthrough(Type.VAR_INT);
// Display Name
protocol.getTranslatableRewriter().processText(packetWrapper.passthrough(Type.OPTIONAL_COMPONENT));
} else if (action == 1) { // Update Game Mode
packetWrapper.passthrough(Type.VAR_INT);
} else if (action == 2) { // Update Ping
packetWrapper.passthrough(Type.VAR_INT);
} else if (action == 3) { // Update Display Name
// Display name
protocol.getTranslatableRewriter().processText(packetWrapper.passthrough(Type.OPTIONAL_COMPONENT));
} // 4 = Remove Player
protocol.registerClientbound(ClientboundPackets1_16.PLAYER_INFO, wrapper -> {
int action = wrapper.passthrough(Type.VAR_INT);
int playerCount = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < playerCount; i++) {
wrapper.passthrough(Type.UUID);
if (action == 0) { // Add
wrapper.passthrough(Type.STRING);
int properties = wrapper.passthrough(Type.VAR_INT);
for (int j = 0; j < properties; j++) {
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.STRING);
wrapper.passthrough(Type.OPTIONAL_STRING);
}
});
wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.VAR_INT);
// Display Name
protocol.getTranslatableRewriter().processText(wrapper.user(), wrapper.passthrough(Type.OPTIONAL_COMPONENT));
} else if (action == 1) { // Update Game Mode
wrapper.passthrough(Type.VAR_INT);
} else if (action == 2) { // Update Ping
wrapper.passthrough(Type.VAR_INT);
} else if (action == 3) { // Update Display Name
// Display name
protocol.getTranslatableRewriter().processText(wrapper.user(), wrapper.passthrough(Type.OPTIONAL_COMPONENT));
} // 4 = Remove Player
}
});
}
@@ -244,27 +239,19 @@ public class EntityPackets1_16 extends EntityRewriter<ClientboundPackets1_16, Pr
MetaType type = meta.metaType();
if (type == Types1_14.META_TYPES.itemType) {
meta.setValue(protocol.getItemRewriter().handleItemToClient((Item) meta.getValue()));
meta.setValue(protocol.getItemRewriter().handleItemToClient(event.user(), (Item) meta.getValue()));
} else if (type == Types1_14.META_TYPES.blockStateType) {
meta.setValue(protocol.getMappingData().getNewBlockStateId((int) meta.getValue()));
} else if (type == Types1_14.META_TYPES.particleType) {
rewriteParticle((Particle) meta.getValue());
rewriteParticle(event.user(), (Particle) meta.getValue());
} else if (type == Types1_14.META_TYPES.optionalComponentType) {
JsonElement text = meta.value();
if (text != null) {
protocol.getTranslatableRewriter().processText(text);
protocol.getTranslatableRewriter().processText(event.user(), text);
}
}
});
mapEntityType(EntityTypes1_16.ZOMBIFIED_PIGLIN, EntityTypes1_15.ZOMBIE_PIGMAN);
mapTypes(EntityTypes1_16.values(), EntityTypes1_15.class);
mapEntityTypeWithData(EntityTypes1_16.HOGLIN, EntityTypes1_16.COW).jsonName();
mapEntityTypeWithData(EntityTypes1_16.ZOGLIN, EntityTypes1_16.COW).jsonName();
mapEntityTypeWithData(EntityTypes1_16.PIGLIN, EntityTypes1_16.ZOMBIFIED_PIGLIN).jsonName();
mapEntityTypeWithData(EntityTypes1_16.STRIDER, EntityTypes1_16.MAGMA_CUBE).jsonName();
filter().type(EntityTypes1_16.ZOGLIN).cancel(16);
filter().type(EntityTypes1_16.HOGLIN).cancel(15);
@@ -312,6 +299,16 @@ public class EntityPackets1_16 extends EntityRewriter<ClientboundPackets1_16, Pr
});
}
@Override
public void onMappingDataLoaded() {
mapTypes();
mapEntityTypeWithData(EntityTypes1_16.HOGLIN, EntityTypes1_16.COW).jsonName();
mapEntityTypeWithData(EntityTypes1_16.ZOGLIN, EntityTypes1_16.COW).jsonName();
mapEntityTypeWithData(EntityTypes1_16.PIGLIN, EntityTypes1_16.ZOMBIFIED_PIGLIN).jsonName();
mapEntityTypeWithData(EntityTypes1_16.STRIDER, EntityTypes1_16.MAGMA_CUBE).jsonName();
}
@Override
public EntityType typeFromId(int typeId) {
return EntityTypes1_16.getTypeFromId(typeId);
@@ -47,6 +47,7 @@ public class Protocol1_16_1To1_16_2 extends BackwardsProtocol<ClientboundPackets
private final EntityPackets1_16_2 entityRewriter = new EntityPackets1_16_2(this);
private final BlockItemPackets1_16_2 blockItemPackets = new BlockItemPackets1_16_2(this);
private final TranslatableRewriter<ClientboundPackets1_16_2> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_16_2> tagRewriter = new TagRewriter<>(this);
public Protocol1_16_1To1_16_2() {
super(ClientboundPackets1_16_2.class, ClientboundPackets1_16.class, ServerboundPackets1_16_2.class, ServerboundPackets1_16.class);
@@ -74,7 +75,7 @@ public class Protocol1_16_1To1_16_2 extends BackwardsProtocol<ClientboundPackets
registerClientbound(ClientboundPackets1_16_2.CHAT_MESSAGE, wrapper -> {
JsonElement message = wrapper.passthrough(Type.COMPONENT);
translatableRewriter.processText(message);
translatableRewriter.processText(wrapper.user(), message);
byte position = wrapper.passthrough(Type.BYTE);
if (position == 2) { // https://bugs.mojang.com/browse/MC-119145
wrapper.clearPacket();
@@ -101,7 +102,7 @@ public class Protocol1_16_1To1_16_2 extends BackwardsProtocol<ClientboundPackets
}
});
new TagRewriter<>(this).register(ClientboundPackets1_16_2.TAGS, RegistryType.ENTITY);
tagRewriter.register(ClientboundPackets1_16_2.TAGS, RegistryType.ENTITY);
new StatisticsRewriter<>(this).register(ClientboundPackets1_16_2.STATISTICS);
}
@@ -142,4 +143,9 @@ public class Protocol1_16_1To1_16_2 extends BackwardsProtocol<ClientboundPackets
public BlockItemPackets1_16_2 getItemRewriter() {
return blockItemPackets;
}
@Override
public TagRewriter<ClientboundPackets1_16_2> getTagRewriter() {
return tagRewriter;
}
}
@@ -18,7 +18,7 @@
package com.viaversion.viabackwards.protocol.protocol1_16_1to1_16_2.data;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.data.VBMappingDataLoader;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
@@ -117,7 +117,7 @@ public final class BiomeMappings {
MODERN_TO_LEGACY_ID.put(entry.getKey(), entry.getIntValue());
}
final JsonObject mappings = VBMappingDataLoader.loadFromDataDir("biome-mappings.json");
final JsonObject mappings = BackwardsMappingDataLoader.INSTANCE.loadFromDataDir("biome-mappings.json");
for (final Map.Entry<String, JsonElement> entry : mappings.entrySet()) {
final int legacyBiome = LEGACY_BIOMES.getInt(entry.getValue().getAsString());
if (legacyBiome == -1) {
@@ -17,6 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_16_1to1_16_2.packets;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_16_1to1_16_2.Protocol1_16_1To1_16_2;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord1_8;
@@ -37,7 +38,7 @@ import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.ServerboundPacke
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
public class BlockItemPackets1_16_2 extends com.viaversion.viabackwards.api.rewriters.ItemRewriter<ClientboundPackets1_16_2, ServerboundPackets1_16, Protocol1_16_1To1_16_2> {
public class BlockItemPackets1_16_2 extends BackwardsItemRewriter<ClientboundPackets1_16_2, ServerboundPackets1_16, Protocol1_16_1To1_16_2> {
public BlockItemPackets1_16_2(Protocol1_16_1To1_16_2 protocol) {
super(protocol, Type.ITEM1_13_2, Type.ITEM1_13_2_SHORT_ARRAY);
@@ -133,7 +134,7 @@ public class BlockItemPackets1_16_2 extends com.viaversion.viabackwards.api.rewr
registerClickWindow(ServerboundPackets1_16.CLICK_WINDOW);
registerCreativeInvAction(ServerboundPackets1_16.CREATIVE_INVENTORY_ACTION);
protocol.registerServerbound(ServerboundPackets1_16.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.passthrough(Type.ITEM1_13_2)));
protocol.registerServerbound(ServerboundPackets1_16.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)));
}
private void handleBlockEntity(CompoundTag tag) {
@@ -149,7 +150,7 @@ public class BlockItemPackets1_16_2 extends com.viaversion.viabackwards.api.rewr
CompoundTag properties = skullOwnerTag.getCompoundTag("Properties");
if (properties == null) return;
ListTag textures = properties.getListTag("textures");
ListTag<CompoundTag> textures = properties.getListTag("textures", CompoundTag.class);
if (textures == null) return;
CompoundTag first = !textures.isEmpty() ? textures.get(0) : null;
@@ -23,7 +23,6 @@ import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.protocol1_16_1to1_16_2.Protocol1_16_1To1_16_2;
import com.viaversion.viabackwards.protocol.protocol1_16_1to1_16_2.storage.BiomeStorage;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_16;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_16_2;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
@@ -33,9 +32,10 @@ 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.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ClientboundPackets1_16_2;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.EntityPackets;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.TagUtil;
import java.util.Set;
public class EntityPackets1_16_2 extends EntityRewriter<ClientboundPackets1_16_2, Protocol1_16_1To1_16_2> {
@@ -73,16 +73,14 @@ public class EntityPackets1_16_2 extends EntityRewriter<ClientboundPackets1_16_2
map(Type.STRING_ARRAY); // World List
handler(wrapper -> {
CompoundTag registry = wrapper.read(Type.NAMED_COMPOUND_TAG);
if (wrapper.user().getProtocolInfo().getProtocolVersion() <= ProtocolVersion.v1_15_2.getVersion()) {
if (wrapper.user().getProtocolInfo().protocolVersion().olderThanOrEqualTo(ProtocolVersion.v1_15_2)) {
// Store biomes for <1.16 client handling
CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
ListTag biomes = biomeRegistry.get("value");
ListTag<CompoundTag> biomes = TagUtil.getRegistryEntries(registry, "worldgen/biome");
BiomeStorage biomeStorage = wrapper.user().get(BiomeStorage.class);
biomeStorage.clear();
for (Tag biome : biomes) {
CompoundTag biomeCompound = (CompoundTag) biome;
StringTag name = biomeCompound.get("name");
NumberTag id = biomeCompound.get("id");
for (CompoundTag biome : biomes) {
StringTag name = biome.getStringTag("name");
NumberTag id = biome.getNumberTag("id");
biomeStorage.addBiome(name.getValue(), id.asInt());
}
} else if (!warned) {
@@ -115,8 +113,8 @@ public class EntityPackets1_16_2 extends EntityRewriter<ClientboundPackets1_16_2
private String getDimensionFromData(CompoundTag dimensionData) {
// This may technically break other custom dimension settings for 1.16/1.16.1 clients, so those cases are considered semi "unsupported" here
StringTag effectsLocation = dimensionData.get("effects");
return effectsLocation != null && oldDimensions.contains(effectsLocation.getValue()) ?
StringTag effectsLocation = dimensionData.getStringTag("effects");
return effectsLocation != null && oldDimensions.contains(Key.namespaced(effectsLocation.getValue())) ?
effectsLocation.getValue() : "minecraft:overworld";
}
@@ -125,13 +123,17 @@ public class EntityPackets1_16_2 extends EntityRewriter<ClientboundPackets1_16_2
registerMetaTypeHandler(Types1_16.META_TYPES.itemType, Types1_16.META_TYPES.blockStateType, null,
Types1_16.META_TYPES.particleType, Types1_16.META_TYPES.componentType, Types1_16.META_TYPES.optionalComponentType);
mapTypes(EntityTypes1_16_2.values(), EntityTypes1_16.class);
mapEntityTypeWithData(EntityTypes1_16_2.PIGLIN_BRUTE, EntityTypes1_16_2.PIGLIN).jsonName();
filter().type(EntityTypes1_16_2.ABSTRACT_PIGLIN).index(15).toIndex(16);
filter().type(EntityTypes1_16_2.ABSTRACT_PIGLIN).index(16).toIndex(15);
}
@Override
public void onMappingDataLoaded() {
mapTypes();
mapEntityTypeWithData(EntityTypes1_16_2.PIGLIN_BRUTE, EntityTypes1_16_2.PIGLIN).jsonName();
}
@Override
public EntityType typeFromId(int typeId) {
return EntityTypes1_16_2.getTypeFromId(typeId);
@@ -59,6 +59,7 @@ public final class Protocol1_16_4To1_17 extends BackwardsProtocol<ClientboundPac
private final EntityPackets1_17 entityRewriter = new EntityPackets1_17(this);
private final BlockItemPackets1_17 blockItemPackets = new BlockItemPackets1_17(this);
private final TranslatableRewriter<ClientboundPackets1_17> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_17> tagRewriter = new TagRewriter<>(this);
public Protocol1_16_4To1_17() {
super(ClientboundPackets1_17.class, ClientboundPackets1_16_2.class, ServerboundPackets1_17.class, ServerboundPackets1_16_2.class);
@@ -81,7 +82,6 @@ public final class Protocol1_16_4To1_17 extends BackwardsProtocol<ClientboundPac
soundRewriter.registerNamedSound(ClientboundPackets1_17.NAMED_SOUND);
soundRewriter.registerStopSound(ClientboundPackets1_17.STOP_SOUND);
TagRewriter<ClientboundPackets1_17> tagRewriter = new TagRewriter<>(this);
registerClientbound(ClientboundPackets1_17.TAGS, wrapper -> {
Map<String, List<TagData>> tags = new HashMap<>();
@@ -249,4 +249,9 @@ public final class Protocol1_16_4To1_17 extends BackwardsProtocol<ClientboundPac
public BlockItemPackets1_17 getItemRewriter() {
return blockItemPackets;
}
@Override
public TagRewriter<ClientboundPackets1_17> getTagRewriter() {
return tagRewriter;
}
}
@@ -18,7 +18,7 @@
package com.viaversion.viabackwards.protocol.protocol1_16_4to1_17.packets;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.api.rewriters.MapColorRewriter;
import com.viaversion.viabackwards.protocol.protocol1_16_4to1_17.Protocol1_16_4To1_17;
import com.viaversion.viabackwards.protocol.protocol1_16_4to1_17.data.MapColorRewrites;
@@ -53,7 +53,7 @@ import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
public final class BlockItemPackets1_17 extends ItemRewriter<ClientboundPackets1_17, ServerboundPackets1_16_2, Protocol1_16_4To1_17> {
public final class BlockItemPackets1_17 extends BackwardsItemRewriter<ClientboundPackets1_17, ServerboundPackets1_16_2, Protocol1_16_4To1_17> {
public BlockItemPackets1_17(Protocol1_16_4To1_17 protocol) {
super(protocol, Type.ITEM1_13_2, Type.ITEM1_13_2_SHORT_ARRAY);
@@ -77,7 +77,7 @@ public final class BlockItemPackets1_17 extends ItemRewriter<ClientboundPackets1
registerCreativeInvAction(ServerboundPackets1_16_2.CREATIVE_INVENTORY_ACTION);
protocol.registerServerbound(ServerboundPackets1_16_2.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.passthrough(Type.ITEM1_13_2)));
protocol.registerServerbound(ServerboundPackets1_16_2.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)));
// TODO Since the carried and modified items are typically set incorrectly, the server sends unnecessary
// set slot packets after practically every window click, since it thinks the client and server
@@ -95,7 +95,7 @@ public final class BlockItemPackets1_17 extends ItemRewriter<ClientboundPackets1
byte button = wrapper.passthrough(Type.BYTE); // Button
wrapper.read(Type.SHORT); // Action id - removed
int mode = wrapper.passthrough(Type.VAR_INT); // Mode
Item clicked = handleItemToServer(wrapper.read(Type.ITEM1_13_2)); // Clicked item
Item clicked = handleItemToServer(wrapper.user(), wrapper.read(Type.ITEM1_13_2)); // Clicked item
// The 1.17 client would check the entire inventory for changes before -> after a click and send the changed slots here
wrapper.write(Type.VAR_INT, 0); // Empty array of slot+item
@@ -152,7 +152,7 @@ public final class BlockItemPackets1_17 extends ItemRewriter<ClientboundPackets1
wrapper.user().get(PlayerLastCursorItem.class).setLastCursorItem(carried);
}
wrapper.write(Type.ITEM1_13_2, handleItemToClient(carried));
wrapper.write(Type.ITEM1_13_2, handleItemToClient(wrapper.user(), carried));
});
protocol.registerServerbound(ServerboundPackets1_16_2.WINDOW_CONFIRMATION, null, wrapper -> {
@@ -339,6 +339,10 @@ public final class BlockItemPackets1_17 extends ItemRewriter<ClientboundPackets1
CompoundTag heightMaps = chunk.getHeightMap();
for (Tag heightMapTag : heightMaps.values()) {
if (!(heightMapTag instanceof LongArrayTag)) {
continue; // Client can handle bad data
}
LongArrayTag heightMap = (LongArrayTag) heightMapTag;
int[] heightMapData = new int[256];
int bitsPerEntry = MathUtil.ceilLog2((currentWorldSectionHeight << 4) + 1);
@@ -22,20 +22,16 @@ import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.protocol1_16_4to1_17.Protocol1_16_4To1_17;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_16_2;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_17;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_16;
import com.viaversion.viaversion.api.type.types.version.Types1_17;
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.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.*;
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ClientboundPackets1_16_2;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ClientboundPackets1_17;
import com.viaversion.viaversion.util.TagUtil;
public final class EntityPackets1_17 extends EntityRewriter<ClientboundPackets1_17, Protocol1_16_4To1_17> {
@@ -84,20 +80,18 @@ public final class EntityPackets1_17 extends EntityRewriter<ClientboundPackets1_
handler(worldDataTrackerHandler(1));
handler(wrapper -> {
CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
ListTag biomes = biomeRegistry.get("value");
for (Tag biome : biomes) {
CompoundTag biomeCompound = ((CompoundTag) biome).get("element");
StringTag category = biomeCompound.get("category");
ListTag<CompoundTag> biomes = TagUtil.getRegistryEntries(registry, "worldgen/biome");
for (CompoundTag biome : biomes) {
CompoundTag biomeCompound = biome.getCompoundTag("element");
StringTag category = biomeCompound.getStringTag("category");
if (category.getValue().equalsIgnoreCase("underground")) {
category.setValue("none");
}
}
CompoundTag dimensionRegistry = registry.get("minecraft:dimension_type");
ListTag dimensions = dimensionRegistry.get("value");
for (Tag dimension : dimensions) {
CompoundTag dimensionCompound = ((CompoundTag) dimension).get("element");
ListTag<CompoundTag> dimensions = TagUtil.getRegistryEntries(registry, "dimension_type");
for (CompoundTag dimension : dimensions) {
CompoundTag dimensionCompound = dimension.getCompoundTag("element");
reduceExtendedHeight(dimensionCompound, false);
}
@@ -157,17 +151,17 @@ public final class EntityPackets1_17 extends EntityRewriter<ClientboundPackets1_
MetaType type = meta.metaType();
if (type == Types1_16.META_TYPES.particleType) {
Particle particle = (Particle) meta.getValue();
if (particle.getId() == 16) { // Dust / Dust Transition
if (particle.id() == 16) { // Dust / Dust Transition
// Remove transition target color values 4-6
particle.getArguments().subList(4, 7).clear();
} else if (particle.getId() == 37) { // Vibration Signal
} else if (particle.id() == 37) { // Vibration Signal
// No nice mapping possible without tracking entity positions and doing particle tasks
particle.setId(0);
particle.getArguments().clear();
return;
}
rewriteParticle(particle);
rewriteParticle(event.user(), particle);
} else if (type == Types1_16.META_TYPES.poseType) {
// Goat LONG_JUMP added at 6
int pose = meta.value();
@@ -183,7 +177,6 @@ public final class EntityPackets1_17 extends EntityRewriter<ClientboundPackets1_
registerMetaTypeHandler(Types1_16.META_TYPES.itemType, Types1_16.META_TYPES.blockStateType, null, null,
Types1_16.META_TYPES.componentType, Types1_16.META_TYPES.optionalComponentType);
mapTypes(EntityTypes1_17.values(), EntityTypes1_16_2.class);
filter().type(EntityTypes1_17.AXOLOTL).cancel(17);
filter().type(EntityTypes1_17.AXOLOTL).cancel(18);
filter().type(EntityTypes1_17.AXOLOTL).cancel(19);
@@ -192,17 +185,21 @@ public final class EntityPackets1_17 extends EntityRewriter<ClientboundPackets1_
filter().type(EntityTypes1_17.GOAT).cancel(17);
mapEntityTypeWithData(EntityTypes1_17.AXOLOTL, EntityTypes1_17.TROPICAL_FISH).jsonName();
mapEntityTypeWithData(EntityTypes1_17.GOAT, EntityTypes1_17.SHEEP).jsonName();
mapEntityTypeWithData(EntityTypes1_17.GLOW_SQUID, EntityTypes1_17.SQUID).jsonName();
mapEntityTypeWithData(EntityTypes1_17.GLOW_ITEM_FRAME, EntityTypes1_17.ITEM_FRAME);
filter().type(EntityTypes1_17.SHULKER).addIndex(17); // TODO Handle attachment pos?
filter().removeIndex(7); // Ticks frozen
}
@Override
public void onMappingDataLoaded() {
mapTypes();
mapEntityTypeWithData(EntityTypes1_17.AXOLOTL, EntityTypes1_17.TROPICAL_FISH).jsonName();
mapEntityTypeWithData(EntityTypes1_17.GOAT, EntityTypes1_17.SHEEP).jsonName();
mapEntityTypeWithData(EntityTypes1_17.GLOW_SQUID, EntityTypes1_17.SQUID).jsonName();
mapEntityTypeWithData(EntityTypes1_17.GLOW_ITEM_FRAME, EntityTypes1_17.ITEM_FRAME);
}
@Override
public EntityType typeFromId(int typeId) {
return EntityTypes1_17.getTypeFromId(typeId);
@@ -214,8 +211,7 @@ public final class EntityPackets1_17 extends EntityRewriter<ClientboundPackets1_
NumberTag logicalHeight = tag.getNumberTag("logical_height");
if (minY.asInt() != 0 || height.asInt() > 256 || logicalHeight.asInt() > 256) {
if (warn && !warned) {
ViaBackwards.getPlatform().getLogger().warning("Custom worlds heights are NOT SUPPORTED for 1.16 players and older and may lead to errors!");
ViaBackwards.getPlatform().getLogger().warning("You have min/max set to " + minY.asInt() + "/" + height.asInt());
ViaBackwards.getPlatform().getLogger().warning("Increased world height is NOT SUPPORTED for 1.16 players and below. They will see a void below y 0 and above 256");
warned = true;
}
@@ -42,6 +42,7 @@ public final class Protocol1_17_1To1_18 extends BackwardsProtocol<ClientboundPac
private final EntityPackets1_18 entityRewriter = new EntityPackets1_18(this);
private final BlockItemPackets1_18 itemRewriter = new BlockItemPackets1_18(this);
private final TranslatableRewriter<ClientboundPackets1_18> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_18> tagRewriter = new TagRewriter<>(this);
public Protocol1_17_1To1_18() {
super(ClientboundPackets1_18.class, ClientboundPackets1_17_1.class, ServerboundPackets1_17.class, ServerboundPackets1_17.class);
@@ -68,7 +69,6 @@ public final class Protocol1_17_1To1_18 extends BackwardsProtocol<ClientboundPac
soundRewriter.registerStopSound(ClientboundPackets1_18.STOP_SOUND);
soundRewriter.registerNamedSound(ClientboundPackets1_18.NAMED_SOUND);
final TagRewriter<ClientboundPackets1_18> tagRewriter = new TagRewriter<>(this);
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:lava_pool_stone_replaceables");
tagRewriter.registerGeneric(ClientboundPackets1_18.TAGS);
@@ -154,4 +154,9 @@ public final class Protocol1_17_1To1_18 extends BackwardsProtocol<ClientboundPac
public TranslatableRewriter<ClientboundPackets1_18> getTranslatableRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_18> getTagRewriter() {
return tagRewriter;
}
}
@@ -22,6 +22,7 @@ import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.Protocol1_18To1_17_1;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.data.BlockEntities;
public final class BackwardsMappings extends com.viaversion.viabackwards.api.data.BackwardsMappings {
@@ -35,7 +36,7 @@ public final class BackwardsMappings extends com.viaversion.viabackwards.api.dat
protected void loadExtras(final CompoundTag data) {
super.loadExtras(data);
for (final Object2IntMap.Entry<String> entry : Protocol1_18To1_17_1.MAPPINGS.blockEntityIds().object2IntEntrySet()) {
for (final Object2IntMap.Entry<String> entry : BlockEntities.blockEntityIds().object2IntEntrySet()) {
blockEntities.put(entry.getIntValue(), entry.getKey());
}
}
@@ -24,7 +24,7 @@ public final class BlockEntityIds {
private static final int[] IDS;
static {
final int[] ids = com.viaversion.viaversion.protocols.protocol1_18to1_17_1.BlockEntityIds.getIds();
final int[] ids = com.viaversion.viaversion.protocols.protocol1_18to1_17_1.data.BlockEntityIds.getIds();
IDS = new int[Arrays.stream(ids).max().getAsInt() + 1];
Arrays.fill(IDS, -1);
for (int i = 0; i < ids.length; i++) {
@@ -17,7 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_17_1to1_18.packets;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_17_1to1_18.Protocol1_17_1To1_18;
import com.viaversion.viabackwards.protocol.protocol1_17_1to1_18.data.BlockEntityIds;
import com.viaversion.viaversion.api.data.ParticleMappings;
@@ -45,7 +45,7 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
public final class BlockItemPackets1_18 extends ItemRewriter<ClientboundPackets1_18, ServerboundPackets1_17, Protocol1_17_1To1_18> {
public final class BlockItemPackets1_18 extends BackwardsItemRewriter<ClientboundPackets1_18, ServerboundPackets1_17, Protocol1_17_1To1_18> {
public BlockItemPackets1_18(final Protocol1_17_1To1_18 protocol) {
super(protocol, Type.ITEM1_13_2, Type.ITEM1_13_2_ARRAY);
@@ -112,7 +112,7 @@ public final class BlockItemPackets1_18 extends ItemRewriter<ClientboundPackets1
int data = wrapper.passthrough(Type.VAR_INT);
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (mappings.isItemParticle(id)) {
handleItemToClient(wrapper.passthrough(Type.ITEM1_13_2));
handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2));
}
int newId = protocol.getMappingData().getNewParticleId(id);
@@ -32,6 +32,7 @@ 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_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.util.TagUtil;
public final class EntityPackets1_18 extends EntityRewriter<ClientboundPackets1_18, Protocol1_17_1To1_18> {
@@ -61,11 +62,10 @@ public final class EntityPackets1_18 extends EntityRewriter<ClientboundPackets1_
handler(worldDataTrackerHandler(1));
handler(wrapper -> {
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
final ListTag biomes = biomeRegistry.get("value");
for (final Tag biome : biomes.getValue()) {
final CompoundTag biomeCompound = ((CompoundTag) biome).get("element");
final StringTag category = biomeCompound.get("category");
final ListTag<CompoundTag> biomes = TagUtil.getRegistryEntries(registry, "worldgen/biome");
for (final CompoundTag biome : biomes) {
final CompoundTag biomeCompound = biome.getCompoundTag("element");
final StringTag category = biomeCompound.getStringTag("category");
if (category.getValue().equals("mountain")) {
category.setValue("extreme_hills");
}
@@ -99,7 +99,7 @@ public final class EntityPackets1_18 extends EntityRewriter<ClientboundPackets1_
MetaType type = meta.metaType();
if (type == Types1_17.META_TYPES.particleType) {
Particle particle = meta.value();
if (particle.getId() == 3) { // Block marker
if (particle.id() == 3) { // Block marker
Particle.ParticleData<?> data = particle.getArguments().remove(0);
int blockState = (int) data.getValue();
if (blockState == 7786) { // Light block
@@ -111,7 +111,7 @@ public final class EntityPackets1_18 extends EntityRewriter<ClientboundPackets1_
return;
}
rewriteParticle(particle);
rewriteParticle(event.user(), particle);
}
});
@@ -102,10 +102,10 @@ public final class Protocol1_17To1_17_1 extends BackwardsProtocol<ClientboundPac
wrapper.passthrough(Type.VAR_INT); // Slot comes first
CompoundTag tag = item.tag();
ListTag pagesTag;
ListTag<StringTag> pagesTag;
StringTag titleTag = null;
// Sanity checks
if (tag == null || (pagesTag = tag.getListTag("pages")) == null
if (tag == null || (pagesTag = tag.getListTag("pages", StringTag.class)) == null
|| (signing && (titleTag = tag.getStringTag("title")) == null)) {
wrapper.write(Type.VAR_INT, 0); // Pages length
wrapper.write(Type.BOOLEAN, false); // Optional title
@@ -114,12 +114,12 @@ public final class Protocol1_17To1_17_1 extends BackwardsProtocol<ClientboundPac
// Write pages - limit them first
if (pagesTag.size() > MAX_PAGES) {
pagesTag = new ListTag(pagesTag.getValue().subList(0, MAX_PAGES));
pagesTag = new ListTag<>(pagesTag.getValue().subList(0, MAX_PAGES));
}
wrapper.write(Type.VAR_INT, pagesTag.size());
for (Tag pageTag : pagesTag) {
String page = ((StringTag) pageTag).getValue();
for (StringTag pageTag : pagesTag) {
String page = pageTag.getValue();
// Limit page length
if (page.length() > MAX_PAGE_LENGTH) {
page = page.substring(0, MAX_PAGE_LENGTH);
@@ -47,8 +47,8 @@ import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.ChatDecorationResult;
import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.Protocol1_19_1To1_19;
import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.data.ChatDecorationResult;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPackets1_19;
import com.viaversion.viaversion.rewriter.CommandRewriter;
@@ -69,6 +69,7 @@ public final class Protocol1_18_2To1_19 extends BackwardsProtocol<ClientboundPac
private final EntityPackets1_19 entityRewriter = new EntityPackets1_19(this);
private final BlockItemPackets1_19 blockItemPackets = new BlockItemPackets1_19(this);
private final TranslatableRewriter<ClientboundPackets1_19> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_19> tagRewriter = new TagRewriter<>(this);
public Protocol1_18_2To1_19() {
super(ClientboundPackets1_19.class, ClientboundPackets1_18.class, ServerboundPackets1_19.class, ServerboundPackets1_17.class);
@@ -131,7 +132,6 @@ public final class Protocol1_18_2To1_19 extends BackwardsProtocol<ClientboundPac
}
});
final TagRewriter<ClientboundPackets1_19> tagRewriter = new TagRewriter<>(this);
tagRewriter.removeTags("minecraft:banner_pattern");
tagRewriter.removeTags("minecraft:instrument");
tagRewriter.removeTags("minecraft:cat_variant");
@@ -200,7 +200,7 @@ public final class Protocol1_18_2To1_19 extends BackwardsProtocol<ClientboundPac
return;
}
translatableRewriter.processText(decorationResult.content());
translatableRewriter.processText(wrapper.user(), decorationResult.content());
wrapper.write(Type.COMPONENT, decorationResult.content());
wrapper.write(Type.BYTE, decorationResult.overlay() ? (byte) 2 : 1);
wrapper.write(Type.UUID, sender);
@@ -216,7 +216,7 @@ public final class Protocol1_18_2To1_19 extends BackwardsProtocol<ClientboundPac
public void register() {
handler(wrapper -> {
final JsonElement content = wrapper.passthrough(Type.COMPONENT);
translatableRewriter.processText(content);
translatableRewriter.processText(wrapper.user(), content);
// Screw everything that isn't a system or game info type (which would only happen on funny 1.19.0 servers)
final int typeId = wrapper.read(Type.VAR_INT);
@@ -290,9 +290,7 @@ public final class Protocol1_18_2To1_19 extends BackwardsProtocol<ClientboundPac
for (int i = 0; i < properties; i++) {
wrapper.read(Type.STRING); // Name
wrapper.read(Type.STRING); // Value
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.STRING); // Signature
}
wrapper.read(Type.OPTIONAL_STRING); // Optional signature
}
});
}
@@ -371,4 +369,9 @@ public final class Protocol1_18_2To1_19 extends BackwardsProtocol<ClientboundPac
public BlockItemPackets1_19 getItemRewriter() {
return blockItemPackets;
}
@Override
public TagRewriter<ClientboundPackets1_19> getTagRewriter() {
return tagRewriter;
}
}
@@ -17,13 +17,12 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_18_2to1_19.data;
import com.viaversion.viabackwards.api.data.VBMappingDataLoader;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
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.ListTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.NumberTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -39,11 +38,10 @@ public final class BackwardsMappings extends com.viaversion.viabackwards.api.dat
protected void loadExtras(final CompoundTag data) {
super.loadExtras(data);
final ListTag chatTypes = VBMappingDataLoader.loadNBT("chat-types-1.19.1.nbt").get("values");
for (final Tag chatType : chatTypes) {
final CompoundTag chatTypeCompound = (CompoundTag) chatType;
final NumberTag idTag = chatTypeCompound.get("id");
defaultChatTypes.put(idTag.asInt(), chatTypeCompound);
final ListTag<CompoundTag> chatTypes = BackwardsMappingDataLoader.INSTANCE.loadNBT("chat-types-1.19.1.nbt").getListTag("values", CompoundTag.class);
for (final CompoundTag chatType : chatTypes) {
final NumberTag idTag = chatType.getNumberTag("id");
defaultChatTypes.put(idTag.asInt(), chatType);
}
}
@@ -17,7 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_18_2to1_19.packets;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_18_2to1_19.Protocol1_18_2To1_19;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
@@ -36,7 +36,7 @@ import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
import com.viaversion.viaversion.util.MathUtil;
public final class BlockItemPackets1_19 extends ItemRewriter<ClientboundPackets1_19, ServerboundPackets1_17, Protocol1_18_2To1_19> {
public final class BlockItemPackets1_19 extends BackwardsItemRewriter<ClientboundPackets1_19, ServerboundPackets1_17, Protocol1_18_2To1_19> {
public BlockItemPackets1_19(final Protocol1_18_2To1_19 protocol) {
super(protocol, Type.ITEM1_13_2, Type.ITEM1_13_2_ARRAY);
@@ -70,12 +70,12 @@ public final class BlockItemPackets1_19 extends ItemRewriter<ClientboundPackets1
final int size = wrapper.read(Type.VAR_INT);
wrapper.write(Type.UNSIGNED_BYTE, (short) size);
for (int i = 0; i < size; i++) {
handleItemToClient(wrapper.passthrough(Type.ITEM1_13_2)); // First item
handleItemToClient(wrapper.passthrough(Type.ITEM1_13_2)); // Result
handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)); // First item
handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)); // Result
final Item secondItem = wrapper.read(Type.ITEM1_13_2);
if (secondItem != null) {
handleItemToClient(secondItem);
handleItemToClient(wrapper.user(), secondItem);
wrapper.write(Type.BOOLEAN, true);
wrapper.write(Type.ITEM1_13_2, secondItem);
} else {
@@ -37,9 +37,10 @@ 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.StringTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.TagUtil;
public final class EntityPackets1_19 extends EntityRewriter<ClientboundPackets1_19, Protocol1_18_2To1_19> {
@@ -108,9 +109,7 @@ public final class EntityPackets1_19 extends EntityRewriter<ClientboundPackets1_
map(Type.BYTE); // Flags
handler(wrapper -> {
// Remove factor data
if (wrapper.read(Type.BOOLEAN)) {
wrapper.read(Type.NAMED_COMPOUND_TAG);
}
wrapper.read(Type.OPTIONAL_NAMED_COMPOUND_TAG);
});
}
});
@@ -129,17 +128,16 @@ public final class EntityPackets1_19 extends EntityRewriter<ClientboundPackets1_
dimensionRegistryStorage.clear();
// Cache dimensions and find current dimension
final String dimensionKey = wrapper.read(Type.STRING);
final String dimensionKey = Key.stripMinecraftNamespace(wrapper.read(Type.STRING));
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
final ListTag dimensions = ((CompoundTag) registry.get("minecraft:dimension_type")).get("value");
final ListTag<CompoundTag> dimensions = TagUtil.getRegistryEntries(registry, "dimension_type");
boolean found = false;
for (final Tag dimension : dimensions) {
final CompoundTag dimensionCompound = (CompoundTag) dimension;
final StringTag nameTag = dimensionCompound.get("name");
final CompoundTag dimensionData = dimensionCompound.get("element");
for (final CompoundTag dimension : dimensions) {
final StringTag nameTag = dimension.getStringTag("name");
final CompoundTag dimensionData = dimension.getCompoundTag("element");
dimensionRegistryStorage.addDimension(nameTag.getValue(), dimensionData.copy());
if (!found && nameTag.getValue().equals(dimensionKey)) {
if (!found && Key.stripMinecraftNamespace(nameTag.getValue()).equals(dimensionKey)) {
wrapper.write(Type.NAMED_COMPOUND_TAG, dimensionData);
found = true;
}
@@ -149,20 +147,18 @@ public final class EntityPackets1_19 extends EntityRewriter<ClientboundPackets1_
}
// Add biome category and track biomes
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
final ListTag biomes = biomeRegistry.get("value");
for (final Tag biome : biomes.getValue()) {
final CompoundTag biomeCompound = ((CompoundTag) biome).get("element");
final ListTag<CompoundTag> biomes = TagUtil.getRegistryEntries(registry, "worldgen/biome");
for (final CompoundTag biome : biomes) {
final CompoundTag biomeCompound = biome.getCompoundTag("element");
biomeCompound.putString("category", "none");
}
tracker(wrapper.user()).setBiomesSent(biomes.size());
// Cache and remove chat types
final ListTag chatTypes = ((CompoundTag) registry.remove("minecraft:chat_type")).get("value");
for (final Tag chatType : chatTypes) {
final CompoundTag chatTypeCompound = (CompoundTag) chatType;
final NumberTag idTag = chatTypeCompound.get("id");
dimensionRegistryStorage.addChatType(idTag.asInt(), chatTypeCompound);
final ListTag<CompoundTag> chatTypes = TagUtil.removeRegistryEntries(registry, "chat_type");
for (final CompoundTag chatType : chatTypes) {
final NumberTag idTag = chatType.getNumberTag("id");
dimensionRegistryStorage.addChatType(idTag.asInt(), chatType);
}
});
map(Type.STRING); // World
@@ -245,21 +241,21 @@ public final class EntityPackets1_19 extends EntityRewriter<ClientboundPackets1_
if (type == Types1_18.META_TYPES.particleType) {
final Particle particle = (Particle) meta.getValue();
final ParticleMappings particleMappings = protocol.getMappingData().getParticleMappings();
if (particle.getId() == particleMappings.id("sculk_charge")) {
if (particle.id() == particleMappings.id("sculk_charge")) {
//TODO
event.cancel();
return;
} else if (particle.getId() == particleMappings.id("shriek")) {
} else if (particle.id() == particleMappings.id("shriek")) {
//TODO
event.cancel();
return;
} else if (particle.getId() == particleMappings.id("vibration")) {
} else if (particle.id() == particleMappings.id("vibration")) {
// Can't do without the position
event.cancel();
return;
}
rewriteParticle(particle);
rewriteParticle(event.user(), particle);
} else if (type == Types1_18.META_TYPES.poseType) {
final int pose = meta.value();
if (pose >= 8) {
@@ -27,9 +27,9 @@ 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.protocols.protocol1_17to1_16_4.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.util.TagUtil;
public final class Protocol1_18To1_18_2 extends BackwardsProtocol<ClientboundPackets1_18, ClientboundPackets1_18, ServerboundPackets1_17, ServerboundPackets1_17> {
@@ -81,10 +81,9 @@ public final class Protocol1_18To1_18_2 extends BackwardsProtocol<ClientboundPac
map(Type.NAMED_COMPOUND_TAG); // Current dimension data
handler(wrapper -> {
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
final CompoundTag dimensionsHolder = registry.get("minecraft:dimension_type");
final ListTag dimensions = dimensionsHolder.get("value");
for (final Tag dimension : dimensions) {
removeTagPrefix(((CompoundTag) dimension).get("element"));
final ListTag<CompoundTag> dimensions = TagUtil.getRegistryEntries(registry, "dimension_type");
for (final CompoundTag dimension : dimensions) {
removeTagPrefix(dimension.getCompoundTag("element"));
}
removeTagPrefix(wrapper.get(Type.NAMED_COMPOUND_TAG, 1));
@@ -96,10 +95,9 @@ public final class Protocol1_18To1_18_2 extends BackwardsProtocol<ClientboundPac
}
private void removeTagPrefix(CompoundTag tag) {
final Tag infiniburnTag = tag.get("infiniburn");
if (infiniburnTag instanceof StringTag) {
final StringTag infiniburn = (StringTag) infiniburnTag;
infiniburn.setValue(infiniburn.getValue().substring(1));
final StringTag infiniburnTag = tag.getStringTag("infiniburn");
if (infiniburnTag != null) {
infiniburnTag.setValue(infiniburnTag.getValue().substring(1));
}
}
}
@@ -30,9 +30,11 @@ import com.viaversion.viabackwards.protocol.protocol1_19_1to1_19_3.storage.Nonce
import com.viaversion.viabackwards.protocol.protocol1_19to1_19_1.Protocol1_19To1_19_1;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.PlayerMessageSignature;
import com.viaversion.viaversion.api.minecraft.ProfileKey;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_19_3;
import com.viaversion.viaversion.api.minecraft.signature.SignableCommandArgumentsProvider;
import com.viaversion.viaversion.api.minecraft.signature.model.MessageMetadata;
@@ -70,6 +72,7 @@ public final class Protocol1_19_1To1_19_3 extends BackwardsProtocol<ClientboundP
private final EntityPackets1_19_3 entityRewriter = new EntityPackets1_19_3(this);
private final BlockItemPackets1_19_3 itemRewriter = new BlockItemPackets1_19_3(this);
private final TranslatableRewriter<ClientboundPackets1_19_3> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_19_3> tagRewriter = new TagRewriter<>(this);
public Protocol1_19_1To1_19_3() {
super(ClientboundPackets1_19_3.class, ClientboundPackets1_19_1.class, ServerboundPackets1_19_3.class, ServerboundPackets1_19_1.class);
@@ -114,7 +117,6 @@ public final class Protocol1_19_1To1_19_3 extends BackwardsProtocol<ClientboundP
wrapper.write(Type.VAR_INT, mappedId);
});
final TagRewriter<ClientboundPackets1_19_3> tagRewriter = new TagRewriter<>(this);
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:non_flammable_wood");
tagRewriter.addEmptyTag(RegistryType.ITEM, "minecraft:overworld_natural_logs");
tagRewriter.registerGeneric(ClientboundPackets1_19_3.TAGS);
@@ -307,7 +309,7 @@ public final class Protocol1_19_1To1_19_3 extends BackwardsProtocol<ClientboundP
final JsonElement unsignedContent = wrapper.read(Type.OPTIONAL_COMPONENT);
final JsonElement content = unsignedContent != null ? unsignedContent : ComponentUtil.plainToJson(plainContent);
translatableRewriter.processText(content);
translatableRewriter.processText(wrapper.user(), content);
final int filterMaskType = wrapper.read(Type.VAR_INT);
if (filterMaskType == 2) {
wrapper.read(Type.LONG_ARRAY_PRIMITIVE); // Mask
@@ -329,7 +331,7 @@ public final class Protocol1_19_1To1_19_3 extends BackwardsProtocol<ClientboundP
});
registerClientbound(ClientboundPackets1_19_3.DISGUISED_CHAT, ClientboundPackets1_19_1.SYSTEM_CHAT, wrapper -> {
final JsonElement content = wrapper.read(Type.COMPONENT);
translatableRewriter.processText(content);
translatableRewriter.processText(wrapper.user(), content);
final int chatTypeId = wrapper.read(Type.VAR_INT);
final JsonElement senderName = wrapper.read(Type.COMPONENT);
final JsonElement targetName = wrapper.read(Type.OPTIONAL_COMPONENT);
@@ -349,9 +351,9 @@ public final class Protocol1_19_1To1_19_3 extends BackwardsProtocol<ClientboundP
}
private @Nullable String rewriteSound(final PacketWrapper wrapper) throws Exception {
final int soundId = wrapper.read(Type.VAR_INT) - 1; // Normalize the id
if (soundId != -1) {
final int mappedId = MAPPINGS.getSoundMappings().getNewId(soundId);
final Holder<SoundEvent> holder = wrapper.read(Type.SOUND_EVENT);
if (holder.hasId()) {
final int mappedId = MAPPINGS.getSoundMappings().getNewId(holder.id());
if (mappedId == -1) {
wrapper.cancel();
return null;
@@ -362,8 +364,7 @@ public final class Protocol1_19_1To1_19_3 extends BackwardsProtocol<ClientboundP
}
// Convert the resource location to the corresponding integer id
final String soundIdentifier = wrapper.read(Type.STRING);
wrapper.read(Type.OPTIONAL_FLOAT); // Fixed range
final String soundIdentifier = holder.value().identifier();
final String mappedIdentifier = MAPPINGS.getMappedNamedSound(soundIdentifier);
if (mappedIdentifier == null) {
return soundIdentifier;
@@ -403,4 +404,9 @@ public final class Protocol1_19_1To1_19_3 extends BackwardsProtocol<ClientboundP
public EntityPackets1_19_3 getEntityRewriter() {
return entityRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_3> getTagRewriter() {
return tagRewriter;
}
}
@@ -17,7 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_19_1to1_19_3.data;
import com.viaversion.viabackwards.api.data.VBMappingDataLoader;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
import com.viaversion.viaversion.libs.gson.JsonArray;
@@ -39,7 +39,7 @@ public final class BackwardsMappings extends com.viaversion.viabackwards.api.dat
protected void loadExtras(final CompoundTag data) {
super.loadExtras(data);
final JsonArray sounds = VBMappingDataLoader.loadData("sounds-1.19.json").getAsJsonArray("sounds");
final JsonArray sounds = BackwardsMappingDataLoader.INSTANCE.loadData("sounds-1.19.json").getAsJsonArray("sounds");
int i = 0;
for (final JsonElement sound : sounds) {
mappedSounds.put(sound.getAsString(), i++);
@@ -17,7 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_19_1to1_19_3.packets;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_19_1to1_19_3.Protocol1_19_1To1_19_3;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@@ -29,7 +29,7 @@ import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
import com.viaversion.viaversion.util.Key;
public final class BlockItemPackets1_19_3 extends ItemRewriter<ClientboundPackets1_19_3, ServerboundPackets1_19_1, Protocol1_19_1To1_19_3> {
public final class BlockItemPackets1_19_3 extends BackwardsItemRewriter<ClientboundPackets1_19_3, ServerboundPackets1_19_1, Protocol1_19_1To1_19_3> {
public BlockItemPackets1_19_3(final Protocol1_19_1To1_19_3 protocol) {
super(protocol, Type.ITEM1_13_2, Type.ITEM1_13_2_ARRAY);
@@ -79,10 +79,10 @@ public final class BlockItemPackets1_19_3 extends ItemRewriter<ClientboundPacket
for (int j = 0; j < ingredients; j++) {
final Item[] items = wrapper.passthrough(Type.ITEM1_13_2_ARRAY); // Ingredients
for (final Item item : items) {
handleItemToClient(item);
handleItemToClient(wrapper.user(), item);
}
}
handleItemToClient(wrapper.passthrough(Type.ITEM1_13_2)); // Result
handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)); // Result
break;
}
case "crafting_shaped": {
@@ -92,10 +92,10 @@ public final class BlockItemPackets1_19_3 extends ItemRewriter<ClientboundPacket
for (int j = 0; j < ingredients; j++) {
final Item[] items = wrapper.passthrough(Type.ITEM1_13_2_ARRAY); // Ingredients
for (final Item item : items) {
handleItemToClient(item);
handleItemToClient(wrapper.user(), item);
}
}
handleItemToClient(wrapper.passthrough(Type.ITEM1_13_2)); // Result
handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)); // Result
break;
}
case "smelting":
@@ -106,9 +106,9 @@ public final class BlockItemPackets1_19_3 extends ItemRewriter<ClientboundPacket
wrapper.read(Type.VAR_INT); // Crafting book category
final Item[] items = wrapper.passthrough(Type.ITEM1_13_2_ARRAY); // Ingredients
for (final Item item : items) {
handleItemToClient(item);
handleItemToClient(wrapper.user(), item);
}
handleItemToClient(wrapper.passthrough(Type.ITEM1_13_2)); // Result
handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)); // Result
wrapper.passthrough(Type.FLOAT); // EXP
wrapper.passthrough(Type.VAR_INT); // Cooking time
break;
@@ -35,10 +35,10 @@ import com.viaversion.viaversion.libs.gson.JsonElement;
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.protocols.protocol1_19_1to1_19.ClientboundPackets1_19_1;
import com.viaversion.viaversion.protocols.protocol1_19_3to1_19_1.ClientboundPackets1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19_3to1_19_1.ServerboundPackets1_19_3;
import com.viaversion.viaversion.util.TagUtil;
import java.util.BitSet;
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -81,12 +81,12 @@ public final class EntityPackets1_19_3 extends EntityRewriter<ClientboundPackets
handler(wrapper -> {
final ChatTypeStorage1_19_3 chatTypeStorage = wrapper.user().get(ChatTypeStorage1_19_3.class);
chatTypeStorage.clear();
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
final ListTag chatTypes = registry.getCompoundTag("minecraft:chat_type").get("value");
for (final Tag chatType : chatTypes) {
final CompoundTag chatTypeCompound = (CompoundTag) chatType;
final NumberTag idTag = chatTypeCompound.get("id");
chatTypeStorage.addChatType(idTag.asInt(), chatTypeCompound);
final ListTag<CompoundTag> chatTypes = TagUtil.getRegistryEntries(registry, "chat_type", new ListTag<>(CompoundTag.class));
for (final CompoundTag chatType : chatTypes) {
final NumberTag idTag = chatType.getNumberTag("id");
chatTypeStorage.addChatType(idTag.asInt(), chatType);
}
});
handler(wrapper -> {
@@ -47,6 +47,7 @@ public final class Protocol1_19_3To1_19_4 extends BackwardsProtocol<ClientboundP
private final EntityPackets1_19_4 entityRewriter = new EntityPackets1_19_4(this);
private final BlockItemPackets1_19_4 itemRewriter = new BlockItemPackets1_19_4(this);
private final TranslatableRewriter<ClientboundPackets1_19_4> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final TagRewriter<ClientboundPackets1_19_4> tagRewriter = new TagRewriter<>(this);
public Protocol1_19_3To1_19_4() {
super(ClientboundPackets1_19_4.class, ClientboundPackets1_19_3.class, ServerboundPackets1_19_4.class, ServerboundPackets1_19_3.class);
@@ -59,7 +60,7 @@ public final class Protocol1_19_3To1_19_4 extends BackwardsProtocol<ClientboundP
final SoundRewriter<ClientboundPackets1_19_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerStopSound(ClientboundPackets1_19_4.STOP_SOUND);
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.SOUND);
soundRewriter.registerSound(ClientboundPackets1_19_4.ENTITY_SOUND);
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.ENTITY_SOUND);
// TODO fallback field in components
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.ACTIONBAR);
@@ -96,7 +97,6 @@ public final class Protocol1_19_3To1_19_4 extends BackwardsProtocol<ClientboundP
}
}.registerDeclareCommands1_19(ClientboundPackets1_19_4.DECLARE_COMMANDS);
final TagRewriter<ClientboundPackets1_19_4> tagRewriter = new TagRewriter<>(this);
tagRewriter.removeTags("minecraft:damage_type");
tagRewriter.registerGeneric(ClientboundPackets1_19_4.TAGS);
@@ -139,4 +139,9 @@ public final class Protocol1_19_3To1_19_4 extends BackwardsProtocol<ClientboundP
public TranslatableRewriter<ClientboundPackets1_19_4> getTranslatableRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_4> getTagRewriter() {
return tagRewriter;
}
}
@@ -17,7 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_19_3to1_19_4.packets;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_19_3to1_19_4.Protocol1_19_3To1_19_4;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@@ -29,7 +29,7 @@ import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPac
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.util.Key;
public final class BlockItemPackets1_19_4 extends ItemRewriter<ClientboundPackets1_19_4, ServerboundPackets1_19_3, Protocol1_19_3To1_19_4> {
public final class BlockItemPackets1_19_4 extends BackwardsItemRewriter<ClientboundPackets1_19_4, ServerboundPackets1_19_3, Protocol1_19_3To1_19_4> {
public BlockItemPackets1_19_4(final Protocol1_19_3To1_19_4 protocol) {
super(protocol, Type.ITEM1_13_2, Type.ITEM1_13_2_ARRAY);
@@ -59,7 +59,7 @@ public final class BlockItemPackets1_19_4 extends ItemRewriter<ClientboundPacket
wrapper.set(Type.VAR_INT, 1, windowType - 1);
}
protocol.getTranslatableRewriter().processText(wrapper.get(Type.COMPONENT, 0));
protocol.getTranslatableRewriter().processText(wrapper.user(), wrapper.get(Type.COMPONENT, 0));
});
}
});
@@ -84,7 +84,7 @@ public final class BlockItemPackets1_19_4 extends ItemRewriter<ClientboundPacket
for (int i = 0; i < ingredients; i++) {
handleIngredient(wrapper);
}
rewrite(wrapper.passthrough(Type.ITEM1_13_2)); // Result
rewrite(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)); // Result
// Remove notification boolean
wrapper.read(Type.BOOLEAN);
@@ -31,9 +31,9 @@ import com.viaversion.viaversion.libs.gson.JsonElement;
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.protocols.protocol1_19_3to1_19_1.ClientboundPackets1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.util.TagUtil;
public final class EntityPackets1_19_4 extends EntityRewriter<ClientboundPackets1_19_4, Protocol1_19_3To1_19_4> {
@@ -63,15 +63,14 @@ public final class EntityPackets1_19_4 extends EntityRewriter<ClientboundPackets
handler(worldDataTrackerHandlerByKey());
handler(wrapper -> {
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
registry.remove("minecraft:trim_pattern");
registry.remove("minecraft:trim_material");
registry.remove("minecraft:damage_type");
TagUtil.removeNamespaced(registry, "trim_pattern");
TagUtil.removeNamespaced(registry, "trim_material");
TagUtil.removeNamespaced(registry, "damage_type");
final CompoundTag biomeRegistry = registry.get("minecraft:worldgen/biome");
final ListTag biomes = biomeRegistry.get("value");
for (final Tag biomeTag : biomes) {
final CompoundTag biomeData = ((CompoundTag) biomeTag).get("element");
final NumberTag hasPrecipitation = biomeData.get("has_precipitation");
final ListTag<CompoundTag> biomes = TagUtil.getRegistryEntries(registry, "worldgen/biome");
for (final CompoundTag biomeTag : biomes) {
final CompoundTag biomeData = biomeTag.getCompoundTag("element");
final NumberTag hasPrecipitation = biomeData.getNumberTag("has_precipitation");
biomeData.putString("precipitation", hasPrecipitation.asByte() == 1 ? "rain" : "none");
}
});
@@ -164,7 +163,7 @@ public final class EntityPackets1_19_4 extends EntityRewriter<ClientboundPackets
event.createExtraMeta(new Metadata(3, Types1_19_3.META_TYPES.booleanType, true)); // Show custom name
final JsonElement element = meta.value();
protocol.getTranslatableRewriter().processText(element);
protocol.getTranslatableRewriter().processText(event.user(), element);
}));
filter().type(EntityTypes1_19_4.DISPLAY).handler((event, meta) -> {
// TODO Maybe spawn an extra entity to ride the armor stand for blocks and items
@@ -41,6 +41,7 @@ public final class Protocol1_19_4To1_20 extends BackwardsProtocol<ClientboundPac
private final TranslatableRewriter<ClientboundPackets1_19_4> translatableRewriter = new TranslatableRewriter<>(this, ComponentRewriter.ReadType.JSON);
private final EntityPackets1_20 entityRewriter = new EntityPackets1_20(this);
private final BlockItemPackets1_20 itemRewriter = new BlockItemPackets1_20(this);
private final TagRewriter<ClientboundPackets1_19_4> tagRewriter = new TagRewriter<>(this);
public Protocol1_19_4To1_20() {
super(ClientboundPackets1_19_4.class, ClientboundPackets1_19_4.class, ServerboundPackets1_19_4.class, ServerboundPackets1_19_4.class);
@@ -50,14 +51,13 @@ public final class Protocol1_19_4To1_20 extends BackwardsProtocol<ClientboundPac
protected void registerPackets() {
super.registerPackets();
final TagRewriter<ClientboundPackets1_19_4> tagRewriter = new TagRewriter<>(this);
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:replaceable_plants");
tagRewriter.registerGeneric(ClientboundPackets1_19_4.TAGS);
final SoundRewriter<ClientboundPackets1_19_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerStopSound(ClientboundPackets1_19_4.STOP_SOUND);
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.SOUND);
soundRewriter.registerSound(ClientboundPackets1_19_4.ENTITY_SOUND);
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.ENTITY_SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_4.STATISTICS);
@@ -87,7 +87,7 @@ public final class Protocol1_19_4To1_20 extends BackwardsProtocol<ClientboundPac
registerClientbound(ClientboundPackets1_19_4.COMBAT_KILL, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Duration
wrapper.write(Type.INT, -1); // Killer ID - unused (who knows for how long?)
translatableRewriter.processText(wrapper.passthrough(Type.COMPONENT));
translatableRewriter.processText(wrapper.user(), wrapper.passthrough(Type.COMPONENT));
});
}
@@ -115,4 +115,9 @@ public final class Protocol1_19_4To1_20 extends BackwardsProtocol<ClientboundPac
public TranslatableRewriter<ClientboundPackets1_19_4> getTranslatableRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPackets1_19_4> getTagRewriter() {
return tagRewriter;
}
}
@@ -17,7 +17,7 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_19_4to1_20.data;
import com.viaversion.viabackwards.api.data.VBMappingDataLoader;
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.Protocol1_20To1_19_4;
@@ -33,7 +33,7 @@ public class BackwardsMappings extends com.viaversion.viabackwards.api.data.Back
protected void loadExtras(CompoundTag data) {
super.loadExtras(data);
trimPatternRegistry = VBMappingDataLoader.loadNBT("trim_pattern-1.19.4.nbt");
trimPatternRegistry = BackwardsMappingDataLoader.INSTANCE.loadNBT("trim_pattern-1.19.4.nbt");
}
public CompoundTag getTrimPatternRegistry() {
@@ -17,9 +17,10 @@
*/
package com.viaversion.viabackwards.protocol.protocol1_19_4to1_20.packets;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_19_4to1_20.Protocol1_19_4To1_20;
import com.viaversion.viabackwards.protocol.protocol1_19_4to1_20.storage.BackSignEditStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
@@ -41,7 +42,7 @@ import java.util.HashSet;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class BlockItemPackets1_20 extends ItemRewriter<ClientboundPackets1_19_4, ServerboundPackets1_19_4, Protocol1_19_4To1_20> {
public final class BlockItemPackets1_20 extends BackwardsItemRewriter<ClientboundPackets1_19_4, ServerboundPackets1_19_4, Protocol1_19_4To1_20> {
private static final Set<String> NEW_TRIM_PATTERNS = new HashSet<>(Arrays.asList("host", "raiser", "shaper", "silence", "wayfinder"));
@@ -60,7 +61,7 @@ public final class BlockItemPackets1_20 extends ItemRewriter<ClientboundPackets1
protocol.registerClientbound(ClientboundPackets1_19_4.CHUNK_DATA, new PacketHandlers() {
@Override
protected void register() {
handler(blockRewriter.chunkDataHandler1_19(ChunkType1_18::new, BlockItemPackets1_20.this::handleBlockEntity));
handler(blockRewriter.chunkDataHandler1_19(ChunkType1_18::new, (user, blockEntity) -> handleBlockEntity(blockEntity)));
create(Type.BOOLEAN, true); // Trust edges
}
});
@@ -100,16 +101,13 @@ public final class BlockItemPackets1_20 extends ItemRewriter<ClientboundPackets1
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)) {
wrapper.passthrough(Type.COMPONENT); // Title
wrapper.passthrough(Type.COMPONENT); // Description
handleItemToClient(wrapper.passthrough(Type.ITEM1_13_2)); // Icon
handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_13_2)); // Icon
wrapper.passthrough(Type.VAR_INT); // Frame type
int flags = wrapper.passthrough(Type.INT); // Flags
if ((flags & 1) != 0) {
@@ -150,12 +148,12 @@ public final class BlockItemPackets1_20 extends ItemRewriter<ClientboundPackets1
}
@Override
public @Nullable Item handleItemToClient(@Nullable final Item item) {
public @Nullable Item handleItemToClient(UserConnection connection, @Nullable final Item item) {
if (item == null) {
return null;
}
super.handleItemToClient(item);
super.handleItemToClient(connection, item);
// Remove new trim tags
final CompoundTag trimTag;
@@ -166,7 +164,7 @@ public final class BlockItemPackets1_20 extends ItemRewriter<ClientboundPackets1
final String pattern = Key.stripMinecraftNamespace(patternTag.getValue());
if (NEW_TRIM_PATTERNS.contains(pattern)) {
tag.remove("Trim");
tag.put(nbtTagName + "|Trim", trimTag);
tag.put(nbtTagName("Trim"), trimTag);
}
}
}
@@ -174,17 +172,17 @@ public final class BlockItemPackets1_20 extends ItemRewriter<ClientboundPackets1
}
@Override
public @Nullable Item handleItemToServer(@Nullable final Item item) {
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable final Item item) {
if (item == null) {
return null;
}
super.handleItemToServer(item);
super.handleItemToServer(connection, item);
// Add back original trim tag
final Tag trimTag;
final CompoundTag tag = item.tag();
if (tag != null && (trimTag = tag.remove(nbtTagName + "|Trim")) != null) {
if (tag != null && (trimTag = tag.remove(nbtTagName("Trim"))) != null) {
tag.put("Trim", trimTag);
}
return item;
@@ -218,13 +216,13 @@ public final class BlockItemPackets1_20 extends ItemRewriter<ClientboundPackets1
}
private void writeMessages(final CompoundTag frontText, final CompoundTag tag, final boolean filtered) {
final ListTag messages = frontText.getListTag(filtered ? "filtered_messages" : "messages");
final ListTag<StringTag> messages = frontText.getListTag(filtered ? "filtered_messages" : "messages", StringTag.class);
if (messages == null) {
return;
}
int i = 0;
for (final Tag message : messages) {
for (final StringTag message : messages) {
tag.put((filtered ? "FilteredText" : "Text") + ++i, message);
}
@@ -80,21 +80,21 @@ public final class EntityPackets1_20 extends EntityRewriter<ClientboundPackets1_
handler(wrapper -> {
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
final ListTag values;
final ListTag<CompoundTag> values;
// A 1.20 server can't send this element, and the 1.20 client still works, if the element is missing
// on a 1.19.4 client there is an exception, so in case the 1.20 server doesn't send the element we put in an original 1.20 element
final CompoundTag trimPatternTag = registry.getCompoundTag("minecraft:trim_pattern");
if (trimPatternTag != null) {
values = trimPatternTag.getListTag("value");
CompoundTag trimPatternTag = registry.getCompoundTag("minecraft:trim_pattern");
if (trimPatternTag != null || (trimPatternTag = registry.getCompoundTag("trim_pattern")) != null) {
values = trimPatternTag.getListTag("value", CompoundTag.class);
} else {
final CompoundTag trimPatternRegistry = Protocol1_19_4To1_20.MAPPINGS.getTrimPatternRegistry().copy();
registry.put("minecraft:trim_pattern", trimPatternRegistry);
values = trimPatternRegistry.get("value");
values = trimPatternRegistry.getListTag("value", CompoundTag.class);
}
for (final Tag entry : values) {
final CompoundTag element = ((CompoundTag) entry).get("element");
final StringTag templateItem = element.get("template_item");
for (final CompoundTag entry : values) {
final CompoundTag element = entry.getCompoundTag("element");
final StringTag templateItem = element.getStringTag("template_item");
if (newTrimPatterns.contains(Key.stripMinecraftNamespace(templateItem.getValue()))) {
templateItem.setValue("minecraft:spire_armor_trim_smithing_template");
}
@@ -43,19 +43,19 @@ import com.viaversion.viaversion.libs.gson.JsonElement;
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.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.ClientboundPackets1_19_1;
import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.Protocol1_19_1To1_19;
import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.ServerboundPackets1_19_1;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPackets1_19;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets.EntityPackets;
import com.viaversion.viaversion.rewriter.ComponentRewriter;
import com.viaversion.viaversion.util.CipherUtil;
import com.viaversion.viaversion.util.ComponentUtil;
import com.viaversion.viaversion.util.Pair;
import com.viaversion.viaversion.util.TagUtil;
import java.util.List;
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -103,16 +103,15 @@ public final class Protocol1_19To1_19_1 extends BackwardsProtocol<ClientboundPac
chatTypeStorage.clear();
final CompoundTag registry = wrapper.get(Type.NAMED_COMPOUND_TAG, 0);
final ListTag chatTypes = registry.getCompoundTag("minecraft:chat_type").get("value");
for (final Tag chatType : chatTypes) {
final CompoundTag chatTypeCompound = (CompoundTag) chatType;
final NumberTag idTag = chatTypeCompound.get("id");
chatTypeStorage.addChatType(idTag.asInt(), chatTypeCompound);
final ListTag<CompoundTag> chatTypes = TagUtil.removeRegistryEntries(registry, "chat_type", new ListTag<>(CompoundTag.class));
for (final CompoundTag chatType : chatTypes) {
final NumberTag idTag = chatType.getNumberTag("id");
chatTypeStorage.addChatType(idTag.asInt(), chatType);
}
// Replace with 1.19 chat types
// Ensures that the client has a chat type for system message, with and without overlay
registry.put("minecraft:chat_type", EntityPackets.CHAT_REGISTRY.copy());
registry.put("minecraft:chat_type", Protocol1_19To1_18_2.MAPPINGS.chatRegistry());
});
handler(entityRewriter.worldTrackerHandlerByKey());
}
@@ -173,14 +172,14 @@ public final class Protocol1_19To1_19_1 extends BackwardsProtocol<ClientboundPac
return;
}
translatableRewriter.processText(decoratedMessage);
translatableRewriter.processText(wrapper.user(), decoratedMessage);
wrapper.write(Type.COMPONENT, decoratedMessage);
wrapper.write(Type.VAR_INT, SYSTEM_CHAT_ID);
});
registerClientbound(ClientboundPackets1_19_1.SYSTEM_CHAT, wrapper -> {
final JsonElement content = wrapper.passthrough(Type.COMPONENT);
translatableRewriter.processText(content);
translatableRewriter.processText(wrapper.user(), content);
final boolean overlay = wrapper.read(Type.BOOLEAN);
wrapper.write(Type.VAR_INT, overlay ? GAME_INFO_ID : SYSTEM_CHAT_ID);
@@ -28,10 +28,9 @@ import com.viaversion.viabackwards.protocol.protocol1_20_2to1_20_3.storage.Spawn
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_3;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
@@ -40,12 +39,16 @@ import com.viaversion.viaversion.libs.fastutil.Pair;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.CommandRewriter1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPacket1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPacket1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.Protocol1_20_3To1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPackets1_20_3;
import com.viaversion.viaversion.rewriter.ComponentRewriter.ReadType;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
@@ -54,31 +57,33 @@ import com.viaversion.viaversion.util.ComponentUtil;
import java.util.BitSet;
import java.util.UUID;
public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundPackets1_20_3, ClientboundPackets1_20_2, ServerboundPackets1_20_3, ServerboundPackets1_20_2> {
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundPacket1_20_3, ClientboundPacket1_20_2, ServerboundPacket1_20_3, ServerboundPacket1_20_2> {
public static final BackwardsMappings MAPPINGS = new BackwardsMappings("1.20.3", "1.20.2", Protocol1_20_3To1_20_2.class);
private final EntityPacketRewriter1_20_3 entityRewriter = new EntityPacketRewriter1_20_3(this);
private final BlockItemPacketRewriter1_20_3 itemRewriter = new BlockItemPacketRewriter1_20_3(this);
private final TranslatableRewriter<ClientboundPackets1_20_3> translatableRewriter = new TranslatableRewriter<>(this, ReadType.NBT);
private final TranslatableRewriter<ClientboundPacket1_20_3> translatableRewriter = new TranslatableRewriter<>(this, ReadType.NBT);
private final TagRewriter<ClientboundPacket1_20_3> tagRewriter = new TagRewriter<>(this);
public Protocol1_20_2To1_20_3() {
super(ClientboundPackets1_20_3.class, ClientboundPackets1_20_2.class, ServerboundPackets1_20_3.class, ServerboundPackets1_20_2.class);
super(ClientboundPacket1_20_3.class, ClientboundPacket1_20_2.class, ServerboundPacket1_20_3.class, ServerboundPacket1_20_2.class);
}
@Override
protected void registerPackets() {
super.registerPackets();
final TagRewriter<ClientboundPackets1_20_3> tagRewriter = new TagRewriter<>(this);
tagRewriter.registerGeneric(ClientboundPackets1_20_3.TAGS);
final SoundRewriter<ClientboundPackets1_20_3> soundRewriter = new SoundRewriter<>(this);
final SoundRewriter<ClientboundPacket1_20_3> soundRewriter = new SoundRewriter<>(this);
soundRewriter.register1_19_3Sound(ClientboundPackets1_20_3.SOUND);
soundRewriter.registerEntitySound(ClientboundPackets1_20_3.ENTITY_SOUND);
soundRewriter.register1_19_3Sound(ClientboundPackets1_20_3.ENTITY_SOUND);
soundRewriter.registerStopSound(ClientboundPackets1_20_3.STOP_SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_20_3.STATISTICS);
new CommandRewriter1_19_4<ClientboundPackets1_20_3>(this) {
new CommandRewriter1_19_4<ClientboundPacket1_20_3>(this) {
@Override
public void handleArgument(final PacketWrapper wrapper, final String argumentType) throws Exception {
if (argumentType.equals("minecraft:style")) {
@@ -137,17 +142,13 @@ public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundP
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)) {
convertComponent(wrapper); // Title
convertComponent(wrapper); // Description
itemRewriter.handleItemToClient(wrapper.passthrough(Type.ITEM1_20_2)); // Icon
itemRewriter.handleItemToClient(wrapper.user(), wrapper.passthrough(Type.ITEM1_20_2)); // Icon
wrapper.passthrough(Type.VAR_INT); // Frame type
final int flags = wrapper.passthrough(Type.INT);
if ((flags & 1) != 0) {
@@ -240,7 +241,7 @@ public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundP
}
});
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.DISCONNECT.getId(), ClientboundConfigurationPackets1_20_2.DISCONNECT.getId(), this::convertComponent);
registerClientbound(ClientboundConfigurationPackets1_20_3.DISCONNECT, this::convertComponent);
registerClientbound(ClientboundPackets1_20_3.DISCONNECT, this::convertComponent);
registerClientbound(ClientboundPackets1_20_3.RESOURCE_PACK_PUSH, ClientboundPackets1_20_2.RESOURCE_PACK, resourcePackHandler());
registerClientbound(ClientboundPackets1_20_3.SERVER_DATA, this::convertComponent);
@@ -338,12 +339,10 @@ public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundP
cancelClientbound(ClientboundPackets1_20_3.RESOURCE_PACK_POP);
registerServerbound(ServerboundPackets1_20_2.RESOURCE_PACK_STATUS, resourcePackStatusHandler());
cancelClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_3.RESOURCE_PACK_POP.getId());
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK, resourcePackStatusHandler());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_3.RESOURCE_PACK_PUSH.getId(), ClientboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), resourcePackHandler());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_3.UPDATE_TAGS.getId(), ClientboundConfigurationPackets1_20_2.UPDATE_TAGS.getId(), tagRewriter.getGenericHandler());
// TODO Auto map via packet types provider
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_3.UPDATE_ENABLED_FEATURES.getId(), ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES.getId());
cancelClientbound(ClientboundConfigurationPackets1_20_3.RESOURCE_PACK_POP);
registerServerbound(ServerboundConfigurationPackets1_20_2.RESOURCE_PACK, resourcePackStatusHandler());
registerClientbound(ClientboundConfigurationPackets1_20_3.RESOURCE_PACK_PUSH, ClientboundConfigurationPackets1_20_2.RESOURCE_PACK, resourcePackHandler());
registerClientbound(ClientboundConfigurationPackets1_20_3.UPDATE_TAGS, tagRewriter.getGenericHandler());
}
private PacketHandler resourcePackStatusHandler() {
@@ -367,13 +366,13 @@ public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundP
private void convertComponent(final PacketWrapper wrapper) throws Exception {
final Tag tag = wrapper.read(Type.TAG);
translatableRewriter.processTag(tag);
translatableRewriter.processTag(wrapper.user(), tag);
wrapper.write(Type.COMPONENT, ComponentUtil.tagToJson(tag));
}
private void convertOptionalComponent(final PacketWrapper wrapper) throws Exception {
final Tag tag = wrapper.read(Type.OPTIONAL_TAG);
translatableRewriter.processTag(tag);
translatableRewriter.processTag(wrapper.user(), tag);
wrapper.write(Type.OPTIONAL_COMPONENT, ComponentUtil.tagToJson(tag));
}
@@ -383,16 +382,6 @@ public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundP
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_20_3.PLAYER));
}
@Override
protected ServerboundPacketType serverboundFinishConfigurationPacket() {
return ServerboundConfigurationPackets1_20_2.FINISH_CONFIGURATION;
}
@Override
protected ClientboundPacketType clientboundFinishConfigurationPacket() {
return ClientboundConfigurationPackets1_20_3.FINISH_CONFIGURATION;
}
@Override
public BackwardsMappings getMappingData() {
return MAPPINGS;
@@ -409,7 +398,22 @@ public final class Protocol1_20_2To1_20_3 extends BackwardsProtocol<ClientboundP
}
@Override
public TranslatableRewriter<ClientboundPackets1_20_3> getTranslatableRewriter() {
public TranslatableRewriter<ClientboundPacket1_20_3> getTranslatableRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_20_3> getTagRewriter() {
return tagRewriter;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_20_3, ClientboundPacket1_20_2, ServerboundPacket1_20_3, ServerboundPacket1_20_2> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_20_3.class, ClientboundConfigurationPackets1_20_3.class),
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_20_2.class, ClientboundConfigurationPackets1_20_2.class),
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_3.class, ServerboundConfigurationPackets1_20_2.class),
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_20_2.class, ServerboundConfigurationPackets1_20_2.class)
);
}
}
@@ -18,7 +18,7 @@
package com.viaversion.viabackwards.protocol.protocol1_20_2to1_20_3.rewriter;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.rewriters.ItemRewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_20_2to1_20_3.Protocol1_20_2To1_20_3;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
@@ -26,12 +26,14 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPacket1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.rewriter.RecipeRewriter1_20_3;
import com.viaversion.viaversion.rewriter.BlockRewriter;
public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<ClientboundPackets1_20_3, ServerboundPackets1_20_2, Protocol1_20_2To1_20_3> {
public final class BlockItemPacketRewriter1_20_3 extends BackwardsItemRewriter<ClientboundPacket1_20_3, ServerboundPacket1_20_2, Protocol1_20_2To1_20_3> {
public BlockItemPacketRewriter1_20_3(final Protocol1_20_2To1_20_3 protocol) {
super(protocol, Type.ITEM1_20_2, Type.ITEM1_20_2_ARRAY);
@@ -39,7 +41,7 @@ public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<Clientboun
@Override
public void registerPackets() {
final BlockRewriter<ClientboundPackets1_20_3> blockRewriter = BlockRewriter.for1_20_2(protocol);
final BlockRewriter<ClientboundPacket1_20_3> blockRewriter = BlockRewriter.for1_20_2(protocol);
blockRewriter.registerBlockAction(ClientboundPackets1_20_3.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_20_3.BLOCK_CHANGE);
blockRewriter.registerVarLongMultiBlockChange1_20(ClientboundPackets1_20_3.MULTI_BLOCK_CHANGE);
@@ -88,7 +90,7 @@ public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<Clientboun
}
});
new RecipeRewriter1_20_3<ClientboundPackets1_20_3>(protocol) {
new RecipeRewriter1_20_3<ClientboundPacket1_20_3>(protocol) {
@Override
public void handleCraftingShaped(final PacketWrapper wrapper) throws Exception {
// Move width and height up
@@ -105,7 +107,7 @@ public final class BlockItemPacketRewriter1_20_3 extends ItemRewriter<Clientboun
for (int i = 0; i < ingredients; i++) {
handleIngredient(wrapper);
}
rewrite(wrapper.passthrough(itemType())); // Result
rewrite(wrapper.user(), wrapper.passthrough(itemType())); // Result
wrapper.passthrough(Type.BOOLEAN); // Show notification
}
}.register(ClientboundPackets1_20_3.DECLARE_RECIPES);
@@ -25,17 +25,17 @@ import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_3;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
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.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.util.ComponentUtil;
public final class EntityPacketRewriter1_20_3 extends EntityRewriter<ClientboundPackets1_20_3, Protocol1_20_2To1_20_3> {
public final class EntityPacketRewriter1_20_3 extends EntityRewriter<ClientboundPacket1_20_3, Protocol1_20_2To1_20_3> {
public EntityPacketRewriter1_20_3(final Protocol1_20_2To1_20_3 protocol) {
super(protocol, Types1_20_2.META_TYPES.optionalComponentType, Types1_20_2.META_TYPES.booleanType);
@@ -47,7 +47,7 @@ public final class EntityPacketRewriter1_20_3 extends EntityRewriter<Clientbound
registerMetadataRewriter(ClientboundPackets1_20_3.ENTITY_METADATA, Types1_20_3.METADATA_LIST, Types1_20_2.METADATA_LIST);
registerRemoveEntities(ClientboundPackets1_20_3.REMOVE_ENTITIES);
protocol.registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.REGISTRY_DATA, new PacketHandlers() {
protocol.registerClientbound(ClientboundConfigurationPackets1_20_3.REGISTRY_DATA, new PacketHandlers() {
@Override
protected void register() {
map(Type.COMPOUND_TAG); // Registry data
@@ -107,7 +107,7 @@ public final class EntityPacketRewriter1_20_3 extends EntityRewriter<Clientbound
} else if (type == Types1_20_3.META_TYPES.particleType) {
final Particle particle = (Particle) meta.getValue();
final ParticleMappings particleMappings = protocol.getMappingData().getParticleMappings();
if (particle.getId() == particleMappings.id("vibration")) {
if (particle.id() == particleMappings.id("vibration")) {
// Change the type of the position source type argument
final int positionSourceType = particle.<Integer>removeArgument(0).getValue();
if (positionSourceType == 0) {
@@ -116,8 +116,6 @@ public final class EntityPacketRewriter1_20_3 extends EntityRewriter<Clientbound
particle.add(0, Type.STRING, "minecraft:entity");
}
}
rewriteParticle(particle);
} else if (type == Types1_20_3.META_TYPES.poseType) {
final int pose = meta.value();
if (pose >= 15) {
@@ -0,0 +1,264 @@
/*
* 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_20_3to1_20_5;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.BackwardsMappings;
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
import com.viaversion.viabackwards.api.rewriters.TranslatableRewriter;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.provider.TransferProvider;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.rewriter.BlockItemPacketRewriter1_20_5;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.rewriter.EntityPacketRewriter1_20_5;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.storage.CookieStorage;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.storage.RegistryDataStorage;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.storage.SecureChatStorage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.CommandRewriter1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPacket1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPacket1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.storage.BannerPatternStorage;
import com.viaversion.viaversion.rewriter.ComponentRewriter.ReadType;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
public final class Protocol1_20_3To1_20_5 extends BackwardsProtocol<ClientboundPacket1_20_5, ClientboundPacket1_20_3, ServerboundPacket1_20_5, ServerboundPacket1_20_3> {
public static final BackwardsMappings MAPPINGS = new BackwardsMappings("1.20.5", "1.20.3", Protocol1_20_5To1_20_3.class);
private final EntityPacketRewriter1_20_5 entityRewriter = new EntityPacketRewriter1_20_5(this);
private final BlockItemPacketRewriter1_20_5 itemRewriter = new BlockItemPacketRewriter1_20_5(this);
private final TranslatableRewriter<ClientboundPacket1_20_5> translatableRewriter = new TranslatableRewriter<>(this, ReadType.NBT);
private final TagRewriter<ClientboundPacket1_20_5> tagRewriter = new TagRewriter<>(this);
public Protocol1_20_3To1_20_5() {
super(ClientboundPacket1_20_5.class, ClientboundPacket1_20_3.class, ServerboundPacket1_20_5.class, ServerboundPacket1_20_3.class);
}
@Override
protected void registerPackets() {
super.registerPackets();
tagRewriter.registerGeneric(ClientboundPackets1_20_5.TAGS);
registerClientbound(ClientboundConfigurationPackets1_20_5.UPDATE_TAGS, wrapper -> {
// Send off registry data first
final PacketWrapper registryDataPacket = wrapper.create(ClientboundConfigurationPackets1_20_3.REGISTRY_DATA);
registryDataPacket.write(Type.COMPOUND_TAG, wrapper.user().get(RegistryDataStorage.class).registryData().copy());
registryDataPacket.send(Protocol1_20_3To1_20_5.class);
tagRewriter.getGenericHandler().handle(wrapper);
});
registerClientbound(ClientboundPackets1_20_5.START_CONFIGURATION, wrapper -> wrapper.user().get(RegistryDataStorage.class).clear());
final SoundRewriter<ClientboundPacket1_20_5> soundRewriter = new SoundRewriter<>(this);
soundRewriter.register1_19_3Sound(ClientboundPackets1_20_5.SOUND);
soundRewriter.register1_19_3Sound(ClientboundPackets1_20_5.ENTITY_SOUND);
soundRewriter.registerStopSound(ClientboundPackets1_20_5.STOP_SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_20_5.STATISTICS);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.ACTIONBAR);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.TITLE_TEXT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.TITLE_SUBTITLE);
translatableRewriter.registerBossBar(ClientboundPackets1_20_5.BOSSBAR);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_20_5.TAB_LIST);
translatableRewriter.registerCombatKill1_20(ClientboundPackets1_20_5.COMBAT_KILL);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.SYSTEM_CHAT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.DISGUISED_CHAT);
translatableRewriter.registerPing();
registerClientbound(State.LOGIN, ClientboundLoginPackets.HELLO, wrapper -> {
wrapper.passthrough(Type.STRING); // Server ID
wrapper.passthrough(Type.BYTE_ARRAY_PRIMITIVE); // Public key
wrapper.passthrough(Type.BYTE_ARRAY_PRIMITIVE); // Challenge
wrapper.read(Type.BOOLEAN); // Authenticate
});
registerClientbound(ClientboundPackets1_20_5.SERVER_DATA, wrapper -> {
wrapper.passthrough(Type.TAG); // MOTD
wrapper.passthrough(Type.OPTIONAL_BYTE_ARRAY_PRIMITIVE); // Icon
wrapper.write(Type.BOOLEAN, wrapper.user().get(SecureChatStorage.class).enforcesSecureChat());
});
registerServerbound(ServerboundPackets1_20_3.CHAT_COMMAND, ServerboundPackets1_20_5.CHAT_COMMAND_SIGNED, wrapper -> {
final String command = wrapper.passthrough(Type.STRING); // Command
wrapper.passthrough(Type.LONG); // Timestamp
wrapper.passthrough(Type.LONG); // Salt
final int signatures = wrapper.passthrough(Type.VAR_INT); // Signatures
if (signatures == 0) {
wrapper.cancel();
final PacketWrapper chatCommand = wrapper.create(ServerboundPackets1_20_5.CHAT_COMMAND);
chatCommand.write(Type.STRING, command);
chatCommand.sendToServer(Protocol1_20_3To1_20_5.class);
}
});
registerClientbound(State.LOGIN, ClientboundLoginPackets.COOKIE_REQUEST.getId(), -1, wrapper -> handleCookieRequest(wrapper, ServerboundLoginPackets.COOKIE_RESPONSE));
cancelClientbound(ClientboundConfigurationPackets1_20_5.RESET_CHAT); // Old clients already reset chat when entering the configuration phase
registerClientbound(ClientboundConfigurationPackets1_20_5.COOKIE_REQUEST, null, wrapper -> handleCookieRequest(wrapper, ServerboundConfigurationPackets1_20_5.COOKIE_RESPONSE));
registerClientbound(ClientboundConfigurationPackets1_20_5.STORE_COOKIE, null, this::handleStoreCookie);
registerClientbound(ClientboundConfigurationPackets1_20_5.TRANSFER, null, this::handleTransfer);
registerClientbound(ClientboundPackets1_20_5.COOKIE_REQUEST, null, wrapper -> handleCookieRequest(wrapper, ServerboundPackets1_20_5.COOKIE_RESPONSE));
registerClientbound(ClientboundPackets1_20_5.STORE_COOKIE, null, this::handleStoreCookie);
registerClientbound(ClientboundPackets1_20_5.TRANSFER, null, this::handleTransfer);
registerClientbound(ClientboundConfigurationPackets1_20_5.SELECT_KNOWN_PACKS, null, wrapper -> {
wrapper.cancel();
final PacketWrapper response = wrapper.create(ServerboundConfigurationPackets1_20_5.SELECT_KNOWN_PACKS);
response.write(Type.VAR_INT, 0); // Empty, we don't know anything
response.sendToServer(Protocol1_20_3To1_20_5.class);
});
new CommandRewriter1_19_4<ClientboundPacket1_20_5>(this) {
@Override
public void handleArgument(final PacketWrapper wrapper, final String argumentType) throws Exception {
if (argumentType.equals("minecraft:loot_table")
|| argumentType.equals("minecraft:loot_predicate")
|| argumentType.equals("minecraft:loot_modifier")) {
wrapper.write(Type.VAR_INT, 0);
} else {
super.handleArgument(wrapper, argumentType);
}
}
}.registerDeclareCommands1_19(ClientboundPackets1_20_5.DECLARE_COMMANDS);
registerClientbound(State.LOGIN, ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
wrapper.passthrough(Type.UUID); // UUID
wrapper.passthrough(Type.STRING); // Name
final int properties = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < properties; i++) {
wrapper.passthrough(Type.STRING); // Name
wrapper.passthrough(Type.STRING); // Value
wrapper.passthrough(Type.OPTIONAL_STRING); // Signature
}
wrapper.read(Type.BOOLEAN); // Strict error handling
});
cancelClientbound(ClientboundPackets1_20_5.PROJECTILE_POWER);
cancelClientbound(ClientboundPackets1_20_5.DEBUG_SAMPLE);
}
private void handleStoreCookie(final PacketWrapper wrapper) throws Exception {
wrapper.cancel();
final String resourceLocation = wrapper.read(Type.STRING);
final byte[] data = wrapper.read(Type.BYTE_ARRAY_PRIMITIVE);
if (data.length > 5120) {
throw new IllegalArgumentException("Cookie data too large");
}
wrapper.user().get(CookieStorage.class).cookies().put(resourceLocation, data);
}
private void handleCookieRequest(final PacketWrapper wrapper, final ServerboundPacketType responseType) throws Exception {
wrapper.cancel();
final String resourceLocation = wrapper.read(Type.STRING);
final byte[] data = wrapper.user().get(CookieStorage.class).cookies().get(resourceLocation);
final PacketWrapper responsePacket = wrapper.create(responseType);
responsePacket.write(Type.STRING, resourceLocation);
responsePacket.write(Type.OPTIONAL_BYTE_ARRAY_PRIMITIVE, data);
responsePacket.sendToServer(Protocol1_20_3To1_20_5.class);
}
private void handleTransfer(final PacketWrapper wrapper) throws Exception {
wrapper.cancel();
final String host = wrapper.read(Type.STRING);
final int port = wrapper.read(Type.VAR_INT);
Via.getManager().getProviders().get(TransferProvider.class).connectToServer(wrapper.user(), host, port);
}
@Override
public void init(final UserConnection user) {
addEntityTracker(user, new EntityTrackerBase(user, EntityTypes1_20_5.PLAYER));
user.put(new SecureChatStorage());
user.put(new CookieStorage());
user.put(new RegistryDataStorage());
user.put(new BannerPatternStorage());
}
@Override
public void register(final ViaProviders providers) {
providers.register(TransferProvider.class, TransferProvider.NOOP);
}
@Override
public BackwardsMappings getMappingData() {
return MAPPINGS;
}
@Override
public EntityPacketRewriter1_20_5 getEntityRewriter() {
return entityRewriter;
}
@Override
public BlockItemPacketRewriter1_20_5 getItemRewriter() {
return itemRewriter;
}
@Override
public TranslatableRewriter<ClientboundPacket1_20_5> getTranslatableRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_20_5> getTagRewriter() {
return tagRewriter;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_20_5, ClientboundPacket1_20_3, ServerboundPacket1_20_5, ServerboundPacket1_20_3> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_20_5.class, ClientboundConfigurationPackets1_20_5.class),
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_20_3.class, ClientboundConfigurationPackets1_20_3.class),
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_20_5.class, ServerboundConfigurationPackets1_20_5.class),
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_20_3.class, ServerboundConfigurationPackets1_20_2.class)
);
}
}
@@ -0,0 +1,27 @@
/*
* 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_20_3to1_20_5.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
final class NoopTransferProvider implements TransferProvider {
@Override
public void connectToServer(final UserConnection connection, final String host, final int port) {
}
}
@@ -0,0 +1,29 @@
/*
* 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_20_3to1_20_5.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.platform.providers.Provider;
@FunctionalInterface
public interface TransferProvider extends Provider {
TransferProvider NOOP = new NoopTransferProvider();
void connectToServer(UserConnection connection, String host, int port);
}
@@ -0,0 +1,349 @@
/*
* 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_20_3to1_20_5.rewriter;
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.Protocol1_20_3To1_20_5;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
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.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_20_3to1_20_2.packet.ServerboundPacket1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.rewriter.RecipeRewriter1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.BannerPatterns1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPacket1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.rewriter.StructuredDataConverter;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.util.Key;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItemRewriter<ClientboundPacket1_20_5, ServerboundPacket1_20_3, Protocol1_20_3To1_20_5> {
private static final StructuredDataConverter DATA_CONVERTER = new StructuredDataConverter(true);
private final Protocol1_20_5To1_20_3 vvProtocol = Via.getManager().getProtocolManager().getProtocol(Protocol1_20_5To1_20_3.class);
public BlockItemPacketRewriter1_20_5(final Protocol1_20_3To1_20_5 protocol) {
super(protocol, Types1_20_5.ITEM, Types1_20_5.ITEM_ARRAY, Type.ITEM1_20_2, Type.ITEM1_20_2_ARRAY);
enchantmentRewriter.setRewriteIds(false); // Let VV handle it
}
@Override
public void registerPackets() {
final BlockRewriter<ClientboundPacket1_20_5> blockRewriter = BlockRewriter.for1_20_2(protocol);
blockRewriter.registerBlockAction(ClientboundPackets1_20_5.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_20_5.BLOCK_CHANGE);
blockRewriter.registerVarLongMultiBlockChange1_20(ClientboundPackets1_20_5.MULTI_BLOCK_CHANGE);
blockRewriter.registerEffect(ClientboundPackets1_20_5.EFFECT, 1010, 2001);
blockRewriter.registerChunkData1_19(ClientboundPackets1_20_5.CHUNK_DATA, ChunkType1_20_2::new, (user, blockEntity) -> updateBlockEntityTag(user, blockEntity.tag()));
protocol.registerClientbound(ClientboundPackets1_20_5.BLOCK_ENTITY_DATA, wrapper -> {
wrapper.passthrough(Type.POSITION1_14); // Position
wrapper.passthrough(Type.VAR_INT); // Block entity type
final CompoundTag tag = wrapper.passthrough(Type.COMPOUND_TAG);
updateBlockEntityTag(wrapper.user(), tag);
});
registerSetCooldown(ClientboundPackets1_20_5.COOLDOWN);
registerWindowItems1_17_1(ClientboundPackets1_20_5.WINDOW_ITEMS);
registerSetSlot1_17_1(ClientboundPackets1_20_5.SET_SLOT);
registerAdvancements1_20_3(ClientboundPackets1_20_5.ADVANCEMENTS);
registerClickWindow1_17_1(ServerboundPackets1_20_3.CLICK_WINDOW);
registerWindowPropertyEnchantmentHandler(ClientboundPackets1_20_5.WINDOW_PROPERTY);
registerCreativeInvAction(ServerboundPackets1_20_3.CREATIVE_INVENTORY_ACTION);
protocol.registerServerbound(ServerboundPackets1_20_3.CLICK_WINDOW_BUTTON, wrapper -> {
final int containerId = wrapper.read(Type.BYTE) & 0xFF;
final int buttonId = wrapper.read(Type.BYTE) & 0xFF;
wrapper.write(Type.VAR_INT, containerId);
wrapper.write(Type.VAR_INT, buttonId);
});
protocol.registerClientbound(ClientboundPackets1_20_5.SPAWN_PARTICLE, wrapper -> {
wrapper.write(Type.VAR_INT, 0); // Write dummy value, set later
wrapper.passthrough(Type.BOOLEAN); // Long Distance
wrapper.passthrough(Type.DOUBLE); // X
wrapper.passthrough(Type.DOUBLE); // Y
wrapper.passthrough(Type.DOUBLE); // Z
wrapper.passthrough(Type.FLOAT); // Offset X
wrapper.passthrough(Type.FLOAT); // Offset Y
wrapper.passthrough(Type.FLOAT); // Offset Z
final float data = wrapper.passthrough(Type.FLOAT);
wrapper.passthrough(Type.INT); // Particle Count
// Move it to the beginning, move out arguments here
final Particle particle = wrapper.read(Types1_20_5.PARTICLE);
rewriteParticle(wrapper.user(), particle);
if (particle.id() == protocol.getMappingData().getParticleMappings().mappedId("entity_effect")) {
// Remove color argument
final int color = particle.<Integer>removeArgument(0).getValue();
if (data == 0) {
wrapper.set(Type.FLOAT, 3, (float) color);
}
} else if (particle.id() == protocol.getMappingData().getParticleMappings().mappedId("dust_color_transition")) {
// fromColor, toColor, scale -> fromColor, scale, toColor
particle.add(3, Type.FLOAT, particle.<Float>removeArgument(6).getValue());
}
wrapper.set(Type.VAR_INT, 0, particle.id());
for (final Particle.ParticleData<?> argument : particle.getArguments()) {
argument.write(wrapper);
}
});
protocol.registerClientbound(ClientboundPackets1_20_5.EXPLOSION, wrapper -> {
wrapper.passthrough(Type.DOUBLE); // X
wrapper.passthrough(Type.DOUBLE); // Y
wrapper.passthrough(Type.DOUBLE); // Z
wrapper.passthrough(Type.FLOAT); // Power
final int blocks = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < blocks; i++) {
wrapper.passthrough(Type.BYTE); // Relative X
wrapper.passthrough(Type.BYTE); // Relative Y
wrapper.passthrough(Type.BYTE); // Relative Z
}
wrapper.passthrough(Type.FLOAT); // Knockback X
wrapper.passthrough(Type.FLOAT); // Knockback Y
wrapper.passthrough(Type.FLOAT); // Knockback Z
wrapper.passthrough(Type.VAR_INT); // Block interaction type
protocol.getEntityRewriter().rewriteParticle(wrapper, Types1_20_5.PARTICLE, Types1_20_3.PARTICLE); // Small explosion particle
protocol.getEntityRewriter().rewriteParticle(wrapper, Types1_20_5.PARTICLE, Types1_20_3.PARTICLE); // Large explosion particle
int soundId = wrapper.read(Type.VAR_INT) - 1;
if (soundId == -1) {
// Already followed by the resource location
return;
}
soundId = protocol.getMappingData().getSoundMappings().getNewId(soundId);
final String soundKey = Protocol1_20_5To1_20_3.MAPPINGS.soundName(soundId);
wrapper.write(Type.STRING, soundKey != null ? soundKey : "minecraft:entity.generic.explode");
wrapper.write(Type.OPTIONAL_FLOAT, null); // Fixed range
});
protocol.registerClientbound(ClientboundPackets1_20_5.TRADE_LIST, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Container id
final int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
final Item input = handleItemToClient(wrapper.user(), wrapper.read(Types1_20_5.ITEM_COST));
cleanInput(input);
wrapper.write(Type.ITEM1_20_2, input);
final Item result = handleItemToClient(wrapper.user(), wrapper.read(Types1_20_5.ITEM));
wrapper.write(Type.ITEM1_20_2, result);
final Item secondInput = handleItemToClient(wrapper.user(), wrapper.read(Types1_20_5.OPTIONAL_ITEM_COST));
cleanInput(secondInput);
wrapper.write(Type.ITEM1_20_2, secondInput);
wrapper.passthrough(Type.BOOLEAN); // Out of stock
wrapper.passthrough(Type.INT); // Number of trade uses
wrapper.passthrough(Type.INT); // Maximum number of trade uses
wrapper.passthrough(Type.INT); // XP
wrapper.passthrough(Type.INT); // Special price
wrapper.passthrough(Type.FLOAT); // Price multiplier
wrapper.passthrough(Type.INT); // Demand
}
});
final RecipeRewriter1_20_3<ClientboundPacket1_20_5> recipeRewriter = new RecipeRewriter1_20_3<>(protocol);
protocol.registerClientbound(ClientboundPackets1_20_5.DECLARE_RECIPES, wrapper -> {
final int size = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < size; i++) {
// Change order and write the type as an int
final String recipeIdentifier = wrapper.read(Type.STRING);
final int serializerTypeId = wrapper.read(Type.VAR_INT);
final String serializerType = protocol.getMappingData().getRecipeSerializerMappings().mappedIdentifier(serializerTypeId);
wrapper.write(Type.STRING, serializerType);
wrapper.write(Type.STRING, recipeIdentifier);
recipeRewriter.handleRecipeType(wrapper, Key.stripMinecraftNamespace(serializerType));
}
});
}
private void updateBlockEntityTag(final UserConnection connection, final CompoundTag tag) {
if (tag == null) {
return;
}
final Tag profileTag = tag.remove("profile");
if (profileTag instanceof StringTag) {
tag.put("SkullOwner", profileTag);
} else if (profileTag instanceof CompoundTag) {
updateProfileTag(tag, (CompoundTag) profileTag);
}
final ListTag<CompoundTag> patternsTag = tag.getListTag("patterns", CompoundTag.class);
if (patternsTag != null) {
for (final CompoundTag patternTag : patternsTag) {
final String pattern = patternTag.getString("pattern", "");
final String color = patternTag.getString("color");
final String compactIdentifier = BannerPatterns1_20_5.fullIdToCompact(Key.stripMinecraftNamespace(pattern));
if (compactIdentifier == null || color == null) {
continue;
}
patternTag.remove("pattern");
patternTag.remove("color");
patternTag.putString("Pattern", compactIdentifier);
patternTag.putInt("Color", colorId(color));
}
tag.remove("patterns");
tag.put("Patterns", patternsTag);
}
}
private void updateProfileTag(final CompoundTag tag, final CompoundTag profileTag) {
final CompoundTag skullOwnerTag = new CompoundTag();
tag.put("SkullOwner", skullOwnerTag);
final String name = profileTag.getString("name");
if (name != null) {
skullOwnerTag.putString("Name", name);
}
final IntArrayTag idTag = profileTag.getIntArrayTag("id");
if (idTag != null) {
skullOwnerTag.put("Id", idTag);
}
final ListTag<CompoundTag> propertiesListTag = profileTag.getListTag("properties", CompoundTag.class);
if (propertiesListTag == null) {
return;
}
final CompoundTag propertiesTag = new CompoundTag();
for (final CompoundTag propertyTag : propertiesListTag) {
final String property = propertyTag.getString("name", "");
final String value = propertyTag.getString("value", "");
final String signature = propertyTag.getString("signature");
final ListTag<CompoundTag> list = new ListTag<>(CompoundTag.class);
final CompoundTag updatedPropertyTag = new CompoundTag();
updatedPropertyTag.putString("Value", value);
if (signature != null) {
updatedPropertyTag.putString("Signature", signature);
}
list.add(updatedPropertyTag);
propertiesTag.put(property, list);
}
skullOwnerTag.put("Properties", propertiesTag);
}
private void cleanInput(@Nullable final Item item) {
// Try to maybe hopefully get the tag matching to what the client will try to input by removing default data
if (item == null || item.tag() == null) {
return;
}
final CompoundTag tag = item.tag();
StructuredDataConverter.removeBackupTag(tag);
final CompoundTag display = tag.getCompoundTag("display");
if (display != null) {
removeEmptyList(display, "Lore");
if (display.isEmpty()) {
tag.remove("display");
}
}
removeEmptyList(tag, "Enchantments");
removeEmptyList(tag, "AttributeModifiers");
if (tag.getInt("RepairCost", -1) == 0) {
tag.remove("RepairCost");
}
if (tag.isEmpty()) {
item.setTag(null);
}
}
private void removeEmptyList(final CompoundTag tag, final String key) {
final ListTag<?> list = tag.getListTag(key);
if (list != null && list.isEmpty()) {
tag.remove(key);
}
}
private static int colorId(final String color) {
switch (color) {
case "orange":
return 1;
case "magenta":
return 2;
case "light_blue":
return 3;
case "yellow":
return 4;
case "lime":
return 5;
case "pink":
return 6;
case "gray":
return 7;
case "light_gray":
return 8;
case "cyan":
return 9;
case "purple":
return 10;
case "blue":
return 11;
case "brown":
return 12;
case "green":
return 13;
case "red":
return 14;
case "black":
return 15;
default:
return 0;
}
}
@Override
public @Nullable Item handleItemToClient(final UserConnection connection, @Nullable final Item item) {
if (item == null) return null;
super.handleItemToClient(connection, item);
return vvProtocol.getItemRewriter().toOldItem(connection, item, DATA_CONVERTER);
}
@Override
public @Nullable Item handleItemToServer(final UserConnection connection, @Nullable final Item item) {
if (item == null) return null;
// Convert to structured item first
final Item structuredItem = vvProtocol.getItemRewriter().toStructuredItem(connection, item);
return super.handleItemToServer(connection, structuredItem);
}
}
@@ -0,0 +1,420 @@
/*
* 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_20_3to1_20_5.rewriter;
import com.google.common.base.Preconditions;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.Protocol1_20_3To1_20_5;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.storage.RegistryDataStorage;
import com.viaversion.viabackwards.protocol.protocol1_20_3to1_20_5.storage.SecureChatStorage;
import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.data.entity.DimensionDataImpl;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.FloatTag;
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 com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.Protocol1_20_5To1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.data.Attributes1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundConfigurationPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPacket1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.packet.ClientboundPackets1_20_5;
import com.viaversion.viaversion.protocols.protocol1_20_5to1_20_3.storage.BannerPatternStorage;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.KeyMappings;
import com.viaversion.viaversion.util.MathUtil;
import java.util.HashMap;
import java.util.Map;
public final class EntityPacketRewriter1_20_5 extends EntityRewriter<ClientboundPacket1_20_5, Protocol1_20_3To1_20_5> {
public EntityPacketRewriter1_20_5(final Protocol1_20_3To1_20_5 protocol) {
super(protocol, Types1_20_3.META_TYPES.optionalComponentType, Types1_20_3.META_TYPES.booleanType);
}
@Override
public void registerPackets() {
registerTrackerWithData1_19(ClientboundPackets1_20_5.SPAWN_ENTITY, EntityTypes1_20_5.FALLING_BLOCK);
registerMetadataRewriter(ClientboundPackets1_20_5.ENTITY_METADATA, Types1_20_5.METADATA_LIST, Types1_20_3.METADATA_LIST);
registerRemoveEntities(ClientboundPackets1_20_5.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_20_5.ENTITY_EQUIPMENT, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Entity id
byte slot;
do {
slot = wrapper.read(Type.BYTE);
if (slot == 6) {
//TODO
// Body to... something else? the actual inventory slot is still broken for llamas
// Incoming click also needs to be fixed
slot = 2;
}
wrapper.write(Type.BYTE, slot);
final Item item = protocol.getItemRewriter().handleItemToClient(wrapper.user(), wrapper.read(Types1_20_5.ITEM));
wrapper.write(Type.ITEM1_20_2, item);
} while (slot < 0);
});
protocol.registerClientbound(ClientboundConfigurationPackets1_20_5.REGISTRY_DATA, wrapper -> {
wrapper.cancel();
final String registryKey = Key.stripMinecraftNamespace(wrapper.read(Type.STRING));
if (registryKey.equals("wolf_variant")) {
// There's only one wolf variant now
return;
}
final RegistryDataStorage registryDataStorage = wrapper.user().get(RegistryDataStorage.class);
final RegistryEntry[] entries = wrapper.read(Type.REGISTRY_ENTRY_ARRAY);
if (registryKey.equals("banner_pattern")) {
// Track banner pattern and material ids for conversion in items
final String[] keys = new String[entries.length];
for (int i = 0; i < entries.length; i++) {
keys[i] = Key.stripMinecraftNamespace(entries[i].key());
}
wrapper.user().get(BannerPatternStorage.class).setBannerPatterns(new KeyMappings(keys));
return;
}
// Track biome and dimension data
if (registryKey.equals("worldgen/biome")) {
tracker(wrapper.user()).setBiomesSent(entries.length);
// Update format of particles
for (final RegistryEntry entry : entries) {
if (entry.tag() == null) {
continue;
}
final CompoundTag effects = ((CompoundTag) entry.tag()).getCompoundTag("effects");
final CompoundTag particle = effects.getCompoundTag("particle");
if (particle != null) {
final CompoundTag particleOptions = particle.getCompoundTag("options");
final String particleType = particleOptions.getString("type");
updateParticleFormat(particleOptions, Key.stripMinecraftNamespace(particleType));
}
}
} else if (registryKey.equals("dimension_type")) {
final Map<String, DimensionData> dimensionDataMap = new HashMap<>(entries.length);
final String[] keys = new String[entries.length];
for (int i = 0; i < entries.length; i++) {
final RegistryEntry entry = entries[i];
Preconditions.checkNotNull(entry.tag(), "Server unexpectedly sent null dimension data for " + entry.key());
final String dimensionKey = Key.stripMinecraftNamespace(entry.key());
final CompoundTag tag = (CompoundTag) entry.tag();
updateDimensionTypeData(tag);
dimensionDataMap.put(dimensionKey, new DimensionDataImpl(i, tag));
keys[i] = dimensionKey;
}
registryDataStorage.setDimensionKeys(keys);
tracker(wrapper.user()).setDimensions(dimensionDataMap);
}
// Write to old format
final boolean isTrimPattern = registryKey.equals("trim_pattern");
final CompoundTag registryTag = new CompoundTag();
final ListTag<CompoundTag> entriesTag = new ListTag<>(CompoundTag.class);
registryTag.putString("type", registryKey);
registryTag.put("value", entriesTag);
for (int i = 0; i < entries.length; i++) {
final RegistryEntry entry = entries[i];
Preconditions.checkNotNull(entry.tag(), "Server unexpectedly sent null registry data entry for " + entry.key());
if (isTrimPattern) {
final CompoundTag patternTag = (CompoundTag) entry.tag();
final StringTag templateItem = patternTag.getStringTag("template_item");
if (Protocol1_20_5To1_20_3.MAPPINGS.getFullItemMappings().id(templateItem.getValue()) == -1) {
// Skip new items
continue;
}
}
final CompoundTag entryCompoundTag = new CompoundTag();
entryCompoundTag.putString("name", entry.key());
entryCompoundTag.putInt("id", i);
entryCompoundTag.put("element", entry.tag());
entriesTag.add(entryCompoundTag);
}
// Store and send together with the rest later
registryDataStorage.registryData().put(registryKey, registryTag);
});
protocol.registerClientbound(ClientboundPackets1_20_5.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // Entity id
map(Type.BOOLEAN); // Hardcore
map(Type.STRING_ARRAY); // World List
map(Type.VAR_INT); // Max players
map(Type.VAR_INT); // View distance
map(Type.VAR_INT); // Simulation distance
map(Type.BOOLEAN); // Reduced debug info
map(Type.BOOLEAN); // Show death screen
map(Type.BOOLEAN); // Limited crafting
handler(wrapper -> {
final int dimensionId = wrapper.read(Type.VAR_INT);
final RegistryDataStorage storage = wrapper.user().get(RegistryDataStorage.class);
wrapper.write(Type.STRING, storage.dimensionKeys()[dimensionId]);
});
map(Type.STRING); // World
map(Type.LONG); // Seed
map(Type.BYTE); // Gamemode
map(Type.BYTE); // Previous gamemode
map(Type.BOOLEAN); // Debug
map(Type.BOOLEAN); // Flat
map(Type.OPTIONAL_GLOBAL_POSITION); // Last death location
map(Type.VAR_INT); // Portal cooldown
handler(wrapper -> {
// Moved to server data
final boolean enforcesSecureChat = wrapper.read(Type.BOOLEAN);
wrapper.user().get(SecureChatStorage.class).setEnforcesSecureChat(enforcesSecureChat);
});
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
handler(playerTrackerHandler());
}
});
protocol.registerClientbound(ClientboundPackets1_20_5.RESPAWN, new PacketHandlers() {
@Override
public void register() {
handler(wrapper -> {
final int dimensionId = wrapper.read(Type.VAR_INT);
final RegistryDataStorage storage = wrapper.user().get(RegistryDataStorage.class);
wrapper.write(Type.STRING, storage.dimensionKeys()[dimensionId]);
});
map(Type.STRING); // World
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
}
});
protocol.registerClientbound(ClientboundPackets1_20_5.ENTITY_EFFECT, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Entity ID
wrapper.passthrough(Type.VAR_INT); // Effect ID
final int amplifier = wrapper.read(Type.VAR_INT);
wrapper.write(Type.BYTE, (byte) MathUtil.clamp(amplifier, Byte.MIN_VALUE, Byte.MAX_VALUE));
wrapper.passthrough(Type.VAR_INT); // Duration
wrapper.passthrough(Type.BYTE); // Flags
wrapper.write(Type.OPTIONAL_COMPOUND_TAG, null); // Add empty factor data
});
protocol.registerClientbound(ClientboundPackets1_20_5.ENTITY_PROPERTIES, wrapper -> {
final int entityId = wrapper.passthrough(Type.VAR_INT);
final int size = wrapper.passthrough(Type.VAR_INT);
int newSize = size;
for (int i = 0; i < size; i++) {
// From a registry int ID to a string
final int attributeId = wrapper.read(Type.VAR_INT);
final String attribute = Attributes1_20_5.idToKey(attributeId);
int mappedId = protocol.getMappingData().getAttributeMappings().getNewId(attributeId);
if ("generic.jump_strength".equals(attribute)) {
final EntityType type = tracker(wrapper.user()).entityType(entityId);
if (type == null || !type.isOrHasParent(EntityTypes1_20_5.HORSE)) {
// Jump strength only applies to horses in old versions
mappedId = -1;
}
}
if (mappedId == -1) {
// Remove new attributes from the list
newSize--;
wrapper.read(Type.DOUBLE); // Base
final int modifierSize = wrapper.read(Type.VAR_INT);
for (int j = 0; j < modifierSize; j++) {
wrapper.read(Type.UUID); // ID
wrapper.read(Type.DOUBLE); // Amount
wrapper.read(Type.BYTE); // Operation
}
continue;
}
wrapper.write(Type.STRING, attribute);
wrapper.passthrough(Type.DOUBLE); // Base
final int modifierSize = wrapper.passthrough(Type.VAR_INT);
for (int j = 0; j < modifierSize; j++) {
wrapper.passthrough(Type.UUID); // ID
wrapper.passthrough(Type.DOUBLE); // Amount
wrapper.passthrough(Type.BYTE); // Operation
}
}
wrapper.set(Type.VAR_INT, 1, newSize);
});
}
private void updateParticleFormat(final CompoundTag options, final String particleType) {
if ("block".equals(particleType) || "block_marker".equals(particleType) || "falling_dust".equals(particleType) || "dust_pillar".equals(particleType)) {
// TODO Can be a string
moveTag(options, "block_state", "value");
} else if ("item".equals(particleType)) {
Tag item = options.remove("item");
if (item instanceof StringTag) {
final CompoundTag compoundTag = new CompoundTag();
compoundTag.put("id", item);
item = compoundTag;
}
options.put("value", item);
} else if ("dust_color_transition".equals(particleType)) {
moveTag(options, "from_color", "fromColor");
moveTag(options, "to_color", "toColor");
} else if ("entity_effect".equals(particleType)) {
Tag color = options.remove("color");
if (color instanceof ListTag) {
//noinspection unchecked
ListTag<? extends NumberTag> colorParts = (ListTag<? extends NumberTag>) color;
color = new FloatTag(encodeARGB(
colorParts.get(0).getValue().floatValue(),
colorParts.get(1).getValue().floatValue(),
colorParts.get(2).getValue().floatValue(),
colorParts.get(3).getValue().floatValue()
));
}
options.put("value", color);
}
}
private int encodeARGB(final float a, final float r, final float g, final float b) {
final int encodedAlpha = encodeColorPart(a);
final int encodedRed = encodeColorPart(r);
final int encodedGreen = encodeColorPart(g);
final int encodedBlue = encodeColorPart(b);
return encodedAlpha << 24 | encodedRed << 16 | encodedGreen << 8 | encodedBlue;
}
private int encodeColorPart(final float part) {
return (int) Math.floor(part * 255);
}
private int removeAlpha(final int argb) {
return argb & 0x00FFFFFF;
}
private void moveTag(final CompoundTag compoundTag, final String from, final String to) {
final Tag tag = compoundTag.remove(from);
if (tag != null) {
compoundTag.put(to, tag);
}
}
private void updateDimensionTypeData(final CompoundTag elementTag) {
final CompoundTag monsterSpawnLightLevel = elementTag.getCompoundTag("monster_spawn_light_level");
if (monsterSpawnLightLevel != null) {
final CompoundTag value = new CompoundTag();
monsterSpawnLightLevel.put("value", value);
value.putInt("min_inclusive", monsterSpawnLightLevel.getInt("min_inclusive"));
value.putInt("max_inclusive", monsterSpawnLightLevel.getInt("max_inclusive"));
}
}
@Override
protected void registerRewrites() {
filter().mapMetaType(typeId -> {
if (typeId == Types1_20_5.META_TYPES.particlesType.typeId()) {
// Handled with living entity
return Types1_20_5.META_TYPES.particlesType;
}
int id = typeId;
if (typeId >= Types1_20_5.META_TYPES.wolfVariantType.typeId()) {
id--;
}
if (typeId >= Types1_20_5.META_TYPES.armadilloState.typeId()) {
id--;
}
if (typeId >= Types1_20_5.META_TYPES.particlesType.typeId()) {
id--;
}
return Types1_20_3.META_TYPES.byId(id);
});
registerMetaTypeHandler1_20_3(
Types1_20_3.META_TYPES.itemType,
Types1_20_3.META_TYPES.blockStateType,
Types1_20_3.META_TYPES.optionalBlockStateType,
Types1_20_3.META_TYPES.particleType,
null,
Types1_20_3.META_TYPES.componentType,
Types1_20_3.META_TYPES.optionalComponentType
);
filter().type(EntityTypes1_20_5.LIVINGENTITY).index(10).handler((event, meta) -> {
final Particle[] particles = meta.value();
int color = 0;
for (final Particle particle : particles) {
if (particle.id() == protocol.getMappingData().getParticleMappings().id("entity_effect")) {
// Remove color argument, use one of them for the ambient particle color
color = particle.<Integer>removeArgument(0).getValue();
}
}
meta.setTypeAndValue(Types1_20_3.META_TYPES.varIntType, removeAlpha(color));
});
filter().type(EntityTypes1_20_5.AREA_EFFECT_CLOUD).addIndex(9); // Color
filter().type(EntityTypes1_20_5.AREA_EFFECT_CLOUD).index(11).handler((event, meta) -> {
final Particle particle = meta.value();
if (particle.id() == protocol.getMappingData().getParticleMappings().mappedId("entity_effect")) {
// Move color to its own metadata
final int color = particle.<Integer>removeArgument(0).getValue();
event.createExtraMeta(new Metadata(9, Types1_20_3.META_TYPES.varIntType, removeAlpha(color)));
}
});
filter().type(EntityTypes1_20_5.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
final int blockState = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState));
});
filter().type(EntityTypes1_20_5.LLAMA).addIndex(20); // Carpet color
filter().type(EntityTypes1_20_5.ARMADILLO).removeIndex(17); // State
filter().type(EntityTypes1_20_5.WOLF).removeIndex(22); // Wolf variant
filter().type(EntityTypes1_20_5.OMINOUS_ITEM_SPAWNER).removeIndex(8); // Item
}
@Override
public void onMappingDataLoaded() {
mapTypes();
mapEntityTypeWithData(EntityTypes1_20_5.ARMADILLO, EntityTypes1_20_5.COW).tagName();
mapEntityTypeWithData(EntityTypes1_20_5.BOGGED, EntityTypes1_20_5.STRAY).tagName();
mapEntityTypeWithData(EntityTypes1_20_5.BREEZE_WIND_CHARGE, EntityTypes1_20_5.WIND_CHARGE);
mapEntityTypeWithData(EntityTypes1_20_5.OMINOUS_ITEM_SPAWNER, EntityTypes1_20_5.TEXT_DISPLAY);
}
@Override
public EntityType typeFromId(final int type) {
return EntityTypes1_20_5.getTypeFromId(type);
}
}
Loaded 100 of 135 files, more files were not shown because too many files have changed in this diff. Show more