From c1e175c3e84280c160ae5c7f84e44805f159bbf3 Mon Sep 17 00:00:00 2001 From: Lixfel Date: Thu, 8 Sep 2022 10:42:57 +0200 Subject: [PATCH] WIP current state --- src/de/steamwar/sql/BauweltMember.java | 79 +++++++++ src/de/steamwar/sql/Event.java | 72 +++++++++ src/de/steamwar/sql/EventFight.java | 72 +++++++++ src/de/steamwar/sql/Field.java | 34 ---- src/de/steamwar/sql/Fight.java | 61 +++++++ src/de/steamwar/sql/FightPlayer.java | 49 ++++++ src/de/steamwar/sql/NoClipboardException.java | 23 +++ src/de/steamwar/sql/NodeMember.java | 69 ++++++++ src/de/steamwar/sql/Replay.java | 73 +++++++++ src/de/steamwar/sql/SQLConfig.java | 34 ---- src/de/steamwar/sql/SQLWrapper.java | 31 ++++ src/de/steamwar/sql/SchematicType.java | 116 +++++++++++++ src/de/steamwar/sql/SteamwarUser.java | 153 ++++++++++++++++++ src/de/steamwar/sql/UserGroup.java | 45 ++++++ src/de/steamwar/sql/internal/Field.java | 34 ++++ src/de/steamwar/sql/internal/SQLConfig.java | 34 ++++ .../sql/{ => internal}/SelectStatement.java | 26 +-- .../sql/{ => internal}/SqlTypeMapper.java | 58 ++++--- .../sql/{ => internal}/Statement.java | 54 ++++--- src/de/steamwar/sql/{ => internal}/Table.java | 42 +++-- 20 files changed, 1018 insertions(+), 141 deletions(-) create mode 100644 src/de/steamwar/sql/BauweltMember.java create mode 100644 src/de/steamwar/sql/Event.java create mode 100644 src/de/steamwar/sql/EventFight.java delete mode 100644 src/de/steamwar/sql/Field.java create mode 100644 src/de/steamwar/sql/Fight.java create mode 100644 src/de/steamwar/sql/FightPlayer.java create mode 100644 src/de/steamwar/sql/NoClipboardException.java create mode 100644 src/de/steamwar/sql/NodeMember.java create mode 100644 src/de/steamwar/sql/Replay.java delete mode 100644 src/de/steamwar/sql/SQLConfig.java create mode 100644 src/de/steamwar/sql/SQLWrapper.java create mode 100644 src/de/steamwar/sql/SchematicType.java create mode 100644 src/de/steamwar/sql/SteamwarUser.java create mode 100644 src/de/steamwar/sql/UserGroup.java create mode 100644 src/de/steamwar/sql/internal/Field.java create mode 100644 src/de/steamwar/sql/internal/SQLConfig.java rename src/de/steamwar/sql/{ => internal}/SelectStatement.java (66%) rename src/de/steamwar/sql/{ => internal}/SqlTypeMapper.java (55%) rename src/de/steamwar/sql/{ => internal}/Statement.java (82%) rename src/de/steamwar/sql/{ => internal}/Table.java (79%) diff --git a/src/de/steamwar/sql/BauweltMember.java b/src/de/steamwar/sql/BauweltMember.java new file mode 100644 index 0000000..aa3ed93 --- /dev/null +++ b/src/de/steamwar/sql/BauweltMember.java @@ -0,0 +1,79 @@ +/* + 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 de.steamwar.sql.internal.Field; +import de.steamwar.sql.internal.SelectStatement; +import de.steamwar.sql.internal.Table; +import lombok.Getter; + +import java.util.*; + +public class BauweltMember { + private static final Map memberCache = new HashMap<>(); + + public static void clear() { + memberCache.clear(); + } + + private static final Table table = new Table<>(BauweltMember.class); + private static final SelectStatement getMember = table.select(Table.PRIMARY); + private static final SelectStatement getMembers = table.selectFields("BauweltID"); + + public static BauweltMember getBauMember(UUID ownerID, UUID memberID){ + return getBauMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId()); + } + + public static BauweltMember getBauMember(int ownerID, int memberID){ + BauweltMember member = memberCache.get(memberID); + if(member != null) + return member; + return getMember.select(ownerID, memberID); + } + + public static List getMembers(UUID bauweltID){ + return getMembers(SteamwarUser.get(bauweltID).getId()); + } + + public static List getMembers(int bauweltID){ + return getMembers.listSelect(bauweltID); + } + + @Getter + @Field(keys = {Table.PRIMARY}) + private final int bauweltID; + @Getter + @Field(keys = {Table.PRIMARY}) + private final int memberID; + @Getter + @Field + private final boolean worldEdit; + @Getter + @Field + 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.put(memberID, this); + } +} diff --git a/src/de/steamwar/sql/Event.java b/src/de/steamwar/sql/Event.java new file mode 100644 index 0000000..b3f8f8c --- /dev/null +++ b/src/de/steamwar/sql/Event.java @@ -0,0 +1,72 @@ +/* + 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 de.steamwar.sql.internal.Field; +import de.steamwar.sql.internal.SelectStatement; +import de.steamwar.sql.internal.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.sql.Timestamp; + +@AllArgsConstructor +public class Event { + + private static final Table table = new Table<>(Event.class); + private static final SelectStatement byId = table.select(Table.PRIMARY); + + public static Event get(int eventID){ + return byId.select(eventID); + } + + @Getter + @Field(keys = {Table.PRIMARY}, autoincrement = true) + private final int eventID; + @Getter + @Field(keys = {"eventName"}) + private final String eventName; + @Getter + @Field + private final Timestamp deadline; + @Getter + @Field + private final Timestamp start; + @Getter + @Field + private final Timestamp end; + @Getter + @Field + private final int maximumTeamMembers; + @Getter + @Field(nullable = true) + private final SchematicType schematicType; + @Field + private final boolean publicSchemsOnly; + @Field + private final boolean spectateSystem; + + public boolean publicSchemsOnly() { + return publicSchemsOnly; + } + public boolean spectateSystem(){ + return spectateSystem; + } +} diff --git a/src/de/steamwar/sql/EventFight.java b/src/de/steamwar/sql/EventFight.java new file mode 100644 index 0000000..60e4831 --- /dev/null +++ b/src/de/steamwar/sql/EventFight.java @@ -0,0 +1,72 @@ +/* + 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 de.steamwar.sql.internal.Field; +import de.steamwar.sql.internal.SelectStatement; +import de.steamwar.sql.internal.Statement; +import de.steamwar.sql.internal.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public class EventFight { + + private static final Table table = new Table<>(EventFight.class); + private static final SelectStatement byId = table.select(Table.PRIMARY); + private static final Statement setResult = table.update(Table.PRIMARY, "Ergebnis"); + private static final Statement setFight = table.update(Table.PRIMARY, "Fight"); + + public static EventFight get(int fightID) { + return byId.select(fightID); + } + + @Getter + @Field + private final int eventID; + @Getter + @Field(keys = {Table.PRIMARY}, autoincrement = true) + private final int fightID; + @Getter + @Field + private final int teamBlue; + @Getter + @Field + private final int teamRed; + @Getter + @Field + private final int kampfleiter; + @Getter + @Field(def = "0") + private int ergebnis; + @Field(nullable = true) + private int fight; + + public void setErgebnis(int winner) { + this.ergebnis = winner; + setResult.update(winner, fightID); + } + + public void setFight(int fight) { + //Fight.FightID, not EventFight.FightID + this.fight = fight; + setFight.update(fight, fightID); + } +} diff --git a/src/de/steamwar/sql/Field.java b/src/de/steamwar/sql/Field.java deleted file mode 100644 index 656fdd9..0000000 --- a/src/de/steamwar/sql/Field.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.FIELD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Field { - String[] keys() default {}; - String def() default ""; - boolean nullable() default false; - boolean autoincrement() default false; -} diff --git a/src/de/steamwar/sql/Fight.java b/src/de/steamwar/sql/Fight.java new file mode 100644 index 0000000..0f9eae6 --- /dev/null +++ b/src/de/steamwar/sql/Fight.java @@ -0,0 +1,61 @@ +/* + 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 de.steamwar.sql.internal.Field; +import de.steamwar.sql.internal.Statement; +import de.steamwar.sql.internal.Table; +import lombok.AllArgsConstructor; + +import java.sql.Timestamp; + +@AllArgsConstructor +public class Fight { + + private static final Table table = new Table<>(Fight.class); + private static final Statement insert = table.insertFields(true, "GameMode", "Server", "StartTime", "Duration", "BlueLeader", "RedLeader", "BlueSchem", "RedSchem", "Win", "WinCondition"); + + @Field(keys = {Table.PRIMARY}, autoincrement = true) + private final int fightID; + @Field + private final String gameMode; + @Field + private final String server; + @Field + private final Timestamp startTime; + @Field + private final int duration; + @Field + private final int blueLeader; + @Field + private final int redLeader; + @Field(nullable = true) + private final Integer blueSchem; + @Field(nullable = true) + private final Integer redSchem; + @Field + private final int win; + @Field + private final String wincondition; + + 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 insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition); + } +} diff --git a/src/de/steamwar/sql/FightPlayer.java b/src/de/steamwar/sql/FightPlayer.java new file mode 100644 index 0000000..cc529b8 --- /dev/null +++ b/src/de/steamwar/sql/FightPlayer.java @@ -0,0 +1,49 @@ +/* + 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 de.steamwar.sql.internal.Field; +import de.steamwar.sql.internal.Statement; +import de.steamwar.sql.internal.Table; +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public class FightPlayer { + + private static final Table table = new Table<>(FightPlayer.class); + private static final Statement create = table.insertAll(); + + @Field(keys = {Table.PRIMARY}) + private final int fightID; + @Field(keys = {Table.PRIMARY}) + private final int userID; + @Field + private final int team; + @Field + private final String kit; + @Field + private final int kills; + @Field + private final boolean isOut; + + 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); + } +} diff --git a/src/de/steamwar/sql/NoClipboardException.java b/src/de/steamwar/sql/NoClipboardException.java new file mode 100644 index 0000000..9743348 --- /dev/null +++ b/src/de/steamwar/sql/NoClipboardException.java @@ -0,0 +1,23 @@ +/* + 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 NoClipboardException extends RuntimeException { +} diff --git a/src/de/steamwar/sql/NodeMember.java b/src/de/steamwar/sql/NodeMember.java new file mode 100644 index 0000000..f0de53c --- /dev/null +++ b/src/de/steamwar/sql/NodeMember.java @@ -0,0 +1,69 @@ +/* + * 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 de.steamwar.sql.internal.Field; +import de.steamwar.sql.internal.SelectStatement; +import de.steamwar.sql.internal.Statement; +import de.steamwar.sql.internal.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.HashSet; +import java.util.Set; + +@AllArgsConstructor +public class NodeMember { + + private static final Table table = new Table<>(NodeMember.class); + private static final SelectStatement getNodeMember = table.select(Table.PRIMARY); + private static final SelectStatement getNodeMembers = table.selectFields("Node"); + private static final SelectStatement getSchematics = table.selectFields("Member"); + private static final Statement create = table.insertAll(); + private static final Statement delete = table.delete(Table.PRIMARY); + + @Getter + @Field(keys = {Table.PRIMARY}) + private final int node; + @Getter + @Field(keys = {Table.PRIMARY}) + private final int member; + + public void delete() { + delete.update(node, member); + } + + public static NodeMember createNodeMember(int node, int member) { + create.update(node, member); + return new NodeMember(node, member); + } + + public static NodeMember getNodeMember(int node, int member) { + return getNodeMember.select(node, member); + } + + public static Set getNodeMembers(int node) { + return new HashSet<>(getNodeMembers.listSelect(node)); + } + + public static Set getSchematics(int member) { + return new HashSet<>(getSchematics.listSelect(member)); + } +} diff --git a/src/de/steamwar/sql/Replay.java b/src/de/steamwar/sql/Replay.java new file mode 100644 index 0000000..90d2b34 --- /dev/null +++ b/src/de/steamwar/sql/Replay.java @@ -0,0 +1,73 @@ +/* + * 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.sql.internal.*; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Files; +import java.sql.SQLException; + +@AllArgsConstructor +public class Replay { + + static { + new SqlTypeMapper<>(File.class, "BLOB", (rs, identifier) -> { + try { + File file = File.createTempFile("replay", "replay"); + file.deleteOnExit(); + Files.copy(rs.getBinaryStream(identifier), file.toPath()); + return file; + } catch (IOException e) { + throw new SQLException(e); + } + }, (st, index, value) -> { + try { + st.setBinaryStream(index, new FileInputStream(value)); + } catch (FileNotFoundException e) { + throw new SQLException(e); + } + }); + } + + private static final Table table = new Table<>(Replay.class); + private static final SelectStatement get = table.select(Table.PRIMARY); + + public static final Statement insert = table.insertAll(); + + public static Replay get(int fightID) { + return get.select(fightID); + } + + public static void save(int fightID, File file) { + insert.update(fightID, file); + } + + @Field(keys = {Table.PRIMARY}) + private final int fightID; + @Getter + @Field + private final File replay; +} diff --git a/src/de/steamwar/sql/SQLConfig.java b/src/de/steamwar/sql/SQLConfig.java deleted file mode 100644 index 2420a0e..0000000 --- a/src/de/steamwar/sql/SQLConfig.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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.ImplementationProvider; - -import java.util.logging.Logger; - -public interface SQLConfig { - SQLConfig impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLConfigImpl"); - - Logger getLogger(); - - int maxConnections(); - - -} diff --git a/src/de/steamwar/sql/SQLWrapper.java b/src/de/steamwar/sql/SQLWrapper.java new file mode 100644 index 0000000..81abe61 --- /dev/null +++ b/src/de/steamwar/sql/SQLWrapper.java @@ -0,0 +1,31 @@ +/* + * 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.ImplementationProvider; + +import java.util.List; +import java.util.Map; + +public interface SQLWrapper { + SQLWrapper impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLWrapperImpl"); + + void loadSchemTypes(List tmpTypes, Map tmpFromDB); +} diff --git a/src/de/steamwar/sql/SchematicType.java b/src/de/steamwar/sql/SchematicType.java new file mode 100644 index 0000000..56c46ad --- /dev/null +++ b/src/de/steamwar/sql/SchematicType.java @@ -0,0 +1,116 @@ +/* + 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 de.steamwar.sql.internal.SqlTypeMapper; + +import java.util.*; + +public class SchematicType { + + public static final SchematicType Normal = new SchematicType("Normal", "", Type.NORMAL, null, "STONE_BUTTON"); + + private static final Map fromDB; + private static final List types; + + static { + List tmpTypes = new LinkedList<>(); + Map tmpFromDB = new HashMap<>(); + + tmpTypes.add(Normal); + tmpFromDB.put(Normal.name().toLowerCase(), Normal); + + SQLWrapper.impl.loadSchemTypes(tmpTypes, tmpFromDB); + + fromDB = Collections.unmodifiableMap(tmpFromDB); + types = Collections.unmodifiableList(tmpTypes); + } + + static { + new SqlTypeMapper<>(SchematicType.class, "VARCHAR(16)", (rs, identifier) -> { + String t = rs.getString(identifier); + return t != null ? fromDB.get(t) : null; + }, (st, index, value) -> st.setString(index, value.toDB())); + } + + private final String name; + private final String kuerzel; + private final Type type; + private final SchematicType checkType; + private final String material; + + SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material){ + this.name = name; + this.kuerzel = kuerzel; + this.type = type; + this.checkType = checkType; + this.material = material; + } + + public boolean isAssignable(){ + return type == Type.NORMAL || (type == Type.FIGHT_TYPE && checkType != null); + } + + public SchematicType checkType(){ + return checkType; + } + + public boolean check(){ + return type == Type.CHECK_TYPE; + } + + public boolean fightType(){ + return type == Type.FIGHT_TYPE; + } + + public boolean writeable(){ + return type == Type.NORMAL; + } + + public String name(){ + return name; + } + + public String getKuerzel() { + return kuerzel; + } + + public String getMaterial() { + return material; + } + + public String toDB(){ + return name.toLowerCase(); + } + + public static SchematicType fromDB(String input){ + return fromDB.getOrDefault(input.toLowerCase(), null); + } + + public static List values(){ + return types; + } + + enum Type{ + NORMAL, + CHECK_TYPE, + FIGHT_TYPE + } +} diff --git a/src/de/steamwar/sql/SteamwarUser.java b/src/de/steamwar/sql/SteamwarUser.java new file mode 100644 index 0000000..7245db7 --- /dev/null +++ b/src/de/steamwar/sql/SteamwarUser.java @@ -0,0 +1,153 @@ +/* + * 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.sql.internal.*; +import lombok.Getter; + +import java.util.*; + +public class SteamwarUser { + + static { + new SqlTypeMapper<>(UUID.class, "CHAR(36)", (rs, identifier) -> UUID.fromString(rs.getString(identifier)), (st, index, value) -> st.setString(index, value.toString())); + new SqlTypeMapper<>(Locale.class, "VARCHAR(32)", (rs, identifier) -> { + String l = rs.getString(identifier); + return l != null ? Locale.forLanguageTag(l) : null; + }, (st, index, value) -> st.setString(index, value.toLanguageTag())); + SqlTypeMapper.nameEnumMapper(UserGroup.class); + new SqlTypeMapper<>(SteamwarUser.class, null, (rs, identifier) -> { throw new SecurityException("SteamwarUser cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.id)); + } + + private static final Table table = new Table<>(SteamwarUser.class, "UserData"); + private static final Statement insert = table.insertFields("UUID", "UserName"); + private static final SelectStatement byID = table.selectFields("id"); + private static final SelectStatement byUUID = table.selectFields("UUID"); + private static final SelectStatement byName = table.selectFields("UserName"); + private static final SelectStatement byDiscord = table.selectFields("DiscordId"); + private static final SelectStatement getServerTeam = new SelectStatement<>(table, "SELECT * FROM UserData WHERE UserGroup != 'Member' AND UserGroup != 'YouTuber'"); + private static final Statement updateName = table.update(Table.PRIMARY, "UserName"); + private static final Statement updateLocale = table.update(Table.PRIMARY, "Locale", "ManualLocale"); + private static final Statement updateTeam = table.update(Table.PRIMARY, "Team"); + private static final Statement updateLeader = table.update(Table.PRIMARY, "Leader"); + private static final Statement updateDiscord = table.update(Table.PRIMARY, "DiscordId"); + + private static final Map usersById = new HashMap<>(); + private static final Map usersByUUID = new HashMap<>(); + private static final Map usersByName = new HashMap<>(); + private static final Map usersByDiscord = new HashMap<>(); + public static void clear() { + usersById.clear(); + usersByName.clear(); + usersByUUID.clear(); + usersByDiscord.clear(); + } + + public static void invalidate(int userId) { + SteamwarUser user = usersById.remove(userId); + if (user == null) + return; + usersByName.remove(user.getUserName()); + usersByUUID.remove(user.getUUID()); + } + + @Getter + @Field(keys = {Table.PRIMARY}, autoincrement = true) + private final int id; + @Field(keys = {"uuid"}) + private final UUID uuid; + @Getter + @Field + private String userName; + @Getter + @Field(def = "'Member'") + private final UserGroup userGroup; + @Getter + @Field(def = "0") + private int team; + @Field(def = "0") + private boolean leader; + @Field(nullable = true) + private Locale locale; + @Field(def = "0") + private boolean manualLocale; + @Field(keys = {"discordId"}, nullable = true) + private Long discordId; + + public SteamwarUser(int id, UUID uuid, String userName, UserGroup userGroup, int team, boolean leader, Locale locale, boolean manualLocale, Long discordId) { + this.id = id; + this.uuid = uuid; + this.userName = userName; + this.userGroup = userGroup; + this.team = team; + this.leader = leader; + this.locale = locale; + this.manualLocale = manualLocale; + this.discordId = discordId != 0 ? discordId : null; + + usersById.put(id, this); + usersByName.put(userName.toLowerCase(), this); + usersByUUID.put(uuid, this); + if (this.discordId != null) { + usersByDiscord.put(discordId, this); + } + } + + public UUID getUUID() { + return uuid; + } + + public Locale getLocale() { + if(locale != null) + return locale; + return Locale.getDefault(); //TODO test correct locale on join (z.B. FightSystem Hotbarkit) + } + + public static SteamwarUser get(String userName){ + SteamwarUser user = usersByName.get(userName.toLowerCase()); + if(user != null) + return user; + return byName.select(userName); + } + + public static SteamwarUser get(UUID uuid){ + SteamwarUser user = usersByUUID.get(uuid); + if(user != null) + return user; + return byUUID.select(uuid); + } + + public static SteamwarUser get(int id) { + SteamwarUser user = usersById.get(id); + if(user != null) + return user; + return byID.select(id); + } + + public static SteamwarUser get(Long discordId) { + if(usersByDiscord.containsKey(discordId)) + return usersByDiscord.get(discordId); + return byDiscord.select(discordId); + } + + public static List getServerTeam() { + return getServerTeam.listSelect(); + } +} diff --git a/src/de/steamwar/sql/UserGroup.java b/src/de/steamwar/sql/UserGroup.java new file mode 100644 index 0000000..cef4fee --- /dev/null +++ b/src/de/steamwar/sql/UserGroup.java @@ -0,0 +1,45 @@ +/* + 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 lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +public enum UserGroup { + Admin("§4", "§e", true, true, true), + Developer("§3", "§f", true, true, true), + Moderator("§c", "§f", true, true, true), + Supporter("§9", "§f", false, true, true), + Builder("§2", "§f", false, true, false), + YouTuber("§5", "§f", false, false, false), + Member("§7", "§7", false, false, false); + + @Getter + private final String colorCode; + @Getter + private final String chatColorCode; + @Getter + private final boolean adminGroup; + @Getter + private final boolean teamGroup; + @Getter + private final boolean checkSchematics; +} \ No newline at end of file diff --git a/src/de/steamwar/sql/internal/Field.java b/src/de/steamwar/sql/internal/Field.java new file mode 100644 index 0000000..90bfa1d --- /dev/null +++ b/src/de/steamwar/sql/internal/Field.java @@ -0,0 +1,34 @@ +/* + * 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.internal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Field { + String[] keys() default {}; + String def() default ""; + boolean nullable() default false; + boolean autoincrement() default false; +} diff --git a/src/de/steamwar/sql/internal/SQLConfig.java b/src/de/steamwar/sql/internal/SQLConfig.java new file mode 100644 index 0000000..3153ecb --- /dev/null +++ b/src/de/steamwar/sql/internal/SQLConfig.java @@ -0,0 +1,34 @@ +/* + * 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.internal; + +import de.steamwar.ImplementationProvider; + +import java.util.logging.Logger; + +public interface SQLConfig { + SQLConfig impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLConfigImpl"); + + Logger getLogger(); + + int maxConnections(); + + +} diff --git a/src/de/steamwar/sql/SelectStatement.java b/src/de/steamwar/sql/internal/SelectStatement.java similarity index 66% rename from src/de/steamwar/sql/SelectStatement.java rename to src/de/steamwar/sql/internal/SelectStatement.java index cc00ecc..0f4a329 100644 --- a/src/de/steamwar/sql/SelectStatement.java +++ b/src/de/steamwar/sql/internal/SelectStatement.java @@ -1,23 +1,23 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * 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 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. + * 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 . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ -package de.steamwar.sql; +package de.steamwar.sql.internal; import java.lang.reflect.InvocationTargetException; import java.sql.ResultSet; diff --git a/src/de/steamwar/sql/SqlTypeMapper.java b/src/de/steamwar/sql/internal/SqlTypeMapper.java similarity index 55% rename from src/de/steamwar/sql/SqlTypeMapper.java rename to src/de/steamwar/sql/internal/SqlTypeMapper.java index 68d2ee8..d364bc4 100644 --- a/src/de/steamwar/sql/SqlTypeMapper.java +++ b/src/de/steamwar/sql/internal/SqlTypeMapper.java @@ -1,23 +1,23 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * 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 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. + * 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 . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ -package de.steamwar.sql; +package de.steamwar.sql.internal; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -34,18 +34,6 @@ public final class SqlTypeMapper { return (SqlTypeMapper) mappers.get(clazz); } - static { - new SqlTypeMapper<>(String.class, "TEXT", ResultSet::getString, PreparedStatement::setString); - new SqlTypeMapper<>(Boolean.class, "BOOLEAN", ResultSet::getBoolean, PreparedStatement::setBoolean); - new SqlTypeMapper<>(Byte.class, "INTEGER(1)", ResultSet::getByte, PreparedStatement::setByte); - new SqlTypeMapper<>(Short.class, "INTEGER(2)", ResultSet::getShort, PreparedStatement::setShort); - new SqlTypeMapper<>(Integer.class, "INTEGER(4)", ResultSet::getInt, PreparedStatement::setInt); - new SqlTypeMapper<>(Long.class, "INTEGER(8)", ResultSet::getLong, PreparedStatement::setLong); - new SqlTypeMapper<>(Float.class, "REAL", ResultSet::getFloat, PreparedStatement::setFloat); - new SqlTypeMapper<>(Double.class, "REAL", ResultSet::getDouble, PreparedStatement::setDouble); - new SqlTypeMapper<>(Timestamp.class, "TIMESTAMP", ResultSet::getTimestamp, PreparedStatement::setTimestamp); - } - public static > void ordinalEnumMapper(Class type) { T[] enumConstants = type.getEnumConstants(); new SqlTypeMapper<>( @@ -65,6 +53,26 @@ public final class SqlTypeMapper { ); } + static { + primitiveMapper(boolean.class, Boolean.class, "BOOLEAN", ResultSet::getBoolean, PreparedStatement::setBoolean); + primitiveMapper(byte.class, Byte.class, "INTEGER(1)", ResultSet::getByte, PreparedStatement::setByte); + primitiveMapper(short.class, Short.class, "INTEGER(2)", ResultSet::getShort, PreparedStatement::setShort); + primitiveMapper(int.class, Integer.class, "INTEGER(4)", ResultSet::getInt, PreparedStatement::setInt); + primitiveMapper(long.class, Long.class, "INTEGER(8)", ResultSet::getLong, PreparedStatement::setLong); + primitiveMapper(float.class, Float.class, "REAL", ResultSet::getFloat, PreparedStatement::setFloat); + primitiveMapper(double.class, Double.class, "REAL", ResultSet::getDouble, PreparedStatement::setDouble); + new SqlTypeMapper<>(String.class, "TEXT", ResultSet::getString, PreparedStatement::setString); + new SqlTypeMapper<>(Timestamp.class, "TIMESTAMP", ResultSet::getTimestamp, PreparedStatement::setTimestamp); + } + + private static void primitiveMapper(Class primitive, Class wrapped, String sqlType, SQLReader reader, SQLWriter writer) { + new SqlTypeMapper<>(primitive, sqlType, reader, writer); + new SqlTypeMapper<>(wrapped, sqlType, (rs, identifier) -> { + T value = reader.read(rs, identifier); + return rs.wasNull() ? null : value; + }, writer); + } + private final String sqlType; private final SQLReader reader; private final SQLWriter writer; diff --git a/src/de/steamwar/sql/Statement.java b/src/de/steamwar/sql/internal/Statement.java similarity index 82% rename from src/de/steamwar/sql/Statement.java rename to src/de/steamwar/sql/internal/Statement.java index 9626f0e..2e9edb8 100644 --- a/src/de/steamwar/sql/Statement.java +++ b/src/de/steamwar/sql/internal/Statement.java @@ -1,23 +1,23 @@ /* - 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 . + * 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; +package de.steamwar.sql.internal; import java.io.File; import java.io.FileReader; @@ -92,11 +92,17 @@ public class Statement implements AutoCloseable { } } + private final boolean returnGeneratedKeys; private final String sql; private final Map cachedStatements = new HashMap<>(); public Statement(String sql) { + this(sql, false); + } + + public Statement(String sql, boolean returnGeneratedKeys) { this.sql = sql; + this.returnGeneratedKeys = returnGeneratedKeys; synchronized (statements) { statements.add(this); } @@ -115,6 +121,15 @@ public class Statement implements AutoCloseable { withConnection(PreparedStatement::executeUpdate, objects); } + public int insertGetKey(Object... objects) { + return withConnection(st -> { + st.executeUpdate(); + ResultSet rs = st.getGeneratedKeys(); + rs.next(); + return rs.getInt(1); + }, objects); + } + public String getSql() { return sql; } @@ -150,7 +165,10 @@ public class Statement implements AutoCloseable { private T tryWithConnection(Connection connection, SQLRunnable runnable, Object... objects) throws SQLException { PreparedStatement st = cachedStatements.get(connection); if(st == null) { - st = connection.prepareStatement(sql); + if(returnGeneratedKeys) + st = connection.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS); + else + st = connection.prepareStatement(sql); cachedStatements.put(connection, st); } diff --git a/src/de/steamwar/sql/Table.java b/src/de/steamwar/sql/internal/Table.java similarity index 79% rename from src/de/steamwar/sql/Table.java rename to src/de/steamwar/sql/internal/Table.java index 74dfc83..ffef01c 100644 --- a/src/de/steamwar/sql/Table.java +++ b/src/de/steamwar/sql/internal/Table.java @@ -1,23 +1,23 @@ /* - * This file is a part of the SteamWar software. + * This file is a part of the SteamWar software. * - * Copyright (C) 2022 SteamWar.de-Serverteam + * 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 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. + * 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 . + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ -package de.steamwar.sql; +package de.steamwar.sql.internal; import java.lang.reflect.Constructor; import java.sql.ResultSet; @@ -83,16 +83,24 @@ public class Table { return insertFields(keyFields(name)); } + public Statement insertAll() { + return insertFields(false, Arrays.stream(fields).map(f -> f.identifier).toArray(String[]::new)); + } + public Statement insertFields(String... fields) { + return insertFields(false, fields); + } + + public Statement insertFields(boolean returnGeneratedKeys, String... fields) { List nonKeyFields = Arrays.stream(fields).filter(f -> fieldsByIdentifier.get(f).field.keys().length == 0).collect(Collectors.toList()); - return new Statement("INSERT INTO " + name + " (" + String.join(", ", fields) + ") VALUES (" + Arrays.stream(fields).map(f -> "?").collect(Collectors.joining(", ")) + ")" + (nonKeyFields.isEmpty() ? "" : " ON DUPLICATE KEY UPDATE " + nonKeyFields.stream().map(f -> f + " = VALUES(" + f + ")").collect(Collectors.joining(", ")))); + return new Statement("INSERT INTO " + name + " (" + String.join(", ", fields) + ") VALUES (" + Arrays.stream(fields).map(f -> "?").collect(Collectors.joining(", ")) + ")" + (nonKeyFields.isEmpty() ? "" : " ON DUPLICATE KEY UPDATE " + nonKeyFields.stream().map(f -> f + " = VALUES(" + f + ")").collect(Collectors.joining(", "))), returnGeneratedKeys); } - public Statement deleteWithKey(String name) { - return delete(keyFields(name)); + public Statement delete(String name) { + return deleteFields(keyFields(name)); } - public Statement delete(String... kfields) { + public Statement deleteFields(String... kfields) { return new Statement("DELETE FROM " + name + " WHERE " + Arrays.stream(kfields).map(f -> f + " = ?").collect(Collectors.joining(", "))); }