diff --git a/Changelog.txt b/Changelog.txt index b34693412..69119e735 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -26,6 +26,7 @@ Version 1.4.07-dev ! Admin and Party chat prefixes are now customizable ! Changed the color of party leader names in Party chat ! Improved profile saving + ! Improved partial name matcher ! Slightly improved update checker feedback ! Updated localization files ! Party item share category states are now saved when the server shuts down. diff --git a/src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java b/src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java index 56520bcc4..35f97cb97 100644 --- a/src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/experience/ExperienceCommand.java @@ -15,6 +15,7 @@ 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.commands.CommandUtils; import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.skills.SkillUtils; @@ -65,11 +66,12 @@ public abstract class ExperienceCommand implements TabExecutor { return true; } - mcMMOPlayer = UserManager.getPlayer(args[0]); + String playerName = Misc.getMatchedPlayerName(args[0]); + McMMOPlayer mcMMOPlayer = UserManager.getPlayerExact(playerName); // 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 = mcMMO.getDatabaseManager().loadPlayerProfile(args[0], false); + profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, false); if (CommandUtils.unloadedProfile(sender, profile)) { return true; @@ -84,7 +86,7 @@ public abstract class ExperienceCommand implements TabExecutor { editValues(); } - handleSenderMessage(sender, args[0]); + handleSenderMessage(sender, playerName); cleanUp(); return true; diff --git a/src/main/java/com/gmail/nossr50/commands/party/PartyChangeOwnerCommand.java b/src/main/java/com/gmail/nossr50/commands/party/PartyChangeOwnerCommand.java index cb314515a..1ebcc5607 100644 --- a/src/main/java/com/gmail/nossr50/commands/party/PartyChangeOwnerCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/party/PartyChangeOwnerCommand.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import com.gmail.nossr50.datatypes.party.Party; import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.party.PartyManager; +import com.gmail.nossr50.util.Misc; import com.gmail.nossr50.util.player.UserManager; public class PartyChangeOwnerCommand implements CommandExecutor { @@ -16,13 +17,14 @@ public class PartyChangeOwnerCommand implements CommandExecutor { switch (args.length) { case 2: Party playerParty = UserManager.getPlayer((Player) sender).getParty(); + String targetName = Misc.getMatchedPlayerName(args[1]); - if (!playerParty.getMembers().contains(args[1])) { - sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", args[1])); + if (!playerParty.getMembers().contains(targetName)) { + sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetName)); return true; } - PartyManager.setPartyLeader(args[1], playerParty); + PartyManager.setPartyLeader(targetName, playerParty); return true; default: diff --git a/src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java b/src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java index 714d1beb2..b902136ed 100644 --- a/src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java @@ -9,6 +9,7 @@ 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.Misc; import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.player.UserManager; @@ -17,9 +18,10 @@ public class PartyInviteCommand implements CommandExecutor { public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { switch (args.length) { case 2: - McMMOPlayer mcMMOTarget = UserManager.getPlayer(args[1]); + String playerName = Misc.getMatchedPlayerName(args[1]); + McMMOPlayer mcMMOTarget = UserManager.getPlayerExact(playerName); - if (!CommandUtils.checkPlayerExistence(sender, args[1], mcMMOTarget)) { + if (!CommandUtils.checkPlayerExistence(sender, playerName, mcMMOTarget)) { return false; } diff --git a/src/main/java/com/gmail/nossr50/commands/party/PartyJoinCommand.java b/src/main/java/com/gmail/nossr50/commands/party/PartyJoinCommand.java index 5c9c2c777..a560540bd 100644 --- a/src/main/java/com/gmail/nossr50/commands/party/PartyJoinCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/party/PartyJoinCommand.java @@ -9,6 +9,7 @@ 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.Misc; import com.gmail.nossr50.util.commands.CommandUtils; import com.gmail.nossr50.util.player.UserManager; @@ -64,7 +65,8 @@ public class PartyJoinCommand implements CommandExecutor { } private boolean canJoinParty(CommandSender sender, String targetName) { - mcMMOTarget = UserManager.getPlayer(targetName); + targetName = Misc.getMatchedPlayerName(targetName); + mcMMOTarget = UserManager.getPlayerExact(targetName); if (!CommandUtils.checkPlayerExistence(sender, targetName, mcMMOTarget)) { return false; diff --git a/src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java b/src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java index 7d4afd7b2..be912aa28 100644 --- a/src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java @@ -16,6 +16,7 @@ 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; @@ -32,11 +33,12 @@ public class InspectCommand implements TabExecutor { ScoreboardManager.setupPlayerScoreboard(sender.getName()); } - McMMOPlayer mcMMOPlayer = UserManager.getPlayer(args[0]); + String playerName = Misc.getMatchedPlayerName(args[0]); + McMMOPlayer mcMMOPlayer = UserManager.getPlayerExact(playerName); // 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) { - PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(args[0], false); // Temporary Profile + PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, false); // Temporary Profile if (CommandUtils.inspectOffline(sender, profile, Permissions.inspectOffline(sender))) { return true; @@ -47,7 +49,7 @@ public class InspectCommand implements TabExecutor { return true; } - sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", args[0])); + sender.sendMessage(LocaleLoader.getString("Inspect.OfflineStats", playerName)); sender.sendMessage(LocaleLoader.getString("Stats.Header.Gathering")); CommandUtils.displaySkill(sender, profile, SkillType.EXCAVATION); diff --git a/src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java b/src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java index 081dc3a6a..6a3ace8b5 100644 --- a/src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java +++ b/src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java @@ -14,6 +14,7 @@ import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.config.Config; import com.gmail.nossr50.datatypes.player.McMMOPlayer; 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; @@ -50,8 +51,8 @@ public class McrankCommand implements TabExecutor { return true; } - String playerName = args[0]; - McMMOPlayer mcMMOPlayer = UserManager.getPlayer(playerName); + String playerName = Misc.getMatchedPlayerName(args[0]); + McMMOPlayer mcMMOPlayer = UserManager.getPlayerExact(playerName); if (mcMMOPlayer != null) { playerName = mcMMOPlayer.getPlayer().getName(); diff --git a/src/main/java/com/gmail/nossr50/util/Misc.java b/src/main/java/com/gmail/nossr50/util/Misc.java index 0576c9af2..a2088221a 100644 --- a/src/main/java/com/gmail/nossr50/util/Misc.java +++ b/src/main/java/com/gmail/nossr50/util/Misc.java @@ -1,5 +1,6 @@ package com.gmail.nossr50.util; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Random; @@ -260,6 +261,49 @@ public final class Misc { return ((Furnace) furnaceState).getInventory().getResult(); } + /** + * Attempts to match any player names with the given name, and returns a list of all possibly matches. + * + * This list is not sorted in any particular order. + * If an exact match is found, the returned list will only contain a single result. + * + * @param partialName Name to match + * @return List of all possible names + */ + public static List matchPlayer(String partialName) { + List matchedPlayers = new ArrayList(); + + for (String iterPlayerName : mcMMO.getDatabaseManager().getStoredUsers()) { + if (partialName.equalsIgnoreCase(iterPlayerName)) { + // Exact match + matchedPlayers.clear(); + matchedPlayers.add(iterPlayerName); + break; + } + if (iterPlayerName.toLowerCase().contains(partialName.toLowerCase())) { + // Partial match + matchedPlayers.add(iterPlayerName); + } + } + + return matchedPlayers; + } + + /** + * Get a matched player name if one was found in the database. + * + * @param partialName Name to match + * @return Matched name or {@code partialName} if no match was found + */ + public static String getMatchedPlayerName(String partialName) { + List matches = matchPlayer(partialName); + + if (matches.size() == 1) { + partialName = matches.get(0); + } + return partialName; + } + public static boolean noErrorsInConfig(List issues) { for (String issue : issues) { mcMMO.p.getLogger().warning(issue); diff --git a/src/main/java/com/gmail/nossr50/util/player/UserManager.java b/src/main/java/com/gmail/nossr50/util/player/UserManager.java index c6b691ecd..9f4120d54 100644 --- a/src/main/java/com/gmail/nossr50/util/player/UserManager.java +++ b/src/main/java/com/gmail/nossr50/util/player/UserManager.java @@ -9,8 +9,8 @@ import java.util.Set; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; -import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.datatypes.player.McMMOPlayer; +import com.gmail.nossr50.util.Misc; public final class UserManager { private final static Map players = new HashMap(); @@ -78,15 +78,25 @@ public final class UserManager { * @return the player's McMMOPlayer object */ public static McMMOPlayer getPlayer(String playerName) { - List matches = mcMMO.p.getServer().matchPlayer(playerName); + List matches = Misc.matchPlayer(playerName); if (matches.size() == 1) { - playerName = matches.get(0).getName(); + playerName = matches.get(0); } return players.get(playerName); } + /** + * Get the McMMOPlayer of a player by the exact name. + * + * @param playerName The exact name of the player whose McMMOPlayer to retrieve + * @return the player's McMMOPlayer object + */ + public static McMMOPlayer getPlayerExact(String playerName) { + return players.get(playerName); + } + /** * Get the McMMOPlayer of a player. *