diff --git a/protocol/src/main/java/mc/protocol/model/text/Text.java b/protocol/src/main/java/mc/protocol/model/text/Text.java index 0472114..d7527e2 100644 --- a/protocol/src/main/java/mc/protocol/model/text/Text.java +++ b/protocol/src/main/java/mc/protocol/model/text/Text.java @@ -4,8 +4,10 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.ToString; +import lombok.Getter; import lombok.experimental.Accessors; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; @@ -43,11 +45,21 @@ public class Text { @ToString public static class Builder { + @Getter(onMethod = @__(@Nullable)) private StringBuilder contentBuilder; private TextStyle.Builder styleBuilder; private TextColor color; private List children; + public Builder append(char content) { + if (this.contentBuilder == null) { + this.contentBuilder = new StringBuilder(); + } + + this.contentBuilder.append(content); + return this; + } + public Builder append(String content) { if (this.contentBuilder == null) { this.contentBuilder = new StringBuilder(content); diff --git a/protocol/src/main/java/mc/protocol/model/text/TextColor.java b/protocol/src/main/java/mc/protocol/model/text/TextColor.java index ba0b1c2..8e914cc 100644 --- a/protocol/src/main/java/mc/protocol/model/text/TextColor.java +++ b/protocol/src/main/java/mc/protocol/model/text/TextColor.java @@ -20,10 +20,9 @@ public enum TextColor { GREEN ("green", 'a'), AQUA ("aqua", 'b'), RED ("red", 'c'), - PUEPLE ("light_purple",'d'), + PURPLE ("light_purple",'d'), YELLOW ("yellow", 'e'), - WHITE ("white", 'f'), - RESET ("reset", 'r'); + WHITE ("white", 'f'); //@formatter:on private final String name; diff --git a/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java b/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java index 69f2ff3..8633d02 100644 --- a/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java +++ b/protocol/src/main/java/mc/protocol/serializer/TextSerializer.java @@ -5,10 +5,17 @@ import com.eclipsesource.json.JsonArray; import com.eclipsesource.json.JsonObject; import lombok.experimental.UtilityClass; import mc.protocol.model.text.Text; +import mc.protocol.model.text.TextColor; +import mc.protocol.model.text.TextStyle; + +import java.util.Map; @UtilityClass public class TextSerializer { + private static final Map legacyStyleCodes; + private static final Map legacyColorCodes; + public JsonObject toJsonObject(Text text) { JsonObject jsonObject = Json.object(); @@ -38,4 +45,85 @@ public class TextSerializer { return jsonObject; } + + /** + * Преобразование строки вида "&4красный" в {@link Text}. + * + * @param string тест + * @return Text + */ + @SuppressWarnings({"java:S3776", "java:S2583", "java:S135"}) + public Text fromPlain(String string) { + boolean flagSys = false; + Text.Builder rootTextBuilder = Text.builder(); + Text.Builder textBuilder = rootTextBuilder; + + for (char ch : string.toCharArray()) { + if (!flagSys) { + if ('&' == ch) { + flagSys = true; + } else { + textBuilder.append(ch); + } + continue; + } + + if (!legacyStyleCodes.containsKey(ch) && !legacyColorCodes.containsKey(ch) && '&' == ch) { + textBuilder.append('&'); + flagSys = false; + continue; + } + + //noinspection ConstantConditions + if (textBuilder.contentBuilder() != null && textBuilder.contentBuilder().length() > 0) { + if (textBuilder != rootTextBuilder) { + rootTextBuilder.append(textBuilder.build()); + } + textBuilder = Text.builder(); + } + + if (legacyStyleCodes.containsKey(ch)) { + textBuilder.style(legacyStyleCodes.get(ch)); + } else { + textBuilder.color(legacyColorCodes.get(ch)); + } + + flagSys = false; + } + + if (textBuilder != rootTextBuilder) { + rootTextBuilder.append(textBuilder.build()); + } + + return rootTextBuilder.build(); + } + + static { + legacyColorCodes = Map.ofEntries( + Map.entry('0', TextColor.BLACK), + Map.entry('1', TextColor.DARK_BLUE), + Map.entry('2', TextColor.DARK_GREEN), + Map.entry('3', TextColor.DARK_AQUA), + Map.entry('4', TextColor.DARK_RED), + Map.entry('5', TextColor.DARK_PUEPLE), + Map.entry('6', TextColor.GOLD), + Map.entry('7', TextColor.GRAY), + Map.entry('8', TextColor.DARK_GRAY), + Map.entry('9', TextColor.BLUE), + Map.entry('a', TextColor.GREEN), + Map.entry('b', TextColor.AQUA), + Map.entry('c', TextColor.RED), + Map.entry('d', TextColor.PURPLE), + Map.entry('e', TextColor.YELLOW), + Map.entry('f', TextColor.WHITE) + ); + + legacyStyleCodes = Map.of( + 'k', TextStyle.OBFUSCATED, + 'l', TextStyle.BOLD, + 'm', TextStyle.STRIKETHOUGH, + 'n', TextStyle.UNDERLINE, + 'o', TextStyle.ITALIC + ); + } } diff --git a/protocol/src/test/java/mc/protocol/serializer/TextSerializerTest.java b/protocol/src/test/java/mc/protocol/serializer/TextSerializerTest.java new file mode 100644 index 0000000..61bd4fa --- /dev/null +++ b/protocol/src/test/java/mc/protocol/serializer/TextSerializerTest.java @@ -0,0 +1,40 @@ +package mc.protocol.serializer; + +import mc.protocol.model.text.Text; +import mc.protocol.model.text.TextColor; +import mc.protocol.model.text.TextStyle; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class TextSerializerTest { + + @ParameterizedTest + @MethodSource("paramsPlain") + void fromPlain(String sample, Text expected) { + Text actual = TextSerializer.fromPlain(sample); + assertEquals(expected, actual); + } + + @SuppressWarnings("unused") + static Stream paramsPlain() { + return Stream.of( + Arguments.of("text", Text.of("text")), + Arguments.of("&&text", Text.of("&text")), + Arguments.of("&ztext", Text.of("text")), + Arguments.of("&4red_text", Text.of(TextColor.DARK_RED, "red_text")), + Arguments.of("&l&4red_text", Text.of(TextColor.DARK_RED, TextStyle.BOLD, "red_text")), + Arguments.of("&4&lred_text", Text.of(TextColor.DARK_RED, TextStyle.BOLD, "red_text")), + + Arguments.of("&4red_text &eyellow_text", Text.builder() + .color(TextColor.DARK_RED) + .append("red_text ") + .append(Text.of(TextColor.YELLOW, "yellow_text")) + .build()) + ); + } +} \ No newline at end of file