fork(1) download
  1. /* package whatever; // don't place package name! */
  2.  
  3. import java.util.*;
  4. import java.lang.*;
  5. import java.io.*;
  6. import java.util.HashMap;
  7. import java.util.Map;
  8. import java.util.regex.Matcher;
  9. import java.util.regex.Pattern;
  10.  
  11. /* Name of the class has to be "Main" only if the class is public. */
  12. class Ideone
  13. {
  14. private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf('ยง') + "[0-9A-FK-OR]");
  15.  
  16. private enum ChatColor
  17. {
  18. /**
  19.   * Represents black
  20.   */
  21. BLACK('0', 0x00),
  22. /**
  23.   * Represents dark blue
  24.   */
  25. DARK_BLUE('1', 0x1),
  26. /**
  27.   * Represents dark green
  28.   */
  29. DARK_GREEN('2', 0x2),
  30. /**
  31.   * Represents dark blue (aqua)
  32.   */
  33. DARK_AQUA('3', 0x3),
  34. /**
  35.   * Represents dark red
  36.   */
  37. DARK_RED('4', 0x4),
  38. /**
  39.   * Represents dark purple
  40.   */
  41. DARK_PURPLE('5', 0x5),
  42. /**
  43.   * Represents gold
  44.   */
  45. GOLD('6', 0x6),
  46. /**
  47.   * Represents gray
  48.   */
  49. GRAY('7', 0x7),
  50. /**
  51.   * Represents dark gray
  52.   */
  53. DARK_GRAY('8', 0x8),
  54. /**
  55.   * Represents blue
  56.   */
  57. BLUE('9', 0x9),
  58. /**
  59.   * Represents green
  60.   */
  61. GREEN('a', 0xA),
  62. /**
  63.   * Represents aqua
  64.   */
  65. AQUA('b', 0xB),
  66. /**
  67.   * Represents red
  68.   */
  69. RED('c', 0xC),
  70. /**
  71.   * Represents light purple
  72.   */
  73. LIGHT_PURPLE('d', 0xD),
  74. /**
  75.   * Represents yellow
  76.   */
  77. YELLOW('e', 0xE),
  78. /**
  79.   * Represents white
  80.   */
  81. WHITE('f', 0xF),
  82. /**
  83.   * Represents magical characters that change around randomly
  84.   */
  85. MAGIC('k', 0x10, true),
  86. /**
  87.   * Makes the text bold.
  88.   */
  89. BOLD('l', 0x11, true),
  90. /**
  91.   * Makes a line appear through the text.
  92.   */
  93. STRIKETHROUGH('m', 0x12, true),
  94. /**
  95.   * Makes the text appear underlined.
  96.   */
  97. UNDERLINE('n', 0x13, true),
  98. /**
  99.   * Makes the text italic.
  100.   */
  101. ITALIC('o', 0x14, true),
  102. /**
  103.   * Resets all previous chat colors or formats.
  104.   */
  105. RESET('r', 0x15);
  106.  
  107. /**
  108.   * The special character which prefixes all chat colour codes. Use this if
  109.   * you need to dynamically convert colour codes from your custom format.
  110.   */
  111. public static final char COLOR_CHAR = '\u00A7';
  112. private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]");
  113.  
  114. private final int intCode;
  115. private final char code;
  116. private final boolean isFormat;
  117. private final String toString;
  118. private final static Map<Integer, ChatColor> BY_ID = new HashMap<>();
  119. private final static Map<Character, ChatColor> BY_CHAR = new HashMap<>();
  120.  
  121. private ChatColor(char code, int intCode) {
  122. this(code, intCode, false);
  123. }
  124.  
  125. private ChatColor(char code, int intCode, boolean isFormat) {
  126. this.code = code;
  127. this.intCode = intCode;
  128. this.isFormat = isFormat;
  129. this.toString = new String(new char[] {COLOR_CHAR, code});
  130. }
  131.  
  132. /**
  133.   * Gets the char value associated with this color
  134.   *
  135.   * @return A char value of this color code
  136.   */
  137. public char getChar() {
  138. return code;
  139. }
  140.  
  141. @Override
  142. public String toString() {
  143. return toString;
  144. }
  145.  
  146. /**
  147.   * Checks if this code is a format code as opposed to a color code.
  148.   */
  149. public boolean isFormat() {
  150. return isFormat;
  151. }
  152.  
  153. /**
  154.   * Checks if this code is a color code as opposed to a format code.
  155.   */
  156. public boolean isColor() {
  157. return !isFormat && this != RESET;
  158. }
  159.  
  160. /**
  161.   * Gets the color represented by the specified color code
  162.   *
  163.   * @param code Code to check
  164.   * @return Associative {@link org.bukkit.ChatColor} with the given code,
  165.   * or null if it doesn't exist
  166.   */
  167. public static ChatColor getByChar(char code) {
  168. return BY_CHAR.get(code);
  169. }
  170.  
  171. /**
  172.   * Gets the color represented by the specified color code
  173.   *
  174.   * @param code Code to check
  175.   * @return Associative {@link org.bukkit.ChatColor} with the given code,
  176.   * or null if it doesn't exist
  177.   */
  178. public static ChatColor getByChar(String code) {
  179. return BY_CHAR.get(code.charAt(0));
  180. }
  181.  
  182. /**
  183.   * Strips the given message of all color codes
  184.   *
  185.   * @param input String to strip of color
  186.   * @return A copy of the input string, without any coloring
  187.   */
  188. public static String stripColor(final String input) {
  189. if (input == null) {
  190. return null;
  191. }
  192.  
  193. return STRIP_COLOR_PATTERN.matcher(input).replaceAll("");
  194. }
  195.  
  196. /**
  197.   * Translates a string using an alternate color code character into a
  198.   * string that uses the internal ChatColor.COLOR_CODE color code
  199.   * character. The alternate color code character will only be replaced if
  200.   * it is immediately followed by 0-9, A-F, a-f, K-O, k-o, R or r.
  201.   *
  202.   * @param altColorChar The alternate color code character to replace. Ex: &
  203.   * @param textToTranslate Text containing the alternate color code character.
  204.   * @return Text containing the ChatColor.COLOR_CODE color code character.
  205.   */
  206. public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) {
  207. char[] b = textToTranslate.toCharArray();
  208. for (int i = 0; i < b.length - 1; i++) {
  209. if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i+1]) > -1) {
  210. b[i] = ChatColor.COLOR_CHAR;
  211. b[i+1] = Character.toLowerCase(b[i+1]);
  212. }
  213. }
  214. return new String(b);
  215. }
  216.  
  217. /**
  218.   * Gets the ChatColors used at the end of the given input string.
  219.   *
  220.   * @param input Input string to retrieve the colors from.
  221.   * @return Any remaining ChatColors to pass onto the next line.
  222.   */
  223. public static String getLastColors(String input) {
  224. String result = "";
  225. int length = input.length();
  226.  
  227. // Search backwards from the end as it is faster
  228. for (int index = length - 1; index > -1; index--) {
  229. char section = input.charAt(index);
  230. if (section == COLOR_CHAR && index < length - 1) {
  231. char c = input.charAt(index + 1);
  232. ChatColor color = getByChar(c);
  233.  
  234. if (color != null) {
  235. result = color.toString() + result;
  236.  
  237. // Once we find a color or reset we can stop searching
  238. if (color.isColor() || color.equals(RESET)) {
  239. break;
  240. }
  241. }
  242. }
  243. }
  244.  
  245. return result;
  246. }
  247.  
  248. static {
  249. for (ChatColor color : values()) {
  250. BY_ID.put(color.intCode, color);
  251. BY_CHAR.put(color.code, color);
  252. }
  253. }
  254. }
  255.  
  256. private interface Executor {
  257. void execute();
  258. }
  259.  
  260. public static void checkTime(int amount, Executor executor) {
  261. long start = System.nanoTime();
  262.  
  263. for (int i = 0; i < amount; i++)
  264. {
  265. executor.execute();
  266. }
  267.  
  268. long end = System.nanoTime();
  269.  
  270. System.out.println("Average per call: "+((end - start) / 1000000) + "ns");
  271. }
  272.  
  273. public static String format1(String input, ChatColor...formats)
  274. {
  275. StringBuilder result = new StringBuilder();
  276.  
  277. StringBuilder format = new StringBuilder();
  278. for (ChatColor color : formats) format.append(color);
  279. String formatString = format.toString();
  280.  
  281. for (int i = 0; i < input.length(); i ++) {
  282. result.append(input.charAt(i));
  283.  
  284. if (input.charAt(i) == ChatColor.COLOR_CHAR) {
  285. if (i + 1 < input.length()) {
  286. ChatColor color = ChatColor.getByChar(input.charAt(++i));
  287.  
  288. if (color != null) {
  289. result.append(color.getChar());
  290. result.append(formatString);
  291. }
  292. }
  293. }
  294. }
  295.  
  296. result.append(ChatColor.RESET);
  297.  
  298. return result.toString();
  299. }
  300.  
  301. public static String format2(String input, ChatColor...formats)
  302. {
  303. StringBuilder format = new StringBuilder();
  304. for (ChatColor color : formats) format.append(color);
  305. char[] formatString = format.toString().toCharArray();
  306. char[] o = input.toCharArray();
  307. // List of indices where we should inject our format
  308. LinkedList<Integer> indices = new LinkedList<>();
  309. for (int i = 0; i < o.length - 1; i++) {
  310. int j = i + 1;
  311. if (o[i] == ChatColor.COLOR_CHAR && (('0' <= o[j] && o[j] <= '9') || ('a' <= o[j] && o[j] <= 'f') || ('A' <= o[j] && o[j] <= 'F'))) {
  312. indices.add(j + 1);
  313. i++; // Skip this char
  314. }
  315. }
  316. char[] n = new char[o.length + formatString.length * indices.size() + 2];
  317. n[n.length - 2] = ChatColor.COLOR_CHAR;
  318. n[n.length - 1] = 'r';
  319. Iterator<Integer> it = indices.iterator();
  320. int offset = 0;
  321. int previous = 0;
  322. while (it.hasNext()) {
  323. int next = it.next();
  324. System.arraycopy(o, previous, n, previous + offset, next - previous);
  325. System.arraycopy(formatString, 0, n, next + offset, formatString.length);
  326. previous = next;
  327. offset += formatString.length;
  328. }
  329. System.arraycopy(o, previous, n, previous + offset, o.length - previous);
  330. return new String(n);
  331. }
  332.  
  333. public static void main(String[] args)
  334. {
  335. String name = ChatColor.RED + "Dragon" + ChatColor.BLUE + "phase";
  336. ChatColor[] formats = new ChatColor[]{ChatColor.BOLD, ChatColor.UNDERLINE};
  337.  
  338. System.out.println("Format1: " + format1(name, formats));
  339. System.out.println("Format2: " + format2(name, formats));
  340. checkTime(1000000, new Executor() {
  341. public void execute() {
  342. format1(name, formats);
  343. }
  344. });
  345.  
  346. checkTime(1000000, new Executor() {
  347. public void execute() {
  348. format2(name, formats);
  349. }
  350. });
  351. }
  352. }
Success #stdin #stdout 1.14s 320704KB
stdin
Standard input is empty
stdout
Format1: §c§l§nDragon§9§l§nphase§r
Format2: §c§l§nDragon§9§l§nphase§r
Average per call: 543ns
Average per call: 499ns