From 59a75c455371a56fe4602f4e428a2bb7f9429376 Mon Sep 17 00:00:00 2001
From: NorbiPeti
+ * The class for holding data common to all TBMC plugins
+ *
+ * Listen to the load and save events from this package to load and save plugin-specific data
+ *
+ * This event gets called when a new player joins. After this event, the
+ * {@link TBMCPlayerSaveEvent} will be called.
+ *
+ * This method adds a plugin's commands to help and sets their executor.
+ *
+ * The command must be registered in the caller plugin's plugin.yml. Otherwise the plugin will output a messsage to console.
+ *
+ * Using this method after the server is done loading will have no effect.
+ *
+ * Add player information for {@link PlayerInfoCommand}. Only mods can see the given information.
+ *
+ * Add player information for hover text at {@link ChatProcessing}. Every online player can see the given information.
+ *
- * Listen to the load and save events from this package to load and save plugin-specific data + * Use {@link #asPluginPlayer(Class)} to get plugin-specific data *
* * @author Norbi * */ -public class TBMCPlayer { +public class TBMCPlayer implements AutoCloseable { private static final String TBMC_PLAYERS_DIR = "TBMC/players"; - public String PlayerName; + private HashMap
+ * Gets a player data entry for the caller plugin returning the desired type.
+ * It will automatically determine the key and the return type.
+ * Usage:
+ *
+ * {@code + * public String getPlayerName() { + * return getData(); + * } + *+ * + * @return The value or null if not found + */ + @SuppressWarnings("unchecked") + protected
+ * {@code + * public String setPlayerName(String value) { + * return setData(value); + * } + *+ * + * @param value + * The value to set + */ + protected void setData(Object value) { + StackTraceElement st = new Exception().getStackTrace()[0]; + String mname = st.getMethodName(); + if (!mname.startsWith("set")) + throw new UnsupportedOperationException("Can only use setData from a setXYZ method"); + LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value); + } + + /** + * Gets the player's Minecraft name + * + * @return The player's Minecraft name + */ + public String getPlayerName() { + return getData(); + } + + /** + * Sets the player's Minecraft name + * + * @param playerName + * the new name + */ + public void setPlayerName(String playerName) { + setData(playerName); + } + + private UUID uuid; // Do not save it in the file + + /** + * Get the player's UUID + * + * @return The Minecraft UUID of the player + */ + public UUID getUuid() { + return uuid; + } + + /** + * Gets the TBMCPlayer object as a specific plugin player, keeping it's data + * + * @param cl + * @return + */ + public
+ * {@code + * try(TBMCPlayer player = GetPlayer(p)) + * { + * ... + * } + *+ * * @param p * The Player object * @return The {@link TBMCPlayer} object for the player */ - public static TBMCPlayer GetPlayer(OfflinePlayer p) { - if (TBMCPlayer.OnlinePlayers.containsKey(p.getUniqueId())) - return TBMCPlayer.OnlinePlayers.get(p.getUniqueId()); + public static TBMCPlayer getPlayer(OfflinePlayer p) { + if (TBMCPlayer.LoadedPlayers.containsKey(p.getUniqueId())) + return TBMCPlayer.LoadedPlayers.get(p.getUniqueId()); else - return TBMCPlayer.LoadPlayer(p); + return TBMCPlayer.loadPlayer(p); } - public static TBMCPlayer LoadPlayer(OfflinePlayer p) { - if (OnlinePlayers.containsKey(p.getUniqueId())) - return OnlinePlayers.get(p.getUniqueId()); + /** + * Only intended to use from ButtonCore + */ + public static TBMCPlayer loadPlayer(OfflinePlayer p) { + if (LoadedPlayers.containsKey(p.getUniqueId())) + return LoadedPlayers.get(p.getUniqueId()); File file = new File(TBMC_PLAYERS_DIR); file.mkdirs(); file = new File(TBMC_PLAYERS_DIR, p.getUniqueId().toString() + ".yml"); if (!file.exists()) - return AddPlayer(p); + return addPlayer(p); else { final YamlConfiguration yc = new YamlConfiguration(); try { @@ -87,25 +183,26 @@ public class TBMCPlayer { return null; } TBMCPlayer player = new TBMCPlayer(); - player.UUID = p.getUniqueId(); - player.PlayerName = yc.getString("playername"); - System.out.println("Player name: " + player.PlayerName); - if (player.PlayerName == null) { - player.PlayerName = p.getName(); - System.out.println("Player name saved: " + player.PlayerName); - } else if (!p.getName().equals(player.PlayerName)) { - System.out.println("Renaming " + player.PlayerName + " to " + p.getName()); + player.uuid = p.getUniqueId(); + player.data.putAll(yc.getValues(true)); + Bukkit.getLogger().info("Loaded player: " + player.getPlayerName()); + if (player.getPlayerName() == null) { + player.setPlayerName(p.getName()); + Bukkit.getLogger().info("Player name saved: " + player.getPlayerName()); + } else if (!p.getName().equals(player.getPlayerName())) { + Bukkit.getLogger().info("Renaming " + player.getPlayerName() + " to " + p.getName()); TownyUniverse tu = Towny.getPlugin(Towny.class).getTownyUniverse(); - Resident resident = tu.getResidentMap().get(player.PlayerName); + Resident resident = tu.getResidentMap().get(player.getPlayerName()); if (resident == null) - System.out.println("Resident not found - couldn't rename in Towny."); + Bukkit.getLogger().warning("Resident not found - couldn't rename in Towny."); else if (tu.getResidentMap().contains(p.getName())) - System.out.println("Target resident name is already in use."); // TODO: Handle + Bukkit.getLogger().warning("Target resident name is already in use."); // TODO: Handle else resident.setName(p.getName()); - player.PlayerName = p.getName(); - System.out.println("Renaming done."); + player.setPlayerName(p.getName()); + Bukkit.getLogger().info("Renaming done."); } + LoadedPlayers.put(p.getUniqueId(), player); // Load in other plugins Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerLoadEvent(yc, player)); @@ -113,38 +210,58 @@ public class TBMCPlayer { } } - static TBMCPlayer AddPlayer(OfflinePlayer p) { + /** + * Only intended to use from ButtonCore + */ + public static TBMCPlayer addPlayer(OfflinePlayer p) { TBMCPlayer player = new TBMCPlayer(); - player.UUID = p.getUniqueId(); - player.PlayerName = p.getName(); - OnlinePlayers.put(p.getUniqueId(), player); + player.uuid = p.getUniqueId(); + player.setPlayerName(p.getName()); + LoadedPlayers.put(p.getUniqueId(), player); Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerAddEvent(player)); - SavePlayer(player); + savePlayer(player); return player; } - public static void SavePlayer(TBMCPlayer player) { + /** + * Only intended to use from ButtonCore + */ + public static void savePlayer(TBMCPlayer player) { YamlConfiguration yc = new YamlConfiguration(); - yc.set("playername", player.PlayerName); + for (Entry
+ * {@code + * try(TBMCPlayer player = getFromName(p)) + * { + * ... + * } + *+ * * @param name * The player's name * @return The {@link TBMCPlayer} object for the player */ - public static TBMCPlayer GetFromName(String name) { + public static TBMCPlayer getFromName(String name) { @SuppressWarnings("deprecation") OfflinePlayer p = Bukkit.getOfflinePlayer(name); if (p != null) @@ -146,7 +157,7 @@ public class TBMCPlayer implements AutoCloseable { * *
* {@code - * try(TBMCPlayer player = GetPlayer(p)) + * try(TBMCPlayer player = getPlayer(p)) * { * ... * } From 24d778e69d6933311738c80be0323657728dda09 Mon Sep 17 00:00:00 2001 From: NorbiPetiDate: Sat, 29 Oct 2016 19:05:50 +0200 Subject: [PATCH 09/21] Added UUID overload for getPlayer --- .../java/buttondevteam/lib/TBMCPlayer.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 6b52160..94ee5be 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -24,7 +24,7 @@ import com.palmergames.bukkit.towny.object.TownyUniverse; * @author Norbi * */ -public class TBMCPlayer implements AutoCloseable { //TODO: Load player data in Core +public class TBMCPlayer implements AutoCloseable { private static final String TBMC_PLAYERS_DIR = "TBMC/players"; private HashMap data = new HashMap<>(); @@ -127,8 +127,8 @@ public class TBMCPlayer implements AutoCloseable { //TODO: Load player data in C private static HashMap LoadedPlayers = new HashMap<>(); /** - * This method returns a TBMC player from their name. Calling this method may return an offline player which will load it, therefore it's highly recommended to use {@link #close()} to unload the player data. Using - * try-with-resources may be the easiest way to achieve this. Example: + * This method returns a TBMC player from their name. Calling this method may return an offline player which will load it, therefore it's highly recommended to use {@link #close()} to unload the + * player data. Using try-with-resources may be the easiest way to achieve this. Example: * * * {@code @@ -174,6 +174,29 @@ public class TBMCPlayer implements AutoCloseable { //TODO: Load player data in C return TBMCPlayer.loadPlayer(p); } + /** + * This method returns a TBMC player from a Bukkit player. Calling this method may return an offline player, therefore it's highly recommended to use {@link #close()} to unload the player data. + * Using try-with-resources may be the easiest way to achieve this. Example: + * + *+ * {@code + * try(TBMCPlayer player = getPlayer(p)) + * { + * ... + * } + *+ * + * @param p + * The Player object + * @return The {@link TBMCPlayer} object for the player + */ + public static TBMCPlayer getPlayer(UUID uuid) { + if (TBMCPlayer.LoadedPlayers.containsKey(uuid)) + return TBMCPlayer.LoadedPlayers.get(uuid); + else + return TBMCPlayer.loadPlayer(Bukkit.getOfflinePlayer(uuid)); + } + /** * Only intended to use from ButtonCore */ From ee40f7b5827e48be1725ecf14f3386f6727c57b9 Mon Sep 17 00:00:00 2001 From: NorbiPetiDate: Sat, 29 Oct 2016 19:19:40 +0200 Subject: [PATCH 10/21] Added getPlayerAs --- .../java/buttondevteam/lib/TBMCPlayer.java | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 94ee5be..7181405 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -108,10 +108,12 @@ public class TBMCPlayer implements AutoCloseable { } /** - * Gets the TBMCPlayer object as a specific plugin player, keeping it's data + * Gets the TBMCPlayer object as a specific plugin player, keeping it's data * * + * @param p + * Player to get * @param cl - * @return + * The TBMCPlayer subclass */ public T asPluginPlayer(Class cl) { T obj = null; @@ -175,7 +177,7 @@ public class TBMCPlayer implements AutoCloseable { } /** - * This method returns a TBMC player from a Bukkit player. Calling this method may return an offline player, therefore it's highly recommended to use {@link #close()} to unload the player data. + * This method returns a TBMC player from a player UUID. Calling this method may return an offline player, therefore it's highly recommended to use {@link #close()} to unload the player data. * Using try-with-resources may be the easiest way to achieve this. Example: * * @@ -197,6 +199,36 @@ public class TBMCPlayer implements AutoCloseable { return TBMCPlayer.loadPlayer(Bukkit.getOfflinePlayer(uuid)); } + /** + * This is a convenience method for {@link #getPlayer(OfflinePlayer)}.{@link #asPluginPlayer(Class)}. + * + * See those methods for more information. + * + * @param p + * Player to get + * @param cl + * The TBMCPlayer subclass + * @return The player as a subtype of TBMCPlayer + */ + public staticTBMCPlayer getPlayerAs(OfflinePlayer p, Class cl) { + return getPlayer(p).asPluginPlayer(cl); + } + + /** + * This is a convenience method for {@link #getPlayer(UUID)}.{@link #asPluginPlayer(Class)} + * + * See those methods for more information. + * + * @param uuid + * The UUID of the player to get + * @param cl + * The TBMCPlayer subclass + * @return The player as a subtype of TBMCPlayer + */ + public static TBMCPlayer getPlayerAs(UUID uuid, Class cl) { + return getPlayer(uuid).asPluginPlayer(cl); + } + /** * Only intended to use from ButtonCore */ From 981b2e70dbe09ab978d7869095adf6981cc7539e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 29 Oct 2016 19:20:42 +0200 Subject: [PATCH 11/21] Fixed return type --- src/main/java/buttondevteam/lib/TBMCPlayer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 7181405..65fe19d 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -210,7 +210,7 @@ public class TBMCPlayer implements AutoCloseable { * The TBMCPlayer subclass * @return The player as a subtype of TBMCPlayer */ - public static TBMCPlayer getPlayerAs(OfflinePlayer p, Class cl) { + public static T getPlayerAs(OfflinePlayer p, Class cl) { return getPlayer(p).asPluginPlayer(cl); } @@ -225,7 +225,7 @@ public class TBMCPlayer implements AutoCloseable { * The TBMCPlayer subclass * @return The player as a subtype of TBMCPlayer */ - public static TBMCPlayer getPlayerAs(UUID uuid, Class cl) { + public static T getPlayerAs(UUID uuid, Class cl) { return getPlayer(uuid).asPluginPlayer(cl); } From 2ebadbe5d413573c909eb02ade01d59d4624352e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sat, 29 Oct 2016 22:10:00 +0200 Subject: [PATCH 12/21] Moved GetSubCommands --- .../java/buttondevteam/lib/chat/TBMCChatAPI.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java b/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java index e5571df..c1804d9 100644 --- a/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java +++ b/src/main/java/buttondevteam/lib/chat/TBMCChatAPI.java @@ -1,6 +1,7 @@ package buttondevteam.lib.chat; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.HashMap; import java.util.Set; @@ -20,6 +21,20 @@ public class TBMCChatAPI { return commands; } + public static String[] GetSubCommands(TBMCCommandBase command) { + ArrayList cmds = new ArrayList (); + cmds.add("ยง6---- Subcommands ----"); + for (TBMCCommandBase cmd : TBMCChatAPI.GetCommands().values()) { + if (cmd.GetCommandPath().startsWith(command.GetCommandPath() + "/")) { + int ind = cmd.GetCommandPath().indexOf('/', command.GetCommandPath().length() + 2); + if (ind >= 0) + continue; + cmds.add(cmd.GetCommandPath().replace('/', ' ')); + } + } + return cmds.toArray(new String[cmds.size()]); + } + /** * * This method adds a plugin's commands to help and sets their executor. From daa7d29224089eccd8041a3c7333b7d58e4774ee Mon Sep 17 00:00:00 2001 From: NorbiPeti
+ * + *Date: Sat, 29 Oct 2016 22:39:15 +0200 Subject: [PATCH 13/21] There's a relocated dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 308183b..0c5e083 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ - From 0b12aebfe2f6c6b99c6980029fbf8144766f6472 Mon Sep 17 00:00:00 2001 From: NorbiPetiorg.apache.commons +commons-io commons-io 1.3.2 Date: Sun, 30 Oct 2016 00:23:16 +0200 Subject: [PATCH 14/21] Fixed NPE on player data access --- src/main/java/buttondevteam/lib/TBMCPlayer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 65fe19d..f2c2c06 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -251,6 +251,7 @@ public class TBMCPlayer implements AutoCloseable { TBMCPlayer player = new TBMCPlayer(); player.uuid = p.getUniqueId(); player.data.putAll(yc.getValues(true)); + LoadedPlayers.put(p.getUniqueId(), player); // Accessing any value requires it to be in the map Bukkit.getLogger().info("Loaded player: " + player.getPlayerName()); if (player.getPlayerName() == null) { player.setPlayerName(p.getName()); @@ -268,7 +269,6 @@ public class TBMCPlayer implements AutoCloseable { player.setPlayerName(p.getName()); Bukkit.getLogger().info("Renaming done."); } - LoadedPlayers.put(p.getUniqueId(), player); // Load in other plugins Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerLoadEvent(yc, player)); @@ -282,8 +282,8 @@ public class TBMCPlayer implements AutoCloseable { public static TBMCPlayer addPlayer(OfflinePlayer p) { TBMCPlayer player = new TBMCPlayer(); player.uuid = p.getUniqueId(); + LoadedPlayers.put(p.getUniqueId(), player); // Accessing any value requires it to be in the map player.setPlayerName(p.getName()); - LoadedPlayers.put(p.getUniqueId(), player); Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerAddEvent(player)); savePlayer(player); return player; From 44109db61f12c3b9f07b165f5e36d1374fedfe7a Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 30 Oct 2016 21:44:56 +0100 Subject: [PATCH 15/21] Added Enum data handling --- .../java/buttondevteam/lib/TBMCPlayer.java | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index f2c2c06..66d568e 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -47,7 +47,7 @@ public class TBMCPlayer implements AutoCloseable { */ @SuppressWarnings("unchecked") protected T getData() { - StackTraceElement st = new Exception().getStackTrace()[0]; + StackTraceElement st = new Exception().getStackTrace()[1]; String mname = st.getMethodName(); if (!mname.startsWith("get")) throw new UnsupportedOperationException("Can only use getData from a getXYZ method"); @@ -77,6 +77,54 @@ public class TBMCPlayer implements AutoCloseable { LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value); } + /** + * + * Gets a player data entry for the caller plugin returning the desired type, which is an enum
+ * + *
+ * It will automatically determine the key and the return type.
+ * Usage: + *+ * {@code + * public String getPlayerName() { + * return getData(); + * } + *+ * + * @return The value or null if not found + */ + protected> T getEnumData(Class cl) { + StackTraceElement st = new Exception().getStackTrace()[1]; + String mname = st.getMethodName(); + if (!mname.startsWith("get")) + throw new UnsupportedOperationException("Can only use getData from a getXYZ method"); + return Enum.valueOf(cl, + (String) LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase())); + } + + /** + * Sets a player data entry based on the caller method
+ * Usage: + *+ * {@code + * public String setPlayerName(String value) { + * return setData(value); + * } + *+ * + * @param value + * The value to set + */ + protected void setEnumData(Enum> value) { + StackTraceElement st = new Exception().getStackTrace()[0]; + String mname = st.getMethodName(); + if (!mname.startsWith("set")) + throw new UnsupportedOperationException("Can only use setData from a setXYZ method"); + LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value.toString()); + } + /** * Gets the player's Minecraft name * From be8685725cb56b1415b07d0d5194a1f1a372a5c4 Mon Sep 17 00:00:00 2001 From: NorbiPetiDate: Sun, 30 Oct 2016 22:57:59 +0100 Subject: [PATCH 16/21] Fixes IT WORKS! --- .../java/buttondevteam/lib/TBMCPlayer.java | 80 ++++++++++++++++--- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 66d568e..26d78da 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -51,7 +51,10 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("get")) throw new UnsupportedOperationException("Can only use getData from a getXYZ method"); - return (T) LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + Object ret = LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + if (Integer.class.isAssignableFrom(ret.getClass())) + throw new UnsupportedOperationException("For integers use getIntData()"); + return (T) ret; } /** @@ -86,8 +89,8 @@ public class TBMCPlayer implements AutoCloseable { * * * {@code - * public String getPlayerName() { - * return getData(); + * public String getSomeEnum() { + * return getEnumData(); * } ** @@ -97,9 +100,12 @@ public class TBMCPlayer implements AutoCloseable { StackTraceElement st = new Exception().getStackTrace()[1]; String mname = st.getMethodName(); if (!mname.startsWith("get")) - throw new UnsupportedOperationException("Can only use getData from a getXYZ method"); - return Enum.valueOf(cl, - (String) LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase())); + throw new UnsupportedOperationException("Can only use getEnumData from a getXYZ method"); + final String retstr = (String) LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + if (retstr != null) + return Enum.valueOf(cl, retstr); + else + return null; } /** @@ -109,8 +115,8 @@ public class TBMCPlayer implements AutoCloseable { * ** {@code - * public String setPlayerName(String value) { - * return setData(value); + * public String setSomeEnum(SomeEnum value) { + * return setEnumData(value); * } ** @@ -121,10 +127,65 @@ public class TBMCPlayer implements AutoCloseable { StackTraceElement st = new Exception().getStackTrace()[0]; String mname = st.getMethodName(); if (!mname.startsWith("set")) - throw new UnsupportedOperationException("Can only use setData from a setXYZ method"); + throw new UnsupportedOperationException("Can only use setEnumData from a setXYZ method"); LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value.toString()); } + /** + *+ * Gets a player data entry for the caller plugin returning the desired type, which is a number
+ * + *
+ * It will automatically determine the key and the return type.
+ * Usage: + *+ * {@code + * public short getNumber() { + * return getIntData(); + * } + *+ * + * @return The value or null if not found + */ + @SuppressWarnings("unchecked") + protectedT getIntData(Class cl) { + StackTraceElement st = new Exception().getStackTrace()[1]; + String mname = st.getMethodName(); + if (!mname.startsWith("get")) + throw new UnsupportedOperationException("Can only use getIntData from a getXYZ method"); + Object obj = LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + if (!(obj instanceof Integer)) + throw new UnsupportedOperationException("The retrieved object isn't a number: " + obj); + Integer int_ = (Integer) obj; + if (Short.class.isAssignableFrom(cl)) + return (T) (Object) int_.shortValue(); + else + return (T) (Object) int_; + } + + /** + * Sets a player data entry based on the caller method
+ * Usage: + * + * + *+ * {@code + * public String setNumber(short value) { + * return setIntData(value); + * } + *+ * + * @param value + * The value to set + */ + protected void setIntData(Number value) { + StackTraceElement st = new Exception().getStackTrace()[0]; + String mname = st.getMethodName(); + if (!mname.startsWith("set")) + throw new UnsupportedOperationException("Can only use setIntData from a setXYZ method"); + LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value); + } + /** * Gets the player's Minecraft name * @@ -167,6 +228,7 @@ public class TBMCPlayer implements AutoCloseable { T obj = null; try { obj = cl.newInstance(); + ((TBMCPlayer) obj).uuid = uuid; ((TBMCPlayer) obj).data.putAll(data); } catch (Exception e) { e.printStackTrace(); From a6477f5831e5b24e75f196486be13407786a3e04 Mon Sep 17 00:00:00 2001 From: NorbiPetiDate: Mon, 31 Oct 2016 17:23:18 +0100 Subject: [PATCH 17/21] Added getLoadedPlayers --- .../java/buttondevteam/lib/TBMCPlayer.java | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 26d78da..22c0564 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -51,7 +51,7 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("get")) throw new UnsupportedOperationException("Can only use getData from a getXYZ method"); - Object ret = LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + Object ret = getLoadedPlayers().get(uuid).data.get(mname.substring("get".length()).toLowerCase()); if (Integer.class.isAssignableFrom(ret.getClass())) throw new UnsupportedOperationException("For integers use getIntData()"); return (T) ret; @@ -77,7 +77,7 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("set")) throw new UnsupportedOperationException("Can only use setData from a setXYZ method"); - LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value); + getLoadedPlayers().get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value); } /** @@ -101,7 +101,7 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("get")) throw new UnsupportedOperationException("Can only use getEnumData from a getXYZ method"); - final String retstr = (String) LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + final String retstr = (String) getLoadedPlayers().get(uuid).data.get(mname.substring("get".length()).toLowerCase()); if (retstr != null) return Enum.valueOf(cl, retstr); else @@ -128,7 +128,7 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("set")) throw new UnsupportedOperationException("Can only use setEnumData from a setXYZ method"); - LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value.toString()); + getLoadedPlayers().get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value.toString()); } /** @@ -153,7 +153,7 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("get")) throw new UnsupportedOperationException("Can only use getIntData from a getXYZ method"); - Object obj = LoadedPlayers.get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + Object obj = getLoadedPlayers().get(uuid).data.get(mname.substring("get".length()).toLowerCase()); if (!(obj instanceof Integer)) throw new UnsupportedOperationException("The retrieved object isn't a number: " + obj); Integer int_ = (Integer) obj; @@ -183,7 +183,7 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("set")) throw new UnsupportedOperationException("Can only use setIntData from a setXYZ method"); - LoadedPlayers.get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value); + getLoadedPlayers().get(uuid).data.put(mname.substring("set".length()).toLowerCase(), value); } /** @@ -280,8 +280,8 @@ public class TBMCPlayer implements AutoCloseable { * @return The {@link TBMCPlayer} object for the player */ public static TBMCPlayer getPlayer(OfflinePlayer p) { - if (TBMCPlayer.LoadedPlayers.containsKey(p.getUniqueId())) - return TBMCPlayer.LoadedPlayers.get(p.getUniqueId()); + if (TBMCPlayer.getLoadedPlayers().containsKey(p.getUniqueId())) + return TBMCPlayer.getLoadedPlayers().get(p.getUniqueId()); else return TBMCPlayer.loadPlayer(p); } @@ -303,8 +303,8 @@ public class TBMCPlayer implements AutoCloseable { * @return The {@link TBMCPlayer} object for the player */ public static TBMCPlayer getPlayer(UUID uuid) { - if (TBMCPlayer.LoadedPlayers.containsKey(uuid)) - return TBMCPlayer.LoadedPlayers.get(uuid); + if (TBMCPlayer.getLoadedPlayers().containsKey(uuid)) + return TBMCPlayer.getLoadedPlayers().get(uuid); else return TBMCPlayer.loadPlayer(Bukkit.getOfflinePlayer(uuid)); } @@ -343,8 +343,8 @@ public class TBMCPlayer implements AutoCloseable { * Only intended to use from ButtonCore */ public static TBMCPlayer loadPlayer(OfflinePlayer p) { - if (LoadedPlayers.containsKey(p.getUniqueId())) - return LoadedPlayers.get(p.getUniqueId()); + if (getLoadedPlayers().containsKey(p.getUniqueId())) + return getLoadedPlayers().get(p.getUniqueId()); File file = new File(TBMC_PLAYERS_DIR); file.mkdirs(); file = new File(TBMC_PLAYERS_DIR, p.getUniqueId().toString() + ".yml"); @@ -361,7 +361,7 @@ public class TBMCPlayer implements AutoCloseable { TBMCPlayer player = new TBMCPlayer(); player.uuid = p.getUniqueId(); player.data.putAll(yc.getValues(true)); - LoadedPlayers.put(p.getUniqueId(), player); // Accessing any value requires it to be in the map + getLoadedPlayers().put(p.getUniqueId(), player); // Accessing any value requires it to be in the map Bukkit.getLogger().info("Loaded player: " + player.getPlayerName()); if (player.getPlayerName() == null) { player.setPlayerName(p.getName()); @@ -392,7 +392,7 @@ public class TBMCPlayer implements AutoCloseable { public static TBMCPlayer addPlayer(OfflinePlayer p) { TBMCPlayer player = new TBMCPlayer(); player.uuid = p.getUniqueId(); - LoadedPlayers.put(p.getUniqueId(), player); // Accessing any value requires it to be in the map + getLoadedPlayers().put(p.getUniqueId(), player); // Accessing any value requires it to be in the map player.setPlayerName(p.getName()); Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerAddEvent(player)); savePlayer(player); @@ -418,7 +418,7 @@ public class TBMCPlayer implements AutoCloseable { * Only intended to use from ButtonCore */ public static void joinPlayer(TBMCPlayer player) { - LoadedPlayers.put(player.uuid, player); + getLoadedPlayers().put(player.uuid, player); Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerJoinEvent(player)); } @@ -426,7 +426,7 @@ public class TBMCPlayer implements AutoCloseable { * Only intended to use from ButtonCore */ public static void quitPlayer(TBMCPlayer player) { - LoadedPlayers.remove(player.uuid); + getLoadedPlayers().remove(player.uuid); Bukkit.getServer().getPluginManager().callEvent(new TBMCPlayerQuitEvent(player)); } @@ -438,6 +438,10 @@ public class TBMCPlayer implements AutoCloseable { @Override public void close() throws Exception { if (!Bukkit.getPlayer(uuid).isOnline()) - LoadedPlayers.remove(uuid); + getLoadedPlayers().remove(uuid); + } + + public static HashMap getLoadedPlayers() { + return LoadedPlayers; } } From 076ee4ffd0dd3041b8c40d1c35dd22533442fd4e Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Mon, 31 Oct 2016 17:35:19 +0100 Subject: [PATCH 18/21] Fixed a stack trace index --- src/main/java/buttondevteam/lib/TBMCPlayer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 22c0564..5deb51f 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -73,7 +73,7 @@ public class TBMCPlayer implements AutoCloseable { * The value to set */ protected void setData(Object value) { - StackTraceElement st = new Exception().getStackTrace()[0]; + StackTraceElement st = new Exception().getStackTrace()[1]; String mname = st.getMethodName(); if (!mname.startsWith("set")) throw new UnsupportedOperationException("Can only use setData from a setXYZ method"); @@ -124,7 +124,7 @@ public class TBMCPlayer implements AutoCloseable { * The value to set */ protected void setEnumData(Enum> value) { - StackTraceElement st = new Exception().getStackTrace()[0]; + StackTraceElement st = new Exception().getStackTrace()[1]; String mname = st.getMethodName(); if (!mname.startsWith("set")) throw new UnsupportedOperationException("Can only use setEnumData from a setXYZ method"); @@ -179,7 +179,7 @@ public class TBMCPlayer implements AutoCloseable { * The value to set */ protected void setIntData(Number value) { - StackTraceElement st = new Exception().getStackTrace()[0]; + StackTraceElement st = new Exception().getStackTrace()[1]; String mname = st.getMethodName(); if (!mname.startsWith("set")) throw new UnsupportedOperationException("Can only use setIntData from a setXYZ method"); From 347c6d40a488a46355070e177cc5bc7d3d70e071 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 1 Nov 2016 21:13:12 +0100 Subject: [PATCH 19/21] Added getInfo method and an event for it --- .../java/buttondevteam/lib/TBMCPlayer.java | 20 ++++- .../lib/TBMCPlayerGetInfoEvent.java | 73 +++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 src/main/java/buttondevteam/lib/TBMCPlayerGetInfoEvent.java diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index 5deb51f..a6e6118 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -101,7 +101,8 @@ public class TBMCPlayer implements AutoCloseable { String mname = st.getMethodName(); if (!mname.startsWith("get")) throw new UnsupportedOperationException("Can only use getEnumData from a getXYZ method"); - final String retstr = (String) getLoadedPlayers().get(uuid).data.get(mname.substring("get".length()).toLowerCase()); + final String retstr = (String) getLoadedPlayers().get(uuid).data + .get(mname.substring("get".length()).toLowerCase()); if (retstr != null) return Enum.valueOf(cl, retstr); else @@ -444,4 +445,21 @@ public class TBMCPlayer implements AutoCloseable { public static HashMap getLoadedPlayers() { return LoadedPlayers; } + + /** + * Get player information. This method calls the {@link TBMCPlayerGetInfoEvent} to get all the player information across the TBMC plugins. + * + * @param target + * The {@link InfoTarget} to return the info for. + * @return The player information. + */ + public String getInfo(InfoTarget target) { + TBMCPlayerGetInfoEvent event = new TBMCPlayerGetInfoEvent(this, target); + Bukkit.getServer().getPluginManager().callEvent(event); + return event.getResult(); + } + + public enum InfoTarget { + MCHover, MCCommand, Discord + } } diff --git a/src/main/java/buttondevteam/lib/TBMCPlayerGetInfoEvent.java b/src/main/java/buttondevteam/lib/TBMCPlayerGetInfoEvent.java new file mode 100644 index 0000000..6dac56d --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCPlayerGetInfoEvent.java @@ -0,0 +1,73 @@ +package buttondevteam.lib; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import buttondevteam.lib.TBMCPlayer.InfoTarget; + +/** + * + * This event gets called when player information is requested. It can be used to give more per-plugin information about a player. + *
+ * + * @author Norbi + * + */ +public class TBMCPlayerGetInfoEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private TBMCPlayer player; + private Listinfolines; + private TBMCPlayer.InfoTarget target; + + TBMCPlayerGetInfoEvent(TBMCPlayer player, TBMCPlayer.InfoTarget target) { + this.player = player; + infolines = new ArrayList<>(); + this.target = target; + } + + /** + * Get the {@link TBMCPlayer} object + * + * @return A player object + */ + public TBMCPlayer getPlayer() { + return player; + } + + /** + * Add a line to the information text. The line should be in the format of key: value . + * + * @param infoline + * The line to add + */ + public void addInfo(String infoline) { + infolines.add(infoline); + } + + /** + * Get the {@link InfoTarget} we want the information for. Use this to format the returned string. + * + * @return The target of the information. + */ + public TBMCPlayer.InfoTarget getTarget() { + return target; + } + + String getResult() { + return infolines.stream().collect(Collectors.joining("\n")); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} From e6179f447fb7ada0cb2ccfb490cba34c5671f50f Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 1 Nov 2016 22:22:50 +0100 Subject: [PATCH 20/21] Removed throws declaration --- src/main/java/buttondevteam/lib/TBMCPlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/buttondevteam/lib/TBMCPlayer.java b/src/main/java/buttondevteam/lib/TBMCPlayer.java index a6e6118..a15f266 100644 --- a/src/main/java/buttondevteam/lib/TBMCPlayer.java +++ b/src/main/java/buttondevteam/lib/TBMCPlayer.java @@ -437,7 +437,7 @@ public class TBMCPlayer implements AutoCloseable { * Therefore, the recommended use is to call it when using {@link #GetPlayer} or use try-with-resources. */ @Override - public void close() throws Exception { + public void close() { if (!Bukkit.getPlayer(uuid).isOnline()) getLoadedPlayers().remove(uuid); } From 77aca9d5c17322eac7af4fe57b3b8d4bd74874bb Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Tue, 1 Nov 2016 22:47:46 +0100 Subject: [PATCH 21/21] Moved SendException --- .../java/buttondevteam/lib/TBMCCoreAPI.java | 11 +++- .../buttondevteam/lib/TBMCExceptionEvent.java | 57 +++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/main/java/buttondevteam/lib/TBMCExceptionEvent.java diff --git a/src/main/java/buttondevteam/lib/TBMCCoreAPI.java b/src/main/java/buttondevteam/lib/TBMCCoreAPI.java index b544c72..44da4df 100644 --- a/src/main/java/buttondevteam/lib/TBMCCoreAPI.java +++ b/src/main/java/buttondevteam/lib/TBMCCoreAPI.java @@ -44,9 +44,8 @@ public final class TBMCCoreAPI { String ret = ""; URL url; try { - url = new URL("https://jitpack.io/com/github/TBMCPlugins/" - + correctname + "/master-SNAPSHOT/" - + correctname + "-master-SNAPSHOT.jar"); // ButtonLib exception not required, not a separate plugin + url = new URL("https://jitpack.io/com/github/TBMCPlugins/" + correctname + "/master-SNAPSHOT/" + correctname + + "-master-SNAPSHOT.jar"); // ButtonLib exception not required, not a separate plugin FileUtils.copyURLToFile(url, new File("plugins/" + correctname + ".jar")); } catch (FileNotFoundException e) { ret = "Can't find JAR, the build probably failed. Build log (scroll to bottom):\nhttps://jitpack.io/com/github/TBMCPlugins/" @@ -91,4 +90,10 @@ public final class TBMCCoreAPI { in.close(); return body; } + + public static void SendException(String sourcemsg, Exception e) { + Bukkit.getPluginManager().callEvent(new TBMCExceptionEvent(sourcemsg, e)); + Bukkit.getLogger().warning(sourcemsg); + e.printStackTrace(); + } } diff --git a/src/main/java/buttondevteam/lib/TBMCExceptionEvent.java b/src/main/java/buttondevteam/lib/TBMCExceptionEvent.java new file mode 100644 index 0000000..ec7f11d --- /dev/null +++ b/src/main/java/buttondevteam/lib/TBMCExceptionEvent.java @@ -0,0 +1,57 @@ +package buttondevteam.lib; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import buttondevteam.lib.TBMCPlayer.InfoTarget; + +/** + * + * This event gets called (ideally) each time an exception occurs in a TBMC plugin. To call it, use {@link TBMCCoreAPI#SendException(String, Exception)}. + *
+ * + * @author Norbi + * + */ +public class TBMCExceptionEvent extends Event { + private static final HandlerList handlers = new HandlerList(); + + private String sourcemsg; + private Exception exception; + + TBMCExceptionEvent(String sourcemsg, Exception exception) { + this.sourcemsg = sourcemsg; + this.exception = exception; + } + + /** + * Gets the source message (where did this exception occur, etc.) + * + * @return The message + */ + public String getSourceMessage() { + return sourcemsg; + } + + /** + * Gets the exception + * + * @return The exception + */ + public Exception getException() { + return exception; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +}