diff --git a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java index e04157d64..549bc32f4 100644 --- a/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java +++ b/bukkit/src/main/java/us/myles/ViaVersion/bukkit/platform/BukkitConfigAPI.java @@ -157,6 +157,11 @@ public class BukkitConfigAPI extends Config implements ViaVersionConfig { return getBoolean("force-json-transform", false); } + @Override + public boolean is1_12NBTArrayFix() { + return getBoolean("chat-nbt-fix", true); + } + @Override public List getBlockedProtocols() { return getIntegerList("block-protocols"); diff --git a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java index fef66fe0b..bf7e6a28e 100644 --- a/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java +++ b/bungee/src/main/java/us/myles/ViaVersion/bungee/platform/BungeeConfigAPI.java @@ -191,6 +191,11 @@ public class BungeeConfigAPI extends Config implements ViaVersionConfig { return getBoolean("force-json-transform", false); } + @Override + public boolean is1_12NBTArrayFix() { + return getBoolean("chat-nbt-fix", true); + } + @Override public List getBlockedProtocols() { return getIntegerList("block-protocols"); diff --git a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java index dafdc62e0..90f85ff39 100644 --- a/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java +++ b/common/src/main/java/us/myles/ViaVersion/api/ViaVersionConfig.java @@ -203,6 +203,13 @@ public interface ViaVersionConfig { */ boolean isForceJsonTransform(); + /** + * Should we fix nbt array's in json chat messages for 1.12 clients + * + * @return True if enabled + */ + boolean is1_12NBTArrayFix(); + /** * Get the blocked protocols * diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/ChatItemRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/ChatItemRewriter.java new file mode 100644 index 000000000..d5f7bdc4c --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/ChatItemRewriter.java @@ -0,0 +1,42 @@ +package us.myles.ViaVersion.protocols.protocol1_12to1_11_1; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import us.myles.ViaVersion.api.data.UserConnection; + +import java.util.regex.Pattern; + +public class ChatItemRewriter { + private static Pattern indexRemoval = Pattern.compile("\\d+:(?=([^\"\\\\]*(\\\\.|\"([^\"\\\\]*\\\\.)*[^\"\\\\]*\"))*[^\"]*$)"); + // Taken from https://stackoverflow.com/questions/6462578/alternative-to-regex-match-all-instances-not-inside-quotes + + public static void toClient(JsonElement element, UserConnection user) { + if (element instanceof JsonObject) { + JsonObject obj = (JsonObject) element; + if (obj.has("hoverEvent")) { + if (obj.get("hoverEvent") instanceof JsonObject) { + JsonObject hoverEvent = (JsonObject) obj.get("hoverEvent"); + if (hoverEvent.has("action") && hoverEvent.has("value")) { + String type = hoverEvent.get("action").getAsString(); + if (type.equals("show_item") || type.equals("show_entity")) { + String value = hoverEvent.get("value").getAsString(); + value = indexRemoval.matcher(value).replaceAll(""); + hoverEvent.addProperty("value", value); + } + } + } + } else { + if (obj.has("extra")) { + toClient(obj.get("extra"), user); + } + } + } + if (element instanceof JsonArray) { + JsonArray array = (JsonArray) element; + for (JsonElement value : array) { + toClient(value, user); + } + } + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java index 51c3c6446..f153ea234 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_12to1_11_1/Protocol1_12To1_11_1.java @@ -4,7 +4,10 @@ import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; import com.github.steveice10.opennbt.tag.builtin.StringTag; import com.google.common.base.Optional; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.entities.Entity1_12Types; import us.myles.ViaVersion.api.minecraft.chunks.Chunk; @@ -19,6 +22,7 @@ import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.packets.InventoryPacke import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.storage.EntityTracker; import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.types.Chunk1_9_3_4Type; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; +import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8; public class Protocol1_12To1_11_1 extends Protocol { @@ -85,6 +89,29 @@ public class Protocol1_12To1_11_1 extends Protocol { } }); + // Chat message packet + registerOutgoing(State.PLAY, 0x0F, 0x0F, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.STRING, Protocol1_9TO1_8.FIX_JSON); // 0 - Chat Message (json) + map(Type.BYTE); // 1 - Chat Positon + + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (!Via.getConfig().is1_12NBTArrayFix()) return; + try { + JsonElement obj = new JsonParser().parse(wrapper.get(Type.STRING, 0)); + ChatItemRewriter.toClient(obj, wrapper.user()); + wrapper.set(Type.STRING, 0, obj.toString()); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + }); + // Chunk Data registerOutgoing(State.PLAY, 0x20, 0x20, new PacketRemapper() { @Override @@ -128,6 +155,7 @@ public class Protocol1_12To1_11_1 extends Protocol { }); } }); + // Join Packet registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() { @Override diff --git a/common/src/main/java/us/myles/ViaVersion/util/Config.java b/common/src/main/java/us/myles/ViaVersion/util/Config.java index 609d1a778..9bf099723 100644 --- a/common/src/main/java/us/myles/ViaVersion/util/Config.java +++ b/common/src/main/java/us/myles/ViaVersion/util/Config.java @@ -24,6 +24,7 @@ public abstract class Config implements ConfigurationProvider { return new Yaml(new YamlConstructor(), new Representer(), options); } }; + private CommentStore commentStore = new CommentStore('.', 2); private final File configFile; private ConcurrentSkipListMap config; diff --git a/common/src/main/resources/config.yml b/common/src/main/resources/config.yml index fe7d749e5..43855685b 100644 --- a/common/src/main/resources/config.yml +++ b/common/src/main/resources/config.yml @@ -82,6 +82,8 @@ hologram-y: -0.96 # Should we disable piston animation for 1.11/1.11.1 clients? # In some cases when firing lots of pistons it crashes them. piston-animation-patch: false +# Should we fix nbt for 1.12 and above clients in chat messages (causes invalid item) +chat-nbt-fix: true # #----------------------------------------------------------# # 1.9 & 1.10 CLIENTS ON 1.8 SERVERS OPTIONS # diff --git a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java index b9e24bc2d..ba7222976 100644 --- a/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java +++ b/sponge/src/main/java/us/myles/ViaVersion/sponge/platform/SpongeConfigAPI.java @@ -164,6 +164,11 @@ public class SpongeConfigAPI extends Config implements ViaVersionConfig { return getBoolean("force-json-transform", false); } + @Override + public boolean is1_12NBTArrayFix() { + return getBoolean("chat-nbt-fix", true); + } + @Override public List getBlockedProtocols() { return getIntegerList("block-protocols");