diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index fdc019e4..abdf3308 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(); new GDPRQuery(); new PlaytimeCommand(); @@ -181,7 +182,7 @@ public class BungeeCore extends Plugin { } errorLogger.unregister(); - Statement.close(); + Statement.closeAll(); } public static BungeeCore get() { 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/SubserverSystem.java b/src/de/steamwar/bungeecore/SubserverSystem.java index 6b34d8ce..ef55b3c7 100644 --- a/src/de/steamwar/bungeecore/SubserverSystem.java +++ b/src/de/steamwar/bungeecore/SubserverSystem.java @@ -59,6 +59,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) @@ -82,7 +83,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 Node node = eventFightID > 0 ? Node.local : Node.getNode(); int port = arenaPorts.freePort(); @@ -113,6 +114,7 @@ public class SubserverSystem { "logPath=" + mapName, "config=" + modus.getConfig(), "fightID=" + eventFightID, "ranked=" + ranked, "checkSchemID=" + checkSchemID, "prepareSchemID=" + prepareSchemID, + "replay=" + replayID, player1 != null && eventFightID != -1 ? "blueLeader=" + player1 : null, player2 != null ? "redLeader=" + player2 : null ); @@ -139,7 +141,7 @@ public class SubserverSystem { eventFight.getFightID(), 0, 0, - serverName, + 0, serverName, serverName + eventFight.getStartTime().toLocalDateTime().format(DateTimeFormatter.ISO_TIME), null, null, @@ -147,7 +149,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 1025eea2..ae34de97 100644 --- a/src/de/steamwar/bungeecore/commands/ChallengeCommand.java +++ b/src/de/steamwar/bungeecore/commands/ChallengeCommand.java @@ -76,7 +76,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/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 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 0ddfef22..6d1f936e 100644 --- a/src/de/steamwar/bungeecore/commands/HistoricCommand.java +++ b/src/de/steamwar/bungeecore/commands/HistoricCommand.java @@ -36,7 +36,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 f1649cb4..a9d87771 100644 --- a/src/de/steamwar/bungeecore/commands/RankedCommand.java +++ b/src/de/steamwar/bungeecore/commands/RankedCommand.java @@ -168,7 +168,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..109a8a0f --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/ReplayCommand.java @@ -0,0 +1,64 @@ +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.ArrayList; +import java.util.List; +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; + ProxiedPlayer player = (ProxiedPlayer) sender; + + new SWStreamInv<>(player, Message.parse("REPLAY_TITLE", player), (click, fight) -> { + if(!fight.isReplayAvailable()) { + Message.send("REPLAY_UNAVAILABLE", player); + return; + } + ArenaMode mode = fight.getGameMode(); + + 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) { + 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/inventory/SWStreamInv.java b/src/de/steamwar/bungeecore/inventory/SWStreamInv.java new file mode 100644 index 00000000..1235de0c --- /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("§7Seite 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/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); } diff --git a/src/de/steamwar/bungeecore/sql/Fight.java b/src/de/steamwar/bungeecore/sql/Fight.java new file mode 100644 index 00000000..77ceefde --- /dev/null +++ b/src/de/steamwar/bungeecore/sql/Fight.java @@ -0,0 +1,128 @@ +package de.steamwar.bungeecore.sql; + +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, ReplayLock, Replay is not NULL AS ReplayAvailable FROM Fight ORDER BY FightID DESC LIMIT ?, ?"); + + 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 Timestamp replayLock; + private final boolean replayAvailable; + + 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"); + replayLock = rs.getTimestamp("ReplayLock"); + replayAvailable = rs.getBoolean("ReplayAvailable"); + } + + 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) { + List fights = getPage.select(rs -> { + List f = new ArrayList<>(); + while(rs.next()){ + f.add(new Fight(rs)); + } + return f; + }, page * elementsPerPage, elementsPerPage); + + 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 SchematicType getSchemType() { + return SchematicType.fromDB(gameMode); + } + + public ArenaMode getGameMode() { + SchematicType schemType = getSchemType(); + if(schemType == null) + return null; + return ArenaMode.getBySchemType(schemType); + } + + public int getFightID() { + return fightID; + } + + public Timestamp getStartTime() { + return startTime; + } + + 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 List getBluePlayers() { + return bluePlayers; + } + + public List getRedPlayers() { + return redPlayers; + } + + public boolean isReplayAvailable() { + return replayAvailable && replayLock.before(Timestamp.from(Instant.now())) && getGameMode() != null; + } +} diff --git a/src/de/steamwar/bungeecore/sql/FightPlayer.java b/src/de/steamwar/bungeecore/sql/FightPlayer.java new file mode 100644 index 00000000..a4e11926 --- /dev/null +++ b/src/de/steamwar/bungeecore/sql/FightPlayer.java @@ -0,0 +1,54 @@ +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; + + 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; + } + + public int getFightID() { + return fightID; + } + + public int getTeam() { + return team; + } + + public int getUserID() { + return userID; + } +} 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/bungeecore/sql/Statement.java b/src/de/steamwar/bungeecore/sql/Statement.java index 9889a7a4..1bd849f1 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; @@ -48,7 +48,7 @@ public class Statement { } private static void reset() { - close(); + closeAll(); connect(url, user, password); try { for (Statement statement : statements) { @@ -59,7 +59,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() { synchronized (statements) { for (Statement statement : statements) { try { diff --git a/src/de/steamwar/bungeecore/sql/SteamwarUser.java b/src/de/steamwar/bungeecore/sql/SteamwarUser.java index ea73ffd6..86d5d023 100644 --- a/src/de/steamwar/bungeecore/sql/SteamwarUser.java +++ b/src/de/steamwar/bungeecore/sql/SteamwarUser.java @@ -39,6 +39,7 @@ import java.sql.Timestamp; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.logging.Level; +import java.util.stream.Collectors; public class SteamwarUser { @@ -187,6 +188,20 @@ public class SteamwarUser { }, id); } + public static void batchCache(Set ids) { + ids.removeIf(usersById::containsKey); + if(ids.isEmpty()) + return; + + 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) { if(usersByDiscord.containsKey(discordId)) return usersByDiscord.get(discordId); diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index 77a720ab..436827d5 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}