From f4954efb39612b2903a57a0cbeaa088e67644976 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Tue, 3 May 2022 13:07:40 -0400 Subject: start of 1.4.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'pom.xml') diff --git a/pom.xml b/pom.xml index e6bab08..4f73ae1 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 net.tylermurphy HideAndSeek - 1.4.2 + 1.4.3 Hide and Seek Plugin UTF-8 -- cgit v1.2.3-freya From e89e5f932c77034038c1fe166d1dfe2151a258f2 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Sat, 7 May 2022 23:54:48 -0400 Subject: rewrite database and damage event, add placeholders --- pom.xml | 10 ++ .../java/net/tylermurphy/hideAndSeek/Main.java | 5 + .../net/tylermurphy/hideAndSeek/command/Wins.java | 4 +- .../hideAndSeek/configuration/Config.java | 4 +- .../tylermurphy/hideAndSeek/database/Database.java | 8 -- .../hideAndSeek/database/PlayerInfo.java | 13 +- .../hideAndSeek/database/PlayerInfoTable.java | 124 +++++++++++------ .../net/tylermurphy/hideAndSeek/game/Board.java | 36 +++++ .../hideAndSeek/game/EventListener.java | 151 +++++++++------------ .../net/tylermurphy/hideAndSeek/game/Game.java | 4 +- .../hideAndSeek/util/PAPIExpansion.java | 128 +++++++++++++++++ src/main/resources/config.yml | 7 + 12 files changed, 351 insertions(+), 143 deletions(-) create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java (limited to 'pom.xml') diff --git a/pom.xml b/pom.xml index 4f73ae1..8073d7a 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,10 @@ dmulloy2-repo https://repo.dmulloy2.net/repository/public/ + + placeholderapi + https://repo.extendedclip.com/content/repositories/placeholderapi/ + @@ -103,5 +107,11 @@ XSeries 8.7.1 + + me.clip + placeholderapi + 2.11.1 + provided + \ No newline at end of file diff --git a/src/main/java/net/tylermurphy/hideAndSeek/Main.java b/src/main/java/net/tylermurphy/hideAndSeek/Main.java index ac6c2d5..cf73757 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/Main.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/Main.java @@ -23,6 +23,7 @@ import java.io.File; import java.util.List; import net.tylermurphy.hideAndSeek.database.Database; +import net.tylermurphy.hideAndSeek.util.PAPIExpansion; import net.tylermurphy.hideAndSeek.util.UUIDFetcher; import org.bukkit.Bukkit; @@ -74,6 +75,10 @@ public class Main extends JavaPlugin implements Listener { },0,1).getTaskId(); Bukkit.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); + + if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + new PAPIExpansion().register(); + } } public void onDisable() { diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java b/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java index dfa5338..9140f49 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java @@ -66,8 +66,8 @@ public class Wins implements ICommand { message = message + message("INFORMATION_FOR").addPlayer(name) + "\n"; message = message + "==============================\n"; message = message + String.format("%sTOTAL WINS: %s%s\n%sHIDER WINS: %s%s\n%sSEEKER WINS: %s%s\n%sGAMES PLAYED: %s", - ChatColor.YELLOW, ChatColor.WHITE, info.wins, ChatColor.GOLD, ChatColor.WHITE, info.hider_wins, - ChatColor.RED, ChatColor.WHITE, info.seeker_wins, ChatColor.WHITE, info.games_played); + ChatColor.YELLOW, ChatColor.WHITE, info.seeker_wins+info.hider_wins, ChatColor.GOLD, ChatColor.WHITE, info.hider_wins, + ChatColor.RED, ChatColor.WHITE, info.seeker_wins, ChatColor.WHITE, info.seeker_games+info.hider_games); message = message + ChatColor.WHITE + "" + ChatColor.BOLD + "\n=============================="; sender.sendMessage(message); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java index ec4e84e..f94ba0b 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java @@ -79,7 +79,8 @@ public class Config { bungeeLeave, lobbyItemStartAdmin, leaveOnEnd, - mapSaveEnabled; + mapSaveEnabled, + allowNaturalCauses; public static int minPlayers, @@ -251,6 +252,7 @@ public class Config { permissionsRequired = config.getBoolean("permissionsRequired"); gameLength = config.getInt("gameLength"); pvpEnabled = config.getBoolean("pvp"); + allowNaturalCauses = config.getBoolean("allowNaturalCauses"); autoJoin = config.getBoolean("autoJoin"); teleportToExit = config.getBoolean("teleportToExit"); locale = config.getString("locale", "local"); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java index 25a4171..fe5ac5b 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java @@ -55,14 +55,6 @@ public class Database { return conn; } - protected static InputStream convertUniqueId(UUID uuid) { - byte[] bytes = new byte[16]; - ByteBuffer.wrap(bytes) - .putLong(uuid.getMostSignificantBits()) - .putLong(uuid.getLeastSignificantBits()); - return new ByteArrayInputStream(bytes); - } - protected static UUID convertBinaryStream(InputStream stream) { ByteBuffer buffer = ByteBuffer.allocate(16); try { diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java index 8464b54..5fbb96b 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java @@ -24,14 +24,17 @@ import java.util.UUID; public class PlayerInfo { public UUID uuid; - public int wins, hider_wins, seeker_wins, games_played; + public int hider_wins, seeker_wins, hider_games, seeker_games, hider_kills, seeker_kills, hider_deaths, seeker_deaths; - public PlayerInfo(UUID uuid, int wins, int hider_wins, int seeker_wins, int games_played){ + public PlayerInfo(UUID uuid, int hider_wins, int seeker_wins, int hider_games, int seeker_games, int hider_kills, int seeker_kills, int hider_deaths, int seeker_deaths) { this.uuid = uuid; - this.wins = wins; this.hider_wins = hider_wins; this.seeker_wins = seeker_wins; - this.games_played = games_played; + this.hider_games = hider_games; + this.seeker_games = seeker_games; + this.hider_kills = hider_kills; + this.seeker_kills = seeker_kills; + this.hider_deaths = hider_deaths; + this.seeker_deaths = seeker_deaths; } - } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java index 142c263..06c036d 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java @@ -19,28 +19,37 @@ package net.tylermurphy.hideAndSeek.database; +import com.google.common.io.ByteStreams; import net.tylermurphy.hideAndSeek.Main; import net.tylermurphy.hideAndSeek.configuration.Config; +import net.tylermurphy.hideAndSeek.game.Board; import net.tylermurphy.hideAndSeek.util.WinType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.ByteBuffer; import java.sql.*; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import java.util.*; public class PlayerInfoTable { + private static final Map CACHE = new HashMap<>(); + protected PlayerInfoTable(){ - String sql = "CREATE TABLE IF NOT EXISTS player_info (\n" + String sql = "CREATE TABLE IF NOT EXISTS hs_data (\n" + " uuid BINARY(16) PRIMARY KEY,\n" - + " wins int NOT NULL,\n" - + " seeker_wins int NOT NULL,\n" + " hider_wins int NOT NULL,\n" - + " games_played 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" + + " seeker_deaths int NOT NULL\n" + ");"; try(Connection connection = Database.connect(); Statement statement = connection.createStatement()){ @@ -51,52 +60,87 @@ public class PlayerInfoTable { } } + private byte[] encodeUUID(UUID uuid){ + try { + byte[] bytes = new byte[16]; + ByteBuffer.wrap(bytes) + .putLong(uuid.getMostSignificantBits()) + .putLong(uuid.getLeastSignificantBits()); + InputStream is = new ByteArrayInputStream(bytes); + byte[] result = new byte[is.available()]; + if (is.read(result) == -1) { + Main.plugin.getLogger().severe("IO Error: Failed to read bytes from input stream"); + return new byte[0]; + } + return result; + } catch (IOException e){ + Main.plugin.getLogger().severe("IO Error: " + e.getMessage()); + return new byte[0]; + } + } + + private UUID decodeUUID(byte[] bytes){ + InputStream is = new ByteArrayInputStream(bytes); + ByteBuffer buffer = ByteBuffer.allocate(16); + try { + buffer.put(ByteStreams.toByteArray(is)); + buffer.flip(); + return new UUID(buffer.getLong(), buffer.getLong()); + } catch (IOException e) { + Main.plugin.getLogger().severe("IO Error: " + e.getMessage()); + } + return null; + } + + @NotNull public PlayerInfo getInfo(UUID uuid){ - String sql = "SELECT * FROM player_info WHERE uuid = ?;"; + String sql = "SELECT * FROM hs_data WHERE uuid = ?;"; try(Connection connection = Database.connect(); PreparedStatement statement = connection.prepareStatement(sql)){ - InputStream is = Database.convertUniqueId(uuid); - byte[] bytes = new byte[is.available()]; - if(is.read(bytes) == -1){ - throw new IOException("Failed to read bytes from input stream"); - } - statement.setBytes(1, bytes); + statement.setBytes(1, encodeUUID(uuid)); ResultSet rs = statement.executeQuery(); if(rs.next()){ PlayerInfo info = new PlayerInfo( uuid, - rs.getInt("wins"), - rs.getInt("seeker_wins"), rs.getInt("hider_wins"), - rs.getInt("games_played") + 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(); - } catch (IOException e) { - Main.plugin.getLogger().severe("IO Error: " + e.getMessage()); - e.printStackTrace(); } - return new PlayerInfo(uuid, 0, 0, 0, 0); + return new PlayerInfo(uuid, 0, 0, 0, 0, 0, 0, 0, 0); } + @Nullable public List getInfoPage(int page){ - String sql = "SELECT * FROM player_info ORDER BY wins DESC LIMIT 10 OFFSET ?;"; + String sql = "SELECT * FROM hs_data ORDER BY (hider_wins + seeker_wins) DESC LIMIT 10 OFFSET ?;"; try(Connection connection = Database.connect(); PreparedStatement statement = connection.prepareStatement(sql)){ statement.setInt(1, (page-1)*10); ResultSet rs = statement.executeQuery(); List infoList = new ArrayList<>(); while(rs.next()){ PlayerInfo info = new PlayerInfo( - Database.convertBinaryStream(new ByteArrayInputStream(rs.getBytes("uuid"))), - rs.getInt("wins"), - rs.getInt("seeker_wins"), + decodeUUID(rs.getBytes("uuid")), rs.getInt("hider_wins"), - rs.getInt("games_played") + 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") ); infoList.add(info); } @@ -110,31 +154,31 @@ public class PlayerInfoTable { return null; } - public void addWins(List uuids, List winners, WinType type){ + public void addWins(List uuids, List winners, Map kills, Map deaths, WinType type){ for(UUID uuid : uuids){ - String sql = "INSERT OR REPLACE INTO player_info (uuid, wins, seeker_wins, hider_wins, games_played) VALUES (?,?,?,?,?)"; + String sql = "INSERT OR REPLACE INTO hs_data (uuid, hider_wins, seeker_wins, hider_games, seeker_games, hider_kills, seeker_kills, hider_deaths, seeker_deaths) VALUES (?,?,?,?,?,?,?,?,?)"; PlayerInfo info = getInfo(uuid); try(Connection connection = Database.connect(); PreparedStatement statement = connection.prepareStatement(sql)){ - InputStream is = Database.convertUniqueId(uuid); - byte[] bytes = new byte[is.available()]; - if(is.read(bytes) == -1){ - throw new IOException("Failed to read bytes from input stream"); - } - statement.setBytes(1, bytes); - statement.setInt(2, info.wins + (winners.contains(uuid) ? 1 : 0)); + statement.setBytes(1, encodeUUID(uuid)); + statement.setInt(2, info.hider_wins + (winners.contains(uuid) && type == WinType.HIDER_WIN ? 1 : 0)); statement.setInt(3, info.seeker_wins + (winners.contains(uuid) && type == WinType.SEEKER_WIN ? 1 : 0)); - statement.setInt(4, info.hider_wins + (winners.contains(uuid) && type == WinType.HIDER_WIN ? 1 : 0)); - statement.setInt(5, info.games_played + 1); + statement.setInt(4, info.hider_games + (Board.isHider(uuid) ? 1 : 0)); + statement.setInt(5, info.seeker_games + (Board.isSeeker(uuid) ? 1 : 0)); + statement.setInt(6, info.hider_kills + (Board.isHider(uuid) ? kills.get(uuid.toString()) : 0)); + statement.setInt(7, info.seeker_kills + (Board.isSeeker(uuid) ? kills.get(uuid.toString()) : 0)); + statement.setInt(8, info.hider_deaths + (Board.isHider(uuid) ? deaths.get(uuid.toString()) : 0)); + statement.setInt(9, info.seeker_deaths + (Board.isSeeker(uuid) ? deaths.get(uuid.toString()) : 0)); statement.execute(); } catch (SQLException e){ Main.plugin.getLogger().severe("SQL Error: " + e.getMessage()); e.printStackTrace(); return; - } catch (IOException e) { - Main.plugin.getLogger().severe("IO Error: " + e.getMessage()); - e.printStackTrace(); + } finally { + CACHE.remove(uuid); } } } + + } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java index c08b779..86711ab 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java @@ -38,6 +38,8 @@ public class Board { private static final List Hider = new ArrayList<>(), Seeker = new ArrayList<>(), Spectator = new ArrayList<>(); private static final Map playerList = new HashMap<>(); private static final Map customBoards = new HashMap<>(); + private static final Map kills = new HashMap<>(); + private static final Map deaths = new HashMap<>(); public static boolean isPlayer(Player player) { return playerList.containsKey(player.getUniqueId().toString()); @@ -51,10 +53,18 @@ public class Board { return Hider.contains(player.getUniqueId().toString()); } + public static boolean isHider(UUID uuid){ + return Hider.contains(uuid.toString()); + } + public static boolean isSeeker(Player player) { return Seeker.contains(player.getUniqueId().toString()); } + public static boolean isSeeker(UUID uuid){ + return Seeker.contains(uuid.toString()); + } + public static boolean isSpectator(Player player) { return Spectator.contains(player.getUniqueId().toString()); } @@ -133,6 +143,32 @@ public class Board { Hider.clear(); Seeker.clear(); Spectator.clear(); + kills.clear(); + deaths.clear(); + } + + public static void addKill(UUID uuid){ + if(kills.containsKey(uuid.toString())){ + kills.put(uuid.toString(), kills.get(uuid.toString())+1); + } else { + kills.put(uuid.toString(), 1); + } + } + + public static void addDeath(UUID uuid){ + if(deaths.containsKey(uuid.toString())){ + deaths.put(uuid.toString(), deaths.get(uuid.toString())+1); + } else { + deaths.put(uuid.toString(), 1); + } + } + + public static Map getKills(){ + return new HashMap<>(kills); + } + + public static Map getDeaths(){ + return new HashMap<>(deaths); } public static void createLobbyBoard(Player player) { diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/EventListener.java b/src/main/java/net/tylermurphy/hideAndSeek/game/EventListener.java index 35089e4..7d83217 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/EventListener.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/EventListener.java @@ -32,6 +32,7 @@ import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.Arrow; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -148,93 +149,73 @@ public class EventListener implements Listener { @EventHandler(priority = EventPriority.HIGHEST) public void onEntityDamage(EntityDamageEvent event) { - try { - if (event.getEntity() instanceof Player) { - Player player = (Player) event.getEntity(); - if (!Board.isPlayer(player)) { - if (event instanceof EntityDamageByEntityEvent) { - Entity damager = ((EntityDamageByEntityEvent) event).getDamager(); - if (damager instanceof Player) { - if(Board.isPlayer(damager)){ - event.setCancelled(true); - return; - } - } - } - return; - } - if (Game.status != Status.PLAYING) { - event.setCancelled(true); - return; - } - Player attacker = null; - if (event instanceof EntityDamageByEntityEvent) { - Entity damager = ((EntityDamageByEntityEvent) event).getDamager(); - if (damager instanceof Player) { - attacker = (Player) damager; - if (!Board.isPlayer(attacker)) event.setCancelled(true); - if (Board.onSameTeam(player, attacker)) event.setCancelled(true); - if (Board.isSpectator(player)) event.setCancelled(true); - } else if(damager instanceof Arrow){ - ProjectileSource source = ((Arrow) damager).getShooter(); - if(source instanceof Player){ - attacker = (Player) source; - if (!Board.isPlayer(attacker)) event.setCancelled(true); - if (Board.onSameTeam(player, attacker)) event.setCancelled(true); - if (Board.isSpectator(player)) event.setCancelled(true); - } - } - } - if(event.isCancelled()) return; - if (player.getHealth() - event.getFinalDamage() < 0.5 || !pvpEnabled) { - if (event instanceof EntityDamageByEntityEvent && !pvpEnabled) { - Entity damager = ((EntityDamageByEntityEvent) event).getDamager(); - if (damager instanceof Player) { - Player atacker = (Player) damager; - if(!Board.isSeeker(atacker)){ - event.setCancelled(true); - return; - } - } else { - event.setCancelled(true); - return; - } - } else if(!pvpEnabled) { - event.setCancelled(true); - return; - } - if (spawnPosition == null) return; - event.setCancelled(true); - if(Version.atLeast("1.9")) { - AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH); - if (attribute != null) player.setHealth(attribute.getValue()); - } else { - player.setHealth(player.getMaxHealth()); - } - player.teleport(new Location(Bukkit.getWorld(Game.getGameWorld()), spawnPosition.getX(), spawnPosition.getY(), spawnPosition.getZ())); - if(Version.atLeast("1.9")){ - XSound.ENTITY_PLAYER_DEATH.play(player, 1, 1); - } else { - XSound.ENTITY_PLAYER_HURT.play(player, 1, 1); - } - if (Board.isSeeker(player)) { - Game.broadcastMessage(message("GAME_PLAYER_DEATH").addPlayer(player).toString()); - } - if (Board.isHider(player)) { - if (attacker == null) { - Game.broadcastMessage(message("GAME_PLAYER_FOUND").addPlayer(player).toString()); - } else { - Game.broadcastMessage(message("GAME_PLAYER_FOUND_BY").addPlayer(player).addPlayer(attacker).toString()); - } - Board.addSeeker(player); - } - Game.resetPlayer(player); - Board.reloadBoardTeams(); - } + // If you are not a player, get out of here + if(!(event.getEntity() instanceof Player)) return; + // Define variables + Player player = (Player) event.getEntity(); + Player attacker = null; + // If player pvp is enabled, and player doesn't die, we do not care + if(pvpEnabled && player.getHealth() - event.getFinalDamage() >= 0.5){ return; } + // If no spawn position, we won't be able to manage their death :o + if(spawnPosition == null){ return; } + // If there is an attacker, find them + if (event instanceof EntityDamageByEntityEvent) { + if(((EntityDamageByEntityEvent) event).getDamager() instanceof Player) + attacker = (Player) ((EntityDamageByEntityEvent) event).getDamager(); + else if(((EntityDamageByEntityEvent) event).getDamager() instanceof Projectile) + if(((Projectile) ((EntityDamageByEntityEvent) event).getDamager()).getShooter() instanceof Player) + attacker = (Player) ((Projectile) ((EntityDamageByEntityEvent) event).getDamager()).getShooter(); + } + // Makes sure that if there was an attacking player, that the event is allowed for the game + if(attacker != null){ + // Cancel if one player is in the game but other isn't + if((Board.isPlayer(player) && !Board.isPlayer(attacker)) || (!Board.isPlayer(player) && Board.isPlayer(attacker))){ + event.setCancelled(true); + return; + // Ignore event if neither player are in the game + } else if(!Board.isPlayer(player) && !Board.isPlayer(attacker)){ + return; + // Ignore event if players are on the same team, or one of them is a spectator + } else if(Board.onSameTeam(player, attacker) || Board.isSpectator(player) || Board.isSpectator(attacker)){ + event.setCancelled(true); + return; + // Ignore the event if pvp is disabled, and a hider is trying to attack a seeker + } else if(!pvpEnabled && Board.isHider(attacker) && Board.isSeeker(player)){ + event.setCancelled(true); + return; + } + // If there is no attacker, it must of been by natural causes. If pvp is disabled, and config doesn't allow natural causes, cancel event. + } else if(!pvpEnabled && !allowNaturalCauses){ + event.setCancelled(true); + return; + } + // Handle death event + event.setCancelled(true); + // Reset health and play death effect + if(Version.atLeast("1.9")) { + AttributeInstance attribute = player.getAttribute(Attribute.GENERIC_MAX_HEALTH); + if (attribute != null) player.setHealth(attribute.getValue()); + XSound.ENTITY_PLAYER_DEATH.play(player, 1, 1); + } else { + player.setHealth(player.getMaxHealth()); + XSound.ENTITY_PLAYER_HURT.play(player, 1, 1); + } + // Teleport player to seeker spawn + player.teleport(new Location(Bukkit.getWorld(Game.getGameWorld()), spawnPosition.getX(), spawnPosition.getY(), spawnPosition.getZ())); + // Broadcast player death message + if (Board.isSeeker(player)) { + Game.broadcastMessage(message("GAME_PLAYER_DEATH").addPlayer(player).toString()); + } else if (Board.isHider(player)) { + if (attacker == null) { + Game.broadcastMessage(message("GAME_PLAYER_FOUND").addPlayer(player).toString()); + } else { + Game.broadcastMessage(message("GAME_PLAYER_FOUND_BY").addPlayer(player).addPlayer(attacker).toString()); } - } catch (Exception e){ - Main.plugin.getLogger().severe("Entity Damage Event Error: " + e.getMessage()); + Board.addSeeker(player); } + // Add leaderboard stats + Board.addDeath(player.getUniqueId()); + if(attacker != null){ Board.addKill(attacker.getUniqueId()); } } @EventHandler(priority = EventPriority.HIGHEST) diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java index 16caee4..fb91a2f 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java @@ -178,11 +178,11 @@ public class Game { List players = Board.getPlayers().stream().map(Entity::getUniqueId).collect(Collectors.toList()); if(type == WinType.HIDER_WIN){ List winners = Board.getHiders().stream().map(Entity::getUniqueId).collect(Collectors.toList()); - Database.playerInfo.addWins(players, winners, type); + Database.playerInfo.addWins(players, winners, Board.getKills(), Board.getDeaths(), type); } else if(type == WinType.SEEKER_WIN){ List winners = new ArrayList<>(); winners.add(Board.getFirstSeeker().getUniqueId()); - Database.playerInfo.addWins(players, winners, type); + Database.playerInfo.addWins(players, winners, Board.getKills(), Board.getDeaths(), type); } worldBorder.resetWorldborder(getGameWorld()); for(Player player : Board.getPlayers()) { diff --git a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java new file mode 100644 index 0000000..c5d70bc --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java @@ -0,0 +1,128 @@ +package net.tylermurphy.hideAndSeek.util; + +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"; + } + + @Override + public @NotNull String getAuthor() { + return "KenshinEto"; + } + + @Override + public @NotNull String getVersion() { + return "1.4.3"; + } + + @Override + public boolean persist() { + return true; + } + + @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()); + 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); + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 88eab62..45261a3 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -46,6 +46,13 @@ minPlayers: 2 # default: true pvp: true +# !! Only effects the game at all if pvp is set to false !! +# By default, If you disable pvp, Hiders and Seekers can no longer take damage from natural causes such as +# falling or projectiles. If you want, you can keep pvp disabled so that Seekers only have to tag Hiders, but +# all players can still take fall damage or any other damage that's not from another player. +# deafult: false +allowNaturalCauses: false + # Players that join the server will automatically be placed into the lobby. # default: false autoJoin: false -- cgit v1.2.3-freya From b74b8136365ca2542242023fc91e370873d6eabf Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Tue, 17 May 2022 16:36:35 -0400 Subject: working on expanding database --- pom.xml | 28 ++- .../java/net/tylermurphy/hideAndSeek/Main.java | 25 ++- .../net/tylermurphy/hideAndSeek/command/Top.java | 2 +- .../net/tylermurphy/hideAndSeek/command/Wins.java | 2 +- .../tylermurphy/hideAndSeek/database/Database.java | 41 ++-- .../hideAndSeek/database/GameDataTable.java | 218 +++++++++++++++++++++ .../hideAndSeek/database/LegacyTable.java | 104 ++++++++++ .../hideAndSeek/database/NameDataTable.java | 99 ++++++++++ .../hideAndSeek/database/PlayerInfo.java | 84 -------- .../hideAndSeek/database/PlayerInfoTable.java | 199 ------------------- .../database/connections/DatabaseConnection.java | 29 +++ .../database/connections/MySQLConnection.java | 61 ++++++ .../database/connections/SQLiteConnection.java | 64 ++++++ .../database/util/LegacyPlayerInfo.java | 56 ++++++ .../hideAndSeek/database/util/PlayerInfo.java | 84 ++++++++ .../game/listener/JoinLeaveHandler.java | 3 + .../hideAndSeek/util/PAPIExpansion.java | 2 +- src/test/java/MainTest.java | 42 ++++ 18 files changed, 826 insertions(+), 317 deletions(-) create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/LegacyTable.java create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/NameDataTable.java delete mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java delete mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/connections/DatabaseConnection.java create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/util/LegacyPlayerInfo.java create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/database/util/PlayerInfo.java create mode 100644 src/test/java/MainTest.java (limited to 'pom.xml') diff --git a/pom.xml b/pom.xml index 8073d7a..fff9f6c 100644 --- a/pom.xml +++ b/pom.xml @@ -30,18 +30,18 @@ - - org.spigotmc:spigot-api - com.comphenix.protocol:ProtocolLib - org.jetbrains:annotations - net.bytebuddy:byte-buddy - + + com.github.cryptomorin:XSeries + org.xerial:sqlite-jdbc + com.zaxxer:HikariCP + *:* META-INF/*.MF + META-INF/*.md META-INF sqlite-jdbc.properties @@ -113,5 +113,21 @@ 2.11.1 provided + + com.zaxxer + HikariCP + 5.0.1 + + + org.junit.jupiter + junit-jupiter + 5.9.0-M1 + + + com.github.seeseemelk + MockBukkit-v1.17 + 1.13.0 + test + \ No newline at end of file diff --git a/src/main/java/net/tylermurphy/hideAndSeek/Main.java b/src/main/java/net/tylermurphy/hideAndSeek/Main.java index 2737e81..126deaa 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/Main.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/Main.java @@ -19,6 +19,7 @@ package net.tylermurphy.hideAndSeek; +import jdk.jpackage.internal.IOUtils; import net.tylermurphy.hideAndSeek.configuration.Config; import net.tylermurphy.hideAndSeek.configuration.Items; import net.tylermurphy.hideAndSeek.configuration.Localization; @@ -34,7 +35,9 @@ import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.event.Listener; +import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.plugin.java.JavaPluginLoader; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -47,13 +50,26 @@ public class Main extends JavaPlugin implements Listener { private static Main instance; private static int version; - private Database database; - private Board board; + private final Database database; + private final Board board; + private Game game; - public void onEnable() { + public Main() { + super(); + instance = this; + board = new Board(); + database = new Database(); + } + protected Main(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); instance = this; + board = new Board(); + database = new Database(); + } + + public void onEnable() { this.registerListeners(); @@ -63,9 +79,6 @@ public class Main extends JavaPlugin implements Listener { CommandHandler.registerCommands(); - board = new Board(); - database = new Database(); - game = new Game(board); getServer().getScheduler().runTaskTimer(this, this::onTick,0,1).getTaskId(); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java b/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java index e0aa2fb..caa751b 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java @@ -20,7 +20,7 @@ package net.tylermurphy.hideAndSeek.command; import net.tylermurphy.hideAndSeek.Main; -import net.tylermurphy.hideAndSeek.database.PlayerInfo; +import net.tylermurphy.hideAndSeek.database.util.PlayerInfo; import org.bukkit.ChatColor; import org.bukkit.entity.Player; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java b/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java index bb69cd4..8a0b6dc 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java @@ -20,7 +20,7 @@ package net.tylermurphy.hideAndSeek.command; import net.tylermurphy.hideAndSeek.Main; -import net.tylermurphy.hideAndSeek.database.PlayerInfo; +import net.tylermurphy.hideAndSeek.database.util.PlayerInfo; import org.bukkit.ChatColor; import org.bukkit.entity.Player; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java index ce06244..0eceb98 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java @@ -21,48 +21,51 @@ package net.tylermurphy.hideAndSeek.database; import com.google.common.io.ByteStreams; import net.tylermurphy.hideAndSeek.Main; -import org.sqlite.SQLiteConfig; +import net.tylermurphy.hideAndSeek.database.connections.DatabaseConnection; +import net.tylermurphy.hideAndSeek.database.connections.SQLiteConnection; import java.io.ByteArrayInputStream; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.SQLException; import java.util.UUID; public class Database { - private final File databaseFile = new File(Main.getInstance().getDataFolder(), "database.db"); - private final PlayerInfoTable playerInfo; - private final SQLiteConfig config; + private final GameDataTable playerInfo; + private final NameDataTable nameInfo; + private final DatabaseConnection connection; public Database(){ - try { - Class.forName("org.sqlite.JDBC"); - } catch (ClassNotFoundException e) { - Main.getInstance().getLogger().severe(e.getMessage()); - throw new RuntimeException(e.getMessage()); - } - config = new SQLiteConfig(); - config.setSynchronous(SQLiteConfig.SynchronousMode.NORMAL); - config.setTempStore(SQLiteConfig.TempStore.MEMORY); + connection = new SQLiteConnection(); + + playerInfo = new GameDataTable(this); - playerInfo = new PlayerInfoTable(this); + nameInfo = new NameDataTable(this); + + LegacyTable legacyTable = new LegacyTable(this); + if(legacyTable.exists()){ + if(legacyTable.copyData()){ + if(!legacyTable.drop()){ + Main.getInstance().getLogger().severe("Failed to drop old legacy table: player_info. Some data may be duplicated!"); + } + } + } } - public PlayerInfoTable getGameData(){ + public GameDataTable getGameData(){ return playerInfo; } + public NameDataTable getNameData() { return nameInfo; } + protected Connection connect() { Connection conn = null; try { - String url = "jdbc:sqlite:"+databaseFile; - conn = DriverManager.getConnection(url, config.toProperties()); + conn = connection.connect(); } catch (SQLException e) { Main.getInstance().getLogger().severe(e.getMessage()); e.printStackTrace(); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java b/src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java new file mode 100644 index 0000000..128614d --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java @@ -0,0 +1,218 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2021-2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database; + +import net.tylermurphy.hideAndSeek.Main; +import net.tylermurphy.hideAndSeek.database.util.PlayerInfo; +import net.tylermurphy.hideAndSeek.game.Board; +import net.tylermurphy.hideAndSeek.game.util.WinType; +import org.jetbrains.annotations.Nullable; + +import java.sql.*; +import java.util.*; + +public class GameDataTable { + + private final Map CACHE = new HashMap<>(); + private final Database database; + + protected GameDataTable(Database database) { + + String sql = "CREATE TABLE IF NOT EXISTS hs_data (\n" + + " 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" + + " seeker_deaths int NOT NULL\n" + + ");"; + + try(Connection connection = database.connect(); Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + + this.database = database; + } + + @Nullable + public PlayerInfo getInfo(UUID uuid) { + if(CACHE.containsKey(uuid)) return CACHE.get(uuid); + String sql = "SELECT * FROM hs_data WHERE uuid = ?;"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setBytes(1, database.encodeUUID(uuid)); + ResultSet rs = statement.executeQuery(); + if (rs.next()) { + 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.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + return null; + } + + @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 = database.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.getInstance().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 ?;"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setInt(1, (page-1)*10); + ResultSet rs = statement.executeQuery(); + List infoList = new ArrayList<>(); + while(rs.next()) { + PlayerInfo info = new PlayerInfo( + database.decodeUUID(rs.getBytes("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") + ); + infoList.add(info); + } + rs.close(); + connection.close(); + return infoList; + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + return null; + } + + @Nullable + public Integer getRanking(String order, UUID uuid) { + String sql = "SELECT count(*) AS total FROM hs_data WHERE "+order+" >= (SELECT "+order+" FROM hs_data WHERE uuid = ?) AND "+order+" > 0;"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setBytes(1, database.encodeUUID(uuid)); + ResultSet rs = statement.executeQuery(); + if (rs.next()) { + return rs.getInt("total"); + } + rs.close(); + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + return null; + } + + public void addWins(Board board, List uuids, List winners, Map hider_kills, Map hider_deaths, Map seeker_kills, Map seeker_deaths, WinType type) { + for(UUID uuid : uuids) { + PlayerInfo info = getInfo(uuid); + if(info == null){ + info = new PlayerInfo(uuid, 0, 0, 0, 0, 0, 0, 0, 0); + } + updateInfo( + database.encodeUUID(info.getUniqueId()), + info.getHiderWins() + (winners.contains(uuid) && type == WinType.HIDER_WIN ? 1 : 0), + info.getSeekerWins() + (winners.contains(uuid) && type == WinType.SEEKER_WIN ? 1 : 0), + info.getHiderGames() + (board.isHider(uuid) || (board.isSeeker(uuid) && !board.getFirstSeeker().getUniqueId().equals(uuid)) ? 1 : 0), + info.getSeekerGames() + (board.getFirstSeeker().getUniqueId().equals(uuid) ? 1 : 0), + info.getHiderKills() + hider_kills.getOrDefault(uuid.toString(), 0), + info.getSeekerKills() + seeker_kills.getOrDefault(uuid.toString(), 0), + info.getHiderDeaths() + hider_deaths.getOrDefault(uuid.toString(), 0), + info.getSeekerDeaths() + seeker_deaths.getOrDefault(uuid.toString(), 0) + ); + } + } + + protected boolean updateInfo(byte[] uuid, int hider_wins, int seeker_wins, int hider_games, int seeker_games, int hider_kills, int seeker_kills, int hider_deaths, int seeker_deaths){ + boolean success; + String sql = "INSERT OR REPLACE INTO hs_data (uuid, hider_wins, seeker_wins, hider_games, seeker_games, hider_kills, seeker_kills, hider_deaths, seeker_deaths) VALUES (?,?,?,?,?,?,?,?,?)"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setBytes(1, uuid); + statement.setInt(2, hider_wins); + statement.setInt(3, seeker_wins); + statement.setInt(4, hider_games); + statement.setInt(5, seeker_games); + statement.setInt(6, hider_kills); + statement.setInt(7, seeker_kills); + statement.setInt(8, hider_deaths); + statement.setInt(9, seeker_deaths); + statement.execute(); + statement.close(); + success = true; + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + success = false; + } finally { + CACHE.remove(uuid); + } + return success; + } + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/LegacyTable.java b/src/main/java/net/tylermurphy/hideAndSeek/database/LegacyTable.java new file mode 100644 index 0000000..580c2f5 --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/LegacyTable.java @@ -0,0 +1,104 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database; + +import net.tylermurphy.hideAndSeek.Main; +import net.tylermurphy.hideAndSeek.database.Database; +import net.tylermurphy.hideAndSeek.database.util.LegacyPlayerInfo; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +public class LegacyTable { + + private final Database database; + private final boolean exists; + + protected LegacyTable(Database database) { + + String sql = "SELECT * FROM player_info LIMIT 1;"; + + boolean check; + try(Connection connection = database.connect(); Statement statement = connection.createStatement()) { + ResultSet resultSet = statement.executeQuery(sql); + check = resultSet.next(); + } catch (SQLException e) { + check = false; + } + + this.exists = check; + this.database = database; + } + + public boolean exists(){ + return exists; + } + + public boolean copyData(){ + String sql = "SELECT * FROM player_info;"; + List legacyPlayerInfoList = new ArrayList<>(); + try(Connection connection = database.connect(); Statement statement = connection.createStatement()) { + ResultSet resultSet = statement.executeQuery(sql); + while(resultSet.next()){ + legacyPlayerInfoList.add(new LegacyPlayerInfo( + resultSet.getBytes("uuid"), + resultSet.getInt("wins"), + resultSet.getInt("hider_wins"), + resultSet.getInt("seeker_wins"), + resultSet.getInt("games_played") + )); + } + resultSet.close(); + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + for(LegacyPlayerInfo legacyInfo : legacyPlayerInfoList){ + database.getGameData().updateInfo( + legacyInfo.getUniqueId(), + legacyInfo.getHiderWins(), + legacyInfo.getSeekerWins(), + legacyInfo.getGamesPlayer() - legacyInfo.getSeekerWins(), + legacyInfo.getSeekerWins(), + 0, + 0, + 0, + 0 + ); + } + return true; + } + + public boolean drop(){ + String sql = "DROP table player_info"; + try(Connection connection = database.connect(); Statement statement = connection.createStatement()) { + statement.execute(sql); + return true; + } catch (SQLException e) { + e.printStackTrace(); + return false; + } + } + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/NameDataTable.java b/src/main/java/net/tylermurphy/hideAndSeek/database/NameDataTable.java new file mode 100644 index 0000000..cbf410a --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/NameDataTable.java @@ -0,0 +1,99 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database; + +import net.tylermurphy.hideAndSeek.Main; +import org.jetbrains.annotations.Nullable; + +import java.sql.*; +import java.util.UUID; + +public class NameDataTable { + + private final Database database; + + protected NameDataTable(Database database) { + + String sql = "CREATE TABLE IF NOT EXISTS hs_names (\n" + + " uuid BINARY(16) NOT NULL,\n" + + " name VARCHAR(48) NOT NULL,\n" + + " PRIMARY KEY (uuid,name)\n" + + ");"; + + try(Connection connection = database.connect(); Statement statement = connection.createStatement()) { + statement.executeUpdate(sql); + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + + this.database = database; + } + + @Nullable + public String getName(UUID uuid) { + String sql = "SELECT * FROM hs_names WHERE uuid = ?;"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setBytes(1, database.encodeUUID(uuid)); + ResultSet rs = statement.executeQuery(); + if (rs.next()) { + return rs.getString("name"); + } + rs.close(); + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + return null; + } + + @Nullable + public UUID getUUID(String name) { + String sql = "SELECT * FROM hs_names WHERE name = ?;"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setString(1, name); + ResultSet rs = statement.executeQuery(); + if (rs.next()) { + return database.decodeUUID(rs.getBytes("uuid")); + } + rs.close(); + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + } + return null; + } + + public boolean update(UUID uuid, String name){ + String sql = "INSERT OR REPLACE INTO hs_names (uuid, name) VALUES (?,?)"; + try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setBytes(1, database.encodeUUID(uuid)); + statement.setString(2, name); + statement.execute(); + statement.close(); + return true; + } catch (SQLException e) { + Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); + e.printStackTrace(); + return false; + } + } + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java deleted file mode 100644 index 5c74e76..0000000 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfo.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Kenshins Hide and Seek - * - * Copyright (c) 2021 Tyler Murphy. - * - * Kenshins Hide and Seek free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * he Free Software Foundation version 3. - * - * Kenshins Hide and Seek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package net.tylermurphy.hideAndSeek.database; - -import java.util.UUID; - -public class PlayerInfo { - - private final UUID uniqueId; - private final int hiderWins; - private final int seekerWins; - private final int hiderGames; - private final int seekerGames; - private final int hiderKills; - private final int seekerKills; - private final int hiderDeaths; - private final int seekerDeaths; - - public PlayerInfo(UUID uniqueId, int hiderWins, int seekerWins, int hiderGames, int seekerGames, int hiderKills, int seekerKills, int hiderDeaths, int seekerDeaths) { - this.uniqueId = uniqueId; - this.hiderWins = hiderWins; - this.seekerWins = seekerWins; - this.hiderGames = hiderGames; - this.seekerGames = seekerGames; - this.hiderKills = hiderKills; - this.seekerKills = seekerKills; - this.hiderDeaths = hiderDeaths; - this.seekerDeaths = seekerDeaths; - } - - public UUID getUniqueId() { - return uniqueId; - } - - public int getHiderWins() { - return hiderWins; - } - - public int getSeekerWins() { - return seekerWins; - } - - public int getHiderGames() { - return hiderGames; - } - - public int getSeekerGames() { - return seekerGames; - } - - public int getHiderKills() { - return hiderKills; - } - - public int getSeekerKills() { - return seekerKills; - } - - public int getHiderDeaths() { - return hiderDeaths; - } - - public int getSeekerDeaths() { - return seekerDeaths; - } - -} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java b/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java deleted file mode 100644 index 500cdc0..0000000 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/PlayerInfoTable.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * This file is part of Kenshins Hide and Seek - * - * Copyright (c) 2021 Tyler Murphy. - * - * Kenshins Hide and Seek free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * he Free Software Foundation version 3. - * - * Kenshins Hide and Seek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package net.tylermurphy.hideAndSeek.database; - -import net.tylermurphy.hideAndSeek.Main; -import net.tylermurphy.hideAndSeek.game.Board; -import net.tylermurphy.hideAndSeek.game.util.WinType; -import org.jetbrains.annotations.Nullable; - -import java.sql.*; -import java.util.*; - -public class PlayerInfoTable { - - private final Map CACHE = new HashMap<>(); - private final Database database; - - protected PlayerInfoTable(Database database) { - - String sql = "CREATE TABLE IF NOT EXISTS hs_data (\n" - + " 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" - + " seeker_deaths int NOT NULL\n" - + ");"; - - try(Connection connection = database.connect(); Statement statement = connection.createStatement()) { - statement.executeUpdate(sql); - } catch (SQLException e) { - Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); - e.printStackTrace(); - } - - this.database = database; - } - - @Nullable - public PlayerInfo getInfo(UUID uuid) { - if(CACHE.containsKey(uuid)) return CACHE.get(uuid); - String sql = "SELECT * FROM hs_data WHERE uuid = ?;"; - try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { - statement.setBytes(1, database.encodeUUID(uuid)); - ResultSet rs = statement.executeQuery(); - if (rs.next()) { - 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.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); - e.printStackTrace(); - } - return null; - } - - @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 = database.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.getInstance().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 ?;"; - try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { - statement.setInt(1, (page-1)*10); - ResultSet rs = statement.executeQuery(); - List infoList = new ArrayList<>(); - while(rs.next()) { - PlayerInfo info = new PlayerInfo( - database.decodeUUID(rs.getBytes("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") - ); - infoList.add(info); - } - rs.close(); - connection.close(); - return infoList; - } catch (SQLException e) { - Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); - e.printStackTrace(); - } - return null; - } - - @Nullable - public Integer getRanking(String order, UUID uuid) { - String sql = "SELECT count(*) AS total FROM hs_data WHERE "+order+" >= (SELECT "+order+" FROM hs_data WHERE uuid = ?) AND "+order+" > 0;"; - try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { - statement.setBytes(1, database.encodeUUID(uuid)); - ResultSet rs = statement.executeQuery(); - if (rs.next()) { - return rs.getInt("total"); - } - rs.close(); - } catch (SQLException e) { - Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); - e.printStackTrace(); - } - return null; - } - - public void addWins(Board board, List uuids, List winners, Map hider_kills, Map hider_deaths, Map seeker_kills, Map seeker_deaths, WinType type) { - for(UUID uuid : uuids) { - String sql = "INSERT OR REPLACE INTO hs_data (uuid, hider_wins, seeker_wins, hider_games, seeker_games, hider_kills, seeker_kills, hider_deaths, seeker_deaths) VALUES (?,?,?,?,?,?,?,?,?)"; - PlayerInfo info = getInfo(uuid); - if(info == null){ - info = new PlayerInfo(uuid, 0, 0, 0, 0, 0, 0, 0, 0); - } - try(Connection connection = database.connect(); PreparedStatement statement = connection.prepareStatement(sql)) { - statement.setBytes(1, database.encodeUUID(uuid)); - statement.setInt(2, info.getHiderWins() + (winners.contains(uuid) && type == WinType.HIDER_WIN ? 1 : 0)); - statement.setInt(3, info.getSeekerWins() + (winners.contains(uuid) && type == WinType.SEEKER_WIN ? 1 : 0)); - statement.setInt(4, info.getHiderGames() + (board.isHider(uuid) || (board.isSeeker(uuid) && !board.getFirstSeeker().getUniqueId().equals(uuid)) ? 1 : 0)); - statement.setInt(5, info.getSeekerGames() + (board.getFirstSeeker().getUniqueId().equals(uuid) ? 1 : 0)); - statement.setInt(6, info.getHiderKills() + hider_kills.getOrDefault(uuid.toString(), 0)); - statement.setInt(7, info.getSeekerKills() + seeker_kills.getOrDefault(uuid.toString(), 0)); - statement.setInt(8, info.getHiderDeaths() + hider_deaths.getOrDefault(uuid.toString(), 0)); - statement.setInt(9, info.getSeekerDeaths() + seeker_deaths.getOrDefault(uuid.toString(), 0)); - statement.execute(); - } catch (SQLException e) { - Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); - e.printStackTrace(); - return; - } finally { - CACHE.remove(uuid); - } - } - } - -} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/DatabaseConnection.java b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/DatabaseConnection.java new file mode 100644 index 0000000..466bda5 --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/DatabaseConnection.java @@ -0,0 +1,29 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database.connections; + +import java.sql.Connection; +import java.sql.SQLException; + +public interface DatabaseConnection { + + Connection connect() throws SQLException; + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java new file mode 100644 index 0000000..c29d1b3 --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java @@ -0,0 +1,61 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database.connections; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; + +import java.sql.Connection; +import java.sql.SQLException; + +public class MySQLConnection implements DatabaseConnection { + + private final HikariConfig config; + private final HikariDataSource ds; + + public MySQLConnection(){ + + String host = "to be implemented"; + String port = "to be implemented"; + String user = "to be implemented"; + String pass = "to be implemented"; + + config = new HikariConfig(); + + config.setJdbcUrl("jdbc:mariadb://"+host+":"+port+"/kenbot"); + config.addDataSourceProperty("cachePrepStmts", "true"); + config.addDataSourceProperty("prepStmtCacheSize", "250"); + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + config.addDataSourceProperty("user", user); + config.addDataSourceProperty("password",pass); + config.addDataSourceProperty("autoCommit", "true"); + config.setAutoCommit(true); + config.setMaximumPoolSize(20); + + ds = new HikariDataSource(config); + + } + + @Override + public Connection connect() throws SQLException { + return ds.getConnection(); + } + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java new file mode 100644 index 0000000..1a03106 --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java @@ -0,0 +1,64 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database.connections; + +import net.tylermurphy.hideAndSeek.Main; +import org.sqlite.SQLiteConfig; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public class SQLiteConnection implements DatabaseConnection { + + private final File databaseFile; + private final SQLiteConfig config; + + public SQLiteConnection(){ + + try { + Class.forName("org.sqlite.JDBC"); + } catch (ClassNotFoundException e) { + Main.getInstance().getLogger().severe(e.getMessage()); + throw new RuntimeException(e.getMessage()); + } + + databaseFile = new File(Main.getInstance().getDataFolder(), "database.db"); + + config = new SQLiteConfig(); + config.setSynchronous(SQLiteConfig.SynchronousMode.NORMAL); + config.setTempStore(SQLiteConfig.TempStore.MEMORY); + } + + @Override + public Connection connect() { + Connection conn = null; + try { + String url = "jdbc:sqlite:"+databaseFile; + conn = DriverManager.getConnection(url, config.toProperties()); + } catch (SQLException e) { + Main.getInstance().getLogger().severe(e.getMessage()); + e.printStackTrace(); + } + return conn; + } + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/util/LegacyPlayerInfo.java b/src/main/java/net/tylermurphy/hideAndSeek/database/util/LegacyPlayerInfo.java new file mode 100644 index 0000000..5b59779 --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/util/LegacyPlayerInfo.java @@ -0,0 +1,56 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2021-2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database.util; + +import java.util.UUID; + +public class LegacyPlayerInfo { + + private final byte[] uniqueId; + private final int totalWins; + private final int hiderWins; + private final int seekerWins; + private final int gamesPlayed; + + public LegacyPlayerInfo(byte[] uniqueId, int totalWins, int hiderWins, int seekerWins, int gamesPlayed) { + this.uniqueId = uniqueId; + this.totalWins = totalWins; + this.hiderWins = hiderWins; + this.seekerWins = seekerWins; + this.gamesPlayed = gamesPlayed; + } + + public byte[] getUniqueId() { + return uniqueId; + } + + public int getTotalWins() { return totalWins; } + + public int getHiderWins() { + return hiderWins; + } + + public int getSeekerWins() { + return seekerWins; + } + + public int getGamesPlayer() { return gamesPlayed; } + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/util/PlayerInfo.java b/src/main/java/net/tylermurphy/hideAndSeek/database/util/PlayerInfo.java new file mode 100644 index 0000000..96fe9d8 --- /dev/null +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/util/PlayerInfo.java @@ -0,0 +1,84 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2021-2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +package net.tylermurphy.hideAndSeek.database.util; + +import java.util.UUID; + +public class PlayerInfo { + + private final UUID uniqueId; + private final int hiderWins; + private final int seekerWins; + private final int hiderGames; + private final int seekerGames; + private final int hiderKills; + private final int seekerKills; + private final int hiderDeaths; + private final int seekerDeaths; + + public PlayerInfo(UUID uniqueId, int hiderWins, int seekerWins, int hiderGames, int seekerGames, int hiderKills, int seekerKills, int hiderDeaths, int seekerDeaths) { + this.uniqueId = uniqueId; + this.hiderWins = hiderWins; + this.seekerWins = seekerWins; + this.hiderGames = hiderGames; + this.seekerGames = seekerGames; + this.hiderKills = hiderKills; + this.seekerKills = seekerKills; + this.hiderDeaths = hiderDeaths; + this.seekerDeaths = seekerDeaths; + } + + public UUID getUniqueId() { + return uniqueId; + } + + public int getHiderWins() { + return hiderWins; + } + + public int getSeekerWins() { + return seekerWins; + } + + public int getHiderGames() { + return hiderGames; + } + + public int getSeekerGames() { + return seekerGames; + } + + public int getHiderKills() { + return hiderKills; + } + + public int getSeekerKills() { + return seekerKills; + } + + public int getHiderDeaths() { + return hiderDeaths; + } + + public int getSeekerDeaths() { + return seekerDeaths; + } + +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java index 37865b0..094ff68 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java @@ -23,6 +23,9 @@ public class JoinLeaveHandler implements Listener { @EventHandler(priority = EventPriority.HIGHEST) public void onPlayerJoin(PlayerJoinEvent event) { + if(!Main.getInstance().getDatabase().getNameData().update(event.getPlayer().getUniqueId(), event.getPlayer().getDisplayName())){ + Main.getInstance().getLogger().warning("Failed to save name data for user: " + event.getPlayer().getDisplayName()); + } Main.getInstance().getBoard().remove(event.getPlayer()); removeItems(event.getPlayer()); if (Main.getInstance().getGame().isNotSetup()) return; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java index c1f8c2a..72d1f4d 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java @@ -3,7 +3,7 @@ package net.tylermurphy.hideAndSeek.util; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import net.tylermurphy.hideAndSeek.Main; import net.tylermurphy.hideAndSeek.database.Database; -import net.tylermurphy.hideAndSeek.database.PlayerInfo; +import net.tylermurphy.hideAndSeek.database.util.PlayerInfo; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; diff --git a/src/test/java/MainTest.java b/src/test/java/MainTest.java new file mode 100644 index 0000000..9997e04 --- /dev/null +++ b/src/test/java/MainTest.java @@ -0,0 +1,42 @@ +/* + * This file is part of Kenshins Hide and Seek + * + * Copyright (c) 2022 Tyler Murphy. + * + * Kenshins Hide and Seek free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * he Free Software Foundation version 3. + * + * Kenshins Hide and Seek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import net.tylermurphy.hideAndSeek.Main; +import org.junit.After; +import org.junit.Before; + +public class MainTest { + + private ServerMock server; + private Main plugin; + + @Before + public void setUp() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(Main.class); + } + + @After + public void tearDown() { + MockBukkit.unmock(); + } + +} -- cgit v1.2.3-freya From 13e6b38aa97f59e5a432f2d88ea15738358df019 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Tue, 17 May 2022 19:26:00 -0400 Subject: mysql support, always glow, countdown_last, kill stat change, game board null fix --- pom.xml | 6 ++-- .../net/tylermurphy/hideAndSeek/command/Top.java | 9 ++++- .../net/tylermurphy/hideAndSeek/command/Wins.java | 20 +++++------ .../hideAndSeek/configuration/Config.java | 25 +++++++++++-- .../hideAndSeek/configuration/ConfigManager.java | 4 +++ .../hideAndSeek/configuration/Localization.java | 24 +++++++++---- .../tylermurphy/hideAndSeek/database/Database.java | 9 ++++- .../database/connections/MySQLConnection.java | 16 ++++----- .../net/tylermurphy/hideAndSeek/game/Board.java | 6 ++-- .../net/tylermurphy/hideAndSeek/game/Game.java | 6 ++-- .../tylermurphy/hideAndSeek/game/events/Glow.java | 7 ++-- .../hideAndSeek/game/listener/DamageHandler.java | 11 +++--- .../game/listener/JoinLeaveHandler.java | 4 +-- .../hideAndSeek/util/PAPIExpansion.java | 37 ++++++++++--------- src/main/resources/config.yml | 28 +++++++++++++++ src/main/resources/lang/localization_de-DE.yml | 1 + src/main/resources/lang/localization_en-US.yml | 1 + src/test/java/MainTest.java | 42 ---------------------- 18 files changed, 146 insertions(+), 110 deletions(-) delete mode 100644 src/test/java/MainTest.java (limited to 'pom.xml') diff --git a/pom.xml b/pom.xml index fff9f6c..b72260d 100644 --- a/pom.xml +++ b/pom.xml @@ -41,8 +41,10 @@ *:* META-INF/*.MF - META-INF/*.md - META-INF + META-INF/*.MD + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA sqlite-jdbc.properties diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java b/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java index caa751b..9b55c9f 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/Top.java @@ -22,6 +22,7 @@ package net.tylermurphy.hideAndSeek.command; import net.tylermurphy.hideAndSeek.Main; import net.tylermurphy.hideAndSeek.database.util.PlayerInfo; import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import java.util.List; @@ -54,7 +55,13 @@ public class Top implements ICommand { return; } for(PlayerInfo info : infos) { - String name = Main.getInstance().getServer().getOfflinePlayer(info.getUniqueId()).getName(); + OfflinePlayer temp = Main.getInstance().getServer().getOfflinePlayer(info.getUniqueId()); + String name; + if(temp == null){ + name = Main.getInstance().getDatabase().getNameData().getName(info.getUniqueId()); + } else { + name = temp.getName(); + } ChatColor color; switch (i) { case 1: color = ChatColor.YELLOW; break; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java b/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java index 8a0b6dc..491c9a4 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/Wins.java @@ -37,23 +37,21 @@ public class Wins implements ICommand { UUID uuid; String name; if (args.length == 0) { - Player player = Main.getInstance().getServer().getPlayer(sender.getName()); - if (player == null) { - sender.sendMessage(errorPrefix + message("START_INVALID_NAME").addPlayer(sender.getName())); - return; - } - uuid = player.getUniqueId(); + uuid = sender.getUniqueId(); name = sender.getName(); } else { - try { - name = args[0]; + name = args[0]; + if(Main.getInstance().getServer().getOfflinePlayer(args[0]) == null){ + uuid = Main.getInstance().getDatabase().getNameData().getUUID(args[0]); + } else { uuid = Main.getInstance().getServer().getOfflinePlayer(args[0]).getUniqueId(); - } catch (Exception e) { - sender.sendMessage(errorPrefix + message("START_INVALID_NAME").addPlayer(args[0])); - return; } } + if(uuid == null){ + sender.sendMessage(errorPrefix + message("START_INVALID_NAME").addPlayer(args[0])); + return; + } PlayerInfo info = Main.getInstance().getDatabase().getGameData().getInfo(uuid); if (info == null) { sender.sendMessage(errorPrefix + message("NO_GAME_INFO")); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java index 03d7504..4aeac68 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java @@ -55,7 +55,13 @@ public class Config { locale, leaveServer, placeholderError, - placeholderNoData; + placeholderNoData, + databaseType, + databaseHost, + databasePort, + databaseUser, + databasePass, + databaseName; public static Vector spawnPosition, @@ -71,6 +77,7 @@ public class Config { tauntEnabled, tauntCountdown, tauntLast, + alwaysGlow, glowEnabled, glowStackable, pvpEnabled, @@ -218,9 +225,10 @@ public class Config { tauntLast = config.getBoolean("taunt.whenLastPerson"); //Glow + alwaysGlow = config.getBoolean("alwaysGlow") && Main.getInstance().supports(9); glowLength = Math.max(1, config.getInt("glow.time")); glowStackable = config.getBoolean("glow.stackable"); - glowEnabled = config.getBoolean("glow.enabled") && Main.getInstance().supports(9); + glowEnabled = config.getBoolean("glow.enabled") && Main.getInstance().supports(9) && !alwaysGlow; if (glowEnabled) { glowPowerupItem = createItemStack("glow"); } @@ -314,6 +322,19 @@ public class Config { teleportItem = createItemStack("spectatorItems.teleport"); teleportItemPosition = config.getInt("spectatorItems.teleport.position"); + + //Database + databaseHost = config.getString("databaseHost"); + databasePort = config.getString("databasePort"); + databaseUser = config.getString("databaseUser"); + databasePass = config.getString("databasePass"); + databaseName = config.getString("databaseName"); + + databaseType = config.getString("databaseType").toUpperCase(); + if(!databaseType.equals("SQLITE") && !databaseType.equals("MYSQL")){ + Main.getInstance().getLogger().warning("databaseType: "+databaseType+" is not a valid configuration option!"); + databaseType = "SQLITE"; + } } public static void addToConfig(String path, Object value) { diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java index f02eaba..381a41c 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java @@ -205,6 +205,10 @@ public class ConfigManager { } } + public ConfigurationSection getDefaultConfigurationSection(String path) { + return defaultConfig.getConfigurationSection(path); + } + public void set(String path, Object value) { config.set(path, value); } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Localization.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Localization.java index be60b61..9418414 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Localization.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Localization.java @@ -28,6 +28,7 @@ import java.util.Map; public class Localization { public static final Map LOCAL = new HashMap<>(); + public static final Map DEFAULT_LOCAL = new HashMap<>(); private static final Map CHANGES = new HashMap() {{ put("en-US", new String[][]{{"WORLDBORDER_DECREASING"},{"START","TAUNTED"}}); @@ -61,17 +62,28 @@ public class Localization { for(String key : manager.getConfigurationSection("Localization").getKeys(false)) { LOCAL.put( - key, + key, new LocalizationString( ChatColor.translateAlternateColorCodes('&', manager.getString("Localization."+key) ) ) - ); + ); + } + + for(String key : manager.getDefaultConfigurationSection("Localization").getKeys(false)) { + DEFAULT_LOCAL.put( + key, + new LocalizationString( ChatColor.translateAlternateColorCodes('&', manager.getString("Localization."+key) ) ) + ); } } public static LocalizationString message(String key) { - LocalizationString temp = LOCAL.get(key); - if (temp == null) { - return new LocalizationString(ChatColor.RED + "" + ChatColor.ITALIC + key + " is not found in localization.yml. This is a plugin issue, please report it."); + LocalizationString message = LOCAL.get(key); + if (message == null) { + LocalizationString defaultMessage = DEFAULT_LOCAL.get(key); + if(defaultMessage == null) { + return new LocalizationString(ChatColor.RED + "" + ChatColor.ITALIC + key + " is not found in localization.yml. This is a plugin issue, please report it."); + } + return new LocalizationString(defaultMessage.toString()); } - return new LocalizationString(temp.toString()); + return new LocalizationString(message.toString()); } } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java index 0eceb98..0489b5d 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/Database.java @@ -22,6 +22,7 @@ package net.tylermurphy.hideAndSeek.database; import com.google.common.io.ByteStreams; import net.tylermurphy.hideAndSeek.Main; import net.tylermurphy.hideAndSeek.database.connections.DatabaseConnection; +import net.tylermurphy.hideAndSeek.database.connections.MySQLConnection; import net.tylermurphy.hideAndSeek.database.connections.SQLiteConnection; import java.io.ByteArrayInputStream; @@ -32,6 +33,8 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.UUID; +import static net.tylermurphy.hideAndSeek.configuration.Config.databaseType; + public class Database { private final GameDataTable playerInfo; @@ -40,7 +43,11 @@ public class Database { public Database(){ - connection = new SQLiteConnection(); + if(databaseType.equals("SQLITE")) { + connection = new SQLiteConnection(); + } else { + connection = new MySQLConnection(); + } playerInfo = new GameDataTable(this); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java index c29d1b3..b7c1b1d 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java @@ -25,26 +25,22 @@ import com.zaxxer.hikari.HikariDataSource; import java.sql.Connection; import java.sql.SQLException; +import static net.tylermurphy.hideAndSeek.configuration.Config.*; + public class MySQLConnection implements DatabaseConnection { - private final HikariConfig config; private final HikariDataSource ds; public MySQLConnection(){ - String host = "to be implemented"; - String port = "to be implemented"; - String user = "to be implemented"; - String pass = "to be implemented"; - - config = new HikariConfig(); + HikariConfig config = new HikariConfig(); - config.setJdbcUrl("jdbc:mariadb://"+host+":"+port+"/kenbot"); + config.setJdbcUrl("jdbc:mariadb://"+databaseHost+":"+databasePort+"/"+databaseName); config.addDataSourceProperty("cachePrepStmts", "true"); config.addDataSourceProperty("prepStmtCacheSize", "250"); config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); - config.addDataSourceProperty("user", user); - config.addDataSourceProperty("password",pass); + config.addDataSourceProperty("user", databaseUser); + config.addDataSourceProperty("password",databasePass); config.addDataSourceProperty("autoCommit", "true"); config.setAutoCommit(true); config.setMaximumPoolSize(20); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java index 04b0d37..a8e41c7 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java @@ -153,7 +153,7 @@ public class Board { } else { hider_kills.put(uuid.toString(), 1); } - } else if (getFirstSeeker().getUniqueId().equals(uuid)) { + } else if (Seeker.contains(uuid.toString())) { if (seeker_kills.containsKey(uuid.toString())) { seeker_kills.put(uuid.toString(), seeker_kills.get(uuid.toString())+1); } else { @@ -169,7 +169,7 @@ public class Board { } else { hider_deaths.put(uuid.toString(), 1); } - } else if (getFirstSeeker().getUniqueId().equals(uuid)) { + } else if (Seeker.contains(uuid.toString())) { if (seeker_deaths.containsKey(uuid.toString())) { seeker_deaths.put(uuid.toString(), seeker_deaths.get(uuid.toString())+1); } else { @@ -234,7 +234,7 @@ public class Board { private void createGameBoard(Player player, boolean recreate) { CustomBoard board = customBoards.get(player.getUniqueId().toString()); - if (recreate) { + if (recreate || board == null) { board = new CustomBoard(player, GAME_TITLE); board.updateTeams(); } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java index c261b52..cb3ad1f 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java @@ -242,12 +242,14 @@ public class Game { private void whileStarting() { if(gameTick % 20 == 0) { - if (startingTimer % 5 == 0 || startingTimer < 4) { + if (startingTimer % 5 == 0 || startingTimer < 5) { String message; if (startingTimer == 0) { message = message("START").toString(); status = Status.PLAYING; board.getPlayers().forEach(player -> PlayerLoader.resetPlayer(player, board)); + } else if (startingTimer == 1){ + message = message("START_COUNTDOWN_LAST").addAmount(startingTimer).toString(); } else { message = message("START_COUNTDOWN").addAmount(startingTimer).toString(); } @@ -305,7 +307,7 @@ public class Game { } if (worldBorderEnabled) worldBorder.update(); if (tauntEnabled) taunt.update(); - if (glowEnabled) glow.update(); + if (glowEnabled || alwaysGlow) glow.update(); } board.getSpectators().forEach(spectator -> spectator.setFlying(spectator.getAllowFlight())); checkWinConditions(); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/events/Glow.java b/src/main/java/net/tylermurphy/hideAndSeek/game/events/Glow.java index a1d7295..8631ef5 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/events/Glow.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/events/Glow.java @@ -10,8 +10,7 @@ import org.bukkit.entity.Player; import java.lang.reflect.InvocationTargetException; -import static net.tylermurphy.hideAndSeek.configuration.Config.glowLength; -import static net.tylermurphy.hideAndSeek.configuration.Config.glowStackable; +import static net.tylermurphy.hideAndSeek.configuration.Config.*; public class Glow { @@ -37,6 +36,10 @@ public class Glow { } public void update() { + if(alwaysGlow){ + sendPackets(); + return; + } if (running) { sendPackets(); glowTime--; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java index 701f446..3b90d39 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java @@ -96,21 +96,18 @@ public class DamageHandler implements Listener { // Broadcast player death message if (board.isSeeker(player)) { game.broadcastMessage(message("GAME_PLAYER_DEATH").addPlayer(player).toString()); - if (board.getFirstSeeker().getName().equals(player.getName())) { - board.addDeath(player.getUniqueId()); - } } else if (board.isHider(player)) { if (attacker == null) { game.broadcastMessage(message("GAME_PLAYER_FOUND").addPlayer(player).toString()); } else { game.broadcastMessage(message("GAME_PLAYER_FOUND_BY").addPlayer(player).addPlayer(attacker).toString()); } - board.addDeath(player.getUniqueId()); board.addSeeker(player); } - // Add leaderboard kills if attacker - if (attacker != null && ( board.isHider(attacker) || board.getFirstSeeker().getName().equals(attacker.getName()) ) ) - board.addKill(attacker.getUniqueId()); + // Add leaderboard stats + board.addDeath(player.getUniqueId()); + if (attacker != null) board.addKill(attacker.getUniqueId()); + //Reload player PlayerLoader.resetPlayer(player, board); board.reloadBoardTeams(); } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java index 094ff68..7ac4f85 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/JoinLeaveHandler.java @@ -23,8 +23,8 @@ public class JoinLeaveHandler implements Listener { @EventHandler(priority = EventPriority.HIGHEST) public void onPlayerJoin(PlayerJoinEvent event) { - if(!Main.getInstance().getDatabase().getNameData().update(event.getPlayer().getUniqueId(), event.getPlayer().getDisplayName())){ - Main.getInstance().getLogger().warning("Failed to save name data for user: " + event.getPlayer().getDisplayName()); + if(!Main.getInstance().getDatabase().getNameData().update(event.getPlayer().getUniqueId(), event.getPlayer().getName())){ + Main.getInstance().getLogger().warning("Failed to save name data for user: " + event.getPlayer().getName()); } Main.getInstance().getBoard().remove(event.getPlayer()); removeItems(event.getPlayer()); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java index 72d1f4d..7823fe9 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java @@ -39,15 +39,17 @@ public class PAPIExpansion extends PlaceholderExpansion { Database database = Main.getInstance().getDatabase(); String[] args = params.split("_"); if (args.length < 1) return null; - if (args[0].equals("stats") && args.length == 2) { - PlayerInfo info = database.getGameData().getInfo(player.getUniqueId()); + if (args[0].equals("stats") && (args.length == 2 || args.length == 3)) { + PlayerInfo info = null; + if(args.length == 2) { + database.getGameData().getInfo(player.getUniqueId()); + } else { + UUID uuid; + try { uuid = Main.getInstance().getServer().getOfflinePlayer(args[2]).getUniqueId(); } catch (Exception e) { return placeholderError; } + info = database.getGameData().getInfo(uuid); + } if (info == null) return placeholderNoData; return getValue(info, args[1]); - } else if (args[0].equals("stats") && args.length == 3) { - UUID uuid; - try { uuid = Main.getInstance().getServer().getOfflinePlayer(args[2]).getUniqueId(); } catch (Exception e) { return placeholderError; } - PlayerInfo info = database.getGameData().getInfo(uuid); - return getValue(info, args[1]); } else if ((args[0].equals("rank-score") || args[0].equals("rank-name") ) && args.length == 3) { int place; try { place = Integer.parseInt(args[2]); } catch (NumberFormatException e) { return placeholderError; } @@ -60,24 +62,21 @@ public class PAPIExpansion extends PlaceholderExpansion { } else { return Main.getInstance().getServer().getOfflinePlayer(info.getUniqueId()).getName(); } - } else if (args[0].equals("rank-place") && args.length == 2) { + } else if (args[0].equals("rank-place") && (args.length == 2 || args.length == 3)) { if (getRanking(args[1]) == null) { return placeholderError; } - PlayerInfo info = database.getGameData().getInfo(player.getUniqueId()); + PlayerInfo info = null; + if(args.length == 2){ + database.getGameData().getInfo(player.getUniqueId()); + } else { + UUID uuid; + try { uuid = Main.getInstance().getServer().getOfflinePlayer(args[2]).getUniqueId(); } catch (Exception e) { return placeholderError; } + info = database.getGameData().getInfo(uuid); + } if (info == null) return placeholderNoData; if (getValue(info, args[1]).equals("0")) { return "-"; } Integer count = database.getGameData().getRanking(getRanking(args[1]), player.getUniqueId()); if (count == null) { return placeholderNoData; } return count.toString(); - } else if (args[0].equals("rank-place") && args.length == 3) { - UUID uuid; - try { uuid = Main.getInstance().getServer().getOfflinePlayer(args[2]).getUniqueId(); } catch (Exception e) { return placeholderError; } - if (getRanking(args[1]) == null) { return placeholderError; } - PlayerInfo info = database.getGameData().getInfo(player.getUniqueId()); - if (info == null) return placeholderNoData; - if (getValue(info, args[1]).equals("0")) { return "-"; } - Integer count = database.getGameData().getRanking(getRanking(args[1]), uuid); - if (count == null) { return placeholderNoData; } - return count.toString(); } return null; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2d76b4a..6153c46 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -94,6 +94,26 @@ leaveServer: hub # default: true mapSaveEnabled: true +# How you want to store game data. If you are running a single server, sqlite is fine, as no setup is necessary. +# But if you want the data to go across multiple servers, you can switch it to mysql. +# WARNING: Data is not saved across databases. You have to migrate the data yourself! +# +# SQLITE - A single database.db file in the plugin folder, good for a single server. +# +# MYSQL - Uses a mysql server to store data, good for multi-server setups or large servers. +# +# default: SQLITE +databaseType: SQLITE + +# The following settings are used for MYSQL databases ONLY. If you are running SQLITE, these +# will be ignored. If you are running MYSQL, you need to provide the database host url, database +# host port (usually 3306), database username, and database password. +databaseHost: localhost +databasePort: 3306 +databaseUser: root +databasePass: +databaseName: hideandseek + # The world border closes every interval, which is evey [delay] in minutes. # Thw world border starts at [size], and decreases 100 blocks every interval. # x & z are the center location. [enabled] is whenever the border is enabled. @@ -132,6 +152,14 @@ glow: material: SNOWBALL model-data: 0 +# This has the same glow effect as the glow powerup in that all seekers positions get +# shown to hiders. But enabling this force disables the powerup, and instead always shows +# the seekers positions to the hiders. Good for small maps. Since the glow effect wasn't added +# until Minecraft 1.9, any server running 1.8 will have this disabled regardless of the +# options below. +# default: false +alwaysGlow: false + # The message prefixes displayed before messages. The message contents themselves # can be changed in localization.yml. prefix: diff --git a/src/main/resources/lang/localization_de-DE.yml b/src/main/resources/lang/localization_de-DE.yml index 84ada18..a1a6eea 100644 --- a/src/main/resources/lang/localization_de-DE.yml +++ b/src/main/resources/lang/localization_de-DE.yml @@ -56,6 +56,7 @@ Localization: START_MIN_PLAYERS: "Um das Spiel zu starten benötigst du mindestens {AMOUNT} Spieler." START_INVALID_NAME: "Ungültiger Spieler: {PLAYER}." START_COUNTDOWN: "Die Hider haben {AMOUNT} Sekunden Zeit sich zu verstecken!" + START_COUNTDOWN_LAST: "Die Hider haben {AMOUNT} Sekunde Zeit sich zu verstecken!" START: "Los, Seeker! Es ist Zeit, die Hider zu finden." STOP: "Das Spiel wurde gestoppt." HIDER_TEAM_NAME: "&6&lHIDER" diff --git a/src/main/resources/lang/localization_en-US.yml b/src/main/resources/lang/localization_en-US.yml index 07d547b..96ccf7a 100644 --- a/src/main/resources/lang/localization_en-US.yml +++ b/src/main/resources/lang/localization_en-US.yml @@ -57,6 +57,7 @@ Localization: START_MIN_PLAYERS: "You must have at least {AMOUNT} players to start." START_INVALID_NAME: "Invalid player: {PLAYER}." START_COUNTDOWN: "Hiders have {AMOUNT} seconds to hide!" + START_COUNTDOWN_LAST: "Hiders have {AMOUNT} second to hide!" START: "Attention SEEKERS, its time to find the hiders!" STOP: "Game has been force stopped." HIDER_TEAM_NAME: "&6&lHIDER" diff --git a/src/test/java/MainTest.java b/src/test/java/MainTest.java deleted file mode 100644 index 9997e04..0000000 --- a/src/test/java/MainTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Kenshins Hide and Seek - * - * Copyright (c) 2022 Tyler Murphy. - * - * Kenshins Hide and Seek free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * he Free Software Foundation version 3. - * - * Kenshins Hide and Seek is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -import be.seeseemelk.mockbukkit.MockBukkit; -import be.seeseemelk.mockbukkit.ServerMock; -import net.tylermurphy.hideAndSeek.Main; -import org.junit.After; -import org.junit.Before; - -public class MainTest { - - private ServerMock server; - private Main plugin; - - @Before - public void setUp() { - server = MockBukkit.mock(); - plugin = MockBukkit.load(Main.class); - } - - @After - public void tearDown() { - MockBukkit.unmock(); - } - -} -- cgit v1.2.3-freya From 0ce33ae3ce8ab24aa8d6cbb4527ea4aa695b7185 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Tue, 17 May 2022 19:35:12 -0400 Subject: pom fix --- pom.xml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'pom.xml') diff --git a/pom.xml b/pom.xml index b72260d..42cd0f7 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,7 @@ com.github.cryptomorin:XSeries org.xerial:sqlite-jdbc + org.mariadb.jdbc:mariadb-java-client com.zaxxer:HikariCP @@ -118,18 +119,12 @@ com.zaxxer HikariCP - 5.0.1 + 4.0.3 - org.junit.jupiter - junit-jupiter - 5.9.0-M1 - - - com.github.seeseemelk - MockBukkit-v1.17 - 1.13.0 - test + org.mariadb.jdbc + mariadb-java-client + 2.7.2 \ No newline at end of file -- cgit v1.2.3-freya From e79c4ad1c5dbbc3717fbb7ab1c5fcb7e2d538409 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Wed, 18 May 2022 21:45:38 -0400 Subject: 1.5.0 Release Canidate 2 (Previously 1.4.3) --- pom.xml | 4 +- .../java/net/tylermurphy/hideAndSeek/Main.java | 43 +++++++++++++++------- .../net/tylermurphy/hideAndSeek/command/About.java | 2 +- .../hideAndSeek/configuration/ConfigManager.java | 21 +++++++++-- .../net/tylermurphy/hideAndSeek/game/Board.java | 8 ++-- .../net/tylermurphy/hideAndSeek/game/Game.java | 2 +- .../hideAndSeek/game/listener/DamageHandler.java | 4 +- .../tylermurphy/hideAndSeek/world/WorldLoader.java | 2 + src/main/resources/plugin.yml | 4 +- 9 files changed, 60 insertions(+), 30 deletions(-) (limited to 'pom.xml') diff --git a/pom.xml b/pom.xml index 42cd0f7..7e1be5a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 net.tylermurphy - HideAndSeek - 1.4.3 + KenshinsHideAndSeek + 1.5.0 Hide and Seek Plugin UTF-8 diff --git a/src/main/java/net/tylermurphy/hideAndSeek/Main.java b/src/main/java/net/tylermurphy/hideAndSeek/Main.java index 7bd86cb..1248551 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/Main.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/Main.java @@ -24,6 +24,7 @@ import net.tylermurphy.hideAndSeek.configuration.Items; import net.tylermurphy.hideAndSeek.configuration.Localization; import net.tylermurphy.hideAndSeek.database.Database; import net.tylermurphy.hideAndSeek.game.Board; +import net.tylermurphy.hideAndSeek.game.PlayerLoader; import net.tylermurphy.hideAndSeek.game.util.Status; import net.tylermurphy.hideAndSeek.util.CommandHandler; import net.tylermurphy.hideAndSeek.game.Game; @@ -31,6 +32,7 @@ import net.tylermurphy.hideAndSeek.game.listener.*; import net.tylermurphy.hideAndSeek.util.PAPIExpansion; import net.tylermurphy.hideAndSeek.util.TabCompleter; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.event.Listener; @@ -44,6 +46,9 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import static net.tylermurphy.hideAndSeek.configuration.Config.exitPosition; +import static net.tylermurphy.hideAndSeek.configuration.Config.exitWorld; + public class Main extends JavaPlugin implements Listener { private static Main instance; @@ -56,11 +61,7 @@ public class Main extends JavaPlugin implements Listener { public Main() { super(); - instance = this; - - Config.loadConfig(); - Localization.loadLocalization(); - Items.loadItems(); + onConstructed(); board = new Board(); database = new Database(); @@ -68,15 +69,27 @@ public class Main extends JavaPlugin implements Listener { protected Main(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { super(loader, description, dataFolder, file); + onConstructed(); + + board = new Board(); + database = new Database(); + } + + private void onConstructed(){ instance = this; + Matcher matcher = Pattern.compile("MC: \\d\\.(\\d+)").matcher(Bukkit.getVersion()); + if (matcher.find()) { + version = Integer.parseInt(matcher.group(1)); + } else { + throw new IllegalArgumentException("Failed to parse server version from: " + Bukkit.getVersion()); + } + Config.loadConfig(); Localization.loadLocalization(); Items.loadItems(); - board = new Board(); - database = new Database(); } public void onEnable() { @@ -94,16 +107,18 @@ public class Main extends JavaPlugin implements Listener { if (getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) { new PAPIExpansion().register(); } - - Matcher matcher = Pattern.compile("MC: \\d\\.(\\d+)").matcher(Bukkit.getVersion()); - if (matcher.find()) { - version = Integer.parseInt(matcher.group(1)); - } else { - throw new IllegalArgumentException("Failed to parse server version from: " + Bukkit.getVersion()); - } } public void onDisable() { + + version = 0; + + board.getPlayers().forEach(player -> { + board.removeBoard(player); + PlayerLoader.unloadPlayer(player); + player.teleport(new Location(Bukkit.getWorld(exitWorld), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ())); + }); + Bukkit.getServer().getMessenger().unregisterOutgoingPluginChannel(this); board.cleanup(); } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/About.java b/src/main/java/net/tylermurphy/hideAndSeek/command/About.java index f996519..bda6016 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/About.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/About.java @@ -26,7 +26,7 @@ public class About implements ICommand { public void execute(Player sender, String[] args) { sender.sendMessage( - String.format("%s%sHide and Seek %s(%s1.4.3%s)\n", ChatColor.AQUA, ChatColor.BOLD, ChatColor.GRAY,ChatColor.WHITE,ChatColor.GRAY) + + String.format("%s%sHide and Seek %s(%s1.5.0%s)\n", ChatColor.AQUA, ChatColor.BOLD, ChatColor.GRAY,ChatColor.WHITE,ChatColor.GRAY) + String.format("%sAuthor: %s[KenshinEto]\n", ChatColor.GRAY, ChatColor.WHITE) + String.format("%sHelp Command: %s/hs %shelp", ChatColor.GRAY, ChatColor.AQUA, ChatColor.WHITE) ); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java index 381a41c..5e28258 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/ConfigManager.java @@ -46,12 +46,25 @@ public class ConfigManager { private ConfigManager(String filename, String defaultFilename) { + File dataFolder = Main.getInstance().getDataFolder(); + File oldDataFolder = new File(Main.getInstance().getDataFolder().getParent() + File.separator + "HideAndSeek"); + this.defaultFilename = defaultFilename; - this.file = new File(Main.getInstance().getDataFolder(), filename); + this.file = new File(dataFolder, filename); + + if(oldDataFolder.exists()){ + if(!dataFolder.exists()){ + if(!oldDataFolder.renameTo(dataFolder)){ + throw new RuntimeException("Could not rename folder: " + oldDataFolder.getPath()); + } + } else { + throw new RuntimeException("Plugin folders for HideAndSeek & KenshinsHideAndSeek both exists. There can only be one!"); + } + + } - File folder = Main.getInstance().getDataFolder(); - if (!folder.exists()) { - if (!folder.mkdirs()) { + if (!dataFolder.exists()) { + if (!dataFolder.mkdirs()) { throw new RuntimeException("Failed to make directory: " + file.getPath()); } } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java index a8e41c7..bb1984e 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java @@ -79,11 +79,11 @@ public class Board { } public List getHiders() { - return Hider.stream().map(playerList::get).collect(Collectors.toList()); + return Hider.stream().filter(Objects::nonNull).map(playerList::get).collect(Collectors.toList()); } public List getSeekers() { - return Seeker.stream().map(playerList::get).collect(Collectors.toList()); + return Seeker.stream().filter(Objects::nonNull).map(playerList::get).collect(Collectors.toList()); } public Player getFirstSeeker() { @@ -91,11 +91,11 @@ public class Board { } public List getSpectators() { - return Spectator.stream().map(playerList::get).collect(Collectors.toList()); + return Spectator.stream().filter(Objects::nonNull).map(playerList::get).collect(Collectors.toList()); } public List getPlayers() { - return new ArrayList<>(playerList.values()); + return playerList.values().stream().filter(Objects::nonNull).collect(Collectors.toList()); } public Player getPlayer(UUID uuid) { diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java index cb3ad1f..34f3a46 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java @@ -121,11 +121,11 @@ public class Game { board.addSeeker(seeker); PlayerLoader.loadSeeker(seeker, getGameWorld()); board.getPlayers().forEach(player -> { - board.createGameBoard(player); if(board.isSeeker(player)) return; board.addHider(player); PlayerLoader.loadHider(player, getGameWorld()); }); + board.getPlayers().forEach(board::createGameBoard); worldBorder.resetWorldBorder(getGameWorld()); if (gameLength > 0) gameTimer = gameLength; status = Status.STARTING; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java index 3b90d39..086a48a 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java @@ -69,9 +69,9 @@ public class DamageHandler implements Listener { // Spectators cannot take damage if (board.isSpectator(player)) { event.setCancelled(true); - if (Main.getInstance().supports(18) && player.getLocation().getY() < -64) { + if (Main.getInstance().supports(18) && player.getLocation().getBlockY() < -64) { player.teleport(new Location(Bukkit.getWorld(game.getGameWorld()), spawnPosition.getX(), spawnPosition.getY(), spawnPosition.getZ())); - } else if (player.getLocation().getY() < 0) { + } else if (!Main.getInstance().supports(18) && player.getLocation().getY() < 0) { player.teleport(new Location(Bukkit.getWorld(game.getGameWorld()), spawnPosition.getX(), spawnPosition.getY(), spawnPosition.getZ())); } return; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java b/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java index ebfedcd..1d4ff71 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/world/WorldLoader.java @@ -21,6 +21,7 @@ package net.tylermurphy.hideAndSeek.world; import net.tylermurphy.hideAndSeek.Main; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldCreator; @@ -55,6 +56,7 @@ public class WorldLoader { Main.getInstance().getLogger().warning(saveName + " already unloaded."); return; } + world.getPlayers().forEach(player -> player.teleport(new Location(Bukkit.getWorld(exitWorld), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ()))); if (Bukkit.getServer().unloadWorld(world, false)) { Main.getInstance().getLogger().info("Successfully unloaded " + saveName); }else{ diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 74c4855..c4224dc 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ -name: HideAndSeek +name: KenshinsHideAndSeek main: net.tylermurphy.hideAndSeek.Main -version: 1.4.3 +version: 1.5.0 author: KenshinEto load: STARTUP api-version: 1.13 -- cgit v1.2.3-freya