소스 검색

Clean up on all of our commands. Abstracted experience commands and
hardcore commands. Moved lots of duplicated code to functions in
CommandUtils.java. Split /ptp into individual commands, just like /party.
Used ternary logic to simplify some of our /skillname stat displays. Fixed
skill guide to not allow for negative pages. Simplified logic for many
/skillname data calculations. Use permission checks to prevent calculating
data that will never be displayed. Made the skill guide into its own
command.

GJ 12 년 전
부모
커밋
2838a52e0c
64개의 변경된 파일1529개의 추가작업 그리고 1840개의 파일을 삭제
  1. 27 32
      src/main/java/com/gmail/nossr50/commands/McabilityCommand.java
  2. 26 40
      src/main/java/com/gmail/nossr50/commands/McgodCommand.java
  3. 22 30
      src/main/java/com/gmail/nossr50/commands/McrefreshCommand.java
  4. 15 6
      src/main/java/com/gmail/nossr50/commands/XprateCommand.java
  5. 6 7
      src/main/java/com/gmail/nossr50/commands/chat/ChatCommand.java
  6. 3 2
      src/main/java/com/gmail/nossr50/commands/database/McremoveCommand.java
  7. 20 138
      src/main/java/com/gmail/nossr50/commands/experience/AddlevelsCommand.java
  8. 24 136
      src/main/java/com/gmail/nossr50/commands/experience/AddxpCommand.java
  9. 149 0
      src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java
  10. 19 134
      src/main/java/com/gmail/nossr50/commands/experience/MmoeditCommand.java
  11. 56 110
      src/main/java/com/gmail/nossr50/commands/experience/SkillresetCommand.java
  12. 25 69
      src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreCommand.java
  13. 94 0
      src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreModeCommand.java
  14. 23 72
      src/main/java/com/gmail/nossr50/commands/hardcore/VampirismCommand.java
  15. 2 5
      src/main/java/com/gmail/nossr50/commands/party/PartyAcceptCommand.java
  16. 1 2
      src/main/java/com/gmail/nossr50/commands/party/PartyChangeOwnerCommand.java
  17. 8 7
      src/main/java/com/gmail/nossr50/commands/party/PartyChangePasswordCommand.java
  18. 2 3
      src/main/java/com/gmail/nossr50/commands/party/PartyCommand.java
  19. 4 9
      src/main/java/com/gmail/nossr50/commands/party/PartyCreateCommand.java
  20. 3 2
      src/main/java/com/gmail/nossr50/commands/party/PartyDisbandCommand.java
  21. 7 4
      src/main/java/com/gmail/nossr50/commands/party/PartyExpShareCommand.java
  22. 0 1
      src/main/java/com/gmail/nossr50/commands/party/PartyHelpCommand.java
  23. 11 7
      src/main/java/com/gmail/nossr50/commands/party/PartyInfoCommand.java
  24. 7 20
      src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java
  25. 18 13
      src/main/java/com/gmail/nossr50/commands/party/PartyItemShareCommand.java
  26. 6 12
      src/main/java/com/gmail/nossr50/commands/party/PartyJoinCommand.java
  27. 1 2
      src/main/java/com/gmail/nossr50/commands/party/PartyKickCommand.java
  28. 12 12
      src/main/java/com/gmail/nossr50/commands/party/PartyLockCommand.java
  29. 3 6
      src/main/java/com/gmail/nossr50/commands/party/PartyQuitCommand.java
  30. 11 7
      src/main/java/com/gmail/nossr50/commands/party/PartyRenameCommand.java
  31. 0 218
      src/main/java/com/gmail/nossr50/commands/party/PtpCommand.java
  32. 34 0
      src/main/java/com/gmail/nossr50/commands/party/teleport/PtpAcceptAnyCommand.java
  33. 64 0
      src/main/java/com/gmail/nossr50/commands/party/teleport/PtpAcceptCommand.java
  34. 133 0
      src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java
  35. 34 0
      src/main/java/com/gmail/nossr50/commands/party/teleport/PtpToggleCommand.java
  36. 19 35
      src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java
  37. 9 23
      src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java
  38. 7 9
      src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java
  39. 42 40
      src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java
  40. 18 27
      src/main/java/com/gmail/nossr50/commands/skills/AcrobaticsCommand.java
  41. 15 25
      src/main/java/com/gmail/nossr50/commands/skills/ArcheryCommand.java
  42. 20 29
      src/main/java/com/gmail/nossr50/commands/skills/AxesCommand.java
  43. 6 9
      src/main/java/com/gmail/nossr50/commands/skills/ExcavationCommand.java
  44. 26 29
      src/main/java/com/gmail/nossr50/commands/skills/FishingCommand.java
  45. 49 64
      src/main/java/com/gmail/nossr50/commands/skills/HerbalismCommand.java
  46. 39 39
      src/main/java/com/gmail/nossr50/commands/skills/MiningCommand.java
  47. 14 22
      src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java
  48. 55 75
      src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java
  49. 51 68
      src/main/java/com/gmail/nossr50/commands/skills/SkillGuideCommand.java
  50. 20 26
      src/main/java/com/gmail/nossr50/commands/skills/SmeltingCommand.java
  51. 20 35
      src/main/java/com/gmail/nossr50/commands/skills/SwordsCommand.java
  52. 6 9
      src/main/java/com/gmail/nossr50/commands/skills/TamingCommand.java
  53. 27 42
      src/main/java/com/gmail/nossr50/commands/skills/UnarmedCommand.java
  54. 17 25
      src/main/java/com/gmail/nossr50/commands/skills/WoodcuttingCommand.java
  55. 1 2
      src/main/java/com/gmail/nossr50/commands/spout/SpoutCommand.java
  56. 5 6
      src/main/java/com/gmail/nossr50/commands/spout/XplockCommand.java
  57. 3 30
      src/main/java/com/gmail/nossr50/database/DatabaseManager.java
  58. 4 0
      src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java
  59. 4 0
      src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java
  60. 9 0
      src/main/java/com/gmail/nossr50/party/PartyManager.java
  61. 28 0
      src/main/java/com/gmail/nossr50/util/Misc.java
  62. 2 2
      src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
  63. 141 61
      src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java
  64. 2 2
      src/main/java/com/gmail/nossr50/util/skills/PerksUtils.java

+ 27 - 32
src/main/java/com/gmail/nossr50/commands/McabilityCommand.java

@@ -6,33 +6,32 @@ import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 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;
+
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        McMMOPlayer mcMMOPlayer;
-
         switch (args.length) {
             case 0:
+                if (CommandUtils.noConsoleUsage(sender)) {
+                    return true;
+                }
+
                 if (!Permissions.mcability(sender)) {
                     sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
 
-                mcMMOPlayer = UserManager.getPlayer((Player) sender);
+                mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                player = mcMMOPlayer.getPlayer();
 
-                if (mcMMOPlayer.getAbilityUse()) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Ability.Off"));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Ability.On"));
-                }
-
-                mcMMOPlayer.toggleAbilityUse();
+                toggleAbilityUse();
                 return true;
 
             case 1:
@@ -43,37 +42,33 @@ public class McabilityCommand implements CommandExecutor {
 
                 mcMMOPlayer = UserManager.getPlayer(args[0]);
 
-                if (mcMMOPlayer == null) {
-                    PlayerProfile playerProfile = new PlayerProfile(args[0], false);
-
-                    if (!playerProfile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
-
-                    sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+                if (CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
                     return true;
                 }
 
-                Player player = mcMMOPlayer.getPlayer();
+                player = mcMMOPlayer.getPlayer();
 
-                if (!player.isOnline()) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+                if (CommandUtils.isOffline(sender, player)) {
                     return true;
                 }
 
-                if (mcMMOPlayer.getAbilityUse()) {
-                    player.sendMessage(LocaleLoader.getString("Commands.Ability.Off"));
-                }
-                else {
-                    player.sendMessage(LocaleLoader.getString("Commands.Ability.On"));
-                }
-
-                mcMMOPlayer.toggleAbilityUse();
+                toggleAbilityUse();
+                sender.sendMessage("Ability use has been toggled for" + args[0]); // TODO: Localize
                 return true;
 
             default:
                 return false;
         }
     }
+
+    private void toggleAbilityUse() {
+        if (mcMMOPlayer.getAbilityUse()) {
+            player.sendMessage(LocaleLoader.getString("Commands.Ability.Off"));
+        }
+        else {
+            player.sendMessage(LocaleLoader.getString("Commands.Ability.On"));
+        }
+
+        mcMMOPlayer.toggleAbilityUse();
+    }
 }

+ 26 - 40
src/main/java/com/gmail/nossr50/commands/McgodCommand.java

@@ -6,42 +6,32 @@ import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 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;
+
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        McMMOPlayer mcMMOPlayer;
-
         switch (args.length) {
             case 0:
-                if (!Permissions.mcgod(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
+                if (CommandUtils.noConsoleUsage(sender)) {
                     return true;
                 }
 
-                if (!(sender instanceof Player)) {
-                    return false;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer((Player) sender);
-
-                if (mcMMOPlayer == null) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                if (!Permissions.mcgod(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
 
-                if (mcMMOPlayer.getGodMode()) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.GodMode.Disabled"));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.GodMode.Enabled"));
-                }
+                mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                player = mcMMOPlayer.getPlayer();
 
-                mcMMOPlayer.toggleGodMode();
+                toggleGodMode();
                 return true;
 
             case 1:
@@ -52,37 +42,33 @@ public class McgodCommand implements CommandExecutor {
 
                 mcMMOPlayer = UserManager.getPlayer(args[0]);
 
-                if (mcMMOPlayer == null) {
-                    PlayerProfile playerProfile = new PlayerProfile(args[0], false);
-
-                    if (!playerProfile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
-
-                    sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+                if (CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
                     return true;
                 }
 
-                Player player = mcMMOPlayer.getPlayer();
+                player = mcMMOPlayer.getPlayer();
 
-                if (!player.isOnline()) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+                if (CommandUtils.isOffline(sender, player)) {
                     return true;
                 }
 
-                if (mcMMOPlayer.getGodMode()) {
-                    player.sendMessage(LocaleLoader.getString("Commands.GodMode.Disabled"));
-                }
-                else {
-                    player.sendMessage(LocaleLoader.getString("Commands.GodMode.Enabled"));
-                }
-
-                mcMMOPlayer.toggleGodMode();
+                toggleGodMode();
+                sender.sendMessage("God mode has been toggled for" + args[0]); // TODO: Localize
                 return true;
 
             default:
                 return false;
         }
     }
+
+    private void toggleGodMode() {
+        if (mcMMOPlayer.getGodMode()) {
+            player.sendMessage(LocaleLoader.getString("Commands.GodMode.Disabled"));
+        }
+        else {
+            player.sendMessage(LocaleLoader.getString("Commands.GodMode.Enabled"));
+        }
+
+        mcMMOPlayer.toggleGodMode();
+    }
 }

+ 22 - 30
src/main/java/com/gmail/nossr50/commands/McrefreshCommand.java

@@ -6,35 +6,32 @@ import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 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;
+
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        McMMOPlayer mcMMOPlayer;
-
         switch (args.length) {
             case 0:
-                if (!Permissions.mcrefresh(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
+                if (CommandUtils.noConsoleUsage(sender)) {
                     return true;
                 }
 
-                if (!(sender instanceof Player)) {
-                    return false;
+                if (!Permissions.mcrefresh(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
                 }
 
                 mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                player = mcMMOPlayer.getPlayer();
 
-                mcMMOPlayer.setRecentlyHurt(0);
-                mcMMOPlayer.getProfile().resetCooldowns();
-                mcMMOPlayer.resetToolPrepMode();
-                mcMMOPlayer.resetAbilityMode();
-
-                sender.sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
+                refreshPlayer();
                 return true;
 
             case 1:
@@ -45,31 +42,17 @@ public class McrefreshCommand implements CommandExecutor {
 
                 mcMMOPlayer = UserManager.getPlayer(args[0]);
 
-                if (mcMMOPlayer == null) {
-                    PlayerProfile playerProfile = new PlayerProfile(args[0], false);
-
-                    if (!playerProfile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
-
-                    sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+                if (CommandUtils.checkPlayerExistence(sender, args[0], mcMMOPlayer)) {
                     return true;
                 }
 
                 Player player = mcMMOPlayer.getPlayer();
 
-                if (!player.isOnline()) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+                if (CommandUtils.isOffline(sender, player)) {
                     return true;
                 }
 
-                mcMMOPlayer.setRecentlyHurt(0);
-                mcMMOPlayer.getProfile().resetCooldowns();
-                mcMMOPlayer.resetToolPrepMode();
-                mcMMOPlayer.resetAbilityMode();
-
-                player.sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
+                refreshPlayer();
                 sender.sendMessage(LocaleLoader.getString("Commands.mcrefresh.Success", args[0]));
                 return true;
 
@@ -77,4 +60,13 @@ public class McrefreshCommand implements CommandExecutor {
                 return false;
         }
     }
+
+    private void refreshPlayer() {
+        mcMMOPlayer.setRecentlyHurt(0);
+        mcMMOPlayer.getProfile().resetCooldowns();
+        mcMMOPlayer.resetToolPrepMode();
+        mcMMOPlayer.resetAbilityMode();
+
+        player.sendMessage(LocaleLoader.getString("Ability.Generic.Refresh"));
+    }
 }

+ 15 - 6
src/main/java/com/gmail/nossr50/commands/XprateCommand.java

@@ -8,10 +8,14 @@ import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.StringUtils;
+import com.gmail.nossr50.util.commands.CommandUtils;
 
 public class XprateCommand implements CommandExecutor {
-    private static double originalRate = Config.getInstance().getExperienceGainsGlobalMultiplier();
+    private double originalRate;
+
+    public XprateCommand() {
+        originalRate = Config.getInstance().getExperienceGainsGlobalMultiplier();
+    }
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
@@ -35,8 +39,8 @@ public class XprateCommand implements CommandExecutor {
                 return true;
 
             case 2:
-                if (!StringUtils.isInt(args[0])) {
-                    return false;
+                if (CommandUtils.isInvalidInteger(sender, args[0])) {
+                    return true;
                 }
 
                 if (!Permissions.xprateSet(sender)) {
@@ -44,11 +48,16 @@ public class XprateCommand implements CommandExecutor {
                     return true;
                 }
 
-                if (!args[1].equalsIgnoreCase("true") && !args[1].equalsIgnoreCase("false")) {
+                if (CommandUtils.shouldDisableToggle(args[1])) {
+                    mcMMO.p.setXPEventEnabled(false);
+                }
+                else if (CommandUtils.shouldEnableToggle(args[1])) {
+                    mcMMO.p.setXPEventEnabled(true);
+                }
+                else {
                     return false;
                 }
 
-                mcMMO.p.setXPEventEnabled(Boolean.valueOf(args[1]));
                 int newXpRate = Integer.parseInt(args[0]);
                 Config.getInstance().setExperienceGainsGlobalMultiplier(newXpRate);
 

+ 6 - 7
src/main/java/com/gmail/nossr50/commands/chat/ChatCommand.java

@@ -3,7 +3,6 @@ package com.gmail.nossr50.commands.chat;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.chat.ChatMode;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -12,8 +11,8 @@ import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 
 public abstract class ChatCommand implements CommandExecutor {
-    protected McMMOPlayer mcMMOPlayer;
     protected ChatMode chatMode;
+    private McMMOPlayer mcMMOPlayer;
 
     public ChatCommand(ChatMode chatMode) {
         this.chatMode = chatMode;
@@ -27,7 +26,7 @@ public abstract class ChatCommand implements CommandExecutor {
                     return true;
                 }
 
-                mcMMOPlayer = UserManager.getPlayer((Player) sender);
+                mcMMOPlayer = UserManager.getPlayer(sender.getName());
 
                 if (chatMode.isEnabled(mcMMOPlayer)) {
                     disableChatMode(sender);
@@ -39,23 +38,23 @@ public abstract class ChatCommand implements CommandExecutor {
                 return true;
 
             case 1:
-                if (args[0].equalsIgnoreCase("on")) {
+                if (CommandUtils.shouldEnableToggle(args[0])) {
                     if (CommandUtils.noConsoleUsage(sender)) {
                         return true;
                     }
 
-                    mcMMOPlayer = UserManager.getPlayer((Player) sender);
+                    mcMMOPlayer = UserManager.getPlayer(sender.getName());
 
                     enableChatMode(sender);
                     return true;
                 }
 
-                if (args[0].equalsIgnoreCase("off")) {
+                if (CommandUtils.shouldDisableToggle(args[0])) {
                     if (CommandUtils.noConsoleUsage(sender)) {
                         return true;
                     }
 
-                    mcMMOPlayer = UserManager.getPlayer((Player) sender);
+                    mcMMOPlayer = UserManager.getPlayer(sender.getName());
 
                     disableChatMode(sender);
                     return true;

+ 3 - 2
src/main/java/com/gmail/nossr50/commands/database/McremoveCommand.java

@@ -8,6 +8,7 @@ import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.LeaderboardManager;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
 
 public class McremoveCommand implements CommandExecutor {
@@ -25,7 +26,7 @@ public class McremoveCommand implements CommandExecutor {
                     String tablePrefix = Config.getInstance().getMySQLTablePrefix();
 
                     if (DatabaseManager.update("DELETE FROM " + tablePrefix + "users WHERE " + tablePrefix + "users.user = '" + args[0] + "'") != 0) {
-                        DatabaseManager.profileCleanup(args[0]);
+                        Misc.profileCleanup(args[0]);
                         sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
                     }
                     else {
@@ -34,7 +35,7 @@ public class McremoveCommand implements CommandExecutor {
                 }
                 else {
                     if (LeaderboardManager.removeFlatFileUser(args[0])) {
-                        DatabaseManager.profileCleanup(args[0]);
+                        Misc.profileCleanup(args[0]);
                         sender.sendMessage(LocaleLoader.getString("Commands.mcremove.Success", args[0]));
                     }
                     else {

+ 20 - 138
src/main/java/com/gmail/nossr50/commands/experience/AddlevelsCommand.java

@@ -1,154 +1,36 @@
 package com.gmail.nossr50.commands.experience;
 
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.StringUtils;
-import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
-public class AddlevelsCommand implements CommandExecutor {
+public class AddlevelsCommand extends ExperienceCommand {
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        PlayerProfile profile;
-        int levels;
-        boolean allSkills = false;
-        SkillType skill = null;
-
-        switch (args.length) {
-            case 2:
-                if (!Permissions.addlevels(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (!(sender instanceof Player)) {
-                    return false;
-                }
-
-                if (args[0].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[0])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
-                    return true;
-                }
-
-                if (!StringUtils.isInt(args[1])) {
-                    return false;
-                }
-
-                levels = Integer.parseInt(args[1]);
-                profile = UserManager.getPlayer((Player) sender).getProfile();
-
-                if (allSkills) {
-                    for (SkillType skillType : SkillType.values()) {
-                        if (skillType.isChildSkill()) {
-                            continue;
-                        }
-
-                        profile.addLevels(skillType, levels);
-                    }
-                }
-                else {
-                    skill = SkillType.getSkill(args[0]);
-                    profile.addLevels(skill, levels);
-                }
-
-                if (allSkills) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.1", levels));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", levels, SkillUtils.getSkillName(skill)));
-                }
-
-                return true;
-
-            case 3:
-                if (!Permissions.addlevelsOthers(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (args[1].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[1])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
-                    return true;
-                }
-
-                if (!StringUtils.isInt(args[2])) {
-                    return false;
-                }
-
-                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
-                levels = Integer.parseInt(args[2]);
-
-                // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
-                if (mcMMOPlayer == null) {
-                    profile = new PlayerProfile(args[0], false);
-
-                    if (!profile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
-
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            profile.addLevels(skillType, levels);
-                        }
-                    }
-                    else {
-                        skill = SkillType.getSkill(args[1]);
-                        profile.addLevels(skill, levels);
-                    }
-
-                    profile.save(); // Since this is a temporary profile, we save it here.
-                }
-                else {
-                    profile = mcMMOPlayer.getProfile();
-
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            profile.addLevels(skillType, levels);
-                        }
+    protected boolean permissionsCheckSelf(CommandSender sender) {
+        return Permissions.addlevels(sender);
+    }
 
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.1", levels));
-                    }
-                    else {
-                        skill = SkillType.getSkill(args[1]);
-                        profile.addLevels(skill, levels);
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", levels, SkillUtils.getSkillName(skill)));
-                    }
-                }
+    @Override
+    protected boolean permissionsCheckOthers(CommandSender sender) {
+        return Permissions.addlevelsOthers(sender);
+    }
 
-                if (allSkills) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", args[0]));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", SkillUtils.getSkillName(skill), args[0]));
-                }
+    @Override
+    protected void handleCommand(SkillType skill) {
+        profile.addLevels(skill, value);
+    }
 
-                return true;
+    @Override
+    protected void handlePlayerMessageAll() {
+        player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.1", value));
+    }
 
-            default:
-                return false;
-        }
+    @Override
+    protected void handlePlayerMessageSkill() {
+        player.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.1", value, SkillUtils.getSkillName(skill)));
+        
     }
 }

+ 24 - 136
src/main/java/com/gmail/nossr50/commands/experience/AddxpCommand.java

@@ -1,152 +1,40 @@
 package com.gmail.nossr50.commands.experience;
 
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.StringUtils;
-import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
-public class AddxpCommand implements CommandExecutor {
+public class AddxpCommand extends ExperienceCommand {
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        int xp;
-        McMMOPlayer mcMMOPlayer;
-        PlayerProfile profile;
-        boolean allSkills = false;
-        SkillType skill = null;
-
-        switch (args.length) {
-            case 2:
-                if (!Permissions.addxp(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (!(sender instanceof Player)) {
-                    return false;
-                }
-
-                if (args[0].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[0])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
-                    return true;
-                }
-
-                if (!StringUtils.isInt(args[1])) {
-                    return false;
-                }
-
-                xp = Integer.parseInt(args[1]);
-                mcMMOPlayer = UserManager.getPlayer((Player) sender);
-                profile = mcMMOPlayer.getProfile();
-
-                if (allSkills) {
-                    for (SkillType skillType : SkillType.values()) {
-                        if (skillType.isChildSkill()) {
-                            continue;
-                        }
-
-                        mcMMOPlayer.applyXpGain(skillType, xp);
-                    }
-
-                    sender.sendMessage(LocaleLoader.getString("Commands.addxp.AwardAll", xp));
-                }
-                else {
-                    skill = SkillType.getSkill(args[0]);
-
-                    mcMMOPlayer.applyXpGain(skill, xp);
-                    sender.sendMessage(LocaleLoader.getString("Commands.addxp.AwardSkill", xp, SkillUtils.getSkillName(skill)));
-                }
-
-                return true;
-
-            case 3:
-                if (!Permissions.addxpOthers(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (args[1].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[1])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
-                    return true;
-                }
-
-                if (!StringUtils.isInt(args[2])) {
-                    return false;
-                }
-
-                mcMMOPlayer = UserManager.getPlayer(args[0]);
-                xp = Integer.parseInt(args[2]);
-
-                // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
-                if (mcMMOPlayer == null) {
-                    profile = new PlayerProfile(args[0], false);
-
-                    if (!profile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
-
-                    // TODO: Currently the offline player doesn't level up automatically
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            profile.setSkillXpLevel(skillType, xp);
-                        }
-                    }
-                    else {
-                        skill = SkillType.getSkill(args[1]);
-                        profile.setSkillXpLevel(skill, xp);
-                    }
-
-                    profile.save(); // Since this is a temporary profile, we save it here.
-                }
-                else {
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            mcMMOPlayer.applyXpGain(skillType, xp);
-                        }
+    protected boolean permissionsCheckSelf(CommandSender sender) {
+        return Permissions.addxp(sender);
+    }
 
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.addxp.AwardAll", xp));
-                    }
-                    else {
-                        skill = SkillType.getSkill(args[1]);
-                        mcMMOPlayer.applyXpGain(skill, xp);
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.addxp.AwardSkill", xp, SkillUtils.getSkillName(skill)));
-                    }
-                }
+    @Override
+    protected boolean permissionsCheckOthers(CommandSender sender) {
+        return Permissions.addxpOthers(sender);
+    }
 
-                if (allSkills) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", args[0]));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", SkillUtils.getSkillName(skill), args[0]));
-                }
+    @Override
+    protected void handleCommand(SkillType skill) {
+        if (player != null) {
+            mcMMOPlayer.applyXpGain(skill, value);
+        }
+        else {
+            profile.setSkillXpLevel(skill, value);
+        }
+    }
 
-                return true;
+    @Override
+    protected void handlePlayerMessageAll() {
+        player.sendMessage(LocaleLoader.getString("Commands.addxp.AwardAll", value));
+    }
 
-            default:
-                return false;
-        }
+    @Override
+    protected void handlePlayerMessageSkill() {
+        player.sendMessage(LocaleLoader.getString("Commands.addxp.AwardSkill", value, SkillUtils.getSkillName(skill)));
     }
 }

+ 149 - 0
src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java

@@ -0,0 +1,149 @@
+package com.gmail.nossr50.commands.experience;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.datatypes.player.PlayerProfile;
+import com.gmail.nossr50.datatypes.skills.SkillType;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.commands.CommandUtils;
+import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.skills.SkillUtils;
+
+
+public abstract class ExperienceCommand implements CommandExecutor {
+    protected McMMOPlayer mcMMOPlayer;
+    protected Player player;
+    protected PlayerProfile profile;
+
+    protected boolean allSkills;
+    protected SkillType skill;
+    protected int value;
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        switch (args.length) {
+            case 2:
+                if (CommandUtils.noConsoleUsage(sender)) {
+                    return true;
+                }
+
+                if (!permissionsCheckSelf(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
+                if (!validateArguments(sender, args[0], args[1])) {
+                    return true;
+                }
+
+                mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                player = mcMMOPlayer.getPlayer();
+                profile = mcMMOPlayer.getProfile();
+
+                editValues();
+                return true;
+
+            case 3:
+                if (!permissionsCheckOthers(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
+                if (!validateArguments(sender, args[1], args[2])) {
+                    return true;
+                }
+
+                mcMMOPlayer = UserManager.getPlayer(args[0]);
+
+                // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
+                if (mcMMOPlayer == null) {
+                    profile = new PlayerProfile(args[0], false);
+
+                    if (CommandUtils.unloadedProfile(sender, profile)) {
+                        return true;
+                    }
+
+                    editValues();
+                    profile.save(); // Since this is a temporary profile, we save it here.
+                }
+                else {
+                    profile = mcMMOPlayer.getProfile();
+                    editValues();
+                }
+
+                handleSenderMessage(sender, args[0]);
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    protected abstract boolean permissionsCheckSelf(CommandSender sender);
+    protected abstract boolean permissionsCheckOthers(CommandSender sender);
+    protected abstract void handleCommand(SkillType skill);
+    protected abstract void handlePlayerMessageAll();
+    protected abstract void handlePlayerMessageSkill();
+
+    private boolean validateArguments(CommandSender sender, String skillName, String value) {
+        if (isInvalidInteger(sender, value) || isInvalidSkill(sender, skillName)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean isInvalidInteger(CommandSender sender, String value) {
+        if (CommandUtils.isInvalidInteger(sender, value)) {
+            return true;
+        }
+
+        this.value = Integer.parseInt(value);
+        return false;
+    }
+
+    protected boolean isInvalidSkill(CommandSender sender, String skillName) {
+        if (skillName.equalsIgnoreCase("all")) {
+            allSkills = true;
+            return false;
+        }
+        else if (CommandUtils.isInvalidSkill(sender, skillName)) {
+            return true;
+        }
+
+        skill = SkillType.getSkill(skillName);
+        return false;
+    }
+
+    protected void handleSenderMessage(CommandSender sender, String playerName) {
+        if (allSkills) {
+            sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", playerName));
+        }
+        else {
+            sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardSkill.2", SkillUtils.getSkillName(skill), playerName));
+        }
+    }
+
+    protected void editValues() {
+        if (allSkills) {
+            for (SkillType skillType : SkillType.values()) {
+                handleCommand(skillType);
+            }
+
+            if (player != null) {
+                handlePlayerMessageAll();
+            }
+        }
+        else {
+            handleCommand(skill);
+
+            if (player != null) {
+                handlePlayerMessageSkill();
+            }
+        }
+    }
+}

+ 19 - 134
src/main/java/com/gmail/nossr50/commands/experience/MmoeditCommand.java

@@ -1,150 +1,35 @@
 package com.gmail.nossr50.commands.experience;
 
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.StringUtils;
-import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
-public class MmoeditCommand implements CommandExecutor {
+public class MmoeditCommand extends ExperienceCommand {
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        PlayerProfile profile;
-        int newValue;
-        boolean allSkills = false;
-        SkillType skill = null;
-
-        switch (args.length) {
-            case 2:
-                if (!Permissions.mmoedit(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (!(sender instanceof Player)) {
-                    return false;
-                }
-
-                if (args[0].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[0])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
-                    return true;
-                }
-
-                if (!StringUtils.isInt(args[1])) {
-                    return false;
-                }
-
-                newValue = Integer.parseInt(args[1]);
-                profile = UserManager.getPlayer((Player) sender).getProfile();
-
-                if (allSkills) {
-                    for (SkillType skillType : SkillType.values()) {
-                        if (skillType.isChildSkill()) {
-                            continue;
-                        }
-
-                        profile.modifySkill(skillType, newValue);
-                    }
-
-                    sender.sendMessage(LocaleLoader.getString("Commands.mmoedit.AllSkills.1", newValue));
-                }
-                else {
-                    skill = SkillType.getSkill(args[0]);
-                    profile.modifySkill(skill, newValue);
-                    sender.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.1", SkillUtils.getSkillName(skill), newValue));
-                }
-
-                return true;
-
-            case 3:
-                if (!Permissions.mmoeditOthers(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (args[1].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[1])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
-                    return true;
-                }
-
-                if (!StringUtils.isInt(args[2])) {
-                    return false;
-                }
-
-                newValue = Integer.parseInt(args[2]);
-                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
-
-                // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
-                if (mcMMOPlayer == null) {
-                    profile = new PlayerProfile(args[0], false);
-
-                    if (!profile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
-
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            profile.modifySkill(skillType, newValue);
-                        }
-                    }
-                    else {
-                        skill = SkillType.getSkill(args[1]);
-                        profile.modifySkill(skill, newValue);
-                    }
-
-                    profile.save(); // Since this is a temporary profile, we save it here.
-                }
-                else {
-                    profile = mcMMOPlayer.getProfile();
-
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            profile.modifySkill(skillType, newValue);
-                        }
+    protected boolean permissionsCheckSelf(CommandSender sender) {
+        return Permissions.mmoedit(sender);
+    }
 
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.mmoedit.AllSkills.1", newValue));
-                    }
-                    else {
-                        skill = SkillType.getSkill(args[1]);
-                        profile.modifySkill(skill, newValue);
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.1", SkillUtils.getSkillName(skill), newValue));
-                    }
-                }
+    @Override
+    protected boolean permissionsCheckOthers(CommandSender sender) {
+        return Permissions.mmoeditOthers(sender);
+    }
 
-                if (allSkills) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", args[0]));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.2", SkillUtils.getSkillName(skill), args[0]));
-                }
+    @Override
+    protected void handleCommand(SkillType skill) {
+        profile.modifySkill(skill, value);
+    }
 
-                return true;
+    @Override
+    protected void handlePlayerMessageAll() {
+        player.sendMessage(LocaleLoader.getString("Commands.mmoedit.AllSkills.1", value));
+    }
 
-            default:
-                return false;
-        }
+    @Override
+    protected void handlePlayerMessageSkill() {
+        player.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.1", SkillUtils.getSkillName(skill), value));
     }
 }

+ 56 - 110
src/main/java/com/gmail/nossr50/commands/experience/SkillresetCommand.java

@@ -1,76 +1,45 @@
 package com.gmail.nossr50.commands.experience;
 
 import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
-public class SkillresetCommand implements CommandExecutor {
+public class SkillresetCommand extends ExperienceCommand {
+    private CommandSender sender;
+    private Command command;
+
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        PlayerProfile profile;
-        boolean allSkills = false;
-        SkillType skill = null;
-        String skillName = "";
-
         switch (args.length) {
             case 1:
-                if (!Permissions.skillreset(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
+                if (CommandUtils.noConsoleUsage(sender)) {
                     return true;
                 }
 
-                if (!(sender instanceof Player)) {
-                    return false;
-                }
-
-                if (args[0].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[0])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
+                if (!Permissions.skillreset(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
                     return true;
                 }
 
-                profile = UserManager.getPlayer((Player) sender).getProfile();
-
-                if (allSkills) {
-                    for (SkillType skillType : SkillType.values()) {
-                        if (skillType.isChildSkill()) {
-                            continue;
-                        }
-
-                        if (!Permissions.skillreset(sender, skillType)) {
-                            sender.sendMessage(command.getPermissionMessage());
-                            continue;
-                        }
-
-                        profile.modifySkill(skillType, 0);
-                    }
-
-                    sender.sendMessage(LocaleLoader.getString("Commands.Reset.All"));
+                if (isInvalidSkill(sender, args[0])) {
+                    return true;
                 }
-                else {
-                    skill = SkillType.getSkill(args[0]);
-                    skillName = SkillUtils.getSkillName(skill);
 
-                    if (!Permissions.skillreset(sender, skill)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
+                mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                player = mcMMOPlayer.getPlayer();
+                profile = mcMMOPlayer.getProfile();
 
-                    profile.modifySkill(skill, 0);
-                    sender.sendMessage(LocaleLoader.getString("Commands.Reset.Single", skillName));
-                }
+                this.command = command;
+                this.sender = sender;
 
+                editValues();
                 return true;
 
             case 2:
@@ -79,91 +48,68 @@ public class SkillresetCommand implements CommandExecutor {
                     return true;
                 }
 
-                if (args[1].equalsIgnoreCase("all")) {
-                    allSkills = true;
-                }
-                else if (!SkillUtils.isSkill(args[1])) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
+                if (isInvalidSkill(sender, args[1])) {
                     return true;
                 }
 
-                if (!allSkills) {
-                    skill = SkillType.getSkill(args[1]);
-                    skillName = SkillUtils.getSkillName(skill);
-
-                    if (!Permissions.skillresetOthers(sender, skill)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-                }
-
-                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
+                mcMMOPlayer = UserManager.getPlayer(args[0]);
 
                 // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
                 if (mcMMOPlayer == null) {
                     profile = new PlayerProfile(args[0], false);
 
-                    if (!profile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+                    if (CommandUtils.unloadedProfile(sender, profile)) {
                         return true;
                     }
 
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            if (!Permissions.skillresetOthers(sender, skill)) {
-                                sender.sendMessage(command.getPermissionMessage());
-                                continue;
-                            }
-
-                            profile.modifySkill(skillType, 0);
-                        }
-                    }
-                    else {
-                        profile.modifySkill(skill, 0);
-                    }
+                    this.command = command;
+                    this.sender = sender;
 
+                    editValues();
                     profile.save(); // Since this is a temporary profile, we save it here.
                 }
                 else {
                     profile = mcMMOPlayer.getProfile();
-
-                    if (allSkills) {
-                        for (SkillType skillType : SkillType.values()) {
-                            if (skillType.isChildSkill()) {
-                                continue;
-                            }
-
-                            if (!Permissions.skillresetOthers(sender, skillType)) {
-                                sender.sendMessage(command.getPermissionMessage());
-                                continue;
-                            }
-
-                            profile.modifySkill(skillType, 0);
-                        }
-
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.Reset.All"));
-                    }
-                    else {
-                        profile.modifySkill(skill, 0);
-                        mcMMOPlayer.getPlayer().sendMessage(LocaleLoader.getString("Commands.Reset.Single", skillName));
-                    }
-                }
-
-                if (allSkills) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.addlevels.AwardAll.2", args[0]));
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.mmoedit.Modified.2", skillName, args[0]));
+                    editValues();
                 }
 
+                handleSenderMessage(sender, args[0]);
                 return true;
 
             default:
                 return false;
         }
     }
+
+    @Override
+    protected boolean permissionsCheckSelf(CommandSender sender) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected boolean permissionsCheckOthers(CommandSender sender) {
+        // TODO Auto-generated method stub
+        return false;
+    }
+
+    @Override
+    protected void handleCommand(SkillType skill) {
+        if ((player.equals(sender) && !Permissions.skillreset(sender, skill)) || (!player.equals(sender) && !Permissions.skillresetOthers(sender, skill))) {
+            sender.sendMessage(command.getPermissionMessage());
+            return;
+        }
+
+        profile.modifySkill(skill, 0);
+    }
+
+    @Override
+    protected void handlePlayerMessageAll() {
+        player.sendMessage(LocaleLoader.getString("Commands.Reset.All"));
+    }
+
+    @Override
+    protected void handlePlayerMessageSkill() {
+        player.sendMessage(LocaleLoader.getString("Commands.Reset.Single", SkillUtils.getSkillName(skill)));
+    }
 }

+ 25 - 69
src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreCommand.java

@@ -1,85 +1,41 @@
 package com.gmail.nossr50.commands.hardcore;
 
-import java.text.DecimalFormat;
-
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.StringUtils;
 
-public class HardcoreCommand implements CommandExecutor {
+public class HardcoreCommand extends HardcoreModeCommand {
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        switch (args.length) {
-            case 0:
-                if (!Permissions.hardcoreToggle(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (Config.getInstance().getHardcoreEnabled()) {
-                    disableHardcore();
-                }
-                else {
-                    enableHardcore();
-                }
-
-                return true;
-
-            case 1:
-                if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("true") || args[0].equalsIgnoreCase("enabled")) {
-                    if (!Permissions.hardcoreToggle(sender)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-
-                    enableHardcore();
-                    return true;
-                }
-
-                if (args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("false") || args[0].equalsIgnoreCase("disabled")) {
-                    if (!Permissions.hardcoreToggle(sender)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-
-                    disableHardcore();
-                    return true;
-                }
-
-                if (!StringUtils.isDouble(args[0])) {
-                    return false;
-                }
-
-                if (!Permissions.hardcoreModify(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
+    protected void disable() {
+        Config.getInstance().setHardcoreEnabled(false);
+        mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Disabled"));
+    }
 
-                DecimalFormat percent = new DecimalFormat("##0.00%");
-                double newPercent = Double.parseDouble(args[0]);
+    @Override
+    protected void enable() {
+        Config.getInstance().setHardcoreEnabled(true);
+        mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Enabled"));
+    }
 
-                Config.getInstance().setHardcoreDeathStatPenaltyPercentage(newPercent);
-                sender.sendMessage(LocaleLoader.getString("Hardcore.PercentageChanged", percent.format(newPercent / 100D)));
-                return true;
+    @Override
+    protected boolean checkTogglePermissions() {
+        return Permissions.hardcoreToggle(sender);
+    }
 
-            default:
-                return false;
-        }
+    @Override
+    protected boolean checkModifyPermissions() {
+        return Permissions.hardcoreModify(sender);
     }
 
-    private void disableHardcore() {
-        Config.getInstance().setHardcoreEnabled(false);
-        mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Disabled"));
+    @Override
+    protected boolean checkEnabled() {
+        return Config.getInstance().getHardcoreEnabled();
     }
 
-    private void enableHardcore() {
-        Config.getInstance().setHardcoreEnabled(true);
-        mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Hardcore.Enabled"));
+    @Override
+    protected void modify() {
+        Config.getInstance().setHardcoreDeathStatPenaltyPercentage(newPercent);
+        sender.sendMessage(LocaleLoader.getString("Hardcore.PercentageChanged", percent.format(newPercent / 100D)));
     }
-}
+}

+ 94 - 0
src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreModeCommand.java

@@ -0,0 +1,94 @@
+package com.gmail.nossr50.commands.hardcore;
+
+import java.text.DecimalFormat;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.commands.CommandUtils;
+
+public abstract class HardcoreModeCommand implements CommandExecutor {
+    protected CommandSender sender;
+    protected double newPercent;
+    protected DecimalFormat percent;
+
+    public HardcoreModeCommand() {
+        percent = new DecimalFormat("##0.00%");
+    }
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        switch (args.length) {
+            case 0:
+                this.sender = sender;
+
+                if (!checkTogglePermissions()) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
+                if (checkEnabled()) {
+                    disable();
+                }
+                else {
+                    enable();
+                }
+
+                return true;
+
+            case 1:
+                if (CommandUtils.shouldEnableToggle(args[0])) {
+                    if (!Permissions.hardcoreToggle(sender)) {
+                        sender.sendMessage(command.getPermissionMessage());
+                        return true;
+                    }
+
+                    enable();
+                    return true;
+                }
+
+                if (CommandUtils.shouldDisableToggle(args[0])) {
+                    if (!Permissions.hardcoreToggle(sender)) {
+                        sender.sendMessage(command.getPermissionMessage());
+                        return true;
+                    }
+
+                    disable();
+                    return true;
+                }
+
+                if (isInvalidPercentage(sender, args[0])) {
+                    return true;
+                }
+
+                if (!Permissions.hardcoreModify(sender)) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
+                modify();
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    protected abstract boolean checkTogglePermissions();
+    protected abstract boolean checkModifyPermissions();
+    protected abstract boolean checkEnabled();
+    protected abstract void enable();
+    protected abstract void disable();
+    protected abstract void modify();
+
+    private boolean isInvalidPercentage(CommandSender sender, String value) {
+        if (CommandUtils.isInvalidDouble(sender, value)) {
+            return true;
+        }
+
+        newPercent = Double.parseDouble(value);
+        return false;
+    }
+}

+ 23 - 72
src/main/java/com/gmail/nossr50/commands/hardcore/VampirismCommand.java

@@ -1,90 +1,41 @@
 package com.gmail.nossr50.commands.hardcore;
 
-import java.text.DecimalFormat;
-
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.StringUtils;
 
-public class VampirismCommand implements CommandExecutor {
+public class VampirismCommand extends HardcoreModeCommand {
     @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (!Config.getInstance().getHardcoreEnabled()) {
-            sender.sendMessage(LocaleLoader.getString("Hardcore.Disabled"));
-            return true;
-        }
-
-        switch (args.length) {
-            case 0:
-                if (!Permissions.vampirismToggle(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
-
-                if (Config.getInstance().getHardcoreVampirismEnabled()) {
-                    disableVampirism();
-                }
-                else {
-                    enableVampirism();
-                }
-
-                return true;
-
-            case 1:
-                if (args[0].equalsIgnoreCase("on") || args[0].equalsIgnoreCase("true") || args[0].equalsIgnoreCase("enabled")) {
-                    if (!Permissions.vampirismToggle(sender)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-
-                    enableVampirism();
-                    return true;
-                }
-
-                if (args[0].equalsIgnoreCase("off") || args[0].equalsIgnoreCase("false") || args[0].equalsIgnoreCase("disabled")) {
-                    if (!Permissions.vampirismToggle(sender)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-
-                    disableVampirism();
-                    return true;
-                }
-
-                if (!StringUtils.isDouble(args[0])) {
-                    return false;
-                }
-
-                if (!Permissions.vampirismModify(sender)) {
-                    sender.sendMessage(command.getPermissionMessage());
-                    return true;
-                }
+    protected boolean checkTogglePermissions() {
+        return Permissions.vampirismToggle(sender);
+    }
 
-                DecimalFormat percent = new DecimalFormat("##0.00%");
-                double newPercent = Double.parseDouble(args[0]);
+    @Override
+    protected boolean checkModifyPermissions() {
+        return Permissions.vampirismModify(sender);
+    }
 
-                Config.getInstance().setHardcoreVampirismStatLeechPercentage(newPercent);
-                sender.sendMessage(LocaleLoader.getString("Vampirism.PercentageChanged", percent.format(newPercent / 100D)));
-                return true;
+    @Override
+    protected boolean checkEnabled() {
+        return Config.getInstance().getHardcoreVampirismEnabled();
+    }
 
-            default:
-                return false;
-        }
+    @Override
+    protected void enable() {
+        Config.getInstance().setHardcoreVampirismEnabled(true);
+        mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Vampirism.Enabled"));
     }
 
-    private void disableVampirism() {
+    @Override
+    protected void disable() {
         Config.getInstance().setHardcoreVampirismEnabled(false);
         mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Vampirism.Disabled"));
     }
 
-    private void enableVampirism() {
-        Config.getInstance().setHardcoreVampirismEnabled(true);
-        mcMMO.p.getServer().broadcastMessage(LocaleLoader.getString("Vampirism.Enabled"));
+    @Override
+    protected void modify() {
+        Config.getInstance().setHardcoreVampirismStatLeechPercentage(newPercent);
+        sender.sendMessage(LocaleLoader.getString("Vampirism.PercentageChanged", percent.format(newPercent / 100D)));
     }
-}
+}

+ 2 - 5
src/main/java/com/gmail/nossr50/commands/party/PartyAcceptCommand.java

@@ -11,15 +11,12 @@ import com.gmail.nossr50.party.PartyManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyAcceptCommand implements CommandExecutor {
-    private McMMOPlayer mcMMOPlayer;
-    private Player player;
-
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 1:
-                player = (Player) sender;
-                mcMMOPlayer = UserManager.getPlayer(player);
+                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                Player player = mcMMOPlayer.getPlayer();
 
                 if (!mcMMOPlayer.hasPartyInvite()) {
                     sender.sendMessage(LocaleLoader.getString("mcMMO.NoInvites"));

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

@@ -3,7 +3,6 @@ package com.gmail.nossr50.commands.party;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.party.Party;
@@ -16,7 +15,7 @@ public class PartyChangeOwnerCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 2:
-                Party playerParty = UserManager.getPlayer((Player) sender).getParty();
+                Party playerParty = UserManager.getPlayer(sender.getName()).getParty();
 
                 if (!playerParty.getMembers().contains(mcMMO.p.getServer().getOfflinePlayer(args[1]))) {
                     sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", args[1]));

+ 8 - 7
src/main/java/com/gmail/nossr50/commands/party/PartyChangePasswordCommand.java

@@ -3,29 +3,30 @@ package com.gmail.nossr50.commands.party;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyChangePasswordCommand implements CommandExecutor {
+    private Party playerParty;
+
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        Party playerParty = UserManager.getPlayer((Player) sender).getParty();
+        playerParty = UserManager.getPlayer(sender.getName()).getParty();
 
         switch (args.length) {
             case 1:
-                unprotectParty(sender, playerParty);
+                unprotectParty(sender);
                 return true;
 
             case 2:
                 if (args[1].equalsIgnoreCase("clear") || args[1].equalsIgnoreCase("reset")) {
-                    unprotectParty(sender, playerParty);
+                    unprotectParty(sender);
                     return true;
                 }
 
-                protectParty(sender, playerParty, args[1]);
+                protectParty(sender, args[1]);
                 return true;
 
             default:
@@ -35,13 +36,13 @@ public class PartyChangePasswordCommand implements CommandExecutor {
         }
     }
 
-    private void unprotectParty(CommandSender sender, Party playerParty) {
+    private void unprotectParty(CommandSender sender) {
         playerParty.setLocked(true);
         playerParty.setPassword(null);
         sender.sendMessage(LocaleLoader.getString("Party.Password.Removed"));
     }
 
-    private void protectParty(CommandSender sender, Party playerParty, String password) {
+    private void protectParty(CommandSender sender, String password) {
         playerParty.setLocked(true);
         playerParty.setPassword(password);
         sender.sendMessage(LocaleLoader.getString("Party.Password.Set", password));

+ 2 - 3
src/main/java/com/gmail/nossr50/commands/party/PartyCommand.java

@@ -45,8 +45,8 @@ public class PartyCommand implements CommandExecutor {
             return true;
         }
 
-        player = (Player) sender;
-        mcMMOPlayer = UserManager.getPlayer(player);
+        mcMMOPlayer = UserManager.getPlayer(sender.getName());
+        player = mcMMOPlayer.getPlayer();
 
         if (args.length < 1) {
             if (!mcMMOPlayer.inParty()) {
@@ -121,7 +121,6 @@ public class PartyCommand implements CommandExecutor {
             case OWNER:
                 return partyChangeOwnerCommand.onCommand(sender, command, label, args);
             case LOCK:
-                // Fallthrough
             case UNLOCK:
                 return partyLockCommand.onCommand(sender, command, label, args);
             case PASSWORD:

+ 4 - 9
src/main/java/com/gmail/nossr50/commands/party/PartyCreateCommand.java

@@ -12,26 +12,21 @@ import com.gmail.nossr50.party.PartyManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyCreateCommand implements CommandExecutor {
-    private McMMOPlayer mcMMOPlayer;
-    private Player player;
-
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 2:
-                // Fallthrough
             case 3:
                 Party newParty = PartyManager.getParty(args[1]);
 
+                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                Player player = mcMMOPlayer.getPlayer();
+
                 // Check to see if the party exists, and if it does cancel creating a new party
-                if (newParty != null) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", args[1]));
+                if (PartyManager.checkPartyExistence(player, newParty, args[1])) {
                     return true;
                 }
 
-                player = (Player) sender;
-                mcMMOPlayer = UserManager.getPlayer(player);
-
                 // Changing parties
                 if (!PartyManager.changeOrJoinParty(mcMMOPlayer, player, mcMMOPlayer.getParty(), args[1])) {
                     return true;

+ 3 - 2
src/main/java/com/gmail/nossr50/commands/party/PartyDisbandCommand.java

@@ -16,10 +16,11 @@ public class PartyDisbandCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 1:
-                Party playerParty = UserManager.getPlayer((Player) sender).getParty();
+                Party playerParty = UserManager.getPlayer(sender.getName()).getParty();
+                String partyName = playerParty.getName();
 
                 for (Player member : playerParty.getOnlineMembers()) {
-                    if (!PartyManager.handlePartyChangeEvent(member, playerParty.getName(), null, EventReason.KICKED_FROM_PARTY)) {
+                    if (!PartyManager.handlePartyChangeEvent(member, partyName, null, EventReason.KICKED_FROM_PARTY)) {
                         return true;
                     }
 

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

@@ -11,6 +11,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.ShareHandler;
 import com.gmail.nossr50.party.ShareHandler.ShareMode;
 import com.gmail.nossr50.util.StringUtils;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyExpShareCommand implements CommandExecutor {
@@ -25,12 +26,12 @@ public class PartyExpShareCommand implements CommandExecutor {
 
         switch (args.length) {
             case 2:
-                playerParty = UserManager.getPlayer((Player) sender).getParty();
+                playerParty = UserManager.getPlayer(sender.getName()).getParty();
 
-                if (args[1].equalsIgnoreCase("none") || args[1].equalsIgnoreCase("off") || args[1].equalsIgnoreCase("false")) {
+                if (args[1].equalsIgnoreCase("none") || CommandUtils.shouldDisableToggle(args[1])) {
                     handleChangingShareMode(ShareMode.NONE);
                 }
-                else if (args[1].equalsIgnoreCase("equal") || args[1].equalsIgnoreCase("even") || args[1].equalsIgnoreCase("on") || args[1].equalsIgnoreCase("true")) {
+                else if (args[1].equalsIgnoreCase("equal") || args[1].equalsIgnoreCase("even") || CommandUtils.shouldEnableToggle(args[1])) {
                     handleChangingShareMode(ShareMode.EQUAL);
                 }
                 else {
@@ -48,8 +49,10 @@ public class PartyExpShareCommand implements CommandExecutor {
     private void handleChangingShareMode(ShareHandler.ShareMode mode) {
         playerParty.setXpShareMode(mode);
 
+        String changeModeMessage = LocaleLoader.getString("Commands.Party.SetSharing", LocaleLoader.getString("Party.ShareType.Exp"), LocaleLoader.getString("Party.ShareMode." + StringUtils.getCapitalized(mode.toString())));
+
         for (Player member : playerParty.getOnlineMembers()) {
-            member.sendMessage(LocaleLoader.getString("Commands.Party.SetSharing", LocaleLoader.getString("Party.ShareType.Exp"), LocaleLoader.getString("Party.ShareMode." + StringUtils.getCapitalized(mode.toString()))));
+            member.sendMessage(changeModeMessage);
         }
     }
 }

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

@@ -26,5 +26,4 @@ public class PartyHelpCommand implements CommandExecutor {
                 return true;
         }
     }
-
 }

+ 11 - 7
src/main/java/com/gmail/nossr50/commands/party/PartyInfoCommand.java

@@ -21,8 +21,8 @@ public class PartyInfoCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        player = (Player) sender;
-        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
+        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+        player = mcMMOPlayer.getPlayer();
         playerParty = mcMMOPlayer.getParty();
 
         displayPartyHeader();
@@ -35,15 +35,19 @@ public class PartyInfoCommand implements CommandExecutor {
         StringBuilder memberList = new StringBuilder();
 
         for (OfflinePlayer member : playerParty.getMembers()) {
-            if (playerParty.getLeader().equalsIgnoreCase(member.getName())) {
-                memberList.append(ChatColor.GOLD).append(member.getName()).append(" ");
+            String memberName = member.getName();
+
+            if (playerParty.getLeader().equalsIgnoreCase(memberName)) {
+                memberList.append(ChatColor.GOLD);
             }
             else if (member.isOnline()) {
-                memberList.append(ChatColor.WHITE).append(member.getName()).append(" ");
+                memberList.append(ChatColor.WHITE);
             }
             else {
-                memberList.append(ChatColor.GRAY).append(member.getName()).append(" ");
+                memberList.append(ChatColor.GRAY);
             }
+
+            memberList.append(memberName).append(" ");
         }
 
         return memberList.toString();
@@ -52,7 +56,7 @@ public class PartyInfoCommand implements CommandExecutor {
     private void displayShareModeInfo() {
         boolean xpShareEnabled = Config.getInstance().getExpShareEnabled();
         boolean itemShareEnabled = Config.getInstance().getItemShareEnabled();
-        boolean itemSharingActive = playerParty.getItemShareMode() != ShareHandler.ShareMode.NONE;
+        boolean itemSharingActive = (playerParty.getItemShareMode() != ShareHandler.ShareMode.NONE);
 
         if (!xpShareEnabled && !itemShareEnabled) {
             return;

+ 7 - 20
src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java

@@ -5,40 +5,27 @@ import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
-import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.PartyManager;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyInviteCommand implements CommandExecutor {
-    private McMMOPlayer mcMMOTarget;
-    private Player target;
-
-    private McMMOPlayer mcMMOPlayer;
-    private Player player;
-    private Party playerParty;
-
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 2:
-                if (!mcMMO.p.getServer().getOfflinePlayer(args[1]).isOnline()) {
-                    sender.sendMessage(LocaleLoader.getString("Party.NotOnline", args[1]));
-                    return true;
-                }
-
-                mcMMOTarget = UserManager.getPlayer(args[1]);
+                McMMOPlayer mcMMOTarget = UserManager.getPlayer(args[1]);
 
-                if (mcMMOTarget == null) {
-                    sender.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
+                if (CommandUtils.checkPlayerExistence(sender, args[1], mcMMOTarget)) {
                     return true;
                 }
 
-                target = mcMMOTarget.getPlayer();
-                mcMMOPlayer = UserManager.getPlayer((Player) sender);
-                player = mcMMOPlayer.getPlayer();
+                Player target = mcMMOTarget.getPlayer();
+                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                Player player = mcMMOPlayer.getPlayer();
 
                 if (player.equals(target)) {
                     sender.sendMessage(LocaleLoader.getString("Party.Invite.Self"));
@@ -50,7 +37,7 @@ public class PartyInviteCommand implements CommandExecutor {
                     return true;
                 }
 
-                playerParty = mcMMOPlayer.getParty();
+                Party playerParty = mcMMOPlayer.getParty();
 
                 if (!PartyManager.canInvite(player, playerParty)) {
                     player.sendMessage(LocaleLoader.getString("Party.Locked"));

+ 18 - 13
src/main/java/com/gmail/nossr50/commands/party/PartyItemShareCommand.java

@@ -11,6 +11,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.ShareHandler;
 import com.gmail.nossr50.party.ShareHandler.ShareMode;
 import com.gmail.nossr50.util.StringUtils;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyItemShareCommand implements CommandExecutor {
@@ -25,9 +26,9 @@ public class PartyItemShareCommand implements CommandExecutor {
 
         switch (args.length) {
             case 2:
-                playerParty = UserManager.getPlayer((Player) sender).getParty();
+                playerParty = UserManager.getPlayer(sender.getName()).getParty();
 
-                if (args[1].equalsIgnoreCase("none") || args[1].equalsIgnoreCase("off") || args[1].equalsIgnoreCase("false")) {
+                if (args[1].equalsIgnoreCase("none") || CommandUtils.shouldDisableToggle(args[1])) {
                     handleChangingShareMode(ShareMode.NONE);
                 }
                 else if (args[1].equalsIgnoreCase("equal") || args[1].equalsIgnoreCase("even")) {
@@ -43,15 +44,19 @@ public class PartyItemShareCommand implements CommandExecutor {
                 return true;
 
             case 3:
-                playerParty = UserManager.getPlayer((Player) sender).getParty();
+                playerParty = UserManager.getPlayer(sender.getName()).getParty();
                 boolean toggle = false;
 
-                if (args[2].equalsIgnoreCase("true") || args[2].equalsIgnoreCase("on") || args[2].equalsIgnoreCase("enabled")) {
+                if (CommandUtils.shouldEnableToggle(args[2])) {
                     toggle = true;
                 }
-                else if (args[2].equalsIgnoreCase("false") || args[2].equalsIgnoreCase("off") || args[2].equalsIgnoreCase("disabled")) {
+                else if (CommandUtils.shouldDisableToggle(args[2])) {
                     toggle = false;
                 }
+                else {
+                    sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting> <true | false>"));
+                    return true;
+                }
 
                 if (args[1].equalsIgnoreCase("loot")) {
                     playerParty.setSharingLootDrops(toggle);
@@ -69,7 +74,7 @@ public class PartyItemShareCommand implements CommandExecutor {
                     sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting> <true | false>"));
                 }
 
-                notifyToggleItemShareCategory(args, toggle);
+                notifyToggleItemShareCategory(args[1], toggle);
                 return true;
 
             default:
@@ -82,20 +87,20 @@ public class PartyItemShareCommand implements CommandExecutor {
     private void handleChangingShareMode(ShareHandler.ShareMode mode) {
         playerParty.setItemShareMode(mode);
 
+        String changeModeMessage = LocaleLoader.getString("Commands.Party.SetSharing", LocaleLoader.getString("Party.ShareType.Item"), LocaleLoader.getString("Party.ShareMode." + StringUtils.getCapitalized(mode.toString())));
+
         for (Player member : playerParty.getOnlineMembers()) {
-            member.sendMessage(LocaleLoader.getString("Commands.Party.SetSharing", LocaleLoader.getString("Party.ShareType.Item"), LocaleLoader.getString("Party.ShareMode." + StringUtils.getCapitalized(mode.toString()))));
+            member.sendMessage(changeModeMessage);
         }
     }
 
-    private void notifyToggleItemShareCategory(String[] args, boolean toggle) {
-        String state = "disabled";
+    private void notifyToggleItemShareCategory(String category, boolean toggle) {
+        String state = toggle ? "enabled" : "disabled";
 
-        if (toggle) {
-            state = "enabled";
-        }
+        String toggleMessage = LocaleLoader.getString("Commands.Party.ToggleShareCategory", StringUtils.getCapitalized(category), state);
 
         for (Player member : playerParty.getOnlineMembers()) {
-            member.sendMessage(LocaleLoader.getString("Commands.Party.ToggleShareCategory", StringUtils.getCapitalized(args[1]), state));
+            member.sendMessage(toggleMessage);
         }
     }
 }

+ 6 - 12
src/main/java/com/gmail/nossr50/commands/party/PartyJoinCommand.java

@@ -5,11 +5,11 @@ import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
-import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.PartyManager;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyJoinCommand implements CommandExecutor {
@@ -25,7 +25,6 @@ public class PartyJoinCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 2:
-                // Fallthrough
             case 3:
                 // Verify target exists and is in a different party than the player
                 if (!canJoinParty(sender, args[1])) {
@@ -62,16 +61,10 @@ public class PartyJoinCommand implements CommandExecutor {
     }
 
     private boolean canJoinParty(CommandSender sender, String targetName) {
-        if (!mcMMO.p.getServer().getOfflinePlayer(targetName).isOnline()) {
-            sender.sendMessage(LocaleLoader.getString("Party.NotOnline", targetName));
-            return false;
-        }
-
         mcMMOTarget = UserManager.getPlayer(targetName);
 
-        if (mcMMOTarget == null) {
-            sender.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
-            return false;
+        if (CommandUtils.checkPlayerExistence(sender, targetName, mcMMOTarget)) {
+            return true;
         }
 
         target = mcMMOTarget.getPlayer();
@@ -81,8 +74,9 @@ public class PartyJoinCommand implements CommandExecutor {
             return false;
         }
 
-        player = (Player) sender;
-        mcMMOPlayer = UserManager.getPlayer(player);
+        mcMMOPlayer = UserManager.getPlayer(sender.getName());
+        player = mcMMOPlayer.getPlayer();
+
         playerParty = mcMMOPlayer.getParty();
         targetParty = mcMMOTarget.getParty();
 

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

@@ -18,8 +18,7 @@ public class PartyKickCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 2:
-                Party playerParty = UserManager.getPlayer((Player) sender).getParty();
-
+                Party playerParty = UserManager.getPlayer(sender.getName()).getParty();
                 OfflinePlayer target = mcMMO.p.getServer().getOfflinePlayer(args[1]);
 
                 if (!playerParty.getMembers().contains(target)) {

+ 12 - 12
src/main/java/com/gmail/nossr50/commands/party/PartyLockCommand.java

@@ -3,11 +3,11 @@ package com.gmail.nossr50.commands.party;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyLockCommand implements CommandExecutor {
@@ -15,15 +15,15 @@ public class PartyLockCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        playerParty = UserManager.getPlayer((Player) sender).getParty();
+        playerParty = UserManager.getPlayer(sender.getName()).getParty();
 
         switch (args.length) {
             case 1:
                 if (args[0].equalsIgnoreCase("lock")) {
-                    lockParty(sender, command);
+                    lockParty(sender, command.getPermissionMessage());
                 }
                 else if (args[0].equalsIgnoreCase("unlock")) {
-                    unlockParty(sender, command);
+                    unlockParty(sender, command.getPermissionMessage());
                 }
 
                 return true;
@@ -34,11 +34,11 @@ public class PartyLockCommand implements CommandExecutor {
                     return true;
                 }
 
-                if (args[1].equalsIgnoreCase("on") || args[1].equalsIgnoreCase("true")) {
-                    lockParty(sender, command);
+                if (CommandUtils.shouldEnableToggle(args[1])) {
+                    lockParty(sender, command.getPermissionMessage());
                 }
-                else if (args[1].equalsIgnoreCase("off") || args[1].equalsIgnoreCase("false")) {
-                    unlockParty(sender, command);
+                else if (CommandUtils.shouldDisableToggle(args[1])) {
+                    unlockParty(sender, command.getPermissionMessage());
                 }
                 else {
                     sendUsageStrings(sender);
@@ -55,9 +55,9 @@ public class PartyLockCommand implements CommandExecutor {
     /**
      * Handle locking a party.
      */
-    private void lockParty(CommandSender sender, Command command) {
+    private void lockParty(CommandSender sender, String permissionMessage) {
         if (!Permissions.partySubcommand(sender, PartySubcommandType.LOCK)) {
-            sender.sendMessage(command.getPermissionMessage());
+            sender.sendMessage(permissionMessage);
             return;
         }
 
@@ -75,9 +75,9 @@ public class PartyLockCommand implements CommandExecutor {
      *
      * @return true if party is successfully unlocked, false otherwise.
      */
-    private void unlockParty(CommandSender sender, Command command) {
+    private void unlockParty(CommandSender sender, String permissionMessage) {
         if (!Permissions.partySubcommand(sender, PartySubcommandType.UNLOCK)) {
-            sender.sendMessage(command.getPermissionMessage());
+            sender.sendMessage(permissionMessage);
             return;
         }
 

+ 3 - 6
src/main/java/com/gmail/nossr50/commands/party/PartyQuitCommand.java

@@ -12,15 +12,12 @@ import com.gmail.nossr50.party.PartyManager;
 import com.gmail.nossr50.util.player.UserManager;
 
 public class PartyQuitCommand implements CommandExecutor {
-    private Player player;
-    private Party playerParty;
-
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 1:
-                player = (Player) sender;
-                playerParty = UserManager.getPlayer(player).getParty();
+                Player player = (Player) sender;
+                Party playerParty = UserManager.getPlayer(player).getParty();
 
                 if (!PartyManager.handlePartyChangeEvent(player, playerParty.getName(), null, EventReason.LEFT_PARTY)) {
                     return true;
@@ -31,7 +28,7 @@ public class PartyQuitCommand implements CommandExecutor {
                 return true;
 
             default:
-                sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "[quit|q|leave]"));
+                sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "quit"));
                 return true;
         }
     }

+ 11 - 7
src/main/java/com/gmail/nossr50/commands/party/PartyRenameCommand.java

@@ -6,6 +6,7 @@ import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.datatypes.party.Party;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.PartyManager;
@@ -14,29 +15,32 @@ import com.gmail.nossr50.util.player.UserManager;
 public class PartyRenameCommand implements CommandExecutor {
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        Party playerParty = UserManager.getPlayer((Player) sender).getParty();
-        String leaderName = playerParty.getLeader();
-
         switch (args.length) {
             case 2:
+                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                Party playerParty = mcMMOPlayer.getParty();
+
+                String oldPartyName = playerParty.getName();
                 String newPartyName = args[1];
 
                 // This is to prevent party leaders from spamming other players with the rename message
-                if (playerParty.getName().equalsIgnoreCase(newPartyName)) {
+                if (oldPartyName.equalsIgnoreCase(newPartyName)) {
                     sender.sendMessage(LocaleLoader.getString("Party.Rename.Same"));
                     return true;
                 }
 
+                Player player = mcMMOPlayer.getPlayer();
                 Party newParty = PartyManager.getParty(newPartyName);
 
                 // Check to see if the party exists, and if it does cancel renaming the party
-                if (newParty != null) {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", newPartyName));
+                if (PartyManager.checkPartyExistence(player, newParty, newPartyName)) {
                     return true;
                 }
 
+                String leaderName = playerParty.getLeader();
+
                 for (Player member : playerParty.getOnlineMembers()) {
-                    if (!PartyManager.handlePartyChangeEvent(member, playerParty.getName(), newPartyName, EventReason.CHANGED_PARTIES)) {
+                    if (!PartyManager.handlePartyChangeEvent(member, oldPartyName, newPartyName, EventReason.CHANGED_PARTIES)) {
                         return true;
                     }
 

+ 0 - 218
src/main/java/com/gmail/nossr50/commands/party/PtpCommand.java

@@ -1,218 +0,0 @@
-package com.gmail.nossr50.commands.party;
-
-import org.bukkit.World;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-
-import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.events.party.McMMOPartyTeleportEvent;
-import com.gmail.nossr50.locale.LocaleLoader;
-import com.gmail.nossr50.party.PartyManager;
-import com.gmail.nossr50.util.Misc;
-import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.commands.CommandUtils;
-import com.gmail.nossr50.util.player.UserManager;
-
-public class PtpCommand implements CommandExecutor {
-    private Player player;
-    private McMMOPlayer mcMMOPlayer;
-
-    private Player target;
-    private McMMOPlayer mcMMOTarget;
-
-    @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (CommandUtils.noConsoleUsage(sender)) {
-            return true;
-        }
-
-        switch (args.length) {
-            case 1:
-                player = (Player) sender;
-                mcMMOPlayer = UserManager.getPlayer(player);
-
-                if (args[0].equalsIgnoreCase("toggle")) {
-                    if (!Permissions.partyTeleportToggle(sender)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-
-                    return togglePartyTeleportation();
-                }
-
-                if (args[0].equalsIgnoreCase("acceptany") || args[0].equalsIgnoreCase("acceptall")) {
-                    if (!Permissions.partyTeleportAcceptAll(sender)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-
-                    return acceptAnyTeleportRequest();
-                }
-
-                int ptpCooldown = Config.getInstance().getPTPCommandCooldown();
-                long recentlyHurt = UserManager.getPlayer(player).getRecentlyHurt();
-
-                if ((recentlyHurt * Misc.TIME_CONVERSION_FACTOR + ptpCooldown * Misc.TIME_CONVERSION_FACTOR) > System.currentTimeMillis()) {
-                    player.sendMessage(LocaleLoader.getString("Party.Teleport.Hurt", ptpCooldown));
-                    return true;
-                }
-
-                if (args[0].equalsIgnoreCase("accept")) {
-                    if (!Permissions.partyTeleportAccept(sender)) {
-                        sender.sendMessage(command.getPermissionMessage());
-                        return true;
-                    }
-
-                    return acceptTeleportRequest();
-                }
-
-                return sendTeleportRequest(args[0]);
-
-            default:
-                return false;
-        }
-    }
-
-    private boolean sendTeleportRequest(String targetName) {
-        if (!canTeleport(targetName)) {
-            return true;
-        }
-
-        if (!mcMMOTarget.getPtpConfirmRequired()) {
-            return handlePartyTeleportEvent(player, target);
-        }
-
-        mcMMOTarget.setPtpRequest(player);
-        mcMMOTarget.actualizePtpTimeout();
-        player.sendMessage(LocaleLoader.getString("Commands.Invite.Success"));
-
-        int ptpRequestExpire = Config.getInstance().getPTPCommandTimeout();
-
-        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request1", player.getName()));
-        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", ptpRequestExpire));
-        return true;
-    }
-
-    private boolean acceptTeleportRequest() {
-        if (!mcMMOPlayer.hasPtpRequest()) {
-            player.sendMessage(LocaleLoader.getString("Commands.ptp.NoRequests"));
-            return true;
-        }
-
-        int ptpRequestExpire = Config.getInstance().getPTPCommandTimeout();
-
-        if ((mcMMOPlayer.getPtpTimeout() + ptpRequestExpire) * Misc.TIME_CONVERSION_FACTOR < System.currentTimeMillis()) {
-            mcMMOPlayer.removePtpRequest();
-            player.sendMessage(LocaleLoader.getString("Commands.ptp.RequestExpired"));
-            return true;
-        }
-
-        target = mcMMOPlayer.getPtpRequest();
-        mcMMOPlayer.removePtpRequest();
-
-        if (!canTeleport(target.getName())) {
-            return true;
-        }
-
-        if (Config.getInstance().getPTPCommandWorldPermissions()) {
-            World targetWorld = target.getWorld();
-            World playerWorld = player.getWorld();
-
-            if (!Permissions.partyTeleportAllWorlds(target)) {
-                if (!Permissions.partyTeleportWorld(target, targetWorld)) {
-                    target.sendMessage(LocaleLoader.getString("Commands.ptp.NoWorldPermissions", targetWorld.getName()));
-                    return true;
-                }
-                else if (targetWorld != playerWorld && !Permissions.partyTeleportWorld(target, playerWorld)) {
-                    target.sendMessage(LocaleLoader.getString("Commands.ptp.NoWorldPermissions", playerWorld.getName()));
-                    return true;
-                }
-            }
-        }
-
-        return handlePartyTeleportEvent(target, player);
-    }
-
-    private boolean acceptAnyTeleportRequest() {
-        if (mcMMOPlayer.getPtpConfirmRequired()) {
-            player.sendMessage(LocaleLoader.getString("Commands.ptp.AcceptAny.Disabled"));
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Commands.ptp.AcceptAny.Enabled"));
-        }
-
-        mcMMOPlayer.togglePtpConfirmRequired();
-        return true;
-    }
-
-    private boolean togglePartyTeleportation() {
-        if (mcMMOPlayer.getPtpEnabled()) {
-            player.sendMessage(LocaleLoader.getString("Commands.ptp.Disabled"));
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Commands.ptp.Enabled"));
-        }
-
-        mcMMOPlayer.togglePtpUse();
-        return true;
-    }
-
-    private boolean canTeleport(String targetName) {
-        if (!mcMMO.p.getServer().getOfflinePlayer(targetName).isOnline()) {
-            player.sendMessage(LocaleLoader.getString("Party.NotOnline", targetName));
-            return false;
-        }
-
-        mcMMOTarget = UserManager.getPlayer(targetName);
-
-        if (mcMMOTarget == null) {
-            player.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
-            return false;
-        }
-
-        target = mcMMOTarget.getPlayer();
-
-        if (player.equals(target)) {
-            player.sendMessage(LocaleLoader.getString("Party.Teleport.Self"));
-            return false;
-        }
-
-        if (!PartyManager.inSameParty(player, target)) {
-            player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetName));
-            return false;
-        }
-
-        if (!mcMMOTarget.getPtpEnabled()) {
-            player.sendMessage(LocaleLoader.getString("Party.Teleport.Disabled", target.getName()));
-            return false;
-        }
-
-        if (target.isDead()) {
-            player.sendMessage(LocaleLoader.getString("Party.Teleport.Dead"));
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean handlePartyTeleportEvent(Player player, Player target) {
-        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
-        McMMOPartyTeleportEvent event = new McMMOPartyTeleportEvent(player, target, mcMMOPlayer.getParty().getName());
-
-        mcMMO.p.getServer().getPluginManager().callEvent(event);
-
-        if (event.isCancelled()) {
-            return true;
-        }
-
-        player.teleport(target);
-        player.sendMessage(LocaleLoader.getString("Party.Teleport.Player", target.getName()));
-        target.sendMessage(LocaleLoader.getString("Party.Teleport.Target", player.getName()));
-        mcMMOPlayer.actualizeRecentlyHurt();
-        return true;
-    }
-}

+ 34 - 0
src/main/java/com/gmail/nossr50/commands/party/teleport/PtpAcceptAnyCommand.java

@@ -0,0 +1,34 @@
+package com.gmail.nossr50.commands.party.teleport;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+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.util.Permissions;
+import com.gmail.nossr50.util.player.UserManager;
+
+public class PtpAcceptAnyCommand implements CommandExecutor {
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Permissions.partyTeleportAcceptAll(sender)) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
+        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+        Player player = mcMMOPlayer.getPlayer();
+
+        if (mcMMOPlayer.getPtpConfirmRequired()) {
+            player.sendMessage(LocaleLoader.getString("Commands.ptp.AcceptAny.Disabled"));
+        }
+        else {
+            player.sendMessage(LocaleLoader.getString("Commands.ptp.AcceptAny.Enabled"));
+        }
+
+        mcMMOPlayer.togglePtpConfirmRequired();
+        return true;
+    }
+}

+ 64 - 0
src/main/java/com/gmail/nossr50/commands/party/teleport/PtpAcceptCommand.java

@@ -0,0 +1,64 @@
+package com.gmail.nossr50.commands.party.teleport;
+
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.player.UserManager;
+
+public class PtpAcceptCommand implements CommandExecutor {
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Permissions.partyTeleportAccept(sender)) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
+        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+        Player player = mcMMOPlayer.getPlayer();
+
+        if (!mcMMOPlayer.hasPtpRequest()) {
+            player.sendMessage(LocaleLoader.getString("Commands.ptp.NoRequests"));
+            return true;
+        }
+
+        if ((mcMMOPlayer.getPtpTimeout() + Config.getInstance().getPTPCommandTimeout()) * Misc.TIME_CONVERSION_FACTOR < System.currentTimeMillis()) {
+            mcMMOPlayer.removePtpRequest();
+            player.sendMessage(LocaleLoader.getString("Commands.ptp.RequestExpired"));
+            return true;
+        }
+
+        Player target = mcMMOPlayer.getPtpRequest();
+        mcMMOPlayer.removePtpRequest();
+
+        if (!PtpCommand.canTeleport(sender, player, target.getName())) {
+            return true;
+        }
+
+        if (Config.getInstance().getPTPCommandWorldPermissions()) {
+            World targetWorld = target.getWorld();
+            World playerWorld = player.getWorld();
+
+            if (!Permissions.partyTeleportAllWorlds(target)) {
+                if (!Permissions.partyTeleportWorld(target, targetWorld)) {
+                    target.sendMessage(LocaleLoader.getString("Commands.ptp.NoWorldPermissions", targetWorld.getName()));
+                    return true;
+                }
+                else if (targetWorld != playerWorld && !Permissions.partyTeleportWorld(target, playerWorld)) {
+                    target.sendMessage(LocaleLoader.getString("Commands.ptp.NoWorldPermissions", playerWorld.getName()));
+                    return true;
+                }
+            }
+        }
+
+        PtpCommand.handlePartyTeleportEvent(target, player);
+        return true;
+    }
+}

+ 133 - 0
src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java

@@ -0,0 +1,133 @@
+package com.gmail.nossr50.commands.party.teleport;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.events.party.McMMOPartyTeleportEvent;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.PartyManager;
+import com.gmail.nossr50.util.Misc;
+import com.gmail.nossr50.util.commands.CommandUtils;
+import com.gmail.nossr50.util.player.UserManager;
+
+public class PtpCommand implements CommandExecutor {
+    private static Player target;
+    private static McMMOPlayer mcMMOTarget;
+
+    private CommandExecutor ptpToggleCommand = new PtpToggleCommand();
+    private CommandExecutor ptpAcceptAnyCommand = new PtpAcceptAnyCommand();
+    private CommandExecutor ptpAcceptCommand = new PtpAcceptCommand();
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (CommandUtils.noConsoleUsage(sender)) {
+            return true;
+        }
+
+        switch (args.length) {
+            case 1:
+                if (args[0].equalsIgnoreCase("toggle")) {
+                    return ptpToggleCommand.onCommand(sender, command, label, args);
+                }
+
+                if (args[0].equalsIgnoreCase("acceptany") || args[0].equalsIgnoreCase("acceptall")) {
+                    return ptpAcceptAnyCommand.onCommand(sender, command, label, args);
+                }
+
+                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                Player player = mcMMOPlayer.getPlayer();
+
+                int ptpCooldown = Config.getInstance().getPTPCommandCooldown();
+                long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
+
+                if (((recentlyHurt * Misc.TIME_CONVERSION_FACTOR) + (ptpCooldown * Misc.TIME_CONVERSION_FACTOR)) > System.currentTimeMillis()) {
+                    player.sendMessage(LocaleLoader.getString("Party.Teleport.Hurt", ptpCooldown));
+                    return true;
+                }
+
+                if (args[0].equalsIgnoreCase("accept")) {
+                    return ptpAcceptCommand.onCommand(sender, command, label, args);
+                }
+
+                sendTeleportRequest(sender, player, args[0]);
+                return true;
+
+            default:
+                return false;
+        }
+    }
+
+    private void sendTeleportRequest(CommandSender sender, Player player, String targetName) {
+        if (!canTeleport(sender, player, targetName)) {
+            return;
+        }
+
+        if (!mcMMOTarget.getPtpConfirmRequired()) {
+            handlePartyTeleportEvent(player, target);
+            return;
+        }
+
+        mcMMOTarget.setPtpRequest(player);
+        mcMMOTarget.actualizePtpTimeout();
+
+        player.sendMessage(LocaleLoader.getString("Commands.Invite.Success"));
+
+        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request1", player.getName()));
+        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", Config.getInstance().getPTPCommandTimeout()));
+    }
+
+    protected static boolean canTeleport(CommandSender sender, Player player, String targetName) {
+        mcMMOTarget = UserManager.getPlayer(targetName);
+
+        if (CommandUtils.checkPlayerExistence(sender, targetName, mcMMOTarget)) {
+            return false;
+        }
+
+        target = mcMMOTarget.getPlayer();
+
+        if (player.equals(target)) {
+            player.sendMessage(LocaleLoader.getString("Party.Teleport.Self"));
+            return false;
+        }
+
+        if (!PartyManager.inSameParty(player, target)) {
+            player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetName));
+            return false;
+        }
+
+        if (!mcMMOTarget.getPtpEnabled()) {
+            player.sendMessage(LocaleLoader.getString("Party.Teleport.Disabled", targetName));
+            return false;
+        }
+
+        if (!target.isValid()) {
+            player.sendMessage(LocaleLoader.getString("Party.Teleport.Dead"));
+            return false;
+        }
+
+        return true;
+    }
+
+    protected static void handlePartyTeleportEvent(Player teleportingPlayer, Player targetPlayer) {
+        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
+        McMMOPartyTeleportEvent event = new McMMOPartyTeleportEvent(teleportingPlayer, targetPlayer, mcMMOPlayer.getParty().getName());
+
+        mcMMO.p.getServer().getPluginManager().callEvent(event);
+
+        if (event.isCancelled()) {
+            return;
+        }
+
+        teleportingPlayer.teleport(targetPlayer);
+
+        teleportingPlayer.sendMessage(LocaleLoader.getString("Party.Teleport.Player", targetPlayer.getName()));
+        targetPlayer.sendMessage(LocaleLoader.getString("Party.Teleport.Target", teleportingPlayer.getName()));
+
+        mcMMOPlayer.actualizeRecentlyHurt();
+    }
+}

+ 34 - 0
src/main/java/com/gmail/nossr50/commands/party/teleport/PtpToggleCommand.java

@@ -0,0 +1,34 @@
+package com.gmail.nossr50.commands.party.teleport;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+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.util.Permissions;
+import com.gmail.nossr50.util.player.UserManager;
+
+public class PtpToggleCommand implements CommandExecutor {
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Permissions.partyTeleportToggle(sender)) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
+        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+        Player player = mcMMOPlayer.getPlayer();
+
+        if (mcMMOPlayer.getPtpEnabled()) {
+            player.sendMessage(LocaleLoader.getString("Commands.ptp.Disabled"));
+        }
+        else {
+            player.sendMessage(LocaleLoader.getString("Commands.ptp.Enabled"));
+        }
+
+        mcMMOPlayer.togglePtpUse();
+        return true;
+    }
+}

+ 19 - 35
src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java

@@ -9,7 +9,6 @@ import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
-import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
@@ -17,64 +16,49 @@ import com.gmail.nossr50.util.player.UserManager;
 public class InspectCommand implements CommandExecutor {
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        PlayerProfile profile;
-
         switch (args.length) {
             case 1:
                 McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
 
                 // If the mcMMOPlayer doesn't exist, create a temporary profile and check if it's present in the database. If it's not, abort the process.
                 if (mcMMOPlayer == null) {
-                    profile = new PlayerProfile(args[0], false); // Temporary Profile
-
-                    if (!profile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
+                    PlayerProfile profile = new PlayerProfile(args[0], false); // Temporary Profile
 
-                    // TODO: Why do we care if this is a player?
-                    if (sender instanceof Player && !Permissions.inspectOffline(sender)) {
-                        sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
+                    if (CommandUtils.inspectOffline(sender, profile, Permissions.inspectOffline(sender))) {
                         return true;
                     }
 
                     sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", args[0]));
 
                     sender.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Excavation.Listener"), profile.getSkillLevel(SkillType.EXCAVATION), profile.getSkillXpLevel(SkillType.EXCAVATION), profile.getXpToLevel(SkillType.EXCAVATION)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Fishing.Listener"), profile.getSkillLevel(SkillType.FISHING), profile.getSkillXpLevel(SkillType.FISHING), profile.getXpToLevel(SkillType.FISHING)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Herbalism.Listener"), profile.getSkillLevel(SkillType.HERBALISM), profile.getSkillXpLevel(SkillType.HERBALISM), profile.getXpToLevel(SkillType.HERBALISM)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Mining.Listener"), profile.getSkillLevel(SkillType.MINING), profile.getSkillXpLevel(SkillType.MINING), profile.getXpToLevel(SkillType.MINING)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Woodcutting.Listener"), profile.getSkillLevel(SkillType.WOODCUTTING), profile.getSkillXpLevel(SkillType.WOODCUTTING), profile.getXpToLevel(SkillType.WOODCUTTING)));
+                    CommandUtils.displaySkill(sender, profile, SkillType.EXCAVATION);
+                    CommandUtils.displaySkill(sender, profile, SkillType.FISHING);
+                    CommandUtils.displaySkill(sender, profile, SkillType.HERBALISM);
+                    CommandUtils.displaySkill(sender, profile, SkillType.MINING);
+                    CommandUtils.displaySkill(sender, profile, SkillType.WOODCUTTING);
 
                     sender.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Axes.Listener"), profile.getSkillLevel(SkillType.AXES), profile.getSkillXpLevel(SkillType.AXES), profile.getXpToLevel(SkillType.AXES)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Archery.Listener"), profile.getSkillLevel(SkillType.ARCHERY), profile.getSkillXpLevel(SkillType.ARCHERY), profile.getXpToLevel(SkillType.ARCHERY)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Swords.Listener"), profile.getSkillLevel(SkillType.SWORDS), profile.getSkillXpLevel(SkillType.SWORDS), profile.getXpToLevel(SkillType.SWORDS)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Taming.Listener"), profile.getSkillLevel(SkillType.TAMING), profile.getSkillXpLevel(SkillType.TAMING), profile.getXpToLevel(SkillType.TAMING)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Unarmed.Listener"), profile.getSkillLevel(SkillType.UNARMED), profile.getSkillXpLevel(SkillType.UNARMED), profile.getXpToLevel(SkillType.UNARMED)));
+                    CommandUtils.displaySkill(sender, profile, SkillType.AXES);
+                    CommandUtils.displaySkill(sender, profile, SkillType.ARCHERY);
+                    CommandUtils.displaySkill(sender, profile, SkillType.SWORDS);
+                    CommandUtils.displaySkill(sender, profile, SkillType.TAMING);
+                    CommandUtils.displaySkill(sender, profile, SkillType.UNARMED);
 
                     sender.sendMessage(LocaleLoader.getString("Stats.Header.Misc"));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Acrobatics.Listener"), profile.getSkillLevel(SkillType.ACROBATICS), profile.getSkillXpLevel(SkillType.ACROBATICS), profile.getXpToLevel(SkillType.ACROBATICS)));
-                    sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Repair.Listener"), profile.getSkillLevel(SkillType.REPAIR), profile.getSkillXpLevel(SkillType.REPAIR), profile.getXpToLevel(SkillType.REPAIR)));
+                    CommandUtils.displaySkill(sender, profile, SkillType.ACROBATICS);
+                    CommandUtils.displaySkill(sender, profile, SkillType.REPAIR);
                 }
                 else {
                     Player target = mcMMOPlayer.getPlayer();
 
-                    if (sender instanceof Player) {
-                        Player inspector = (Player) sender;
-
-                        if (!Misc.isNear(inspector.getLocation(), target.getLocation(), 5.0) && !Permissions.inspectFar(inspector)) {
-                            sender.sendMessage(LocaleLoader.getString("Inspect.TooFar"));
-                            return true;
-                        }
+                    if (CommandUtils.tooFar(sender, target, Permissions.inspectFar(sender))) {
+                        return true;
                     }
-                    profile = mcMMOPlayer.getProfile();
 
                     sender.sendMessage(LocaleLoader.getString("Inspect.Stats", target.getName()));
-                    CommandUtils.printGatheringSkills(target, profile, sender);
-                    CommandUtils.printCombatSkills(target, profile, sender);
-                    CommandUtils.printMiscSkills(target, profile, sender);
+                    CommandUtils.printGatheringSkills(target, sender);
+                    CommandUtils.printCombatSkills(target, sender);
+                    CommandUtils.printMiscSkills(target, sender);
                     sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel", mcMMOPlayer.getPowerLevel()));
                 }
 

+ 9 - 23
src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java

@@ -3,7 +3,6 @@ package com.gmail.nossr50.commands.player;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
@@ -13,8 +12,8 @@ import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.runnables.commands.McrankCommandAsyncTask;
-import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
@@ -23,8 +22,8 @@ public class McrankCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
             case 0:
-                if (!(sender instanceof Player)) {
-                    return false;
+                if (CommandUtils.noConsoleUsage(sender)) {
+                    return true;
                 }
 
                 if (!Permissions.mcrank(sender)) {
@@ -36,7 +35,6 @@ public class McrankCommand implements CommandExecutor {
                     sqlDisplay(sender, sender.getName());
                 }
                 else {
-                    LeaderboardManager.updateLeaderboards(); // Make sure the information is up to date
                     flatfileDisplay(sender, sender.getName());
                 }
 
@@ -51,32 +49,18 @@ public class McrankCommand implements CommandExecutor {
                 McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]);
 
                 if (mcMMOPlayer == null) {
-                    PlayerProfile profile = new PlayerProfile(args[0], false); // Temporary Profile
-
-                    if (!profile.isLoaded()) {
-                        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-                        return true;
-                    }
-
-                    if (sender instanceof Player && !Permissions.mcrankOffline(sender)) {
-                        sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
+                    if (CommandUtils.inspectOffline(sender, new PlayerProfile(args[0], false), Permissions.mcrankOffline(sender))) {
                         return true;
                     }
                 }
-                else {
-                    Player target = mcMMOPlayer.getPlayer();
-
-                    if (sender instanceof Player && !Misc.isNear(((Player) sender).getLocation(), target.getLocation(), 5.0) && !Permissions.mcrankFar(sender)) {
-                        sender.sendMessage(LocaleLoader.getString("Inspect.TooFar"));
-                        return true;
-                    }
+                else if (CommandUtils.tooFar(sender, mcMMOPlayer.getPlayer(), Permissions.mcrankFar(sender))) {
+                    return true;
                 }
 
                 if (Config.getInstance().getUseMySQL()) {
                     sqlDisplay(sender, args[0]);
                 }
                 else {
-                    LeaderboardManager.updateLeaderboards(); // Make sure the information is up to date
                     flatfileDisplay(sender, args[0]);
                 }
 
@@ -88,13 +72,15 @@ public class McrankCommand implements CommandExecutor {
     }
 
     private void flatfileDisplay(CommandSender sender, String playerName) {
+        LeaderboardManager.updateLeaderboards(); // Make sure the information is up to date
+
         sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
         sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
 
         for (SkillType skillType : SkillType.values()) {
             int[] rankInts = LeaderboardManager.getPlayerRank(playerName, skillType);
 
-            if ((sender instanceof Player && !Permissions.skillEnabled(sender, skillType)) || skillType.isChildSkill()) {
+            if (!Permissions.skillEnabled(sender, skillType) || skillType.isChildSkill()) {
                 continue;
             }
 

+ 7 - 9
src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java

@@ -7,7 +7,6 @@ import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
-import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
@@ -21,24 +20,23 @@ public class McstatsCommand implements CommandExecutor {
 
         switch (args.length) {
             case 0:
-                Player player = (Player) sender;
-                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
-                PlayerProfile profile = mcMMOPlayer.getProfile();
+                McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
+                Player player = mcMMOPlayer.getPlayer();
 
                 player.sendMessage(LocaleLoader.getString("Stats.Own.Stats"));
                 player.sendMessage(LocaleLoader.getString("mcMMO.NoSkillNote"));
 
-                CommandUtils.printGatheringSkills(player, profile);
-                CommandUtils.printCombatSkills(player, profile);
-                CommandUtils.printMiscSkills(player, profile);
+                CommandUtils.printGatheringSkills(player);
+                CommandUtils.printCombatSkills(player);
+                CommandUtils.printMiscSkills(player);
 
                 int powerLevelCap = Config.getInstance().getPowerLevelCap();
 
                 if (powerLevelCap != Integer.MAX_VALUE) {
-                    player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", mcMMOPlayer.getPowerLevel(), powerLevelCap));
+                    player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));
                 }
                 else {
-                    player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", mcMMOPlayer.getPowerLevel()));
+                    player.sendMessage(LocaleLoader.getString("Commands.PowerLevel", UserManager.getPlayer(player).getPowerLevel()));
                 }
 
                 return true;

+ 42 - 40
src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java

@@ -13,13 +13,16 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.runnables.commands.MctopCommandAsyncTask;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
-import com.gmail.nossr50.util.skills.SkillUtils;
+import com.gmail.nossr50.util.commands.CommandUtils;
 
 public class MctopCommand implements CommandExecutor {
+    private SkillType skill;
+
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         boolean useMySQL = Config.getInstance().getUseMySQL();
 
+
         switch (args.length) {
             case 0:
                 display(1, "ALL", sender, useMySQL, command);
@@ -28,42 +31,26 @@ public class MctopCommand implements CommandExecutor {
             case 1:
                 if (StringUtils.isInt(args[0])) {
                     display(Integer.parseInt(args[0]), "ALL", sender, useMySQL, command);
+                    return true;
                 }
-                else if (SkillUtils.isSkill(args[0])) {
-                    SkillType skill = SkillType.getSkill(args[0]);
-
-                    if (skill.isChildSkill()) {
-                        sender.sendMessage("Child skills are not yet supported by this command."); // TODO: Localize this
-                        return true;
-                    }
 
-                    display(1, skill.toString(), sender, useMySQL, command);
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
+                if (!extractSkill(sender, args[0])) {
+                    return true;
                 }
 
+                display(1, skill.toString(), sender, useMySQL, command);
                 return true;
 
             case 2:
-                if (!StringUtils.isInt(args[1])) {
-                    return false;
+                if (CommandUtils.isInvalidInteger(sender, args[1])) {
+                    return true;
                 }
 
-                if (SkillUtils.isSkill(args[0])) {
-                    SkillType skill = SkillType.getSkill(args[0]);
-
-                    if (skill.isChildSkill()) {
-                        sender.sendMessage("Child skills are not yet supported by this command."); // TODO: Localize this
-                        return true;
-                    }
-
-                    display(Integer.parseInt(args[1]), skill.toString(), sender, useMySQL, command);
-                }
-                else {
-                    sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
+                if (!extractSkill(sender, args[0])) {
+                    return true;
                 }
 
+                display(Integer.parseInt(args[1]), skill.toString(), sender, useMySQL, command);
                 return true;
 
             default:
@@ -72,7 +59,7 @@ public class MctopCommand implements CommandExecutor {
     }
 
     private void display(int page, String skill, CommandSender sender, boolean sql, Command command) {
-        if (!skill.equalsIgnoreCase("all") && !Permissions.mctop(sender, SkillType.getSkill(skill))) {
+        if (!skill.equalsIgnoreCase("all") && !Permissions.mctop(sender, this.skill)) {
             sender.sendMessage(command.getPermissionMessage());
             return;
         }
@@ -93,8 +80,6 @@ public class MctopCommand implements CommandExecutor {
     private void flatfileDisplay(int page, String skill, CommandSender sender) {
         LeaderboardManager.updateLeaderboards(); // Make sure we have the latest information
 
-        String[] info = LeaderboardManager.retrieveInfo(skill, page);
-
         if (skill.equalsIgnoreCase("all")) {
             sender.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Leaderboard"));
         }
@@ -102,21 +87,24 @@ public class MctopCommand implements CommandExecutor {
             sender.sendMessage(LocaleLoader.getString("Commands.Skill.Leaderboard", StringUtils.getCapitalized(skill)));
         }
 
-        int n = (page * 10) - 9; // Position
-        for (String x : info) {
-            if (x != null) {
-                String digit = String.valueOf(n);
+        int position = (page * 10) - 9;
 
-                if (n < 10) {
-                    digit = "0" + digit;
-                }
+        for (String playerStat : LeaderboardManager.retrieveInfo(skill, page)) {
+            if (playerStat == null) {
+                continue;
+            }
 
-                String[] splitx = x.split(":");
+            String digit = String.valueOf(position);
 
-                // Format: 1. Playername - skill value
-                sender.sendMessage(digit + ". " + ChatColor.GREEN + splitx[1] + " - " + ChatColor.WHITE + splitx[0]);
-                n++;
+            if (position < 10) {
+                digit = "0" + digit;
             }
+
+            String[] splitStat = playerStat.split(":");
+
+            // Format: 1. Playername - skill value
+            sender.sendMessage(digit + ". " + ChatColor.GREEN + splitStat[1] + " - " + ChatColor.WHITE + splitStat[0]);
+            position++;
         }
 
         sender.sendMessage(LocaleLoader.getString("Commands.mctop.Tip"));
@@ -125,4 +113,18 @@ public class MctopCommand implements CommandExecutor {
     private void sqlDisplay(int page, String query, CommandSender sender) {
         mcMMO.p.getServer().getScheduler().runTaskAsynchronously(mcMMO.p, new MctopCommandAsyncTask(page, query, sender));
     }
+
+    private boolean extractSkill(CommandSender sender, String skillName) {
+        if (CommandUtils.isInvalidSkill(sender, skillName)) {
+            return false;
+        }
+
+        skill = SkillType.getSkill(skillName);
+
+        if (CommandUtils.isChildSkill(sender, skill)) {
+            return true;
+        }
+
+        return true;
+    }
 }

+ 18 - 27
src/main/java/com/gmail/nossr50/commands/skills/AcrobaticsCommand.java

@@ -24,19 +24,25 @@ public class AcrobaticsCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // DODGE
-        String[] dodgeStrings = calculateAbilityDisplayValues(Acrobatics.dodgeMaxBonusLevel, Acrobatics.dodgeMaxChance);
-        dodgeChance = dodgeStrings[0];
-        dodgeChanceLucky = dodgeStrings[1];
+        if (canDodge) {
+            String[] dodgeStrings = calculateAbilityDisplayValues(Acrobatics.dodgeMaxBonusLevel, Acrobatics.dodgeMaxChance);
+            dodgeChance = dodgeStrings[0];
+            dodgeChanceLucky = dodgeStrings[1];
+        }
 
         // ROLL
-        String[] rollStrings = calculateAbilityDisplayValues(Acrobatics.rollMaxBonusLevel, Acrobatics.rollMaxChance);
-        rollChance = rollStrings[0];
-        rollChanceLucky = rollStrings[1];
+        if (canRoll) {
+            String[] rollStrings = calculateAbilityDisplayValues(Acrobatics.rollMaxBonusLevel, Acrobatics.rollMaxChance);
+            rollChance = rollStrings[0];
+            rollChanceLucky = rollStrings[1];
+        }
 
         // GRACEFUL ROLL
-        String[] gracefulRollStrings = calculateAbilityDisplayValues(Acrobatics.gracefulRollMaxBonusLevel, Acrobatics.gracefulRollMaxChance);
-        gracefulRollChance = gracefulRollStrings[0];
-        gracefulRollChanceLucky = gracefulRollStrings[1];
+        if (canGracefulRoll) {
+            String[] gracefulRollStrings = calculateAbilityDisplayValues(Acrobatics.gracefulRollMaxBonusLevel, Acrobatics.gracefulRollMaxChance);
+            gracefulRollChance = gracefulRollStrings[0];
+            gracefulRollChanceLucky = gracefulRollStrings[1];
+        }
     }
 
     @Override
@@ -76,30 +82,15 @@ public class AcrobaticsCommand extends SkillCommand {
     @Override
     protected void statsDisplay() {
         if (canRoll) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Chance", new Object[] { rollChance }) + LocaleLoader.getString("Perks.lucky.bonus", new Object[] { rollChanceLucky }));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Chance", new Object[] { rollChance }));
-            }
+            player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.Chance", rollChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", rollChanceLucky) : ""));
         }
 
         if (canGracefulRoll) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.GraceChance", new Object[] { gracefulRollChance }) + LocaleLoader.getString("Perks.lucky.bonus", new Object[] { gracefulRollChanceLucky }));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.GraceChance", new Object[] { gracefulRollChance }));
-            }
+            player.sendMessage(LocaleLoader.getString("Acrobatics.Roll.GraceChance", gracefulRollChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", gracefulRollChanceLucky) : ""));
         }
 
         if (canDodge) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Acrobatics.DodgeChance", new Object[] { dodgeChance }) + LocaleLoader.getString("Perks.lucky.bonus", new Object[] { dodgeChanceLucky }));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Acrobatics.DodgeChance", new Object[] { dodgeChance }));
-            }
+            player.sendMessage(LocaleLoader.getString("Acrobatics.DodgeChance", dodgeChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", dodgeChanceLucky) : ""));
         }
     }
 }

+ 15 - 25
src/main/java/com/gmail/nossr50/commands/skills/ArcheryCommand.java

@@ -23,24 +23,24 @@ public class ArcheryCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // SKILL SHOT
-        double bonus = (skillValue / Archery.skillShotIncreaseLevel) * Archery.skillShotIncreasePercentage;
-
-        if (bonus > Archery.skillShotMaxBonusPercentage) {
-            skillShotBonus = percent.format(Archery.skillShotMaxBonusPercentage);
-        }
-        else {
-            skillShotBonus = percent.format(bonus);
+        if (canSkillShot) {
+            double bonus = (skillValue / Archery.skillShotIncreaseLevel) * Archery.skillShotIncreasePercentage;
+            skillShotBonus = percent.format(Math.min(bonus, Archery.skillShotMaxBonusPercentage));
         }
 
         // DAZE
-        String[] dazeStrings = calculateAbilityDisplayValues(Archery.dazeMaxBonusLevel, Archery.dazeMaxBonus);
-        dazeChance = dazeStrings[0];
-        dazeChanceLucky = dazeStrings[1];
+        if (canDaze) {
+            String[] dazeStrings = calculateAbilityDisplayValues(Archery.dazeMaxBonusLevel, Archery.dazeMaxBonus);
+            dazeChance = dazeStrings[0];
+            dazeChanceLucky = dazeStrings[1];
+        }
 
         // RETRIEVE
-        String[] retrieveStrings = calculateAbilityDisplayValues(Archery.retrieveMaxBonusLevel, Archery.retrieveMaxChance);
-        retrieveChance = retrieveStrings[0];
-        retrieveChanceLucky = retrieveStrings[1];
+        if (canRetrieve) {
+            String[] retrieveStrings = calculateAbilityDisplayValues(Archery.retrieveMaxBonusLevel, Archery.retrieveMaxChance);
+            retrieveChance = retrieveStrings[0];
+            retrieveChanceLucky = retrieveStrings[1];
+        }
     }
 
     @Override
@@ -84,21 +84,11 @@ public class ArcheryCommand extends SkillCommand {
         }
 
         if (canDaze) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Archery.Combat.DazeChance", dazeChance) + LocaleLoader.getString("Perks.lucky.bonus", dazeChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Archery.Combat.DazeChance", dazeChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Archery.Combat.DazeChance", dazeChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", dazeChanceLucky) : ""));
         }
 
         if (canRetrieve) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Archery.Combat.RetrieveChance", retrieveChance) + LocaleLoader.getString("Perks.lucky.bonus", retrieveChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Archery.Combat.RetrieveChance", retrieveChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Archery.Combat.RetrieveChance", retrieveChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", retrieveChanceLucky) : ""));
         }
     }
 }

+ 20 - 29
src/main/java/com/gmail/nossr50/commands/skills/AxesCommand.java

@@ -8,9 +8,8 @@ import com.gmail.nossr50.util.Permissions;
 public class AxesCommand extends SkillCommand {
     private String critChance;
     private String critChanceLucky;
-    private String bonusDamage;
-    private String impactDamage;
-    private String greaterImpactDamage;
+    private float bonusDamage;
+    private float impactDamage;
     private String skullSplitterLength;
     private String skullSplitterLengthEndurance;
 
@@ -27,25 +26,27 @@ public class AxesCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // IMPACT
-        impactDamage = String.valueOf(1 + (skillValue / Axes.impactIncreaseLevel));
-        greaterImpactDamage = String.valueOf(Axes.greaterImpactBonusDamage);
+        if (canImpact) {
+            impactDamage = 1 + (skillValue / Axes.impactIncreaseLevel);
+        }
 
         // SKULL SPLITTER
-        String[] skullSplitterStrings = calculateLengthDisplayValues();
-        skullSplitterLength = skullSplitterStrings[0];
-        skullSplitterLengthEndurance = skullSplitterStrings[1];
+        if (canSkullSplitter) {
+            String[] skullSplitterStrings = calculateLengthDisplayValues();
+            skullSplitterLength = skullSplitterStrings[0];
+            skullSplitterLengthEndurance = skullSplitterStrings[1];
+        }
 
         // CRITICAL STRIKES
-        String[] criticalStrikeStrings = calculateAbilityDisplayValues(Axes.criticalHitMaxBonusLevel, Axes.criticalHitMaxChance);
-        critChance = criticalStrikeStrings[0];
-        critChanceLucky = criticalStrikeStrings[1];
+        if (canCritical) {
+            String[] criticalStrikeStrings = calculateAbilityDisplayValues(Axes.criticalHitMaxBonusLevel, Axes.criticalHitMaxChance);
+            critChance = criticalStrikeStrings[0];
+            critChanceLucky = criticalStrikeStrings[1];
+        }
 
         // AXE MASTERY
-        if (skillValue >= Axes.bonusDamageMaxBonusLevel) {
-            bonusDamage = String.valueOf(Axes.bonusDamageMaxBonus);
-        }
-        else {
-            bonusDamage = String.valueOf(skillValue / (Axes.bonusDamageMaxBonusLevel / Axes.bonusDamageMaxBonus));
+        if (canBonusDamage) {
+            bonusDamage = Math.min(skillValue / (Axes.bonusDamageMaxBonusLevel / Axes.bonusDamageMaxBonus), Axes.bonusDamageMaxBonus);
         }
     }
 
@@ -104,25 +105,15 @@ public class AxesCommand extends SkillCommand {
         }
 
         if (canGreaterImpact) {
-            player.sendMessage(LocaleLoader.getString("Ability.Generic.Template", LocaleLoader.getString("Axes.Ability.Bonus.4"), LocaleLoader.getString("Axes.Ability.Bonus.5", greaterImpactDamage)));
+            player.sendMessage(LocaleLoader.getString("Ability.Generic.Template", LocaleLoader.getString("Axes.Ability.Bonus.4"), LocaleLoader.getString("Axes.Ability.Bonus.5", Axes.greaterImpactBonusDamage)));
         }
 
         if (canCritical) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Axes.Combat.CritChance", critChance) + LocaleLoader.getString("Perks.lucky.bonus", critChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Axes.Combat.CritChance", critChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Axes.Combat.CritChance", critChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", critChanceLucky) : ""));
         }
 
         if (canSkullSplitter) {
-            if (hasEndurance) {
-                player.sendMessage(LocaleLoader.getString("Axes.Combat.SS.Length", skullSplitterLength) + LocaleLoader.getString("Perks.activationtime.bonus", skullSplitterLengthEndurance));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Axes.Combat.SS.Length", skullSplitterLength));
-            }
+            player.sendMessage(LocaleLoader.getString("Axes.Combat.SS.Length", skullSplitterLength) + (hasEndurance ? LocaleLoader.getString("Perks.activationtime.bonus", skullSplitterLengthEndurance) : ""));
         }
     }
 }

+ 6 - 9
src/main/java/com/gmail/nossr50/commands/skills/ExcavationCommand.java

@@ -18,9 +18,11 @@ public class ExcavationCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // GIGA DRILL BREAKER
-        String gigaDrillStrings[] = calculateLengthDisplayValues();
-        gigaDrillBreakerLength = gigaDrillStrings[0];
-        gigaDrillBreakerLengthEndurance = gigaDrillStrings[1];
+        if (canGigaDrill) {
+            String gigaDrillStrings[] = calculateLengthDisplayValues();
+            gigaDrillBreakerLength = gigaDrillStrings[0];
+            gigaDrillBreakerLengthEndurance = gigaDrillStrings[1];
+        }
     }
 
     @Override
@@ -55,12 +57,7 @@ public class ExcavationCommand extends SkillCommand {
     @Override
     protected void statsDisplay() {
         if (canGigaDrill) {
-            if (hasEndurance) {
-                player.sendMessage(LocaleLoader.getString("Excavation.Effect.Length", gigaDrillBreakerLength) + LocaleLoader.getString("Perks.activationtime.bonus", gigaDrillBreakerLengthEndurance));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Excavation.Effect.Length", gigaDrillBreakerLength));
-            }
+            player.sendMessage(LocaleLoader.getString("Excavation.Effect.Length", gigaDrillBreakerLength) + (hasEndurance ? LocaleLoader.getString("Perks.activationtime.bonus", gigaDrillBreakerLengthEndurance) : ""));
         }
     }
 }

+ 26 - 29
src/main/java/com/gmail/nossr50/commands/skills/FishingCommand.java

@@ -14,7 +14,7 @@ public class FishingCommand extends SkillCommand {
     private String chanceRaining = "";
     private String shakeChance;
     private String shakeChanceLucky;
-    private String fishermansDietRank;
+    private int fishermansDietRank;
 
     private boolean canTreasureHunt;
     private boolean canMagicHunt;
@@ -27,27 +27,32 @@ public class FishingCommand extends SkillCommand {
 
     @Override
     protected void dataCalculations() {
-        lootTier = UserManager.getPlayer(player).getFishingManager().getLootTier();
-
         // TREASURE HUNTER
-        double enchantChance = lootTier * AdvancedConfig.getInstance().getFishingMagicMultiplier();
+        if (canTreasureHunt) {
+            lootTier = mcMMOPlayer.getFishingManager().getLootTier();
+            double enchantChance = lootTier * AdvancedConfig.getInstance().getFishingMagicMultiplier();
 
-        if (player.getWorld().hasStorm()) {
-            chanceRaining = LocaleLoader.getString("Fishing.Chance.Raining");
-            enchantChance = enchantChance * 1.1D;
-        }
+            if (player.getWorld().hasStorm()) {
+                chanceRaining = LocaleLoader.getString("Fishing.Chance.Raining");
+                enchantChance *= 1.1D;
+            }
 
-        String[] treasureHunterStrings = calculateAbilityDisplayValues(enchantChance);
-        magicChance = treasureHunterStrings[0];
-        magicChanceLucky = treasureHunterStrings[1];
+            String[] treasureHunterStrings = calculateAbilityDisplayValues(enchantChance);
+            magicChance = treasureHunterStrings[0];
+            magicChanceLucky = treasureHunterStrings[1];
+        }
 
         // SHAKE
-        String[] shakeStrings = calculateAbilityDisplayValues(UserManager.getPlayer(player).getFishingManager().getShakeProbability());
-        shakeChance = shakeStrings[0];
-        shakeChanceLucky = shakeStrings[1];
+        if (canShake) {
+            String[] shakeStrings = calculateAbilityDisplayValues(UserManager.getPlayer(player).getFishingManager().getShakeProbability());
+            shakeChance = shakeStrings[0];
+            shakeChanceLucky = shakeStrings[1];
+        }
 
         // FISHERMAN'S DIET
-        fishermansDietRank = calculateRank(Fishing.fishermansDietMaxLevel, Fishing.fishermansDietRankLevel1);
+        if (canFishermansDiet) {
+            fishermansDietRank = calculateRank(Fishing.fishermansDietMaxLevel, Fishing.fishermansDietRankLevel1);
+        }
     }
 
     @Override
@@ -96,25 +101,17 @@ public class FishingCommand extends SkillCommand {
         }
 
         if (canMagicHunt) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Fishing.Enchant.Chance", magicChance) + chanceRaining + LocaleLoader.getString("Perks.lucky.bonus", magicChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Fishing.Enchant.Chance", magicChance) + chanceRaining);
-            }
+            player.sendMessage(LocaleLoader.getString("Fishing.Enchant.Chance", magicChance) + chanceRaining + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", magicChanceLucky) : ""));
         }
 
         if (canShake) {
-            if (skillValue < AdvancedConfig.getInstance().getShakeUnlockLevel()) {
-                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Fishing.Ability.Locked.0", AdvancedConfig.getInstance().getShakeUnlockLevel())));
+            int unlockLevel = AdvancedConfig.getInstance().getShakeUnlockLevel();
+
+            if (skillValue < unlockLevel) {
+                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Fishing.Ability.Locked.0", unlockLevel)));
             }
             else {
-                if (isLucky) {
-                    player.sendMessage(LocaleLoader.getString("Fishing.Ability.Shake", shakeChance) + LocaleLoader.getString("Perks.lucky.bonus", shakeChanceLucky));
-                }
-                else {
-                    player.sendMessage(LocaleLoader.getString("Fishing.Ability.Shake", shakeChance));
-                }
+                player.sendMessage(LocaleLoader.getString("Fishing.Ability.Shake", shakeChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", shakeChanceLucky) : ""));
             }
         }
 

+ 49 - 64
src/main/java/com/gmail/nossr50/commands/skills/HerbalismCommand.java

@@ -12,8 +12,8 @@ public class HerbalismCommand extends SkillCommand {
     private String greenTerraLengthEndurance;
     private String greenThumbChance;
     private String greenThumbChanceLucky;
-    private String greenThumbStage;
-    private String farmersDietRank;
+    private int greenThumbStage;
+    private int farmersDietRank;
     private String doubleDropChance;
     private String doubleDropChanceLucky;
     private String hylianLuckChance;
@@ -23,12 +23,11 @@ public class HerbalismCommand extends SkillCommand {
 
     private boolean hasHylianLuck;
     private boolean canGreenTerra;
-    private boolean canGreenThumbWheat;
+    private boolean canGreenThumbPlants;
     private boolean canGreenThumbBlocks;
     private boolean canFarmersDiet;
     private boolean canDoubleDrop;
     private boolean canShroomThumb;
-    private boolean doubleDropsDisabled;
 
     public HerbalismCommand() {
         super(SkillType.HERBALISM);
@@ -37,51 +36,62 @@ public class HerbalismCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // GREEN TERRA
-        String[] greenTerraStrings = calculateLengthDisplayValues();
-        greenTerraLength = greenTerraStrings[0];
-        greenTerraLengthEndurance = greenTerraStrings[1];
+        if (canGreenTerra) {
+            String[] greenTerraStrings = calculateLengthDisplayValues();
+            greenTerraLength = greenTerraStrings[0];
+            greenTerraLengthEndurance = greenTerraStrings[1];
+        }
 
         // FARMERS DIET
-        farmersDietRank = calculateRank(Herbalism.farmersDietMaxLevel, Herbalism.farmersDietRankLevel1);
+        if (canFarmersDiet) {
+            farmersDietRank = calculateRank(Herbalism.farmersDietMaxLevel, Herbalism.farmersDietRankLevel1);
+        }
 
         // GREEN THUMB
-        greenThumbStage = calculateRank(Herbalism.greenThumbStageMaxLevel, Herbalism.greenThumbStageChangeLevel);
+        if (canGreenThumbBlocks || canGreenThumbPlants) {
+            greenThumbStage = calculateRank(Herbalism.greenThumbStageMaxLevel, Herbalism.greenThumbStageChangeLevel);
 
-        String[] greenThumbStrings = calculateAbilityDisplayValues(Herbalism.greenThumbMaxLevel, Herbalism.greenThumbMaxChance);
-        greenThumbChance = greenThumbStrings[0];
-        greenThumbChanceLucky = greenThumbStrings[1];
+            String[] greenThumbStrings = calculateAbilityDisplayValues(Herbalism.greenThumbMaxLevel, Herbalism.greenThumbMaxChance);
+            greenThumbChance = greenThumbStrings[0];
+            greenThumbChanceLucky = greenThumbStrings[1];
+        }
 
         // DOUBLE DROPS
-        String[] doubleDropStrings = calculateAbilityDisplayValues(Herbalism.doubleDropsMaxLevel, Herbalism.doubleDropsMaxChance);
-        doubleDropChance = doubleDropStrings[0];
-        doubleDropChanceLucky = doubleDropStrings[1];
+        if (canDoubleDrop) {
+            String[] doubleDropStrings = calculateAbilityDisplayValues(Herbalism.doubleDropsMaxLevel, Herbalism.doubleDropsMaxChance);
+            doubleDropChance = doubleDropStrings[0];
+            doubleDropChanceLucky = doubleDropStrings[1];
+        }
 
         // HYLIAN LUCK
-        String[] hylianLuckStrings = calculateAbilityDisplayValues(Herbalism.hylianLuckMaxLevel, Herbalism.hylianLuckMaxChance);
-        hylianLuckChance = hylianLuckStrings[0];
-        hylianLuckChanceLucky = hylianLuckStrings[1];
+        if (hasHylianLuck) {
+            String[] hylianLuckStrings = calculateAbilityDisplayValues(Herbalism.hylianLuckMaxLevel, Herbalism.hylianLuckMaxChance);
+            hylianLuckChance = hylianLuckStrings[0];
+            hylianLuckChanceLucky = hylianLuckStrings[1];
+        }
 
         // SHROOM THUMB
-        String[] shroomThumbStrings = calculateAbilityDisplayValues(Herbalism.shroomThumbMaxLevel, Herbalism.shroomThumbMaxChance);
-        shroomThumbChance = shroomThumbStrings[0];
-        shroomThumbChanceLucky = shroomThumbStrings[1];
+        if (canShroomThumb) {
+            String[] shroomThumbStrings = calculateAbilityDisplayValues(Herbalism.shroomThumbMaxLevel, Herbalism.shroomThumbMaxChance);
+            shroomThumbChance = shroomThumbStrings[0];
+            shroomThumbChanceLucky = shroomThumbStrings[1];
+        }
     }
 
     @Override
     protected void permissionsCheck() {
         hasHylianLuck = Permissions.hylianLuck(player);
         canGreenTerra = Permissions.greenTerra(player);
-        canGreenThumbWheat = Permissions.greenThumbPlant(player, Material.CROPS); // TODO: This isn't really accurate - they could have perms for other crops but not wheat.
-        canGreenThumbBlocks = (Permissions.greenThumbBlock(player, Material.DIRT) || Permissions.greenThumbBlock(player, Material.COBBLESTONE) || Permissions.greenThumbBlock(player, Material.COBBLE_WALL) || Permissions.greenThumbBlock(player, Material.SMOOTH_BRICK));
+        canGreenThumbPlants = Permissions.greenThumbPlant(player, Material.CROPS) || Permissions.greenThumbPlant(player, Material.CARROT) || Permissions.greenThumbPlant(player, Material.POTATO) || Permissions.greenThumbPlant(player, Material.NETHER_WARTS) || Permissions.greenThumbPlant(player, Material.COCOA);
+        canGreenThumbBlocks = Permissions.greenThumbBlock(player, Material.DIRT) || Permissions.greenThumbBlock(player, Material.COBBLESTONE) || Permissions.greenThumbBlock(player, Material.COBBLE_WALL) || Permissions.greenThumbBlock(player, Material.SMOOTH_BRICK);
         canFarmersDiet = Permissions.farmersDiet(player);
-        canDoubleDrop = Permissions.doubleDrops(player, skill);
-        doubleDropsDisabled = skill.getDoubleDropsDisabled();
+        canDoubleDrop = Permissions.doubleDrops(player, skill) && !skill.getDoubleDropsDisabled();
         canShroomThumb = Permissions.shroomThumb(player);
     }
 
     @Override
     protected boolean effectsHeaderPermissions() {
-        return canGreenTerra || (canDoubleDrop && !doubleDropsDisabled) || canFarmersDiet || canGreenThumbBlocks || canGreenThumbWheat || canShroomThumb;
+        return canGreenTerra || canDoubleDrop || canFarmersDiet || canGreenThumbBlocks || canGreenThumbPlants || canShroomThumb;
     }
 
     @Override
@@ -92,7 +102,7 @@ public class HerbalismCommand extends SkillCommand {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Herbalism.Effect.0"), LocaleLoader.getString("Herbalism.Effect.1")));
         }
 
-        if (canGreenThumbWheat) {
+        if (canGreenThumbPlants) {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Herbalism.Effect.2"), LocaleLoader.getString("Herbalism.Effect.3")));
         }
 
@@ -112,37 +122,27 @@ public class HerbalismCommand extends SkillCommand {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Herbalism.Effect.12"), LocaleLoader.getString("Herbalism.Effect.13")));
         }
 
-        if (canDoubleDrop && !doubleDropsDisabled) {
+        if (canDoubleDrop) {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Herbalism.Effect.8"), LocaleLoader.getString("Herbalism.Effect.9")));
         }
     }
 
     @Override
     protected boolean statsHeaderPermissions() {
-        return canGreenTerra || (canDoubleDrop && !doubleDropsDisabled) || canFarmersDiet || canGreenThumbBlocks || canGreenThumbWheat || canShroomThumb;
+        return canGreenTerra || canDoubleDrop || canFarmersDiet || canGreenThumbBlocks || canGreenThumbPlants || canShroomThumb;
     }
 
     @Override
     protected void statsDisplay() {
         if (canGreenTerra) {
-            if (hasEndurance) {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTe.Length", greenTerraLength) + LocaleLoader.getString("Perks.activationtime.bonus", greenTerraLengthEndurance));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTe.Length", greenTerraLength));
-            }
+            player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTe.Length", greenTerraLength) + (hasEndurance ? LocaleLoader.getString("Perks.activationtime.bonus", greenTerraLengthEndurance) : ""));
         }
 
-        if (canGreenThumbBlocks || canGreenThumbWheat) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTh.Chance", greenThumbChance) + LocaleLoader.getString("Perks.lucky.bonus", greenThumbChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTh.Chance", greenThumbChance));
-            }
+        if (canGreenThumbBlocks || canGreenThumbPlants) {
+            player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTh.Chance", greenThumbChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", greenThumbChanceLucky) : ""));
         }
 
-        if (canGreenThumbWheat) {
+        if (canGreenThumbPlants) {
             player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTh.Stage", greenThumbStage));
         }
 
@@ -151,30 +151,15 @@ public class HerbalismCommand extends SkillCommand {
         }
 
         if (hasHylianLuck) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.HylianLuck", hylianLuckChance) + LocaleLoader.getString("Perks.lucky.bonus", hylianLuckChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.HylianLuck", hylianLuckChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Herbalism.Ability.HylianLuck", hylianLuckChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", hylianLuckChanceLucky) : ""));
         }
 
         if (canShroomThumb) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.ShroomThumb.Chance", shroomThumbChance) + LocaleLoader.getString("Perks.lucky.bonus", shroomThumbChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.ShroomThumb.Chance", shroomThumbChance));
-            }
-        }
-
-        if (canDoubleDrop && !doubleDropsDisabled) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.DoubleDropChance", doubleDropChance) + LocaleLoader.getString("Perks.lucky.bonus", doubleDropChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Herbalism.Ability.DoubleDropChance", doubleDropChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Herbalism.Ability.ShroomThumb.Chance", shroomThumbChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", shroomThumbChanceLucky) : ""));
+        }
+
+        if (canDoubleDrop) {
+            player.sendMessage(LocaleLoader.getString("Herbalism.Ability.DoubleDropChance", doubleDropChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", doubleDropChanceLucky) : ""));
         }
     }
 }

+ 39 - 39
src/main/java/com/gmail/nossr50/commands/skills/MiningCommand.java

@@ -6,7 +6,6 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.mining.Mining;
 import com.gmail.nossr50.skills.mining.MiningManager;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.player.UserManager;
 
 public class MiningCommand extends SkillCommand {
     private String doubleDropChance;
@@ -26,7 +25,6 @@ public class MiningCommand extends SkillCommand {
     private boolean canBlast;
     private boolean canBiggerBombs;
     private boolean canDemoExpert;
-    private boolean doubleDropsDisabled;
 
     public MiningCommand() {
         super(SkillType.MINING);
@@ -35,23 +33,30 @@ public class MiningCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // SUPER BREAKER
-        String[] superBreakerStrings = calculateLengthDisplayValues();
-        superBreakerLength = superBreakerStrings[0];
-        superBreakerLengthEndurance = superBreakerStrings[1];
+        if (canSuperBreaker) {
+            String[] superBreakerStrings = calculateLengthDisplayValues();
+            superBreakerLength = superBreakerStrings[0];
+            superBreakerLengthEndurance = superBreakerStrings[1];
+        }
 
         // DOUBLE DROPS
-        String[] doubleDropStrings = calculateAbilityDisplayValues(Mining.doubleDropsMaxLevel, Mining.doubleDropsMaxChance);
-        doubleDropChance = doubleDropStrings[0];
-        doubleDropChanceLucky = doubleDropStrings[1];
+        if (canDoubleDrop) {
+            String[] doubleDropStrings = calculateAbilityDisplayValues(Mining.doubleDropsMaxLevel, Mining.doubleDropsMaxChance);
+            doubleDropChance = doubleDropStrings[0];
+            doubleDropChanceLucky = doubleDropStrings[1];
+        }
 
         // BLAST MINING
-        MiningManager miningManager = UserManager.getPlayer(player).getMiningManager();
-        blastMiningRank = miningManager.getBlastMiningTier();
-        bonusTNTDrops = miningManager.getDropMultiplier();
-        oreBonus = percent.format(miningManager.getOreBonus() / 30.0D); // Base received in TNT is 30%
-        debrisReduction = percent.format(miningManager.getDebrisReduction() / 30.0D); // Base received in TNT is 30%
-        blastDamageDecrease = percent.format(miningManager.getBlastDamageModifier() / 100.0D);
-        blastRadiusIncrease = miningManager.getBlastRadiusModifier();
+        if (canBlast || canDemoExpert || canBiggerBombs) {
+            MiningManager miningManager = mcMMOPlayer.getMiningManager();
+
+            blastMiningRank = miningManager.getBlastMiningTier();
+            bonusTNTDrops = miningManager.getDropMultiplier();
+            oreBonus = percent.format(miningManager.getOreBonus() / 30.0D); // Base received in TNT is 30%
+            debrisReduction = percent.format(miningManager.getDebrisReduction() / 30.0D); // Base received in TNT is 30%
+            blastDamageDecrease = percent.format(miningManager.getBlastDamageModifier() / 100.0D);
+            blastRadiusIncrease = miningManager.getBlastRadiusModifier();
+        }
     }
 
     @Override
@@ -59,14 +64,13 @@ public class MiningCommand extends SkillCommand {
         canBiggerBombs = Permissions.biggerBombs(player);
         canBlast = Permissions.remoteDetonation(player);
         canDemoExpert = Permissions.demolitionsExpertise(player);
-        canDoubleDrop = Permissions.doubleDrops(player, skill);
+        canDoubleDrop = Permissions.doubleDrops(player, skill) && !skill.getDoubleDropsDisabled();
         canSuperBreaker = Permissions.superBreaker(player);
-        doubleDropsDisabled = skill.getDoubleDropsDisabled();
     }
 
     @Override
     protected boolean effectsHeaderPermissions() {
-        return canBiggerBombs || canBlast || canDemoExpert || (canDoubleDrop && !doubleDropsDisabled) || canSuperBreaker;
+        return canBiggerBombs || canBlast || canDemoExpert || canDoubleDrop || canSuperBreaker;
     }
 
     @Override
@@ -77,7 +81,7 @@ public class MiningCommand extends SkillCommand {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Mining.Effect.0"), LocaleLoader.getString("Mining.Effect.1")));
         }
 
-        if (canDoubleDrop && !doubleDropsDisabled) {
+        if (canDoubleDrop) {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Mining.Effect.2"), LocaleLoader.getString("Mining.Effect.3")));
         }
 
@@ -96,32 +100,24 @@ public class MiningCommand extends SkillCommand {
 
     @Override
     protected boolean statsHeaderPermissions() {
-        return canBiggerBombs || canBlast || canDemoExpert || (canDoubleDrop && !doubleDropsDisabled) || canSuperBreaker;
+        return canBiggerBombs || canBlast || canDemoExpert || canDoubleDrop || canSuperBreaker;
     }
 
     @Override
     protected void statsDisplay() {
-        if (canDoubleDrop && !doubleDropsDisabled) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Mining.Effect.DropChance", doubleDropChance) + LocaleLoader.getString("Perks.lucky.bonus", doubleDropChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Mining.Effect.DropChance", doubleDropChance));
-            }
+        if (canDoubleDrop) {
+            player.sendMessage(LocaleLoader.getString("Mining.Effect.DropChance", doubleDropChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", doubleDropChanceLucky) : ""));
         }
 
         if (canSuperBreaker) {
-            if (hasEndurance) {
-                player.sendMessage(LocaleLoader.getString("Mining.Ability.Length", superBreakerLength) + LocaleLoader.getString("Perks.activationtime.bonus", superBreakerLengthEndurance));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Mining.Ability.Length", superBreakerLength));
-            }
+            player.sendMessage(LocaleLoader.getString("Mining.Ability.Length", superBreakerLength) + (hasEndurance ? LocaleLoader.getString("Perks.activationtime.bonus", superBreakerLengthEndurance) : ""));
         }
 
         if (canBlast) {
-            if (skillValue < AdvancedConfig.getInstance().getBlastMiningRank1()) {
-                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Mining.Ability.Locked.0", AdvancedConfig.getInstance().getBlastMiningRank1())));
+            int unlockLevel = AdvancedConfig.getInstance().getBlastMiningRank1();
+
+            if (skillValue < unlockLevel) {
+                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Mining.Ability.Locked.0", unlockLevel)));
             }
             else {
                 player.sendMessage(LocaleLoader.getString("Mining.Blast.Rank", blastMiningRank, LocaleLoader.getString("Mining.Blast.Effect", oreBonus, debrisReduction, bonusTNTDrops)));
@@ -129,8 +125,10 @@ public class MiningCommand extends SkillCommand {
         }
 
         if (canBiggerBombs) {
-            if (skillValue < AdvancedConfig.getInstance().getBlastMiningRank2()) {
-                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Mining.Ability.Locked.1", AdvancedConfig.getInstance().getBlastMiningRank2())));
+            int unlockLevel = AdvancedConfig.getInstance().getBlastMiningRank2();
+
+            if (skillValue < unlockLevel) {
+                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Mining.Ability.Locked.1", unlockLevel)));
             }
             else {
                 player.sendMessage(LocaleLoader.getString("Mining.Blast.Radius.Increase", blastRadiusIncrease));
@@ -138,8 +136,10 @@ public class MiningCommand extends SkillCommand {
         }
 
         if (canDemoExpert) {
-            if (skillValue < AdvancedConfig.getInstance().getBlastMiningRank4()) {
-                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Mining.Ability.Locked.2", AdvancedConfig.getInstance().getBlastMiningRank4())));
+            int unlockLevel = AdvancedConfig.getInstance().getBlastMiningRank4();
+
+            if (skillValue < unlockLevel) {
+                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Mining.Ability.Locked.2", unlockLevel)));
             }
             else {
                 player.sendMessage(LocaleLoader.getString("Mining.Effect.Decrease", blastDamageDecrease));

+ 14 - 22
src/main/java/com/gmail/nossr50/commands/skills/RepairCommand.java

@@ -6,12 +6,11 @@ import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.repair.Repair;
+import com.gmail.nossr50.skills.repair.RepairManager;
 import com.gmail.nossr50.skills.repair.Repairable;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.player.UserManager;
 
 public class RepairCommand extends SkillCommand {
-    private int arcaneForgingRank;
     private String repairMasteryBonus;
     private String superRepairChance;
     private String superRepairChanceLucky;
@@ -53,20 +52,16 @@ public class RepairCommand extends SkillCommand {
         stoneLevel = (stoneRepairable == null) ? 0 : stoneRepairable.getMinimumLevel();
 
         // REPAIR MASTERY
-        if (skillValue >= Repair.repairMasteryMaxBonusLevel) {
-            repairMasteryBonus = percent.format(Repair.repairMasteryMaxBonus / 100D);
-        }
-        else {
-            repairMasteryBonus = percent.format(((Repair.repairMasteryMaxBonus / Repair.repairMasteryMaxBonusLevel) * skillValue) / 100D);
+        if (canMasterRepair) {
+            repairMasteryBonus = percent.format(Math.min(((Repair.repairMasteryMaxBonus / Repair.repairMasteryMaxBonusLevel) * skillValue), Repair.repairMasteryMaxBonus) / 100D);
         }
 
         // SUPER REPAIR
-        String[] superRepairStrings = calculateAbilityDisplayValues(Repair.superRepairMaxBonusLevel, Repair.superRepairMaxChance);
-        superRepairChance = superRepairStrings[0];
-        superRepairChanceLucky = superRepairStrings[1];
-
-        // ARCANE FORGING
-        arcaneForgingRank = UserManager.getPlayer(player).getRepairManager().getArcaneForgingRank();
+        if (canSuperRepair) {
+            String[] superRepairStrings = calculateAbilityDisplayValues(Repair.superRepairMaxBonusLevel, Repair.superRepairMaxChance);
+            superRepairChance = superRepairStrings[0];
+            superRepairChanceLucky = superRepairStrings[1];
+        }
     }
 
     @Override
@@ -143,23 +138,20 @@ public class RepairCommand extends SkillCommand {
         }
 
         if (canSuperRepair) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Repair.Skills.Super.Chance", superRepairChance) + LocaleLoader.getString("Perks.lucky.bonus", superRepairChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Repair.Skills.Super.Chance", superRepairChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Repair.Skills.Super.Chance", superRepairChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", superRepairChanceLucky) : ""));
         }
 
         if (canArcaneForge) {
-            player.sendMessage(LocaleLoader.getString("Repair.Arcane.Rank", arcaneForgingRank));
+            RepairManager repairManager = mcMMOPlayer.getRepairManager();
+
+            player.sendMessage(LocaleLoader.getString("Repair.Arcane.Rank", repairManager.getArcaneForgingRank()));
 
             if (Repair.arcaneForgingEnchantLoss) {
-                player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Success", (arcaneBypass ? 100 : UserManager.getPlayer(player).getRepairManager().getKeepEnchantChance())));
+                player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Success", (arcaneBypass ? 100 : repairManager.getKeepEnchantChance())));
             }
 
             if (Repair.arcaneForgingDowngrades) {
-                player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Downgrade", (arcaneBypass ? 0 : UserManager.getPlayer(player).getRepairManager().getDowngradeEnchantChance())));
+                player.sendMessage(LocaleLoader.getString("Repair.Arcane.Chance.Downgrade", (arcaneBypass ? 0 : repairManager.getDowngradeEnchantChance())));
             }
         }
     }

+ 55 - 75
src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java

@@ -9,6 +9,7 @@ import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.config.AdvancedConfig;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
@@ -22,10 +23,12 @@ import com.gmail.nossr50.util.skills.SkillUtils;
 
 public abstract class SkillCommand implements CommandExecutor {
     protected SkillType skill;
-    private String skillString;
+    protected String skillName;
 
     protected Player player;
     protected PlayerProfile profile;
+    protected McMMOPlayer mcMMOPlayer;
+
     protected float skillValue;
     protected boolean isLucky;
     protected boolean hasEndurance;
@@ -33,9 +36,12 @@ public abstract class SkillCommand implements CommandExecutor {
     protected DecimalFormat percent = new DecimalFormat("##0.00%");
     protected DecimalFormat decimal = new DecimalFormat("##0.00");
 
+    private CommandExecutor skillGuideCommand;
+
     public SkillCommand(SkillType skill) {
         this.skill = skill;
-        this.skillString = StringUtils.getCapitalized(skill.toString());
+        skillName = SkillUtils.getSkillName(skill);
+        skillGuideCommand = new SkillGuideCommand(skill);
     }
 
     @Override
@@ -44,97 +50,73 @@ public abstract class SkillCommand implements CommandExecutor {
             return true;
         }
 
-        player = (Player) sender;
-        profile = UserManager.getPlayer(player).getProfile();
+        mcMMOPlayer = UserManager.getPlayer(sender.getName());
+        player = mcMMOPlayer.getPlayer();
 
-        if (profile == null) {
-            sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
-            return true;
-        }
+        switch (args.length) {
+            case 0:
+                profile = mcMMOPlayer.getProfile();
 
-        skillValue = profile.getSkillLevel(skill);
-        isLucky = Permissions.lucky(sender, skill);
-        hasEndurance = (Permissions.twelveSecondActivationBoost(sender) || Permissions.eightSecondActivationBoost(sender) || Permissions.fourSecondActivationBoost(sender));
+                skillValue = profile.getSkillLevel(skill);
+                isLucky = Permissions.lucky(sender, skill);
+                hasEndurance = (PerksUtils.handleActivationPerks(player, 0, 0) != 0);
 
-        dataCalculations();
-        permissionsCheck();
+                permissionsCheck();
+                dataCalculations();
 
-        if (!skill.isChildSkill()) {
-            player.sendMessage(LocaleLoader.getString("Skills.Header", SkillUtils.getSkillName(skill)));
-            player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + skillString)));
-            player.sendMessage(LocaleLoader.getString("Effects.Level", profile.getSkillLevel(skill), profile.getSkillXpLevel(skill), profile.getXpToLevel(skill)));
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Skills.Header", SkillUtils.getSkillName(skill) + " " + LocaleLoader.getString("Skills.Child")));
-            player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain.Child")));
-            player.sendMessage(LocaleLoader.getString("Effects.Child", profile.getSkillLevel(skill)));
+                if (!skill.isChildSkill()) {
+                    player.sendMessage(LocaleLoader.getString("Skills.Header", skillName));
+                    player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain." + StringUtils.getCapitalized(skill.toString()))));
+                    player.sendMessage(LocaleLoader.getString("Effects.Level", (int) skillValue, profile.getSkillXpLevel(skill), profile.getXpToLevel(skill)));
+                }
+                else {
+                    player.sendMessage(LocaleLoader.getString("Skills.Header", skillName + " " + LocaleLoader.getString("Skills.Child")));
+                    player.sendMessage(LocaleLoader.getString("Commands.XPGain", LocaleLoader.getString("Commands.XPGain.Child")));
+                    player.sendMessage(LocaleLoader.getString("Effects.Child", (int) skillValue));
 
-            player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Skills.Parents")));
-            Set<SkillType> parents = FamilyTree.getParents(skill);
+                    player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Skills.Parents")));
+                    Set<SkillType> parents = FamilyTree.getParents(skill);
 
-            for (SkillType parent : parents) {
-                player.sendMessage(SkillUtils.getSkillName(parent) + " - " + LocaleLoader.getString("Effects.Level", profile.getSkillLevel(parent), profile.getSkillXpLevel(parent), profile.getXpToLevel(parent)));
-            }
-        }
+                    for (SkillType parent : parents) {
+                        player.sendMessage(SkillUtils.getSkillName(parent) + " - " + LocaleLoader.getString("Effects.Level", profile.getSkillLevel(parent), profile.getSkillXpLevel(parent), profile.getXpToLevel(parent)));
+                    }
+                }
 
-        if (effectsHeaderPermissions()) {
-            player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Effects.Effects")));
-        }
+                if (effectsHeaderPermissions()) {
+                    player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Effects.Effects")));
+                }
 
-        effectsDisplay();
+                effectsDisplay();
 
-        if (statsHeaderPermissions()) {
-            player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Commands.Stats.Self")));
-        }
+                if (statsHeaderPermissions()) {
+                    player.sendMessage(LocaleLoader.getString("Skills.Header", LocaleLoader.getString("Commands.Stats.Self")));
+                }
 
-        statsDisplay();
+                statsDisplay();
 
-        return SkillGuideCommand.grabGuidePageForSkill(skill, player, args);
-    }
+                player.sendMessage(LocaleLoader.getString("Guides.Available", skillName, skillName.toLowerCase()));
+                return true;
 
-    protected String calculateRank(int maxLevel, int rankChangeLevel) {
-        if (skillValue >= maxLevel) {
-            return String.valueOf(maxLevel / rankChangeLevel);
+            default:
+                return skillGuideCommand.onCommand(sender, command, label, args);
         }
+    }
 
-        return String.valueOf((int) (skillValue / rankChangeLevel));
+    protected int calculateRank(int maxLevel, int rankChangeLevel) {
+        return Math.min((int) skillValue, maxLevel) / rankChangeLevel;
     }
 
     protected String[] calculateAbilityDisplayValues(double chance) {
-        if (isLucky) {
-            double luckyChance = chance * 1.3333D;
+        String[] displayValues = new String[2];
 
-            if (luckyChance >= 100D) {
-                return new String[] { percent.format(chance / 100.0D), percent.format(1.0D) };
-            }
+        displayValues[0] = percent.format(Math.min(chance, 100.0D) / 100.0D);
+        displayValues[1] = isLucky ? percent.format(Math.min(chance * 1.3333D, 100.0D) / 100.0D) : null;
 
-            return new String[] { percent.format(chance / 100.0D), percent.format(luckyChance / 100.0D) };
-        }
-
-        return new String[] { percent.format(chance / 100.0D), null };
+        return displayValues;
     }
 
     protected String[] calculateAbilityDisplayValues(int maxBonusLevel, double maxChance) {
-        double abilityChance;
-
-        if (skillValue >= maxBonusLevel) {
-            abilityChance = maxChance;
-        }
-        else {
-            abilityChance = (maxChance / maxBonusLevel) * skillValue;
-        }
-
-        if (isLucky) {
-            double luckyChance = abilityChance * 1.3333D;
-
-            if (luckyChance >= 100D) {
-                return new String[] { percent.format(abilityChance / 100.0D), percent.format(1.0D) };
-            }
-
-            return new String[] { percent.format(abilityChance / 100.0D), percent.format(luckyChance / 100.0D) };
-        }
-
-        return new String[] { percent.format(abilityChance / 100.0D), null };
+        return calculateAbilityDisplayValues((maxChance / Math.min(skillValue, maxBonusLevel)) * skillValue);
     }
 
     protected String[] calculateLengthDisplayValues() {
@@ -143,9 +125,7 @@ public abstract class SkillCommand implements CommandExecutor {
         int enduranceLength = PerksUtils.handleActivationPerks(player, length, maxLength);
 
         if (maxLength != 0) {
-            if (length > maxLength) {
-                length = maxLength;
-            }
+            length = Math.min(length, maxLength);
         }
 
         return new String[] { String.valueOf(length), String.valueOf(enduranceLength) };
@@ -154,7 +134,7 @@ public abstract class SkillCommand implements CommandExecutor {
     protected void luckyEffectsDisplay() {
         if (isLucky) {
             String perkPrefix = LocaleLoader.getString("MOTD.PerksPrefix");
-            player.sendMessage(perkPrefix + LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Perks.lucky.name"), LocaleLoader.getString("Perks.lucky.desc", SkillUtils.getSkillName(skill))));
+            player.sendMessage(perkPrefix + LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Perks.lucky.name"), LocaleLoader.getString("Perks.lucky.desc", skillName)));
         }
     }
 

+ 51 - 68
src/main/java/com/gmail/nossr50/commands/skills/SkillGuideCommand.java

@@ -2,106 +2,89 @@ package com.gmail.nossr50.commands.skills;
 
 import java.util.ArrayList;
 
-import org.bukkit.entity.Player;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
 
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
-public final class SkillGuideCommand {
-    private SkillGuideCommand() {}
+public class SkillGuideCommand implements CommandExecutor {
+    private String header;
+    private String[] guide;
 
-    public static int getTotalPageNumber(String address) {
-        String[] addressSplit = LocaleLoader.getString(address).split("\n");
+    private String invalidPage;
 
-        if (addressSplit.length <= 8) {
-            return 1;
-        }
+    public SkillGuideCommand(SkillType skillType) {
+        header = LocaleLoader.getString("Guides.Header", SkillUtils.getSkillName(skillType));
+        guide = LocaleLoader.getString("Guides." + StringUtils.getCapitalized(skillType.toString())).split("\n");
 
-        return (addressSplit.length / 8) + 1;
+        invalidPage = LocaleLoader.getString("Guides.Page.Invalid");
     }
 
-    public static ArrayList<String> grabPageContents(String header, String address, int pagenum) {
-        int pageIndexStart = 0;
-
-        // Determine what string to start at
-        if (pagenum > 1) {
-            pageIndexStart = 8 * (pagenum - 1);
-        }
-
-        ArrayList<String> allStrings = new ArrayList<String>();
-        String split[] = LocaleLoader.getString(address).split("\n");
-
-        allStrings.add(LocaleLoader.getString("Guides.Header", header));
-
-        // Add targeted strings
-        while (allStrings.size() < 9) {
-            if (pageIndexStart + allStrings.size() > split.length) {
-                allStrings.add("");
-            }
-            else {
-                allStrings.add(split[pageIndexStart + allStrings.size() - 1]);
-            }
-        }
-
-        allStrings.add("Page " + pagenum + " of " + getTotalPageNumber(address));
-        return allStrings;
-    }
-
-    public static void clearChat(Player player) {
-        player.sendMessage("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); // Dear god why?
-    }
-
-    public static boolean grabGuidePageForSkill(SkillType skilltype, Player player, String[] args) {
-        String skillName = skilltype.toString();
-        String capitalized = StringUtils.getCapitalized(skillName);
-        String localized = SkillUtils.getSkillName(skilltype);
-        player.sendMessage(LocaleLoader.getString("Guides.Available", localized, localized.toLowerCase()));
-
-        String address = "Guides." + capitalized;
-
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         switch (args.length) {
-            case 0:
-                // We have to specify this, otherwise we get the usage string every time we call /skillname...
-                return true;
-
             case 1:
                 if (!args[0].equals("?")) {
                     return false;
                 }
 
-                SkillGuideCommand.clearChat(player);
-
-                for (String target : SkillGuideCommand.grabPageContents(localized, address, 1)) {
-                    player.sendMessage(target);
-                }
-
+                sendGuide(sender, 1);
                 return true;
 
             case 2:
-                int totalPages = SkillGuideCommand.getTotalPageNumber(address);
+                int totalPages = getTotalPageNumber();
 
                 if (!StringUtils.isInt(args[1])) {
-                    player.sendMessage(LocaleLoader.getString("Guides.Page.Invalid"));
+                    sender.sendMessage(invalidPage);
                     return true;
                 }
 
-                if (Integer.parseInt(args[1]) > totalPages) {
-                    player.sendMessage(LocaleLoader.getString("Guides.Page.OutOfRange", totalPages));
-                    return true;
-                }
+                int pageNumber = Integer.parseInt(args[1]);
 
-                SkillGuideCommand.clearChat(player);
-
-                for (String target : SkillGuideCommand.grabPageContents(localized, address, Integer.parseInt(args[1]))) {
-                    player.sendMessage(target);
+                if (pageNumber > totalPages || pageNumber <= 0) {
+                    sender.sendMessage(LocaleLoader.getString("Guides.Page.OutOfRange", totalPages));
+                    return true;
                 }
 
+                sendGuide(sender, pageNumber);
                 return true;
 
             default:
                 return false;
         }
     }
+
+    private int getTotalPageNumber() {
+        return (int) Math.ceil(guide.length / 8.0);
+    }
+
+    private void sendGuide(CommandSender sender, int pageNumber) {
+        for (String target : grabPageContents(pageNumber)) {
+            sender.sendMessage(target);
+        }
+    }
+
+    private ArrayList<String> grabPageContents(int pagenum) {
+        int pageIndexStart = 8 * (pagenum - 1); // Determine what string to start at
+        ArrayList<String> allStrings = new ArrayList<String>();
+
+        allStrings.add(header);
+
+        // Add targeted strings
+        while (allStrings.size() < 9) {
+            if (pageIndexStart + allStrings.size() > guide.length) {
+                allStrings.add("");
+            }
+            else {
+                allStrings.add(guide[pageIndexStart + (allStrings.size() - 1)]);
+            }
+        }
+
+        allStrings.add("Page " + pagenum + " of " + getTotalPageNumber());
+        return allStrings;
+    }
 }

+ 20 - 26
src/main/java/com/gmail/nossr50/commands/skills/SmeltingCommand.java

@@ -5,7 +5,6 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.smelting.Smelting;
 import com.gmail.nossr50.util.Permissions;
-import com.gmail.nossr50.util.player.UserManager;
 
 public class SmeltingCommand extends SkillCommand {
     private String burnTimeModifier;
@@ -14,8 +13,6 @@ public class SmeltingCommand extends SkillCommand {
     private String fluxMiningChance;
     private String fluxMiningChanceLucky;
 
-    private int vanillaXPModifier;
-
     private boolean canFuelEfficiency;
     private boolean canSecondSmelt;
     private boolean canFluxMine;
@@ -28,20 +25,23 @@ public class SmeltingCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // FUEL EFFICIENCY
-        burnTimeModifier = decimal.format(1 + ((skillValue / Smelting.burnModifierMaxLevel) * Smelting.burnTimeMultiplier));
+        if (canFuelEfficiency) {
+            burnTimeModifier = decimal.format(1 + ((skillValue / Smelting.burnModifierMaxLevel) * Smelting.burnTimeMultiplier));
+        }
 
         // SECOND SMELT
-        String[] secondSmeltStrings = calculateAbilityDisplayValues(Smelting.secondSmeltMaxLevel, Smelting.secondSmeltMaxChance);
-        secondSmeltChance = secondSmeltStrings[0];
-        secondSmeltChanceLucky = secondSmeltStrings[1];
+        if (canSecondSmelt) {
+            String[] secondSmeltStrings = calculateAbilityDisplayValues(Smelting.secondSmeltMaxLevel, Smelting.secondSmeltMaxChance);
+            secondSmeltChance = secondSmeltStrings[0];
+            secondSmeltChanceLucky = secondSmeltStrings[1];
+        }
 
         // FLUX MINING
-        String[] fluxMiningStrings = calculateAbilityDisplayValues(Smelting.fluxMiningChance);
-        fluxMiningChance = fluxMiningStrings[0];
-        fluxMiningChanceLucky = fluxMiningStrings[1];
-
-        // VANILLA XP BOOST
-        vanillaXPModifier = UserManager.getPlayer(player).getSmeltingManager().getVanillaXpMultiplier();
+        if (canFluxMine) {
+            String[] fluxMiningStrings = calculateAbilityDisplayValues(Smelting.fluxMiningChance);
+            fluxMiningChance = fluxMiningStrings[0];
+            fluxMiningChanceLucky = fluxMiningStrings[1];
+        }
     }
 
     @Override
@@ -90,20 +90,17 @@ public class SmeltingCommand extends SkillCommand {
         }
 
         if (canSecondSmelt) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Smelting.Ability.SecondSmelt", secondSmeltChance) + LocaleLoader.getString("Perks.lucky.bonus", secondSmeltChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Smelting.Ability.SecondSmelt", secondSmeltChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Smelting.Ability.SecondSmelt", secondSmeltChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", secondSmeltChanceLucky) : ""));
         }
 
         if (canVanillaXPBoost) {
-            if (skillValue < AdvancedConfig.getInstance().getSmeltingVanillaXPBoostRank1Level()) {
-                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Smelting.Ability.Locked.0", AdvancedConfig.getInstance().getSmeltingVanillaXPBoostRank1Level())));
+            int unlockLevel = AdvancedConfig.getInstance().getSmeltingVanillaXPBoostRank1Level();
+
+            if (skillValue < unlockLevel) {
+                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Smelting.Ability.Locked.0", unlockLevel)));
             }
             else {
-                player.sendMessage(LocaleLoader.getString("Smelting.Ability.VanillaXPBoost", vanillaXPModifier));
+                player.sendMessage(LocaleLoader.getString("Smelting.Ability.VanillaXPBoost", mcMMOPlayer.getSmeltingManager().getVanillaXpMultiplier()));
             }
         }
 
@@ -111,11 +108,8 @@ public class SmeltingCommand extends SkillCommand {
             if (skillValue < Smelting.fluxMiningUnlockLevel) {
                 player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Smelting.Ability.Locked.1", Smelting.fluxMiningUnlockLevel)));
             }
-            else if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Smelting.Ability.FluxMining", fluxMiningChance) + LocaleLoader.getString("Perks.lucky.bonus", fluxMiningChanceLucky));
-            }
             else {
-                player.sendMessage(LocaleLoader.getString("Smelting.Ability.FluxMining", fluxMiningChance));
+                player.sendMessage(LocaleLoader.getString("Smelting.Ability.FluxMining", fluxMiningChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", fluxMiningChanceLucky) : ""));
             }
         }
     }

+ 20 - 35
src/main/java/com/gmail/nossr50/commands/skills/SwordsCommand.java

@@ -8,7 +8,7 @@ import com.gmail.nossr50.util.Permissions;
 public class SwordsCommand extends SkillCommand {
     private String counterAttackChance;
     private String counterAttackChanceLucky;
-    private String bleedLength;
+    private int bleedLength;
     private String bleedChance;
     private String bleedChanceLucky;
     private String serratedStrikesLength;
@@ -25,26 +25,27 @@ public class SwordsCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // SERRATED STRIKES
-        String[] serratedStrikesStrings = calculateLengthDisplayValues();
-        serratedStrikesLength = serratedStrikesStrings[0];
-        serratedStrikesLengthEndurance = serratedStrikesStrings[1];
+        if (canSerratedStrike) {
+            String[] serratedStrikesStrings = calculateLengthDisplayValues();
+            serratedStrikesLength = serratedStrikesStrings[0];
+            serratedStrikesLengthEndurance = serratedStrikesStrings[1];
+        }
 
         // BLEED
-        if (skillValue >= Swords.bleedMaxBonusLevel) {
-            bleedLength = String.valueOf(Swords.bleedMaxTicks);
-        }
-        else {
-            bleedLength = String.valueOf(Swords.bleedBaseTicks);
-        }
+        if (canBleed) {
+            bleedLength = (skillValue >= Swords.bleedMaxBonusLevel) ? Swords.bleedMaxTicks : Swords.bleedBaseTicks;
 
-        String[] bleedStrings = calculateAbilityDisplayValues(Swords.bleedMaxBonusLevel, Swords.bleedMaxChance);
-        bleedChance = bleedStrings[0];
-        bleedChanceLucky = bleedStrings[1];
+            String[] bleedStrings = calculateAbilityDisplayValues(Swords.bleedMaxBonusLevel, Swords.bleedMaxChance);
+            bleedChance = bleedStrings[0];
+            bleedChanceLucky = bleedStrings[1];
+        }
 
         // COUNTER ATTACK
-        String[] counterAttackStrings = calculateAbilityDisplayValues(Swords.counterAttackMaxBonusLevel, Swords.counterAttackMaxChance);
-        counterAttackChance = counterAttackStrings[0];
-        counterAttackChanceLucky = counterAttackStrings[1];
+        if (canCounter) {
+            String[] counterAttackStrings = calculateAbilityDisplayValues(Swords.counterAttackMaxBonusLevel, Swords.counterAttackMaxChance);
+            counterAttackChance = counterAttackStrings[0];
+            counterAttackChanceLucky = counterAttackStrings[1];
+        }
     }
 
     @Override
@@ -85,33 +86,17 @@ public class SwordsCommand extends SkillCommand {
     @Override
     protected void statsDisplay() {
         if (canCounter) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Swords.Combat.Counter.Chance", counterAttackChance) + LocaleLoader.getString("Perks.lucky.bonus", counterAttackChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Swords.Combat.Counter.Chance", counterAttackChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Swords.Combat.Counter.Chance", counterAttackChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", counterAttackChanceLucky) : ""));
         }
 
         if (canBleed) {
             player.sendMessage(LocaleLoader.getString("Swords.Combat.Bleed.Length", bleedLength));
             player.sendMessage(LocaleLoader.getString("Swords.Combat.Bleed.Note"));
-
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Swords.Combat.Bleed.Chance", bleedChance) + LocaleLoader.getString("Perks.lucky.bonus", bleedChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Swords.Combat.Bleed.Chance", bleedChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Swords.Combat.Bleed.Chance", bleedChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", bleedChanceLucky) : ""));
         }
 
         if (canSerratedStrike) {
-            if (hasEndurance) {
-                player.sendMessage(LocaleLoader.getString("Swords.SS.Length", serratedStrikesLength) + LocaleLoader.getString("Perks.activationtime.bonus", serratedStrikesLengthEndurance));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Swords.SS.Length", serratedStrikesLength));
-            }
+            player.sendMessage(LocaleLoader.getString("Swords.SS.Length", serratedStrikesLength) + (hasEndurance ? LocaleLoader.getString("Perks.activationtime.bonus", serratedStrikesLengthEndurance) : ""));
         }
     }
 }

+ 6 - 9
src/main/java/com/gmail/nossr50/commands/skills/TamingCommand.java

@@ -26,9 +26,11 @@ public class TamingCommand extends SkillCommand {
 
     @Override
     protected void dataCalculations() {
-        String[] goreStrings = calculateAbilityDisplayValues(Taming.goreMaxBonusLevel, Taming.goreMaxChance);
-        goreChance = goreStrings[0];
-        goreChanceLucky = goreStrings[1];
+        if (canGore) {
+            String[] goreStrings = calculateAbilityDisplayValues(Taming.goreMaxBonusLevel, Taming.goreMaxChance);
+            goreChance = goreStrings[0];
+            goreChanceLucky = goreStrings[1];
+        }
     }
 
     @Override
@@ -154,12 +156,7 @@ public class TamingCommand extends SkillCommand {
         }
 
         if (canGore) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Taming.Combat.Chance.Gore", goreChance) + LocaleLoader.getString("Perks.lucky.bonus", goreChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Taming.Combat.Chance.Gore", goreChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Taming.Combat.Chance.Gore", goreChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", goreChanceLucky) : ""));
         }
     }
 }

+ 27 - 42
src/main/java/com/gmail/nossr50/commands/skills/UnarmedCommand.java

@@ -14,7 +14,7 @@ public class UnarmedCommand extends SkillCommand {
     private String disarmChanceLucky;
     private String ironGripChance;
     private String ironGripChanceLucky;
-    private String ironArmBonus;
+    private int ironArmBonus;
 
     private boolean canBerserk;
     private boolean canDisarm;
@@ -29,32 +29,37 @@ public class UnarmedCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // BERSERK
-        String[] berserkStrings = calculateLengthDisplayValues();
-        berserkLength = berserkStrings[0];
-        berserkLengthEndurance = berserkStrings[1];
+        if (canBerserk) {
+            String[] berserkStrings = calculateLengthDisplayValues();
+            berserkLength = berserkStrings[0];
+            berserkLengthEndurance = berserkStrings[1];
+        }
 
         // DISARM
-        String[] disarmStrings = calculateAbilityDisplayValues(Unarmed.disarmMaxBonusLevel, Unarmed.disarmMaxChance);
-        disarmChance = disarmStrings[0];
-        disarmChanceLucky = disarmStrings[1];
+        if (canDisarm) {
+            String[] disarmStrings = calculateAbilityDisplayValues(Unarmed.disarmMaxBonusLevel, Unarmed.disarmMaxChance);
+            disarmChance = disarmStrings[0];
+            disarmChanceLucky = disarmStrings[1];
+        }
 
         // DEFLECT
-        String[] deflectStrings = calculateAbilityDisplayValues(Unarmed.deflectMaxBonusLevel, Unarmed.deflectMaxChance);
-        deflectChance = deflectStrings[0];
-        deflectChanceLucky = deflectStrings[1];
+        if (canDeflect) {
+            String[] deflectStrings = calculateAbilityDisplayValues(Unarmed.deflectMaxBonusLevel, Unarmed.deflectMaxChance);
+            deflectChance = deflectStrings[0];
+            deflectChanceLucky = deflectStrings[1];
+        }
 
         // IRON ARM
-        if (skillValue >= ((Unarmed.ironArmMaxBonusDamage - 3) * Unarmed.ironArmIncreaseLevel)) {
-            ironArmBonus = String.valueOf(Unarmed.ironArmMaxBonusDamage);
-        }
-        else {
-            ironArmBonus = String.valueOf(3 + (skillValue / Unarmed.ironArmIncreaseLevel));
+        if (canBonusDamage) {
+            ironArmBonus = Math.min(3 + ((int) skillValue / Unarmed.ironArmIncreaseLevel), Unarmed.ironArmMaxBonusDamage);
         }
 
         // IRON GRIP
-        String[] ironGripStrings = calculateAbilityDisplayValues(Unarmed.ironGripMaxBonusLevel, Unarmed.ironGripMaxChance);
-        ironGripChance = ironGripStrings[0];
-        ironGripChanceLucky = ironGripStrings[1];
+        if (canIronGrip) {
+            String[] ironGripStrings = calculateAbilityDisplayValues(Unarmed.ironGripMaxBonusLevel, Unarmed.ironGripMaxChance);
+            ironGripChance = ironGripStrings[0];
+            ironGripChanceLucky = ironGripStrings[1];
+        }
     }
 
     @Override
@@ -108,39 +113,19 @@ public class UnarmedCommand extends SkillCommand {
         }
 
         if (canDeflect) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.ArrowDeflect", deflectChance) + LocaleLoader.getString("Perks.lucky.bonus", deflectChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.ArrowDeflect", deflectChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.ArrowDeflect", deflectChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", deflectChanceLucky) : ""));
         }
 
         if (canDisarm) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.Disarm", disarmChance) + LocaleLoader.getString("Perks.lucky.bonus", disarmChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.Disarm", disarmChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.Disarm", disarmChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", disarmChanceLucky) : ""));
         }
 
         if (canIronGrip) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.IronGrip", ironGripChance) + LocaleLoader.getString("Perks.lucky.bonus", ironGripChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.IronGrip", ironGripChance));
-            }
+            player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Chance.IronGrip", ironGripChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", ironGripChanceLucky) : ""));
         }
 
         if (canBerserk) {
-            if (hasEndurance) {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Berserk.Length", berserkLength) + LocaleLoader.getString("Perks.activationtime.bonus", berserkLengthEndurance));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Berserk.Length", berserkLength));
-            }
+            player.sendMessage(LocaleLoader.getString("Unarmed.Ability.Berserk.Length", berserkLength) + (hasEndurance ? LocaleLoader.getString("Perks.activationtime.bonus", berserkLengthEndurance) : ""));
         }
     }
 }

+ 17 - 25
src/main/java/com/gmail/nossr50/commands/skills/WoodcuttingCommand.java

@@ -15,7 +15,6 @@ public class WoodcuttingCommand extends SkillCommand {
     private boolean canTreeFell;
     private boolean canLeafBlow;
     private boolean canDoubleDrop;
-    private boolean doubleDropsDisabled;
 
     public WoodcuttingCommand() {
         super(SkillType.WOODCUTTING);
@@ -24,27 +23,30 @@ public class WoodcuttingCommand extends SkillCommand {
     @Override
     protected void dataCalculations() {
         // TREE FELLER
-        String[] treeFellerStrings = calculateLengthDisplayValues();
-        treeFellerLength = treeFellerStrings[0];
-        treeFellerLengthEndurance = treeFellerStrings[1];
+        if (canTreeFell) {
+            String[] treeFellerStrings = calculateLengthDisplayValues();
+            treeFellerLength = treeFellerStrings[0];
+            treeFellerLengthEndurance = treeFellerStrings[1];
+        }
 
         // DOUBLE DROPS
-        String[] doubleDropStrings = calculateAbilityDisplayValues(Woodcutting.doubleDropsMaxLevel, Woodcutting.doubleDropsMaxChance);
-        doubleDropChance = doubleDropStrings[0];
-        doubleDropChanceLucky = doubleDropStrings[1];
+        if (canDoubleDrop) {
+            String[] doubleDropStrings = calculateAbilityDisplayValues(Woodcutting.doubleDropsMaxLevel, Woodcutting.doubleDropsMaxChance);
+            doubleDropChance = doubleDropStrings[0];
+            doubleDropChanceLucky = doubleDropStrings[1];
+        }
     }
 
     @Override
     protected void permissionsCheck() {
         canTreeFell = Permissions.treeFeller(player);
-        canDoubleDrop = Permissions.doubleDrops(player, skill);
+        canDoubleDrop = Permissions.doubleDrops(player, skill) && !skill.getDoubleDropsDisabled();
         canLeafBlow = Permissions.leafBlower(player);
-        doubleDropsDisabled = skill.getDoubleDropsDisabled();
     }
 
     @Override
     protected boolean effectsHeaderPermissions() {
-        return (canDoubleDrop && !doubleDropsDisabled) || canLeafBlow || canTreeFell;
+        return canDoubleDrop || canLeafBlow || canTreeFell;
     }
 
     @Override
@@ -59,14 +61,14 @@ public class WoodcuttingCommand extends SkillCommand {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Woodcutting.Effect.2"), LocaleLoader.getString("Woodcutting.Effect.3")));
         }
 
-        if (canDoubleDrop && !doubleDropsDisabled) {
+        if (canDoubleDrop) {
             player.sendMessage(LocaleLoader.getString("Effects.Template", LocaleLoader.getString("Woodcutting.Effect.4"), LocaleLoader.getString("Woodcutting.Effect.5")));
         }
     }
 
     @Override
     protected boolean statsHeaderPermissions() {
-        return (canDoubleDrop && !doubleDropsDisabled) || canLeafBlow || canTreeFell;
+        return canDoubleDrop || canLeafBlow || canTreeFell;
     }
 
     @Override
@@ -82,22 +84,12 @@ public class WoodcuttingCommand extends SkillCommand {
             }
         }
 
-        if (canDoubleDrop && !doubleDropsDisabled) {
-            if (isLucky) {
-                player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Chance.DDrop", doubleDropChance) + LocaleLoader.getString("Perks.lucky.bonus", doubleDropChanceLucky));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Chance.DDrop", doubleDropChance));
-            }
+        if (canDoubleDrop) {
+            player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Chance.DDrop", doubleDropChance) + (isLucky ? LocaleLoader.getString("Perks.lucky.bonus", doubleDropChanceLucky) : ""));
         }
 
         if (canTreeFell) {
-            if (hasEndurance) {
-                player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Length", treeFellerLength) + LocaleLoader.getString("Perks.activationtime.bonus", treeFellerLengthEndurance));
-            }
-            else {
-                player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Length", treeFellerLength));
-            }
+            player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Length", treeFellerLength) + (hasEndurance ? LocaleLoader.getString("Perks.activationtime.bonus", treeFellerLengthEndurance) : ""));
         }
     }
 }

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

@@ -3,7 +3,6 @@ package com.gmail.nossr50.commands.spout;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.spout.SpoutConfig;
@@ -28,7 +27,7 @@ public abstract class SpoutCommand implements CommandExecutor {
             return true;
         }
 
-        playerProfile = UserManager.getPlayer((Player) sender).getProfile();
+        playerProfile = UserManager.getPlayer(sender.getName()).getProfile();
         spoutHud = playerProfile.getSpoutHud();
 
         if (spoutHud == null) {

+ 5 - 6
src/main/java/com/gmail/nossr50/commands/spout/XplockCommand.java

@@ -6,6 +6,7 @@ import org.bukkit.command.CommandSender;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
 public class XplockCommand extends SpoutCommand {
@@ -22,25 +23,23 @@ public class XplockCommand extends SpoutCommand {
 
     @Override
     protected boolean oneArgument(Command command, CommandSender sender, String[] args) {
-        if (args[0].equalsIgnoreCase("on")) {
+        if (CommandUtils.shouldEnableToggle(args[0])) {
             lockXpBar(sender, spoutHud.getLastGained());
             return true;
         }
 
-        if (args[0].equalsIgnoreCase("off")) {
+        if (CommandUtils.shouldDisableToggle(args[0])) {
             unlockXpBar(sender);
             return true;
         }
 
-        if (!SkillUtils.isSkill(args[0])) {
-            sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
+        if (CommandUtils.isInvalidSkill(sender, args[0])) {
             return true;
         }
 
         SkillType skill = SkillType.getSkill(args[0]);
 
-        if (skill.isChildSkill()) {
-            sender.sendMessage("Child skills are not yet supported by this command."); // TODO: Localize this
+        if (CommandUtils.isChildSkill(sender, skill)) {
             return true;
         }
 

+ 3 - 30
src/main/java/com/gmail/nossr50/database/DatabaseManager.java

@@ -10,17 +10,13 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 
-import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.database.DatabaseUpdateType;
-import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SkillType;
-import com.gmail.nossr50.datatypes.spout.huds.McMMOHud;
 import com.gmail.nossr50.runnables.database.SQLReconnectTask;
-import com.gmail.nossr50.util.player.UserManager;
-import com.gmail.nossr50.util.spout.SpoutUtils;
+import com.gmail.nossr50.util.Misc;
 
 public final class DatabaseManager {
     private static String connectionString;
@@ -502,7 +498,7 @@ public final class DatabaseManager {
                 continue;
             }
 
-            profileCleanup(playerName);
+            Misc.profileCleanup(playerName);
             purgedUsers++;
         }
 
@@ -524,36 +520,13 @@ public final class DatabaseManager {
                 continue;
             }
 
-            profileCleanup(playerName);
+            Misc.profileCleanup(playerName);
             purgedUsers++;
         }
 
         mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
     }
 
-    public static void profileCleanup(String playerName) {
-        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(playerName);
-
-        if (mcMMOPlayer != null) {
-            Player player = mcMMOPlayer.getPlayer();
-            McMMOHud spoutHud = mcMMOPlayer.getProfile().getSpoutHud();
-
-            if (spoutHud != null) {
-                spoutHud.removeWidgets();
-            }
-
-            UserManager.remove(playerName);
-
-            if (player.isOnline()) {
-                UserManager.addUser(player);
-
-                if (mcMMO.spoutEnabled) {
-                    SpoutUtils.reloadSpoutPlayer(player);
-                }
-            }
-        }
-    }
-
     /**
      * Check database structure for missing values.
      *

+ 4 - 0
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -449,6 +449,10 @@ public class McMMOPlayer {
      * @param xp Experience amount to add
      */
     public void applyXpGain(SkillType skillType, int xp) {
+        if (skillType.isChildSkill()) {
+            return;
+        }
+
         McMMOPlayerXpGainEvent event = new McMMOPlayerXpGainEvent(player, skillType, xp);
         mcMMO.p.getServer().getPluginManager().callEvent(event);
 

+ 4 - 0
src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java

@@ -611,6 +611,10 @@ public class PlayerProfile {
     }
 
     public void setSkillXpLevel(SkillType skillType, int newValue) {
+        if (skillType.isChildSkill()) {
+            return;
+        }
+
         skillsXp.put(skillType, newValue);
     }
 

+ 9 - 0
src/main/java/com/gmail/nossr50/party/PartyManager.java

@@ -24,6 +24,15 @@ public final class PartyManager {
 
     private PartyManager() {}
 
+    public static boolean checkPartyExistence(Player player, Party party, String partyName) {
+        if (party == null) {
+            return false;
+        }
+
+        player.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", partyName));
+        return true;
+    }
+
     public static boolean changeOrJoinParty(McMMOPlayer mcMMOPlayer, Player player, Party oldParty, String newPartyName) {
         if (mcMMOPlayer.inParty()) {
             if (!handlePartyChangeEvent(player, oldParty.getName(), newPartyName, EventReason.CHANGED_PARTIES)) {

+ 28 - 0
src/main/java/com/gmail/nossr50/util/Misc.java

@@ -6,11 +6,16 @@ import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.entity.Entity;
 import org.bukkit.entity.Item;
+import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
 
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
+import com.gmail.nossr50.datatypes.spout.huds.McMMOHud;
 import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
+import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.spout.SpoutUtils;
 
 public final class Misc {
     private static Random random = new Random();
@@ -161,6 +166,29 @@ public final class Misc {
         newItem.setItemStack(cloned);
     }
 
+    public static void profileCleanup(String playerName) {
+        McMMOPlayer mcMMOPlayer = UserManager.getPlayer(playerName);
+
+        if (mcMMOPlayer != null) {
+            Player player = mcMMOPlayer.getPlayer();
+            McMMOHud spoutHud = mcMMOPlayer.getProfile().getSpoutHud();
+
+            if (spoutHud != null) {
+                spoutHud.removeWidgets();
+            }
+
+            UserManager.remove(playerName);
+
+            if (player.isOnline()) {
+                UserManager.addUser(player);
+
+                if (mcMMO.spoutEnabled) {
+                    SpoutUtils.reloadSpoutPlayer(player);
+                }
+            }
+        }
+    }
+
     public static Random getRandom() {
         return random;
     }

+ 2 - 2
src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java

@@ -24,7 +24,7 @@ import com.gmail.nossr50.commands.experience.SkillresetCommand;
 import com.gmail.nossr50.commands.hardcore.HardcoreCommand;
 import com.gmail.nossr50.commands.hardcore.VampirismCommand;
 import com.gmail.nossr50.commands.party.PartyCommand;
-import com.gmail.nossr50.commands.party.PtpCommand;
+import com.gmail.nossr50.commands.party.teleport.PtpCommand;
 import com.gmail.nossr50.commands.player.InspectCommand;
 import com.gmail.nossr50.commands.player.McrankCommand;
 import com.gmail.nossr50.commands.player.McstatsCommand;
@@ -58,7 +58,7 @@ public final class CommandRegistrationManager {
     public static void registerSkillCommands() {
         for (SkillType skill : SkillType.values()) {
             String commandName = skill.toString().toLowerCase();
-            String localizedName = SkillUtils.getSkillName(skill);
+            String localizedName = SkillUtils.getSkillName(skill).toLowerCase();
 
             PluginCommand command;
 

+ 141 - 61
src/main/java/com/gmail/nossr50/util/commands/CommandUtils.java

@@ -3,120 +3,200 @@ package com.gmail.nossr50.util.commands;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
+import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.SkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.StringUtils;
+import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.skills.SkillUtils;
 
 public final class CommandUtils {
     private CommandUtils() {}
 
-    public static boolean noConsoleUsage(CommandSender sender) {
-        if (!(sender instanceof Player)) {
-            sender.sendMessage(LocaleLoader.getString("Commands.NoConsole"));
+    public static boolean isChildSkill(CommandSender sender, SkillType skill) {
+        if (!skill.isChildSkill()) {
+            return false;
+        }
+
+        sender.sendMessage("Child skills are not supported by this command."); // TODO: Localize this
+        return true;
+    }
+
+    public static boolean inspectOffline(CommandSender sender, PlayerProfile profile, boolean hasPermission) {
+        if (unloadedProfile(sender, profile)) {
+            return true;
+        }
+
+        if (!hasPermission) {
+            sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
             return true;
         }
 
         return false;
     }
 
+    public static boolean tooFar(CommandSender sender, Player target, boolean hasPermission) {
+        if (sender instanceof Player && !Misc.isNear(((Player) sender).getLocation(), target.getLocation(), 5.0) && !hasPermission) {
+            sender.sendMessage(LocaleLoader.getString("Inspect.TooFar"));
+            return true;
+        }
+
+        return false;
+    }
+
+    public static boolean noConsoleUsage(CommandSender sender) {
+        if (sender instanceof Player) {
+            return false;
+        }
+
+        sender.sendMessage(LocaleLoader.getString("Commands.NoConsole"));
+        return true;
+    }
+
+    public static boolean isOffline(CommandSender sender, Player player) {
+        if (player.isOnline()) {
+            return false;
+        }
+
+        sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+        return true;
+    }
+
+    public static boolean checkPlayerExistence(CommandSender sender, String playerName, McMMOPlayer mcMMOPlayer) {
+        if (mcMMOPlayer != null) {
+            return false;
+        }
+
+        PlayerProfile playerProfile = new PlayerProfile(playerName, false);
+
+        if (unloadedProfile(sender, playerProfile)) {
+            return true;
+        }
+
+        sender.sendMessage(LocaleLoader.getString("Commands.Offline"));
+        return true;
+    }
+
+    public static boolean unloadedProfile(CommandSender sender, PlayerProfile profile) {
+        if (profile.isLoaded()) {
+            return false;
+        }
+
+        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
+        return true;
+    }
+
+    public static boolean isInvalidInteger(CommandSender sender, String value) {
+        if (StringUtils.isInt(value)) {
+            return false;
+        }
+
+        sender.sendMessage("That is not a valid integer."); // TODO: Localize
+        return true;
+    }
+
+    public static boolean isInvalidDouble(CommandSender sender, String value) {
+        if (StringUtils.isDouble(value)) {
+            return false;
+        }
+
+        sender.sendMessage("That is not a valid percentage."); // TODO: Localize
+        return true;
+    }
+
+    public static boolean isInvalidSkill(CommandSender sender, String skillName) {
+        if (SkillUtils.isSkill(skillName)) {
+            return false;
+        }
+
+        sender.sendMessage(LocaleLoader.getString("Commands.Skill.Invalid"));
+        return true;
+    }
+
+    public static boolean shouldEnableToggle(String arg) {
+        return arg.equalsIgnoreCase("on") || arg.equalsIgnoreCase("true") || arg.equalsIgnoreCase("enabled");
+    }
+
+    public static boolean shouldDisableToggle(String arg) {
+        return arg.equalsIgnoreCase("off") || arg.equalsIgnoreCase("false") || arg.equalsIgnoreCase("disabled");
+    }
+
     /**
      * Print out details on Gathering skills. Only for online players.
      *
      * @param inspect The player to retrieve stats for
-     * @param profile The player's profile
      * @param display The sender to display stats to
      */
-    public static void printGatheringSkills(Player inspect, PlayerProfile profile, CommandSender display) {
+    public static void printGatheringSkills(Player inspect, CommandSender display) {
         if (SkillUtils.hasGatheringSkills(inspect)) {
-            display.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
-
-            if (Permissions.skillEnabled(inspect, SkillType.EXCAVATION)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Excavation.Listener"), profile.getSkillLevel(SkillType.EXCAVATION), profile.getSkillXpLevel(SkillType.EXCAVATION), profile.getXpToLevel(SkillType.EXCAVATION)));
-            }
-
-            if (Permissions.skillEnabled(inspect, SkillType.FISHING)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Fishing.Listener"), profile.getSkillLevel(SkillType.FISHING), profile.getSkillXpLevel(SkillType.FISHING), profile.getXpToLevel(SkillType.FISHING)));
-            }
-
-            if (Permissions.skillEnabled(inspect, SkillType.HERBALISM)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Herbalism.Listener"), profile.getSkillLevel(SkillType.HERBALISM), profile.getSkillXpLevel(SkillType.HERBALISM), profile.getXpToLevel(SkillType.HERBALISM)));
-            }
+            PlayerProfile profile = UserManager.getPlayer(inspect).getProfile();
 
-            if (Permissions.skillEnabled(inspect, SkillType.MINING)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Mining.Listener"), profile.getSkillLevel(SkillType.MINING), profile.getSkillXpLevel(SkillType.MINING), profile.getXpToLevel(SkillType.MINING)));
-            }
-
-            if (Permissions.skillEnabled(inspect, SkillType.WOODCUTTING)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Woodcutting.Listener"), profile.getSkillLevel(SkillType.WOODCUTTING), profile.getSkillXpLevel(SkillType.WOODCUTTING), profile.getXpToLevel(SkillType.WOODCUTTING)));
-            }
+            display.sendMessage(LocaleLoader.getString("Stats.Header.Gathering"));
+            displaySkill(inspect, profile, SkillType.EXCAVATION, display);
+            displaySkill(inspect, profile, SkillType.FISHING, display);
+            displaySkill(inspect, profile, SkillType.HERBALISM, display);
+            displaySkill(inspect, profile, SkillType.MINING, display);
+            displaySkill(inspect, profile, SkillType.WOODCUTTING, display);
         }
     }
 
-    public static void printGatheringSkills(Player player, PlayerProfile profile) {
-        printGatheringSkills(player, profile, player);
+    public static void printGatheringSkills(Player player) {
+        printGatheringSkills(player, player);
     }
 
     /**
      * Print out details on Combat skills. Only for online players.
      *
      * @param inspect The player to retrieve stats for
-     * @param profile The player's profile
      * @param display The sender to display stats to
      */
-    public static void printCombatSkills(Player inspect, PlayerProfile profile, CommandSender display) {
+    public static void printCombatSkills(Player inspect, CommandSender display) {
         if (SkillUtils.hasCombatSkills(inspect)) {
-            display.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
-
-            if (Permissions.skillEnabled(inspect, SkillType.AXES)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Axes.Listener"), profile.getSkillLevel(SkillType.AXES), profile.getSkillXpLevel(SkillType.AXES), profile.getXpToLevel(SkillType.AXES)));
-            }
+            PlayerProfile profile = UserManager.getPlayer(inspect).getProfile();
 
-            if (Permissions.skillEnabled(inspect, SkillType.ARCHERY)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Archery.Listener"), profile.getSkillLevel(SkillType.ARCHERY), profile.getSkillXpLevel(SkillType.ARCHERY), profile.getXpToLevel(SkillType.ARCHERY)));
-            }
-
-            if (Permissions.skillEnabled(inspect, SkillType.SWORDS)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Swords.Listener"), profile.getSkillLevel(SkillType.SWORDS), profile.getSkillXpLevel(SkillType.SWORDS), profile.getXpToLevel(SkillType.SWORDS)));
-            }
-
-            if (Permissions.skillEnabled(inspect, SkillType.TAMING)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Taming.Listener"), profile.getSkillLevel(SkillType.TAMING), profile.getSkillXpLevel(SkillType.TAMING), profile.getXpToLevel(SkillType.TAMING)));
-            }
-
-            if (Permissions.skillEnabled(inspect, SkillType.UNARMED)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Unarmed.Listener"), profile.getSkillLevel(SkillType.UNARMED), profile.getSkillXpLevel(SkillType.UNARMED), profile.getXpToLevel(SkillType.UNARMED)));
-            }
+            display.sendMessage(LocaleLoader.getString("Stats.Header.Combat"));
+            displaySkill(inspect, profile, SkillType.AXES, display);
+            displaySkill(inspect, profile, SkillType.ARCHERY, display);
+            displaySkill(inspect, profile, SkillType.SWORDS, display);
+            displaySkill(inspect, profile, SkillType.TAMING, display);
+            displaySkill(inspect, profile, SkillType.UNARMED, display);
         }
     }
 
-    public static void printCombatSkills(Player player, PlayerProfile profile) {
-        printCombatSkills(player, profile, player);
+    public static void printCombatSkills(Player player) {
+        printCombatSkills(player, player);
     }
 
     /**
      * Print out details on Misc skills. Only for online players.
      *
      * @param inspect The player to retrieve stats for
-     * @param profile The player's profile
      * @param display The sender to display stats to
      */
-    public static void printMiscSkills(Player inspect, PlayerProfile profile, CommandSender display) {
+    public static void printMiscSkills(Player inspect, CommandSender display) {
         if (SkillUtils.hasMiscSkills(inspect)) {
+            PlayerProfile profile = UserManager.getPlayer(inspect).getProfile();
+
             display.sendMessage(LocaleLoader.getString("Stats.Header.Misc"));
+            displaySkill(inspect, profile, SkillType.ACROBATICS, display);
+            displaySkill(inspect, profile, SkillType.REPAIR, display);
+        }
+    }
 
-            if (Permissions.skillEnabled(inspect, SkillType.ACROBATICS)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Acrobatics.Listener"), profile.getSkillLevel(SkillType.ACROBATICS), profile.getSkillXpLevel(SkillType.ACROBATICS), profile.getXpToLevel(SkillType.ACROBATICS)));
-            }
+    public static void printMiscSkills(Player player) {
+        printMiscSkills(player, player);
+    }
 
-            if (Permissions.skillEnabled(inspect, SkillType.REPAIR)) {
-                display.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString("Repair.Listener"), profile.getSkillLevel(SkillType.REPAIR), profile.getSkillXpLevel(SkillType.REPAIR), profile.getXpToLevel(SkillType.REPAIR)));
-            }
+    private static void displaySkill(Player player, PlayerProfile profile, SkillType skill, CommandSender display) {
+        if (Permissions.skillEnabled(player, skill)) {
+            displaySkill(display, profile, skill);
         }
     }
 
-    public static void printMiscSkills(Player player, PlayerProfile profile) {
-        printMiscSkills(player, profile, player);
+    public static void displaySkill(CommandSender sender, PlayerProfile profile, SkillType skill) {
+        sender.sendMessage(LocaleLoader.getString("Skills.Stats", LocaleLoader.getString(StringUtils.getCapitalized(skill.toString()) + ".Listener"), profile.getSkillLevel(skill), profile.getSkillXpLevel(skill), profile.getXpToLevel(skill)));
     }
 }

+ 2 - 2
src/main/java/com/gmail/nossr50/util/skills/PerksUtils.java

@@ -36,8 +36,8 @@ public final class PerksUtils {
             ticks += 4;
         }
 
-        if (maxTicks != 0 && ticks > maxTicks) {
-            ticks = maxTicks;
+        if (maxTicks != 0) {
+            ticks = Math.min(ticks, maxTicks);
         }
 
         return ticks;