fork(3) 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 name, ChatColor...formats)
  302. {
  303. // Remove any initial section sign, to avoid empty Strings beforehand
  304. StringBuilder sb = new StringBuilder();
  305. for (ChatColor cc : formats)
  306. sb.append(cc);
  307. String format = sb.toString();
  308.  
  309. boolean startsWith = name.startsWith(String.valueOf(ChatColor.COLOR_CHAR));
  310. if (startsWith)
  311. name = name.substring(1);
  312.  
  313. int index = 0;
  314. // Get length
  315. int len = 0;
  316. while ((index = name.indexOf(ChatColor.COLOR_CHAR, index + 1)) >= 0)
  317. len++;
  318. // resetting index
  319. index = 0;
  320. String[] parts = new String[len + 1];
  321. // For each colour char (section sign) in the String
  322. for (int i = 0; (index = name.indexOf(ChatColor.COLOR_CHAR, index + 1)) >= 0; i++)
  323. {
  324. // I was lazy, don't forget the null check!!!!!
  325. if (ChatColor.getByChar(name.substring(index + 1, index + 2)).isFormat())
  326. {
  327. // Skip formats
  328. i--; // Undo increment
  329. continue;
  330. }
  331. // Assign the part up to the section sign, and prepend a the section sign
  332. parts[i] = ChatColor.COLOR_CHAR + name.substring(0, index);
  333. // Remove the part beforehand
  334. name = name.substring(index);
  335. }
  336. parts[parts.length - 1] = name; // Leftovers
  337.  
  338. // Now join
  339. boolean first = true;
  340. StringBuilder joined = new StringBuilder(startsWith ? String.valueOf(ChatColor.COLOR_CHAR) : "");
  341. for (String part : parts)
  342. {
  343. // Start with the format
  344. joined.append(format);
  345. // If it was the first, only add the colour char if it previously had any
  346. if (first)
  347. {
  348. first = false;
  349. }
  350. else // they were split based on colour char, so always add one between
  351. {
  352. joined.append(ChatColor.COLOR_CHAR);
  353. }
  354. joined.append(part);
  355. }
  356. return joined.toString();
  357. }
  358.  
  359. public static void main(String[] args)
  360. {
  361. String name = ChatColor.RED + "Dragon" + ChatColor.BLUE + "phase";
  362. ChatColor[] formats = new ChatColor[]{ChatColor.BOLD, ChatColor.UNDERLINE};
  363.  
  364. System.out.println("Format1: " + format1(name, formats));
  365. System.out.println("Format2: " + format2(name, formats));
  366.  
  367. checkTime(1000000, new Executor() {
  368. public void execute() {
  369. format1(name, formats);
  370. }
  371. });
  372.  
  373. checkTime(1000000, new Executor() {
  374. public void execute() {
  375. format2(name, formats);
  376. }
  377. });
  378. }
  379. }
Success #stdin #stdout 1.5s 320704KB
stdin
Standard input is empty
stdout
Format1: §c§l§nDragon§9§l§nphase§r
Format2: §§l§n§cDragon§l§n§§9phase
Average per call: 535ns
Average per call: 872ns