diff --git a/SpigotCore_Main/src/SpigotCore.properties b/SpigotCore_Main/src/SpigotCore.properties index 450de5a..388f441 100644 --- a/SpigotCore_Main/src/SpigotCore.properties +++ b/SpigotCore_Main/src/SpigotCore.properties @@ -42,6 +42,7 @@ SCHEM_SELECTOR_SORTING_UPDATE=Last update SCHEM_SELECTOR_SORTING_DIRECTION=§e{0} §7order SCHEM_SELECTOR_SORTING_ASC=Ascending SCHEM_SELECTOR_SORTING_DSC=Descending +SCHEM_SELECTOR_CLICK_BACK=§7Click to go back SCHEM_SELECTOR_ITEM_NAME=§e{0} SCHEM_SELECTOR_ITEM_NAME_FILTER=§7{0} diff --git a/SpigotCore_Main/src/SpigotCore_de.properties b/SpigotCore_Main/src/SpigotCore_de.properties index b5e089a..1279d36 100644 --- a/SpigotCore_Main/src/SpigotCore_de.properties +++ b/SpigotCore_Main/src/SpigotCore_de.properties @@ -42,6 +42,7 @@ SCHEM_SELECTOR_SORTING_UPDATE=Letztes Update SCHEM_SELECTOR_SORTING_DIRECTION=§7Richtung: §e{0} SCHEM_SELECTOR_SORTING_ASC=Aufsteigend SCHEM_SELECTOR_SORTING_DSC=Absteigend +SCHEM_SELECTOR_CLICK_BACK=§7Klicke hier, um zurückzugehen SCHEM_SELECTOR_CREATE_DIR_TITLE=Ordner erstellen diff --git a/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore_Main/src/de/steamwar/core/Core.java index fe320b8..bbd8644 100644 --- a/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -135,8 +135,13 @@ public class Core extends JavaPlugin{ @Override public void onDisable() { TinyProtocol.instance.close(); - crashDetector.stop(); errorHandler.unregister(); - Statement.closeAll(); + if(crashDetector.onMainThread()) + Statement.closeAll(); + } + + private static void setSqlConfig() { + sqlConfig = new File(System.getProperty("user.home"), "MySQL.yml"); + standalone = !sqlConfig.exists(); } } diff --git a/SpigotCore_Main/src/de/steamwar/core/CrashDetector.java b/SpigotCore_Main/src/de/steamwar/core/CrashDetector.java index 1320c2c..b4f612e 100644 --- a/SpigotCore_Main/src/de/steamwar/core/CrashDetector.java +++ b/SpigotCore_Main/src/de/steamwar/core/CrashDetector.java @@ -20,6 +20,7 @@ package de.steamwar.core; import de.steamwar.sql.SWException; +import de.steamwar.sql.Statement; import org.bukkit.Bukkit; import java.util.Arrays; @@ -47,7 +48,12 @@ public class CrashDetector { watchdog.interrupt(); } + public boolean onMainThread() { + return Thread.currentThread() == mainThread; + } + private void run() { + SWException.init(); while (run) { long curTime = System.currentTimeMillis(); if(curTime - TIMEOUT > lastTick.get()) { @@ -58,6 +64,7 @@ public class CrashDetector { if(Core.getInstance().isEnabled()) { Core.getInstance().onDisable(); } + Statement.close(); //System.exit(0); Does freeze, potential freezing issues: ConsoleRestoreHook, ApplicationShutdownHooks or DeleteOnExitHook Runtime.getRuntime().halt(0); } diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SWActionBar.java b/SpigotCore_Main/src/de/steamwar/inventory/SWActionBar.java deleted file mode 100644 index c824347..0000000 --- a/SpigotCore_Main/src/de/steamwar/inventory/SWActionBar.java +++ /dev/null @@ -1,31 +0,0 @@ -package de.steamwar.inventory; - -public class SWActionBar { - - public enum Slot { - ZERO(0), - ONE(1), - TWO(2), - THREE(3), - FOUR(4), - FIVE(5), - SIX(6); - - private int index; - - Slot(int index) { - this.index = index; - } - - int getIndex() { - return index; - } - } - - SWItem[] actionBar = new SWItem[7]; - - public void setItem(Slot slot, SWItem item) { - actionBar[slot.getIndex()] = item; - } - -} diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SWActionListInv.java b/SpigotCore_Main/src/de/steamwar/inventory/SWActionListInv.java deleted file mode 100644 index 68ef71c..0000000 --- a/SpigotCore_Main/src/de/steamwar/inventory/SWActionListInv.java +++ /dev/null @@ -1,73 +0,0 @@ -package de.steamwar.inventory; - -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; - -import java.util.List; - -public class SWActionListInv extends SWInventory { - - private SWListInv.ListCallback callback; - private List> elements; - private SWActionBar actionBar = null; - private int page; - - public SWActionListInv(Player p, String t, List> l, SWListInv.ListCallback c){ - super(p, 54, t); - callback = c; - elements = l; - page = 0; - } - - public void setActionBar(SWActionBar actionBar) { - this.actionBar = actionBar; - } - - @Override - public void open(){ - inventory.clear(); - setCallback(-999, (ClickType click) -> player.closeInventory()); - if (page != 0) { - setItem(0, SWItem.getDye(10), (byte) 10, "§eSeite zurück", (ClickType click) -> { - page--; - open(); - }); - } else { - setItem(0, SWItem.getDye(8), (byte) 8, "§7Seite zurück", (ClickType click) -> {}); - } - if (page < elements.size() / 45) { - setItem(8, SWItem.getDye(10), (byte) 10, "§eSeite vor", (ClickType click) -> { - page++; - open(); - }); - } else { - setItem(8, SWItem.getDye(8), (byte) 8, "§7Seite vor", (ClickType click) -> {}); - } - - if (actionBar != null) { - for (int i = 0; i < 7; i++) { - setItem(i + 1, actionBar.actionBar[i]); - } - } - - int ipageLimit = elements.size() - page*45; - if(ipageLimit > 45 && elements.size() > 45){ - ipageLimit = 45; - } - int i = page*45; - for(int ipage=0; ipage < ipageLimit; ipage++ ){ - SWItem e = elements.get(i).getItem(); - - final int pos = i; - setItem(ipage + 9, e); - setCallback(ipage, (ClickType click) -> callback.clicked(click, elements.get(pos).getObject())); - i++; - } - super.open(); - } - - public void setCallback(SWListInv.ListCallback c){ - callback = c; - } - -} diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SWAnvilInv.java b/SpigotCore_Main/src/de/steamwar/inventory/SWAnvilInv.java index 8244390..733fae9 100644 --- a/SpigotCore_Main/src/de/steamwar/inventory/SWAnvilInv.java +++ b/SpigotCore_Main/src/de/steamwar/inventory/SWAnvilInv.java @@ -66,6 +66,10 @@ public class SWAnvilInv { this.callback = callback; } + public void addLeftCallback(Runnable callback) { + builder.onLeftInputClick(p -> callback.run()); + } + public void addCloseCallback(Runnable callback) { builder.onClose(p -> callback.run()); } diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java b/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java index 9116443..28c92fc 100644 --- a/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java +++ b/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java @@ -28,6 +28,7 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import java.util.*; +import java.util.stream.Collectors; public class SWListInv extends SWInventory { @@ -55,8 +56,10 @@ public class SWListInv extends SWInventory { public void open(){ opened = true; inventory.clear(); - callbacks.clear(); - setCallback(-999, (ClickType click) -> player.closeInventory()); + callbacks.keySet().stream().filter(i -> i >= 0).collect(Collectors.toList()).forEach(callbacks::remove); + if(!callbacks.containsKey(-999)) { + setCallback(-999, (ClickType click) -> player.closeInventory()); + } if (sizeBiggerMax()) { if (page != 0) { diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java index c530544..ef9cf7f 100644 --- a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java +++ b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java @@ -25,11 +25,13 @@ import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicType; import de.steamwar.sql.SteamwarUser; import lombok.*; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.Player; import java.text.MessageFormat; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; public class SchematicSelector { @@ -249,9 +251,23 @@ public class SchematicSelector { return new SWListInv.SWListEntry<>(item, node); } + private void addLeftCloseAction(SWAnvilInv inv, Runnable runnable) { + AtomicBoolean wasLeft = new AtomicBoolean(false); + inv.addCloseCallback(() -> { + if(injectable.onAnvilInvCloseAction(this) == SchematicSelectorInjectable.AnvilInvCloseAction.REOPEN && !wasLeft.get()) { + player.closeInventory(); + Bukkit.getScheduler().runTaskLater(Core.getInstance(), runnable, 1); + } + }); + inv.addLeftCallback(() -> { + wasLeft.set(true); + runnable.run(); + }); + } + private void createFolderIn(SchematicNode parent) { SWAnvilInv inv = new SWAnvilInv(player, Core.MESSAGE.parse("SCHEM_SELECTOR_CREATE_DIR_TITLE", player)); - inv.setItem(Material.CHEST); + inv.setItem(Material.CHEST, Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_CLICK_BACK", player)), false); inv.setCallback(s -> { if(!SchematicNode.invalidSchemName(new String[] {s})) { if(injectable.onFolderCreate(this, s)) { @@ -262,6 +278,7 @@ public class SchematicSelector { } player.closeInventory(); }); + addLeftCloseAction(inv, this::reOpen); inv.open(); } @@ -273,11 +290,12 @@ public class SchematicSelector { openFilter(); } else { SWAnvilInv swAnvilInv = new SWAnvilInv(player, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_ENTER_NAME", player)); - swAnvilInv.setItem(Material.NAME_TAG); + swAnvilInv.setItem(Material.NAME_TAG, Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_CLICK_BACK", player)), false); swAnvilInv.setCallback(s -> { filter.setName(s); openFilter(); }); + addLeftCloseAction(swAnvilInv, this::openFilter); swAnvilInv.open(); } }; @@ -293,13 +311,14 @@ public class SchematicSelector { openFilter(); } else { SWAnvilInv swAnvilInv = new SWAnvilInv(player, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_ENTER_OWNER", player)); - swAnvilInv.setItem(SWItem.getMaterial("SKULL_ITEM"), (byte) 3); + swAnvilInv.setItem(SWItem.getMaterial("SKULL_ITEM"), (byte) 3, Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_CLICK_BACK", player)), false); swAnvilInv.setCallback(s -> { if(SteamwarUser.get(s) != null) { filter.setOwner(SteamwarUser.get(s).getId()); } openFilter(); }); + addLeftCloseAction(swAnvilInv, this::openFilter); swAnvilInv.open(); } }; @@ -387,7 +406,7 @@ public class SchematicSelector { nodes.removeIf(node -> !node.isDir()); } if(target.target == Target.SCHEMATIC_TYPE) { - nodes.removeIf(node -> node.isDir() || !node.getSchemtype().equals(target.type)); + nodes.removeIf(node -> node.isDir() || !node.getSchemtype().equals(target.type) || node.getRank() > target.rank); } return nodes; } diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java index 29bd658..235dda4 100644 --- a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java +++ b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java @@ -45,8 +45,15 @@ public interface SchematicSelectorInjectable { default void onSelectorOpen(SchematicSelector selector, OpenFrom from) {} + default AnvilInvCloseAction onAnvilInvCloseAction(SchematicSelector selector) {return AnvilInvCloseAction.CLOSE;} + enum OpenFrom { FRESH, REOPEN } + + enum AnvilInvCloseAction { + CLOSE, + REOPEN + } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/Replay.java b/SpigotCore_Main/src/de/steamwar/sql/Replay.java new file mode 100644 index 0000000..c3bc96f --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/sql/Replay.java @@ -0,0 +1,65 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.sql; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.sql.SQLException; + +@AllArgsConstructor +public class Replay { + + private static final Statement get = new Statement("SELECT Replay FROM Replay WHERE FightID = ?"); + private static final Statement insert = new Statement("INSERT INTO Replay (FightID, Replay) VALUES (?, ?)"); + + public static Replay get(int fightID) { + return get.select(rs -> { + rs.next(); + + File file; + try { + file = File.createTempFile("replay", "replay"); + file.deleteOnExit(); + Files.copy(rs.getBinaryStream("Replay"), file.toPath()); + } catch (IOException e) { + throw new SQLException(e); + } + return new Replay(fightID, file); + }, fightID); + } + + public static void save(int fightID, File file) { + try { + insert.update(fightID, new FileInputStream(file)); + } catch (FileNotFoundException e) { + throw new SecurityException("Could not save replay", e); + } + } + + private final int fightID; + @Getter + private final File replay; +} \ No newline at end of file diff --git a/SpigotCore_Main/src/de/steamwar/sql/SWException.java b/SpigotCore_Main/src/de/steamwar/sql/SWException.java new file mode 100644 index 0000000..c370744 --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/sql/SWException.java @@ -0,0 +1,51 @@ +/* + This file is a part of the SteamWar software. + + Copyright (C) 2020 SteamWar.de-Serverteam + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package de.steamwar.sql; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.io.File; + +public class SWException { + private SWException(){} + + private static final String serverVersion = Bukkit.getServer().getVersion(); + private static final String cwd = System.getProperty("user.dir"); + private static final String server = new File(cwd).getName(); + + public static void init() { + //force class loading + } + + public static void log(String message, String stacktrace){ + StringBuilder msgBuilder = new StringBuilder(message).append("\nPlayers: "); + for(Player player : Bukkit.getOnlinePlayers()) + msgBuilder.append(player.getName()).append(" "); + msgBuilder.append("\nWorlds: "); + for(World world : Bukkit.getWorlds()) + msgBuilder.append(world.getName()).append(" "); + msgBuilder.append("\nServer: ").append(serverVersion); + msgBuilder.append("\nCWD: ").append(cwd); + + Provider.impl.logException(server, msgBuilder.toString(), stacktrace); + } +}