Fix scoreboard component coversion (#586)

This commit is contained in:
SplotyCode 2023-09-08 04:22:16 +02:00 committed by GitHub
parent 80438807cc
commit 643c6b18dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 27 deletions

View File

@ -203,11 +203,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
if (mode == 0 || mode == 2) {
JsonElement value = wrapper.read(Type.COMPONENT);
String legacyValue = protocol.jsonToLegacy(value);
if (legacyValue.length() > 32) {
legacyValue = legacyValue.substring(0, 32);
}
wrapper.write(Type.STRING, legacyValue);
wrapper.write(Type.STRING, ChatUtil.fromLegacy(legacyValue, 'f', 32));
int type = wrapper.read(Type.VAR_INT);
wrapper.write(Type.STRING, type == 1 ? "hearts" : "integer");
}
@ -225,11 +221,7 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
if (action == 0 || action == 2) {
JsonElement displayName = wrapper.read(Type.COMPONENT);
String legacyTextDisplayName = protocol.jsonToLegacy(displayName);
legacyTextDisplayName = ChatUtil.removeUnusedColor(legacyTextDisplayName, 'f');
if (legacyTextDisplayName.length() > 32) {
legacyTextDisplayName = legacyTextDisplayName.substring(0, 32);
}
wrapper.write(Type.STRING, legacyTextDisplayName);
wrapper.write(Type.STRING, ChatUtil.fromLegacy(legacyTextDisplayName, 'f', 32));
byte flags = wrapper.read(Type.BYTE);
String nameTagVisibility = wrapper.read(Type.STRING);
@ -247,18 +239,10 @@ public class PlayerPacket1_13 extends RewriterBase<Protocol1_12_2To1_13> {
if (ViaBackwards.getConfig().addTeamColorTo1_13Prefix()) {
prefix += "§" + (colour > -1 && colour <= 15 ? Integer.toHexString(colour) : "r");
}
prefix = ChatUtil.removeUnusedColor(prefix, 'f', true);
if (prefix.length() > 16) prefix = prefix.substring(0, 16);
if (prefix.endsWith("§")) prefix = prefix.substring(0, prefix.length() - 1);
String suffix = protocol.jsonToLegacy(suffixComponent);
suffix = ChatUtil.removeUnusedColor(suffix, '\0'); // Don't remove white coloring
if (suffix.length() > 16) suffix = suffix.substring(0, 16);
if (suffix.endsWith("§")) suffix = suffix.substring(0, suffix.length() - 1);
wrapper.write(Type.STRING, prefix);
wrapper.write(Type.STRING, suffix);
wrapper.write(Type.STRING, ChatUtil.fromLegacyPrefix(prefix, 'f', 16));
wrapper.write(Type.STRING, ChatUtil.fromLegacy(suffix, '\0', 16));
wrapper.write(Type.BYTE, flags);
wrapper.write(Type.STRING, nameTagVisibility);

View File

@ -17,6 +17,9 @@
*/
package com.viaversion.viabackwards.utils;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
public class ChatUtil {
@ -27,25 +30,103 @@ public class ChatUtil {
return removeUnusedColor(legacy, defaultColor, false);
}
private static class ChatFormattingState {
private final Set<Character> formatting;
private final char defaultColor;
private char color;
private ChatFormattingState(char defaultColor) {
this(new HashSet<>(), defaultColor, defaultColor);
}
public ChatFormattingState(Set<Character> formatting, char defaultColor, char color) {
this.formatting = formatting;
this.defaultColor = defaultColor;
this.color = color;
}
private void setColor(char newColor) {
formatting.clear();
color = newColor;
}
public ChatFormattingState copy() {
return new ChatFormattingState(new HashSet<>(formatting), defaultColor, color);
}
public void appendTo(StringBuilder builder) {
builder.append('§').append(color);
for (Character formatCharacter : formatting) {
builder.append('§').append(formatCharacter);
}
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ChatFormattingState that = (ChatFormattingState) o;
return defaultColor == that.defaultColor
&& color == that.color
&& Objects.equals(formatting, that.formatting);
}
@Override
public int hashCode() {
return Objects.hash(formatting, defaultColor, color);
}
public void processNextControlChar(char controlChar) {
if (controlChar == 'r') {
setColor(defaultColor);
return;
}
if (controlChar == 'l' || controlChar == 'm' || controlChar == 'n' || controlChar == 'o') {
formatting.add(controlChar);
return;
}
setColor(controlChar);
}
}
public static String fromLegacy(String legacy, char defaultColor, int limit) {
return fromLegacy(legacy, defaultColor, limit, false);
}
public static String fromLegacyPrefix(String legacy, char defaultColor, int limit) {
return fromLegacy(legacy, defaultColor, limit, true);
}
public static String fromLegacy(String legacy, char defaultColor, int limit, boolean isPrefix) {
legacy = removeUnusedColor(legacy, defaultColor, isPrefix);
if (legacy.length() > limit) legacy = legacy.substring(0, limit);
if (legacy.endsWith("§")) legacy = legacy.substring(0, legacy.length() - 1);
return legacy;
}
public static String removeUnusedColor(String legacy, char defaultColor, boolean isPrefix) {
if (legacy == null) return null;
Pattern pattern = isPrefix ? UNUSED_COLOR_PATTERN_PREFIX : UNUSED_COLOR_PATTERN;
legacy = pattern.matcher(legacy).replaceAll("$1$2");
StringBuilder builder = new StringBuilder();
char last = defaultColor;
ChatFormattingState builderState = new ChatFormattingState(defaultColor);
ChatFormattingState lastState = new ChatFormattingState(defaultColor);
for (int i = 0; i < legacy.length(); i++) {
char current = legacy.charAt(i);
if (current != '§' || i == legacy.length() - 1) {
if (!lastState.equals(builderState)) {
lastState.appendTo(builder);
builderState = lastState.copy();
}
builder.append(current);
continue;
}
current = legacy.charAt(++i);
if (current != last) {
builder.append('§').append(current);
last = current;
}
lastState.processNextControlChar(current);
}
return builder.toString();
}