diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java index f94ba0b..4a2ae3a 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java @@ -53,7 +53,9 @@ public class Config { exitWorld, lobbyWorld, locale, - leaveServer; + leaveServer, + placeholderError, + placeholderNoData; public static Vector spawnPosition, @@ -258,6 +260,8 @@ public class Config { locale = config.getString("locale", "local"); blockedCommands = config.getStringList("blockedCommands"); leaveOnEnd = config.getBoolean("leaveOnEnd"); + placeholderError = config.getString("placeholder.incorrect"); + placeholderNoData = config.getString("placeholder.noData"); try { countdownDisplay = CountdownDisplay.valueOf(config.getString("hideCountdownDisplay")); } catch (IllegalArgumentException e){ diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java index 06c036d..6948134 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java @@ -44,11 +44,11 @@ public class PlayerInfoTable { + " uuid BINARY(16) PRIMARY KEY,\n" + " hider_wins int NOT NULL,\n" + " seeker_wins int NOT NULL,\n" - + " hider_games int NOT NULL\n" - + " seeker_games int NOT NULL\n" - + " hider_kills int NOT NULL\n" - + " seeker_kills int NOT NULL\n" - + " hider_deaths int NOT NULL\n" + + " hider_games int NOT NULL,\n" + + " seeker_games int NOT NULL,\n" + + " hider_kills int NOT NULL,\n" + + " seeker_kills int NOT NULL,\n" + + " hider_deaths int NOT NULL,\n" + " seeker_deaths int NOT NULL\n" + ");"; @@ -123,6 +123,38 @@ public class PlayerInfoTable { return new PlayerInfo(uuid, 0, 0, 0, 0, 0, 0, 0, 0); } + @Nullable + public PlayerInfo getInfoRanking(String order, int place){ + String sql = "SELECT * FROM hs_data ORDER BY "+order+" DESC LIMIT 1 OFFSET ?;"; + try(Connection connection = Database.connect(); PreparedStatement statement = connection.prepareStatement(sql)){ + statement.setInt(1, place-1); + ResultSet rs = statement.executeQuery(); + if(rs.next()){ + UUID uuid = decodeUUID(rs.getBytes("uuid")); + PlayerInfo info = new PlayerInfo( + uuid, + rs.getInt("hider_wins"), + rs.getInt("seeker_wins"), + rs.getInt("hider_games"), + rs.getInt("seeker_games"), + rs.getInt("hider_kills"), + rs.getInt("seeker_kills"), + rs.getInt("hider_deaths"), + rs.getInt("seeker_deaths") + ); + rs.close(); + connection.close(); + CACHE.put(uuid, info); + return info; + } + rs.close(); + } catch (SQLException e){ + Main.plugin.getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + return null; + } + @Nullable public List getInfoPage(int page){ String sql = "SELECT * FROM hs_data ORDER BY (hider_wins + seeker_wins) DESC LIMIT 10 OFFSET ?;"; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java index c5d70bc..90f6432 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java @@ -1,21 +1,20 @@ package net.tylermurphy.hideAndSeek.util; +import static net.tylermurphy.hideAndSeek.configuration.Config.*; + import me.clip.placeholderapi.expansion.PlaceholderExpansion; import net.tylermurphy.hideAndSeek.database.Database; import net.tylermurphy.hideAndSeek.database.PlayerInfo; import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; -import java.lang.reflect.Method; -import java.util.Locale; import java.util.UUID; public class PAPIExpansion extends PlaceholderExpansion { @Override public @NotNull String getIdentifier() { - return "kenshinshideandseek"; + return "hs"; } @Override @@ -35,94 +34,95 @@ public class PAPIExpansion extends PlaceholderExpansion { @Override public String onRequest(OfflinePlayer player, @NotNull String params) { - switch (params.toLowerCase(Locale.ROOT)) { - case "hs_stats_total-wins": - return hs_stats_total_wins(player.getUniqueId()); - case "hs_stats_hider-wins": - return hs_stats_hider_wins(player.getUniqueId()); - case "hs_stats_seeker-wins": - return hs_stats_seeker_wins(player.getUniqueId()); - case "hs_stats_total-games": - return hs_stats_total_games(player.getUniqueId()); - case "hs_stats_hider-games": - return hs_stats_hider_games(player.getUniqueId()); - case "hs_stats_seeker-games": - return hs_stats_seeker_games(player.getUniqueId()); - case "hs_stats_total-kills": - return hs_stats_total_kills(player.getUniqueId()); - case "hs_stats_hider-kills": - return hs_stats_hider_kills(player.getUniqueId()); - case "hs_stats_seeker-kills": - return hs_stats_seeker_kills(player.getUniqueId()); - case "hs_stats_total-deaths": - return hs_stats_total_deaths(player.getUniqueId()); - case "hs_stats_hider-deaths": - return hs_stats_hider_deaths(player.getUniqueId()); - case "hs_stats_seeker-deaths": - return hs_stats_seeker_deaths(player.getUniqueId()); + String[] args = params.split("_"); + System.out.println(); + if(args.length < 1) return null; + if(args[0].equals("stats") && args.length == 2){ + PlayerInfo info = Database.playerInfo.getInfo(player.getUniqueId()); + return getValue(info, args[1]); + } else if(args[0].equals("stats") && args.length == 3){ + UUID uuid; + try { uuid = UUIDFetcher.getUUID(args[2]); } catch (Exception e) { return placeholderError; } + PlayerInfo info = Database.playerInfo.getInfo(uuid); + return getValue(info, args[1]); + } else if(args[0].equals("rank") && args.length == 3){ + int place; + try { place = Integer.parseInt(args[2]); } catch (NumberFormatException e) { return placeholderError; } + if(place < 1) { return placeholderError; } + if(getRanking(args[1]) == null) { return placeholderError; } + PlayerInfo info = Database.playerInfo.getInfoRanking(getRanking(args[1]), place); + if(info == null) return placeholderNoData; + if(args[0].equals("rankStat")){ + return getValue(info, args[1]); + } else { + return UUIDFetcher.getPlayer(info.uuid).getName(); + } + } + return null; + } + + private String getValue(PlayerInfo info, String query){ + if(query == null) return null; + switch (query) { + case "total-wins": + return String.valueOf(info.hider_wins + info.seeker_wins); + case "hider-wins": + return String.valueOf(info.hider_wins); + case "seeker-wins": + return String.valueOf(info.seeker_wins); + case "total-games": + return String.valueOf(info.hider_games + info.seeker_games); + case "hider-games": + return String.valueOf(info.hider_games); + case "seeker-games": + return String.valueOf(info.seeker_games); + case "total-kills": + return String.valueOf(info.hider_kills + info.seeker_kills); + case "hider-kills": + return String.valueOf(info.hider_kills); + case "seeker-kills": + return String.valueOf(info.seeker_kills); + case "total-deaths": + return String.valueOf(info.hider_deaths + info.seeker_deaths); + case "hider-deaths": + return String.valueOf(info.hider_deaths); + case "seeker-deaths": + return String.valueOf(info.seeker_deaths); default: return null; } } - private String hs_stats_total_wins(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_wins + info.seeker_wins); - } - - private String hs_stats_hider_wins(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_wins); - } - - private String hs_stats_seeker_wins(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.seeker_wins); - } - - private String hs_stats_total_games(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_games + info.seeker_games); - } - - private String hs_stats_hider_games(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_games); - } - - private String hs_stats_seeker_games(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.seeker_games); - } - - private String hs_stats_total_kills(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_kills + info.seeker_kills); - } - - private String hs_stats_hider_kills(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_kills); - } - - private String hs_stats_seeker_kills(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.seeker_kills); - } - - private String hs_stats_total_deaths(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_deaths + info.seeker_deaths); - } - - private String hs_stats_hider_deaths(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.hider_deaths); - } - - private String hs_stats_seeker_deaths(UUID uuid){ - PlayerInfo info = Database.playerInfo.getInfo(uuid); - return String.valueOf(info.seeker_deaths); + private String getRanking(String query){ + if(query == null) return null; + switch (query) { + case "total-wins": + return "(hider_wins + seeker_wins)"; + case "hider-wins": + return "hider_wins"; + case "seeker-wins": + return "seeker_wins"; + case "total-games": + return "(hider_games + seeker_games)"; + case "hider-games": + return "hider_games"; + case "seeker-games": + return "seeker_games"; + case "total-kills": + return "(hider_kills + seeker_kills)"; + case "hider-kills": + return "hider_kills"; + case "seeker-kills": + return "seeker_kills"; + case "total-deaths": + return "(hider_deaths + seeker_deaths)"; + case "hider-deaths": + return "hider_deaths"; + case "seeker-deaths": + return "seeker_deaths"; + default: + return null; + } } } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/util/UUIDFetcher.java b/src/main/java/net/tylermurphy/hideAndSeek/util/UUIDFetcher.java index ef65af3..4ab883d 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/util/UUIDFetcher.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/util/UUIDFetcher.java @@ -20,6 +20,9 @@ package net.tylermurphy.hideAndSeek.util; import net.tylermurphy.hideAndSeek.Main; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; import java.io.BufferedReader; import java.io.InputStreamReader; @@ -33,12 +36,16 @@ import java.util.UUID; public final class UUIDFetcher { private static final Map CACHE = new HashMap<>(); + private static final Map PLAYER_CACHE = new HashMap<>(); private static final String UUID_URL = "https://api.mojang.com/users/profiles/minecraft/"; private static int cacheTask; public static void init(){ - cacheTask = Main.plugin.getServer().getScheduler().scheduleSyncRepeatingTask(Main.plugin, CACHE::clear,600*20, 600*20); + cacheTask = Main.plugin.getServer().getScheduler().scheduleSyncRepeatingTask(Main.plugin, () -> { + CACHE.clear(); + PLAYER_CACHE.clear(); + }, 600 * 20, 600 * 20); } public static void cleanup(){ @@ -66,6 +73,13 @@ public final class UUIDFetcher { return UUID.fromString(uuid.toString()); } + public static OfflinePlayer getPlayer(UUID uuid){ + if(PLAYER_CACHE.containsKey(uuid)) return PLAYER_CACHE.get(uuid); + OfflinePlayer temp = Bukkit.getOfflinePlayer(uuid); + PLAYER_CACHE.put(uuid, temp); + return temp; + } + private static void readData(String toRead, StringBuilder result) { for (int i = toRead.length() - 3; i >= 0; i--) { if (toRead.charAt(i) != '"') { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 45261a3..75658b6 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -142,6 +142,12 @@ prefix: gameover: '&aGame Over > &f' warning: '&cWarning > &f' +# This plugin has support for custom placeholders with PlaceholderAPI. If you make a mistake when creating a placeholder, +# the plugin may tell you an error. Below you can change what could appear as an error message. +placeholder: + incorrect: "{Error}" + noData: "{No Data}" + # This is the section if you want a standard "waiting for players" lobby. You can specify # the standard countdown length under [countdown] (min 10 seconds). Then once the lobby gets to a size specified # by [changeCountdown], the timer will automatically go to 10 seconds. [min] is the minimum players