From e89e5f932c77034038c1fe166d1dfe2151a258f2 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Sat, 7 May 2022 23:54:48 -0400 Subject: [PATCH] rewrite database and damage event, add placeholders --- pom.xml | 10 ++ .../net/tylermurphy/hideAndSeek/Main.java | 5 + .../tylermurphy/hideAndSeek/command/Wins.java | 4 +- .../hideAndSeek/configuration/Config.java | 4 +- .../hideAndSeek/database/Database.java | 8 - .../hideAndSeek/database/PlayerInfo.java | 13 +- .../hideAndSeek/database/PlayerInfoTable.java | 126 ++++++++++----- .../tylermurphy/hideAndSeek/game/Board.java | 36 +++++ .../hideAndSeek/game/EventListener.java | 153 ++++++++---------- .../tylermurphy/hideAndSeek/game/Game.java | 4 +- .../hideAndSeek/util/PAPIExpansion.java | 128 +++++++++++++++ src/main/resources/config.yml | 7 + 12 files changed, 353 insertions(+), 145 deletions(-) create mode 100644 src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java 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 { } } - public PlayerInfo getInfo(UUID uuid){ - String sql = "SELECT * FROM player_info 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"); + 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]; } - statement.setBytes(1, bytes); + 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 hs_data WHERE uuid = ?;"; + try(Connection connection = Database.connect(); PreparedStatement statement = connection.prepareStatement(sql)){ + 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(); - } - } - } catch (Exception e){ - Main.plugin.getLogger().severe("Entity Damage Event Error: " + e.getMessage()); + // 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()); + } + 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