PageRenderTime 77ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Player.java

http://github.com/traitor/Minecraft-Server-Mod
Java | 1397 lines | 979 code | 131 blank | 287 comment | 409 complexity | 73c98262ce6f15ab290e2e534a309207 MD5 | raw file
  1. import java.util.ArrayList;
  2. import java.util.Date;
  3. import java.util.List;
  4. import java.util.Map;
  5. import java.util.Map.Entry;
  6. import java.util.logging.Level;
  7. import java.util.logging.Logger;
  8. import java.util.regex.Matcher;
  9. import java.util.regex.Pattern;
  10. import net.minecraft.server.MinecraftServer;
  11. /**
  12. * Player.java - Interface for eo so mods don't have to update often.
  13. *
  14. * @author James
  15. */
  16. public class Player extends HumanEntity implements MessageReceiver {
  17. private static final Logger log = Logger.getLogger("Minecraft");
  18. private int id = -1;
  19. private String prefix = "";
  20. private String[] commands = new String[] { "" };
  21. private ArrayList<String> groups = new ArrayList<String>();
  22. private String[] ips = new String[] { "" };
  23. private boolean ignoreRestrictions = false;
  24. private boolean admin = false;
  25. private boolean canModifyWorld = false;
  26. private boolean muted = false;
  27. private PlayerInventory inventory;
  28. private List<String> onlyOneUseKits = new ArrayList<String>();
  29. private Pattern badChatPattern = Pattern.compile("[^ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ\\[\\\\\\]^_'abcdefghijklmnopqrstuvwxyz{|}~\u2302\u00C7\u00FC\u00E9\u00E2\u00E4\u00E0\u00E5\u00E7\u00EA\u00EB\u00E8\u00EF\u00EE\u00EC\u00C4\u00C5\u00C9\u00E6\u00C6\u00F4\u00F6\u00F2\u00FB\u00F9\u00FF\u00D6\u00DC\u00F8\u00A3\u00D8\u00D7\u0192\u00E1\u00ED\u00F3\u00FA\u00F1\u00D1\u00AA\u00BA\u00BF\u00AE\u00AC\u00BD\u00BC\u00A1\u00AB\u00BB]");
  30. /**
  31. * Creates an empty player. Add the player by calling {@link #setUser(es)}
  32. */
  33. public Player() {
  34. }
  35. public Player(OEntityPlayerMP player) {
  36. setUser(player);
  37. }
  38. /**
  39. * Returns the entity we're wrapping.
  40. *
  41. * @return
  42. */
  43. public OEntityPlayerMP getEntity() {
  44. return (OEntityPlayerMP) entity;
  45. }
  46. /**
  47. * Returns if the player is still connected
  48. *
  49. * @return
  50. */
  51. public boolean isConnected() {
  52. return !getEntity().a.c;
  53. }
  54. /**
  55. * Kicks player with the specified reason
  56. *
  57. * @param reason
  58. */
  59. public void kick(String reason) {
  60. getEntity().a.a(reason);
  61. }
  62. /**
  63. * Sends player a notification
  64. *
  65. * @param message
  66. */
  67. public void notify(String message) {
  68. if (message.length() > 0)
  69. sendMessage(Colors.Rose + message);
  70. }
  71. /**
  72. * Sends a message to the player
  73. *
  74. * @param message
  75. */
  76. public void sendMessage(String message) {
  77. getEntity().a.msg(message);
  78. }
  79. /**
  80. * Gives an item to the player
  81. *
  82. * @param item
  83. */
  84. public void giveItem(Item item) {
  85. inventory.addItem(item);
  86. inventory.update();
  87. }
  88. /**
  89. * Makes player send message.
  90. *
  91. * @param message
  92. */
  93. public void chat(String message) {
  94. if (message.length() > 100) {
  95. kick("Chat message too long");
  96. return;
  97. }
  98. message = message.trim();
  99. Matcher m = badChatPattern.matcher(message);
  100. if (m.find()) {
  101. kick("Illegal characters '" + m.group() + "' hex: " + Integer.toHexString(message.charAt(m.start())) + " in chat");
  102. return;
  103. }
  104. if (message.startsWith("/"))
  105. command(message);
  106. else {
  107. if (isMuted()) {
  108. sendMessage(Colors.Rose + "You are currently muted.");
  109. return;
  110. }
  111. if ((Boolean) etc.getLoader().callHook(PluginLoader.Hook.CHAT, new Object[] { this, message }))
  112. return;
  113. String chat = "<" + getColor() + getName() + Colors.White + "> " + message;
  114. log.log(Level.INFO, "<" + getName() + "> " + message);
  115. etc.getServer().messageAll(chat);
  116. }
  117. }
  118. /**
  119. * Makes player use command.
  120. *
  121. * @param command
  122. *
  123. */
  124. public void command(String command) {
  125. try {
  126. if (etc.getInstance().isLogging())
  127. log.info("Command used by " + getName() + " " + command);
  128. String[] split = command.split(" ");
  129. String cmd = split[0];
  130. if ((Boolean) etc.getLoader().callHook(PluginLoader.Hook.COMMAND, new Object[] { this, split }))
  131. return; // No need to go on, commands were parsed.
  132. if (!canUseCommand(cmd) && !cmd.startsWith("/#")) {
  133. if (etc.getInstance().showUnknownCommand())
  134. sendMessage(Colors.Rose + "Unknown command.");
  135. return;
  136. }
  137. // Remove '/' before checking.
  138. if (ServerConsoleCommands.parseServerConsoleCommand(this, cmd.substring(1), split)) {
  139. // Command parsed successfully...
  140. } else if (cmd.equalsIgnoreCase("/help")) {
  141. // Meh, not the greatest way, but not the worst either.
  142. List<String> availableCommands = new ArrayList<String>();
  143. for (Entry<String, String> entry : etc.getInstance().getCommands().entrySet())
  144. if (canUseCommand(entry.getKey())) {
  145. if (entry.getKey().equals("/kit") && !etc.getDataSource().hasKits())
  146. continue;
  147. if (entry.getKey().equals("/listwarps") && !etc.getDataSource().hasWarps())
  148. continue;
  149. availableCommands.add(entry.getKey() + " " + entry.getValue());
  150. }
  151. sendMessage(Colors.Blue + "Available commands (Page " + (split.length == 2 ? split[1] : "1") + " of " + (int) Math.ceil((double) availableCommands.size() / (double) 7) + ") [] = required <> = optional:");
  152. if (split.length == 2)
  153. try {
  154. int amount = Integer.parseInt(split[1]);
  155. if (amount > 0)
  156. amount = (amount - 1) * 7;
  157. else
  158. amount = 0;
  159. for (int i = amount; i < amount + 7; i++)
  160. if (availableCommands.size() > i)
  161. sendMessage(Colors.Rose + availableCommands.get(i));
  162. } catch (NumberFormatException ex) {
  163. sendMessage(Colors.Rose + "Not a valid page number.");
  164. }
  165. else
  166. for (int i = 0; i < 7; i++)
  167. if (availableCommands.size() > i)
  168. sendMessage(Colors.Rose + availableCommands.get(i));
  169. } else if (cmd.equalsIgnoreCase("/mute")) {
  170. if (split.length != 2) {
  171. sendMessage(Colors.Rose + "Correct usage is: /mute [player]");
  172. return;
  173. }
  174. Player player = etc.getServer().matchPlayer(split[1]);
  175. if (player != null) {
  176. if (player.toggleMute())
  177. sendMessage(Colors.Rose + "player was muted");
  178. else
  179. sendMessage(Colors.Rose + "player was unmuted");
  180. } else
  181. sendMessage(Colors.Rose + "Can't find player " + split[1]);
  182. } else if ((cmd.equalsIgnoreCase("/msg") || cmd.equalsIgnoreCase("/tell")) || cmd.equalsIgnoreCase("/m")) {
  183. if (split.length < 3) {
  184. sendMessage(Colors.Rose + "Correct usage is: /msg [player] [message]");
  185. return;
  186. }
  187. if (isMuted()) {
  188. sendMessage(Colors.Rose + "You are currently muted.");
  189. return;
  190. }
  191. Player player = etc.getServer().matchPlayer(split[1]);
  192. if (player != null) {
  193. if (player.getName().equals(getName())) {
  194. sendMessage(Colors.Rose + "You can't message yourself!");
  195. return;
  196. }
  197. player.sendMessage("(MSG) " + getColor() + "<" + getName() + "> " + Colors.White + etc.combineSplit(2, split, " "));
  198. sendMessage("(MSG) " + getColor() + "<" + getName() + "> " + Colors.White + etc.combineSplit(2, split, " "));
  199. } else
  200. sendMessage(Colors.Rose + "Couldn't find player " + split[1]);
  201. } else if (cmd.equalsIgnoreCase("/kit") && etc.getDataSource().hasKits()) {
  202. if (split.length != 2 && split.length != 3) {
  203. sendMessage(Colors.Rose + "Available kits" + Colors.White + ": " + etc.getDataSource().getKitNames(this));
  204. return;
  205. }
  206. Player toGive = this;
  207. if (split.length > 2 && canIgnoreRestrictions())
  208. toGive = etc.getServer().matchPlayer(split[2]);
  209. Kit kit = etc.getDataSource().getKit(split[1]);
  210. if (toGive != null) {
  211. if (kit != null) {
  212. if (!isInGroup(kit.Group) && !kit.Group.equals(""))
  213. sendMessage(Colors.Rose + "That kit does not exist.");
  214. else if (onlyOneUseKits.contains(kit.Name))
  215. sendMessage(Colors.Rose + "You can only get this kit once per login.");
  216. else if (MinecraftServer.b.containsKey(getName() + " " + kit.Name))
  217. sendMessage(Colors.Rose + "You can't get this kit again for a while.");
  218. else {
  219. if (!canIgnoreRestrictions())
  220. if (kit.Delay >= 0)
  221. MinecraftServer.b.put(getName() + " " + kit.Name, kit.Delay);
  222. else
  223. onlyOneUseKits.add(kit.Name);
  224. log.info(getName() + " got a kit!");
  225. toGive.sendMessage(Colors.Rose + "Enjoy this kit!");
  226. for (Map.Entry<String, Integer> entry : kit.IDs.entrySet())
  227. try {
  228. int itemId = 0;
  229. try {
  230. itemId = Integer.parseInt(entry.getKey());
  231. } catch (NumberFormatException n) {
  232. itemId = etc.getDataSource().getItem(entry.getKey());
  233. }
  234. toGive.giveItem(itemId, kit.IDs.get(entry.getKey()));
  235. } catch (Exception e1) {
  236. log.info("Got an exception while giving out a kit (Kit name \"" + kit.Name + "\"). Are you sure all the Ids are numbers?");
  237. sendMessage(Colors.Rose + "The server encountered a problem while giving the kit :(");
  238. }
  239. }
  240. } else
  241. sendMessage(Colors.Rose + "That kit does not exist.");
  242. } else
  243. sendMessage(Colors.Rose + "That user does not exist.");
  244. } else if (cmd.equalsIgnoreCase("/tp")) {
  245. if (split.length < 2) {
  246. sendMessage(Colors.Rose + "Correct usage is: /tp [player]");
  247. return;
  248. }
  249. Player player = etc.getServer().matchPlayer(split[1]);
  250. if (player != null) {
  251. if (getName().equalsIgnoreCase(player.getName())) {
  252. sendMessage(Colors.Rose + "You're already here!");
  253. return;
  254. }
  255. log.info(getName() + " teleported to " + player.getName());
  256. teleportTo(player);
  257. } else
  258. sendMessage(Colors.Rose + "Can't find user " + split[1] + ".");
  259. } else if ((cmd.equalsIgnoreCase("/tphere") || cmd.equalsIgnoreCase("/s"))) {
  260. if (split.length < 2) {
  261. sendMessage(Colors.Rose + "Correct usage is: /tphere [player]");
  262. return;
  263. }
  264. Player player = etc.getServer().matchPlayer(split[1]);
  265. if (player != null) {
  266. if (getName().equalsIgnoreCase(player.getName())) {
  267. sendMessage(Colors.Rose + "Wow look at that! You teleported yourself to yourself!");
  268. return;
  269. }
  270. log.info(getName() + " teleported " + player.getName() + " to their self.");
  271. player.teleportTo(this);
  272. } else
  273. sendMessage(Colors.Rose + "Can't find user " + split[1] + ".");
  274. } else if (cmd.equalsIgnoreCase("/playerlist") || cmd.equalsIgnoreCase("/who"))
  275. sendMessage(Colors.Rose + "Player list (" + etc.getMCServer().f.b.size() + "/" + etc.getInstance().getPlayerLimit() + "): " + Colors.White + etc.getMCServer().f.c());
  276. else if (cmd.equalsIgnoreCase("/item") || cmd.equalsIgnoreCase("/i") || cmd.equalsIgnoreCase("/give")) {
  277. if (split.length < 2) {
  278. if (canIgnoreRestrictions())
  279. sendMessage(Colors.Rose + "Correct usage is: /item [itemid] <amount> <damage> <player> (optional)");
  280. else
  281. sendMessage(Colors.Rose + "Correct usage is: /item [itemid] <amount> <damage>");
  282. return;
  283. }
  284. Player toGive = this;
  285. int itemId = 0, amount = 1, damage = 0;
  286. try {
  287. if (split.length > 1)
  288. try {
  289. itemId = Integer.parseInt(split[1]);
  290. } catch (NumberFormatException n) {
  291. itemId = etc.getDataSource().getItem(split[1]);
  292. }
  293. if (split.length > 2) {
  294. amount = Integer.parseInt(split[2]);
  295. if (amount <= 0 && !isAdmin())
  296. amount = 1;
  297. if (amount > 64 && !canIgnoreRestrictions())
  298. amount = 64;
  299. if (amount > 1024)
  300. amount = 1024; // 16 stacks worth. More than enough.
  301. }
  302. if (split.length == 4) {
  303. int temp = -1;
  304. try {
  305. temp = Integer.parseInt(split[3]);
  306. } catch (NumberFormatException n) {
  307. if (canIgnoreRestrictions())
  308. toGive = etc.getServer().matchPlayer(split[3]);
  309. }
  310. if (temp > -1 && temp < 50)
  311. damage = temp;
  312. } else if (split.length == 5) {
  313. damage = Integer.parseInt(split[3]);
  314. if (damage < 0 && damage > 49)
  315. damage = 0;
  316. if (canIgnoreRestrictions())
  317. toGive = etc.getServer().matchPlayer(split[4]);
  318. }
  319. } catch (NumberFormatException localNumberFormatException) {
  320. sendMessage(Colors.Rose + "Improper ID and/or amount.");
  321. return;
  322. }
  323. if (toGive != null) {
  324. boolean allowedItem = etc.getInstance().getAllowedItems().isEmpty() || etc.getInstance().getAllowedItems().contains(itemId);
  325. if (!etc.getInstance().getDisallowedItems().isEmpty() && etc.getInstance().getDisallowedItems().contains(itemId))
  326. allowedItem = false;
  327. if (Item.isValidItem(itemId)) {
  328. if (allowedItem || canIgnoreRestrictions()) {
  329. Item i = new Item(itemId, amount, -1, damage);
  330. log.log(Level.INFO, "Giving " + toGive.getName() + " some " + i.toString());
  331. // toGive.giveItem(itemId, amount);
  332. Inventory inv = toGive.getInventory();
  333. ArrayList<Item> list = new ArrayList<Item>();
  334. for (Item it : inv.getContents())
  335. if (it != null && it.getItemId() == i.getItemId() && it.getDamage() == i.getDamage())
  336. list.add(it);
  337. for (Item it : list) {
  338. if (it.getAmount() < 64) {
  339. if (amount >= 64 - it.getAmount()) {
  340. amount -= 64 - it.getAmount();
  341. it.setAmount(64);
  342. toGive.giveItem(it);
  343. } else {
  344. it.setAmount(it.getAmount() + amount);
  345. amount = 0;
  346. toGive.giveItem(it);
  347. }
  348. }
  349. }
  350. if (amount != 0) {
  351. i.setAmount(64);
  352. while (amount > 64) {
  353. amount -= 64;
  354. toGive.giveItem(i);
  355. i.setSlot(-1);
  356. }
  357. i.setAmount(amount);
  358. toGive.giveItem(i);
  359. }
  360. if (toGive.getName().equalsIgnoreCase(getName()))
  361. sendMessage(Colors.Rose + "There you go " + getName() + ".");
  362. else {
  363. sendMessage(Colors.Rose + "Gift given! :D");
  364. toGive.sendMessage(Colors.Rose + "Enjoy your gift! :D");
  365. }
  366. } else if (!allowedItem && !canIgnoreRestrictions())
  367. sendMessage(Colors.Rose + "You are not allowed to spawn that item.");
  368. } else
  369. sendMessage(Colors.Rose + "No item with ID " + split[1]);
  370. } else
  371. sendMessage(Colors.Rose + "Can't find user " + split[3]);
  372. } else if (cmd.equalsIgnoreCase("/cloth") || cmd.equalsIgnoreCase("/dye")) {
  373. if (split.length < 3) {
  374. sendMessage(Colors.Rose + "Correct usage is: " + cmd + " [amount] [color]");
  375. return;
  376. }
  377. try {
  378. int amount = Integer.parseInt(split[1]);
  379. if (amount <= 0 && !isAdmin())
  380. amount = 1;
  381. if (amount > 64 && !canIgnoreRestrictions())
  382. amount = 64;
  383. if (amount > 1024)
  384. amount = 1024; // 16 stacks worth. More than enough.
  385. String color = split[2];
  386. if (split.length > 3)
  387. color += " " + split[3];
  388. Cloth.Color c = Cloth.Color.getColor(color.toLowerCase());
  389. if (c == null) {
  390. sendMessage(Colors.Rose + "Invalid color name!");
  391. return;
  392. }
  393. Item i = c.getItem();
  394. if (cmd.equalsIgnoreCase("/dye")) {
  395. i.setType(Item.Type.InkSack);
  396. // some1 had fun inverting this i guess .....
  397. i.setDamage(15 - i.getDamage());
  398. }
  399. i.setAmount(amount);
  400. log.log(Level.INFO, "Giving " + getName() + " some " + i.toString());
  401. Inventory inv = getInventory();
  402. ArrayList<Item> list = new ArrayList<Item>();
  403. for (Item it : inv.getContents())
  404. if (it != null && it.getItemId() == i.getItemId() && it.getDamage() == i.getDamage())
  405. list.add(it);
  406. for (Item it : list) {
  407. if (it.getAmount() < 64) {
  408. if (amount >= 64 - it.getAmount()) {
  409. amount -= 64 - it.getAmount();
  410. it.setAmount(64);
  411. giveItem(it);
  412. } else {
  413. it.setAmount(it.getAmount() + amount);
  414. amount = 0;
  415. giveItem(it);
  416. }
  417. }
  418. }
  419. if (amount != 0) {
  420. i.setAmount(64);
  421. while (amount > 64) {
  422. amount -= 64;
  423. giveItem(i);
  424. i.setSlot(-1);
  425. }
  426. i.setAmount(amount);
  427. giveItem(i);
  428. }
  429. sendMessage(Colors.Rose + "There you go " + getName() + ".");
  430. } catch (NumberFormatException localNumberFormatException) {
  431. sendMessage(Colors.Rose + "Improper ID and/or amount.");
  432. }
  433. } else if (cmd.equalsIgnoreCase("/tempban")) {
  434. // /tempban MINUTES HOURS DAYS
  435. if (split.length == 1)
  436. return;
  437. int minutes = 0, hours = 0, days = 0;
  438. if (split.length >= 2)
  439. minutes = Integer.parseInt(split[1]);
  440. if (split.length >= 3)
  441. hours = Integer.parseInt(split[2]);
  442. if (split.length >= 4)
  443. days = Integer.parseInt(split[3]);
  444. Date date = new Date();
  445. // date.
  446. } else if (cmd.equalsIgnoreCase("/banlist")) {
  447. byte type = 0;
  448. if (split.length == 2)
  449. if (split[1].equalsIgnoreCase("ips"))
  450. type = 1;
  451. if (type == 0)
  452. sendMessage(Colors.Blue + "Ban list:" + Colors.White + " " + etc.getMCServer().f.getBans());
  453. else
  454. sendMessage(Colors.Blue + "IP Ban list:" + Colors.White + " " + etc.getMCServer().f.getIpBans());
  455. } else if (cmd.equalsIgnoreCase("/banip")) {
  456. if (split.length < 2) {
  457. sendMessage(Colors.Rose + "Correct usage is: /banip [player] <reason> (optional) NOTE: this permabans IPs.");
  458. return;
  459. }
  460. Player player = etc.getServer().matchPlayer(split[1]);
  461. if (player != null) {
  462. if (!hasControlOver(player)) {
  463. sendMessage(Colors.Rose + "You can't ban that user.");
  464. return;
  465. }
  466. // adds player to ban list
  467. etc.getMCServer().f.c(player.getIP());
  468. etc.getLoader().callHook(PluginLoader.Hook.IPBAN, new Object[] { this, player, split.length >= 3 ? etc.combineSplit(2, split, " ") : "" });
  469. log.log(Level.INFO, "IP Banning " + player.getName() + " (IP: " + player.getIP() + ")");
  470. sendMessage(Colors.Rose + "IP Banning " + player.getName() + " (IP: " + player.getIP() + ")");
  471. if (split.length > 2)
  472. player.kick("IP Banned by " + getName() + ": " + etc.combineSplit(2, split, " "));
  473. else
  474. player.kick("IP Banned by " + getName() + ".");
  475. } else
  476. sendMessage(Colors.Rose + "Can't find user " + split[1] + ".");
  477. } else if (cmd.equalsIgnoreCase("/ban")) {
  478. if (split.length < 2) {
  479. sendMessage(Colors.Rose + "Correct usage is: /ban [player] <reason> (optional)");
  480. return;
  481. }
  482. Player player = etc.getServer().matchPlayer(split[1]);
  483. if (player != null) {
  484. if (!hasControlOver(player)) {
  485. sendMessage(Colors.Rose + "You can't ban that user.");
  486. return;
  487. }
  488. // adds player to ban list
  489. etc.getServer().ban(player.getName());
  490. etc.getLoader().callHook(PluginLoader.Hook.BAN, new Object[] { this, player, split.length >= 3 ? etc.combineSplit(2, split, " ") : "" });
  491. if (split.length > 2)
  492. player.kick("Banned by " + getName() + ": " + etc.combineSplit(2, split, " "));
  493. else
  494. player.kick("Banned by " + getName() + ".");
  495. log.log(Level.INFO, "Banning " + player.getName());
  496. sendMessage(Colors.Rose + "Banning " + player.getName());
  497. } else {
  498. // sendMessage(Colors.Rose + "Can't find user " + split[1] +
  499. // ".");
  500. etc.getServer().ban(split[1]);
  501. log.log(Level.INFO, "Banning " + split[1]);
  502. sendMessage(Colors.Rose + "Banning " + split[1]);
  503. }
  504. } else if (cmd.equalsIgnoreCase("/unban")) {
  505. if (split.length != 2) {
  506. sendMessage(Colors.Rose + "Correct usage is: /unban [player]");
  507. return;
  508. }
  509. etc.getServer().unban(split[1]);
  510. sendMessage(Colors.Rose + "Unbanned " + split[1]);
  511. } else if (cmd.equalsIgnoreCase("/unbanip")) {
  512. if (split.length != 2) {
  513. sendMessage(Colors.Rose + "Correct usage is: /unbanip [ip]");
  514. return;
  515. }
  516. etc.getMCServer().f.d(split[1]);
  517. sendMessage(Colors.Rose + "Unbanned " + split[1]);
  518. } else if (cmd.equalsIgnoreCase("/kick")) {
  519. if (split.length < 2) {
  520. sendMessage(Colors.Rose + "Correct usage is: /kick [player] <reason> (optional)");
  521. return;
  522. }
  523. Player player = etc.getServer().matchPlayer(split[1]);
  524. if (player != null) {
  525. if (!hasControlOver(player)) {
  526. sendMessage(Colors.Rose + "You can't kick that user.");
  527. return;
  528. }
  529. etc.getLoader().callHook(PluginLoader.Hook.KICK, new Object[] { this, player, split.length >= 3 ? etc.combineSplit(2, split, " ") : "" });
  530. if (split.length > 2)
  531. player.kick("Kicked by " + getName() + ": " + etc.combineSplit(2, split, " "));
  532. else
  533. player.kick("Kicked by " + getName() + ".");
  534. log.log(Level.INFO, "Kicking " + player.getName());
  535. sendMessage(Colors.Rose + "Kicking " + player.getName());
  536. } else
  537. sendMessage(Colors.Rose + "Can't find user " + split[1] + ".");
  538. } else if (cmd.equalsIgnoreCase("/me")) {
  539. if (isMuted()) {
  540. sendMessage(Colors.Rose + "You are currently muted.");
  541. return;
  542. }
  543. if (split.length == 1)
  544. return;
  545. String paramString2 = "* " + getColor() + getName() + Colors.White + " " + command.substring(command.indexOf(" ")).trim();
  546. log.info("* " + getName() + " " + command.substring(command.indexOf(" ")).trim());
  547. etc.getServer().messageAll(paramString2);
  548. } else if (cmd.equalsIgnoreCase("/sethome")) {
  549. // player.k, player.l, player.m
  550. // x, y, z
  551. Warp home = new Warp();
  552. home.Location = getLocation();
  553. home.Group = ""; // no group neccessary, lol.
  554. home.Name = getName();
  555. etc.getInstance().changeHome(home);
  556. sendMessage(Colors.Rose + "Your home has been set.");
  557. } else if (cmd.equalsIgnoreCase("/spawn"))
  558. teleportTo(etc.getServer().getSpawnLocation());
  559. else if (cmd.equalsIgnoreCase("/setspawn")) {
  560. // New system in beta 1.3: WorldInfo.
  561. OWorldInfo info = etc.getMCServer().e.q;
  562. info.a((int) getX(), info.d(), (int) getZ());
  563. log.info("Spawn position changed.");
  564. sendMessage(Colors.Rose + "You have set the spawn to your current position.");
  565. } else if (cmd.equalsIgnoreCase("/home")) {
  566. Warp home = null;
  567. if (split.length > 1 && isAdmin())
  568. home = etc.getDataSource().getHome(split[1]);
  569. else
  570. home = etc.getDataSource().getHome(getName());
  571. if (home != null)
  572. teleportTo(home.Location);
  573. else if (split.length > 1 && isAdmin())
  574. sendMessage(Colors.Rose + "That player home does not exist");
  575. else
  576. teleportTo(etc.getServer().getSpawnLocation());
  577. } else if (cmd.equalsIgnoreCase("/warp")) {
  578. if (split.length < 2) {
  579. sendMessage(Colors.Rose + "Correct usage is: /warp [warpname]");
  580. return;
  581. }
  582. Player toWarp = this;
  583. Warp warp = null;
  584. if (split.length == 3 && canIgnoreRestrictions()) {
  585. warp = etc.getDataSource().getWarp(split[1]);
  586. toWarp = etc.getServer().matchPlayer(split[2]);
  587. } else
  588. warp = etc.getDataSource().getWarp(split[1]);
  589. if (toWarp != null) {
  590. if (warp != null) {
  591. if (!isInGroup(warp.Group) && !warp.Group.equals(""))
  592. sendMessage(Colors.Rose + "Warp not found.");
  593. else {
  594. toWarp.teleportTo(warp.Location);
  595. toWarp.sendMessage(Colors.Rose + "Woosh!");
  596. }
  597. } else
  598. sendMessage(Colors.Rose + "Warp not found");
  599. } else
  600. sendMessage(Colors.Rose + "Player not found.");
  601. } else if (cmd.equalsIgnoreCase("/listwarps") && etc.getDataSource().hasWarps()) {
  602. if (split.length != 2 && split.length != 3) {
  603. sendMessage(Colors.Rose + "Available warps: " + Colors.White + etc.getDataSource().getWarpNames(this));
  604. return;
  605. }
  606. } else if (cmd.equalsIgnoreCase("/setwarp")) {
  607. if (split.length < 2) {
  608. if (canIgnoreRestrictions())
  609. sendMessage(Colors.Rose + "Correct usage is: /setwarp [warpname] [group]");
  610. else
  611. sendMessage(Colors.Rose + "Correct usage is: /setwarp [warpname]");
  612. return;
  613. }
  614. if (split[1].contains(":")) {
  615. sendMessage("You can't set a warp with \":\" in its name");
  616. return;
  617. }
  618. Warp warp = new Warp();
  619. warp.Name = split[1];
  620. warp.Location = getLocation();
  621. if (split.length == 3)
  622. warp.Group = split[2];
  623. else
  624. warp.Group = "";
  625. etc.getInstance().setWarp(warp);
  626. sendMessage(Colors.Rose + "Created warp point " + split[1] + ".");
  627. } else if (cmd.equalsIgnoreCase("/removewarp")) {
  628. if (split.length < 2) {
  629. sendMessage(Colors.Rose + "Correct usage is: /removewarp [warpname]");
  630. return;
  631. }
  632. Warp warp = etc.getDataSource().getWarp(split[1]);
  633. if (warp != null) {
  634. etc.getDataSource().removeWarp(warp);
  635. sendMessage(Colors.Blue + "Warp removed.");
  636. } else
  637. sendMessage(Colors.Rose + "That warp does not exist");
  638. } else if (cmd.equalsIgnoreCase("/lighter")) {
  639. if (MinecraftServer.b.containsKey(getName() + " lighter")) {
  640. log.info(getName() + " failed to iron!");
  641. sendMessage(Colors.Rose + "You can't create another lighter again so soon");
  642. } else {
  643. if (!canIgnoreRestrictions())
  644. MinecraftServer.b.put(getName() + " lighter", Integer.valueOf(6000));
  645. log.info(getName() + " created a lighter!");
  646. giveItem(259, 1);
  647. }
  648. } else if ((command.startsWith("/#")) && (etc.getMCServer().f.h(getName()))) {
  649. String str = command.substring(2);
  650. log.info(getName() + " issued server command: " + str);
  651. etc.getMCServer().a(str, getEntity().a);
  652. } else if (cmd.equalsIgnoreCase("/time")) {
  653. if (split.length == 2) {
  654. if (split[1].equalsIgnoreCase("day"))
  655. etc.getServer().setRelativeTime(0);
  656. else if (split[1].equalsIgnoreCase("night"))
  657. etc.getServer().setRelativeTime(13000);
  658. else if (split[1].equalsIgnoreCase("check"))
  659. sendMessage(Colors.Rose + "The time is " + etc.getServer().getRelativeTime() + "! (RAW: " + etc.getServer().getTime() + ")");
  660. else
  661. try {
  662. etc.getServer().setRelativeTime(Long.parseLong(split[1]));
  663. } catch (NumberFormatException ex) {
  664. sendMessage(Colors.Rose + "Please enter numbers, not letters.");
  665. }
  666. } else if (split.length == 3) {
  667. if (split[1].equalsIgnoreCase("raw"))
  668. try {
  669. etc.getServer().setTime(Long.parseLong(split[2]));
  670. } catch (NumberFormatException ex) {
  671. sendMessage(Colors.Rose + "Please enter numbers, not letters.");
  672. }
  673. } else {
  674. sendMessage(Colors.Rose + "Correct usage is: /time [time|'day|night|check|raw'] (rawtime)");
  675. return;
  676. }
  677. } else if (cmd.equalsIgnoreCase("/getpos")) {
  678. sendMessage("Pos X: " + getX() + " Y: " + getY() + " Z: " + getZ());
  679. sendMessage("Rotation: " + getRotation() + " Pitch: " + getPitch());
  680. double degreeRotation = ((getRotation() - 90) % 360);
  681. if (degreeRotation < 0)
  682. degreeRotation += 360.0;
  683. sendMessage("Compass: " + etc.getCompassPointForDirection(degreeRotation) + " (" + (Math.round(degreeRotation * 10) / 10.0) + ")");
  684. } else if (cmd.equalsIgnoreCase("/compass")) {
  685. double degreeRotation = ((getRotation() - 90) % 360);
  686. if (degreeRotation < 0)
  687. degreeRotation += 360.0;
  688. sendMessage(Colors.Rose + "Compass: " + etc.getCompassPointForDirection(degreeRotation));
  689. } else if (cmd.equalsIgnoreCase("/motd"))
  690. for (String str : etc.getInstance().getMotd())
  691. sendMessage(str);
  692. else if (cmd.equalsIgnoreCase("/spawnmob")) {
  693. if (split.length == 1) {
  694. sendMessage(Colors.Rose + "Correct usage is: /spawnmob [name] <amount>");
  695. return;
  696. }
  697. if (!Mob.isValid(split[1])) {
  698. sendMessage(Colors.Rose + "Invalid mob. Name has to start with a capital like so: Pig");
  699. return;
  700. }
  701. if (split.length == 2) {
  702. Mob mob = new Mob(split[1], getLocation());
  703. mob.spawn();
  704. } else if (split.length == 3)
  705. try {
  706. int mobnumber = Integer.parseInt(split[2]);
  707. for (int i = 0; i < mobnumber; i++) {
  708. Mob mob = new Mob(split[1], getLocation());
  709. mob.spawn();
  710. }
  711. } catch (NumberFormatException nfe) {
  712. if (!Mob.isValid(split[2])) {
  713. sendMessage(Colors.Rose + "Invalid mob name or number of mobs.");
  714. sendMessage(Colors.Rose + "Mob names have to start with a capital like so: Pig");
  715. } else {
  716. Mob mob = new Mob(split[1], getLocation());
  717. mob.spawn(new Mob(split[2]));
  718. }
  719. }
  720. else if (split.length == 4)
  721. try {
  722. int mobnumber = Integer.parseInt(split[3]);
  723. if (!Mob.isValid(split[2]))
  724. sendMessage(Colors.Rose + "Invalid rider. Name has to start with a capital like so: Pig");
  725. else
  726. for (int i = 0; i < mobnumber; i++) {
  727. Mob mob = new Mob(split[1], getLocation());
  728. mob.spawn(new Mob(split[2]));
  729. }
  730. } catch (NumberFormatException nfe) {
  731. sendMessage(Colors.Rose + "Invalid number of mobs.");
  732. }
  733. } else if (cmd.equalsIgnoreCase("/clearinventory")) {
  734. Player target = this;
  735. if (split.length >= 2 && isAdmin())
  736. target = etc.getServer().matchPlayer(split[1]);
  737. if (target != null) {
  738. Inventory inv = target.getInventory();
  739. inv.clearContents();
  740. inv.update();
  741. if (!target.getName().equals(getName()))
  742. sendMessage(Colors.Rose + "Cleared " + target.getName() + "'s inventory.");
  743. } else
  744. sendMessage(Colors.Rose + "Target not found");
  745. } else if (cmd.equals("/mspawn")) {
  746. if (split.length != 2) {
  747. sendMessage(Colors.Rose + "You must specify what to change the mob spawner to.");
  748. return;
  749. }
  750. if (!Mob.isValid(split[1])) {
  751. sendMessage(Colors.Rose + "Invalid mob specified.");
  752. return;
  753. }
  754. HitBlox hb = new HitBlox(this);
  755. Block block = hb.getTargetBlock();
  756. if (block.getType() == 52) { // mob spawner
  757. MobSpawner ms = (MobSpawner) etc.getServer().getComplexBlock(block.getX(), block.getY(), block.getZ());
  758. if (ms != null)
  759. ms.setSpawn(split[1]);
  760. } else
  761. sendMessage(Colors.Rose + "You are not targeting a mob spawner.");
  762. } else {
  763. log.info(getName() + " tried command " + command);
  764. if (etc.getInstance().showUnknownCommand())
  765. sendMessage(Colors.Rose + "Unknown command");
  766. }
  767. } catch (Throwable ex) { // Might as well try and catch big exceptions
  768. // before the server crashes from a stack
  769. // overflow or something
  770. log.log(Level.SEVERE, "Exception in command handler (Report this to hey0 unless you did something dumb like enter letters as numbers):", ex);
  771. if (isAdmin())
  772. sendMessage(Colors.Rose + "Exception occured. Check the server for more info.");
  773. }
  774. }
  775. /**
  776. * Gives an item to the player
  777. *
  778. * @param itemId
  779. * @param amount
  780. */
  781. public void giveItem(int itemId, int amount) {
  782. inventory.giveItem(itemId, amount);
  783. inventory.update();
  784. }
  785. /**
  786. * Gives the player this item by dropping it in front of them
  787. *
  788. * @param item
  789. */
  790. public void giveItemDrop(Item item) {
  791. giveItemDrop(item.getItemId(), item.getAmount());
  792. }
  793. /**
  794. * Gives the player this item by dropping it in front of them
  795. *
  796. * @param itemId
  797. * @param amount
  798. */
  799. public void giveItemDrop(int itemId, int amount) {
  800. OEntityPlayerMP player = getEntity();
  801. if (amount == -1)
  802. player.a(new OItemStack(itemId, 255, 0));
  803. else {
  804. int temp = amount;
  805. do {
  806. if (temp - 64 >= 64)
  807. player.a(new OItemStack(itemId, 64, 0));
  808. else
  809. player.a(new OItemStack(itemId, temp, 0));
  810. temp -= 64;
  811. } while (temp > 0);
  812. }
  813. }
  814. /**
  815. * Returns true if this player can use the specified command
  816. *
  817. * @param command
  818. * @return
  819. */
  820. public boolean canUseCommand(String command) {
  821. for (String str : commands)
  822. if (str.equalsIgnoreCase(command))
  823. return true;
  824. for (String str : groups) {
  825. Group g = etc.getDataSource().getGroup(str);
  826. if (g != null)
  827. if (recursiveUseCommand(g, command))
  828. return true;
  829. }
  830. if (hasNoGroups()) {
  831. Group def = etc.getInstance().getDefaultGroup();
  832. if (def != null)
  833. if (recursiveUseCommand(def, command))
  834. return true;
  835. }
  836. return false;
  837. }
  838. private boolean recursiveUseCommand(Group g, String command) {
  839. for (String str : g.Commands)
  840. if (str.equalsIgnoreCase(command) || str.equals("*"))
  841. return true;
  842. if (g.InheritedGroups != null)
  843. for (String str : g.InheritedGroups) {
  844. Group g2 = etc.getDataSource().getGroup(str);
  845. if (g2 != null)
  846. if (recursiveUseCommand(g2, command))
  847. return true;
  848. }
  849. return false;
  850. }
  851. /**
  852. * Checks to see if this player is in the specified group
  853. *
  854. * @param group
  855. * @return
  856. */
  857. public boolean isInGroup(String group) {
  858. if (group != null)
  859. if (etc.getInstance().getDefaultGroup() != null)
  860. if (group.equalsIgnoreCase(etc.getInstance().getDefaultGroup().Name))
  861. return true;
  862. for (String str : groups)
  863. if (recursiveUserInGroup(etc.getDataSource().getGroup(str), group))
  864. return true;
  865. return false;
  866. }
  867. private boolean recursiveUserInGroup(Group g, String group) {
  868. if (g == null || group == null)
  869. return false;
  870. if (g.Name.equalsIgnoreCase(group))
  871. return true;
  872. if (g.InheritedGroups != null)
  873. for (String str : g.InheritedGroups) {
  874. if (g.Name.equalsIgnoreCase(str))
  875. return true;
  876. Group g2 = etc.getDataSource().getGroup(str);
  877. if (g2 != null)
  878. if (recursiveUserInGroup(g2, group))
  879. return true;
  880. }
  881. return false;
  882. }
  883. /**
  884. * Returns true if this player has control over the other player
  885. *
  886. * @param player
  887. * @return true if player has control
  888. */
  889. public boolean hasControlOver(Player player) {
  890. boolean isInGroup = false;
  891. if (player.hasNoGroups())
  892. return true;
  893. for (String str : player.getGroups()) {
  894. if (isInGroup(str))
  895. isInGroup = true;
  896. else
  897. continue;
  898. break;
  899. }
  900. return isInGroup;
  901. }
  902. /**
  903. * Returns the player's current location
  904. *
  905. * @return
  906. */
  907. public Location getLocation() {
  908. Location loc = new Location();
  909. loc.x = getX();
  910. loc.y = getY();
  911. loc.z = getZ();
  912. loc.rotX = getRotation();
  913. loc.rotY = getPitch();
  914. return loc;
  915. }
  916. /**
  917. * Returns the IP of this player
  918. *
  919. * @return
  920. */
  921. public String getIP() {
  922. return getEntity().a.b.b().toString().split(":")[0].substring(1);
  923. }
  924. /**
  925. * Returns true if this player is an admin.
  926. *
  927. * @return
  928. */
  929. public boolean isAdmin() {
  930. if (admin)
  931. return true;
  932. for (String str : groups) {
  933. Group group = etc.getDataSource().getGroup(str);
  934. if (group != null)
  935. if (group.Administrator)
  936. return true;
  937. }
  938. return false;
  939. }
  940. /**
  941. * Don't use this! Use isAdmin
  942. *
  943. * @return
  944. */
  945. public boolean getAdmin() {
  946. return admin;
  947. }
  948. /**
  949. * Sets whether or not this player is an administrator
  950. *
  951. * @param admin
  952. */
  953. public void setAdmin(boolean admin) {
  954. this.admin = admin;
  955. }
  956. /**
  957. * Returns false if this player can not modify terrain, edit chests, etc.
  958. *
  959. * @return
  960. */
  961. public boolean canBuild() {
  962. if (canModifyWorld)
  963. return true;
  964. for (String str : groups) {
  965. Group group = etc.getDataSource().getGroup(str);
  966. if (group != null)
  967. if (group.CanModifyWorld)
  968. return true;
  969. }
  970. if (hasNoGroups())
  971. if (etc.getInstance().getDefaultGroup().CanModifyWorld)
  972. return true;
  973. return false;
  974. }
  975. /**
  976. * Don't use this, use canBuild()
  977. *
  978. * @return
  979. */
  980. public boolean canModifyWorld() {
  981. return canModifyWorld;
  982. }
  983. /**
  984. * Sets whether or not this player can modify the world terrain
  985. *
  986. * @param canModifyWorld
  987. */
  988. public void setCanModifyWorld(boolean canModifyWorld) {
  989. this.canModifyWorld = canModifyWorld;
  990. }
  991. /**
  992. * Set allowed commands
  993. *
  994. * @return
  995. */
  996. public String[] getCommands() {
  997. return commands;
  998. }
  999. /**
  1000. * Sets this player's allowed commands
  1001. *
  1002. * @param commands
  1003. */
  1004. public void setCommands(String[] commands) {
  1005. this.commands = commands;
  1006. }
  1007. /**
  1008. * Returns this player's groups
  1009. *
  1010. * @return
  1011. */
  1012. public String[] getGroups() {
  1013. String[] strGroups = new String[groups.size()];
  1014. groups.toArray(strGroups);
  1015. return strGroups;
  1016. }
  1017. /**
  1018. * Sets this player's groups
  1019. *
  1020. * @param groups
  1021. */
  1022. public void setGroups(String[] groups) {
  1023. this.groups.clear();
  1024. for (String s : groups)
  1025. if (s.length() > 0)
  1026. this.groups.add(s);
  1027. }
  1028. /**
  1029. * Adds the player to the specified group
  1030. *
  1031. * @param group
  1032. * group to add player to
  1033. */
  1034. public void addGroup(String group) {
  1035. groups.add(group);
  1036. }
  1037. /**
  1038. * Removes specified group from list of groups
  1039. *
  1040. * @param group
  1041. * group to remove
  1042. */
  1043. public void removeGroup(String group) {
  1044. groups.remove(group);
  1045. }
  1046. /**
  1047. * Returns the sql ID.
  1048. *
  1049. * @return
  1050. */
  1051. public int getSqlId() {
  1052. return id;
  1053. }
  1054. /**
  1055. * Sets the sql ID. Don't touch this.
  1056. *
  1057. * @param id
  1058. */
  1059. public void setSqlId(int id) {
  1060. this.id = id;
  1061. }
  1062. /**
  1063. * If the user can ignore restrictions this will return true. Things like
  1064. * item amounts and such are unlimited, etc.
  1065. *
  1066. * @return
  1067. */
  1068. public boolean canIgnoreRestrictions() {
  1069. if (admin || ignoreRestrictions)
  1070. return true;
  1071. for (String str : groups) {
  1072. Group group = etc.getDataSource().getGroup(str);
  1073. if (group != null)
  1074. if (group.Administrator || group.IgnoreRestrictions)
  1075. return true;
  1076. }
  1077. return false;
  1078. }
  1079. /**
  1080. * Don't use. Use canIgnoreRestrictions()
  1081. *
  1082. * @return
  1083. */
  1084. public boolean ignoreRestrictions() {
  1085. return ignoreRestrictions;
  1086. }
  1087. /**
  1088. * Sets ignore restrictions
  1089. *
  1090. * @param ignoreRestrictions
  1091. */
  1092. public void setIgnoreRestrictions(boolean ignoreRestrictions) {
  1093. this.ignoreRestrictions = ignoreRestrictions;
  1094. }
  1095. /**
  1096. * Returns allowed IPs
  1097. *
  1098. * @return
  1099. */
  1100. public String[] getIps() {
  1101. return ips;
  1102. }
  1103. /**
  1104. * Sets allowed IPs
  1105. *
  1106. * @param ips
  1107. */
  1108. public void setIps(String[] ips) {
  1109. this.ips = ips;
  1110. }
  1111. /**
  1112. * Returns the correct color/prefix for this player
  1113. *
  1114. * @return
  1115. */
  1116. public String getColor() {
  1117. if (prefix != null)
  1118. if (!prefix.equals(""))
  1119. return "§" + prefix;
  1120. if (groups.size() > 0) {
  1121. Group group = etc.getDataSource().getGroup(groups.get(0));
  1122. if (group != null)
  1123. return "§" + group.Prefix;
  1124. }
  1125. Group def = etc.getInstance().getDefaultGroup();
  1126. return def != null ? "§" + def.Prefix : "";
  1127. }
  1128. /**
  1129. * Returns the prefix. NOTE: Don't use this, use getColor() instead.
  1130. *
  1131. * @return
  1132. */
  1133. public String getPrefix() {
  1134. return prefix;
  1135. }
  1136. /**
  1137. * Sets the prefix
  1138. *
  1139. * @param prefix
  1140. */
  1141. public void setPrefix(String prefix) {
  1142. this.prefix = prefix;
  1143. }
  1144. /**
  1145. * Gets the actual user class.
  1146. *
  1147. * @return
  1148. */
  1149. public OEntityPlayerMP getUser() {
  1150. return getEntity();
  1151. }
  1152. /**
  1153. * Sets the user. Don't use this.
  1154. *
  1155. * @param er
  1156. */
  1157. public void setUser(OEntityPlayerMP player) {
  1158. entity = player;
  1159. inventory = new PlayerInventory(this);
  1160. }
  1161. public void teleportTo(double x, double y, double z, float rotation, float pitch) {
  1162. OEntityPlayerMP player = getEntity();
  1163. // If player is in vehicle - eject them before they are teleported.
  1164. if (player.aE != null)
  1165. player.b(player.aE);
  1166. player.a.a(x, y, z, rotation, pitch);
  1167. }
  1168. /**
  1169. * Returns true if the player is muted
  1170. *
  1171. * @return
  1172. */
  1173. public boolean isMuted() {
  1174. return muted;
  1175. }
  1176. /**
  1177. * Toggles mute
  1178. *
  1179. * @return
  1180. */
  1181. public boolean toggleMute() {
  1182. muted = !muted;
  1183. return muted;
  1184. }
  1185. /**
  1186. * Checks to see if this player is in any groups
  1187. *
  1188. * @return true if this player is in any group
  1189. */
  1190. public boolean hasNoGroups() {
  1191. if (groups.isEmpty())
  1192. return true;
  1193. if (groups.size() == 1)
  1194. return groups.get(0).equals("");
  1195. return false;
  1196. }
  1197. /**
  1198. * Returns item id in player's hand
  1199. *
  1200. * @return
  1201. */
  1202. public int getItemInHand() {
  1203. return getEntity().a.getItemInHand();
  1204. }
  1205. /**
  1206. * Returns this player's inventory
  1207. *
  1208. * @return inventory
  1209. */
  1210. public Inventory getInventory() {
  1211. return inventory;
  1212. }
  1213. /**
  1214. * Returns whether or not this Player is currently sneaking (crouching)
  1215. *
  1216. * @return true if sneaking
  1217. */
  1218. public boolean getSneaking() {
  1219. return getEntity().h;
  1220. }
  1221. /**
  1222. * Force this Player to be sneaking or not
  1223. *
  1224. * @param sneaking
  1225. * true if sneaking
  1226. */
  1227. public void setSneaking(boolean sneaking) {
  1228. getEntity().h = sneaking;
  1229. }
  1230. /**
  1231. * Returns a String representation of this Player
  1232. *
  1233. * @return String representation of this Player
  1234. */
  1235. @Override
  1236. public String toString() {
  1237. return String.format("Player[id=%d, name=%s]", id, getName());
  1238. }
  1239. /**
  1240. * Tests the given object to see if it equals this object
  1241. *
  1242. * @param obj
  1243. * the object to test
  1244. * @return true if the two objects match
  1245. */
  1246. @Override
  1247. public boolean equals(Object obj) {
  1248. if (obj == null)
  1249. return false;
  1250. if (getClass() != obj.getClass())
  1251. return false;
  1252. final Player other = (Player) obj;
  1253. return getName().equals(other.getName());
  1254. }
  1255. /**
  1256. * Returns a unique hashcode for this Player
  1257. *
  1258. * @return hashcode
  1259. */
  1260. @Override
  1261. public int hashCode() {
  1262. int hash = 7;
  1263. hash = 71 * hash + id;
  1264. return hash;
  1265. }
  1266. }