Prechádzať zdrojové kódy

Make our commands support tab-complete.

GJ 12 rokov pred
rodič
commit
b391a53c6b
28 zmenil súbory, kde vykonal 596 pridanie a 238 odobranie
  1. 15 60
      src/main/java/com/gmail/nossr50/commands/McabilityCommand.java
  2. 15 60
      src/main/java/com/gmail/nossr50/commands/McgodCommand.java
  3. 12 9
      src/main/java/com/gmail/nossr50/commands/McnotifyCommand.java
  4. 14 54
      src/main/java/com/gmail/nossr50/commands/McrefreshCommand.java
  5. 31 2
      src/main/java/com/gmail/nossr50/commands/MobhealthCommand.java
  6. 84 0
      src/main/java/com/gmail/nossr50/commands/ToggleCommand.java
  7. 25 2
      src/main/java/com/gmail/nossr50/commands/XprateCommand.java
  8. 18 2
      src/main/java/com/gmail/nossr50/commands/chat/ChatCommand.java
  9. 11 2
      src/main/java/com/gmail/nossr50/commands/database/McpurgeCommand.java
  10. 27 8
      src/main/java/com/gmail/nossr50/commands/database/McremoveCommand.java
  11. 15 12
      src/main/java/com/gmail/nossr50/commands/database/MmoupdateCommand.java
  12. 0 1
      src/main/java/com/gmail/nossr50/commands/experience/AddlevelsCommand.java
  13. 21 2
      src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java
  14. 22 2
      src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreModeCommand.java
  15. 81 1
      src/main/java/com/gmail/nossr50/commands/party/PartyCommand.java
  16. 1 1
      src/main/java/com/gmail/nossr50/commands/party/PartyExpShareCommand.java
  17. 15 8
      src/main/java/com/gmail/nossr50/commands/party/PartyInfoCommand.java
  18. 27 1
      src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java
  19. 20 2
      src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java
  20. 20 2
      src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java
  21. 11 2
      src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java
  22. 18 2
      src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java
  23. 15 1
      src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java
  24. 29 0
      src/main/java/com/gmail/nossr50/commands/spout/MchudCommand.java
  25. 2 2
      src/main/java/com/gmail/nossr50/commands/spout/SpoutCommand.java
  26. 21 0
      src/main/java/com/gmail/nossr50/commands/spout/XplockCommand.java
  27. 19 0
      src/main/java/com/gmail/nossr50/datatypes/skills/SkillType.java
  28. 7 0
      src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java

+ 15 - 60
src/main/java/com/gmail/nossr50/commands/McabilityCommand.java

@@ -1,74 +1,29 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.commands.CommandUtils;
-import com.gmail.nossr50.util.player.UserManager;
-
-public class McabilityCommand implements CommandExecutor {
-    private McMMOPlayer mcMMOPlayer;
-    private Player player;
 
 
+public class McabilityCommand extends ToggleCommand {
     @Override
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        switch (args.length) {
-            case 0:
-                if (CommandUtils.noConsoleUsage(sender)) {
-                    return true;
-                }
-
-                if (!Permissions.mcability(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer(sender.getName());
-                player = mcMMOPlayer.getPlayer();
-
-                toggleAbilityUse();
-                return true;
-
-            case 1:
-                if (!Permissions.mcabilityOthers(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer(args[0]);
-
-                if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
-                    return true;
-                }
-
-                player = mcMMOPlayer.getPlayer();
-
-                if (CommandUtils.isOffline(sender, player)) {
-                    return true;
-                }
-
-                toggleAbilityUse();
-                sender.sendMessage("Ability use has been toggled for " + player.getName()); // TODO: Localize
-                return true;
-
-            default:
-                return false;
-        }
+    protected boolean hasOtherPermission(CommandSender sender) {
+        return Permissions.mcabilityOthers(sender);
     }
     }
 
 
-    private void toggleAbilityUse() {
-        if (mcMMOPlayer.getAbilityUse()) {
-            player.sendMessage(LocaleLoader.getString("Commands.Ability.Off"));
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Commands.Ability.On"));
-        }
+    @Override
+    protected boolean hasSelfPermission(CommandSender sender) {
+        return Permissions.mcability(sender);
+    }
 
 
+    @Override
+    protected void applyCommandAction() {
+        player.sendMessage(LocaleLoader.getString("Commands.Ability." + (mcMMOPlayer.getAbilityUse() ? "Off" : "On")));
         mcMMOPlayer.toggleAbilityUse();
         mcMMOPlayer.toggleAbilityUse();
     }
     }
+
+    @Override
+    protected void sendSuccessMessage(CommandSender sender) {
+        sender.sendMessage("Ability use has been toggled for " + player.getName()); // TODO: Localize
+    }
 }
 }

+ 15 - 60
src/main/java/com/gmail/nossr50/commands/McgodCommand.java

@@ -1,74 +1,29 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.commands.CommandUtils;
-import com.gmail.nossr50.util.player.UserManager;
-
-public class McgodCommand implements CommandExecutor {
-    private McMMOPlayer mcMMOPlayer;
-    private Player player;
 
 
+public class McgodCommand extends ToggleCommand {
     @Override
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        switch (args.length) {
-            case 0:
-                if (CommandUtils.noConsoleUsage(sender)) {
-                    return true;
-                }
-
-                if (!Permissions.mcgod(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer(sender.getName());
-                player = mcMMOPlayer.getPlayer();
-
-                toggleGodMode();
-                return true;
-
-            case 1:
-                if (!Permissions.mcgodOthers(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer(args[0]);
-
-                if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
-                    return true;
-                }
-
-                player = mcMMOPlayer.getPlayer();
-
-                if (CommandUtils.isOffline(sender, player)) {
-                    return true;
-                }
-
-                toggleGodMode();
-                sender.sendMessage("God mode has been toggled for " + player.getName()); // TODO: Localize
-                return true;
-
-            default:
-                return false;
-        }
+    protected boolean hasOtherPermission(CommandSender sender) {
+        return Permissions.mcgodOthers(sender);
     }
     }
 
 
-    private void toggleGodMode() {
-        if (mcMMOPlayer.getGodMode()) {
-            player.sendMessage(LocaleLoader.getString("Commands.GodMode.Disabled"));
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Commands.GodMode.Enabled"));
-        }
+    @Override
+    protected boolean hasSelfPermission(CommandSender sender) {
+        return Permissions.mcgod(sender);
+    }
 
 
+    @Override
+    protected void applyCommandAction() {
+        player.sendMessage(LocaleLoader.getString("Commands.GodMode." + (mcMMOPlayer.getGodMode() ? "Disabled" : "Enabled")));
         mcMMOPlayer.toggleGodMode();
         mcMMOPlayer.toggleGodMode();
     }
     }
+
+    @Override
+    protected void sendSuccessMessage(CommandSender sender) {
+        sender.sendMessage("God mode has been toggled for " + player.getName()); // TODO: Localize
+    }
 }
 }

+ 12 - 9
src/main/java/com/gmail/nossr50/commands/McnotifyCommand.java

@@ -1,27 +1,25 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 
-public class McnotifyCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class McnotifyCommand implements TabExecutor {
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
         switch (args.length) {
             case 0:
             case 0:
                 McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
                 McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
 
 
-                if (mcMMOPlayer.useChatNotifications()) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Notifications.Off"));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Notifications.On"));
-                }
-
+                sender.sendMessage(LocaleLoader.getString("Commands.Notifications." + (mcMMOPlayer.useChatNotifications() ? "Off" : "On")));
                 mcMMOPlayer.toggleChatNotifications();
                 mcMMOPlayer.toggleChatNotifications();
                 return true;
                 return true;
 
 
@@ -29,4 +27,9 @@ public class McnotifyCommand implements CommandExecutor {
                 return false;
                 return false;
         }
         }
     }
     }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        return ImmutableList.of();
+    }
 }
 }

+ 14 - 54
src/main/java/com/gmail/nossr50/commands/McrefreshCommand.java

@@ -1,74 +1,34 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.commands.CommandUtils;
-import com.gmail.nossr50.util.player.UserManager;
-
-public class McrefreshCommand implements CommandExecutor {
-    private McMMOPlayer mcMMOPlayer;
-    private Player player;
 
 
+public class McrefreshCommand extends ToggleCommand {
     @Override
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        switch (args.length) {
-            case 0:
-                if (CommandUtils.noConsoleUsage(sender)) {
-                    return true;
-                }
-
-                if (!Permissions.mcrefresh(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer(sender.getName());
-                player = mcMMOPlayer.getPlayer();
-
-                refreshPlayer();
-                return true;
-
-            case 1:
-                if (!Permissions.mcrefreshOthers(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer(args[0]);
-
-                if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
-                    return true;
-                }
-
-                Player player = mcMMOPlayer.getPlayer();
-
-                if (CommandUtils.isOffline(sender, player)) {
-                    return true;
-                }
-
-                refreshPlayer();
-                sender.sendMessage(LocaleLoader.getString("Commands.mcrefresh.Success", player.getName()));
-                return true;
+    protected boolean hasOtherPermission(CommandSender sender) {
+        return Permissions.mcrefreshOthers(sender);
+    }
 
 
-            default:
-                return false;
-        }
+    @Override
+    protected boolean hasSelfPermission(CommandSender sender) {
+        return Permissions.mcrefresh(sender);
     }
     }
 
 
-    private void refreshPlayer() {
+    @Override
+    protected void applyCommandAction() {
         mcMMOPlayer.setRecentlyHurt(0);
         mcMMOPlayer.setRecentlyHurt(0);
         mcMMOPlayer.getProfile().resetCooldowns();
         mcMMOPlayer.getProfile().resetCooldowns();
         mcMMOPlayer.resetToolPrepMode();
         mcMMOPlayer.resetToolPrepMode();
         mcMMOPlayer.resetAbilityMode();
         mcMMOPlayer.resetAbilityMode();
 
 
         player.setCanPickupItems(true);
         player.setCanPickupItems(true);
-        player = mcMMOPlayer.getPlayer();
         player.sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
         player.sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
     }
     }
+
+    @Override
+    protected void sendSuccessMessage(CommandSender sender) {
+        sender.sendMessage(LocaleLoader.getString("Commands.mcrefresh.Success", player.getName()));
+    }
 }
 }

+ 31 - 2
src/main/java/com/gmail/nossr50/commands/MobhealthCommand.java

@@ -1,15 +1,34 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 
-public class MobhealthCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class MobhealthCommand implements TabExecutor {
+    private static final List<String> MOB_HEALTHBAR_TYPES;
+
+    static {
+        ArrayList<String> types = new ArrayList<String>();
+
+        for (MobHealthbarType type : MobHealthbarType.values()) {
+            types.add(type.toString());
+        }
+
+        Collections.sort(types);
+        MOB_HEALTHBAR_TYPES = ImmutableList.copyOf(types);
+    }
 
 
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
@@ -36,4 +55,14 @@ public class MobhealthCommand implements CommandExecutor {
                 return false;
                 return false;
         }
         }
     }
     }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                return StringUtil.copyPartialMatches(args[0], MOB_HEALTHBAR_TYPES, new ArrayList<String>(MOB_HEALTHBAR_TYPES.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
 }
 }

+ 84 - 0
src/main/java/com/gmail/nossr50/commands/ToggleCommand.java

@@ -0,0 +1,84 @@
+package com.gmail.nossr50.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.entity.Player;
+import org.bukkit.util.StringUtil;
+
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.util.commands.CommandUtils;
+import com.gmail.nossr50.util.player.UserManager;
+
+import com.google.common.collect.ImmutableList;
+
+public abstract class ToggleCommand implements TabExecutor {
+    protected McMMOPlayer mcMMOPlayer;
+    protected Player player;
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        switch (args.length) {
+            case 0:
+                if (CommandUtils.noConsoleUsage(sender)) {
+                    return true;
+                }
+
+                if (!hasSelfPermission(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
+                mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                player = mcMMOPlayer.getPlayer();
+
+                applyCommandAction();
+                return true;
+
+            case 1:
+                if (!hasOtherPermission(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
+                mcMMOPlayer = UserManager.getPlayer(args[0]);
+
+                if (!CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
+                    return true;
+                }
+
+                player = mcMMOPlayer.getPlayer();
+
+                if (CommandUtils.isOffline(sender, player)) {
+                    return true;
+                }
+
+                applyCommandAction();
+                sendSuccessMessage(sender);
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                Set<String> playerNames = UserManager.getPlayers().keySet();
+                return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
+
+    protected abstract boolean hasOtherPermission(CommandSender sender);
+    protected abstract boolean hasSelfPermission(CommandSender sender);
+    protected abstract void applyCommandAction();
+    protected abstract void sendSuccessMessage(CommandSender sender);
+}

+ 25 - 2
src/main/java/com/gmail/nossr50/commands/XprateCommand.java

@@ -1,16 +1,23 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 
 
-public class XprateCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class XprateCommand implements TabExecutor {
     private double originalRate;
     private double originalRate;
 
 
     public XprateCommand() {
     public XprateCommand() {
@@ -75,4 +82,20 @@ public class XprateCommand implements CommandExecutor {
                 return false;
                 return false;
         }
         }
     }
     }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                if (StringUtils.isInt(args[0])) {
+                    return ImmutableList.of();
+                }
+
+                return StringUtil.copyPartialMatches(args[0], CommandUtils.RESET_OPTIONS, new ArrayList<String>(CommandUtils.RESET_OPTIONS.size()));
+            case 2:
+                return StringUtil.copyPartialMatches(args[1], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
 }
 }

+ 18 - 2
src/main/java/com/gmail/nossr50/commands/chat/ChatCommand.java

@@ -1,8 +1,12 @@
 package com.gmail.nossr50.commands.chat;
 package com.gmail.nossr50.commands.chat;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.chat.ChatMode;
 import com.gmail.nossr50.chat.ChatMode;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -10,7 +14,9 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 
-public abstract class ChatCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public abstract class ChatCommand implements TabExecutor {
     protected ChatMode chatMode;
     protected ChatMode chatMode;
     private McMMOPlayer mcMMOPlayer;
     private McMMOPlayer mcMMOPlayer;
 
 
@@ -68,6 +74,16 @@ public abstract class ChatCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                return StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     protected String buildChatMessage(String[] args, int index) {
     protected String buildChatMessage(String[] args, int index) {
         StringBuilder builder = new StringBuilder();
         StringBuilder builder = new StringBuilder();
         builder.append(args[index]);
         builder.append(args[index]);

+ 11 - 2
src/main/java/com/gmail/nossr50/commands/database/McpurgeCommand.java

@@ -1,8 +1,10 @@
 package com.gmail.nossr50.commands.database;
 package com.gmail.nossr50.commands.database;
 
 
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 
 
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.DatabaseManager;
@@ -10,7 +12,9 @@ import com.gmail.nossr50.database.LeaderboardManager;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 
 
-public class McpurgeCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class McpurgeCommand implements TabExecutor {
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         if (!Permissions.mcpurge(sender)) {
         if (!Permissions.mcpurge(sender)) {
@@ -42,4 +46,9 @@ public class McpurgeCommand implements CommandExecutor {
                 return false;
                 return false;
         }
         }
     }
     }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        return ImmutableList.of();
+    }
 }
 }

+ 27 - 8
src/main/java/com/gmail/nossr50/commands/database/McremoveCommand.java

@@ -1,17 +1,27 @@
 package com.gmail.nossr50.commands.database;
 package com.gmail.nossr50.commands.database;
 
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.LeaderboardManager;
 import com.gmail.nossr50.database.LeaderboardManager;
+import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.commands.CommandUtils;
+import com.gmail.nossr50.util.player.UserManager;
+
+import com.google.common.collect.ImmutableList;
 
 
-public class McremoveCommand implements CommandExecutor {
+public class McremoveCommand implements TabExecutor {
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         if (!Permissions.mcremove(sender)) {
         if (!Permissions.mcremove(sender)) {
@@ -21,6 +31,10 @@ public class McremoveCommand implements CommandExecutor {
 
 
         switch (args.length) {
         switch (args.length) {
             case 1:
             case 1:
+                if (UserManager.getPlayer(args[0]) == null && CommandUtils.unloadedProfile(sender, new PlayerProfile(args[0], false))) {
+                    return true;
+                }
+
                 /* MySQL */
                 /* MySQL */
                 if (Config.getInstance().getUseMySQL()) {
                 if (Config.getInstance().getUseMySQL()) {
                     String tablePrefix = Config.getInstance().getMySQLTablePrefix();
                     String tablePrefix = Config.getInstance().getMySQLTablePrefix();
@@ -29,18 +43,12 @@ public class McremoveCommand implements CommandExecutor {
                         Misc.profileCleanup(args[0]);
                         Misc.profileCleanup(args[0]);
                         sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
                         sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
                     }
                     }
-                    else {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                    }
                 }
                 }
                 else {
                 else {
                     if (LeaderboardManager.removeFlatFileUser(args[0])) {
                     if (LeaderboardManager.removeFlatFileUser(args[0])) {
                         Misc.profileCleanup(args[0]);
                         Misc.profileCleanup(args[0]);
                         sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
                         sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
                     }
                     }
-                    else {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                    }
                 }
                 }
 
 
                 return true;
                 return true;
@@ -49,4 +57,15 @@ public class McremoveCommand implements CommandExecutor {
                 return false;
                 return false;
         }
         }
     }
     }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                Set<String> playerNames = UserManager.getPlayers().keySet();
+                return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
 }
 }

+ 15 - 12
src/main/java/com/gmail/nossr50/commands/database/MmoupdateCommand.java

@@ -1,8 +1,10 @@
 package com.gmail.nossr50.commands.database;
 package com.gmail.nossr50.commands.database;
 
 
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -12,7 +14,9 @@ import com.gmail.nossr50.runnables.database.SQLConversionTask;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 
-public class MmoupdateCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class MmoupdateCommand implements TabExecutor {
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         if (!Permissions.mmoupdate(sender)) {
         if (!Permissions.mmoupdate(sender)) {
@@ -20,12 +24,17 @@ public class MmoupdateCommand implements CommandExecutor {
             return true;
             return true;
         }
         }
 
 
+        if (!Config.getInstance().getUseMySQL()) {
+            sender.sendMessage("SQL Mode is not enabled."); // TODO: Localize
+            return true;
+        }
+
         switch (args.length) {
         switch (args.length) {
             case 0:
             case 0:
                 sender.sendMessage(LocaleLoader.getString("Commands.mmoupdate.Start"));
                 sender.sendMessage(LocaleLoader.getString("Commands.mmoupdate.Start"));
                 UserManager.saveAll();
                 UserManager.saveAll();
                 UserManager.clearAll();
                 UserManager.clearAll();
-                convertToMySQL();
+                new SQLConversionTask().runTaskLaterAsynchronously(mcMMO.p, 1);
 
 
                 for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
                 for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
                     UserManager.addUser(player);
                     UserManager.addUser(player);
@@ -39,14 +48,8 @@ public class MmoupdateCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
-    /**
-     * Convert FlatFile data to MySQL data.
-     */
-    private void convertToMySQL() {
-        if (!Config.getInstance().getUseMySQL()) {
-            return;
-        }
-
-        new SQLConversionTask().runTaskLaterAsynchronously(mcMMO.p, 1);
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        return ImmutableList.of();
     }
     }
 }
 }

+ 0 - 1
src/main/java/com/gmail/nossr50/commands/experience/AddlevelsCommand.java

@@ -31,6 +31,5 @@ public class AddlevelsCommand extends ExperienceCommand {
     @Override
     @Override
     protected void handlePlayerMessageSkill() {
     protected void handlePlayerMessageSkill() {
         player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, SkillUtils.getSkillName(skill)));
         player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, SkillUtils.getSkillName(skill)));
-        
     }
     }
 }
 }

+ 21 - 2
src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java

@@ -1,9 +1,14 @@
 package com.gmail.nossr50.commands.experience;
 package com.gmail.nossr50.commands.experience;
 
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
@@ -13,8 +18,9 @@ import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
 
+import com.google.common.collect.ImmutableList;
 
 
-public abstract class ExperienceCommand implements CommandExecutor {
+public abstract class ExperienceCommand implements TabExecutor {
     protected McMMOPlayer mcMMOPlayer;
     protected McMMOPlayer mcMMOPlayer;
     protected Player player;
     protected Player player;
     protected PlayerProfile profile;
     protected PlayerProfile profile;
@@ -84,6 +90,19 @@ public abstract class ExperienceCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                Set<String> playerNames = UserManager.getPlayers().keySet();
+                return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
+            case 2:
+                return StringUtil.copyPartialMatches(args[1], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     protected abstract boolean permissionsCheckSelf(CommandSender sender);
     protected abstract boolean permissionsCheckSelf(CommandSender sender);
     protected abstract boolean permissionsCheckOthers(CommandSender sender);
     protected abstract boolean permissionsCheckOthers(CommandSender sender);
     protected abstract void handleCommand(SkillType skill);
     protected abstract void handleCommand(SkillType skill);

+ 22 - 2
src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreModeCommand.java

@@ -1,15 +1,21 @@
 package com.gmail.nossr50.commands.hardcore;
 package com.gmail.nossr50.commands.hardcore;
 
 
 import java.text.DecimalFormat;
 import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
 
 
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 
 
-public abstract class HardcoreModeCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public abstract class HardcoreModeCommand implements TabExecutor {
     protected CommandSender sender;
     protected CommandSender sender;
     protected double newPercent;
     protected double newPercent;
     protected DecimalFormat percent;
     protected DecimalFormat percent;
@@ -76,6 +82,20 @@ public abstract class HardcoreModeCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                if (StringUtils.isDouble(args[0])) {
+                    return ImmutableList.of();
+                }
+
+                return StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     protected abstract boolean checkTogglePermissions();
     protected abstract boolean checkTogglePermissions();
     protected abstract boolean checkModifyPermissions();
     protected abstract boolean checkModifyPermissions();
     protected abstract boolean checkEnabled();
     protected abstract boolean checkEnabled();

+ 81 - 1
src/main/java/com/gmail/nossr50/commands/party/PartyCommand.java

@@ -1,22 +1,46 @@
 package com.gmail.nossr50.commands.party;
 package com.gmail.nossr50.commands.party;
 
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.commands.chat.PartyChatCommand;
 import com.gmail.nossr50.commands.chat.PartyChatCommand;
+import com.gmail.nossr50.commands.party.teleport.PtpCommand;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
+import com.google.common.collect.ImmutableList;
 
 
-public class PartyCommand implements CommandExecutor {
+public class PartyCommand implements TabExecutor {
     private McMMOPlayer mcMMOPlayer;
     private McMMOPlayer mcMMOPlayer;
     private Player player;
     private Player player;
 
 
+    private static final List<String> PARTY_SUBCOMMANDS;
+    private static final List<String> EXPSHARE_COMPLETIONS = ImmutableList.of("none", "equal");
+    private static final List<String> ITEMSHARE_COMPLETIONS = ImmutableList.of("none", "equal", "random", "loot", "mining", "herbalism", "woodcutting");
+
+    static {
+        ArrayList<String> subcommands = new ArrayList<String>();
+
+        for (PartySubcommandType subcommand : PartySubcommandType.values()) {
+            subcommands.add(subcommand.toString());
+        }
+
+        Collections.sort(subcommands);
+        PARTY_SUBCOMMANDS = ImmutableList.copyOf(subcommands);
+    }
+
     private CommandExecutor partyJoinCommand           = new PartyJoinCommand();
     private CommandExecutor partyJoinCommand           = new PartyJoinCommand();
     private CommandExecutor partyAcceptCommand         = new PartyAcceptCommand();
     private CommandExecutor partyAcceptCommand         = new PartyAcceptCommand();
     private CommandExecutor partyCreateCommand         = new PartyCreateCommand();
     private CommandExecutor partyCreateCommand         = new PartyCreateCommand();
@@ -135,6 +159,57 @@ public class PartyCommand implements CommandExecutor {
         return true;
         return true;
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                return StringUtil.copyPartialMatches(args[0], PARTY_SUBCOMMANDS, new ArrayList<String>(PARTY_SUBCOMMANDS.size()));
+            case 2:
+                PartySubcommandType subcommand = PartySubcommandType.getSubcommand(args[0]);
+
+                if (subcommand == null) {
+                    return ImmutableList.of();
+                }
+
+                switch (PartySubcommandType.valueOf(args[0].toUpperCase())) {
+                    case JOIN:
+                    case INVITE:
+                    case KICK:
+                    case OWNER:
+                        Set<String> playerNames = UserManager.getPlayers().keySet();
+                        return StringUtil.copyPartialMatches(args[1], playerNames, new ArrayList<String>(playerNames.size()));
+                    case EXPSHARE:
+                        return StringUtil.copyPartialMatches(args[1], EXPSHARE_COMPLETIONS, new ArrayList<String>(EXPSHARE_COMPLETIONS.size()));
+                    case ITEMSHARE:
+                        return StringUtil.copyPartialMatches(args[1], ITEMSHARE_COMPLETIONS, new ArrayList<String>(ITEMSHARE_COMPLETIONS.size()));
+                    case LOCK:
+                    case CHAT:
+                        return StringUtil.copyPartialMatches(args[1], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
+                    case PASSWORD:
+                        return StringUtil.copyPartialMatches(args[1], CommandUtils.RESET_OPTIONS, new ArrayList<String>(CommandUtils.RESET_OPTIONS.size()));
+                    case TELEPORT:
+                        List<String> matches = StringUtil.copyPartialMatches(args[1], PtpCommand.TELEPORT_SUBCOMMANDS, new ArrayList<String>(PtpCommand.TELEPORT_SUBCOMMANDS.size()));
+
+                        if (matches.size() == 0) {
+                            playerNames = UserManager.getPlayers().keySet();
+                            return StringUtil.copyPartialMatches(args[1], playerNames, new ArrayList<String>(playerNames.size()));
+                        }
+
+                        return matches;
+                    default:
+                        return ImmutableList.of();
+                }
+            case 3:
+                if (PartySubcommandType.getSubcommand(args[0]) == PartySubcommandType.ITEMSHARE && isItemShareCategory(args[1])) {
+                    return StringUtil.copyPartialMatches(args[2], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
+                }
+
+                return ImmutableList.of();
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     private boolean printUsage() {
     private boolean printUsage() {
         player.sendMessage(LocaleLoader.getString("Party.Help.0", "/party join"));
         player.sendMessage(LocaleLoader.getString("Party.Help.0", "/party join"));
         player.sendMessage(LocaleLoader.getString("Party.Help.1", "/party create"));
         player.sendMessage(LocaleLoader.getString("Party.Help.1", "/party create"));
@@ -151,4 +226,9 @@ public class PartyCommand implements CommandExecutor {
 
 
         return newArgs;
         return newArgs;
     }
     }
+
+    private boolean isItemShareCategory(String category) {
+        return category.equalsIgnoreCase("loot") || category.equalsIgnoreCase("mining") || category.equalsIgnoreCase("herbalism") || category.equalsIgnoreCase("woodcutting");
+    }
 }
 }
+

+ 1 - 1
src/main/java/com/gmail/nossr50/commands/party/PartyExpShareCommand.java

@@ -35,7 +35,7 @@ public class PartyExpShareCommand implements CommandExecutor {
                     handleChangingShareMode(ShareMode.EQUAL);
                     handleChangingShareMode(ShareMode.EQUAL);
                 }
                 }
                 else {
                 else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "expshare", "[NONE | EQUAL]"));
+                    sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "expshare", "<NONE | EQUAL>"));
                 }
                 }
 
 
                 return true;
                 return true;

+ 15 - 8
src/main/java/com/gmail/nossr50/commands/party/PartyInfoCommand.java

@@ -21,14 +21,21 @@ public class PartyInfoCommand implements CommandExecutor {
 
 
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
-        player = mcMMOPlayer.getPlayer();
-        playerParty = mcMMOPlayer.getParty();
-
-        displayPartyHeader();
-        displayShareModeInfo();
-        displayMemberInfo();
-        return true;
+        switch (args.length) {
+            case 0:
+            case 1:
+                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                player = mcMMOPlayer.getPlayer();
+                playerParty = mcMMOPlayer.getParty();
+
+                displayPartyHeader();
+                displayShareModeInfo();
+                displayMemberInfo();
+                return true;
+            default:
+                sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "info"));
+                return true;
+        }
     }
     }
 
 
     private String createMembersList() {
     private String createMembersList() {

+ 27 - 1
src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java

@@ -1,9 +1,15 @@
 package com.gmail.nossr50.commands.party.teleport;
 package com.gmail.nossr50.commands.party.teleport;
 
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.Config;
@@ -15,11 +21,14 @@ import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
+import com.google.common.collect.ImmutableList;
 
 
-public class PtpCommand implements CommandExecutor {
+public class PtpCommand implements TabExecutor {
     private static Player target;
     private static Player target;
     private static McMMOPlayer mcMMOTarget;
     private static McMMOPlayer mcMMOTarget;
 
 
+    public static final List<String> TELEPORT_SUBCOMMANDS = ImmutableList.of("toggle", "accept", "acceptany", "acceptall");
+
     private CommandExecutor ptpToggleCommand = new PtpToggleCommand();
     private CommandExecutor ptpToggleCommand = new PtpToggleCommand();
     private CommandExecutor ptpAcceptAnyCommand = new PtpAcceptAnyCommand();
     private CommandExecutor ptpAcceptAnyCommand = new PtpAcceptAnyCommand();
     private CommandExecutor ptpAcceptCommand = new PtpAcceptCommand();
     private CommandExecutor ptpAcceptCommand = new PtpAcceptCommand();
@@ -68,6 +77,23 @@ public class PtpCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                List<String> matches = StringUtil.copyPartialMatches(args[0], TELEPORT_SUBCOMMANDS, new ArrayList<String>(TELEPORT_SUBCOMMANDS.size()));
+
+                if (matches.size() == 0) {
+                    Set<String> playerNames = UserManager.getPlayers().keySet();
+                    return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
+                }
+
+                return matches;
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     private void sendTeleportRequest(CommandSender sender, Player player, String targetName) {
     private void sendTeleportRequest(CommandSender sender, Player player, String targetName) {
         if (!canTeleport(sender, player, targetName)) {
         if (!canTeleport(sender, player, targetName)) {
             return;
             return;

+ 20 - 2
src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java

@@ -1,9 +1,14 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
@@ -13,7 +18,9 @@ import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 
-public class InspectCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class InspectCommand implements TabExecutor {
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
         switch (args.length) {
@@ -68,4 +75,15 @@ public class InspectCommand implements CommandExecutor {
                 return false;
                 return false;
         }
         }
     }
     }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                Set<String> playerNames = UserManager.getPlayers().keySet();
+                return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
 }
 }

+ 20 - 2
src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java

@@ -1,8 +1,13 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.Config;
@@ -17,7 +22,9 @@ import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
 
-public class McrankCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class McrankCommand implements TabExecutor {
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
         switch (args.length) {
@@ -74,6 +81,17 @@ public class McrankCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                Set<String> playerNames = UserManager.getPlayers().keySet();
+                return StringUtil.copyPartialMatches(args[0], playerNames, new ArrayList<String>(playerNames.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     private void flatfileDisplay(CommandSender sender, String playerName) {
     private void flatfileDisplay(CommandSender sender, String playerName) {
         LeaderboardManager.updateLeaderboards(); // Make sure the information is up to date
         LeaderboardManager.updateLeaderboards(); // Make sure the information is up to date
 
 

+ 11 - 2
src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java

@@ -1,8 +1,10 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.Config;
@@ -11,7 +13,9 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 
-public class McstatsCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class McstatsCommand implements TabExecutor {
     @Override
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         if (CommandUtils.noConsoleUsage(sender)) {
         if (CommandUtils.noConsoleUsage(sender)) {
@@ -45,4 +49,9 @@ public class McstatsCommand implements CommandExecutor {
                 return false;
                 return false;
         }
         }
     }
     }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        return ImmutableList.of();
+    }
 }
 }

+ 18 - 2
src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java

@@ -1,9 +1,13 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.bukkit.ChatColor;
 import org.bukkit.ChatColor;
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.Config;
@@ -15,7 +19,9 @@ import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 
 
-public class MctopCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public class MctopCommand implements TabExecutor {
     private SkillType skill;
     private SkillType skill;
 
 
     @Override
     @Override
@@ -58,6 +64,16 @@ public class MctopCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                return StringUtil.copyPartialMatches(args[1], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     private void display(int page, String skill, CommandSender sender, boolean sql, Command command) {
     private void display(int page, String skill, CommandSender sender, boolean sql, Command command) {
         if (!skill.equalsIgnoreCase("all") && !Permissions.mctop(sender, this.skill)) {
         if (!skill.equalsIgnoreCase("all") && !Permissions.mctop(sender, this.skill)) {
             sender.sendMessage(command.getPermissionMessage());
             sender.sendMessage(command.getPermissionMessage());

+ 15 - 1
src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java

@@ -1,11 +1,13 @@
 package com.gmail.nossr50.commands.skills;
 package com.gmail.nossr50.commands.skills;
 
 
 import java.text.DecimalFormat;
 import java.text.DecimalFormat;
+import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 
 import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.AdvancedConfig;
@@ -21,7 +23,9 @@ import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.PerksUtils;
 import com.gmail.nossr50.util.skills.PerksUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
 
-public abstract class SkillCommand implements CommandExecutor {
+import com.google.common.collect.ImmutableList;
+
+public abstract class SkillCommand implements TabExecutor {
     protected SkillType skill;
     protected SkillType skill;
     protected String skillName;
     protected String skillName;
 
 
@@ -102,6 +106,16 @@ public abstract class SkillCommand implements CommandExecutor {
         }
         }
     }
     }
 
 
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                return ImmutableList.of("?");
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     protected int calculateRank(int maxLevel, int rankChangeLevel) {
     protected int calculateRank(int maxLevel, int rankChangeLevel) {
         return Math.min((int) skillValue, maxLevel) / rankChangeLevel;
         return Math.min((int) skillValue, maxLevel) / rankChangeLevel;
     }
     }

+ 29 - 0
src/main/java/com/gmail/nossr50/commands/spout/MchudCommand.java

@@ -1,12 +1,41 @@
 package com.gmail.nossr50.commands.spout;
 package com.gmail.nossr50.commands.spout;
 
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.datatypes.spout.huds.HudType;
 import com.gmail.nossr50.datatypes.spout.huds.HudType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.google.common.collect.ImmutableList;
 
 
 public class MchudCommand extends SpoutCommand {
 public class MchudCommand extends SpoutCommand {
+    private static final List<String> HUD_TYPES;
+
+    static {
+        ArrayList<String> types = new ArrayList<String>();
+
+        for (HudType type : HudType.values()) {
+            types.add(type.toString());
+        }
+
+        Collections.sort(types);
+        HUD_TYPES = ImmutableList.copyOf(types);
+    }
+
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                return StringUtil.copyPartialMatches(args[0], HUD_TYPES, new ArrayList<String>(HUD_TYPES.size()));
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     @Override
     @Override
     protected boolean noArguments(Command command, CommandSender sender, String[] args) {
     protected boolean noArguments(Command command, CommandSender sender, String[] args) {
         return false;
         return false;

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/spout/SpoutCommand.java

@@ -1,8 +1,8 @@
 package com.gmail.nossr50.commands.spout;
 package com.gmail.nossr50.commands.spout;
 
 
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.command.TabExecutor;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.spout.SpoutConfig;
 import com.gmail.nossr50.config.spout.SpoutConfig;
@@ -12,7 +12,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 
-public abstract class SpoutCommand implements CommandExecutor {
+public abstract class SpoutCommand implements TabExecutor {
     protected PlayerProfile playerProfile;
     protected PlayerProfile playerProfile;
     protected McMMOHud spoutHud;
     protected McMMOHud spoutHud;
 
 

+ 21 - 0
src/main/java/com/gmail/nossr50/commands/spout/XplockCommand.java

@@ -1,15 +1,36 @@
 package com.gmail.nossr50.commands.spout;
 package com.gmail.nossr50.commands.spout;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
+import org.bukkit.util.StringUtil;
 
 
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
+import com.google.common.collect.ImmutableList;
 
 
 public class XplockCommand extends SpoutCommand {
 public class XplockCommand extends SpoutCommand {
+    @Override
+    public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
+        switch (args.length) {
+            case 1:
+                List<String> matches = StringUtil.copyPartialMatches(args[0], CommandUtils.TRUE_FALSE_OPTIONS, new ArrayList<String>(CommandUtils.TRUE_FALSE_OPTIONS.size()));
+
+                if (matches.size() == 0) {
+                    return StringUtil.copyPartialMatches(args[0], SkillType.SKILL_NAMES, new ArrayList<String>(SkillType.SKILL_NAMES.size()));
+                }
+
+                return matches;
+            default:
+                return ImmutableList.of();
+        }
+    }
+
     @Override
     @Override
     protected boolean noArguments(Command command, CommandSender sender, String[] args) {
     protected boolean noArguments(Command command, CommandSender sender, String[] args) {
         if (spoutHud.getXpBarLocked()) {
         if (spoutHud.getXpBarLocked()) {

+ 19 - 0
src/main/java/com/gmail/nossr50/datatypes/skills/SkillType.java

@@ -1,5 +1,9 @@
 package com.gmail.nossr50.datatypes.skills;
 package com.gmail.nossr50.datatypes.skills;
 
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 import org.bukkit.Color;
 import org.bukkit.Color;
 
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -20,6 +24,8 @@ import com.gmail.nossr50.skills.taming.TamingManager;
 import com.gmail.nossr50.skills.unarmed.UnarmedManager;
 import com.gmail.nossr50.skills.unarmed.UnarmedManager;
 import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
 import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
+import com.gmail.nossr50.util.skills.SkillUtils;
+import com.google.common.collect.ImmutableList;
 
 
 public enum SkillType {
 public enum SkillType {
     ACROBATICS(AcrobaticsManager.class, Color.WHITE),
     ACROBATICS(AcrobaticsManager.class, Color.WHITE),
@@ -41,6 +47,19 @@ public enum SkillType {
     private AbilityType ability;
     private AbilityType ability;
     private ToolType tool;
     private ToolType tool;
 
 
+    public static final List<String> SKILL_NAMES;
+
+    static {
+        ArrayList<String> names = new ArrayList<String>();
+
+        for (SkillType skill : values()) {
+            names.add(SkillUtils.getSkillName(skill));
+        }
+
+        Collections.sort(names);
+        SKILL_NAMES = ImmutableList.copyOf(names);
+    }
+
     private SkillType(Class<? extends SkillManager> managerClass, Color runescapeColor) {
     private SkillType(Class<? extends SkillManager> managerClass, Color runescapeColor) {
         this.managerClass = managerClass;
         this.managerClass = managerClass;
         this.runescapeColor = runescapeColor;
         this.runescapeColor = runescapeColor;

+ 7 - 0
src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java

@@ -1,5 +1,7 @@
 package com.gmail.nossr50.util.commands;
 package com.gmail.nossr50.util.commands;
 
 
+import java.util.List;
+
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 
@@ -13,7 +15,12 @@ import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
 
+import com.google.common.collect.ImmutableList;
+
 public final class CommandUtils {
 public final class CommandUtils {
+    public static final List<String> TRUE_FALSE_OPTIONS = ImmutableList.of("on", "off", "true", "false", "enabled", "disabled");
+    public static final List<String> RESET_OPTIONS = ImmutableList.of("clear", "reset");
+
     private CommandUtils() {}
     private CommandUtils() {}
 
 
     public static boolean isChildSkill(CommandSender sender, SkillType skill) {
     public static boolean isChildSkill(CommandSender sender, SkillType skill) {