diff --git a/SpigotCore_14/src/de/steamwar/core/FlatteningWrapper14.java b/SpigotCore_14/src/de/steamwar/core/FlatteningWrapper14.java index 2092669..b903db6 100644 --- a/SpigotCore_14/src/de/steamwar/core/FlatteningWrapper14.java +++ b/SpigotCore_14/src/de/steamwar/core/FlatteningWrapper14.java @@ -20,7 +20,6 @@ package de.steamwar.core; import com.comphenix.tinyprotocol.Reflection; -import de.steamwar.scoreboard.SWScoreboard; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; @@ -222,7 +221,7 @@ public class FlatteningWrapper14 implements FlatteningWrapper.IFlatteningWrapper renamedLegacy.put("RECORD_12", Material.MUSIC_DISC_WAIT); } - private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(SWScoreboard.scoreboardObjective, Reflection.getClass("{nms.network.chat}.IChatBaseComponent"), 0); + private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(FlatteningWrapper.scoreboardObjective, Reflection.getClass("{nms.network.chat}.IChatBaseComponent"), 0); private static final Reflection.ConstructorInvoker chatComponentConstructor = Reflection.getConstructor(Reflection.getClass("{nms.network.chat}.ChatComponentText"), String.class); @Override @@ -231,7 +230,7 @@ public class FlatteningWrapper14 implements FlatteningWrapper.IFlatteningWrapper } private static final Class scoreActionEnum = Reflection.getClass("{nms.server}.ScoreboardServer$Action"); - private static final Reflection.FieldAccessor scoreAction = Reflection.getField(SWScoreboard.scoreboardScore, scoreActionEnum, 0); + private static final Reflection.FieldAccessor scoreAction = Reflection.getField(FlatteningWrapper.scoreboardScore, scoreActionEnum, 0); private static final Object scoreActionChange = scoreActionEnum.getEnumConstants()[0]; @Override diff --git a/SpigotCore_18/build.gradle b/SpigotCore_18/build.gradle index c6185e9..5181c28 100644 --- a/SpigotCore_18/build.gradle +++ b/SpigotCore_18/build.gradle @@ -44,6 +44,9 @@ sourceSets { dependencies { implementation project(":SpigotCore_Main") + implementation project(":SpigotCore_14") + + compileOnly files("${project.rootDir}/lib/WorldEdit-1.15.jar") compileOnly 'org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT' compileOnly files("${project.rootDir}/lib/Spigot-1.18.jar") diff --git a/SpigotCore_18/src/de/steamwar/core/WorldEditWrapper18.java b/SpigotCore_18/src/de/steamwar/core/WorldEditWrapper18.java new file mode 100644 index 0000000..a3a12fc --- /dev/null +++ b/SpigotCore_18/src/de/steamwar/core/WorldEditWrapper18.java @@ -0,0 +1,46 @@ +/* + * 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.core; + +import com.sk89q.jnbt.NBTInputStream; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader; +import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader; +import de.steamwar.sql.NoClipboardException; + +import java.io.IOException; +import java.io.InputStream; + +public class WorldEditWrapper18 extends WorldEditWrapper14 { + + @Override + public Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException { + //Use FAWE reader due to FAWE capability of reading corrupt FAWE schems + try { + if(schemFormat){ + return new SpongeSchematicReader(new NBTInputStream(is)).read(); + }else{ + return new MCEditSchematicReader(new NBTInputStream(is)).read(); + } + } catch (NullPointerException e) { + throw new NoClipboardException(); + } + } +} diff --git a/SpigotCore_8/src/de/steamwar/core/FlatteningWrapper8.java b/SpigotCore_8/src/de/steamwar/core/FlatteningWrapper8.java index 371c799..feb679e 100644 --- a/SpigotCore_8/src/de/steamwar/core/FlatteningWrapper8.java +++ b/SpigotCore_8/src/de/steamwar/core/FlatteningWrapper8.java @@ -20,16 +20,15 @@ package de.steamwar.core; import com.comphenix.tinyprotocol.Reflection; -import de.steamwar.scoreboard.SWScoreboard; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.SkullMeta; public class FlatteningWrapper8 implements FlatteningWrapper.IFlatteningWrapper { - private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(SWScoreboard.scoreboardObjective, String.class, 1); + private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(FlatteningWrapper.scoreboardObjective, String.class, 1); private static final Class scoreActionEnum = Reflection.getClass("{nms}.PacketPlayOutScoreboardScore$EnumScoreboardAction"); - private static final Reflection.FieldAccessor scoreAction = Reflection.getField(SWScoreboard.scoreboardScore, scoreActionEnum, 0); + private static final Reflection.FieldAccessor scoreAction = Reflection.getField(FlatteningWrapper.scoreboardScore, scoreActionEnum, 0); private static final Object scoreActionChange = scoreActionEnum.getEnumConstants()[0]; @Override diff --git a/SpigotCore_Main/src/SpigotCore.properties b/SpigotCore_Main/src/SpigotCore.properties index acb3749..8a7692d 100644 --- a/SpigotCore_Main/src/SpigotCore.properties +++ b/SpigotCore_Main/src/SpigotCore.properties @@ -17,6 +17,11 @@ # along with this program. If not, see . # +SWLISINV_NEXT_PAGE_ACTIVE = §eSeite vor +SWLISINV_NEXT_PAGE_INACTIVE = §7Seite vor +SWLISINV_PREVIOUS_PAGE_ACTIVE = §eSeite zurück +SWLISINV_PREVIOUS_PAGE_INACTIVE = §7Seite zurück + SCHEM_SELECTOR_TITLE={0} auswählen: {1} SCHEM_SELECTOR_BACK=§eZurück SCHEM_SELECTOR_DIR=§9Ordner diff --git a/SpigotCore_Main/src/com/comphenix/tinyprotocol/Reflection.java b/SpigotCore_Main/src/com/comphenix/tinyprotocol/Reflection.java index 1742df4..f1138fc 100644 --- a/SpigotCore_Main/src/com/comphenix/tinyprotocol/Reflection.java +++ b/SpigotCore_Main/src/com/comphenix/tinyprotocol/Reflection.java @@ -1,6 +1,7 @@ package com.comphenix.tinyprotocol; import de.steamwar.core.Core; +import jdk.internal.misc.Unsafe; import org.bukkit.Bukkit; import java.lang.reflect.Constructor; @@ -367,7 +368,11 @@ public final class Reflection { @SuppressWarnings("deprecation") public static Object newInstance(Class clazz) { try { - return clazz.newInstance(); + if (Core.getVersion() > 15) { + return Unsafe.getUnsafe().allocateInstance(clazz); + } else { + return clazz.newInstance(); + } } catch (InstantiationException | IllegalAccessException e) { throw new SecurityException("Could not create object", e); } diff --git a/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java b/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java index 658262f..2b0ba73 100644 --- a/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java +++ b/SpigotCore_Main/src/com/comphenix/tinyprotocol/TinyProtocol.java @@ -274,6 +274,9 @@ public class TinyProtocol { // Inject our packet interceptor if (interceptor == null) { interceptor = new PacketInterceptor(); + if(!channel.isActive()) + return interceptor; + channel.pipeline().addBefore("packet_handler", handlerName, interceptor); uninjectedChannels.remove(channel); } diff --git a/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java b/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java index 3e18811..3af5b37 100644 --- a/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java +++ b/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java @@ -162,41 +162,26 @@ public class SWCommandUtils { return createMapper(staticValue.value()); } if (staticValue.allowISE()) { - if (parameter.getType() == boolean.class && staticValue.value().length == 2) { + if ((parameter.getType() == boolean.class || parameter.getType() == Boolean.class) && staticValue.value().length == 2) { List tabCompletes = new ArrayList<>(Arrays.asList(staticValue.value())); - return new TypeMapper() { - @Override - public Boolean map(CommandSender commandSender, String[] previousArguments, String s) { - int index = tabCompletes.indexOf(s); - if (index == -1) { - return null; - } - return index != 0; - } - - @Override - public List tabCompletes(CommandSender commandSender, String[] previousArguments, String s) { - return tabCompletes; - } - }; + return createMapper(s -> { + int index = tabCompletes.indexOf(s); + return index == -1 ? null : index != 0; + }, (commandSender, s) -> tabCompletes); } - if (parameter.getType() == int.class && staticValue.value().length >= 2) { + if ((parameter.getType() == int.class || parameter.getType() == Integer.class) && staticValue.value().length >= 2) { List tabCompletes = new ArrayList<>(Arrays.asList(staticValue.value())); - return new TypeMapper() { - @Override - public Integer map(CommandSender commandSender, String[] previousArguments, String s) { - int index = tabCompletes.indexOf(s); - if (index == -1) { - return null; - } - return index; - } - - @Override - public List tabCompletes(CommandSender commandSender, String[] previousArguments, String s) { - return tabCompletes; - } - }; + return createMapper(s -> { + int index = tabCompletes.indexOf(s); + return index == -1 ? null : index; + }, (commandSender, s) -> tabCompletes); + } + if ((parameter.getType() == long.class || parameter.getType() == Long.class) && staticValue.value().length >= 2) { + List tabCompletes = new ArrayList<>(Arrays.asList(staticValue.value())); + return createMapper(s -> { + long index = tabCompletes.indexOf(s); + return index == -1 ? null : index; + }, (commandSender, s) -> tabCompletes); } } } diff --git a/SpigotCore_Main/src/de/steamwar/comms/packets/PrepareSchemPacket.java b/SpigotCore_Main/src/de/steamwar/comms/packets/PrepareSchemPacket.java index 8c0968d..aba2380 100644 --- a/SpigotCore_Main/src/de/steamwar/comms/packets/PrepareSchemPacket.java +++ b/SpigotCore_Main/src/de/steamwar/comms/packets/PrepareSchemPacket.java @@ -21,7 +21,6 @@ package de.steamwar.comms.packets; import com.google.common.io.ByteArrayDataOutput; import de.steamwar.comms.PacketIdManager; -import de.steamwar.sql.Schematic; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicType; import de.steamwar.sql.SteamwarUser; @@ -38,13 +37,6 @@ public class PrepareSchemPacket extends SpigotPacket{ this.schematicType = schematicType; } - @Deprecated - public PrepareSchemPacket(SteamwarUser user, Schematic schematic, SchematicType schematicType) { - this.user = user; - this.schematic = schematic.getNode(); - this.schematicType = schematicType; - } - @Override public int getName() { return PacketIdManager.PREPARE_SCHEM; diff --git a/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore_Main/src/de/steamwar/core/Core.java index 5cb4e64..1ef9272 100644 --- a/SpigotCore_Main/src/de/steamwar/core/Core.java +++ b/SpigotCore_Main/src/de/steamwar/core/Core.java @@ -26,11 +26,12 @@ import de.steamwar.core.events.ChattingEvent; import de.steamwar.core.events.PlayerJoinedEvent; import de.steamwar.core.events.WorldLoadEvent; import de.steamwar.message.Message; -import de.steamwar.sql.SQL; +import de.steamwar.sql.Statement; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import java.io.BufferedReader; +import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.util.logging.Level; @@ -38,11 +39,9 @@ import java.util.logging.Level; public class Core extends JavaPlugin{ + public static final Message MESSAGE = new Message("SpigotCore", Core.class.getClassLoader()); + private static final int VERSION; - public static final Message MESSAGE; - - private static Core instance; - static{ String packageName = Bukkit.getServer().getClass().getPackage().getName(); if(packageName.contains("1_18")) @@ -61,8 +60,27 @@ public class Core extends JavaPlugin{ VERSION = 8; else VERSION = 18; + } + public static int getVersion(){ + return VERSION; + } - MESSAGE = new Message("SpigotCore", Core.class.getClassLoader()); + private static JavaPlugin instance; + public static JavaPlugin getInstance() { + return instance; + } + public static void setInstance(JavaPlugin instance) { + Core.instance = instance; + } + + private static boolean standalone = true; + public static boolean standalone() { + return standalone; + } + + private static File sqlConfig; + public static File sqlConfig() { + return sqlConfig; } private ErrorHandler errorHandler; @@ -74,6 +92,7 @@ public class Core extends JavaPlugin{ @Override public void onEnable() { + setSqlConfig(); errorHandler = new ErrorHandler(); Bukkit.getPluginManager().registerEvents(new PlayerJoinedEvent(), this); @@ -84,7 +103,7 @@ public class Core extends JavaPlugin{ AuthlibInjector.inject(); TinyProtocol.init(); try { - Bukkit.getLogger().log(Level.INFO, "Running on: " + new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec("hostname").getInputStream())).readLine()); + getLogger().log(Level.INFO, "Running on: " + new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec("hostname").getInputStream())).readLine()); } catch (IOException e) { throw new SecurityException("Could not load Hostname", e); } @@ -94,18 +113,13 @@ public class Core extends JavaPlugin{ public void onDisable() { TinyProtocol.instance.close(); errorHandler.unregister(); - SQL.close(); + if(!standalone) { + Statement.close(); + } } - public static Core getInstance() { - return instance; - } - - public static int getVersion(){ - return VERSION; - } - - private static void setInstance(Core instance) { - Core.instance = instance; + private static void setSqlConfig() { + sqlConfig = new File(Core.getInstance().getDataFolder(), "MySQL.yml"); + standalone = !sqlConfig.exists(); } } diff --git a/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java b/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java index 8981490..2b49104 100644 --- a/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java +++ b/SpigotCore_Main/src/de/steamwar/core/ErrorHandler.java @@ -19,8 +19,8 @@ package de.steamwar.core; -import de.steamwar.sql.SQL; import de.steamwar.sql.SWException; +import de.steamwar.sql.Statement; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -83,7 +83,7 @@ public class ErrorHandler extends Handler { if(stacktrace.contains("POI data mismatch")) return; - if(!SQL.connectionStable()) + if(!Statement.connectionStable()) return; SWException.log(message, stacktrace); diff --git a/SpigotCore_Main/src/de/steamwar/core/FlatteningWrapper.java b/SpigotCore_Main/src/de/steamwar/core/FlatteningWrapper.java index ca673c0..9da4b20 100644 --- a/SpigotCore_Main/src/de/steamwar/core/FlatteningWrapper.java +++ b/SpigotCore_Main/src/de/steamwar/core/FlatteningWrapper.java @@ -19,12 +19,16 @@ package de.steamwar.core; +import com.comphenix.tinyprotocol.Reflection; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; public class FlatteningWrapper { private FlatteningWrapper() {} + public static final Class scoreboardObjective = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutScoreboardObjective"); + public static final Class scoreboardScore = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutScoreboardScore"); + public static final IFlatteningWrapper impl = VersionDependent.getVersionImpl(Core.getInstance()); public interface IFlatteningWrapper { diff --git a/SpigotCore_Main/src/de/steamwar/core/VersionedCallable.java b/SpigotCore_Main/src/de/steamwar/core/VersionedCallable.java deleted file mode 100644 index 0da1b6f..0000000 --- a/SpigotCore_Main/src/de/steamwar/core/VersionedCallable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * 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.core; - -import java.util.concurrent.Callable; - -public class VersionedCallable { - - private Callable callable; - private int minVersion; - - public VersionedCallable(Callable callable, int minVersion) { - this.callable = callable; - this.minVersion = minVersion; - } - - @Deprecated - public static T call(VersionedCallable... versionedCallables) { - for (int i = versionedCallables.length - 1; i >= 0; i--) { - VersionedCallable versionedCallable = versionedCallables[i]; - if (Core.getVersion() >= versionedCallable.minVersion) { - try { - return versionedCallable.callable.call(); - } catch (Exception e) { - throw new RuntimeException("Could not run version dependent code", e); - } - } - } - throw new SecurityException(); - } - -} diff --git a/SpigotCore_Main/src/de/steamwar/core/VersionedRunnable.java b/SpigotCore_Main/src/de/steamwar/core/VersionedRunnable.java deleted file mode 100644 index 604169a..0000000 --- a/SpigotCore_Main/src/de/steamwar/core/VersionedRunnable.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * - * 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.core; - -public class VersionedRunnable { - - private Runnable runnable; - private int minVersion; - - public VersionedRunnable(Runnable runnable, int minVersion) { - this.runnable = runnable; - this.minVersion = minVersion; - } - - @Deprecated - public static void call(VersionedRunnable... versionedRunnables) { - for (int i = versionedRunnables.length - 1; i >= 0; i--) { - VersionedRunnable versionedRunnable = versionedRunnables[i]; - if (Core.getVersion() >= versionedRunnable.minVersion) { - versionedRunnable.runnable.run(); - return; - } - } - } - -} diff --git a/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java b/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java index 0b860ee..269f426 100644 --- a/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java +++ b/SpigotCore_Main/src/de/steamwar/core/WorldEditWrapper.java @@ -17,10 +17,9 @@ public class WorldEditWrapper { InputStream getPlayerClipboard(Player player, boolean schemFormat); void setPlayerClipboard(Player player, InputStream is, boolean schemFormat); Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException; - } - static WorldEditPlugin getWorldEditPlugin() { + public static WorldEditPlugin getWorldEditPlugin() { return (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"); } } diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java b/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java index d0d9c22..9116443 100644 --- a/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java +++ b/SpigotCore_Main/src/de/steamwar/inventory/SWListInv.java @@ -19,7 +19,7 @@ package de.steamwar.inventory; -import de.steamwar.sql.Schematic; +import de.steamwar.core.Core; import de.steamwar.sql.SchematicNode; import de.steamwar.sql.SchematicType; import org.bukkit.Bukkit; @@ -28,7 +28,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import java.util.*; -import java.util.stream.Collectors; public class SWListInv extends SWInventory { @@ -59,29 +58,33 @@ public class SWListInv extends SWInventory { callbacks.clear(); setCallback(-999, (ClickType click) -> player.closeInventory()); - if(sizeBiggerMax()){ - if(page != 0) - setItem(45, SWItem.getDye(10), (byte)10, "§eSeite zurück", (ClickType click) -> { + if (sizeBiggerMax()) { + if (page != 0) { + setItem(45, SWItem.getDye(10), (byte) 10, Core.MESSAGE.parse("SWLISINV_PREVIOUS_PAGE_ACTIVE", player), (ClickType click) -> { page--; open(); }); - else - setItem(45, SWItem.getDye(8), (byte)8, "§7Seite zurück", (ClickType click) -> {}); - if(page < elements.size()/45) - setItem(53, SWItem.getDye(10), (byte)10, "§eSeite vor", (ClickType click) -> { + } else { + setItem(45, SWItem.getDye(8), (byte) 8, Core.MESSAGE.parse("SWLISINV_PREVIOUS_PAGE_INACTIVE", player), (ClickType click) -> { + }); + } + if (page < elements.size() / 45 - (elements.size() % 45 == 0 ? 1 : 0)) { + setItem(53, SWItem.getDye(10), (byte) 10, Core.MESSAGE.parse("SWLISINV_NEXT_PAGE_ACTIVE", player), (ClickType click) -> { page++; open(); }); - else - setItem(53, SWItem.getDye(8), (byte)8, "§7Seite vor", (ClickType click) -> {}); + } else { + setItem(53, SWItem.getDye(8), (byte) 8, Core.MESSAGE.parse("SWLISINV_NEXT_PAGE_INACTIVE", player), (ClickType click) -> { + }); + } } - int ipageLimit = elements.size() - page*45; - if(ipageLimit > 45 && sizeBiggerMax()){ + int ipageLimit = elements.size() - page * 45; + if (ipageLimit > 45 && sizeBiggerMax()) { ipageLimit = 45; } - int i = page*45; - for(int ipage=0; ipage < ipageLimit; ipage++ ){ + int i = page * 45; + for (int ipage = 0; ipage < ipageLimit; ipage++) { SWItem e = elements.get(i).getItem(); final int pos = i; @@ -90,8 +93,9 @@ public class SWListInv extends SWInventory { i++; } - for(Map.Entry customItem : customItems.entrySet()) + for (Map.Entry customItem : customItems.entrySet()) { setItem(customItem.getKey(), customItem.getValue()); + } super.open(); } @@ -138,11 +142,6 @@ public class SWListInv extends SWInventory { } return schemList; } - - @Deprecated - public static List> getSchemList(SchematicType type, int steamwarUserId){ - return getSchemnodeList(type, steamwarUserId).stream().map(schematicNodeSWListEntry -> new SWListEntry(schematicNodeSWListEntry.getItem(), Schematic.wrap(schematicNodeSWListEntry.getObject()))).collect(Collectors.toList()); - } private boolean sizeBiggerMax(){ return dynamicSize ? elements.size() > 54 : elements.size() > 45; diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java index a007562..7676de2 100644 --- a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java +++ b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelector.java @@ -41,7 +41,8 @@ public class SchematicSelector { @Getter private SteamwarUser user; @Getter - private final Consumer callback; + @Setter + private Consumer callback; private final SelectorTarget target; @Getter private final SelectorFilter filter = new SelectorFilter(); @@ -58,6 +59,8 @@ public class SchematicSelector { private int depth = 0; private Sorting sorting = Sorting.NAME; private boolean invertSorting = false; + @Getter + private SchematicNode lastParent; public SchematicSelector(Player player, SelectorTarget target, Consumer callback) { this.player = player; @@ -78,9 +81,22 @@ public class SchematicSelector { this.user = SteamwarUser.get(0); } openList(null); + injectable.onSelectorOpen(this, SchematicSelectorInjectable.OpenFrom.FRESH); + } + + public void reOpen() { + openList(lastParent); + injectable.onSelectorOpen(this, SchematicSelectorInjectable.OpenFrom.REOPEN); + } + + public void reOpenDirUp() { + depth--; + openList(dirUp(lastParent)); + injectable.onSelectorOpen(this, SchematicSelectorInjectable.OpenFrom.REOPEN); } private void openList(SchematicNode parent) { + lastParent = parent; List nodes = applySorting(filter.isFilter()?getFilteredSchematics():getSchematicList(parent)); if(sdoTrigger) { @@ -140,34 +156,38 @@ public class SchematicSelector { inv.open(); } + private SchematicNode dirUp(SchematicNode parent) { + if(!singleDirOpen) { + if(NodeMember.getNodeMember(parent.getId(), user.getId()) != null) { + return null; + } else { + return getParent(parent); + } + } else { + SchematicNode currentParent = parent; + boolean isMember = false; + do { + sdoTrigger = false; + if(NodeMember.getNodeMember(currentParent.getId(), user.getId()) != null) { + isMember = true; + } + currentParent = getParent(currentParent); + if(currentParent == null) + break; + getSchematicList(currentParent); + } while (sdoTrigger); + if(isMember || NodeMember.getNodeMember(parent.getId(), user.getId()) != null) { + return null; + } else { + return currentParent; + } + } + } + private void handleClick(SchematicNode node, SchematicNode parent) { if(node == null) { depth--; - if(!singleDirOpen) { - if(NodeMember.getNodeMember(parent.getId(), user.getId()) != null) { - openList(null); - } else { - openList(getParent(parent)); - } - } else { - SchematicNode currentParent = parent; - boolean isMember = false; - do { - sdoTrigger = false; - if(NodeMember.getNodeMember(currentParent.getId(), user.getId()) != null) { - isMember = true; - } - currentParent = getParent(currentParent); - if(currentParent == null) - break; - getSchematicList(currentParent); - } while (sdoTrigger); - if(isMember || NodeMember.getNodeMember(parent.getId(), user.getId()) != null) { - openList(null); - } else { - openList(currentParent); - } - } + openList(dirUp(parent)); return; } if(node.isDir()) { diff --git a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java index 7c4d718..29bd658 100644 --- a/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java +++ b/SpigotCore_Main/src/de/steamwar/inventory/SchematicSelectorInjectable.java @@ -42,4 +42,11 @@ public interface SchematicSelectorInjectable { default boolean onFolderCreate(SchematicSelector selector, String name) {return true;} default void onNodeFilter(SchematicSelector selector, SchematicNode node) {} + + default void onSelectorOpen(SchematicSelector selector, OpenFrom from) {} + + enum OpenFrom { + FRESH, + REOPEN + } } diff --git a/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java b/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java index 9cde7bc..440e29a 100644 --- a/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java +++ b/SpigotCore_Main/src/de/steamwar/scoreboard/SWScoreboard.java @@ -32,17 +32,15 @@ import java.util.Map; public class SWScoreboard { private SWScoreboard() {} - public static final Class scoreboardObjective = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutScoreboardObjective"); - private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(scoreboardObjective, String.class, 0); - private static final Reflection.FieldAccessor scoreboardAction = Reflection.getField(scoreboardObjective, int.class, 0); + private static final Reflection.FieldAccessor scoreboardName = Reflection.getField(FlatteningWrapper.scoreboardObjective, String.class, 0); + private static final Reflection.FieldAccessor scoreboardAction = Reflection.getField(FlatteningWrapper.scoreboardObjective, int.class, Core.getVersion() > 15 ? 3 : 0); private static final Class scoreboardDisplayEnum = Reflection.getClass("{nms.world.scores.criteria}.IScoreboardCriteria$EnumScoreboardHealthDisplay"); - private static final Reflection.FieldAccessor scoreboardDisplayType = Reflection.getField(scoreboardObjective, scoreboardDisplayEnum, 0); + private static final Reflection.FieldAccessor scoreboardDisplayType = Reflection.getField(FlatteningWrapper.scoreboardObjective, scoreboardDisplayEnum, 0); private static final Object displayTypeIntegers = scoreboardDisplayEnum.getEnumConstants()[0]; - public static final Class scoreboardScore = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutScoreboardScore"); - private static final Reflection.FieldAccessor scoreName = Reflection.getField(scoreboardScore, String.class, 0); - private static final Reflection.FieldAccessor scoreScoreboardName = Reflection.getField(scoreboardScore, String.class, 1); - private static final Reflection.FieldAccessor scoreValue = Reflection.getField(scoreboardScore, int.class, 0); + private static final Reflection.FieldAccessor scoreName = Reflection.getField(FlatteningWrapper.scoreboardScore, String.class, 0); + private static final Reflection.FieldAccessor scoreScoreboardName = Reflection.getField(FlatteningWrapper.scoreboardScore, String.class, 1); + private static final Reflection.FieldAccessor scoreValue = Reflection.getField(FlatteningWrapper.scoreboardScore, int.class, 0); private static final HashMap playerBoards = new HashMap<>(); //Object -> Scoreboard | Alle Versionen in der Map! private static int toggle = 0; // Scoreboard 0 updates while scoreboard 1 is presenting. toggle marks the current active scoreboard @@ -56,7 +54,7 @@ public class SWScoreboard { Reflection.FieldAccessor scoreboardDisplayName = Reflection.getField(scoreboardDisplayObjective, String.class, 0); Reflection.FieldAccessor scoreboardDisplaySlot = Reflection.getField(scoreboardDisplayObjective, int.class, 0); for(int id = 0; id < 2; id++) { - DELETE_SCOREBOARD[id] = Reflection.newInstance(scoreboardObjective); + DELETE_SCOREBOARD[id] = Reflection.newInstance(FlatteningWrapper.scoreboardObjective); scoreboardName.set(DELETE_SCOREBOARD[id], SIDEBAR + id); scoreboardAction.set(DELETE_SCOREBOARD[id], 1); //1 to remove @@ -100,7 +98,7 @@ public class SWScoreboard { } private static Object createSidebarPacket(String name){ - Object packet = Reflection.newInstance(scoreboardObjective); + Object packet = Reflection.newInstance(FlatteningWrapper.scoreboardObjective); scoreboardName.set(packet, SIDEBAR + toggle); scoreboardAction.set(packet, 0); //0 to create FlatteningWrapper.impl.setScoreboardTitle(packet, name); @@ -109,7 +107,7 @@ public class SWScoreboard { } private static Object createScorePacket(String name, int value){ - Object packet = Reflection.newInstance(scoreboardScore); + Object packet = Reflection.newInstance(FlatteningWrapper.scoreboardScore); scoreName.set(packet, name); scoreScoreboardName.set(packet, SIDEBAR + toggle); scoreValue.set(packet, value); diff --git a/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java b/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java index 273f1ce..564b916 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java +++ b/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java @@ -23,50 +23,11 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -public class BauweltMember{ - - private static final SQL.Statement getMember = new SQL.Statement("SELECT * FROM BauweltMember WHERE BauweltID = ? AND MemberID = ?"); - private static final SQL.Statement getMembers = new SQL.Statement("SELECT * FROM BauweltMember WHERE BauweltID = ?"); - - private final int bauweltID; - private final int memberID; - private boolean worldEdit; - private boolean world; - - private static final List members = new ArrayList<>(); +public class BauweltMember { + private static final List memberCache = new ArrayList<>(); public static void clear() { - members.clear(); - } - - private BauweltMember(int ownerID, int memberID, boolean worldEdit, boolean world, boolean updateDB){ - bauweltID = ownerID; - this.memberID = memberID; - this.worldEdit = worldEdit; - this.world = world; - if(updateDB) - updateDB(); - members.add(this); - } - - public BauweltMember(int ownerID, int memberID, boolean worldEdit, boolean world){ - this(ownerID, memberID, worldEdit, world, true); - } - - public BauweltMember(UUID ownerID, UUID memberID, boolean worldEdit, boolean world){ - this(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId(), worldEdit, world, true); - } - - @Deprecated - public void remove(){ - SQL.update("DELETE FROM BauweltMember WHERE BauweltID = ? AND MemberID = ?", bauweltID, memberID); - members.remove(this); - } - - @Deprecated - private void updateDB(){ - SQL.update("INSERT INTO BauweltMember (BauweltID, MemberID, WorldEdit, World) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE WorldEdit = VALUES(WorldEdit), World = VALUES(World)", - bauweltID, memberID, worldEdit, world); + memberCache.clear(); } public static BauweltMember getBauMember(UUID ownerID, UUID memberID){ @@ -74,14 +35,10 @@ public class BauweltMember{ } public static BauweltMember getBauMember(int ownerID, int memberID){ - for(BauweltMember member : members) - if(member.memberID == memberID) + for(BauweltMember member : memberCache) + if(member.getMemberID() == memberID) return member; - return getMember.select(rs -> { - if(!rs.next()) - return null; - return new BauweltMember(ownerID, memberID, rs.getBoolean("WorldEdit"), rs.getBoolean("World"), false); - }, ownerID, memberID); + return Provider.impl.getBauMember(ownerID, memberID); } public static List getMembers(UUID bauweltID){ @@ -89,12 +46,20 @@ public class BauweltMember{ } public static List getMembers(int bauweltID){ - return getMembers.select(rs -> { - List members = new ArrayList<>(); - while(rs.next()) - members.add(new BauweltMember(bauweltID, rs.getInt("MemberID"), rs.getBoolean("WorldEdit"), rs.getBoolean("World"), false)); - return members; - }, bauweltID); + return Provider.impl.getMembers(bauweltID); + } + + private final int bauweltID; + private final int memberID; + private final boolean worldEdit; + private final boolean world; + + public BauweltMember(int bauweltID, int memberID, boolean worldEdit, boolean world) { + this.bauweltID = bauweltID; + this.memberID = memberID; + this.worldEdit = worldEdit; + this.world = world; + memberCache.add(this); } public int getBauweltID() { @@ -109,19 +74,7 @@ public class BauweltMember{ return worldEdit; } - @Deprecated - public void setWorldEdit(boolean worldEdit) { - this.worldEdit = worldEdit; - updateDB(); - } - public boolean isWorld() { return world; } - - @Deprecated - public void setWorld(boolean world) { - this.world = world; - updateDB(); - } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/CheckedSchematic.java b/SpigotCore_Main/src/de/steamwar/sql/CheckedSchematic.java index 0411239..3c19e4e 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/CheckedSchematic.java +++ b/SpigotCore_Main/src/de/steamwar/sql/CheckedSchematic.java @@ -20,75 +20,17 @@ package de.steamwar.sql; import java.sql.Timestamp; -import java.util.ArrayList; import java.util.List; import java.util.UUID; public class CheckedSchematic { - private static final SQL.Statement checkHistory = new SQL.Statement("SELECT * FROM CheckedSchematic WHERE NodeId IN (SELECT NodeId FROM SchematicNode WHERE NodeOwner = ?) AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' AND NodeId is not NULL ORDER BY EndTime DESC"); - private static final SQL.Statement nodeHistory = new SQL.Statement("SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC"); - private static final SQL.Statement insert = new SQL.Statement("INSERT INTO CheckedSchematic (NodeId, NodeName, NodeOwner, Validator, StartTime, EndTime, DeclineReason) VALUES (?, ?, ?, ?, ?, ?, ?)"); - private static final SQL.Statement setNodeNull = new SQL.Statement("UPDATE CheckedSchematic SET NodeId = NULL WHERE NodeId = ?"); - - private final Integer node; - private final int validator; - private final Timestamp startTime; - private final Timestamp endTime; - private final String declineReason; - - private CheckedSchematic(int node, int validator, Timestamp startTime, Timestamp endTime, String declineReason, boolean insertDB){ - this.node = node; - this.validator = validator; - this.startTime = startTime; - this.endTime = endTime; - this.declineReason = declineReason; - if(insertDB) { - insertDB(); - } - } - - @Deprecated - public CheckedSchematic(String schemName, int schemOwner, int validator, Timestamp startTime, Timestamp endTime, String declineReason){ - this(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), validator, startTime, endTime, declineReason, true); - } - - @Deprecated - public CheckedSchematic(String schemName, UUID schemOwner, UUID validator, Timestamp startTime, Timestamp endTime, String declineReason){ - this(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), SteamwarUser.get(validator).getId(), startTime, endTime, declineReason, true); - } - - public CheckedSchematic(int node, int validator, Timestamp startTime, Timestamp endTime, String declineReason){ - this(node, validator, startTime, endTime, declineReason, true); - } - - public CheckedSchematic(int node, UUID validator, Timestamp startTime, Timestamp endTime, String declineReason){ - this(node, SteamwarUser.get(validator).getId(), startTime, endTime, declineReason, true); - } - - private void insertDB() { - SchematicNode sNode = SchematicNode.getSchematicNode(node); - String nodeName = sNode.getName(); - int nodeOwner = sNode.getOwner(); - insert.update(node, nodeName, nodeOwner, validator, startTime, endTime, declineReason); - } - public static List getLastDeclinedOfNode(SchematicNode node){ return getLastDeclinedOfNode(node.getId()); } public static List getLastDeclinedOfNode(int node){ - return nodeHistory.select(rs -> { - List lastDeclined = new ArrayList<>(); - while(rs.next()){ - int validator = rs.getInt("Validator"); - Timestamp startTime = rs.getTimestamp("StartTime"); - Timestamp endTime = rs.getTimestamp("EndTime"); - String declineReason = rs.getString("DeclineReason"); - lastDeclined.add(new CheckedSchematic(node, validator, startTime, endTime, declineReason, false)); - } - return lastDeclined; - }, node); + return Provider.impl.getLastDeclinedOfNode(node); } public static List getLastDeclined(UUID uuid){ @@ -96,12 +38,21 @@ public class CheckedSchematic { } public static List getLastDelined(int schemOwner){ - return checkHistory.select(rs -> { - List history = new ArrayList<>(); - while(rs.next()) - history.add(new CheckedSchematic(rs.getInt("NodeId"), rs.getInt("Validator"), rs.getTimestamp("StartTime"), rs.getTimestamp("EndTime"), rs.getString("DeclineReason"), false)); - return history; - }, schemOwner); + return Provider.impl.getLastDelined(schemOwner); + } + + private final Integer node; + private final int validator; + private final Timestamp startTime; + private final Timestamp endTime; + private final String declineReason; + + public CheckedSchematic(Integer node, int validator, Timestamp startTime, Timestamp endTime, String declineReason) { + this.node = node; + this.validator = validator; + this.startTime = startTime; + this.endTime = endTime; + this.declineReason = declineReason; } public int getValidator() { @@ -131,8 +82,4 @@ public class CheckedSchematic { public int getSchemOwner() { return SchematicNode.getSchematicNode(node).getId(); } - - public void remove() { - setNodeNull.update(node); - } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/DownloadSchematic.java b/SpigotCore_Main/src/de/steamwar/sql/DownloadSchematic.java deleted file mode 100644 index 64812f9..0000000 --- a/SpigotCore_Main/src/de/steamwar/sql/DownloadSchematic.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - 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; - -public class DownloadSchematic { - private DownloadSchematic(){} - - @Deprecated - public static String getLink(Schematic schem){ - return NodeDownload.getLink(schem.getNode()); - } -} diff --git a/SpigotCore_Main/src/de/steamwar/sql/Elo.java b/SpigotCore_Main/src/de/steamwar/sql/Elo.java index f077199..8eeeab7 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/Elo.java +++ b/SpigotCore_Main/src/de/steamwar/sql/Elo.java @@ -22,18 +22,11 @@ package de.steamwar.sql; public class Elo { private Elo(){} - private static final SQL.Statement get = new SQL.Statement("SELECT Elo FROM Elo WHERE UserID = ? AND GameMode = ?"); - private static final SQL.Statement set = new SQL.Statement("INSERT INTO Elo (UserID, GameMode, Elo) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Elo = VALUES(Elo)"); - public static int getElo(int userId, String gameMode){ - return get.select(rs -> { - if(rs.next()) - return rs.getInt("Elo"); - return 1000; - }, userId, gameMode); + return Provider.impl.getElo(userId, gameMode); } public static void setElo(int userId, String gameMode, int elo){ - set.update(userId, gameMode, elo); + Provider.impl.setElo(userId, gameMode, elo); } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/Event.java b/SpigotCore_Main/src/de/steamwar/sql/Event.java index a447f3c..a08ad8f 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/Event.java +++ b/SpigotCore_Main/src/de/steamwar/sql/Event.java @@ -19,13 +19,13 @@ package de.steamwar.sql; -import java.sql.ResultSet; -import java.sql.SQLException; import java.sql.Timestamp; public class Event { - private static final SQL.Statement get = new SQL.Statement("SELECT * FROM Event WHERE EventID = ?"); + public static Event get(int eventID){ + return Provider.impl.getEvent(eventID); + } private final int eventID; private final String eventName; @@ -35,21 +35,14 @@ public class Event { private final boolean publicSchemsOnly; private final boolean spectateSystem; - private Event(ResultSet rs) throws SQLException{ - this.eventID = rs.getInt("EventID"); - this.eventName = rs.getString("EventName"); - this.start = rs.getTimestamp("Start"); - this.end = rs.getTimestamp("End"); - this.maximumTeamMembers = rs.getInt("MaximumTeamMembers"); - this.publicSchemsOnly = rs.getBoolean("PublicSchemsOnly"); - this.spectateSystem = rs.getBoolean("SpectateSystem"); - } - - public static Event get(int eventID){ - return get.select(rs -> { - rs.next(); - return new Event(rs); - }, eventID); + public Event(int eventID, String eventName, Timestamp start, Timestamp end, int maximumTeamMembers, boolean publicSchemsOnly, boolean spectateSystem) { + this.eventID = eventID; + this.eventName = eventName; + this.start = start; + this.end = end; + this.maximumTeamMembers = maximumTeamMembers; + this.publicSchemsOnly = publicSchemsOnly; + this.spectateSystem = spectateSystem; } public int getEventID() { diff --git a/SpigotCore_Main/src/de/steamwar/sql/EventFight.java b/SpigotCore_Main/src/de/steamwar/sql/EventFight.java index 0487855..c60e227 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/EventFight.java +++ b/SpigotCore_Main/src/de/steamwar/sql/EventFight.java @@ -19,14 +19,11 @@ package de.steamwar.sql; -import java.sql.ResultSet; -import java.sql.SQLException; - public class EventFight { - private static final SQL.Statement get = new SQL.Statement("SELECT * FROM EventFight WHERE FightID = ?"); - private static final SQL.Statement setResult = new SQL.Statement("UPDATE EventFight SET Ergebnis = ? WHERE FightID = ?"); - private static final SQL.Statement setFight = new SQL.Statement("UPDATE EventFight SET Fight = ? WHERE FightID = ?"); + public static EventFight get(int fightID) { + return Provider.impl.getEventFight(fightID); + } private final int eventID; private final int fightID; @@ -35,29 +32,22 @@ public class EventFight { private final int kampfleiter; private final int ergebnis; - private EventFight(ResultSet rs) throws SQLException{ - this.eventID = rs.getInt("EventID"); - this.fightID = rs.getInt("FightID"); - this.teamBlue = rs.getInt("TeamBlue"); - this.teamRed = rs.getInt("TeamRed"); - this.kampfleiter = rs.getInt("Kampfleiter"); - this.ergebnis = rs.getInt("Ergebnis"); + public EventFight(int eventID, int fightID, int teamBlue, int teamRed, int kampfleiter, int ergebnis) { + this.eventID = eventID; + this.fightID = fightID; + this.teamBlue = teamBlue; + this.teamRed = teamRed; + this.kampfleiter = kampfleiter; + this.ergebnis = ergebnis; } - public static EventFight get(int fightID){ - return get.select(rs -> { - rs.next(); - return new EventFight(rs); - }, fightID); + public void setErgebnis(int winner) { + Provider.impl.setEventFightResult(this, winner); } - public void setErgebnis(int winner){ - setResult.update(winner, fightID); - } - - public void setFight(int fight){ + public void setFight(int fight) { //Fight.FightID, not EventFight.FightID - setFight.update(fight, fightID); + Provider.impl.setEventFightFightID(this, fight); } public int getTeamBlue() { diff --git a/SpigotCore_Main/src/de/steamwar/sql/Fight.java b/SpigotCore_Main/src/de/steamwar/sql/Fight.java index f3a4938..4f46ca6 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/Fight.java +++ b/SpigotCore_Main/src/de/steamwar/sql/Fight.java @@ -20,8 +20,6 @@ package de.steamwar.sql; import java.io.InputStream; -import java.sql.Blob; -import java.sql.SQLException; import java.sql.Timestamp; import java.time.Instant; import java.util.function.Consumer; @@ -29,52 +27,19 @@ import java.util.function.Consumer; public class Fight { private Fight(){} - private static final SQL.Statement create = new SQL.Statement("INSERT INTO Fight (GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition, ReplayLock) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); - private static final SQL.Statement lastId = new SQL.Statement("SELECT LAST_INSERT_ID() AS FightID"); - private static final SQL.Statement getReplay = new SQL.Statement("SELECT Replay FROM Fight WHERE FightID = ?"); - private static final SQL.Statement setReplay = new SQL.Statement("UPDATE Fight SET Replay = ? WHERE FightID = ?"); - public static int create(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition){ - return create(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition, Timestamp.from(Instant.now())); + return create(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition, Timestamp.from(Instant.now())); } public static int create(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition, Timestamp replayLock){ - create.update(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition, replayLock); - return lastId.select(rs -> { - rs.next(); - return rs.getInt("FightID"); - }); - } - - @Deprecated - public static InputStream getReplay(int fightID) { - return getReplay.select(rs -> { - rs.next(); - Blob replay = rs.getBlob("Replay"); - return replay.getBinaryStream(); - }, fightID); + return Provider.impl.createFight(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition, replayLock); } public static void getReplay(int fightID, Consumer reader) { - getReplay.select(rs -> { - rs.next(); - reader.accept(rs.getBinaryStream("Replay")); - return null; - }, fightID); - } - - @Deprecated - public static void setReplay(int fightID, byte[] data) { - Blob blob = SQL.blob(); - try { - blob.setBytes(1, data); - } catch (SQLException e) { - throw new SecurityException(e); - } - setReplay.update(blob, fightID); + Provider.impl.getReplay(fightID, reader); } public static void setReplay(int fightID, InputStream data) { - setReplay.update(data, fightID); + Provider.impl.setReplay(fightID, data); } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/FightPlayer.java b/SpigotCore_Main/src/de/steamwar/sql/FightPlayer.java index 69e6399..df65d54 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/FightPlayer.java +++ b/SpigotCore_Main/src/de/steamwar/sql/FightPlayer.java @@ -22,9 +22,7 @@ package de.steamwar.sql; public class FightPlayer { private FightPlayer(){} - private static final SQL.Statement create = new SQL.Statement("INSERT INTO FightPlayer (FightID, UserID, Team, Kit, Kills, IsOut) VALUES (?, ?, ?, ?, ?, ?)"); - public static void create(int fightID, int userID, boolean blue, String kit, int kills, boolean isOut){ - create.update(fightID, userID, blue ? 1 : 2, kit, kills, isOut); + Provider.impl.createFightPlayer(fightID, userID, blue, kit, kills, isOut); } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/NodeDownload.java b/SpigotCore_Main/src/de/steamwar/sql/NodeDownload.java index acc7a11..2ffc7d9 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/NodeDownload.java +++ b/SpigotCore_Main/src/de/steamwar/sql/NodeDownload.java @@ -26,8 +26,7 @@ import java.security.NoSuchAlgorithmException; import java.time.Instant; public class NodeDownload { - - private static final SQL.Statement createLink = new SQL.Statement("INSERT INTO NodeDownload (NodeId, Link) VALUES (?, ?) ON DUPLICATE KEY UPDATE Link = VALUES(Link)"); + private NodeDownload() {} private static final String BASE = "https://steamwar.de/download.php?schem="; @@ -43,7 +42,7 @@ public class NodeDownload { digest.reset(); digest.update((Instant.now().toString() + schem.getOwner() + schem.getId()).getBytes()); String hash = BaseEncoding.base16().encode(digest.digest()); - createLink.update(schem.getId(), hash); + Provider.impl.createDownloadLink(schem.getId(), hash); return BASE + hash; } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/NodeMember.java b/SpigotCore_Main/src/de/steamwar/sql/NodeMember.java index f2f1d90..e52298a 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/NodeMember.java +++ b/SpigotCore_Main/src/de/steamwar/sql/NodeMember.java @@ -19,56 +19,36 @@ package de.steamwar.sql; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashSet; import java.util.Set; +import java.util.function.Consumer; public class NodeMember { - private static final SQL.Statement getNodeMember = new SQL.Statement("SELECT * FROM NodeMember WHERE NodeId = ? AND UserId = ?"); - private static final SQL.Statement getNodeMembers = new SQL.Statement("SELECT * FROM NodeMember WHERE NodeId = ?"); - private static final SQL.Statement getSchematics = new SQL.Statement("SELECT * FROM NodeMember WHERE UserId = ?"); - private static final SQL.Statement createNodeMember = new SQL.Statement("INSERT INTO NodeMember (NodeId, UserId) VALUES (?, ?)"); - private static final SQL.Statement deleteNodeMember = new SQL.Statement("DELETE FROM NodeMember WHERE NodeId = ? AND UserId = ?"); - public static NodeMember getNodeMember(int node, int member) { - return getNodeMember.select(rs -> { - if(!rs.next()) - return null; - return new NodeMember(rs); - }, node, member); + return Provider.impl.getNodeMember(node, member); } public static Set getNodeMembers(int node) { - return getNodeMembers.select(rs -> { - Set members = new HashSet<>(); - while (rs.next()) - members.add(new NodeMember(rs)); - return members; - }, node); + return Provider.impl.getNodeMembers(node); } public static Set getSchematics(int member) { - return getSchematics.select(rs -> { - Set members = new HashSet<>(); - while (rs.next()) - members.add(new NodeMember(rs)); - return members; - }, member); + return Provider.impl.getMemberSchematics(member); } public static NodeMember createNodeMember(int node, int member) { - createNodeMember.update(node, member); + Provider.impl.createNodeMember(node, member); return getNodeMember(node, member); } - final int node; - final int member; + private final int node; + private final int member; + private final Consumer delete; - private NodeMember(ResultSet set) throws SQLException { - node = set.getInt("NodeId"); - member = set.getInt("UserId"); + public NodeMember(int node, int member, Consumer delete) { + this.node = node; + this.member = member; + this.delete = delete; } public int getNode() { @@ -80,6 +60,6 @@ public class NodeMember { } public void delete() { - deleteNodeMember.update(node, member); + delete.accept(this); } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java b/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java index f66d07b..b267e5c 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java +++ b/SpigotCore_Main/src/de/steamwar/sql/PersonalKit.java @@ -23,19 +23,31 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.ItemStack; import java.io.StringReader; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; import java.util.Objects; public class PersonalKit { - private static final SQL.Statement getKits = new SQL.Statement("SELECT * FROM PersonalKit WHERE UserID = ? AND GameMode = ?"); - private static final SQL.Statement getKit = new SQL.Statement("SELECT * FROM PersonalKit WHERE UserID = ? AND GameMode = ? AND Name = ?"); - private static final SQL.Statement getKitInUse = new SQL.Statement("SELECT * FROM PersonalKit WHERE UserID = ? AND GameMode = ? AND InUse = 1"); - private static final SQL.Statement delete = new SQL.Statement("DELETE FROM `PersonalKit` WHERE UserID = ? AND GameMode = ? AND Name = ?"); - private static final SQL.Statement update = new SQL.Statement("INSERT INTO PersonalKit (UserID, GameMode, Name, Inventory, Armor, InUse) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE Inventory = VALUES(Inventory), Armor = VALUES(Armor), Name = VALUES(Name), InUse = VALUES(InUse)"); + public static List get(int userID, String gamemode){ + return Provider.impl.getKits(userID, gamemode); + } + + public static PersonalKit get(int userID, String gamemode, String name) { + return Provider.impl.getKit(userID, gamemode, name); + } + + public static PersonalKit create(int userID, String gamemode, String name, ItemStack[] inventory, ItemStack[] armor){ + if(armor == null) { + armor = new ItemStack[]{null, null, null, null}; + } + PersonalKit kit = new PersonalKit(userID, name, gamemode, saveInvConfig("Inventory", inventory), saveInvConfig("Armor", armor), true); + Provider.impl.updateKit(kit); + return kit; + } + + public static PersonalKit getKitInUse(int userID, String gamemode) { + return Provider.impl.getKitInUse(userID, gamemode); + } private final int userID; private String name; @@ -44,62 +56,13 @@ public class PersonalKit { private String armor; private boolean inUse; - private PersonalKit(ResultSet rs) throws SQLException { - userID = rs.getInt("UserID"); - gamemode = rs.getString("GameMode"); - inventory = rs.getString("Inventory"); - armor = rs.getString("Armor"); - name = rs.getString("Name"); - inUse = rs.getBoolean("InUse"); - } - - public static List get(int userID, String gamemode){ - return getKits.select(rs -> { - List list = new ArrayList<>(); - while (rs.next()) - list.add(new PersonalKit(rs)); - return list; - }, userID, gamemode); - } - - public static PersonalKit get(int userID, String gamemode, String name) { - return getKit.select(rs -> { - if(rs.next()) - return new PersonalKit(rs); - return null; - }, userID, gamemode, name); - } - - public static PersonalKit create(int userID, String gamemode, String name, ItemStack[] inventory, ItemStack[] armor){ - if(armor == null) { - armor = new ItemStack[]{null, null, null, null}; - } - SQL.update("INSERT INTO PersonalKit (UserID, GameMode, Name, Inventory, Armor) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE Inventory = VALUES(Inventory), Armor = VALUES(Armor), Name = VALUES(name)", - userID, gamemode, name, saveInvConfig("Inventory", inventory), saveInvConfig("Armor", armor)); - return get(userID, gamemode, name); - } - - public static PersonalKit getKitInUse(int userID, String gamemode) { - return getKitInUse.select(rs -> { - if(!rs.next()) - return null; - PersonalKit kit = new PersonalKit(rs); - while (rs.next()) - new PersonalKit(rs).setUse(false); //TODO: Violation of integrity, should not be necessary? - return kit; - }, userID, gamemode); - } - - @Deprecated - public static boolean nameInUse(int userID, String gamemode, String name) { - ResultSet set = SQL.select("SELECT COUNT(*) AS Count FROM PersonalKit WHERE UserID = ? AND GameMode = ? AND Name = ?", userID, gamemode, name); - try { - if(!set.next()) - return true; - return set.getInt("Count") > 0; - } catch (SQLException e) { - throw new SecurityException("Failed loading personal kit", e); - } + public PersonalKit(int userID, String name, String gamemode, String inventory, String armor, boolean inUse) { + this.userID = userID; + this.name = name; + this.gamemode = gamemode; + this.inventory = inventory; + this.armor = armor; + this.inUse = inUse; } public ItemStack[] getInventory(){ @@ -120,6 +83,18 @@ public class PersonalKit { return name; } + public String getGamemode() { + return gamemode; + } + + public String getRawInventory() { + return inventory; + } + + public String getRawArmor() { + return armor; + } + public boolean isInUse() { return inUse; } @@ -133,32 +108,32 @@ public class PersonalKit { private void setUse(boolean inUse) { this.inUse = inUse; - updateDB(); + Provider.impl.updateKit(this); } public void setName(String name) { this.name = name; - updateDB(); + Provider.impl.updateKit(this); } public void setInventory(ItemStack[] inventory) { this.inventory = saveInvConfig("Inventory", inventory); - updateDB(); + Provider.impl.updateKit(this); } public void setArmor(ItemStack[] armor) { this.armor = saveInvConfig("Armor", armor); - updateDB(); + Provider.impl.updateKit(this); } public void setContainer(ItemStack[] inventory, ItemStack[] armor) { this.armor = saveInvConfig("Armor", armor); this.inventory = saveInvConfig("Inventory", inventory); - updateDB(); + Provider.impl.updateKit(this); } public void delete() { - delete.update(userID, gamemode, name); + Provider.impl.deleteKit(this); } private static String saveInvConfig(String name, ItemStack[] inv) { @@ -167,8 +142,4 @@ public class PersonalKit { return armorConfig.saveToString(); } - - private void updateDB() { - update.update(userID, gamemode, name, inventory, armor, inUse); - } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/Provider.java b/SpigotCore_Main/src/de/steamwar/sql/Provider.java new file mode 100644 index 0000000..3cdadcf --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/sql/Provider.java @@ -0,0 +1,104 @@ +/* + * 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 de.steamwar.core.Core; + +import java.io.IOException; +import java.io.InputStream; +import java.sql.Timestamp; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Consumer; + +public interface Provider { + Provider impl = Core.standalone() ? new StandaloneProvider() : new SQLProvider(); + + BauweltMember getBauMember(int ownerID, int memberID); + List getMembers(int bauweltID); + + List getLastDeclinedOfNode(int node); + List getLastDelined(int schemOwner); + + int getElo(int userId, String gameMode); + void setElo(int userId, String gameMode, int elo); + + Event getEvent(int eventID); + EventFight getEventFight(int fightID); + void setEventFightResult(EventFight fight, int winner); + void setEventFightFightID(EventFight fight, int fightID); + + int createFight(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition, Timestamp replayLock); + void getReplay(int fightID, Consumer reader); + void setReplay(int fightID, InputStream data); + + void createFightPlayer(int fightID, int userID, boolean blue, String kit, int kills, boolean isOut); + + void createDownloadLink(int nodeId, String hash); + + NodeMember getNodeMember(int node, int member); + Set getNodeMembers(int node); + Set getMemberSchematics(int member); + void createNodeMember(int node, int member); + + List getKits(int userID, String gamemode); + PersonalKit getKit(int userID, String gamemode, String name); + void updateKit(PersonalKit kit); + void deleteKit(PersonalKit kit); + PersonalKit getKitInUse(int userID, String gamemode); + + Punishment getPunishmentOfPlayer(int user, Punishment.PunishmentType type); + Map getPunishmentsOfPlayer(int user); + + SteamwarUser getUserByName(String userName); + SteamwarUser getUserByUUID(UUID uuid); + SteamwarUser getUserByID(int id); + + void logException(String server, String message, String stacktrace); + + Team getTeam(int id); + List getTeamMembers(Team team); + + String getConfig(int player, String config); + void updatePlayerConfig(int id, String config, String value); + void removePlayerConfig(int id, String config); + + void createSchematicNode(int owner, String name, Integer parent, String type, String item); + SchematicNode getSchematicNode(int owner, String name, Integer parent); + List getSchematicNodeInNode(Integer parent); + List getSchematicDirectoryInNode(Integer parent); + SchematicNode getSchematicDirectory(String name, Integer parent); + SchematicNode getSchematicNode(String name, Integer parent); + SchematicNode getSchematicNode(int id); + List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent); + List getAllAccessibleSchematicsOfType(int user, String schemType); + List getAllSchematicsOfType(int owner, String schemType); + List getAllSchematicsOfType(String schemType); + List getSchematicsAccessibleByUser(int user, Integer parent); + List getAllSchematicsAccessibleByUser(int user); + List getAllParentsOfNode(int node); + Integer countNodes(); + void updateSchematicNode(SchematicNode node); + void deleteSchematicNode(SchematicNode node); + InputStream getSchematicData(SchematicNode node) throws IOException; + void saveSchematicNode(SchematicNode node, InputStream blob, boolean newFormat); +} diff --git a/SpigotCore_Main/src/de/steamwar/sql/Punishment.java b/SpigotCore_Main/src/de/steamwar/sql/Punishment.java index 2607823..f97285c 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/Punishment.java +++ b/SpigotCore_Main/src/de/steamwar/sql/Punishment.java @@ -22,33 +22,21 @@ package de.steamwar.sql; import lombok.AllArgsConstructor; import lombok.Getter; -import java.sql.ResultSet; -import java.sql.SQLException; import java.sql.Timestamp; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.Date; +import java.util.Map; import java.util.function.Consumer; public class Punishment { - private static final SQL.Statement getPunishment = new SQL.Statement("SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1"); - private static final SQL.Statement getPunishments = new SQL.Statement("SELECT * FROM Punishments WHERE PunishmentId IN (SELECT MAX(PunishmentId) FROM Punishments WHERE UserId = ? GROUP BY Type)"); public static Punishment getPunishmentOfPlayer(int user, PunishmentType type) { - return getPunishment.select(rs -> { - if (rs.next()) - return new Punishment(rs); - return null; - }, user, type.name()); + return Provider.impl.getPunishmentOfPlayer(user, type); } public static Map getPunishmentsOfPlayer(int user) { - return getPunishments.select(rs -> { - Map punishments = new HashMap<>(); - while (rs.next()) - punishments.put(PunishmentType.valueOf(rs.getString("Type")), new Punishment(rs)); - return punishments; - }, user); + return Provider.impl.getPunishmentsOfPlayer(user); } public static boolean isPunished(SteamwarUser user, Punishment.PunishmentType type, Consumer callback) { @@ -61,24 +49,23 @@ public class Punishment { } } - private final Timestamp startTime; - private Timestamp endTime; - private final PunishmentType type; - private final int user; - private final int id; - private String reason; - private final int punisher; - private boolean perma; - private Punishment(ResultSet set) throws SQLException { - user = set.getInt("UserId"); - reason = set.getString("Reason"); - type = PunishmentType.valueOf(set.getString("Type")); - startTime = set.getTimestamp("StartTime"); - endTime = set.getTimestamp("EndTime"); - punisher = set.getInt("Punisher"); - perma = set.getBoolean("Perma"); - id = set.getInt("PunishmentId"); + private final int user; + private final int punisher; + private final PunishmentType type; + private final Timestamp startTime; + private final Timestamp endTime; + private final boolean perma; + private final String reason; + + public Punishment(int user, int punisher, PunishmentType type, Timestamp startTime, Timestamp endTime, boolean perma, String reason) { + this.user = user; + this.punisher = punisher; + this.type = type; + this.startTime = startTime; + this.endTime = endTime; + this.perma = perma; + this.reason = reason; } public Timestamp getStartTime() { diff --git a/SpigotCore_Main/src/de/steamwar/sql/SQL.java b/SpigotCore_Main/src/de/steamwar/sql/SQL.java deleted file mode 100644 index fc8c7a2..0000000 --- a/SpigotCore_Main/src/de/steamwar/sql/SQL.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - 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 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException; -import de.steamwar.core.Core; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.sql.*; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; - - -public class SQL { - private SQL(){} - - private static Connection con; - private static final String URL; - private static final String USER; - private static final String PASSWORD; - - static { - File file = new File(Core.getInstance().getDataFolder(), "MySQL.yml"); - YamlConfiguration config = YamlConfiguration.loadConfiguration(file); - - if(!file.exists()) - throw new SecurityException("SQL-ConfigFile not found!"); - - URL = "jdbc:mysql://" + config.getString("HOST") + ":" + config.getString("PORT") + "/" + config.getString("DATABASE"); - USER = config.getString("USER"); - PASSWORD = config.getString("PASSWORD"); - - connect(); - } - - private static void connect() { - try { - con = DriverManager.getConnection(URL + "?useServerPrepStmts=true", USER, PASSWORD); - } catch (SQLException e) { - throw new SecurityException("Could not start SQL connection", e); - } - } - - public static void close() { - for (Statement statement : Statement.statements) { - try { - statement.st.close(); - } catch (SQLException e) { - Core.getInstance().getLogger().log(Level.INFO, "Could not close statement", e); - } - } - - try { - con.close(); - } catch (SQLException e) { - Core.getInstance().getLogger().log(Level.INFO, "Could not close SQL connection", e); - } - } - - private static void reset() { - close(); - connect(); - - try { - for (Statement statement : Statement.statements) { - statement.init(); - } - } catch (SQLException ex) { - throw new SecurityException("Could not reprepare SQL Statements", ex); - } - } - - public static boolean connectionStable() { - try { - return !con.isClosed(); - } catch (SQLException e) { - return false; - } - } - - @Deprecated - static void update(String qry, Object... objects) { - try { - prepare(qry, objects).executeUpdate(); - } catch (SQLException e) { - reset(); - throw new SecurityException("Could not execute SQL statement", e); - } - } - - @Deprecated - static ResultSet select(String qry, Object... objects) { - try { - return prepare(qry, objects).executeQuery(); - } catch (SQLException e) { - reset(); - throw new SecurityException("Could not execute SQL statement", e); - } - } - - @Deprecated - static Blob blob() { - try { - return con.createBlob(); - } catch (SQLException e) { - reset(); - throw new SecurityException("Could not execute SQL statement", e); - } - } - - @Deprecated - private static PreparedStatement prepare(String qry, Object... objects) throws SQLException { - PreparedStatement st = con.prepareStatement(qry); - for(int i = 0; i < objects.length; i++){ - st.setObject(i+1, objects[i]); - } - return st; - } - - public static class Statement { - private static final List statements = new ArrayList<>(); - - private final String sql; - private PreparedStatement st; - - Statement(String sql) { - this.sql = sql; - statements.add(this); - try { - init(); - } catch (SQLException e) { - throw new SecurityException("Could not init statement", e); - } - } - - private synchronized void init() throws SQLException { - st = con.prepareStatement(sql); - } - - T select(ResultSetUser user, Object... objects) { - return prepare(() -> { - ResultSet rs = st.executeQuery(); - T result = user.use(rs); - rs.close(); - return result; - }, objects); - } - - void update(Object... objects) { - prepare(st::executeUpdate, objects); - } - - private synchronized T prepare(SQLRunnable runnable, Object... objects) { - try { - try { - setObjects(objects); - return runnable.run(); - } catch (CommunicationsException e) { - reset(); - setObjects(objects); - return runnable.run(); - } - } catch (SQLException e) { - throw new SecurityException("Could not execute SQL statement", e); - } - } - - private void setObjects(Object... objects) throws SQLException { - for (int i = 0; i < objects.length; i++) { - st.setObject(i + 1, objects[i]); - } - } - - interface ResultSetUser { - T use(ResultSet rs) throws SQLException; - } - - private interface SQLRunnable { - T run() throws SQLException; - } - } -} diff --git a/SpigotCore_Main/src/de/steamwar/sql/SQLProvider.java b/SpigotCore_Main/src/de/steamwar/sql/SQLProvider.java new file mode 100644 index 0000000..999186a --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/sql/SQLProvider.java @@ -0,0 +1,605 @@ +/* + * 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 java.io.IOException; +import java.io.InputStream; +import java.sql.Blob; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.*; +import java.util.function.Consumer; +import java.util.zip.GZIPInputStream; + +public class SQLProvider implements Provider { + + private static final Statement getBauMember = new Statement("SELECT * FROM BauweltMember WHERE BauweltID = ? AND MemberID = ?"); + @Override + public BauweltMember getBauMember(int ownerID, int memberID) { + return getBauMember.select(rs -> rs.next() ? newBauweltMember(rs) : null, ownerID, memberID); + } + + private static final Statement getBauMembers = new Statement("SELECT * FROM BauweltMember WHERE BauweltID = ?"); + @Override + public List getMembers(int bauweltID) { + return getBauMembers.select(rs -> { + List members = new ArrayList<>(); + while(rs.next()) + members.add(newBauweltMember(rs)); + return members; + }, bauweltID); + } + + private BauweltMember newBauweltMember(ResultSet rs) throws SQLException { + return new BauweltMember(rs.getInt("BauweltID"), rs.getInt("MemberID"), rs.getBoolean("WorldEdit"), rs.getBoolean("World")); + } + + private static final Statement nodeHistory = new Statement("SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC"); + @Override + public List getLastDeclinedOfNode(int node) { + return nodeHistory.select(rs -> { + List lastDeclined = new ArrayList<>(); + while(rs.next()) + lastDeclined.add(newCheckedSchematic(rs)); + return lastDeclined; + }, node); + } + + private static final Statement checkHistory = new Statement("SELECT * FROM CheckedSchematic WHERE NodeId IN (SELECT NodeId FROM SchematicNode WHERE NodeOwner = ?) AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' AND NodeId is not NULL ORDER BY EndTime DESC"); + @Override + public List getLastDelined(int schemOwner) { + return checkHistory.select(rs -> { + List history = new ArrayList<>(); + while(rs.next()) + history.add(newCheckedSchematic(rs)); + return history; + }, schemOwner); + } + + private CheckedSchematic newCheckedSchematic(ResultSet rs) throws SQLException { + return new CheckedSchematic(rs.getInt("NodeId"), rs.getInt("Validator"), rs.getTimestamp("StartTime"), rs.getTimestamp("EndTime"), rs.getString("DeclineReason")); + } + + private static final Statement getElo = new Statement("SELECT Elo FROM Elo WHERE UserID = ? AND GameMode = ?"); + @Override + public int getElo(int userId, String gameMode) { + return getElo.select(rs -> { + if(rs.next()) + return rs.getInt("Elo"); + return 1000; + }, userId, gameMode); + } + + private static final Statement setElo = new Statement("INSERT INTO Elo (UserID, GameMode, Elo) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Elo = VALUES(Elo)"); + @Override + public void setElo(int userId, String gameMode, int elo) { + setElo.update(userId, gameMode, elo); + } + + private static final Statement getEvent = new Statement("SELECT * FROM Event WHERE EventID = ?"); + @Override + public Event getEvent(int eventID) { + return getEvent.select(rs -> { + rs.next(); + return new Event(rs.getInt("EventID"), rs.getString("EventName"), rs.getTimestamp("Start"), rs.getTimestamp("End"), rs.getInt("MaximumTeamMembers"), rs.getBoolean("PublicSchemsOnly"), rs.getBoolean("SpectateSystem")); + }, eventID); + } + + private static final Statement getEventFight = new Statement("SELECT * FROM EventFight WHERE FightID = ?"); + @Override + public EventFight getEventFight(int fightID) { + return getEventFight.select(rs -> { + rs.next(); + return new EventFight(rs.getInt("EventID"), rs.getInt("FightID"), rs.getInt("TeamBlue"), rs.getInt("TeamRed"), rs.getInt("Kampfleiter"), rs.getInt("Ergebnis")); + }, fightID); + } + + private static final Statement setEventFightResult = new Statement("UPDATE EventFight SET Ergebnis = ? WHERE FightID = ?"); + @Override + public void setEventFightResult(EventFight fight, int winner) { + setEventFightResult.update(winner, fight.getFightID()); + } + + private static final Statement setEventFightFightID = new Statement("UPDATE EventFight SET Fight = ? WHERE FightID = ?"); + @Override + public void setEventFightFightID(EventFight fight, int fightID) { + setEventFightFightID.update(fight, fight.getFightID()); + } + + private static final Statement createFight = new Statement("INSERT INTO Fight (GameMode, Server, StartTime, Duration, BlueLeader, RedLeader, BlueSchem, RedSchem, Win, WinCondition, ReplayLock) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); + private static final Statement getLastFightID = new Statement("SELECT LAST_INSERT_ID() AS FightID"); + @Override + public int createFight(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition, Timestamp replayLock) { + createFight.update(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition, replayLock); + return getLastFightID.select(rs -> { + rs.next(); + return rs.getInt("FightID"); + }); + } + + private static final Statement getReplay = new Statement("SELECT Replay FROM Fight WHERE FightID = ?"); + @Override + public void getReplay(int fightID, Consumer reader) { + getReplay.select(rs -> { + rs.next(); + reader.accept(rs.getBinaryStream("Replay")); + return null; + }, fightID); + } + + private static final Statement setReplay = new Statement("UPDATE Fight SET Replay = ? WHERE FightID = ?"); + @Override + public void setReplay(int fightID, InputStream data) { + setReplay.update(data, fightID); + } + + private static final Statement create = new Statement("INSERT INTO FightPlayer (FightID, UserID, Team, Kit, Kills, IsOut) VALUES (?, ?, ?, ?, ?, ?)"); + @Override + public void createFightPlayer(int fightID, int userID, boolean blue, String kit, int kills, boolean isOut) { + create.update(fightID, userID, blue ? 1 : 2, kit, kills, isOut); + } + + private static final Statement createLink = new Statement("INSERT INTO NodeDownload (NodeId, Link) VALUES (?, ?) ON DUPLICATE KEY UPDATE Link = VALUES(Link)"); + @Override + public void createDownloadLink(int nodeId, String hash) { + createLink.update(nodeId, hash); + } + + private static final Statement getNodeMember = new Statement("SELECT * FROM NodeMember WHERE NodeId = ? AND UserId = ?"); + @Override + public NodeMember getNodeMember(int node, int member) { + return getNodeMember.select(rs -> { + if(!rs.next()) + return null; + return newNodeMember(rs); + }, node, member); + } + + private static final Statement getNodeMembers = new Statement("SELECT * FROM NodeMember WHERE NodeId = ?"); + @Override + public Set getNodeMembers(int node) { + return getNodeMembers.select(rs -> { + Set members = new HashSet<>(); + while (rs.next()) + members.add(newNodeMember(rs)); + return members; + }, node); + } + + private static final Statement getSchematics = new Statement("SELECT * FROM NodeMember WHERE UserId = ?"); + @Override + public Set getMemberSchematics(int member) { + return getSchematics.select(rs -> { + Set members = new HashSet<>(); + while (rs.next()) + members.add(newNodeMember(rs)); + return members; + }, member); + } + + private static final Statement deleteNodeMember = new Statement("DELETE FROM NodeMember WHERE NodeId = ? AND UserId = ?"); + private NodeMember newNodeMember(ResultSet rs) throws SQLException { + return new NodeMember(rs.getInt("NodeId"), rs.getInt("UserId"), member -> deleteNodeMember.update(member.getNode(), member.getMember())); + } + + private static final Statement createNodeMember = new Statement("INSERT INTO NodeMember (NodeId, UserId) VALUES (?, ?)"); + @Override + public void createNodeMember(int node, int member) { + createNodeMember.update(node, member); + } + + private static final Statement getKits = new Statement("SELECT * FROM PersonalKit WHERE UserID = ? AND GameMode = ?"); + @Override + public List getKits(int userID, String gamemode) { + return getKits.select(rs -> { + List list = new ArrayList<>(); + while (rs.next()) + list.add(newPersonalKit(rs)); + return list; + }, userID, gamemode); + } + + private static final Statement getKit = new Statement("SELECT * FROM PersonalKit WHERE UserID = ? AND GameMode = ? AND Name = ?"); + @Override + public PersonalKit getKit(int userID, String gamemode, String name) { + return getKit.select(rs -> { + if(rs.next()) + return newPersonalKit(rs); + return null; + }, userID, gamemode, name); + } + + private PersonalKit newPersonalKit(ResultSet rs) throws SQLException { + return new PersonalKit(rs.getInt("UserID"), rs.getString("Name"), rs.getString("GameMode"), rs.getString("Inventory"), rs.getString("Armor"), rs.getBoolean("InUse")); + } + + private static final Statement updateKit = new Statement("INSERT INTO PersonalKit (UserID, GameMode, Name, Inventory, Armor, InUse) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE Inventory = VALUES(Inventory), Armor = VALUES(Armor), Name = VALUES(Name), InUse = VALUES(InUse)"); + @Override + public void updateKit(PersonalKit kit) { + updateKit.update(kit.getUserID(), kit.getGamemode(), kit.getName(), kit.getRawInventory(), kit.getRawArmor(), kit.isInUse()); + } + + private static final Statement deleteKit = new Statement("DELETE FROM `PersonalKit` WHERE UserID = ? AND GameMode = ? AND Name = ?"); + @Override + public void deleteKit(PersonalKit kit) { + deleteKit.update(kit.getUserID(), kit.getGamemode(), kit.getName()); + } + + private static final Statement getKitInUse = new Statement("SELECT * FROM PersonalKit WHERE UserID = ? AND GameMode = ? AND InUse = 1"); + @Override + public PersonalKit getKitInUse(int userID, String gamemode) { + return getKitInUse.select(rs -> { + if(rs.next()) + return newPersonalKit(rs); + return null; + }, userID, gamemode); + } + + private static final Statement getPunishment = new Statement("SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1"); + @Override + public Punishment getPunishmentOfPlayer(int user, Punishment.PunishmentType type) { + return getPunishment.select(rs -> { + if (rs.next()) + return newPunishment(rs); + return null; + }, user, type.name()); + } + + private Punishment newPunishment(ResultSet rs) throws SQLException { + return new Punishment(rs.getInt("UserId"), rs.getInt("Punisher"), Punishment.PunishmentType.valueOf(rs.getString("Type")), rs.getTimestamp("StartTime"), rs.getTimestamp("EndTime"), rs.getBoolean("Perma"), rs.getString("Reason")); + } + + private static final Statement getPunishments = new Statement("SELECT * FROM Punishments WHERE PunishmentId IN (SELECT MAX(PunishmentId) FROM Punishments WHERE UserId = ? GROUP BY Type)"); + @Override + public Map getPunishmentsOfPlayer(int user) { + return getPunishments.select(rs -> { + Map punishments = new HashMap<>(); + while (rs.next()) + punishments.put(Punishment.PunishmentType.valueOf(rs.getString("Type")), newPunishment(rs)); + return punishments; + }, user); + } + + private static final Statement getUserName = new Statement("SELECT * FROM UserData WHERE lower(UserName) = ?"); + @Override + public SteamwarUser getUserByName(String userName) { + return getUserName.select(rs -> { + if(rs.next()) + return newSteamwarUser(rs); + return null; + }, userName.toLowerCase()); + } + + private static final Statement getUserUUID = new Statement("SELECT * FROM UserData WHERE UUID = ?"); + @Override + public SteamwarUser getUserByUUID(UUID uuid) { + return getUserUUID.select(rs -> { + rs.next(); + return newSteamwarUser(rs); + }, uuid.toString()); + } + + private static final Statement getUserId = new Statement("SELECT * FROM UserData WHERE id = ?"); + @Override + public SteamwarUser getUserByID(int id) { + return getUserId.select(rs -> { + rs.next(); + return newSteamwarUser(rs); + }, id); + } + + private SteamwarUser newSteamwarUser(ResultSet rs) throws SQLException { + return new SteamwarUser(rs.getInt("id"), UUID.fromString(rs.getString("UUID")), rs.getString("UserName"), UserGroup.getUsergroup(rs.getString("UserGroup")), rs.getInt("Team"), rs.getBoolean("Bedrock")); + } + + private static final Statement insert = new Statement("INSERT INTO Exception (server, message, stacktrace) VALUES (?, ?, ?)"); + @Override + public void logException(String server, String message, String stacktrace) { + insert.update(server, message, stacktrace); + } + + private static final Statement getTeam = new Statement("SELECT * FROM Team WHERE TeamID = ?"); + @Override + public Team getTeam(int id) { + return getTeam.select(rs -> { + rs.next(); + return new Team(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getString("TeamColor")); + }, id); + } + + private static final Statement getTeamMembers = new Statement("SELECT id FROM UserData WHERE Team = ?"); + @Override + public List getTeamMembers(Team team) { + return getTeamMembers.select(rs -> { + List members = new ArrayList<>(); + while(rs.next()) + members.add(rs.getInt("id")); + return members; + }, team.getTeamId()); + } + + private static final Statement getConfig = new Statement("SELECT Value FROM UserConfig WHERE User = ? AND Config = ?"); + @Override + public String getConfig(int player, String config) { + return getConfig.select(rs -> { + if(rs.next()) + return rs.getString("Value"); + return null; + }, player, config); + } + + private static final Statement setConfig = new Statement("INSERT INTO UserConfig (User, Config, Value) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Value = VALUES(Value)"); + @Override + public void updatePlayerConfig(int id, String config, String value) { + setConfig.update(id, config, value); + } + + private static final Statement deleteConfig = new Statement("DELETE FROM UserConfig WHERE User = ? AND Config = ?"); + @Override + public void removePlayerConfig(int id, String config) { + deleteConfig.update(id, config); + } + + private static final Statement createNode = new Statement("INSERT INTO SchematicNode (NodeName, NodeOwner, ParentNode, NodeType, NodeItem) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE NodeName = VALUES(NodeName), ParentNode = VALUES(ParentNode), NodeItem = VALUES(NodeItem), NodeType = VALUES(NodeType), NodeItem = VALUES(NodeItem)"); + private static final Statement getSchematicNode_Null = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeName = ? AND ParentNode is NULL"); + private static final Statement getSchematicNode = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeName = ? AND ParentNode = ?"); + private static final Statement getSchematicsInNode_Null = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode is NULL ORDER BY NodeName"); + private static final Statement getSchematicsInNode = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode = ? ORDER BY NodeName"); + private static final Statement getDirsInNode_Null = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName"); + private static final Statement getDirsInNode = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName"); + private static final Statement getSchematicDirectory_Null = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode is NULL ORDER BY NodeName"); + private static final Statement getSchematicDirectory = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode = ? ORDER BY NodeName"); + private static final Statement getSchematicNodeO_Null = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode is NULL "); + private static final Statement getSchematicNodeO = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode = ? ORDER BY NodeName"); + private static final Statement getSchematicNodeId = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ?"); + private static final Statement getAllSchemsOfTypeOwner = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName"); + private static final Statement getAllSchemsOfType = new Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeType = ? ORDER BY NodeName"); + private static final Statement getAccessibleByUser = new Statement("SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND ((s.NodeOwner = ? AND s.ParentNode IS NULL) OR NOT s.NodeOwner = ?) GROUP BY s.NodeId ORDER BY s.NodeName"); + private static final Statement getAccessibleByUserByTypeInNode = new Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ? ORDER BY NodeName"); + private static final Statement getAccessibleByUserByTypeInNode_Null = new Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode is null ORDER BY NodeName"); + private static final Statement getAccessibleByUserByType = new Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? ORDER BY NodeName"); + private static final Statement getAllSchematicsAccessibleByUser = new Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName"); + private static final Statement isSchematicAccessibleForUser = new Statement("WITH RECURSIVE RSN AS (SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.ParentNode, SN.NodeType, SN.NodeItem, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN LEFT Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1"); + private static final Statement getAllParentsOfNode = new Statement("WITH RECURSIVE RSN AS (SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ? UNION SELECT SN.NodeId, SN.NodeName, SN.NodeOwner, SN.ParentNode, SN.NodeType, SN.NodeItem, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName"); + private static final Statement countNodes = new Statement("SELECT COUNT(NodeId) AS 'count' FROM SchematicNode"); + private static final Statement updateDB = new Statement("UPDATE SchematicNode SET NodeName = ?, NodeOwner = ?, ParentNode = ?, NodeItem = ?, NodeType = ?, NodeRank = ? WHERE NodeId = ?"); + private static final Statement updateDatabase = new Statement("UPDATE SchematicNode SET NodeData = ?, NodeFormat = ? WHERE NodeId = ?"); + private static final Statement selSchemData = new Statement("SELECT NodeData FROM SchematicNode WHERE NodeId = ?"); + private static final Statement deleteNode = new Statement("DELETE FROM SchematicNode WHERE NodeId = ?"); + + private static final Statement.ResultSetUser> toSchematicList = rs -> { + List nodes = new ArrayList<>(); + while (rs.next()) { + nodes.add(nodeFromResultSet(rs)); + } + return nodes; + }; + private static final Statement.ResultSetUser toSchematicNode = rs -> { + if (rs.next()) { + return nodeFromResultSet(rs); + } + return null; + }; + + private static SchematicNode nodeFromResultSet(ResultSet set) throws SQLException { + Integer parent = set.getInt("ParentNode"); + if(set.wasNull()) { + parent = null; + } + String type = set.getString("NodeType"); + boolean isDir = true; + int rank = 0; + boolean schemFormat = false; + if (type != null) { + isDir = false; + rank = set.getInt("NodeRank"); + schemFormat = set.getBoolean("NodeFormat"); + } + return new SchematicNode( + set.getInt("NodeId"), + set.getInt("NodeOwner"), + set.getString("NodeName"), + parent, + set.getString("NodeItem"), + type, + isDir, + rank, + set.getTimestamp("LastUpdate"), + schemFormat + ); + } + + @Override + public void createSchematicNode(int owner, String name, Integer parent, String type, String item) { + createNode.update(name, owner, parent, type, item); + } + + @Override + public SchematicNode getSchematicNode(int owner, String name, Integer parent) { + + if(parent == null) { + return getSchematicNode_Null.select(toSchematicNode, owner, name); + } else { + return getSchematicNode.select(toSchematicNode, owner, name, parent); + } + } + + @Override + public List getSchematicNodeInNode(Integer parent) { + if(parent == null) { + return getSchematicsInNode_Null.select(toSchematicList); + }else { + return getSchematicsInNode.select(toSchematicList, parent); + } + } + + @Override + public List getSchematicDirectoryInNode(Integer parent) { + if(parent == null) { + return getDirsInNode_Null.select(toSchematicList); + }else { + return getDirsInNode.select(toSchematicList, parent); + } + } + + @Override + public SchematicNode getSchematicDirectory(String name, Integer parent) { + Statement.ResultSetUser user = rs -> { + while (rs.next()) { + SchematicNode node = nodeFromResultSet(rs); + if(node.isDir()) + return node; + } + return null; + }; + + if(parent == null) { + return getSchematicDirectory_Null.select(user, name); + }else { + return getSchematicDirectory.select(user, name, parent); + } + } + + @Override + public SchematicNode getSchematicNode(String name, Integer parent) { + if(parent == null) { + return getSchematicNodeO_Null.select(toSchematicNode, name); + }else { + return getSchematicNodeO.select(toSchematicNode, name, parent); + } + } + + @Override + public SchematicNode getSchematicNode(int id) { + return getSchematicNodeId.select(rs -> { + if (!rs.next()) + return null; + return nodeFromResultSet(rs); + }, id); + } + + @Override + public List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) { + if(parent == null || parent == 0) { + return getAccessibleByUserByTypeInNode_Null.select(toSchematicList, owner, owner, schemType); + } else { + return getAccessibleByUserByTypeInNode.select(toSchematicList, owner, owner, schemType, parent); + } + } + + @Override + public List getAllAccessibleSchematicsOfType(int user, String schemType) { + return getAccessibleByUserByType.select(toSchematicList, user, user, schemType); + } + + @Override + public List getAllSchematicsOfType(int owner, String schemType) { + return getAllSchemsOfTypeOwner.select(toSchematicList, owner, schemType); + } + + @Override + public List getAllSchematicsOfType(String schemType) { + return getAllSchemsOfType.select(toSchematicList, schemType); + } + + @Override + public List getSchematicsAccessibleByUser(int user, Integer parent) { + if (parent != null && parent != 0) { + if(Boolean.TRUE.equals(isSchematicAccessibleForUser.select(rs -> { + rs.next(); + return rs.getInt("Accessible") > 0; + }, parent, user, user))) { + return getSchematicNodeInNode(parent); + } + } else { + return getAccessibleByUser.select(rs -> { + List nodes = new ArrayList<>(); + while(rs.next()) + nodes.add(nodeFromResultSet(rs)); + return nodes; + }, user, user, user, user); + } + return Collections.emptyList(); + } + + @Override + public List getAllSchematicsAccessibleByUser(int user) { + return getAllSchematicsAccessibleByUser.select(toSchematicList, user, user); + } + + @Override + public List getAllParentsOfNode(int node) { + return getAllParentsOfNode.select(toSchematicList, node); + } + + @Override + public Integer countNodes() { + return countNodes.select(rs -> { + if (rs.next()) { + return rs.getInt("count"); + } + return 0; + }); + } + + @Override + public void updateSchematicNode(SchematicNode node) { + updateDB.update( + node.getName(), + node.getOwner(), + node.getParent(), + node.getItem(), + node.getType(), + node.getRank(), + node.getId() + ); + } + + @Override + public void deleteSchematicNode(SchematicNode node) { + deleteNode.update(node.getId()); + } + + @Override + public InputStream getSchematicData(SchematicNode node) throws IOException { + try { + return selSchemData.select(rs -> { + rs.next(); + Blob schemData = rs.getBlob("NodeData"); + if(schemData == null) { + throw new SecurityException("SchemData is null"); + } + try { + return new GZIPInputStream(schemData.getBinaryStream()); + } catch (IOException e) { + throw new SecurityException("SchemData is wrong", e); + } + }, node.getId()); + } catch (Exception e) { + throw new IOException(e); + } + } + + @Override + public void saveSchematicNode(SchematicNode node, InputStream blob, boolean newFormat) { + updateDatabase.update(blob, newFormat, node.getId()); + } +} diff --git a/SpigotCore_Main/src/de/steamwar/sql/SWException.java b/SpigotCore_Main/src/de/steamwar/sql/SWException.java index e1b4cb3..d3703a6 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/SWException.java +++ b/SpigotCore_Main/src/de/steamwar/sql/SWException.java @@ -25,8 +25,6 @@ import org.bukkit.entity.Player; public class SWException { private SWException(){} - private static final SQL.Statement insert = new SQL.Statement("INSERT INTO Exception (server, message, stacktrace) VALUES (?, ?, ?)"); - public static void log(String message, String stacktrace){ message += "\n"; for(Player player : Bukkit.getOnlinePlayers()) @@ -38,6 +36,6 @@ public class SWException { else server = Bukkit.getWorlds().get(0).getName(); - insert.update(server, message, stacktrace); + Provider.impl.logException(server, message, stacktrace); } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/Schematic.java b/SpigotCore_Main/src/de/steamwar/sql/Schematic.java deleted file mode 100644 index ac3cd46..0000000 --- a/SpigotCore_Main/src/de/steamwar/sql/Schematic.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - 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 com.sk89q.worldedit.extent.clipboard.Clipboard; -import de.steamwar.core.Core; -import de.steamwar.core.WorldEditWrapper; -import org.bukkit.entity.Player; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.stream.Collectors; - -@Deprecated -public class Schematic { - - private static final SQL.Statement getSchemsOfType = new SQL.Statement("SELECT DISTINCT s.SchemID, s.SchemName, s.SchemOwner, s.Item, s.SchemType, s.Rank, s.SchemFormat FROM Schematic s LEFT JOIN SchemMember sm ON sm.SchemName = s.SchemName AND sm.SchemOwner = s.SchemOwner WHERE s.SchemType = ? AND (s.SchemOwner = ? OR sm.Member = ?) ORDER BY s.SchemName"); - - private final SchematicNode node; - - private Schematic(SchematicNode node) { - this.node = node; - } - - public static Schematic wrap(SchematicNode node) { - return new Schematic(node); - } - - public static void createSchem(String schemName, UUID schemOwner, String item, SchematicType schemType){ - createSchem(schemName, SteamwarUser.get(schemOwner).getId(), item, schemType); - } - - public static void createSchem(String schemName, int schemOwner, String item, SchematicType schemType){ - SchematicNode.createSchematicNode(schemOwner, schemName, null, schemType.toDB(), item); - } - - public static Schematic getSchemFromDB(String schemName, UUID schemOwner){ - return getSchemFromDB(schemName, SteamwarUser.get(schemOwner).getId()); - } - - public static Schematic getSchemFromDB(String schemName, int schemOwner){ - SchematicNode node = SchematicNode.getSchematicNode(schemOwner, schemName, 0); - if(node != null) { - return new Schematic(node); - } else { - Optional n = SchematicNode.getSchematicsAccessibleByUser(schemOwner, 0).stream().filter(node1 -> node1.getName().equals(schemName)).findAny(); - if(n.isPresent()) { - return new Schematic(n.get()); - } - } - return null; - } - - public static Schematic getSchemFromDB(int schemID){ - SchematicNode node = SchematicNode.getSchematicNode(schemID); - if(node != null) { - return new Schematic(node); - } else { - throw new SecurityException("Failed to load Schematics"); - } - } - - public static List getSchemsAccessibleByUser(UUID schemOwner){ - return getSchemsAccessibleByUser(SteamwarUser.get(schemOwner).getId()); - } - - public static List getSchemsAccessibleByUser(int schemOwner){ - List schematics = new ArrayList<>(); - SchematicNode.getSchematicsAccessibleByUser(schemOwner, null) - .forEach(node1 -> { - if (!node1.isDir()) schematics.add(new Schematic(node1)); - }); - return schematics; - } - - public static List getSchemsOfType(UUID schemOwner, SchematicType schemType){ - return getSchemsOfType(SteamwarUser.get(schemOwner).getId(), schemType); - } - - public static List getSchemsOfType(int schemOwner, SchematicType schemType){ - List schematics = new ArrayList<>(); - SchematicNode.getAllAccessibleSchematicsOfType(schemOwner, schemType.toDB()) - .forEach(node1 -> { - if (!node1.isDir()) schematics.add(new Schematic(node1)); - }); - return schematics; - } - - public static List getAllSchemsOfType(SchematicType schemType){ - List schematics = new ArrayList<>(); - SchematicNode.getAllSchematicsOfType(schemType.toDB()) - .forEach(node1 -> schematics.add(new Schematic(node1))); - return schematics; - } - - public int getSchemID() { - return node.getId(); - } - - public String getSchemName() { - return node.getName(); - } - - public int getSchemOwner() { - return node.getOwner(); - } - - public int getRank(){ - return node.getRank(); - } - - public String getItem() { - return node.getItem(); - } - - public void setItem(String item) { - node.setItem(item); - } - - public void setRank(int rank){ - node.setRank(rank); - } - - public SchematicType getSchemType() { - return node.getSchemtype(); - } - - public void setSchemType(SchematicType schemType) { - node.setType(schemType.toDB()); - } - - public boolean availible(){ - return true; - } - - public InputStream schemData() throws IOException { - return node.schemData(); - } - - public static Clipboard clipboardFromStream(InputStream is, boolean schemFormat) { - try { - return WorldEditWrapper.impl.getClipboard(is, schemFormat); - } catch (IOException e) { - throw new SecurityException("Could not read schem", e); - } - } - - public Clipboard load() throws IOException, NoClipboardException { - return clipboardFromStream(schemData(), node.getSchemFormat()); - } - - public void loadToPlayer(Player player) throws IOException, NoClipboardException { - InputStream is = schemData(); - WorldEditWrapper.impl.setPlayerClipboard(player, is, node.getSchemFormat()); - } - - public void saveOldFormatFromPlayer(Player player) throws IOException, NoClipboardException { - saveFromPlayer(player, false); - } - - public void saveFromPlayer(Player player) throws IOException, NoClipboardException { - saveFromPlayer(player, Core.getVersion() > 12); - } - - public void saveFromBytes(byte[] bytes, boolean newFormat) { - node.saveFromBytes(bytes, newFormat); - } - - private void saveFromPlayer(Player player, boolean newFormat) throws IOException, NoClipboardException { - node.saveFromPlayer(player, newFormat); - } - - public void remove(){ - node.delete(); - } - - public SchematicNode getNode() { - return node; - } - - @Deprecated - public static class WrongVersionException extends Exception{} -} diff --git a/SpigotCore_Main/src/de/steamwar/sql/SchematicMember.java b/SpigotCore_Main/src/de/steamwar/sql/SchematicMember.java deleted file mode 100644 index e84fa54..0000000 --- a/SpigotCore_Main/src/de/steamwar/sql/SchematicMember.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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 java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.UUID; - -@Deprecated -public class SchematicMember { - - private final NodeMember member; - - private SchematicMember(NodeMember member){ - this.member = member; - } - - public SchematicMember(String schemName, int schemOwner, int schemMember){ - this(NodeMember.createNodeMember(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), schemMember)); - } - - public SchematicMember(String schemName, UUID schemOwner, UUID schemMember){ - this(NodeMember.createNodeMember(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), SteamwarUser.get(schemMember).getId())); - } - - public static SchematicMember getSchemMemberFromDB(String schemName, UUID schemOwner, UUID schemMember){ - return getSchemMemberFromDB(schemName, SteamwarUser.get(schemOwner).getId(), SteamwarUser.get(schemMember).getId()); - } - - public static SchematicMember getSchemMemberFromDB(String schemName, int schemOwner, int schemMember){ - NodeMember member = NodeMember.getNodeMember(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), schemMember); - if(member == null) { - return null; - } - return new SchematicMember(member); - } - - public static SchematicMember getMemberBySchematic(String schemName, int schemMember){ - Optional nodeMember = NodeMember.getSchematics(schemMember) - .stream().filter(member1 -> SchematicNode.getSchematicNode(member1.getNode()).getName().equalsIgnoreCase(schemName)).findFirst(); - return nodeMember.map(SchematicMember::new).orElse(null); - } - - public static List getSchemMembers(String schemName, UUID schemOwner){ - return getSchemMembers(schemName, SteamwarUser.get(schemOwner).getId()); - } - - public static List getSchemMembers(String schemName, int schemOwner){ - List members = new ArrayList<>(); - NodeMember.getNodeMembers(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID()) - .forEach(member1 -> members.add(new SchematicMember(member1))); - return members; - } - - public static List getAccessibleSchems(UUID schemMember){ - return getAccessibleSchems(SteamwarUser.get(schemMember).getId()); - } - - public static List getAccessibleSchems(int schemMember){ - List members = new ArrayList<>(); - NodeMember.getSchematics(schemMember) - .forEach(member1 -> members.add(new SchematicMember(member1))); - return members; - } - - public int getSchemOwner() { - return SchematicNode.getSchematicNode(member.getNode()).getOwner(); - } - - public String getSchemName() { - return SchematicNode.getSchematicNode(member.getNode()).getName(); - } - - public int getMember() { - return member.getMember(); - } - - public void remove(){ - member.delete(); - } -} diff --git a/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java b/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java index bb4fe4a..7640395 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java +++ b/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java @@ -40,33 +40,6 @@ import java.util.zip.GZIPInputStream; public class SchematicNode { - private static final SQL.Statement createNode = new SQL.Statement("INSERT INTO SchematicNode (NodeName, NodeOwner, ParentNode, NodeType, NodeItem) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE NodeName = VALUES(NodeName), ParentNode = VALUES(ParentNode), NodeItem = VALUES(NodeItem), NodeType = VALUES(NodeType), NodeItem = VALUES(NodeItem)"); - private static final SQL.Statement getSchematicNode_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeName = ? AND ParentNode is NULL"); - private static final SQL.Statement getSchematicNode = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeName = ? AND ParentNode = ?"); - private static final SQL.Statement getSchematicsInNode_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode is NULL ORDER BY NodeName"); - private static final SQL.Statement getSchematicsInNode = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode = ? ORDER BY NodeName"); - private static final SQL.Statement getDirsInNode_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName"); - private static final SQL.Statement getDirsInNode = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName"); - private static final SQL.Statement getSchematicDirectory_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode is NULL ORDER BY NodeName"); - private static final SQL.Statement getSchematicDirectory = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode = ? ORDER BY NodeName"); - private static final SQL.Statement getSchematicNodeO_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode is NULL "); - private static final SQL.Statement getSchematicNodeO = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode = ? ORDER BY NodeName"); - private static final SQL.Statement getSchematicNodeId = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ?"); - private static final SQL.Statement getAllSchemsOfTypeOwner = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName"); - private static final SQL.Statement getAllSchemsOfType = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeType = ? ORDER BY NodeName"); - private static final SQL.Statement getAccessibleByUser = new SQL.Statement("SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND ((s.NodeOwner = ? AND s.ParentNode IS NULL) OR NOT s.NodeOwner = ?) GROUP BY s.NodeId ORDER BY s.NodeName"); - private static final SQL.Statement getAccessibleByUserByTypeInNode = new SQL.Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ? ORDER BY NodeName"); - private static final SQL.Statement getAccessibleByUserByTypeInNode_Null = new SQL.Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode is null ORDER BY NodeName"); - private static final SQL.Statement getAccessibleByUserByType = new SQL.Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? ORDER BY NodeName"); - private static final SQL.Statement getAllSchematicsAccessibleByUser = new SQL.Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName"); - private static final SQL.Statement isSchematicAccessibleForUser = new SQL.Statement("WITH RECURSIVE RSN AS (SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.ParentNode, SN.NodeType, SN.NodeItem, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN LEFT Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1"); - private static final SQL.Statement getAllParentsOfNode = new SQL.Statement("WITH RECURSIVE RSN AS (SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ? UNION SELECT SN.NodeId, SN.NodeName, SN.NodeOwner, SN.ParentNode, SN.NodeType, SN.NodeItem, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName"); - private static final SQL.Statement countNodes = new SQL.Statement("SELECT COUNT(NodeId) AS 'count' FROM SchematicNode"); - private static final SQL.Statement updateDB = new SQL.Statement("UPDATE SchematicNode SET NodeName = ?, NodeOwner = ?, ParentNode = ?, NodeItem = ?, NodeType = ?, NodeRank = ? WHERE NodeId = ?"); - private static final SQL.Statement updateDatabase = new SQL.Statement("UPDATE SchematicNode SET NodeData = ?, NodeFormat = ? WHERE NodeId = ?"); - private static final SQL.Statement selSchemData = new SQL.Statement("SELECT NodeData FROM SchematicNode WHERE NodeId = ?"); - private static final SQL.Statement deleteNode = new SQL.Statement("DELETE FROM SchematicNode WHERE NodeId = ?"); - public static SchematicNode createSchematic(int owner, String name, Integer parent) { return createSchematicNode(owner, name, parent, SchematicType.Normal.toDB(), ""); } @@ -78,7 +51,7 @@ public class SchematicNode { public static SchematicNode createSchematicNode(int owner, String name, Integer parent, String type, String item) { if (parent != null && parent == 0) parent = null; - createNode.update(name, owner, parent, type, item); + Provider.impl.createSchematicNode(owner, name, parent, type, item); return getSchematicNode(owner, name, parent); } @@ -86,23 +59,29 @@ public class SchematicNode { return getSchematicNode(owner, name, parent.getId()); } - private SchematicNode(ResultSet set) throws SQLException { - id = set.getInt("NodeId"); - owner = set.getInt("NodeOwner"); - name = set.getString("NodeName"); - parent = set.getInt("ParentNode"); - if(set.wasNull()) { - parent = null; - } - item = set.getString("NodeItem"); - type = set.getString("NodeType"); - lastUpdate = set.getTimestamp("LastUpdate"); - if (type != null) { - isDir = false; - rank = set.getInt("NodeRank"); - schemFormat = set.getBoolean("NodeFormat"); - } else { - isDir = true; + public SchematicNode( + int id, + int owner, + String name, + Integer parent, + String item, + String type, + boolean isDir, + int rank, + Timestamp lastUpdate, + boolean schemFormat + ) { + this.id = id; + this.owner = owner; + this.name = name; + this.parent = parent; + this.item = item; + this.type = type; + this.lastUpdate = lastUpdate; + this.isDir = isDir; + if (!isDir) { + this.schemFormat = schemFormat; + this.rank = rank; } } @@ -118,136 +97,60 @@ public class SchematicNode { if (parent != null && parent == 0) { parent = null; } - SQL.Statement.ResultSetUser user = rs -> { - if (rs.next()) { - return new SchematicNode(rs); - } - return null; - }; - if(parent == null) { - return getSchematicNode_Null.select(user, owner, name); - } else { - return getSchematicNode.select(user, owner, name, parent); - } + return Provider.impl.getSchematicNode(owner, name, parent); } public static List getSchematicNodeInNode(Integer parent) { - if(parent != null && parent == 0) + if(parent != null && parent == 0) { parent = null; - SQL.Statement.ResultSetUser> user = rs -> { - List nodes = new ArrayList<>(); - while (rs.next()) { - nodes.add(new SchematicNode(rs)); - } - return nodes; - }; - if(parent == null) { - return getSchematicsInNode_Null.select(user); - }else { - return getSchematicsInNode.select(user, parent); } + return Provider.impl.getSchematicNodeInNode(parent); } public static List getSchematicDirectoryInNode(Integer parent) { - if(parent != null && parent == 0) + if(parent != null && parent == 0) { parent = null; - SQL.Statement.ResultSetUser> user = rs -> { - List nodes = new ArrayList<>(); - while (rs.next()) - nodes.add(new SchematicNode(rs)); - return nodes; - }; - if(parent == null) { - return getDirsInNode_Null.select(user); - }else { - return getDirsInNode.select(user, parent); } + return Provider.impl.getSchematicDirectoryInNode(parent); } public static SchematicNode getSchematicDirectory(String name, Integer parent) { - if(parent != null && parent == 0) + if(parent != null && parent == 0) { parent = null; - SQL.Statement.ResultSetUser user = rs -> { - while (rs.next()) { - SchematicNode node = new SchematicNode(rs); - if(node.isDir()) - return node; - } - return null; - }; - - if(parent == null) { - return getSchematicDirectory_Null.select(user, name); - }else { - return getSchematicDirectory.select(user, name, parent); } + return Provider.impl.getSchematicDirectory(name, parent); } public static SchematicNode getSchematicNode(String name, Integer parent) { - if(parent != null && parent == 0) + if(parent != null && parent == 0) { parent = null; - SQL.Statement.ResultSetUser user = rs -> { - while (rs.next()) { - return new SchematicNode(rs); - } - return null; - }; - if(parent == null) { - return getSchematicNodeO_Null.select(user, name); - }else { - return getSchematicNodeO.select(user, name, parent); } + return Provider.impl.getSchematicNode(name, parent); } public static SchematicNode getSchematicNode(int id) { - return getSchematicNodeId.select(rs -> { - if (!rs.next()) - return null; - return new SchematicNode(rs); - }, id); + return Provider.impl.getSchematicNode(id); } public static List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) { - SQL.Statement.ResultSetUser> user = rs -> { - List nodes = new ArrayList<>(); - while (rs.next()) { - nodes.add(new SchematicNode(rs)); - } - return nodes; - }; - if(parent == null || parent == 0) { - return getAccessibleByUserByTypeInNode_Null.select(user, owner, owner, schemType); - } else { - return getAccessibleByUserByTypeInNode.select(user, owner, owner, schemType, parent); - } + return Provider.impl.getAccessibleSchematicsOfTypeInParent(owner, schemType, parent); } public static List getAllAccessibleSchematicsOfType(int user, String schemType) { - return getAccessibleByUserByType.select(rs -> { - List nodes = new ArrayList<>(); - while (rs.next()) { - nodes.add(new SchematicNode(rs)); - } - return nodes; - }, user, user, schemType); + return Provider.impl.getAllAccessibleSchematicsOfType(user, schemType); } public static List getAllSchematicsOfType(int owner, String schemType) { - return getAllSchemsOfTypeOwner.select(rs -> { - List nodes = new ArrayList<>(); - while (rs.next()) - nodes.add(new SchematicNode(rs)); - return nodes; - }, owner, schemType); + return Provider.impl.getAllSchematicsOfType(owner, schemType); } + @Deprecated public static List getAllSchematicsOfType(String schemType) { - return getAllSchemsOfType.select(rs -> { - List nodes = new ArrayList<>(); - while (rs.next()) - nodes.add(new SchematicNode(rs)); - return nodes; - }, schemType); + return Provider.impl.getAllSchematicsOfType(schemType); + } + + public static List getAllSchematicsOfType(SchematicType schemType) { + return Provider.impl.getAllSchematicsOfType(schemType.toDB()); } public static List deepGet(Integer parent, Predicate filter) { @@ -265,32 +168,11 @@ public class SchematicNode { } public static List getSchematicsAccessibleByUser(int user, Integer parent) { - if (parent != null && parent != 0) { - if(Boolean.TRUE.equals(isSchematicAccessibleForUser.select(rs -> { - rs.next(); - return rs.getInt("Accessible") > 0; - }, parent, user, user))) { - return getSchematicNodeInNode(parent); - } - } else { - return getAccessibleByUser.select(rs -> { - List nodes = new ArrayList<>(); - while(rs.next()) - nodes.add(new SchematicNode(rs)); - return nodes; - }, user, user, user, user); - } - return Collections.emptyList(); + return Provider.impl.getSchematicsAccessibleByUser(user, parent); } public static List getAllSchematicsAccessibleByUser(int user) { - return getAllSchematicsAccessibleByUser.select(rs -> { - List nodes = new ArrayList<>(); - while(rs.next()) { - nodes.add(new SchematicNode(rs)); - } - return nodes; - }, user, user); + return Provider.impl.getAllSchematicsAccessibleByUser(user); } public static List getAllParentsOfNode(SchematicNode node) { @@ -298,13 +180,7 @@ public class SchematicNode { } public static List getAllParentsOfNode(int node) { - return getAllParentsOfNode.select(rs -> { - List nodes = new ArrayList<>(); - while(rs.next()) { - nodes.add(new SchematicNode(rs)); - } - return nodes; - }, node); + return Provider.impl.getAllParentsOfNode(node); } public static SchematicNode getNodeFromPath(SteamwarUser user, String s) { @@ -368,12 +244,7 @@ public class SchematicNode { } public static Integer countNodes() { - return countNodes.select(rs -> { - if (rs.next()) { - return rs.getInt("count"); - } - return 0; - }); + return Provider.impl.countNodes(); } public int getId() { @@ -502,33 +373,18 @@ public class SchematicNode { } private void updateDB() { - updateDB.update(name, owner, parent, item, type, rank, id); + Provider.impl.updateSchematicNode(this); this.lastUpdate = Timestamp.from(Instant.now()); this.brCache.clear(); TAB_CACHE.clear(); } public void delete() { - deleteNode.update(id); + Provider.impl.deleteSchematicNode(this); } public InputStream schemData() throws IOException { - try { - return selSchemData.select(rs -> { - rs.next(); - Blob schemData = rs.getBlob("NodeData"); - if(schemData == null) { - throw new SecurityException("SchemData is null"); - } - try { - return new GZIPInputStream(schemData.getBinaryStream()); - } catch (IOException e) { - throw new SecurityException("SchemData is wrong", e); - } - }, id); - } catch (Exception e) { - throw new IOException(e); - } + return Provider.impl.getSchematicData(this); } public Clipboard load() throws IOException, NoClipboardException { @@ -562,7 +418,7 @@ public class SchematicNode { } private void updateDatabase(InputStream blob, boolean newFormat) { - updateDatabase.update(blob, newFormat, id); + Provider.impl.saveSchematicNode(this, blob, newFormat); schemFormat = newFormat; } diff --git a/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java b/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java new file mode 100644 index 0000000..722a1a0 --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/sql/StandaloneProvider.java @@ -0,0 +1,390 @@ +/* + * 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 com.google.common.collect.Maps; +import de.steamwar.core.WorldEditWrapper; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.*; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.zip.GZIPInputStream; + +public class StandaloneProvider implements Provider { + public StandaloneProvider() { + nodesToPath.put(-1, schematicDir.toPath()); + } + + @Override + public BauweltMember getBauMember(int ownerID, int memberID) { + OfflinePlayer player = Bukkit.getOfflinePlayer(SteamwarUser.get(memberID).getUUID()); + return new BauweltMember(ownerID, memberID, player.isOp(), player.isOp()); + } + + @Override + public List getMembers(int bauweltID) { + return Bukkit.getOnlinePlayers().stream().map(player -> getBauMember(bauweltID, SteamwarUser.get(player.getUniqueId()).getId())).collect(Collectors.toList()); + } + + @Override + public List getLastDeclinedOfNode(int node) { + return new ArrayList<>(); + } + + @Override + public List getLastDelined(int schemOwner) { + return new ArrayList<>(); + } + + @Override + public int getElo(int userId, String gameMode) { + return 1000; + } + + @Override + public void setElo(int userId, String gameMode, int elo) {} + + @Override + public Event getEvent(int eventID) { + return new Event(eventID, "DummyEvent", Timestamp.from(Instant.now()), Timestamp.from(Instant.now()), 6, false, false); + } + + @Override + public EventFight getEventFight(int fightID) { + return new EventFight(0, fightID, 0, 0, 0, 0); + } + + @Override + public void setEventFightResult(EventFight fight, int winner) {} + + @Override + public void setEventFightFightID(EventFight fight, int fightID) {} + + @Override + public int createFight(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition, Timestamp replayLock) { + return 0; + } + + @Override + public void getReplay(int fightID, Consumer reader) {} + + @Override + public void setReplay(int fightID, InputStream data) {} + + @Override + public void createFightPlayer(int fightID, int userID, boolean blue, String kit, int kills, boolean isOut) {} + + @Override + public void createDownloadLink(int nodeId, String hash) {} + + @Override + public NodeMember getNodeMember(int node, int member) { + return null; + } + + @Override + public Set getNodeMembers(int node) { + return Collections.emptySet(); + } + + @Override + public Set getMemberSchematics(int member) { + return Collections.emptySet(); + } + + @Override + public void createNodeMember(int node, int member) {} + + @Override + public List getKits(int userID, String gamemode) { + return Collections.emptyList(); + } + + @Override + public PersonalKit getKit(int userID, String gamemode, String name) { + return null; + } + + @Override + public void updateKit(PersonalKit kit) {} + + @Override + public void deleteKit(PersonalKit kit) {} + + @Override + public PersonalKit getKitInUse(int userID, String gamemode) { + return null; + } + + @Override + public Punishment getPunishmentOfPlayer(int user, Punishment.PunishmentType type) { + return null; + } + + @Override + public Map getPunishmentsOfPlayer(int user) { + return Collections.emptyMap(); + } + + private int userId = 1; + private final Map usersByUUID = new HashMap<>(); + @Override + public SteamwarUser getUserByName(String userName) { + Player player = Bukkit.getPlayer(userName); + if(player == null) + return null; + return usersByUUID.computeIfAbsent(player.getUniqueId(), uuid -> new SteamwarUser(userId++, uuid, userName, UserGroup.Member, 0, false)); + } + + @Override + public SteamwarUser getUserByUUID(UUID uuid) { + return usersByUUID.computeIfAbsent(uuid, uuid1 -> new SteamwarUser(userId++, uuid1, Objects.requireNonNull(Objects.requireNonNull(Bukkit.getOfflinePlayer(uuid1)).getName()), UserGroup.Member, 0, false)); + } + + @Override + public SteamwarUser getUserByID(int id) { + return usersByUUID.values().stream().filter(user -> user.getId() == id).findAny().get(); + } + + @Override + public void logException(String server, String message, String stacktrace) {} + + @Override + public Team getTeam(int id) { + return new Team(0, "TEST", "TestAlliancePleaseIgnore", "c"); + } + + @Override + public List getTeamMembers(Team team) { + return Collections.emptyList(); + } + + private final Map> configs = new HashMap<>(); + @Override + public String getConfig(int player, String config) { + return configs.computeIfAbsent(player, player1 -> new HashMap<>()).get(config); + } + + @Override + public void updatePlayerConfig(int id, String config, String value) { + configs.computeIfAbsent(id, player -> new HashMap<>()).put(config, value); + } + + @Override + public void removePlayerConfig(int id, String config) { + configs.computeIfAbsent(id, player -> new HashMap<>()).remove(config); + } + + private int nodeId = 1; + private final File schematicDir = WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getWorkingDirectoryFile(WorldEditWrapper.getWorldEditPlugin().getWorldEdit().getConfiguration().saveDir); + private final Map nodeById = new HashMap<>(); + private final Map> nodesByParent = new HashMap<>(); + private final Map nodesToPath = new HashMap<>(); + + private List mapDir(Integer id) { + try (Stream stream = Files.list(id==null?schematicDir.toPath():nodesToPath.get(id))) { + List list = stream.map(path -> { + File file = path.toFile(); + SchematicNode node = new SchematicNode( + nodeId++, + 0, + file.isDirectory()?file.getName():file.getName().substring(file.getName().lastIndexOf(".")), + null, + "", + "normal", + file.isDirectory(), + 0, + Timestamp.from(Instant.now()), + file.getName().endsWith(".schem") + ); + nodesToPath.put(node.getId(), path); + nodeById.put(node.getId(), node); + return node; + }).collect(Collectors.toList()); + nodesByParent.putIfAbsent(id == null?-1:id, list); + return list; + } catch (IOException e) { + throw new SecurityException(e); + } + } + + @Override + public void createSchematicNode(int owner, String name, Integer parent, String type, String item) { + boolean isDir = type == null; + Path p = null; + try { + if(isDir) { + p = Files.createDirectory(new File(nodesToPath.get(parent == null?-1:parent).toFile(), name).toPath()); + } else { + p = Files.createFile(new File(nodesToPath.get(parent == null?-1:parent).toFile(), name + ".schem").toPath()); + } + } catch (IOException e) { + throw new SecurityException(e); + } + + File file = p.toFile(); + int id = nodeId++; + nodesToPath.put(id, p); + SchematicNode node = new SchematicNode( + nodeId++, + 0, + file.isDirectory()?file.getName():file.getName().substring(file.getName().lastIndexOf(".")), + null, + "", + "normal", + file.isDirectory(), + 0, + Timestamp.from(Instant.now()), + file.getName().endsWith(".schem") + ); + nodeById.put(id, node); + nodesByParent.get(parent == null?-1:parent).add(node); + } + + @Override + public SchematicNode getSchematicNode(int owner, String name, Integer parent) { + return nodesByParent.get(parent).stream().filter(node -> node.getName().equals(name)).findAny().orElse(null); + } + + @Override + public List getSchematicNodeInNode(Integer parent) { + return nodesByParent.computeIfAbsent(parent==null?-1:parent, integer -> mapDir(parent)); + } + + @Override + public List getSchematicDirectoryInNode(Integer parent) { + return getSchematicNodeInNode(parent).stream().filter(SchematicNode::isDir).collect(Collectors.toList()); + } + + @Override + public SchematicNode getSchematicDirectory(String name, Integer parent) { + return getSchematicDirectoryInNode(parent).stream().filter(node -> node.getName().equals(name)).findFirst().orElse(null); + } + + @Override + public SchematicNode getSchematicNode(String name, Integer parent) { + return getSchematicNodeInNode(parent).stream().filter(node -> name.equals(node.getName())).findFirst().orElse(null); + } + + @Override + public SchematicNode getSchematicNode(int id) { + return nodeById.getOrDefault(id, null); + } + + @Override + public List getAccessibleSchematicsOfTypeInParent(int ignored, String schemType, Integer parent) { + return getSchematicDirectoryInNode(parent).stream().filter(node -> node.getType().equals(schemType)).collect(Collectors.toList()); + } + + @Override + public List getAllAccessibleSchematicsOfType(int ignored, String schemType) { + return getAllSchematicsAccessibleByUser(ignored).stream().filter(node -> schemType.equals(node.getType())).collect(Collectors.toList()); + } + + @Override + public List getAllSchematicsOfType(int ignored, String schemType) { + return getAllAccessibleSchematicsOfType(ignored, schemType); + } + + @Override + public List getAllSchematicsOfType(String schemType) { + return getAllAccessibleSchematicsOfType(-1, schemType); + } + + @Override + public List getSchematicsAccessibleByUser(int ignored, Integer parent) { + return getSchematicNodeInNode(parent); + } + + @Override + public List getAllSchematicsAccessibleByUser(int user) { + return nodesByParent.values().stream().reduce((schematicNodes, schematicNodes2) -> { + schematicNodes.addAll(schematicNodes2); + return schematicNodes; + }).orElse(new ArrayList<>()); + } + + @Override + public List getAllParentsOfNode(int node) { + List allSchematicsAccessibleByUser = getAllSchematicsAccessibleByUser(node); + allSchematicsAccessibleByUser.remove(getSchematicNode(node)); + return allSchematicsAccessibleByUser; + } + + @Override + public Integer countNodes() { + return nodesByParent.values().stream().map(List::size).reduce((Integer::sum)).orElse(0); + } + + @Override + public void updateSchematicNode(SchematicNode node) { + try { + Path newPath = new File(nodesToPath.get(node.getParent() == null?-1:node.getParent()).toFile(), node.getName() + (node.getSchemFormat()?".schem":".schematic")).toPath(); + Files.move(nodesToPath.get(node.getId()), newPath); + nodesToPath.put(node.getId(), newPath); + } catch (IOException e) { + throw new SecurityException(e); + } + } + + @Override + public void deleteSchematicNode(SchematicNode node) { + try { + Files.deleteIfExists(nodesToPath.get(node.getId())); + nodeById.remove(node.getId()); + nodesByParent.get(node.getParent() == null?-1:node.getId()).remove(node); + nodesToPath.remove(node.getId()); + } catch (IOException e) { + throw new SecurityException(e); + } + } + + @Override + public InputStream getSchematicData(SchematicNode node) throws IOException { + return new GZIPInputStream(Files.newInputStream(nodesToPath.get(node.getId()))); + } + + @Override + public void saveSchematicNode(SchematicNode node, InputStream blob, boolean newFormat) { + try (FileOutputStream stream = new FileOutputStream(nodesToPath.get(node.getId()).toFile())) { + byte[] bucket = new byte[1024]; + int nReadBytes; + + while((nReadBytes = blob.read(bucket, 0, bucket.length)) !=-1){ + stream.write(bucket, 0, nReadBytes); + } + + if(newFormat != node.getSchemFormat()) { + nodesToPath.get(node.getId()).toFile().renameTo(new File(nodesToPath.get(node.getId()).toFile().getParentFile(), node.getName() + "." + (newFormat?".schem":"schematic"))); + } + } catch (IOException e) { + throw new SecurityException(e); + } + } +} diff --git a/SpigotCore_Main/src/de/steamwar/sql/Statement.java b/SpigotCore_Main/src/de/steamwar/sql/Statement.java new file mode 100644 index 0000000..13eec67 --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/sql/Statement.java @@ -0,0 +1,155 @@ +/* + 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 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException; +import de.steamwar.core.Core; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; + +public class Statement { + + private static final String URL; + private static final String USER; + private static final String PASSWORD; + + private static Connection con; + + private static final List statements = new ArrayList<>(); + + static { + File file = Core.sqlConfig(); + YamlConfiguration config = YamlConfiguration.loadConfiguration(file); + + if(!file.exists()) + throw new SecurityException("SQL-ConfigFile not found!"); + + URL = "jdbc:mysql://" + config.getString("HOST") + ":" + config.getString("PORT") + "/" + config.getString("DATABASE"); + USER = config.getString("USER"); + PASSWORD = config.getString("PASSWORD"); + + Statement.connect(); + } + + private static void connect() { + try { + con = DriverManager.getConnection(URL + "?useServerPrepStmts=true", USER, PASSWORD); + } catch (SQLException e) { + throw new SecurityException("Could not start SQL connection", e); + } + } + + public static void close() { + for (Statement statement : statements) { + if (statement.st != null) { + try { + statement.st.close(); + } catch (SQLException e) { + Core.getInstance().getLogger().log(Level.INFO, "Could not close statement", e); + } + } + } + + try { + con.close(); + } catch (SQLException e) { + Core.getInstance().getLogger().log(Level.INFO, "Could not close SQL connection", e); + } + } + + private static void reset() { + close(); + connect(); + } + + public static boolean connectionStable() { + try { + return !con.isClosed(); + } catch (SQLException e) { + return false; + } + } + + private final String sql; + private PreparedStatement st; + + public Statement(String sql) { + this.sql = sql; + statements.add(this); + } + + public T select(ResultSetUser user, Object... objects) { + return prepare(() -> { + ResultSet rs = getSt().executeQuery(); + T result = user.use(rs); + rs.close(); + return result; + }, objects); + } + + public void update(Object... objects) { + prepare(getSt()::executeUpdate, objects); + } + + private synchronized T prepare(SQLRunnable runnable, Object... objects) { + try { + try { + setObjects(objects); + return runnable.run(); + } catch (CommunicationsException e) { + reset(); + setObjects(objects); + return runnable.run(); + } + } catch (SQLException e) { + throw new SecurityException("Could not execute SQL statement", e); + } + } + + private PreparedStatement getSt() { + if(st == null) { + try { + st = con.prepareStatement(sql); + } catch (SQLException e) { + throw new SecurityException("Could not prepare statement", e); + } + } + return st; + } + + private void setObjects(Object... objects) throws SQLException { + for (int i = 0; i < objects.length; i++) { + getSt().setObject(i + 1, objects[i]); + } + } + + public interface ResultSetUser { + T use(ResultSet rs) throws SQLException; + } + + private interface SQLRunnable { + T run() throws SQLException; + } +} diff --git a/SpigotCore_Main/src/de/steamwar/sql/SteamwarUser.java b/SpigotCore_Main/src/de/steamwar/sql/SteamwarUser.java index 115367f..69ea9d5 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/SteamwarUser.java +++ b/SpigotCore_Main/src/de/steamwar/sql/SteamwarUser.java @@ -23,17 +23,12 @@ import de.steamwar.core.Core; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.UUID; public class SteamwarUser { - private static final SQL.Statement getId = new SQL.Statement("SELECT * FROM UserData WHERE id = ?"); - private static final SQL.Statement getUUID = new SQL.Statement("SELECT * FROM UserData WHERE UUID = ?"); - private static final SQL.Statement getName = new SQL.Statement("SELECT * FROM UserData WHERE lower(UserName) = ?"); private static final Map byUUID = new HashMap<>(); private static final Map byName = new HashMap<>(); @@ -54,21 +49,17 @@ public class SteamwarUser { private final int team; private final boolean bedrock; - private SteamwarUser(ResultSet rs){ - try { - id = rs.getInt("id"); - uuid = java.util.UUID.fromString(rs.getString("UUID")); - userName = rs.getString("UserName"); - userGroup = UserGroup.getUsergroup(rs.getString("UserGroup")); - team = rs.getInt("Team"); - bedrock = rs.getBoolean("Bedrock"); + public SteamwarUser(int id, UUID uuid, String userName, UserGroup userGroup, int team, boolean bedrock) { + this.id = id; + this.uuid = uuid; + this.userName = userName; + this.userGroup = userGroup; + this.team = team; + this.bedrock = bedrock; - byUUID.put(uuid, this); - byName.put(userName.toLowerCase(), this); - byId.put(id, this); - } catch (SQLException e) { - throw new SecurityException("Could not instance User", e); - } + byUUID.put(uuid, this); + byName.put(userName.toLowerCase(), this); + byId.put(id, this); } public int getId() { @@ -98,31 +89,21 @@ public class SteamwarUser { public static SteamwarUser get(String userName){ SteamwarUser user = byName.get(userName.toLowerCase()); if(user == null) - user = getName.select(rs -> { - if(rs.next()) - return new SteamwarUser(rs); - return null; - }, userName.toLowerCase()); + user = Provider.impl.getUserByName(userName); return user; } public static SteamwarUser get(UUID uuid){ SteamwarUser user = byUUID.get(uuid); if(user == null) - user = getUUID.select(rs -> { - rs.next(); - return new SteamwarUser(rs); - }, uuid.toString()); + user = Provider.impl.getUserByUUID(uuid); return user; } public static SteamwarUser get(int id) { SteamwarUser user = byId.get(id); if(user == null) - user = getId.select(rs -> { - rs.next(); - return new SteamwarUser(rs); - }, id); + user = Provider.impl.getUserByID(id); return user; } diff --git a/SpigotCore_Main/src/de/steamwar/sql/Team.java b/SpigotCore_Main/src/de/steamwar/sql/Team.java index 5f45e7c..a432ba8 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/Team.java +++ b/SpigotCore_Main/src/de/steamwar/sql/Team.java @@ -19,16 +19,10 @@ package de.steamwar.sql; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; import java.util.List; public class Team { - private static final SQL.Statement get = new SQL.Statement("SELECT * FROM Team WHERE TeamID = ?"); - private static final SQL.Statement getMembers = new SQL.Statement("SELECT id FROM UserData WHERE Team = ?"); - private final int teamId; private final String teamKuerzel; private final String teamName; @@ -36,24 +30,17 @@ public class Team { private static final Team pub = new Team(0, "PUB", "Öffentlich", "8"); - private Team(int teamId, String teamKuerzel, String teamName, String teamColor){ + public Team(int teamId, String teamKuerzel, String teamName, String teamColor) { this.teamId = teamId; this.teamKuerzel = teamKuerzel; this.teamName = teamName; this.teamColor = teamColor; } - private Team(ResultSet rs) throws SQLException { - this(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getString("TeamColor")); - } - public static Team get(int id){ if(id == 0) return pub; - return get.select(rs -> { - rs.next(); - return new Team(rs); - }, id); + return Provider.impl.getTeam(id); } public int getTeamId() { @@ -73,11 +60,6 @@ public class Team { } public List getMembers(){ - return getMembers.select(rs -> { - List members = new ArrayList<>(); - while(rs.next()) - members.add(rs.getInt("id")); - return members; - }, teamId); + return Provider.impl.getTeamMembers(this); } } diff --git a/SpigotCore_Main/src/de/steamwar/sql/TeamTeilnahme.java b/SpigotCore_Main/src/de/steamwar/sql/TeamTeilnahme.java deleted file mode 100644 index cd350d0..0000000 --- a/SpigotCore_Main/src/de/steamwar/sql/TeamTeilnahme.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 java.sql.ResultSet; -import java.util.HashSet; -import java.util.Set; - -public class TeamTeilnahme { - private TeamTeilnahme(){} - - private static final SQL.Statement byEventTeam = new SQL.Statement("SELECT * FROM TeamTeilnahme WHERE TeamID = ? AND EventID = ?"); - private static final SQL.Statement byEvent = new SQL.Statement("SELECT * FROM TeamTeilnahme WHERE EventID = ?"); - private static final SQL.Statement byTeam = new SQL.Statement("SELECT * FROM TeamTeilnahme WHERE TeamID = ?"); - - public static boolean nimmtTeil(int teamID, int eventID){ - return byEventTeam.select(ResultSet::next, teamID, eventID); - } - - public static Set getTeams(int eventID){ - return byEvent.select(rs -> { - Set teams = new HashSet<>(); - while(rs.next()) - teams.add(Team.get(rs.getInt("TeamID"))); - return teams; - }, eventID); - } - - public static Set getEvents(int teamID){ - return byTeam.select(rs -> { - Set events = new HashSet<>(); - while(rs.next()) - events.add(Event.get(rs.getInt("EventID"))); - return events; - }, teamID); - } -} diff --git a/SpigotCore_Main/src/de/steamwar/sql/UserConfig.java b/SpigotCore_Main/src/de/steamwar/sql/UserConfig.java index 62a6d08..8547b3b 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/UserConfig.java +++ b/SpigotCore_Main/src/de/steamwar/sql/UserConfig.java @@ -24,20 +24,12 @@ import java.util.UUID; public class UserConfig { private UserConfig() {} - private static final SQL.Statement get = new SQL.Statement("SELECT Value FROM UserConfig WHERE User = ? AND Config = ?"); - private static final SQL.Statement set = new SQL.Statement("INSERT INTO UserConfig (User, Config, Value) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Value = VALUES(Value)"); - private static final SQL.Statement delete = new SQL.Statement("DELETE FROM UserConfig WHERE User = ? AND Config = ?"); - public static String getConfig(UUID player, String config) { return getConfig(SteamwarUser.get(player).getId(), config); } public static String getConfig(int player, String config) { - return get.select(rs -> { - if(rs.next()) - return rs.getString("Value"); - return null; - }, player, config); + return Provider.impl.getConfig(player, config); } public static void updatePlayerConfig(UUID uuid, String config, String value) { @@ -49,7 +41,7 @@ public class UserConfig { removePlayerConfig(id, config); return; } - set.update(id, config, value); + Provider.impl.updatePlayerConfig(id, config, value); } public static void removePlayerConfig(UUID uuid, String config) { @@ -57,6 +49,6 @@ public class UserConfig { } public static void removePlayerConfig(int id, String config) { - delete.update(id, config); + Provider.impl.removePlayerConfig(id, config); } }