From 2db810bafa26beff29889deb005d02dd5fc7d9be Mon Sep 17 00:00:00 2001
From: Felix Cravic <themode@outlook.fr>
Date: Tue, 23 Jun 2020 22:46:22 +0200
Subject: [PATCH] Added legacy message support

---
 .../net/minestom/server/chat/ChatColor.java   | 24 +++++++++++-
 .../net/minestom/server/chat/ColoredText.java | 37 +++++++++++++++++++
 .../net/minestom/server/entity/Player.java    | 23 +++++++++++-
 3 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/src/main/java/net/minestom/server/chat/ChatColor.java b/src/main/java/net/minestom/server/chat/ChatColor.java
index d912950d7..67f43c9c8 100644
--- a/src/main/java/net/minestom/server/chat/ChatColor.java
+++ b/src/main/java/net/minestom/server/chat/ChatColor.java
@@ -18,7 +18,7 @@ public class ChatColor {
     public static final ChatColor DARK_GRAY = new ChatColor("dark_gray", 8);
     public static final ChatColor BLUE = new ChatColor("blue", 9);
     public static final ChatColor BRIGHT_GREEN = new ChatColor("green", 10);
-    public static final ChatColor CYAN = new ChatColor("cyan", 11);
+    public static final ChatColor CYAN = new ChatColor("aqua", 11);
     public static final ChatColor RED = new ChatColor("red", 12);
     public static final ChatColor PINK = new ChatColor("light_purple", 13);
     public static final ChatColor YELLOW = new ChatColor("yellow", 14);
@@ -41,6 +41,7 @@ public class ChatColor {
     public static final ChatColor YELLOW = fromRGB(255, 255, 85);
     public static final ChatColor WHITE = fromRGB(255, 255, 255);*/
     private static Map<String, ChatColor> colorCode = new HashMap<>();
+    private static Map<Character, ChatColor> legacyColorCodesMap = new HashMap<>();
 
     static {
         colorCode.put("black", BLACK);
@@ -59,6 +60,23 @@ public class ChatColor {
         colorCode.put("pink", PINK);
         colorCode.put("yellow", YELLOW);
         colorCode.put("white", WHITE);
+
+        legacyColorCodesMap.put('0', BLACK);
+        legacyColorCodesMap.put('1', DARK_BLUE);
+        legacyColorCodesMap.put('2', DARK_GREEN);
+        legacyColorCodesMap.put('3', DARK_CYAN);
+        legacyColorCodesMap.put('4', DARK_RED);
+        legacyColorCodesMap.put('5', PURPLE);
+        legacyColorCodesMap.put('6', GOLD);
+        legacyColorCodesMap.put('7', GRAY);
+        legacyColorCodesMap.put('8', DARK_GRAY);
+        legacyColorCodesMap.put('9', BLUE);
+        legacyColorCodesMap.put('a', BRIGHT_GREEN);
+        legacyColorCodesMap.put('b', CYAN);
+        legacyColorCodesMap.put('c', RED);
+        legacyColorCodesMap.put('d', PINK);
+        legacyColorCodesMap.put('e', YELLOW);
+        legacyColorCodesMap.put('f', WHITE);
     }
 
     private boolean empty;
@@ -93,6 +111,10 @@ public class ChatColor {
         return colorCode.getOrDefault(name.toLowerCase(), NO_COLOR);
     }
 
+    public static ChatColor fromLegacyColorCodes(char colorCode) {
+        return legacyColorCodesMap.getOrDefault(colorCode, NO_COLOR);
+    }
+
     public boolean isEmpty() {
         return empty;
     }
diff --git a/src/main/java/net/minestom/server/chat/ColoredText.java b/src/main/java/net/minestom/server/chat/ColoredText.java
index 1a0077120..be8f2b2ff 100644
--- a/src/main/java/net/minestom/server/chat/ColoredText.java
+++ b/src/main/java/net/minestom/server/chat/ColoredText.java
@@ -26,6 +26,12 @@ public class ColoredText {
         return new ColoredText(message);
     }
 
+    public static ColoredText ofLegacy(String message, char colorChar) {
+        String legacy = toLegacy(message, colorChar);
+
+        return ofFormat(legacy);
+    }
+
     public ColoredText append(ChatColor color, String message) {
         this.message += color + message;
         return this;
@@ -40,6 +46,32 @@ public class ColoredText {
         return this;
     }
 
+    private static String toLegacy(String message, char colorChar) {
+        String result = "";
+
+        for (int i = 0; i < message.length(); i++) {
+            char c = message.charAt(i);
+            if (c == colorChar) {
+                final boolean hasNextChar = i < message.length();
+                if (hasNextChar) {
+                    final char nextChar = message.charAt(i + 1);
+                    final ChatColor color = ChatColor.fromLegacyColorCodes(nextChar);
+                    if (color != ChatColor.NO_COLOR) {
+                        String replacement = color.toString();
+                        result += replacement;
+                        i++; // Increment to ignore the color code
+                    } else {
+                        result += c;
+                    }
+                }
+            } else {
+                result += c;
+            }
+        }
+
+        return result;
+    }
+
     public String getMessage() {
         return message;
     }
@@ -177,4 +209,9 @@ public class ColoredText {
         RAW, KEYBIND, TRANSLATABLE
     }
 
+    public ColoredText appendLegacy(String message, char colorChar) {
+        String legacy = toLegacy(message, colorChar);
+        return appendFormat(legacy);
+    }
+
 }
diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java
index 96b2216e1..1e627971c 100644
--- a/src/main/java/net/minestom/server/entity/Player.java
+++ b/src/main/java/net/minestom/server/entity/Player.java
@@ -3,6 +3,7 @@ package net.minestom.server.entity;
 import net.minestom.server.MinecraftServer;
 import net.minestom.server.attribute.Attribute;
 import net.minestom.server.bossbar.BossBar;
+import net.minestom.server.chat.Chat;
 import net.minestom.server.chat.ColoredText;
 import net.minestom.server.chat.RichMessage;
 import net.minestom.server.collision.BoundingBox;
@@ -595,7 +596,6 @@ public class Player extends LivingEntity implements CommandSender {
         sendPacketToViewersAndSelf(breakAnimationPacket);
     }
 
-    // Use legacy color formatting
     @Override
     public void sendMessage(String message) {
         sendMessage(ColoredText.of(message));
@@ -619,6 +619,27 @@ public class Player extends LivingEntity implements CommandSender {
         playerConnection.sendPacket(new ChatMessagePacket(richMessage.toString(), ChatMessagePacket.Position.CHAT));
     }
 
+    /**
+     * Send a legacy message with the specified color char
+     *
+     * @param text      the text with the legacy color formatting
+     * @param colorChar the color char
+     */
+    public void sendLegacyMessage(String text, char colorChar) {
+        ColoredText coloredText = ColoredText.ofLegacy(text, colorChar);
+        sendMessage(coloredText);
+    }
+
+    /**
+     * Send a legacy message with the default color char {@link Chat#COLOR_CHAR}
+     *
+     * @param text the text with the legacy color formatting
+     */
+    public void sendLegacyMessage(String text) {
+        ColoredText coloredText = ColoredText.ofLegacy(text, Chat.COLOR_CHAR);
+        sendMessage(coloredText);
+    }
+
     public void playSound(Sound sound, SoundCategory soundCategory, int x, int y, int z, float volume, float pitch) {
         SoundEffectPacket soundEffectPacket = new SoundEffectPacket();
         soundEffectPacket.soundId = sound.getId();