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 }