using System.Text; using System.Text.RegularExpressions; namespace Minecraft.Server.FourKit; /// /// All supported color values for chat. /// public class ChatColor { /// /// The special character which prefixes all chat colour codes. /// public static readonly char COLOR_CHAR = '\u00A7'; // F private static readonly Regex STRIP_COLOR_PATTERN = new Regex("(?i)" + COLOR_CHAR + "[0-9A-FK-OR]", RegexOptions.Compiled); private static readonly Dictionary BY_CHAR = new(); /// Represents black. public static readonly ChatColor BLACK = new('0', false); /// Represents dark blue. public static readonly ChatColor DARK_BLUE = new('1', false); /// Represents dark green. public static readonly ChatColor DARK_GREEN = new('2', false); /// Represents dark blue (aqua). public static readonly ChatColor DARK_AQUA = new('3', false); /// Represents dark red. public static readonly ChatColor DARK_RED = new('4', false); /// Represents dark purple. public static readonly ChatColor DARK_PURPLE = new('5', false); /// Represents gold. public static readonly ChatColor GOLD = new('6', false); /// Represents gray. public static readonly ChatColor GRAY = new('7', false); /// Represents dark gray. public static readonly ChatColor DARK_GRAY = new('8', false); /// Represents blue. public static readonly ChatColor BLUE = new('9', false); /// Represents green. public static readonly ChatColor GREEN = new('a', false); /// Represents aqua. public static readonly ChatColor AQUA = new('b', false); /// Represents red. public static readonly ChatColor RED = new('c', false); /// Represents light purple. public static readonly ChatColor LIGHT_PURPLE = new('d', false); /// Represents yellow. public static readonly ChatColor YELLOW = new('e', false); /// Represents white. public static readonly ChatColor WHITE = new('f', false); /// Resets all previous chat colors or formats. public static readonly ChatColor RESET = new('r', false); private readonly char _code; private readonly bool _isFormat; private readonly string _toString; private ChatColor(char code, bool isFormat) { _code = code; _isFormat = isFormat; _toString = new string(new[] { COLOR_CHAR, code }); BY_CHAR[code] = this; } /// /// Gets the char value associated with this color. /// /// A char value of this color code. public char getChar() => _code; /// /// Checks if this code is a format code as opposed to a color code. /// /// true if this is a format code. public bool isFormat() => _isFormat; /// /// Checks if this code is a color code as opposed to a format code. /// /// true if this is a color code. public bool isColor() => !_isFormat && this != RESET; /// /// Gets the color represented by the specified color code. /// /// Code to check. /// Associative ChatColor with the given code, or null if it doesn't exist. public static ChatColor? getByChar(char code) { return BY_CHAR.TryGetValue(char.ToLower(code), out var color) ? color : null; } /// /// Gets the color represented by the specified color code. /// /// Code to check. /// Associative ChatColor with the given code, or null if it doesn't exist. public static ChatColor? getByChar(string code) { if (string.IsNullOrEmpty(code)) return null; return getByChar(code[0]); } /// /// Strips the given message of all color codes. /// /// String to strip of color. /// A copy of the input string, without any coloring. public static string? stripColor(string? input) { if (input == null) return null; return STRIP_COLOR_PATTERN.Replace(input, ""); } /// /// Translates a string using an alternate color code character into a string /// that uses the internal color code character. /// The alternate color code character will only be replaced if it is immediately /// followed by 0-9, A-F, a-f, K-O, k-o, R or r. /// /// The alternate color code character to replace. Ex: & /// Text containing the alternate color code character. /// Text containing the color code character. public static string translateAlternateColorCodes(char altColorChar, string textToTranslate) { char[] b = textToTranslate.ToCharArray(); for (int i = 0; i < b.Length - 1; i++) { if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".IndexOf(b[i + 1]) > -1) { b[i] = COLOR_CHAR; } } return new string(b); } /// /// Gets the ChatColors used at the end of the given input string. /// /// Input string to retrieve the colors from. /// Any remaining ChatColors to pass onto the next line. public static string getLastColors(string input) { var result = new StringBuilder(); int length = input.Length; for (int index = length - 1; index > -1; index--) { char section = input[index]; if (section == COLOR_CHAR && index < length - 1) { char c = input[index + 1]; ChatColor? color = getByChar(c); if (color != null) { result.Insert(0, color.ToString()); if (color.isColor() || color == RESET) break; } } } return result.ToString(); } public static string operator +(ChatColor color, string text) => color.ToString() + text; /// public override string ToString() => _toString; }