From 8b4733258bfaa502b85fad7200f3b6d8e64faecb Mon Sep 17 00:00:00 2001 From: KennyTV Date: Thu, 28 May 2020 13:29:24 +0200 Subject: [PATCH] Fix show_entity and show_item in 1.16->1.15 --- .../chat/TagSerializer.java | 59 +++++++++++++++++++ .../chat/TranslatableRewriter1_16.java | 20 ++++--- 2 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TagSerializer.java diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TagSerializer.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TagSerializer.java new file mode 100644 index 00000000..92b386d7 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TagSerializer.java @@ -0,0 +1,59 @@ +package nl.matsv.viabackwards.protocol.protocol1_15_2to1_16.chat; + +import com.google.common.base.Preconditions; +import us.myles.viaversion.libs.gson.JsonElement; +import us.myles.viaversion.libs.gson.JsonObject; + +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Utility class to serialize a JsonObject with Minecraft's CompoundTag serialization + */ +public class TagSerializer { + + private static final Pattern PLAIN_TEXT = Pattern.compile("[A-Za-z0-9._+-]+"); + + public static String toString(JsonObject object) { + StringBuilder builder = new StringBuilder("{"); + for (Map.Entry entry : object.entrySet()) { + Preconditions.checkArgument(entry.getValue().isJsonPrimitive()); + if (builder.length() != 1) { + builder.append(','); + } + + String escapedText = escape(entry.getValue().getAsString()); + builder.append(entry.getKey()).append(':').append(escapedText); + } + return builder.append('}').toString(); + } + + public static String escape(String s) { + if (PLAIN_TEXT.matcher(s).matches()) return s; + + StringBuilder builder = new StringBuilder(" "); + char currentQuote = '\0'; + for (int i = 0; i < s.length(); ++i) { + char c = s.charAt(i); + if (c == '\\') { + builder.append('\\'); + } else if (c == '\"' || c == '\'') { + if (currentQuote == '\0') { + currentQuote = ((c == '\"') ? '\'' : '\"'); + } + if (currentQuote == c) { + builder.append('\\'); + } + } + builder.append(c); + } + + if (currentQuote == '\0') { + currentQuote = '\"'; + } + + builder.setCharAt(0, currentQuote); + builder.append(currentQuote); + return builder.toString(); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TranslatableRewriter1_16.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TranslatableRewriter1_16.java index db0c3f13..e3c71bf6 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TranslatableRewriter1_16.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_15_2to1_16/chat/TranslatableRewriter1_16.java @@ -68,22 +68,26 @@ public class TranslatableRewriter1_16 extends TranslatableRewriter { JsonElement contentsElement = hoverEvent.remove("contents"); String action = hoverEvent.getAsJsonPrimitive("action").getAsString(); if (contentsElement != null) { + // show_text as chat component + // show_entity and show_item serialized as nbt if (action.equals("show_text")) { - // show_text as chat component processTranslate(contentsElement); hoverEvent.add("value", contentsElement); } else if (action.equals("show_item")) { JsonObject item = contentsElement.getAsJsonObject(); JsonElement count = item.remove("count"); - if (count != null) { - item.addProperty("Count", count.getAsByte()); + item.addProperty("Count", count != null ? count.getAsByte() : 1); + + hoverEvent.addProperty("value", TagSerializer.toString(item)); + } else if (action.equals("show_entity")) { + JsonObject entity = contentsElement.getAsJsonObject(); + if (entity.has("name")) { + entity.addProperty("name", entity.getAsJsonObject("name").toString()); } - hoverEvent.addProperty("value", contentsElement.toString()); - } else { - //TODO escape/fix? - // the server sends the json as a string - hoverEvent.addProperty("value", contentsElement.toString()); + JsonObject hoverObject = new JsonObject(); + hoverObject.addProperty("text", TagSerializer.toString(entity)); + hoverEvent.add("value", hoverObject); } } }