Browse Source

More command updates, better offline player support.

GJ 13 years ago
parent
commit
80526c0e06

+ 4 - 0
Changelog.txt

@@ -8,6 +8,10 @@ Key:
   - Removal
 
 Version 1.3.06-dev
+ + Added API functions for obtaining offline profiles & profiles via player names
+ + Changed /addlevel command to work for offline users
+ + Changed PlayerProfile constructor to always take a boolean
+ + Changed getPlayerProfile funtion to work for online & offline users
 
 Version 1.3.05
  + Added Skill Shot to Archery which increases damage dealt by 10% every 50 skill levels (caps at 200%)

+ 18 - 32
src/main/java/com/gmail/nossr50/Users.java

@@ -5,6 +5,7 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.util.HashMap;
 
+import org.bukkit.Bukkit;
 import org.bukkit.OfflinePlayer;
 import org.bukkit.entity.Player;
 import com.gmail.nossr50.datatypes.PlayerProfile;
@@ -44,7 +45,7 @@ public class Users {
      */
     public static void addUser(Player player) {
         if (!players.containsKey(player.getName().toLowerCase())) {
-            players.put(player.getName().toLowerCase(), new PlayerProfile(player.getName()));
+            players.put(player.getName().toLowerCase(), new PlayerProfile(player.getName(), true));
         }
     }
 
@@ -88,51 +89,36 @@ public class Users {
     }
 
     /**
-     * Get the profile of an online player.
+     * Get the profile of a player.
      *
      * @param player The player whose profile to retrieve
      * @return the player's profile
      */
-    public static PlayerProfile getProfile(Player player) {
-        return getProfile(player.getName());
+    public static PlayerProfile getProfile(OfflinePlayer player) {
+        return getProfileByName(player.getName());
     }
-    
+
     /**
-     * Get the profile of an online player.
+     * Get the profile of a player by name.
      *
-     * @param player The player whose profile to retrieve
+     * @param player The name of the player whose profile to retrieve
      * @return the player's profile
      */
-    public static PlayerProfile getProfile(String playerName) {
-        if (players.get(playerName.toLowerCase()) != null) {
-            return players.get(playerName.toLowerCase());
+    public static PlayerProfile getProfileByName(String playerName) {
+        if (Bukkit.getServer().getOfflinePlayer(playerName).isOnline()) {
+            if (players.get(playerName.toLowerCase()) != null) {
+                return players.get(playerName.toLowerCase());
+            }
+            else {
+                players.put(playerName.toLowerCase(), new PlayerProfile(playerName, true));
+                return players.get(playerName.toLowerCase());
+            }
         }
         else {
-            players.put(playerName.toLowerCase(), new PlayerProfile(playerName));
-            return players.get(playerName.toLowerCase());
+            return new PlayerProfile(playerName, false);
         }
     }
 
-    /**
-     * Get the profile of an offline player.
-     *
-     * @param player The player whose profile to retrieve
-     * @return the player's profile
-     */
-    public static PlayerProfile getOfflineProfile(OfflinePlayer player) {
-        return getOfflineProfile(player.getName());
-    }
-
-    /**
-     * Get the profile of an offline player.
-     *
-     * @param playerName Name of the player whose profile to retrieve
-     * @return the player's profile
-     */
-    public static PlayerProfile getOfflineProfile(String playerName) {
-        return new PlayerProfile(playerName, false);
-    }
-
     /**
      * Get an instance of this class.
      *

+ 9 - 0
src/main/java/com/gmail/nossr50/commands/CommandHelper.java

@@ -32,6 +32,15 @@ public class CommandHelper {
         return false;
     }
 
+    public static boolean noConsoleUsage(CommandSender sender) {
+        if (!(sender instanceof Player)) {
+            sender.sendMessage(mcLocale.getString("Commands.NoConsole"));
+            return true;
+        }
+
+        return false;
+    }
+    
     /**
      * Print out details on Gathering skills. Only for online players.
      *

+ 23 - 12
src/main/java/com/gmail/nossr50/commands/general/AddlevelsCommand.java

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.commands.general;
 
 import org.bukkit.ChatColor;
+import org.bukkit.OfflinePlayer;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
@@ -10,7 +11,9 @@ import com.gmail.nossr50.Users;
 import com.gmail.nossr50.m;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.commands.CommandHelper;
+import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.datatypes.SkillType;
+import com.gmail.nossr50.locale.mcLocale;
 import com.gmail.nossr50.skills.Skills;
 
 public class AddlevelsCommand implements CommandExecutor{
@@ -22,7 +25,8 @@ public class AddlevelsCommand implements CommandExecutor{
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        Player modifiedPlayer;
+        OfflinePlayer modifiedPlayer;
+        PlayerProfile PP;
         int levels;
         SkillType skill;
         String skillName;
@@ -39,6 +43,7 @@ public class AddlevelsCommand implements CommandExecutor{
                     modifiedPlayer = (Player) sender;
                     levels = Integer.valueOf(args[1]);
                     skill = Skills.getSkillType(args[0]);
+                    PP = Users.getProfile(modifiedPlayer);
 
                     if (skill.equals(SkillType.ALL)) {
                         skillName = "all skills";
@@ -47,21 +52,24 @@ public class AddlevelsCommand implements CommandExecutor{
                         skillName = m.getCapitalized(skill.toString());
                     }
 
-                    Users.getProfile(modifiedPlayer).addLevels(skill, levels);
+                    PP.addLevels(skill, levels);
                     sender.sendMessage(ChatColor.GREEN + "You were awarded " + levels + " levels in " + skillName + "!"); //TODO: Needs more locale.
+
+                    return true;
                 }
             }
-            else {
-                sender.sendMessage(usage);
-            }
-
-            return true;
 
         case 3:
-            modifiedPlayer = plugin.getServer().getPlayer(args[0]);
+            modifiedPlayer = plugin.getServer().getOfflinePlayer(args[0]);
             String playerName = modifiedPlayer.getName();
+            PP = Users.getProfile(modifiedPlayer);
+
+            if (!PP.isLoaded()) {
+                sender.sendMessage(mcLocale.getString("Commands.DoesNotExist"));
+                return true;
+            }
 
-            if (modifiedPlayer != null && m.isInt(args[2]) && Skills.isSkill(args[1])) {
+            if (m.isInt(args[2]) && Skills.isSkill(args[1])) {
                 levels = Integer.valueOf(args[2]);
                 skill = Skills.getSkillType(args[1]);
                 String message;
@@ -78,10 +86,13 @@ public class AddlevelsCommand implements CommandExecutor{
                 }
 
                 sender.sendMessage(message);
-                modifiedPlayer.sendMessage(ChatColor.GREEN + "You were awarded " + levels + " levels in " + skillName + "!"); //TODO: Needs more locale.
-            }
 
-            return true;
+                if (modifiedPlayer.isOnline()) {
+                    ((Player) modifiedPlayer).sendMessage(ChatColor.GREEN + "You were awarded " + levels + " levels in " + skillName + "!"); //TODO: Needs more locale.
+                }
+
+                return true;
+            }
 
         default:
             sender.sendMessage(usage);

+ 4 - 7
src/main/java/com/gmail/nossr50/commands/general/AddxpCommand.java

@@ -57,13 +57,10 @@ public class AddxpCommand implements CommandExecutor {
                     else {
                         Skills.XpCheckSkill(skill, modifiedPlayer);
                     }
+
+                    return true;
                 }
             }
-            else {
-                sender.sendMessage(usage);
-            }
-
-            return true;
 
         case 3:
             modifiedPlayer = plugin.getServer().getPlayer(args[0]);
@@ -94,9 +91,9 @@ public class AddxpCommand implements CommandExecutor {
                 else {
                     Skills.XpCheckSkill(skill, modifiedPlayer);
                 }
-            }
 
-            return true;
+                return true;
+            }
 
         default:
             sender.sendMessage(usage);

+ 15 - 12
src/main/java/com/gmail/nossr50/commands/general/InspectCommand.java

@@ -1,5 +1,6 @@
 package com.gmail.nossr50.commands.general;
 
+import org.bukkit.OfflinePlayer;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
@@ -22,7 +23,7 @@ public class InspectCommand implements CommandExecutor {
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        Player target;
+        OfflinePlayer target;
         PlayerProfile PP;
         String usage = "Proper usage is /inspect <playername>"; //TODO: Needs more locale.
 
@@ -32,24 +33,26 @@ public class InspectCommand implements CommandExecutor {
 
         switch (args.length) {
         case 1:
-            target = plugin.getServer().getPlayer(args[0]);
+            target = plugin.getServer().getOfflinePlayer(args[0]);
+            PP = Users.getProfile(target);
 
-            if (target != null) {
-                PP = Users.getProfile(target);
+            if (target.isOnline()) {
+                Player player = (Player) target;
 
-                if (sender instanceof Player && !sender.isOp() && !m.isNear(((Player) sender).getLocation(), target.getLocation(), 5.0)) {
+                if (sender instanceof Player && !sender.isOp() && !m.isNear(((Player) sender).getLocation(), player.getLocation(), 5.0)) {
                     sender.sendMessage(mcLocale.getString("Inspect.TooFar"));
                     return true;
                 }
 
                 sender.sendMessage(mcLocale.getString("Inspect.Stats", new Object[] { target.getName() }));
-                CommandHelper.printGatheringSkills(target, sender);
-                CommandHelper.printCombatSkills(target, sender);
-                CommandHelper.printMiscSkills(target, sender);
+                CommandHelper.printGatheringSkills(player, sender);
+                CommandHelper.printCombatSkills(player, sender);
+                CommandHelper.printMiscSkills(player, sender);
                 sender.sendMessage(mcLocale.getString("mcPlayerListener.PowerLevel", new Object[] { PP.getPowerLevel() }));
+
+                return true;
             }
             else {
-                PP = Users.getOfflineProfile(args[0]);
 
                 if (sender instanceof Player && !sender.isOp()) {
                     sender.sendMessage(mcLocale.getString("Inspect.Offline"));
@@ -57,7 +60,7 @@ public class InspectCommand implements CommandExecutor {
                 }
 
                 if (!PP.isLoaded()) {
-                    sender.sendMessage(mcLocale.getString("Inspect.DoesNotExist"));
+                    sender.sendMessage(mcLocale.getString("Commands.DoesNotExist"));
                     return true;
                 }
 
@@ -80,9 +83,9 @@ public class InspectCommand implements CommandExecutor {
                 sender.sendMessage(mcLocale.getString("Stats.MiscHeader"));
                 sender.sendMessage(mcLocale.getString("m.SkillStats", new Object[] { mcLocale.getString("mcPlayerListener.AcrobaticsSkill"), PP.getSkillLevel(SkillType.ACROBATICS), PP.getSkillXpLevel(SkillType.ACROBATICS), PP.getXpToLevel(SkillType.ACROBATICS) }));
                 sender.sendMessage(mcLocale.getString("m.SkillStats", new Object[] { mcLocale.getString("mcPlayerListener.RepairSkill"), PP.getSkillLevel(SkillType.REPAIR), PP.getSkillXpLevel(SkillType.REPAIR), PP.getXpToLevel(SkillType.REPAIR) }));
-            }
 
-            return true;
+                return true;
+            }
 
         default:
             sender.sendMessage(usage);

+ 14 - 55
src/main/java/com/gmail/nossr50/commands/general/McstatsCommand.java

@@ -1,77 +1,36 @@
 package com.gmail.nossr50.commands.general;
 
-import org.bukkit.ChatColor;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.Users;
-import com.gmail.nossr50.mcPermissions;
+import com.gmail.nossr50.commands.CommandHelper;
 import com.gmail.nossr50.datatypes.PlayerProfile;
-import com.gmail.nossr50.datatypes.SkillType;
 import com.gmail.nossr50.locale.mcLocale;
-import com.gmail.nossr50.skills.Skills;
 
 public class McstatsCommand implements CommandExecutor {
 
-	@Override
-	public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
 
-		Player player = null;
-        if (sender instanceof Player) {
-            player = (Player) sender;
-        }
-
-        if (!(sender instanceof Player)) {
-            sender.sendMessage("This command does not support console useage."); //TODO: Needs more locale.
+        if (CommandHelper.noConsoleUsage(sender)) {
             return true;
         }
 
-		PlayerProfile PP = Users.getProfile(player);
-
-		player.sendMessage(mcLocale.getString("mcPlayerListener.YourStats"));
-
-		player.sendMessage(mcLocale.getString("mcPlayerListener.NoSkillNote"));
+        Player player = (Player) sender;
+        PlayerProfile PP = Users.getProfile(player);
 
-		ChatColor header = ChatColor.GOLD;
+        player.sendMessage(mcLocale.getString("mcPlayerListener.YourStats"));
+        player.sendMessage(mcLocale.getString("mcPlayerListener.NoSkillNote"));
 
-		if (Skills.hasGatheringSkills(player)) {
-			player.sendMessage(header + "-=GATHERING SKILLS=-"); //TODO: Needs more locale.
-			if (mcPermissions.getInstance().excavation(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.ExcavationSkill"), PP.getSkillLevel(SkillType.EXCAVATION), PP.getSkillXpLevel(SkillType.EXCAVATION), PP.getXpToLevel(SkillType.EXCAVATION)));
-			if (mcPermissions.getInstance().fishing(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.FishingSkill"), PP.getSkillLevel(SkillType.FISHING), PP.getSkillXpLevel(SkillType.FISHING), PP.getXpToLevel(SkillType.FISHING)));
-			if (mcPermissions.getInstance().herbalism(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.HerbalismSkill"), PP.getSkillLevel(SkillType.HERBALISM), PP.getSkillXpLevel(SkillType.HERBALISM), PP.getXpToLevel(SkillType.HERBALISM)));
-			if (mcPermissions.getInstance().mining(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.MiningSkill"), PP.getSkillLevel(SkillType.MINING), PP.getSkillXpLevel(SkillType.MINING), PP.getXpToLevel(SkillType.MINING)));
-			if (mcPermissions.getInstance().woodcutting(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.WoodcuttingSkill"), PP.getSkillLevel(SkillType.WOODCUTTING), PP.getSkillXpLevel(SkillType.WOODCUTTING), PP.getXpToLevel(SkillType.WOODCUTTING)));
-		}
-		if (Skills.hasCombatSkills(player)) {
-			player.sendMessage(header + "-=COMBAT SKILLS=-"); //TODO: Needs more locale.
-			if (mcPermissions.getInstance().axes(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.AxesSkill"), PP.getSkillLevel(SkillType.AXES), PP.getSkillXpLevel(SkillType.AXES), PP.getXpToLevel(SkillType.AXES)));
-			if (mcPermissions.getInstance().archery(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.ArcherySkill"), PP.getSkillLevel(SkillType.ARCHERY), PP.getSkillXpLevel(SkillType.ARCHERY), PP.getXpToLevel(SkillType.ARCHERY)));
-			if (mcPermissions.getInstance().swords(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.SwordsSkill"), PP.getSkillLevel(SkillType.SWORDS), PP.getSkillXpLevel(SkillType.SWORDS), PP.getXpToLevel(SkillType.SWORDS)));
-			if (mcPermissions.getInstance().taming(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.TamingSkill"), PP.getSkillLevel(SkillType.TAMING), PP.getSkillXpLevel(SkillType.TAMING), PP.getXpToLevel(SkillType.TAMING)));
-			if (mcPermissions.getInstance().unarmed(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.UnarmedSkill"), PP.getSkillLevel(SkillType.UNARMED), PP.getSkillXpLevel(SkillType.UNARMED), PP.getXpToLevel(SkillType.UNARMED)));
-		}
+        CommandHelper.printGatheringSkills(player);
+        CommandHelper.printCombatSkills(player);
+        CommandHelper.printMiscSkills(player);
 
-		if (Skills.hasMiscSkills(player)) {
-			player.sendMessage(header + "-=MISC SKILLS=-"); //TODO: Needs more locale.
-			if (mcPermissions.getInstance().acrobatics(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.AcrobaticsSkill"), PP.getSkillLevel(SkillType.ACROBATICS), PP.getSkillXpLevel(SkillType.ACROBATICS), PP.getXpToLevel(SkillType.ACROBATICS)));
-			if (mcPermissions.getInstance().repair(player))
-				player.sendMessage(Skills.getSkillStats(mcLocale.getString("mcPlayerListener.RepairSkill"), PP.getSkillLevel(SkillType.REPAIR), PP.getSkillXpLevel(SkillType.REPAIR), PP.getXpToLevel(SkillType.REPAIR)));
-		}
-		player.sendMessage(mcLocale.getString("mcPlayerListener.PowerLevel") + ChatColor.GREEN + (PP.getPowerLevel()));
+        player.sendMessage(mcLocale.getString("mcPlayerListener.PowerLevel", new Object[] { PP.getPowerLevel() }));
 
-		return true;
-	}
+        return true;
+    }
 }

+ 83 - 97
src/main/java/com/gmail/nossr50/commands/general/MmoeditCommand.java

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.commands.general;
 
 import org.bukkit.ChatColor;
+import org.bukkit.OfflinePlayer;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
@@ -8,109 +9,94 @@ import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.Users;
 import com.gmail.nossr50.m;
-import com.gmail.nossr50.mcPermissions;
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.commands.CommandHelper;
 import com.gmail.nossr50.datatypes.PlayerProfile;
+import com.gmail.nossr50.datatypes.SkillType;
 import com.gmail.nossr50.locale.mcLocale;
 import com.gmail.nossr50.skills.Skills;
 
 public class MmoeditCommand implements CommandExecutor {
+    private final mcMMO plugin;
 
-	@Override
-	public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-		Player player = null;
-        if (sender instanceof Player) 
-        {
-            player = (Player) sender;
+    public MmoeditCommand(mcMMO instance) {
+        this.plugin = instance;
+    }
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        OfflinePlayer modifiedPlayer;
+        PlayerProfile PP;
+        int newValue;
+        SkillType skill;
+        String skillName;
+        String usage = ChatColor.RED + "Proper usage is /mmoedit <playername> <skillname> <newvalue>"; //TODO: Needs more locale.
+
+        if (CommandHelper.noCommandPermissions(sender, "mcmmo.tools.mmoedit")) {
+            return true;
         }
-		
-        if (player != null && !mcPermissions.getInstance().mmoedit(player)) {
-			sender.sendMessage("This command requires permissions."); //TODO: Needs more locale.
-			return true;
-		}
-
-		if (!(sender instanceof Player)) 
-		{
-			if (args.length < 2) 
-			{
-				System.out.println("Usage is /mmoedit playername skillname newvalue"); //TODO: Needs more locale.
-				return true;
-			} else if (args.length == 3)
-			{
-			    PlayerProfile PPt = null;
-			    
-			    if(Users.players.containsKey(args[0].toLowerCase())) {
-			        PPt = Users.players.get(args[0].toLowerCase());
-			    } else
-			        PPt = Users.getOfflineProfile(args[0]); //Only grab offline profile if the above failed
-			        
-			    if(!PPt.isLoaded())
-		        {
-		            sender.sendMessage("Player does not exist in the database!"); //TODO: Needs more locale.
-		            return true;
-		        }
-			    
-				if (m.isInt(args[2]) && Skills.isSkill(args[1])) 
-				{
-					int newvalue = Integer.valueOf(args[2]);
-					Users.getOfflineProfile(args[0]).modifyskill(Skills.getSkillType(args[1]), newvalue);
-					System.out.println(args[1] + " has been modified for " + args[0] + "."); //TODO: Needs more locale.
-				}
-			} else 
-			{
-				System.out.println("Usage is /mmoedit playername skillname newvalue"); //TODO: Needs more locale.
-			}
-
-			return true;
-		}
-
-		if (!mcPermissions.getInstance().mmoedit(player)) 
-		{
-			player.sendMessage(ChatColor.YELLOW + "[mcMMO] " + ChatColor.DARK_RED + mcLocale.getString("mcPlayerListener.NoPermission"));
-			return true;
-		}
-		
-		if (args.length < 2) 
-		{
-			player.sendMessage(ChatColor.RED + "Usage is /mmoedit playername skillname newvalue"); //TODO: Needs more locale.
-			return true;
-		}
-		if (args.length == 3) 
-		{
-		    PlayerProfile PPt = null;
-            
-            if(Users.players.containsKey(args[0].toLowerCase())) {
-                PPt = Users.players.get(args[0].toLowerCase());
+
+        switch (args.length) {
+        case 2:
+            if (sender instanceof Player) {
+                if (m.isInt(args[1]) && Skills.isSkill(args[0])) {
+                    modifiedPlayer = (Player) sender;
+                    newValue = Integer.valueOf(args[1]);
+                    skill = Skills.getSkillType(args[0]);
+                    PP = Users.getProfile(modifiedPlayer);
+
+                    if (skill.equals(SkillType.ALL)) {
+                        skillName = "all skills";
+                    }
+                    else {
+                        skillName = m.getCapitalized(skill.toString());
+                    }
+
+                    PP.modifySkill(skill, newValue);
+                    sender.sendMessage(ChatColor.GREEN + "Your level in " + skillName + " was set to " + newValue + "!"); //TODO: Needs more locale.
+
+                    return true;
+                }
+            }
+
+        case 3:
+            modifiedPlayer = plugin.getServer().getOfflinePlayer(args[0]);
+            String playerName = modifiedPlayer.getName();
+            PP = Users.getProfile(modifiedPlayer);
+
+            if (!PP.isLoaded()) {
+                sender.sendMessage(mcLocale.getString("Commands.DoesNotExist"));
+                return true;
             }
-            
-            if(PPt == null)
-                Users.getOfflineProfile(args[0]); //Only grab offline profile if the above failed
-            
-		    if(!PPt.isLoaded())
-	        {
-	            sender.sendMessage("Player does not exist in the database!"); //TODO: Needs more locale.
-	            return true;
-	        }
-		    
-			if (m.isInt(args[2]) && Skills.isSkill(args[1])) 
-			{
-				int newvalue = Integer.valueOf(args[2]);
-				PPt.modifyskill(Skills.getSkillType(args[1]), newvalue);
-				player.sendMessage(ChatColor.RED + args[1] + " has been modified for "+args[0]); //TODO: Needs more locale.
-			}
-		} else if (args.length == 2) 
-		{
-			if (m.isInt(args[1]) && Skills.isSkill(args[0])) 
-			{
-			    PlayerProfile PP = Users.getProfile(player);
-				int newvalue = Integer.valueOf(args[1]);
-				PP.modifyskill(Skills.getSkillType(args[0]), newvalue);
-				player.sendMessage(ChatColor.RED + args[0] + " has been modified."); //TODO: Needs more locale.
-			}
-		} else 
-		{
-			player.sendMessage(ChatColor.RED + "Usage is /mmoedit playername skillname newvalue"); //TODO: Needs more locale.
-		}
-
-		return true;
-	}
+
+            if (m.isInt(args[2]) && Skills.isSkill(args[1])) {
+                newValue = Integer.valueOf(args[2]);
+                skill = Skills.getSkillType(args[1]);
+                String message;
+
+                Users.getProfile(modifiedPlayer).modifySkill(skill, newValue);
+
+                if (skill.equals(SkillType.ALL)) {
+                    skillName = "all skills";
+                    message = ChatColor.RED + "All skills have been modified for " + playerName + "."; //TODO: Use locale
+                }
+                else {
+                    skillName = m.getCapitalized(skill.toString());
+                    message = ChatColor.RED + skillName + " has been modified for " + playerName + "."; //TODO: Use locale
+                }
+
+                sender.sendMessage(message);
+
+                if (modifiedPlayer.isOnline()) {
+                    ((Player) modifiedPlayer).sendMessage(ChatColor.GREEN + "Your level in " + skillName + " was set to " + newValue + "!"); //TODO: Needs more locale.
+                }
+
+                return true;
+            }
+
+        default:
+            sender.sendMessage(usage);
+            return true;
+        }
+    }
 }

+ 2 - 35
src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java

@@ -63,38 +63,6 @@ public class PlayerProfile {
     private String playerName;
     private String location = "plugins/mcMMO/FlatFileStuff/mcmmo.users";
 
-    public PlayerProfile(String name) {
-        hud = LoadProperties.defaulthud;
-        playerName = name;
-
-        for (AbilityType abilityType : AbilityType.values()) {
-            skillsDATS.put(abilityType, 0);
-        }
-
-        for (SkillType skillType : SkillType.values()) {
-            if (skillType != SkillType.ALL) {
-                skills.put(skillType, 0);
-                skillsXp.put(skillType, 0);
-            }
-        }
-
-        if (LoadProperties.useMySQL) {
-            if (!loadMySQL()) {
-                addMySQLPlayer();
-                loadMySQL(); //This is probably not needed anymore, could just delete. // So can we remove this whole function, or just this line?
-            }
-        }
-        else if (!load()) {
-            addPlayer();
-        }
-
-        lastlogin = ((Long) (System.currentTimeMillis() / 1000)).intValue();
-    }
-
-    /*
-     * Why do we even have this? The only time it's called, it's false.
-     * Why not combine the two?
-     */
     public PlayerProfile(String name, boolean addNew) {
         hud = LoadProperties.defaulthud;
         playerName = name;
@@ -113,7 +81,6 @@ public class PlayerProfile {
         if (LoadProperties.useMySQL) {
             if (!loadMySQL() && addNew) {
                 addMySQLPlayer();
-                loadMySQL(); //This is probably not needed anymore, could just delete. // So can we remove this whole function, or just this line?
             }
         }
         else if (!load() && addNew) {
@@ -151,7 +118,7 @@ public class PlayerProfile {
             }
             HashMap<Integer, ArrayList<String>> users = mcMMO.database.read("SELECT lastlogin, party FROM "+LoadProperties.MySQLtablePrefix+"users WHERE id = " + id);
                 //lastlogin = Integer.parseInt(users.get(1).get(0));
-                party = users.get(1).get(1);                
+                party = users.get(1).get(1);
             HashMap<Integer, ArrayList<String>> cooldowns = mcMMO.database.read("SELECT mining, woodcutting, unarmed, herbalism, excavation, swords, axes, blast_mining FROM "+LoadProperties.MySQLtablePrefix+"cooldowns WHERE user_id = " + id);
             /*
              * I'm still learning MySQL, this is a fix for adding a new table
@@ -1077,7 +1044,7 @@ public class PlayerProfile {
      * @param skillType Type of skill to modify
      * @param newValue New level value for the skill
      */
-    public void modifyskill(SkillType skillType, int newValue) {
+    public void modifySkill(SkillType skillType, int newValue) {
         if (skillType.equals(SkillType.ALL)) {
             for (SkillType skill : SkillType.values()) {
                 if (skill.equals(SkillType.ALL)) {

+ 26 - 1
src/main/java/com/gmail/nossr50/mcMMO.java

@@ -25,6 +25,7 @@ import java.io.InputStream;
 import java.util.HashMap;
 
 import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
 import org.bukkit.plugin.Plugin;
 import org.bukkit.plugin.PluginDescriptionFile;
 import org.bukkit.plugin.java.JavaPlugin;
@@ -167,6 +168,30 @@ public class mcMMO extends JavaPlugin {
         return Users.getProfile(player);
     }
 
+    /**
+     * Get profile of the player by name.
+     * </br>
+     * This function is designed for API usage.
+     *
+     * @param player Name of player whose profile to get
+     * @return the PlayerProfile object
+     */
+    public PlayerProfile getPlayerProfileByName(String playerName) {
+        return Users.getProfileByName(playerName);
+    }
+
+    /**
+     * Get profile of the offline player.
+     * </br>
+     * This function is designed for API usage.
+     *
+     * @param player Offline player whose profile to get
+     * @return the PlayerProfile object
+     */
+    public PlayerProfile getOfflinePlayerProfile(OfflinePlayer player) {
+        return Users.getProfile(player);
+    }
+
     /**
      * Things to be run when the plugin is disabled.
      */
@@ -284,7 +309,7 @@ public class mcMMO extends JavaPlugin {
         }
 
         if (LoadProperties.mmoeditEnable) {
-            getCommand("mmoedit").setExecutor(new MmoeditCommand());
+            getCommand("mmoedit").setExecutor(new MmoeditCommand(this));
         }
 
         if (LoadProperties.inspectEnable) {

+ 1 - 1
src/main/java/com/gmail/nossr50/runnables/RemoveProfileFromMemoryTask.java

@@ -16,7 +16,7 @@ public class RemoveProfileFromMemoryTask implements Runnable {
         String playerName = player.getName();
         //Check if the profile still exists (stuff like MySQL reconnection removes profiles)
         if (Users.players.containsKey(playerName.toLowerCase())) {
-            Users.getProfile(playerName).save(); //We save here so players don't quit/reconnect to cause lag
+            Users.getProfileByName(playerName).save(); //We save here so players don't quit/reconnect to cause lag
             Users.removeUserByName(playerName);
         }
     }

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

@@ -295,25 +295,6 @@ public class Skills {
             return false;
         }
     }
-    
-    /**
-     * Get the format string for 
-     * @param skillname
-     * @param level
-     * @param XP
-     * @param XPToLevel
-     * @return
-     */
-    public static String getSkillStats(String skillname, Integer level, Integer XP, Integer XPToLevel) {
-        //TODO: Ditch this function in favor of better locale setup.
-
-        ChatColor parColor = ChatColor.DARK_AQUA;
-        ChatColor xpColor = ChatColor.GRAY;
-        ChatColor LvlColor = ChatColor.GREEN;
-        ChatColor skillColor = ChatColor.YELLOW;
-
-        return skillColor + skillname + LvlColor + level + parColor +" XP" + "(" + xpColor + XP + parColor + "/" + xpColor + XPToLevel + parColor + ")";
-    }
 
     /**
      * Check if the player has any combat skill permissions.

+ 3 - 2
src/main/resources/locale/locale_de.properties

@@ -441,9 +441,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_en_us.properties

@@ -434,10 +434,11 @@ m.EffectsTaming1_1=Bone-whacking inspects wolves/ocelots
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
 Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
-m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
+m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_es_es.properties

@@ -433,9 +433,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_fi.properties

@@ -426,9 +426,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_fr.properties

@@ -433,9 +433,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_it.properties

@@ -435,9 +435,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_nl.properties

@@ -439,9 +439,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_pl.properties

@@ -433,9 +433,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 3 - 2
src/main/resources/locale/locale_pt_br.properties

@@ -440,9 +440,10 @@ m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
 m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Inspect.TooFar=[[RED]]You are too far away to inspect that player!
 Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
-Inspect.DoesNotExist = [[RED]]Player does not exist in the database!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
 Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
 Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
 Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
 Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
-Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.

+ 11 - 1
src/main/resources/locale/locale_ru.properties

@@ -420,4 +420,14 @@ XPRate.Event = [[GOLD]]mcMMO is currently in an XP rate event! XP rate is {0}x!
 BlastMining.Boom = [[GRAY]]**BOOM**
 Party.Forbidden=[mcMMO] Parties not permitted on this world (See Permissions)
 m.TamingSummonOcelotFailed=[[RED]]You have too many ocelots nearby to summon any more.
-m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
+m.ArcherySkillShot=[[RED]]Skill Shot Bonus Damage: [[YELLOW]]{0}%
+m.SkillStats=[[YELLOW]]{0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
+Inspect.TooFar=[[RED]]You are too far away to inspect that player!
+Inspect.Offline = [[RED]]That player is offline, inspecting offline players is limited to Ops!
+Commands.DoesNotExist = [[RED]]Player does not exist in the database!
+Inspect.Stats=[[GREEN]]mcMMO Stats for [[YELLOW]]{0}
+Inspect.OfflineStats=mcMMO Stats for Offline Player [[YELLOW]]{0}
+Stats.GatheringHeader=[[GOLD]]-=GATHERING SKILLS=-
+Stats.CombatHeader=[[GOLD]]-=COMBAT SKILLS=-
+Stats.MiscHeader=[[GOLD]]-=MISC SKILLS=-
+Commands.NoConsole=This command does not support console usage.