001 package org.bukkit.command.defaults; 002 003 import java.util.ArrayList; 004 import java.util.Collection; 005 import java.util.Collections; 006 import java.util.HashSet; 007 import java.util.List; 008 import java.util.Map; 009 import java.util.Set; 010 011 import org.apache.commons.lang.ArrayUtils; 012 import org.apache.commons.lang.StringUtils; 013 import org.apache.commons.lang.Validate; 014 import org.bukkit.Bukkit; 015 import org.bukkit.ChatColor; 016 import org.bukkit.OfflinePlayer; 017 import org.bukkit.command.CommandSender; 018 import org.bukkit.entity.Player; 019 import org.bukkit.scoreboard.DisplaySlot; 020 import org.bukkit.scoreboard.Objective; 021 import org.bukkit.scoreboard.Score; 022 import org.bukkit.scoreboard.Scoreboard; 023 import org.bukkit.scoreboard.Team; 024 import org.bukkit.util.StringUtil; 025 026 import com.google.common.collect.ImmutableList; 027 import com.google.common.collect.ImmutableMap; 028 029 public class ScoreboardCommand extends VanillaCommand { 030 031 private static final List<String> MAIN_CHOICES = ImmutableList.of("objectives", "players", "teams"); 032 private static final List<String> OBJECTIVES_CHOICES = ImmutableList.of("list", "add", "remove", "setdisplay"); 033 private static final List<String> OBJECTIVES_CRITERIA = ImmutableList.of("health", "playerKillCount", "totalKillCount", "deathCount", "dummy"); 034 private static final List<String> PLAYERS_CHOICES = ImmutableList.of("set", "add", "remove", "reset", "list"); 035 private static final List<String> TEAMS_CHOICES = ImmutableList.of("add", "remove", "join", "leave", "empty", "list", "option"); 036 private static final List<String> TEAMS_OPTION_CHOICES = ImmutableList.of("color", "friendlyfire", "seeFriendlyInvisibles"); 037 private static final Map<String, DisplaySlot> OBJECTIVES_DISPLAYSLOT = ImmutableMap.of("belowName", DisplaySlot.BELOW_NAME, "list", DisplaySlot.PLAYER_LIST, "sidebar", DisplaySlot.SIDEBAR); 038 private static final Map<String, ChatColor> TEAMS_OPTION_COLOR = ImmutableMap.<String, ChatColor>builder() 039 .put("aqua", ChatColor.AQUA) 040 .put("black", ChatColor.BLACK) 041 .put("blue", ChatColor.BLUE) 042 .put("bold", ChatColor.BOLD) 043 .put("dark_aqua", ChatColor.DARK_AQUA) 044 .put("dark_blue", ChatColor.DARK_BLUE) 045 .put("dark_gray", ChatColor.DARK_GRAY) 046 .put("dark_green", ChatColor.DARK_GREEN) 047 .put("dark_purple", ChatColor.DARK_PURPLE) 048 .put("dark_red", ChatColor.DARK_RED) 049 .put("gold", ChatColor.GOLD) 050 .put("gray", ChatColor.GRAY) 051 .put("green", ChatColor.GREEN) 052 .put("italic", ChatColor.ITALIC) 053 .put("light_purple", ChatColor.LIGHT_PURPLE) 054 .put("obfuscated", ChatColor.MAGIC) // This is the important line 055 .put("red", ChatColor.RED) 056 .put("reset", ChatColor.RESET) 057 .put("strikethrough", ChatColor.STRIKETHROUGH) 058 .put("underline", ChatColor.UNDERLINE) 059 .put("white", ChatColor.WHITE) 060 .put("yellow", ChatColor.YELLOW) 061 .build(); 062 private static final List<String> BOOLEAN = ImmutableList.of("true", "false"); 063 064 public ScoreboardCommand() { 065 super("scoreboard"); 066 this.description = "Scoreboard control"; 067 this.usageMessage = "/scoreboard"; 068 this.setPermission("bukkit.command.scoreboard"); 069 } 070 071 @Override 072 public boolean execute(CommandSender sender, String currentAlias, String[] args) { 073 if (!testPermission(sender)) 074 return true; 075 if (args.length < 1 || args[0].length() == 0) { 076 sender.sendMessage(ChatColor.RED + "Usage: /scoreboard <objectives|players|teams>"); 077 return false; 078 } 079 080 final Scoreboard mainScoreboard = Bukkit.getScoreboardManager().getMainScoreboard(); 081 082 if (args[0].equalsIgnoreCase("objectives")) { 083 if (args.length == 1) { 084 sender.sendMessage(ChatColor.RED + "Usage: /scoreboard objectives <list|add|remove|setdisplay>"); 085 return false; 086 } 087 if (args[1].equalsIgnoreCase("list")) { 088 Set<Objective> objectives = mainScoreboard.getObjectives(); 089 if (objectives.isEmpty()) { 090 sender.sendMessage(ChatColor.RED + "There are no objectives on the scoreboard"); 091 return false; 092 } 093 sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + objectives.size() + " objective(s) on scoreboard"); 094 for (Objective objective : objectives) { 095 sender.sendMessage("- " + objective.getName() + ": displays as '" + objective.getDisplayName() + "' and is type '" + objective.getCriteria() + "'"); 096 } 097 } else if (args[1].equalsIgnoreCase("add")) { 098 if (args.length < 4) { 099 sender.sendMessage(ChatColor.RED + "/scoreboard objectives add <name> <criteriaType> [display name ...]"); 100 return false; 101 } 102 String name = args[2]; 103 String criteria = args[3]; 104 105 if (criteria == null) { 106 sender.sendMessage(ChatColor.RED + "Invalid objective criteria type. Valid types are: " + stringCollectionToString(OBJECTIVES_CRITERIA)); 107 } else if (name.length() > 16) { 108 sender.sendMessage(ChatColor.RED + "The name '" + name + "' is too long for an objective, it can be at most 16 characters long"); 109 } else if (mainScoreboard.getObjective(name) != null) { 110 sender.sendMessage(ChatColor.RED + "An objective with the name '" + name + "' already exists"); 111 } else { 112 String displayName = null; 113 if (args.length > 4) { 114 displayName = StringUtils.join(ArrayUtils.subarray(args, 4, args.length), ' '); 115 if (displayName.length() > 32) { 116 sender.sendMessage(ChatColor.RED + "The name '" + displayName + "' is too long for an objective, it can be at most 32 characters long"); 117 return false; 118 } 119 } 120 Objective objective = mainScoreboard.registerNewObjective(name, criteria); 121 if (displayName != null && displayName.length() > 0) { 122 objective.setDisplayName(displayName); 123 } 124 sender.sendMessage("Added new objective '" + name + "' successfully"); 125 } 126 } else if (args[1].equalsIgnoreCase("remove")) { 127 if (args.length != 3) { 128 sender.sendMessage(ChatColor.RED + "/scoreboard objectives remove <name>"); 129 return false; 130 } 131 String name = args[2]; 132 Objective objective = mainScoreboard.getObjective(name); 133 if (objective == null) { 134 sender.sendMessage(ChatColor.RED + "No objective was found by the name '" + name + "'"); 135 } else { 136 objective.unregister(); 137 sender.sendMessage("Removed objective '" + name + "' successfully"); 138 } 139 } else if (args[1].equalsIgnoreCase("setdisplay")) { 140 if (args.length != 3 && args.length != 4) { 141 sender.sendMessage(ChatColor.RED + "/scoreboard objectives setdisplay <slot> [objective]"); 142 return false; 143 } 144 String slotName = args[2]; 145 DisplaySlot slot = OBJECTIVES_DISPLAYSLOT.get(slotName); 146 if (slot == null) { 147 sender.sendMessage(ChatColor.RED + "No such display slot '" + slotName + "'"); 148 } else { 149 if (args.length == 4) { 150 String objectiveName = args[3]; 151 Objective objective = mainScoreboard.getObjective(objectiveName); 152 if (objective == null) { 153 sender.sendMessage(ChatColor.RED + "No objective was found by the name '" + objectiveName + "'"); 154 return false; 155 } 156 157 objective.setDisplaySlot(slot); 158 sender.sendMessage("Set the display objective in slot '" + slotName + "' to '" + objective.getName() + "'"); 159 } else { 160 Objective objective = mainScoreboard.getObjective(slot); 161 if (objective != null) { 162 objective.setDisplaySlot(null); 163 } 164 sender.sendMessage("Cleared objective display slot '" + slotName + "'"); 165 } 166 } 167 } 168 } else if (args[0].equalsIgnoreCase("players")) { 169 if (args.length == 1) { 170 sender.sendMessage(ChatColor.RED + "/scoreboard players <set|add|remove|reset|list>"); 171 return false; 172 } 173 if (args[1].equalsIgnoreCase("set") || args[1].equalsIgnoreCase("add") || args[1].equalsIgnoreCase("remove")) { 174 if (args.length != 5) { 175 if (args[1].equalsIgnoreCase("set")) { 176 sender.sendMessage(ChatColor.RED + "/scoreboard players set <player> <objective> <score>"); 177 } else if (args[1].equalsIgnoreCase("add")) { 178 sender.sendMessage(ChatColor.RED + "/scoreboard players add <player> <objective> <count>"); 179 } else { 180 sender.sendMessage(ChatColor.RED + "/scoreboard players remove <player> <objective> <count>"); 181 } 182 return false; 183 } 184 String objectiveName = args[3]; 185 Objective objective = mainScoreboard.getObjective(objectiveName); 186 if (objective == null) { 187 sender.sendMessage(ChatColor.RED + "No objective was found by the name '" + objectiveName + "'"); 188 return false; 189 } else if (!objective.isModifiable()) { 190 sender.sendMessage(ChatColor.RED + "The objective '" + objectiveName + "' is read-only and cannot be set"); 191 return false; 192 } 193 194 String valueString = args[4]; 195 int value; 196 try { 197 value = Integer.parseInt(valueString); 198 } catch (NumberFormatException e) { 199 sender.sendMessage(ChatColor.RED + "'" + valueString + "' is not a valid number"); 200 return false; 201 } 202 if (value < 1 && !args[1].equalsIgnoreCase("set")) { 203 sender.sendMessage(ChatColor.RED + "The number you have entered (" + value + ") is too small, it must be at least 1"); 204 return false; 205 } 206 207 String playerName = args[2]; 208 if (playerName.length() > 16) { 209 sender.sendMessage(ChatColor.RED + "'" + playerName + "' is too long for a player name"); 210 return false; 211 } 212 Score score = objective.getScore(playerName); 213 int newScore; 214 if (args[1].equalsIgnoreCase("set")) { 215 newScore = value; 216 } else if (args[1].equalsIgnoreCase("add")) { 217 newScore = score.getScore() + value; 218 } else { 219 newScore = score.getScore() - value; 220 } 221 score.setScore(newScore); 222 sender.sendMessage("Set score of " + objectiveName + " for player " + playerName + " to " + newScore); 223 } else if (args[1].equalsIgnoreCase("reset")) { 224 if (args.length != 3) { 225 sender.sendMessage(ChatColor.RED + "/scoreboard players reset <player>"); 226 return false; 227 } 228 String playerName = args[2]; 229 if (playerName.length() > 16) { 230 sender.sendMessage(ChatColor.RED + "'" + playerName + "' is too long for a player name"); 231 return false; 232 } 233 mainScoreboard.resetScores(playerName); 234 sender.sendMessage("Reset all scores of player " + playerName); 235 } else if (args[1].equalsIgnoreCase("list")) { 236 if (args.length > 3) { 237 sender.sendMessage(ChatColor.RED + "/scoreboard players list <player>"); 238 return false; 239 } 240 if (args.length == 2) { 241 Set<String> entries = mainScoreboard.getEntries(); 242 if (entries.isEmpty()) { 243 sender.sendMessage(ChatColor.RED + "There are no tracked players on the scoreboard"); 244 } else { 245 sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + entries.size() + " tracked players on the scoreboard"); 246 sender.sendMessage(stringCollectionToString(entries)); 247 } 248 } else { 249 String playerName = args[2]; 250 if (playerName.length() > 16) { 251 sender.sendMessage(ChatColor.RED + "'" + playerName + "' is too long for a player name"); 252 return false; 253 } 254 Set<Score> scores = mainScoreboard.getScores(playerName); 255 if (scores.isEmpty()) { 256 sender.sendMessage(ChatColor.RED + "Player " + playerName + " has no scores recorded"); 257 } else { 258 sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + scores.size() + " tracked objective(s) for " + playerName); 259 for (Score score : scores) { 260 sender.sendMessage("- " + score.getObjective().getDisplayName() + ": " + score.getScore() + " (" + score.getObjective().getName() + ")"); 261 } 262 } 263 } 264 } 265 } else if (args[0].equalsIgnoreCase("teams")) { 266 if (args.length == 1) { 267 sender.sendMessage(ChatColor.RED + "/scoreboard teams <list|add|remove|empty|join|leave|option>"); 268 return false; 269 } 270 if (args[1].equalsIgnoreCase("list")) { 271 if (args.length == 2) { 272 Set<Team> teams = mainScoreboard.getTeams(); 273 if (teams.isEmpty()) { 274 sender.sendMessage(ChatColor.RED + "There are no teams registered on the scoreboard"); 275 } else { 276 sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + teams.size() + " teams on the scoreboard"); 277 for (Team team : teams) { 278 sender.sendMessage("- " + team.getName() + ": '" + team.getDisplayName() + "' has " + team.getSize() + " players"); 279 } 280 } 281 } else if (args.length == 3) { 282 String teamName = args[2]; 283 Team team = mainScoreboard.getTeam(teamName); 284 if (team == null) { 285 sender.sendMessage(ChatColor.RED + "No team was found by the name '" + teamName + "'"); 286 } else { 287 Set<OfflinePlayer> players = team.getPlayers(); 288 if (players.isEmpty()) { 289 sender.sendMessage(ChatColor.RED + "Team " + team.getName() + " has no players"); 290 } else { 291 sender.sendMessage(ChatColor.DARK_GREEN + "Showing " + players.size() + " player(s) in team " + team.getName()); 292 sender.sendMessage(offlinePlayerSetToString(players)); 293 } 294 } 295 } else { 296 sender.sendMessage(ChatColor.RED + "/scoreboard teams list [name]"); 297 return false; 298 } 299 } else if (args[1].equalsIgnoreCase("add")) { 300 if (args.length < 3) { 301 sender.sendMessage(ChatColor.RED + "/scoreboard teams add <name> [display name ...]"); 302 return false; 303 } 304 String name = args[2]; 305 if (name.length() > 16) { 306 sender.sendMessage(ChatColor.RED + "The name '" + name + "' is too long for a team, it can be at most 16 characters long"); 307 } else if (mainScoreboard.getTeam(name) != null) { 308 sender.sendMessage(ChatColor.RED + "A team with the name '" + name + "' already exists"); 309 } else { 310 String displayName = null; 311 if (args.length > 3) { 312 displayName = StringUtils.join(ArrayUtils.subarray(args, 3, args.length), ' '); 313 if (displayName.length() > 32) { 314 sender.sendMessage(ChatColor.RED + "The display name '" + displayName + "' is too long for a team, it can be at most 32 characters long"); 315 return false; 316 } 317 } 318 Team team = mainScoreboard.registerNewTeam(name); 319 if (displayName != null && displayName.length() > 0) { 320 team.setDisplayName(displayName); 321 } 322 sender.sendMessage("Added new team '" + team.getName() + "' successfully"); 323 } 324 } else if (args[1].equalsIgnoreCase("remove")) { 325 if (args.length != 3) { 326 sender.sendMessage(ChatColor.RED + "/scoreboard teams remove <name>"); 327 return false; 328 } 329 String name = args[2]; 330 Team team = mainScoreboard.getTeam(name); 331 if (team == null) { 332 sender.sendMessage(ChatColor.RED + "No team was found by the name '" + name + "'"); 333 } else { 334 team.unregister(); 335 sender.sendMessage("Removed team " + name); 336 } 337 } else if (args[1].equalsIgnoreCase("empty")) { 338 if (args.length != 3) { 339 sender.sendMessage(ChatColor.RED + "/scoreboard teams clear <name>"); 340 return false; 341 } 342 String name = args[2]; 343 Team team = mainScoreboard.getTeam(name); 344 if (team == null) { 345 sender.sendMessage(ChatColor.RED + "No team was found by the name '" + name + "'"); 346 } else { 347 Set<OfflinePlayer> players = team.getPlayers(); 348 if (players.isEmpty()) { 349 sender.sendMessage(ChatColor.RED + "Team " + team.getName() + " is already empty, cannot remove nonexistant players"); 350 } else { 351 for (OfflinePlayer player : players) { 352 team.removePlayer(player); 353 } 354 sender.sendMessage("Removed all " + players.size() + " player(s) from team " + team.getName()); 355 } 356 } 357 } else if (args[1].equalsIgnoreCase("join")) { 358 if ((sender instanceof Player) ? args.length < 3 : args.length < 4) { 359 sender.sendMessage(ChatColor.RED + "/scoreboard teams join <team> [player...]"); 360 return false; 361 } 362 String teamName = args[2]; 363 Team team = mainScoreboard.getTeam(teamName); 364 if (team == null) { 365 sender.sendMessage(ChatColor.RED + "No team was found by the name '" + teamName + "'"); 366 } else { 367 Set<String> addedPlayers = new HashSet<String>(); 368 if ((sender instanceof Player) && args.length == 3) { 369 team.addPlayer((Player) sender); 370 addedPlayers.add(sender.getName()); 371 } else { 372 for (int i = 3; i < args.length; i++) { 373 String playerName = args[i]; 374 OfflinePlayer offlinePlayer; 375 Player player = Bukkit.getPlayerExact(playerName); 376 if (player != null) { 377 offlinePlayer = player; 378 } else { 379 offlinePlayer = Bukkit.getOfflinePlayer(playerName); 380 } 381 team.addPlayer(offlinePlayer); 382 addedPlayers.add(offlinePlayer.getName()); 383 } 384 } 385 sender.sendMessage("Added " + addedPlayers.size() + " player(s) to team " + team.getName() + ": " + stringCollectionToString(addedPlayers)); 386 } 387 } else if (args[1].equalsIgnoreCase("leave")) { 388 if (!(sender instanceof Player) && args.length < 3) { 389 sender.sendMessage(ChatColor.RED + "/scoreboard teams leave [player...]"); 390 return false; 391 } 392 Set<String> left = new HashSet<String>(); 393 Set<String> noTeam = new HashSet<String>(); 394 if ((sender instanceof Player) && args.length == 2) { 395 Team team = mainScoreboard.getPlayerTeam((Player) sender); 396 if (team != null) { 397 team.removePlayer((Player) sender); 398 left.add(sender.getName()); 399 } else { 400 noTeam.add(sender.getName()); 401 } 402 } else { 403 for (int i = 2; i < args.length; i++) { 404 String playerName = args[i]; 405 OfflinePlayer offlinePlayer; 406 Player player = Bukkit.getPlayerExact(playerName); 407 if (player != null) { 408 offlinePlayer = player; 409 } else { 410 offlinePlayer = Bukkit.getOfflinePlayer(playerName); 411 } 412 Team team = mainScoreboard.getPlayerTeam(offlinePlayer); 413 if (team != null) { 414 team.removePlayer(offlinePlayer); 415 left.add(offlinePlayer.getName()); 416 } else { 417 noTeam.add(offlinePlayer.getName()); 418 } 419 } 420 } 421 if (!left.isEmpty()) { 422 sender.sendMessage("Removed " + left.size() + " player(s) from their teams: " + stringCollectionToString(left)); 423 } 424 if (!noTeam.isEmpty()) { 425 sender.sendMessage("Could not remove " + noTeam.size() + " player(s) from their teams: " + stringCollectionToString(noTeam)); 426 } 427 } else if (args[1].equalsIgnoreCase("option")) { 428 if (args.length != 4 && args.length != 5) { 429 sender.sendMessage(ChatColor.RED + "/scoreboard teams option <team> <friendlyfire|color|seefriendlyinvisibles> <value>"); 430 return false; 431 } 432 String teamName = args[2]; 433 Team team = mainScoreboard.getTeam(teamName); 434 if (team == null) { 435 sender.sendMessage(ChatColor.RED + "No team was found by the name '" + teamName + "'"); 436 return false; 437 } 438 String option = args[3].toLowerCase(); 439 if (!option.equals("friendlyfire") && !option.equals("color") && !option.equals("seefriendlyinvisibles")) { 440 sender.sendMessage(ChatColor.RED + "/scoreboard teams option <team> <friendlyfire|color|seefriendlyinvisibles> <value>"); 441 return false; 442 } 443 if (args.length == 4) { 444 if (option.equals("color")) { 445 sender.sendMessage(ChatColor.RED + "Valid values for option color are: " + stringCollectionToString(TEAMS_OPTION_COLOR.keySet())); 446 } else { 447 sender.sendMessage(ChatColor.RED + "Valid values for option " + option + " are: true and false"); 448 } 449 } else { 450 String value = args[4].toLowerCase(); 451 if (option.equals("color")) { 452 ChatColor color = TEAMS_OPTION_COLOR.get(value); 453 if (color == null) { 454 sender.sendMessage(ChatColor.RED + "Valid values for option color are: " + stringCollectionToString(TEAMS_OPTION_COLOR.keySet())); 455 return false; 456 } 457 team.setPrefix(color.toString()); 458 team.setSuffix(ChatColor.RESET.toString()); 459 } else { 460 if (!value.equals("true") && !value.equals("false")) { 461 sender.sendMessage(ChatColor.RED + "Valid values for option " + option + " are: true and false"); 462 return false; 463 } 464 if (option.equals("friendlyfire")) { 465 team.setAllowFriendlyFire(value.equals("true")); 466 } else { 467 team.setCanSeeFriendlyInvisibles(value.equals("true")); 468 } 469 } 470 sender.sendMessage("Set option " + option + " for team " + team.getName() + " to " + value); 471 } 472 } 473 } else { 474 sender.sendMessage(ChatColor.RED + "Usage: /scoreboard <objectives|players|teams>"); 475 return false; 476 } 477 return true; 478 } 479 480 @Override 481 public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { 482 Validate.notNull(sender, "Sender cannot be null"); 483 Validate.notNull(args, "Arguments cannot be null"); 484 Validate.notNull(alias, "Alias cannot be null"); 485 486 if (args.length == 1) { 487 return StringUtil.copyPartialMatches(args[0], MAIN_CHOICES, new ArrayList<String>()); 488 } 489 if (args.length > 1) { 490 if (args[0].equalsIgnoreCase("objectives")) { 491 if (args.length == 2) { 492 return StringUtil.copyPartialMatches(args[1], OBJECTIVES_CHOICES, new ArrayList<String>()); 493 } 494 if (args[1].equalsIgnoreCase("add")) { 495 if (args.length == 4) { 496 return StringUtil.copyPartialMatches(args[3], OBJECTIVES_CRITERIA, new ArrayList<String>()); 497 } 498 } else if (args[1].equalsIgnoreCase("remove")) { 499 if (args.length == 3) { 500 return StringUtil.copyPartialMatches(args[2], this.getCurrentObjectives(), new ArrayList<String>()); 501 } 502 } else if (args[1].equalsIgnoreCase("setdisplay")) { 503 if (args.length == 3) { 504 return StringUtil.copyPartialMatches(args[2], OBJECTIVES_DISPLAYSLOT.keySet(), new ArrayList<String>()); 505 } 506 if (args.length == 4) { 507 return StringUtil.copyPartialMatches(args[3], this.getCurrentObjectives(), new ArrayList<String>()); 508 } 509 } 510 } else if (args[0].equalsIgnoreCase("players")) { 511 if (args.length == 2) { 512 return StringUtil.copyPartialMatches(args[1], PLAYERS_CHOICES, new ArrayList<String>()); 513 } 514 if (args[1].equalsIgnoreCase("set") || args[1].equalsIgnoreCase("add") || args[1].equalsIgnoreCase("remove")) { 515 if (args.length == 3) { 516 return super.tabComplete(sender, alias, args); 517 } 518 if (args.length == 4) { 519 return StringUtil.copyPartialMatches(args[3], this.getCurrentObjectives(), new ArrayList<String>()); 520 } 521 } else { 522 if (args.length == 3) { 523 return StringUtil.copyPartialMatches(args[2], this.getCurrentEntries(), new ArrayList<String>()); 524 } 525 } 526 } else if (args[0].equalsIgnoreCase("teams")) { 527 if (args.length == 2) { 528 return StringUtil.copyPartialMatches(args[1], TEAMS_CHOICES, new ArrayList<String>()); 529 } 530 if (args[1].equalsIgnoreCase("join")) { 531 if (args.length == 3) { 532 return StringUtil.copyPartialMatches(args[2], this.getCurrentTeams(), new ArrayList<String>()); 533 } 534 if (args.length >= 4) { 535 return super.tabComplete(sender, alias, args); 536 } 537 } else if (args[1].equalsIgnoreCase("leave")) { 538 return super.tabComplete(sender, alias, args); 539 } else if (args[1].equalsIgnoreCase("option")) { 540 if (args.length == 3) { 541 return StringUtil.copyPartialMatches(args[2], this.getCurrentTeams(), new ArrayList<String>()); 542 } 543 if (args.length == 4) { 544 return StringUtil.copyPartialMatches(args[3], TEAMS_OPTION_CHOICES, new ArrayList<String>()); 545 } 546 if (args.length == 5) { 547 if (args[3].equalsIgnoreCase("color")) { 548 return StringUtil.copyPartialMatches(args[4], TEAMS_OPTION_COLOR.keySet(), new ArrayList<String>()); 549 } else { 550 return StringUtil.copyPartialMatches(args[4], BOOLEAN, new ArrayList<String>()); 551 } 552 } 553 } else { 554 if (args.length == 3) { 555 return StringUtil.copyPartialMatches(args[2], this.getCurrentTeams(), new ArrayList<String>()); 556 } 557 } 558 } 559 } 560 561 return ImmutableList.of(); 562 } 563 564 private static String offlinePlayerSetToString(Set<OfflinePlayer> set) { 565 StringBuilder string = new StringBuilder(); 566 String lastValue = null; 567 for (OfflinePlayer value : set) { 568 string.append(lastValue = value.getName()).append(", "); 569 } 570 string.delete(string.length() - 2, Integer.MAX_VALUE); 571 if (string.length() != lastValue.length()) { 572 string.insert(string.length() - lastValue.length(), "and "); 573 } 574 return string.toString(); 575 576 } 577 578 private static String stringCollectionToString(Collection<String> set) { 579 StringBuilder string = new StringBuilder(); 580 String lastValue = null; 581 for (String value : set) { 582 string.append(lastValue = value).append(", "); 583 } 584 string.delete(string.length() - 2, Integer.MAX_VALUE); 585 if (string.length() != lastValue.length()) { 586 string.insert(string.length() - lastValue.length(), "and "); 587 } 588 return string.toString(); 589 } 590 591 private List<String> getCurrentObjectives() { 592 List<String> list = new ArrayList<String>(); 593 for (Objective objective : Bukkit.getScoreboardManager().getMainScoreboard().getObjectives()) { 594 list.add(objective.getName()); 595 } 596 Collections.sort(list, String.CASE_INSENSITIVE_ORDER); 597 return list; 598 } 599 600 private List<String> getCurrentEntries() { 601 List<String> list = new ArrayList<String>(); 602 for (String entry : Bukkit.getScoreboardManager().getMainScoreboard().getEntries()) { 603 list.add(entry); 604 } 605 Collections.sort(list, String.CASE_INSENSITIVE_ORDER); 606 return list; 607 } 608 609 private List<String> getCurrentTeams() { 610 List<String> list = new ArrayList<String>(); 611 for (Team team : Bukkit.getScoreboardManager().getMainScoreboard().getTeams()) { 612 list.add(team.getName()); 613 } 614 Collections.sort(list, String.CASE_INSENSITIVE_ORDER); 615 return list; 616 } 617 }