vMinecraftChat.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. import java.util.ArrayList;
  2. import java.util.logging.Level;
  3. import java.util.logging.Logger;
  4. //=====================================================================
  5. //Class: vMinecraftChat
  6. //Use: Encapsulates all chat commands added by this mod
  7. //Author: nossr50, TrapAlice, cerevisiae
  8. //=====================================================================
  9. public class vMinecraftChat {
  10. protected static final Logger log = Logger.getLogger("Minecraft");
  11. protected static final int lineLength = 312;
  12. //The array of colors to use
  13. protected static final String[] rainbow = new String[] {
  14. Colors.Red,
  15. Colors.Rose,
  16. Colors.Gold,
  17. Colors.Yellow,
  18. Colors.LightGreen,
  19. Colors.Green,
  20. Colors.LightBlue,
  21. Colors.Blue,
  22. Colors.Navy,
  23. Colors.DarkPurple,
  24. Colors.Purple,
  25. Colors.LightPurple};
  26. //=====================================================================
  27. //Function: gmsg
  28. //Input: Player sender: The player sending the message
  29. // String msg: The message to be broadcast to all players
  30. //Output: None
  31. //Use: Outputs a message to everybody
  32. //=====================================================================
  33. public static void gmsg(Player sender, String msg){
  34. if(sender != null && sender.isMuted())
  35. sender.sendMessage(Colors.Red + "You have been muted.");
  36. for (Player receiver : etc.getServer().getPlayerList()) {
  37. if (receiver == null) return;
  38. if(vMinecraftUsers.getProfile(receiver) == null) return;
  39. //Check if the person has the sender ignored
  40. if(sender != null)
  41. if(vMinecraftUsers.getProfile(receiver).isIgnored(sender))
  42. return;
  43. String[] message = applyColors(wordWrap(msg));
  44. for(String out : message)
  45. receiver.sendMessage(out);
  46. }
  47. }
  48. //=====================================================================
  49. //Function: gmsg
  50. //Input: String msg: The message to be broadcast to all players
  51. //Output: None
  52. //Use: Outputs a message to everybody
  53. //=====================================================================
  54. public static void gmsg(String msg){gmsg(null, msg);}
  55. //=====================================================================
  56. //Function: sendMessage
  57. //Input: Player sender: The player sending the message
  58. // Player receiver: The player receiving the message
  59. // String msg: The message to be broadcast to all players
  60. //Output: None
  61. //Use: Outputs a message to everybody
  62. //=====================================================================
  63. public static void sendMessage(Player sender, Player receiver, String msg){
  64. if(sender != null && sender.isMuted())
  65. sender.sendMessage(Colors.Red + "You have been muted.");
  66. //Check if the receiver has the sender ignored
  67. if(vMinecraftUsers.getProfile(receiver) == null)
  68. return;
  69. if(sender != null)
  70. if(vMinecraftUsers.getProfile(receiver).isIgnored(sender))
  71. {
  72. sendMessage(sender, sender, Colors.Rose + receiver.getName()
  73. + " has you on their ignore list.");
  74. return;
  75. }
  76. String[] message = applyColors(wordWrap(msg));
  77. for(String out : message)
  78. receiver.sendMessage(out);
  79. //Tell them if they are
  80. }
  81. //=====================================================================
  82. //Function: sendMessage
  83. //Input: Player receiver: The player receiving the message
  84. // String msg: The message to be broadcast to all players
  85. //Output: None
  86. //Use: Outputs a message to everybody
  87. //=====================================================================
  88. public static void sendMessage(Player receiver, String msg)
  89. {
  90. sendMessage(null, receiver, msg);
  91. }
  92. //=====================================================================
  93. //Function: wordWrap
  94. //Input: String msg: The message to be wrapped
  95. //Output: String[]: The array of substrings
  96. //Use: Cuts the message apart into whole words short enough to fit
  97. // on one line
  98. //=====================================================================
  99. public static String[] wordWrap(String msg){
  100. //Split each word apart
  101. ArrayList<String> split = new ArrayList<String>();
  102. for(String in : msg.split(" "))
  103. split.add(in);
  104. //Create an arraylist for the output
  105. ArrayList<String> out = new ArrayList<String>();
  106. //While i is less than the length of the array of words
  107. while(!split.isEmpty()){
  108. int len = 0;
  109. //Create an arraylist to hold individual words
  110. ArrayList<String> words = new ArrayList<String>();
  111. //Loop through the words finding their length and increasing
  112. //j, the end point for the sub string
  113. while(!split.isEmpty() && split.get(0) != null && len <= lineLength)
  114. {
  115. int wordLength = msgLength(split.get(0)) + 4;
  116. //If a word is too long for a line
  117. if(wordLength > lineLength)
  118. {
  119. String[] tempArray = wordCut(len, split.remove(0));
  120. words.add(tempArray[0]);
  121. split.add(tempArray[1]);
  122. }
  123. //If the word is not too long to fit
  124. len += wordLength;
  125. if( len < lineLength)
  126. words.add(split.remove(0));
  127. }
  128. //Merge them and add them to the output array.
  129. out.add( etc.combineSplit(0,
  130. words.toArray(new String[words.size()]), " ") + " " );
  131. }
  132. //Convert to an array and return
  133. return out.toArray(new String[out.size()]);
  134. }
  135. //=====================================================================
  136. //Function: msgLength
  137. //Input: String str: The string to find the length of
  138. //Output: int: The length on the screen of a string
  139. //Use: Finds the length on the screen of a string. Ignores colors.
  140. //=====================================================================
  141. public static int msgLength(String str){
  142. int length = 0;
  143. //Loop through all the characters, skipping any color characters
  144. //and their following color codes
  145. for(int x = 0; x<str.length(); x++)
  146. {
  147. if(str.charAt(x) == '^' || str.charAt(x) == Colors.White.charAt(0))
  148. {
  149. if(colorChange(str.charAt(x + 1)) != null)
  150. {
  151. x++;
  152. continue;
  153. }
  154. }
  155. int len = charLength(str.charAt(x));
  156. length += len;
  157. }
  158. return length;
  159. }
  160. //=====================================================================
  161. //Function: wordCut
  162. //Input: String str: The string to find the length of
  163. //Output: String[]: The cut up word
  164. //Use: Cuts apart a word that is too long to fit on one line
  165. //=====================================================================
  166. private static String[] wordCut(int lengthBefore, String str){
  167. int length = lengthBefore;
  168. //Loop through all the characters, skipping any color characters
  169. //and their following color codes
  170. String[] output = new String[2];
  171. int x = 0;
  172. while(length < lineLength && x < str.length())
  173. {
  174. int len = charLength(str.charAt(x));
  175. if( len > 0)
  176. length += len;
  177. else
  178. x++;
  179. x++;
  180. }
  181. if(x > str.length())
  182. x = str.length();
  183. //Add the substring to the output after cutting it
  184. output[0] = str.substring(0, x);
  185. //Add the last of the string to the output.
  186. output[1] = str.substring(x);
  187. return output;
  188. }
  189. //=====================================================================
  190. //Function: charLength
  191. //Input: char x: The character to find the length of.
  192. //Output: int: The length of the character
  193. //Use: Finds the visual length of the character on the screen.
  194. //=====================================================================
  195. private static int charLength(char x)
  196. {
  197. if("i.:,;|!".indexOf(x) != -1)
  198. return 2;
  199. else if("l'".indexOf(x) != -1)
  200. return 3;
  201. else if("tI[]".indexOf(x) != -1)
  202. return 4;
  203. else if("fk{}<>\"*()".indexOf(x) != -1)
  204. return 5;
  205. else if("abcdeghjmnopqrsuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ1234567890\\/#?$%-=_+&^".indexOf(x) != -1)
  206. return 6;
  207. else if("@~".indexOf(x) != -1)
  208. return 7;
  209. else if(x==' ')
  210. return 4;
  211. else
  212. return -1;
  213. }
  214. //=====================================================================
  215. //Function: rainbow
  216. //Input: String msg: The string to colorify
  217. //Output: String: The rainbowed result
  218. //Use: Rainbowifies a string;
  219. //=====================================================================
  220. public static String rainbow(String msg){
  221. String temp = "";
  222. int counter=0;
  223. //Loop through the message applying the colors
  224. for(int x=0; x<msg.length(); x++)
  225. {
  226. temp += rainbow[counter]+msg.charAt(x);
  227. if(msg.charAt(x)!=' ') counter++;
  228. if(counter==rainbow.length) counter = 0;
  229. }
  230. return temp;
  231. }
  232. //=====================================================================
  233. //Function: getName
  234. //Input: Player player: The player to get name as color
  235. //Output: String: The name colored
  236. //Use: Returns the colored name;
  237. //=====================================================================
  238. public static String getName(Player player){
  239. //Add the nickname or the name if there is none
  240. String output = vMinecraftUsers.getProfile(player).getNick();
  241. if(output.isEmpty())
  242. output = player.getName();
  243. //Add the color if there is one
  244. if(player.getColor() != null && player.getColor() != "")
  245. output = player.getColor().substring(0,2) + output;
  246. //Add the tag if there is one
  247. output = vMinecraftUsers.getProfile(player).getTag() + output;
  248. //Add the suffix if there is one
  249. output += vMinecraftUsers.getProfile(player).getSuffix();
  250. output = Colors.White + output;
  251. /*if(playerPrefix != null && !playerPrefix.isEmpty())
  252. output = applyColors(playerPrefix.substring(1)) + output;*/
  253. //Return the name
  254. return output;
  255. }
  256. //=====================================================================
  257. //Function: colorChange
  258. //Input: char colour: The color code to find the color for
  259. //Output: String: The color that the code identified
  260. //Use: Finds a color giving a color code
  261. //=====================================================================
  262. public static String colorChange(char colour)
  263. {
  264. String color = "";
  265. switch(colour)
  266. {
  267. case '0':
  268. color = Colors.Black;
  269. break;
  270. case '1':
  271. color = Colors.Navy;
  272. break;
  273. case '2':
  274. color = Colors.Green;
  275. break;
  276. case '3':
  277. color = Colors.Blue;
  278. break;
  279. case '4':
  280. color = Colors.Red;
  281. break;
  282. case '5':
  283. color = Colors.Purple;
  284. break;
  285. case '6':
  286. color = Colors.Gold;
  287. break;
  288. case '7':
  289. color = Colors.LightGray;
  290. break;
  291. case '8':
  292. color = Colors.Gray;
  293. break;
  294. case '9':
  295. color = Colors.DarkPurple;
  296. break;
  297. case 'a':
  298. color = Colors.LightGreen;
  299. break;
  300. case 'b':
  301. color = Colors.LightBlue;
  302. break;
  303. case 'c':
  304. color = Colors.Rose;
  305. break;
  306. case 'd':
  307. color = Colors.LightPurple;
  308. break;
  309. case 'e':
  310. color = Colors.Yellow;
  311. break;
  312. case 'f':
  313. color = Colors.White;
  314. break;
  315. case 'A':
  316. color = Colors.LightGreen;
  317. break;
  318. case 'B':
  319. color = Colors.LightBlue;
  320. break;
  321. case 'C':
  322. color = Colors.Rose;
  323. break;
  324. case 'D':
  325. color = Colors.LightPurple;
  326. break;
  327. case 'E':
  328. color = Colors.Yellow;
  329. break;
  330. case 'F':
  331. color = Colors.White;
  332. break;
  333. case 'R':
  334. color = "^r";
  335. break;
  336. case 'r':
  337. color = "^r";
  338. break;
  339. default:
  340. color = null;
  341. break;
  342. }
  343. return color;
  344. }
  345. //=====================================================================
  346. //Function: adminChat
  347. //Input: Player player: The player talking
  348. // String message: The message to apply the effect to
  349. //Output: boolean: If this feature is enabled
  350. //Use: Sends messages only to admins
  351. //=====================================================================
  352. public static boolean adminChat(Player player, String message){
  353. //Check if the player can use this feature
  354. if(player.isAdmin() || player.canUseCommand("/adminchat"))
  355. {
  356. //Special formatting for adminchat {Username}
  357. String adminchat = Colors.DarkPurple + "{" + getName(player)
  358. + Colors.DarkPurple +"} ";
  359. //Cut off the @ prefix
  360. if(message.startsWith("@"))
  361. message = message.substring(1, message.length());
  362. //Get the player from the playerlist to send the message to.
  363. for (Player p: etc.getServer().getPlayerList()) {
  364. //If p is not null
  365. if (p != null) {
  366. //And if p is an admin or has access to adminchat send message
  367. if (p.isAdmin() || (p.canUseCommand("/adminchat"))) {
  368. sendMessage(player, p, adminchat + message);
  369. }
  370. }
  371. }
  372. //So you can read adminchat from the server console
  373. log.log(Level.INFO, "@" + "<" + player.getName() + "> " + message);
  374. return true;
  375. }
  376. return false;
  377. }
  378. //=====================================================================
  379. //Function: quote
  380. //Input: Player player: The player talking
  381. // String message: The message to apply the effect to
  382. //Output: boolean: If this feature is enabled
  383. //Use: Displays a message as a quote
  384. //=====================================================================
  385. public static boolean quote(Player player, String message)
  386. {
  387. //Format the name
  388. String playerName = Colors.White + "<" + getName(player)
  389. + Colors.White + "> ";
  390. if(vMinecraftSettings.getInstance().greentext()) {
  391. //Log the chat
  392. log.log(Level.INFO, "<"+player.getName()+"> " + message);
  393. //Output the message
  394. gmsg(player, playerName + Colors.LightGreen + message);
  395. return true;
  396. }
  397. return false;
  398. }
  399. //=====================================================================
  400. //Function: rage
  401. //Input: Player player: The player talking
  402. // String message: The message to apply the effect to
  403. //Output: boolean: If this feature is enabled
  404. //Use: Displays a message in red
  405. //=====================================================================
  406. public static boolean rage(Player player, String message)
  407. {
  408. //Format the name
  409. String playerName = Colors.White + "<"
  410. + getName(player) + Colors.White +"> ";
  411. if (vMinecraftSettings.getInstance().FFF()) {
  412. log.log(Level.INFO, "<"+player.getName()+"> "+message);
  413. //Output the message
  414. gmsg(player, playerName + Colors.Red + message);
  415. return true;
  416. }
  417. return false;
  418. }
  419. //=====================================================================
  420. //Function: quakeColors
  421. //Input: Player player: The player talking
  422. // String message: The message to apply the effect to
  423. //Output: boolean: If this feature is enabled
  424. //Use: Displays a message in red
  425. //=====================================================================
  426. public static boolean quakeColors(Player player, String message)
  427. {
  428. //Format the name
  429. String playerName = Colors.White + "<"
  430. + getName(player) + Colors.White +"> ";
  431. if(vMinecraftSettings.getInstance().quakeColors()) {
  432. String color = vMinecraftUsers.getProfile(player).getColor();
  433. //Log the chat
  434. log.log(Level.INFO, "<"+player.getName()+"> " + message);
  435. //Output the message
  436. gmsg(player, playerName + color + message);
  437. //Loop through the string finding the color codes and inserting them
  438. return true;
  439. }
  440. return false;
  441. }
  442. //=====================================================================
  443. //Function: emote
  444. //Input: Player player: The player talking
  445. // String message: The message to apply the effect to
  446. //Output: boolean: If this feature is enabled
  447. //Use: /me but with our custom colors applied
  448. //=====================================================================
  449. public static boolean emote(Player player, String message)
  450. {
  451. gmsg(player, "* " + getName(player) + " " + Colors.White + message);
  452. return true;
  453. }
  454. //=====================================================================
  455. //Function: applyColors
  456. //Input: String[] message: The lines to be colored
  457. //Output: String[]: The lines, but colorful
  458. //Use: Colors each line
  459. //=====================================================================
  460. public static String[] applyColors(String[] message)
  461. {
  462. if(message != null && message[0] != null && !message[0].isEmpty()){
  463. //The color to start the line with
  464. String recentColor = Colors.White;
  465. //Go through each line
  466. int counter = 0;
  467. int i = 0;
  468. boolean taste = false;
  469. for(String msg: message)
  470. {
  471. //Start the line with the most recent color
  472. String temp = "";
  473. if(!recentColor.equals("^r") && recentColor != null)
  474. temp += recentColor;
  475. //Loop through looking for a color code
  476. for(int x = 0; x< msg.length(); x++)
  477. {
  478. //If the char is a ^ or �
  479. if(taste || msg.charAt(x) == '^'
  480. || msg.charAt(x) == Colors.Red.charAt(0))
  481. {
  482. if(x != msg.length() - 1)
  483. {
  484. //If the following character is a color code
  485. if(vMinecraftChat.colorChange(msg.charAt(x+1)) != null)
  486. {
  487. //Set the most recent color to the new color
  488. recentColor = vMinecraftChat.colorChange(msg.charAt(x+1));
  489. //If the color specified is rainbow
  490. if(taste || recentColor.equals("^r"))
  491. {
  492. //Skip the quake code for rainbow
  493. if(recentColor.equals("^r"))
  494. {
  495. x += 2;
  496. }
  497. //Taste keeps it going with rainbow if there
  498. //are more lines
  499. taste = true;
  500. //Loop through the message applying the colors
  501. while(x < msg.length() && msg.charAt(x) != '^'
  502. && msg.charAt(x) != Colors.Red.charAt(0))
  503. {
  504. temp += rainbow[i] + msg.charAt(x);
  505. if(msg.charAt(x) != ' ') i++;
  506. if(i == rainbow.length) i = 0;
  507. x++;
  508. }
  509. //If it reached another color instead of the end
  510. if(x < msg.length() && msg.charAt(x) == '^'
  511. || x < msg.length()
  512. && msg.charAt(x) == Colors.Red.charAt(0) )
  513. {
  514. taste = false;
  515. i = 0;
  516. x--;
  517. }
  518. }
  519. else
  520. {
  521. //Add the color
  522. temp += recentColor;
  523. //Skip these chars
  524. x++;
  525. }
  526. //Otherwise ignore it.
  527. } else {
  528. temp += msg.charAt(x);
  529. }
  530. //Insert the character
  531. } else {
  532. temp += msg.charAt(x);
  533. }
  534. } else {
  535. temp += msg.charAt(x);
  536. }
  537. }
  538. //Replace the message with the colorful message
  539. message[counter] = temp;
  540. counter++;
  541. }
  542. }
  543. return message;
  544. }
  545. }