diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java new file mode 100644 index 000000000..047cecac6 --- /dev/null +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/ChatRewriter.java @@ -0,0 +1,118 @@ +package us.myles.ViaVersion.protocols.protocol1_13to1_12_2; + +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; + +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ChatRewriter { + // Based on https://github.com/SpigotMC/BungeeCord/blob/master/chat/src/main/java/net/md_5/bungee/api/chat/TextComponent.java + + private static final Pattern url = Pattern.compile("^(?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*)?$"); + + public static BaseComponent[] fromLegacyText(String message, ChatColor defaultColor) { + ArrayList components = new ArrayList<>(); + StringBuilder builder = new StringBuilder(); + TextComponent component = new TextComponent(); + Matcher matcher = url.matcher(message); + + for (int i = 0; i < message.length(); i++) { + char c = message.charAt(i); + if (c == ChatColor.COLOR_CHAR) { + if (++i >= message.length()) { + break; + } + c = message.charAt(i); + if (c >= 'A' && c <= 'Z') { + c += 32; + } + ChatColor format = ChatColor.getByChar(c); + if (format == null) { + continue; + } + if (builder.length() > 0) { + TextComponent old = component; + component = new TextComponent(old); + old.setText(builder.toString()); + builder = new StringBuilder(); + components.add(old); + } + switch (format) { + case BOLD: + component.setBold(true); + break; + case ITALIC: + component.setItalic(true); + break; + case UNDERLINE: + component.setUnderlined(true); + break; + case STRIKETHROUGH: + component.setStrikethrough(true); + break; + case MAGIC: + component.setObfuscated(true); + break; + case RESET: + format = defaultColor; + default: + component = new TextComponent(); + component.setColor(format); + // ViaVersion start + component.setBold(false); + component.setItalic(false); + component.setUnderlined(false); + component.setStrikethrough(false); + component.setObfuscated(false); + // ViaVersion end + break; + } + continue; + } + int pos = message.indexOf(' ', i); + if (pos == -1) { + pos = message.length(); + } + if (matcher.region(i, pos).find()) { //Web link handling + + if (builder.length() > 0) { + TextComponent old = component; + component = new TextComponent(old); + old.setText(builder.toString()); + builder = new StringBuilder(); + components.add(old); + } + + TextComponent old = component; + component = new TextComponent(old); + String urlString = message.substring(i, pos); + component.setText(urlString); + component.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, + urlString.startsWith("http") ? urlString : "http://" + urlString)); + components.add(component); + i += pos - i - 1; + component = old; + continue; + } + builder.append(c); + } + + component.setText(builder.toString()); + components.add(component); + + return components.toArray(new BaseComponent[0]); + } + + public static String legacyTextToJson(String legacyText) { + return ComponentSerializer.toString(fromLegacyText(legacyText, ChatColor.WHITE)); + } + + public static String jsonTextToLegacy(String value) { + return TextComponent.toLegacyText(ComponentSerializer.parse(value)); + } +} diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java index 6cedb48df..3f5cea31c 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/Protocol1_13To1_12_2.java @@ -38,12 +38,6 @@ import java.util.Map; public class Protocol1_13To1_12_2 extends Protocol { public static final Particle1_13Type PARTICLE_TYPE = new Particle1_13Type(); - public static String legacyTextToJson(String legacyText) { - return ComponentSerializer.toString( - TextComponent.fromLegacyText(legacyText) - ); - } - public static final PacketHandler POS_TO_3_INT = new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { @@ -108,10 +102,6 @@ public class Protocol1_13To1_12_2 extends Protocol { MappingData.init(); } - public static String jsonTextToLegacy(String value) { - return TextComponent.toLegacyText(ComponentSerializer.parse(value)); - } - @Override protected void registerPackets() { // Register grouped packet changes @@ -358,7 +348,7 @@ public class Protocol1_13To1_12_2 extends Protocol { // On create or update if (mode == 0 || mode == 2) { String value = wrapper.read(Type.STRING); // Value - value = legacyTextToJson(value); + value = ChatRewriter.legacyTextToJson(value); wrapper.write(Type.STRING, value); String type = wrapper.read(Type.STRING); @@ -385,7 +375,7 @@ public class Protocol1_13To1_12_2 extends Protocol { if (action == 0 || action == 2) { String displayName = wrapper.read(Type.STRING); // Display Name - displayName = legacyTextToJson(displayName); + displayName = ChatRewriter.legacyTextToJson(displayName); wrapper.write(Type.STRING, displayName); String prefix = wrapper.read(Type.STRING); // Prefix moved @@ -408,8 +398,8 @@ public class Protocol1_13To1_12_2 extends Protocol { wrapper.write(Type.VAR_INT, colour); - wrapper.write(Type.STRING, legacyTextToJson(prefix)); // Prefix - wrapper.write(Type.STRING, legacyTextToJson(suffix)); // Suffix + wrapper.write(Type.STRING, ChatRewriter.legacyTextToJson(prefix)); // Prefix + wrapper.write(Type.STRING, ChatRewriter.legacyTextToJson(suffix)); // Suffix } } }); diff --git a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java index 5e2257352..187af20f7 100644 --- a/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java +++ b/common/src/main/java/us/myles/ViaVersion/protocols/protocol1_13to1_12_2/packets/InventoryPackets.java @@ -11,7 +11,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.api.type.Type; import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2; +import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ChatRewriter; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.SoundSource; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.SpawnEggRewriter; @@ -299,10 +299,12 @@ public class InventoryPackets { } // Display Name now uses JSON if (tag.get("display") instanceof CompoundTag) { - if (((CompoundTag) tag.get("display")).get("Name") instanceof StringTag) { - StringTag name = ((CompoundTag) tag.get("display")).get("Name"); + CompoundTag display = tag.get("display"); + if (display.get("Name") instanceof StringTag) { + StringTag name = display.get("Name"); + display.put(new StringTag(NBT_TAG_NAME + "|Name", name.getValue())); name.setValue( - Protocol1_13To1_12_2.legacyTextToJson( + ChatRewriter.legacyTextToJson( name.getValue() ) ); @@ -482,13 +484,16 @@ public class InventoryPackets { // Display Name now uses JSON if (tag.get("display") instanceof CompoundTag) { + CompoundTag display = tag.get("display"); if (((CompoundTag) tag.get("display")).get("Name") instanceof StringTag) { - StringTag name = ((CompoundTag) tag.get("display")).get("Name"); + StringTag name = display.get("Name"); + StringTag via = display.get(NBT_TAG_NAME + "|Name"); name.setValue( - Protocol1_13To1_12_2.jsonTextToLegacy( + via != null ? via.getValue() : ChatRewriter.jsonTextToLegacy( name.getValue() ) ); + display.remove(NBT_TAG_NAME + "|Name"); } }