From 40aacaae3307e42bf4e7bff98ed41b867c5d6ce3 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 28 Aug 2021 10:11:07 +0200 Subject: [PATCH 1/7] General replay starter Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/BungeeCore.java | 1 + .../steamwar/bungeecore/SubserverSystem.java | 8 +- .../bungeecore/commands/ChallengeCommand.java | 2 +- .../bungeecore/commands/FightCommand.java | 2 +- .../bungeecore/commands/HistoricCommand.java | 2 +- .../bungeecore/commands/RankedCommand.java | 2 +- .../bungeecore/commands/ReplayCommand.java | 51 +++++++ .../bungeecore/inventory/SWStreamInv.java | 51 +++++++ src/de/steamwar/bungeecore/sql/Fight.java | 126 ++++++++++++++++++ .../steamwar/bungeecore/sql/FightPlayer.java | 55 ++++++++ .../steamwar/bungeecore/sql/SteamwarUser.java | 23 +++- 11 files changed, 309 insertions(+), 14 deletions(-) create mode 100644 src/de/steamwar/bungeecore/commands/ReplayCommand.java create mode 100644 src/de/steamwar/bungeecore/inventory/SWStreamInv.java create mode 100644 src/de/steamwar/bungeecore/sql/Fight.java create mode 100644 src/de/steamwar/bungeecore/sql/FightPlayer.java diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index f2bd01f1..5d78dc15 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -128,6 +128,7 @@ public class BungeeCore extends Plugin { new ListCommand(); new StatCommand(); new VerifyCommand(); + new ReplayCommand(); if(!EVENT_MODE){ new WebregisterCommand(); diff --git a/src/de/steamwar/bungeecore/SubserverSystem.java b/src/de/steamwar/bungeecore/SubserverSystem.java index d5e85b03..714fbc5e 100644 --- a/src/de/steamwar/bungeecore/SubserverSystem.java +++ b/src/de/steamwar/bungeecore/SubserverSystem.java @@ -66,6 +66,7 @@ public class SubserverSystem { * For a test arena: -1 * For an event arena: EventFightID of the fight * + * @param replayID * @param serverName * The name of the server (for event and test arenas) * or null (autogenerated arena name modus.getDisplayName() + number) @@ -89,7 +90,7 @@ public class SubserverSystem { * @return * The new started subserver. */ - public static synchronized Subserver startArena(ArenaMode modus, String map, int eventFightID, int checkSchemID, int prepareSchemID, String serverName, String mapName, UUID player1, UUID player2, boolean ranked){ + public static synchronized Subserver startArena(ArenaMode modus, String map, int eventFightID, int checkSchemID, int prepareSchemID, int replayID, String serverName, String mapName, UUID player1, UUID player2, boolean ranked){ //Generate missing parameters int port = freePort(FIRST_ARENA_PORT); @@ -132,6 +133,7 @@ public class SubserverSystem { "ranked=" + ranked, "checkSchemID=" + checkSchemID, "prepareSchemID=" + prepareSchemID, + "replay=" + replayID, player1 != null && eventFightID != -1 ? "blueLeader=" + player1 : null, player2 != null ? "redLeader=" + player2 : null); @@ -168,7 +170,7 @@ public class SubserverSystem { eventFight.getFightID(), 0, 0, - serverName, + 0, serverName, serverName.replace(' ', '_') + eventFight.getStartTime().toLocalDateTime().format(DateTimeFormatter.ISO_TIME), null, null, @@ -176,7 +178,7 @@ public class SubserverSystem { } public static void startTestServer(ProxiedPlayer p, ArenaMode m, String map, int checkSchemId, int prepareSchemId){ - startArena(m, map, -1, checkSchemId, prepareSchemId, p.getName() + "s Bau", p.getName(), p.getUniqueId(), null, false).sendPlayer(p); + startArena(m, map, -1, checkSchemId, prepareSchemId, 0, p.getName() + "s Bau", p.getName(), p.getUniqueId(), null, false).sendPlayer(p); } private static synchronized void sendToBau(ProxiedPlayer p, UUID owner, String prototype, String worldFolder, String serverJar, String worldDir, String worldName, String xmx, String serverName){ diff --git a/src/de/steamwar/bungeecore/commands/ChallengeCommand.java b/src/de/steamwar/bungeecore/commands/ChallengeCommand.java index 3d4150d3..a059c8d5 100644 --- a/src/de/steamwar/bungeecore/commands/ChallengeCommand.java +++ b/src/de/steamwar/bungeecore/commands/ChallengeCommand.java @@ -75,7 +75,7 @@ public class ChallengeCommand extends BasicCommand { challenges.remove(target); challenges.remove(player); - Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, null, null, player.getUniqueId(), target.getUniqueId(), false); + Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), target.getUniqueId(), false); arena.sendPlayer(player); arena.sendPlayer(target); diff --git a/src/de/steamwar/bungeecore/commands/FightCommand.java b/src/de/steamwar/bungeecore/commands/FightCommand.java index 984bc06b..65eea1c6 100644 --- a/src/de/steamwar/bungeecore/commands/FightCommand.java +++ b/src/de/steamwar/bungeecore/commands/FightCommand.java @@ -164,7 +164,7 @@ public class FightCommand extends BasicCommand { @Override public void execute(CommandSender sender, String[] args) { createArena(sender, "/fight ", args, 0, false, (player, mode, map) -> { - Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, null, null, player.getUniqueId(), null, false); + Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null, false); arena.sendPlayer(player); Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER" , new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), mode.getDisplayName(), player.getName()); diff --git a/src/de/steamwar/bungeecore/commands/HistoricCommand.java b/src/de/steamwar/bungeecore/commands/HistoricCommand.java index ebf93123..b7d8e4e1 100644 --- a/src/de/steamwar/bungeecore/commands/HistoricCommand.java +++ b/src/de/steamwar/bungeecore/commands/HistoricCommand.java @@ -33,7 +33,7 @@ public class HistoricCommand extends BasicCommand { @Override public void execute(CommandSender sender, String[] args) { FightCommand.createArena(sender, "/historic ", args, 0, true, (player, mode, map) -> { - Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, null, null, player.getUniqueId(), null, false); + Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null, false); arena.sendPlayer(player); Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER" , new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), mode.getDisplayName(), player.getName()); diff --git a/src/de/steamwar/bungeecore/commands/RankedCommand.java b/src/de/steamwar/bungeecore/commands/RankedCommand.java index 1a978b55..a1666cbe 100644 --- a/src/de/steamwar/bungeecore/commands/RankedCommand.java +++ b/src/de/steamwar/bungeecore/commands/RankedCommand.java @@ -165,7 +165,7 @@ public class RankedCommand extends BasicCommand { removeFromAll(wp1.player); removeFromAll(wp2.player); - Subserver arena = SubserverSystem.startArena(mode, mode.getRandomMap(), 0, 0, 0, null, null, wp1.player.getUniqueId(), wp2.player.getUniqueId(), true); + Subserver arena = SubserverSystem.startArena(mode, mode.getRandomMap(), 0, 0, 0, 0, null, null, wp1.player.getUniqueId(), wp2.player.getUniqueId(), true); arena.sendPlayer(wp1.player); arena.sendPlayer(wp2.player); diff --git a/src/de/steamwar/bungeecore/commands/ReplayCommand.java b/src/de/steamwar/bungeecore/commands/ReplayCommand.java new file mode 100644 index 00000000..71d92806 --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/ReplayCommand.java @@ -0,0 +1,51 @@ +package de.steamwar.bungeecore.commands; + +import de.steamwar.bungeecore.ArenaMode; +import de.steamwar.bungeecore.SubserverSystem; +import de.steamwar.bungeecore.inventory.SWItem; +import de.steamwar.bungeecore.inventory.SWListInv; +import de.steamwar.bungeecore.inventory.SWStreamInv; +import de.steamwar.bungeecore.sql.Fight; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public class ReplayCommand extends BasicCommand { + + public ReplayCommand() { + super("replay", null); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(!(sender instanceof ProxiedPlayer)) + return; + + //TODO Translate + ProxiedPlayer player = (ProxiedPlayer) sender; + new SWStreamInv<>(player, "Letzte Kämpfe", (click, fight) -> { + ArenaMode mode = fight.getGameMode(); + if(mode == null){ + player.sendMessage("Replay kann aufgrund deaktivertem Spielmodus nicht gestartet werden"); + return; + } + + SubserverSystem.startArena(mode, mode.getRandomMap(), 0, 0, 0, fight.getFightID(), null, null, null, null, false).sendPlayer(player); + }, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(player, fight), fight)).collect(Collectors.toList())).open(); + } + + private SWItem getFightItem(ProxiedPlayer player, Fight fight) { + String title = "§3" + (fight.getWin() == 1 ? "§l" : "") + fight.getBlueLeader().getUserName() + " §r§8vs §c" + (fight.getWin() == 2 ? "§l" : "") + fight.getRedLeader().getUserName(); + SWItem item = new SWItem("JUKEBOX", title); + item.setLore(Arrays.asList( + "§7" + fight.getStartTime().toString(), + "§7" + fight.getServer(), + "§7" + fight.getWinCondition() + " §8nach §e" + fight.getDuration() + "§8s", + fight.getBluePlayers().size() > 1 ? "§3+" + (fight.getBluePlayers().size() - 1) + " §8Spieler" : "", + fight.getRedPlayers().size() > 1 ? "§c+" + (fight.getRedPlayers().size() - 1) + " §8Spieler" : "" + )); + return item; + } +} diff --git a/src/de/steamwar/bungeecore/inventory/SWStreamInv.java b/src/de/steamwar/bungeecore/inventory/SWStreamInv.java new file mode 100644 index 00000000..ef41dcb3 --- /dev/null +++ b/src/de/steamwar/bungeecore/inventory/SWStreamInv.java @@ -0,0 +1,51 @@ +package de.steamwar.bungeecore.inventory; + +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.List; +import java.util.function.Function; + +public class SWStreamInv extends SWInventory { + private final SWListInv.ListCallback callback; + private final Function>> constructor; + private int page; + + public SWStreamInv(ProxiedPlayer proxiedPlayer, String title, SWListInv.ListCallback callback, Function>> constructor) { + super(proxiedPlayer, 54, title); + this.callback = callback; + this.constructor = constructor; + page = 0; + } + + @Override + public void open(){ + List> entries = constructor.apply(page); + + if(page != 0) + addItem(45, new SWItem("§eSeite zurück", 10), (InvCallback.ClickType click) -> { + page--; + open(); + }); + else + addItem(45, new SWItem("§7Seite zurück", 8), (InvCallback.ClickType click) -> {}); + + if(entries.size() < 45) + addItem(53, new SWItem("§eSeite vor", 10), (InvCallback.ClickType click) -> { + page++; + open(); + }); + else + addItem(53, new SWItem("§eSeite vor", 8), (InvCallback.ClickType click) -> {}); + + for(int i = 0; i < entries.size(); i++) { + SWListInv.SWListEntry item = entries.get(i); + addItem(i, item.getItem()); + setCallback(i, (InvCallback.ClickType click) -> { + close(); + callback.clicked(click, item.getObject()); + }); + } + + super.open(); + } +} diff --git a/src/de/steamwar/bungeecore/sql/Fight.java b/src/de/steamwar/bungeecore/sql/Fight.java new file mode 100644 index 00000000..08c24e60 --- /dev/null +++ b/src/de/steamwar/bungeecore/sql/Fight.java @@ -0,0 +1,126 @@ +package de.steamwar.bungeecore.sql; + +import de.steamwar.bungeecore.ArenaMode; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class Fight { + + private final int fightID; + private final String gameMode; + private final String server; + private final Timestamp startTime; + private final int duration; + + private final int blueLeader; + private final int redLeader; + private final int blueSchem; + private final int redSchem; + private final int win; + private final String winCondition; + + private final List bluePlayers = new ArrayList<>(); + private final List redPlayers = new ArrayList<>(); + + private Fight(ResultSet rs) throws SQLException { + fightID = rs.getInt("FightID"); + gameMode = rs.getString("GameMode"); + server = rs.getString("Server"); + startTime = rs.getTimestamp("StartTime"); + duration = rs.getInt("Duration"); + blueLeader = rs.getInt("BlueLeader"); + redLeader = rs.getInt("RedLeader"); + blueSchem = rs.getInt("BlueSchem"); + redSchem = rs.getInt("RedSchem"); + win = rs.getInt("Win"); + winCondition = rs.getString("WinCondition"); + } + + private void initPlayers(List fightPlayers) { + for(FightPlayer fp : fightPlayers) { + if(fp.getFightID() != fightID) + continue; + + if(fp.getTeam() == 1) + bluePlayers.add(fp); + else + redPlayers.add(fp); + } + } + + public static List getPage(int page, int elementsPerPage) { + ResultSet rs = SQL.select("SELECT FightID, GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition FROM Fight WHERE Replay is not NULL ORDER BY FightID DESC LIMIT ?, ?", page * elementsPerPage, elementsPerPage); + List fights = new ArrayList<>(); + try { + while(rs.next()){ + fights.add(new Fight(rs)); + } + }catch (SQLException e) { + throw new SecurityException("Could not load Fights", e); + } + + List fightPlayers = FightPlayer.batchGet(fights.stream().map(f -> f.fightID).collect(Collectors.toSet())); + for(Fight fight : fights) { + fight.initPlayers(fightPlayers); + } + + SteamwarUser.batchCache(fightPlayers.stream().map(FightPlayer::getUserID).collect(Collectors.toSet())); + return fights; + } + + public ArenaMode getGameMode() { + SchematicType schemType = SchematicType.fromDB(gameMode); + if(schemType == null) + return null; + return ArenaMode.getBySchemType(schemType); + } + + public String getRawGameMode() { + return gameMode; + } + + public int getFightID() { + return fightID; + } + + public Timestamp getStartTime() { + return startTime; + } + + public int getDuration() { + return duration; + } + + public SteamwarUser getBlueLeader() { + return SteamwarUser.get(blueLeader); + } + + public SteamwarUser getRedLeader() { + return SteamwarUser.get(redLeader); + } + + public int getWin() { + return win; + } + + public String getServer() { + return server; + } + + public String getWinCondition() { + return winCondition; + } + + public List getBluePlayers() { + return bluePlayers; + } + + public List getRedPlayers() { + return redPlayers; + } +} diff --git a/src/de/steamwar/bungeecore/sql/FightPlayer.java b/src/de/steamwar/bungeecore/sql/FightPlayer.java new file mode 100644 index 00000000..760bf815 --- /dev/null +++ b/src/de/steamwar/bungeecore/sql/FightPlayer.java @@ -0,0 +1,55 @@ +package de.steamwar.bungeecore.sql; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class FightPlayer { + + private final int fightID; + private final int userID; + private final int team; + private final String kit; + private final int kills; + private final boolean isOut; + + private FightPlayer(ResultSet rs) throws SQLException { + fightID = rs.getInt("FightID"); + userID = rs.getInt("UserID"); + team = rs.getInt("Team"); + kit = rs.getString("Kit"); + kills = rs.getInt("Kills"); + isOut = rs.getBoolean("IsOut"); + } + + public static List batchGet(Set fightIds) { + List fightPlayers = new ArrayList<>(); + if(fightIds.isEmpty()) + return fightPlayers; + + ResultSet rs = SQL.select("SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); + try { + while(rs.next()){ + fightPlayers.add(new FightPlayer(rs)); + } + }catch (SQLException e) { + throw new SecurityException("Could not load FightPlayers", e); + } + return fightPlayers; + } + + public int getFightID() { + return fightID; + } + + public int getTeam() { + return team; + } + + public int getUserID() { + return userID; + } +} diff --git a/src/de/steamwar/bungeecore/sql/SteamwarUser.java b/src/de/steamwar/bungeecore/sql/SteamwarUser.java index 00fd2218..063adcd0 100644 --- a/src/de/steamwar/bungeecore/sql/SteamwarUser.java +++ b/src/de/steamwar/bungeecore/sql/SteamwarUser.java @@ -24,24 +24,22 @@ import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.commands.WebregisterCommand; import de.steamwar.bungeecore.listeners.ConnectionListener; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Scanner; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.io.IOException; import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URL; import java.net.UnknownHostException; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import java.util.*; +import java.util.stream.Collectors; public class SteamwarUser { @@ -151,6 +149,17 @@ public class SteamwarUser { return dbInit(SQL.select("SELECT * FROM UserData WHERE id = ?", id)); } + public static void batchCache(Set ids) { + ids.removeIf(usersById::containsKey); + + if(!ids.isEmpty()) { + ResultSet rs = SQL.select("SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); + while(dbInit(rs) != null) { + // nothing to do + } + } + } + public static SteamwarUser get(Long discordId) { if(usersByDiscord.containsKey(discordId.toString())) return usersByDiscord.get(discordId.toString()); From 8daedc4e7466d0bd5baada03f4ab1f2e271120e1 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Sat, 11 Sep 2021 09:26:14 +0200 Subject: [PATCH 2/7] Rework to new SQL api Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/BungeeCore.java | 2 +- src/de/steamwar/bungeecore/sql/Fight.java | 14 ++++++------- .../steamwar/bungeecore/sql/FightPlayer.java | 13 ++++++------ src/de/steamwar/bungeecore/sql/Statement.java | 16 +++++++++++--- .../steamwar/bungeecore/sql/SteamwarUser.java | 21 ++++++++++--------- 5 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index 8b5c3f6c..26313b99 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -160,7 +160,7 @@ public class BungeeCore extends Plugin { @Override public void onDisable(){ ErrorLogger.stop(); - Statement.close(); + Statement.closeAll(); try { SteamwarDiscordBot.instance().getJda().shutdownNow(); SteamwarDiscordBot.instance().getJda().awaitStatus(JDA.Status.SHUTDOWN); diff --git a/src/de/steamwar/bungeecore/sql/Fight.java b/src/de/steamwar/bungeecore/sql/Fight.java index 08c24e60..50e16a80 100644 --- a/src/de/steamwar/bungeecore/sql/Fight.java +++ b/src/de/steamwar/bungeecore/sql/Fight.java @@ -11,6 +11,8 @@ import java.util.stream.Collectors; public class Fight { + private static final Statement getPage = new Statement("SELECT FightID, GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition FROM Fight WHERE Replay is not NULL ORDER BY FightID DESC LIMIT ?, ?"); + private final int fightID; private final String gameMode; private final String server; @@ -54,15 +56,13 @@ public class Fight { } public static List getPage(int page, int elementsPerPage) { - ResultSet rs = SQL.select("SELECT FightID, GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition FROM Fight WHERE Replay is not NULL ORDER BY FightID DESC LIMIT ?, ?", page * elementsPerPage, elementsPerPage); - List fights = new ArrayList<>(); - try { + List fights = getPage.select(rs -> { + List f = new ArrayList<>(); while(rs.next()){ - fights.add(new Fight(rs)); + f.add(new Fight(rs)); } - }catch (SQLException e) { - throw new SecurityException("Could not load Fights", e); - } + return f; + }, page * elementsPerPage, elementsPerPage); List fightPlayers = FightPlayer.batchGet(fights.stream().map(f -> f.fightID).collect(Collectors.toSet())); for(Fight fight : fights) { diff --git a/src/de/steamwar/bungeecore/sql/FightPlayer.java b/src/de/steamwar/bungeecore/sql/FightPlayer.java index 760bf815..e2f118dc 100644 --- a/src/de/steamwar/bungeecore/sql/FightPlayer.java +++ b/src/de/steamwar/bungeecore/sql/FightPlayer.java @@ -30,14 +30,13 @@ public class FightPlayer { if(fightIds.isEmpty()) return fightPlayers; - ResultSet rs = SQL.select("SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); - try { - while(rs.next()){ + Statement batch = new Statement("SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); + batch.select(rs -> { + while(rs.next()) fightPlayers.add(new FightPlayer(rs)); - } - }catch (SQLException e) { - throw new SecurityException("Could not load FightPlayers", e); - } + return null; + }); + batch.close(); return fightPlayers; } diff --git a/src/de/steamwar/bungeecore/sql/Statement.java b/src/de/steamwar/bungeecore/sql/Statement.java index eac76505..22c900bb 100644 --- a/src/de/steamwar/bungeecore/sql/Statement.java +++ b/src/de/steamwar/bungeecore/sql/Statement.java @@ -27,7 +27,7 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; -public class Statement { +public class Statement implements AutoCloseable { private static final List statements = new ArrayList<>(); private static Connection con; @@ -49,7 +49,7 @@ public class Statement { private static void reset(SQLException e) { BungeeCore.get().getLogger().log(Level.WARNING, "SQL Exception thrown", e); - close(); + closeAll(); connect(url, user, password); try { for (Statement statement : statements) { @@ -60,7 +60,17 @@ public class Statement { } } - public static void close() { + @Override + public void close() { + try { + st.close(); + } catch (SQLException e) { + BungeeCore.get().getLogger().log(Level.INFO, "Could not close statement", e); + } + statements.remove(this); + } + + public static void closeAll() { for (Statement statement : statements) { try { statement.st.close(); diff --git a/src/de/steamwar/bungeecore/sql/SteamwarUser.java b/src/de/steamwar/bungeecore/sql/SteamwarUser.java index 7de43596..5cef03ff 100644 --- a/src/de/steamwar/bungeecore/sql/SteamwarUser.java +++ b/src/de/steamwar/bungeecore/sql/SteamwarUser.java @@ -37,11 +37,9 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; -import java.util.UUID; +import java.util.*; import java.util.logging.Level; +import java.util.stream.Collectors; public class SteamwarUser { @@ -179,13 +177,16 @@ public class SteamwarUser { public static void batchCache(Set ids) { ids.removeIf(usersById::containsKey); + if(ids.isEmpty()) + return; - if(!ids.isEmpty()) { - ResultSet rs = SQL.select("SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); - while(dbInit(rs) != null) { - // nothing to do - } - } + Statement batch = new Statement("SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); + batch.select(rs -> { + while(rs.next()) + new SteamwarUser(rs); + return null; + }); + batch.close(); } public static SteamwarUser get(Long discordId) { From 39ccff44a529f49641f846bce278f2c64f118508 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 16 Sep 2021 12:43:22 +0200 Subject: [PATCH 3/7] Fix performance and bugs Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/commands/ReplayCommand.java | 6 +++++- src/de/steamwar/bungeecore/inventory/SWStreamInv.java | 4 ++-- src/de/steamwar/bungeecore/sql/Fight.java | 8 +++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/de/steamwar/bungeecore/commands/ReplayCommand.java b/src/de/steamwar/bungeecore/commands/ReplayCommand.java index 71d92806..df013917 100644 --- a/src/de/steamwar/bungeecore/commands/ReplayCommand.java +++ b/src/de/steamwar/bungeecore/commands/ReplayCommand.java @@ -26,6 +26,10 @@ public class ReplayCommand extends BasicCommand { //TODO Translate ProxiedPlayer player = (ProxiedPlayer) sender; new SWStreamInv<>(player, "Letzte Kämpfe", (click, fight) -> { + if(!fight.isReplayAvailable()) { + player.sendMessage("Replay nicht möglich"); + return; + } ArenaMode mode = fight.getGameMode(); if(mode == null){ player.sendMessage("Replay kann aufgrund deaktivertem Spielmodus nicht gestartet werden"); @@ -38,7 +42,7 @@ public class ReplayCommand extends BasicCommand { private SWItem getFightItem(ProxiedPlayer player, Fight fight) { String title = "§3" + (fight.getWin() == 1 ? "§l" : "") + fight.getBlueLeader().getUserName() + " §r§8vs §c" + (fight.getWin() == 2 ? "§l" : "") + fight.getRedLeader().getUserName(); - SWItem item = new SWItem("JUKEBOX", title); + SWItem item = new SWItem(fight.isReplayAvailable() ? "JUKEBOX" : "STONE", title); item.setLore(Arrays.asList( "§7" + fight.getStartTime().toString(), "§7" + fight.getServer(), diff --git a/src/de/steamwar/bungeecore/inventory/SWStreamInv.java b/src/de/steamwar/bungeecore/inventory/SWStreamInv.java index ef41dcb3..1235de0c 100644 --- a/src/de/steamwar/bungeecore/inventory/SWStreamInv.java +++ b/src/de/steamwar/bungeecore/inventory/SWStreamInv.java @@ -29,13 +29,13 @@ public class SWStreamInv extends SWInventory { else addItem(45, new SWItem("§7Seite zurück", 8), (InvCallback.ClickType click) -> {}); - if(entries.size() < 45) + if(entries.size() == 45) addItem(53, new SWItem("§eSeite vor", 10), (InvCallback.ClickType click) -> { page++; open(); }); else - addItem(53, new SWItem("§eSeite vor", 8), (InvCallback.ClickType click) -> {}); + addItem(53, new SWItem("§7Seite vor", 8), (InvCallback.ClickType click) -> {}); for(int i = 0; i < entries.size(); i++) { SWListInv.SWListEntry item = entries.get(i); diff --git a/src/de/steamwar/bungeecore/sql/Fight.java b/src/de/steamwar/bungeecore/sql/Fight.java index 50e16a80..f9172b16 100644 --- a/src/de/steamwar/bungeecore/sql/Fight.java +++ b/src/de/steamwar/bungeecore/sql/Fight.java @@ -11,7 +11,7 @@ import java.util.stream.Collectors; public class Fight { - private static final Statement getPage = new Statement("SELECT FightID, GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition FROM Fight WHERE Replay is not NULL ORDER BY FightID DESC LIMIT ?, ?"); + private static final Statement getPage = new Statement("SELECT FightID, GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition, Replay is not NULL AS ReplayAvailable FROM Fight ORDER BY FightID DESC LIMIT ?, ?"); private final int fightID; private final String gameMode; @@ -25,6 +25,7 @@ public class Fight { private final int redSchem; private final int win; private final String winCondition; + private final boolean replayAvailable; private final List bluePlayers = new ArrayList<>(); private final List redPlayers = new ArrayList<>(); @@ -41,6 +42,7 @@ public class Fight { redSchem = rs.getInt("RedSchem"); win = rs.getInt("Win"); winCondition = rs.getString("WinCondition"); + replayAvailable = rs.getBoolean("ReplayAvailable"); } private void initPlayers(List fightPlayers) { @@ -123,4 +125,8 @@ public class Fight { public List getRedPlayers() { return redPlayers; } + + public boolean isReplayAvailable() { + return replayAvailable; + } } From 27b8fa969fe1efb6cda4efc49adaa90f6da561f3 Mon Sep 17 00:00:00 2001 From: yoyosource Date: Mon, 27 Dec 2021 14:15:21 +0100 Subject: [PATCH 4/7] Update TablistManager --- src/de/steamwar/bungeecore/listeners/TablistManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/steamwar/bungeecore/listeners/TablistManager.java b/src/de/steamwar/bungeecore/listeners/TablistManager.java index 6b5cb345..f1c1c7a7 100644 --- a/src/de/steamwar/bungeecore/listeners/TablistManager.java +++ b/src/de/steamwar/bungeecore/listeners/TablistManager.java @@ -317,7 +317,7 @@ public class TablistManager extends BasicListener { if(slim && !displaySlim(viewer.player, player.player)) continue; - int ping = sameServer ? 1 : 500; + int ping = sameServer ? 1 : 1000; String name = player.defaultName.startsWith("§7") && user.getTeam() != 0 && user.getTeam() == SteamwarUser.get(player.player.getUniqueId()).getTeam() ? "§f" + player.player.getName() : player.defaultName; viewer.setSlot(BungeeTabListPlusAPI.getIconFromPlayer(player.player), name, ping); } From 7730ea29fe8263768f5864c98a5a1d15e2e7fefc Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Mon, 27 Dec 2021 18:14:45 +0100 Subject: [PATCH 5/7] Old Bug, New Fix Signed-off-by: Chaoscaot --- src/de/steamwar/bungeecore/commands/CheckCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/steamwar/bungeecore/commands/CheckCommand.java b/src/de/steamwar/bungeecore/commands/CheckCommand.java index 6334971b..ba662c03 100644 --- a/src/de/steamwar/bungeecore/commands/CheckCommand.java +++ b/src/de/steamwar/bungeecore/commands/CheckCommand.java @@ -69,7 +69,7 @@ public class CheckCommand extends BasicCommand { public static void sendReminder(ProxiedPlayer player) { List schematics = getSchemsToCheck(); if(schematics.size() != currentCheckers.size()) - Message.send("CHECK_REMINDER", player, "CHECK_REMINDER_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size()); + Message.send("CHECK_REMINDER", player, Message.parse("CHECK_REMINDER_HOVER", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size()); } @Override From 7ad4d73674df51e413eabf739b33b26c8ac49534 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Mon, 27 Dec 2021 19:36:51 +0100 Subject: [PATCH 6/7] Nice Replay display Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/Message.java | 4 ++ .../bungeecore/commands/ReplayCommand.java | 45 +++++++++++-------- src/de/steamwar/bungeecore/sql/Fight.java | 26 +++++------ .../bungeecore/sql/SchematicType.java | 16 +++++-- .../steamwar/messages/BungeeCore.properties | 10 +++++ 5 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/de/steamwar/bungeecore/Message.java b/src/de/steamwar/bungeecore/Message.java index a26f0004..b9a6f585 100644 --- a/src/de/steamwar/bungeecore/Message.java +++ b/src/de/steamwar/bungeecore/Message.java @@ -28,7 +28,9 @@ import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.ProxiedPlayer; +import java.text.DateFormat; import java.text.MessageFormat; +import java.util.Date; import java.util.Locale; import java.util.ResourceBundle; @@ -71,6 +73,8 @@ public class Message { if(params[i] instanceof Message) { Message msg = (Message) params[i]; params[i] = parse(msg.getMessage(), sender, msg.getParams()); + } else if(params[i] instanceof Date) { + params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]); } } return format.format(params); diff --git a/src/de/steamwar/bungeecore/commands/ReplayCommand.java b/src/de/steamwar/bungeecore/commands/ReplayCommand.java index df013917..109a8a0f 100644 --- a/src/de/steamwar/bungeecore/commands/ReplayCommand.java +++ b/src/de/steamwar/bungeecore/commands/ReplayCommand.java @@ -1,15 +1,19 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.ArenaMode; +import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.SubserverSystem; import de.steamwar.bungeecore.inventory.SWItem; import de.steamwar.bungeecore.inventory.SWListInv; import de.steamwar.bungeecore.inventory.SWStreamInv; import de.steamwar.bungeecore.sql.Fight; +import de.steamwar.bungeecore.sql.SchematicType; +import de.steamwar.bungeecore.sql.SteamwarUser; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.stream.Collectors; public class ReplayCommand extends BasicCommand { @@ -22,34 +26,39 @@ public class ReplayCommand extends BasicCommand { public void execute(CommandSender sender, String[] args) { if(!(sender instanceof ProxiedPlayer)) return; - - //TODO Translate ProxiedPlayer player = (ProxiedPlayer) sender; - new SWStreamInv<>(player, "Letzte Kämpfe", (click, fight) -> { + + new SWStreamInv<>(player, Message.parse("REPLAY_TITLE", player), (click, fight) -> { if(!fight.isReplayAvailable()) { - player.sendMessage("Replay nicht möglich"); + Message.send("REPLAY_UNAVAILABLE", player); return; } ArenaMode mode = fight.getGameMode(); - if(mode == null){ - player.sendMessage("Replay kann aufgrund deaktivertem Spielmodus nicht gestartet werden"); - return; - } SubserverSystem.startArena(mode, mode.getRandomMap(), 0, 0, 0, fight.getFightID(), null, null, null, null, false).sendPlayer(player); }, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(player, fight), fight)).collect(Collectors.toList())).open(); } private SWItem getFightItem(ProxiedPlayer player, Fight fight) { - String title = "§3" + (fight.getWin() == 1 ? "§l" : "") + fight.getBlueLeader().getUserName() + " §r§8vs §c" + (fight.getWin() == 2 ? "§l" : "") + fight.getRedLeader().getUserName(); - SWItem item = new SWItem(fight.isReplayAvailable() ? "JUKEBOX" : "STONE", title); - item.setLore(Arrays.asList( - "§7" + fight.getStartTime().toString(), - "§7" + fight.getServer(), - "§7" + fight.getWinCondition() + " §8nach §e" + fight.getDuration() + "§8s", - fight.getBluePlayers().size() > 1 ? "§3+" + (fight.getBluePlayers().size() - 1) + " §8Spieler" : "", - fight.getRedPlayers().size() > 1 ? "§c+" + (fight.getRedPlayers().size() - 1) + " §8Spieler" : "" - )); + SchematicType type = fight.getSchemType(); + SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(player, fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1)); + + List lore = new ArrayList<>(); + lore.add(parseLeader(player, fight.getRedLeader(), fight.getRedPlayers().size(), fight.getWin() == 2)); + lore.add(Message.parse("REPLAY_TIME", player, fight.getStartTime())); + lore.add(""); + lore.add(Message.parse("REPLAY_SERVER", player, fight.getServer())); + if(!fight.isReplayAvailable()) + lore.add(Message.parse("REPLAY_UNAVAILABLE", player)); + item.setLore(lore); + + if(fight.isReplayAvailable()) + item.setEnchanted(true); + return item; } + + private String parseLeader(ProxiedPlayer player, SteamwarUser leader, int players, boolean winner) { + return Message.parse(winner ? (players > 1 ? "REPLAY_WINNER" : "REPLAY_SOLO_WINNER") : (players > 1 ? "REPLAY_LOSER" : "REPLAY_SOLO_LOSER"), player, leader.getUserName(), players - 1); + } } diff --git a/src/de/steamwar/bungeecore/sql/Fight.java b/src/de/steamwar/bungeecore/sql/Fight.java index f9172b16..77ceefde 100644 --- a/src/de/steamwar/bungeecore/sql/Fight.java +++ b/src/de/steamwar/bungeecore/sql/Fight.java @@ -5,13 +5,14 @@ import de.steamwar.bungeecore.ArenaMode; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; +import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; public class Fight { - private static final Statement getPage = new Statement("SELECT FightID, GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition, Replay is not NULL AS ReplayAvailable FROM Fight ORDER BY FightID DESC LIMIT ?, ?"); + private static final Statement getPage = new Statement("SELECT FightID, GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition, ReplayLock, Replay is not NULL AS ReplayAvailable FROM Fight ORDER BY FightID DESC LIMIT ?, ?"); private final int fightID; private final String gameMode; @@ -25,6 +26,8 @@ public class Fight { private final int redSchem; private final int win; private final String winCondition; + + private final Timestamp replayLock; private final boolean replayAvailable; private final List bluePlayers = new ArrayList<>(); @@ -42,6 +45,7 @@ public class Fight { redSchem = rs.getInt("RedSchem"); win = rs.getInt("Win"); winCondition = rs.getString("WinCondition"); + replayLock = rs.getTimestamp("ReplayLock"); replayAvailable = rs.getBoolean("ReplayAvailable"); } @@ -75,17 +79,17 @@ public class Fight { return fights; } + public SchematicType getSchemType() { + return SchematicType.fromDB(gameMode); + } + public ArenaMode getGameMode() { - SchematicType schemType = SchematicType.fromDB(gameMode); + SchematicType schemType = getSchemType(); if(schemType == null) return null; return ArenaMode.getBySchemType(schemType); } - public String getRawGameMode() { - return gameMode; - } - public int getFightID() { return fightID; } @@ -94,10 +98,6 @@ public class Fight { return startTime; } - public int getDuration() { - return duration; - } - public SteamwarUser getBlueLeader() { return SteamwarUser.get(blueLeader); } @@ -114,10 +114,6 @@ public class Fight { return server; } - public String getWinCondition() { - return winCondition; - } - public List getBluePlayers() { return bluePlayers; } @@ -127,6 +123,6 @@ public class Fight { } public boolean isReplayAvailable() { - return replayAvailable; + return replayAvailable && replayLock.before(Timestamp.from(Instant.now())) && getGameMode() != null; } } diff --git a/src/de/steamwar/bungeecore/sql/SchematicType.java b/src/de/steamwar/bungeecore/sql/SchematicType.java index 54290d8f..978ab94a 100644 --- a/src/de/steamwar/bungeecore/sql/SchematicType.java +++ b/src/de/steamwar/bungeecore/sql/SchematicType.java @@ -30,7 +30,7 @@ import java.io.IOException; import java.util.*; public class SchematicType { - public static final SchematicType Normal = new SchematicType("Normal", "", Type.NORMAL, null); //Has to stay publicly availible + public static final SchematicType Normal = new SchematicType("Normal", "", null, Type.NORMAL, null); //Has to stay publicly availible private static final Map fromDB; private static final Map fightType; @@ -64,15 +64,17 @@ public class SchematicType { if(tmpFromDB.containsKey(type.toLowerCase())) continue; + String material = config.getString("Schematic.Material"); + SchematicType checktype = null; if(!config.getStringList("CheckQuestions").isEmpty()) { - checktype = new SchematicType("C" + type, "C" + shortcut, Type.CHECK_TYPE, null); + checktype = new SchematicType("C" + type, "C" + shortcut, material, Type.CHECK_TYPE, null); tmpTypes.add(checktype); tmpFromDB.put(checktype.toDB(), checktype); CheckCommand.setCheckQuestions(checktype, config); } - SchematicType current = new SchematicType(type, shortcut, config.getKeys().contains("Server") ? Type.FIGHT_TYPE : Type.NORMAL, checktype); + SchematicType current = new SchematicType(type, shortcut, material, config.getKeys().contains("Server") ? Type.FIGHT_TYPE : Type.NORMAL, checktype); if(checktype != null) tmpFightType.put(checktype, current); tmpFromDB.put(type.toLowerCase(), current); @@ -86,12 +88,14 @@ public class SchematicType { private final String name; private final String kuerzel; + private final String material; private final Type type; private final SchematicType checkType; - private SchematicType(String name, String kuerzel, Type type, SchematicType checkType){ + private SchematicType(String name, String kuerzel, String material, Type type, SchematicType checkType){ this.name = name; this.kuerzel = kuerzel; + this.material = material != null && !"".equals(material) ? material : "STONE_BUTTON"; this.type = type; this.checkType = checkType; } @@ -124,6 +128,10 @@ public class SchematicType { return name; } + public String getMaterial() { + return material; + } + public String getKuerzel() { return kuerzel; } diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index 9e232f9d..dbd1fb63 100644 --- a/src/de/steamwar/messages/BungeeCore.properties +++ b/src/de/steamwar/messages/BungeeCore.properties @@ -337,6 +337,16 @@ REGELN_WS=§eWarShip§8-§7Regelwerk REGELN_WS_HOVER=§7https://steamwar.de/spielmodi/warship-regelwerk/ REGELN_WS_URL=https://steamwar.de/spielmodi/warship-regelwerk/ +#ReplayCommand +REPLAY_TITLE=Letzte Kämpfe +REPLAY_UNAVAILABLE=§cReplay nicht möglich +REPLAY_SOLO_WINNER=§e§l{0} +REPLAY_WINNER=§e§l{0} §7+§e{1} +REPLAY_SOLO_LOSER=§e{0} +REPLAY_LOSER=§e{0} §7+§e{1} +REPLAY_TIME=§7{0} +REPLAY_SERVER=§7{0} + #ServerTeamchatCommand STC_USAGE=§8/§7stc §8[§eNachricht an das Team§8] STC_FORMAT=§8STC §e{0}» §r{1} From 35c16b1faeb0a5c5c8222e142b0fc57edab19c44 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Tue, 28 Dec 2021 16:16:16 +0100 Subject: [PATCH 7/7] Try with resources Signed-off-by: Lixfel --- src/de/steamwar/bungeecore/sql/FightPlayer.java | 14 +++++++------- src/de/steamwar/bungeecore/sql/SteamwarUser.java | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/de/steamwar/bungeecore/sql/FightPlayer.java b/src/de/steamwar/bungeecore/sql/FightPlayer.java index e2f118dc..a4e11926 100644 --- a/src/de/steamwar/bungeecore/sql/FightPlayer.java +++ b/src/de/steamwar/bungeecore/sql/FightPlayer.java @@ -30,13 +30,13 @@ public class FightPlayer { if(fightIds.isEmpty()) return fightPlayers; - Statement batch = new Statement("SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); - batch.select(rs -> { - while(rs.next()) - fightPlayers.add(new FightPlayer(rs)); - return null; - }); - batch.close(); + try (Statement batch = new Statement("SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")")) { + batch.select(rs -> { + while(rs.next()) + fightPlayers.add(new FightPlayer(rs)); + return null; + }); + } return fightPlayers; } diff --git a/src/de/steamwar/bungeecore/sql/SteamwarUser.java b/src/de/steamwar/bungeecore/sql/SteamwarUser.java index f52ce579..86d5d023 100644 --- a/src/de/steamwar/bungeecore/sql/SteamwarUser.java +++ b/src/de/steamwar/bungeecore/sql/SteamwarUser.java @@ -193,13 +193,13 @@ public class SteamwarUser { if(ids.isEmpty()) return; - Statement batch = new Statement("SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")"); - batch.select(rs -> { - while(rs.next()) - new SteamwarUser(rs); - return null; - }); - batch.close(); + try (Statement batch = new Statement("SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")")) { + batch.select(rs -> { + while (rs.next()) + new SteamwarUser(rs); + return null; + }); + } } public static SteamwarUser get(Long discordId) {