diff --git a/src/de/steamwar/sql/BannedUserIPs.java b/src/de/steamwar/sql/BannedUserIPs.java new file mode 100644 index 0000000..f765b76 --- /dev/null +++ b/src/de/steamwar/sql/BannedUserIPs.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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.sql.Timestamp; +import java.util.List; + +@AllArgsConstructor +public class BannedUserIPs { + + private static final Table table = new Table<>(BannedUserIPs.class); + + private static final SelectStatement getByID = table.selectFields("UserID"); + private static final SelectStatement getByIP = new SelectStatement<>(table, "SELECT * FROM BannedUserIPs WHERE IP = ? ORDER BY Timestamp DESC"); + private static final Statement banIP = table.insert(Table.PRIMARY); + + @Getter + @Field(keys = {Table.PRIMARY}) + private final int userID; + @Getter + @Field(def = "CURRENT_TIMESTAMP") + private final Timestamp timestamp; + @Field(keys = {Table.PRIMARY}) + private final String ip; + + public static List get(int userID) { + return getByID.listSelect(userID); + } + + public static List get(String ip) { + return getByIP.listSelect(ip); + } + + public static void banIP(int userID, String ip){ + banIP.update(userID, ip); + } +} diff --git a/src/de/steamwar/sql/Event.java b/src/de/steamwar/sql/Event.java index a4c30e6..90dcba2 100644 --- a/src/de/steamwar/sql/Event.java +++ b/src/de/steamwar/sql/Event.java @@ -26,17 +26,41 @@ import lombok.AllArgsConstructor; import lombok.Getter; import java.sql.Timestamp; +import java.time.Instant; +import java.util.List; @AllArgsConstructor public class Event { private static final Table table = new Table<>(Event.class); + + private static final SelectStatement byCurrent = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start < now() AND End > now()"); private static final SelectStatement byId = table.select(Table.PRIMARY); + private static final SelectStatement byName = table.select("eventName"); + private static final SelectStatement byComing = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start > now()"); + + private static Event current = null; + + public static Event get(){ + if(current != null && current.now()) + return current; + + current = byCurrent.select(); + return current; + } public static Event get(int eventID){ return byId.select(eventID); } + public static Event get(String eventName) { + return byName.select(eventName); + } + + public static List getComing() { + return byComing.listSelect(); + } + @Getter @Field(keys = {Table.PRIMARY}, autoincrement = true) private final int eventID; @@ -72,4 +96,14 @@ public class Event { public SchematicType getSchematicType() { return schemType; } + + @Deprecated + public String getSchemType() { + return schemType.toDB(); + } + + private boolean now() { + Instant now = Instant.now(); + return now.isAfter(start.toInstant()) && now.isBefore(end.toInstant()); + } } diff --git a/src/de/steamwar/sql/Fight.java b/src/de/steamwar/sql/Fight.java index 0f9eae6..0a26a88 100644 --- a/src/de/steamwar/sql/Fight.java +++ b/src/de/steamwar/sql/Fight.java @@ -25,6 +25,8 @@ import de.steamwar.sql.internal.Table; import lombok.AllArgsConstructor; import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; @AllArgsConstructor public class Fight { @@ -55,6 +57,9 @@ public class Fight { @Field private final String wincondition; + private final List bluePlayers = new ArrayList<>(); + private final List redPlayers = new ArrayList<>(); + 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 index cc529b8..73b5a05 100644 --- a/src/de/steamwar/sql/FightPlayer.java +++ b/src/de/steamwar/sql/FightPlayer.java @@ -20,20 +20,29 @@ 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.Collections; +import java.util.List; @AllArgsConstructor public class FightPlayer { private static final Table table = new Table<>(FightPlayer.class); private static final Statement create = table.insertAll(); + private static final SelectStatement batchGet = new SelectStatement<>(table, "SELECT * FROM FightPlayer WHERE FightID IN ?"); + @Getter @Field(keys = {Table.PRIMARY}) private final int fightID; + @Getter @Field(keys = {Table.PRIMARY}) private final int userID; + @Getter @Field private final int team; @Field @@ -46,4 +55,11 @@ public class FightPlayer { 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); } + + public static List batchGet(Integer[] fightIds) { + if(fightIds.length == 0) + return Collections.emptyList(); + + return batchGet.listSelect((Object) fightIds); + } } diff --git a/src/de/steamwar/sql/PollAnswer.java b/src/de/steamwar/sql/PollAnswer.java new file mode 100644 index 0000000..933f253 --- /dev/null +++ b/src/de/steamwar/sql/PollAnswer.java @@ -0,0 +1,77 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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 lombok.Setter; + +import java.util.HashMap; +import java.util.Map; + +@AllArgsConstructor +public class PollAnswer { + + @Getter + @Setter + private static String currentPoll; + + private static final Table table = new Table<>(PollAnswer.class); + + private static final SelectStatement get = table.select(Table.PRIMARY); + private static final Statement getResults = new Statement("SELECT Count(UserID) AS Times, Answer FROM PollAnswer WHERE Question = ? GROUP BY Answer ORDER BY Times ASC"); + private static final Statement insert = table.insertAll(); + + @Field(keys = {Table.PRIMARY}) + private final int userID; + @Field(keys = {Table.PRIMARY}) + private final String question; + @Field(def = "0") + private int answer; + + public static PollAnswer get(int userID) { + PollAnswer answer = get.select(userID, currentPoll); + if(answer == null) + return new PollAnswer(userID, currentPoll, 0); + return answer; + } + + public static Map getCurrentResults() { + return getResults.select(rs -> { + Map retMap = new HashMap<>(); + while (rs.next()) + retMap.put(rs.getInt("Answer")-1, rs.getInt("Times")); + return retMap; + }, currentPoll); + } + + public boolean hasAnswered(){ + return answer != 0; + } + + public void setAnswer(int answer){ + this.answer = answer; + insert.update(userID, question, answer); + } +} diff --git a/src/de/steamwar/sql/Session.java b/src/de/steamwar/sql/Session.java new file mode 100644 index 0000000..18ad2c8 --- /dev/null +++ b/src/de/steamwar/sql/Session.java @@ -0,0 +1,45 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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 Session { + + private static final Table table = new Table<>(Session.class); + private static final Statement insert = table.insert(Table.PRIMARY); + + public static void insertSession(int userID, Timestamp startTime){ + insert.update(userID, startTime); + } + + @Field(keys = {Table.PRIMARY}) + private int userId; + @Field(keys = {Table.PRIMARY}) + private Timestamp startTime; + @Field(def = "CURRENT_TIMESTAMP") + private Timestamp endTime; +} diff --git a/src/de/steamwar/sql/Team.java b/src/de/steamwar/sql/Team.java index 10e6892..977c4fe 100644 --- a/src/de/steamwar/sql/Team.java +++ b/src/de/steamwar/sql/Team.java @@ -25,14 +25,23 @@ import de.steamwar.sql.internal.Table; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @AllArgsConstructor public class Team { + private static final Map teamCache = new HashMap<>(); + + public static void clear() { + teamCache.clear(); + } + private static final Table table = new Table<>(Team.class); - private static final SelectStatement select = table.select(Table.PRIMARY); + private static final SelectStatement byId = table.select(Table.PRIMARY); + private static final SelectStatement byName = new SelectStatement<>(table, "SELECT * FROM Team WHERE (lower(TeamName) = ? OR lower(TeamKuerzel) = ?) AND NOT TeamDeleted"); @Field(keys = {Table.PRIMARY}) @Getter @@ -46,13 +55,22 @@ public class Team { @Field(def = "'8'") @Getter private final String teamColor; - - private static final Team pub = new Team(0, "PUB", "Öffentlich", "8"); + @Field(nullable = true) + private String address; + @Field(def = "'25565'") + private int port; + @Field(def = "0") + private boolean teamDeleted; public static Team get(int id) { - if(id == 0) - return pub; - return select.select(id); + return teamCache.computeIfAbsent(id, byId::select); + //TODOs: BungeeCore flush caches + //TODOs: Team public removal test + //TODOs: ArraySelect test + } + + public static Team get(String name){ + return byName.select(name, name); } public List getMembers(){ diff --git a/src/de/steamwar/sql/TeamTeilnahme.java b/src/de/steamwar/sql/TeamTeilnahme.java index 533b830..f1484da 100644 --- a/src/de/steamwar/sql/TeamTeilnahme.java +++ b/src/de/steamwar/sql/TeamTeilnahme.java @@ -21,6 +21,7 @@ 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; @@ -34,6 +35,9 @@ public class TeamTeilnahme { private static final SelectStatement select = table.select(Table.PRIMARY); private static final SelectStatement selectTeams = table.selectFields("EventID"); private static final SelectStatement selectEvents = table.selectFields("TeamID"); + private static final Statement insert = table.insert(Table.PRIMARY); + private static final Statement delete = table.delete(Table.PRIMARY); + private static final Statement deleteFuture = new Statement("DELETE t FROM TeamTeilnahme t INNER JOIN Event e ON t.EventID = e.EventID WHERE t.TeamID = ? AND e.Start > NOW()"); @Field(keys = {Table.PRIMARY}) private final int teamId; @@ -44,6 +48,18 @@ public class TeamTeilnahme { return select.select(teamID, eventID) != null; } + public static void teilnehmen(int teamID, int eventID){ + insert.update(teamID, eventID); + } + + public static void notTeilnehmen(int teamID, int eventID){ + delete.update(teamID, eventID); + } + + public static void deleteFuture(int teamID) { + deleteFuture.update(teamID); + } + public static Set getTeams(int eventID){ return selectTeams.listSelect(eventID).stream().map(tt -> Team.get(tt.teamId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries) } diff --git a/src/de/steamwar/sql/UserGroup.java b/src/de/steamwar/sql/UserGroup.java index cef4fee..aea2dba 100644 --- a/src/de/steamwar/sql/UserGroup.java +++ b/src/de/steamwar/sql/UserGroup.java @@ -1,21 +1,21 @@ -/* - 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 . -*/ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 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; @@ -24,22 +24,35 @@ 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); + Admin("§4", "§e", "Admin", true, true, true, true), + Developer("§3", "§f", "Dev", true, true, true, true), + Moderator("§c", "§f", "Mod", true, true, true, true), + Supporter("§9", "§f", "Sup", false, true, true, true), + Builder("§2", "§f", "Arch", false, true, false, true), + YouTuber("§5", "§f", "YT", false, false, false, true), + Member("§7", "§7", "", false, 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; + @Getter + private final String colorCode; + @Getter + private final String chatColorCode; + @Getter + private final String chatPrefix; + @Getter + private final boolean adminGroup; + @Getter + private final boolean teamGroup; + @Getter + private final boolean checkSchematics; + @Getter + private final boolean privilegedMods; + + public static UserGroup getUsergroup(String name) { + for(UserGroup group : values()) { + if(group.name().equalsIgnoreCase(name)) + return group; + } + + throw new IllegalArgumentException(name); + } } \ No newline at end of file diff --git a/src/de/steamwar/sql/internal/SqlTypeMapper.java b/src/de/steamwar/sql/internal/SqlTypeMapper.java index 34c6173..b9ff93e 100644 --- a/src/de/steamwar/sql/internal/SqlTypeMapper.java +++ b/src/de/steamwar/sql/internal/SqlTypeMapper.java @@ -65,6 +65,7 @@ public final class SqlTypeMapper { new SqlTypeMapper<>(String.class, "TEXT", ResultSet::getString, PreparedStatement::setString); new SqlTypeMapper<>(Timestamp.class, "TIMESTAMP", ResultSet::getTimestamp, PreparedStatement::setTimestamp); new SqlTypeMapper<>(InputStream.class, "BLOB", ResultSet::getBinaryStream, PreparedStatement::setBinaryStream); + new SqlTypeMapper<>(Integer[].class, null, (rs, identifier) -> { throw new SecurityException("Arrays cannot be used as type (recursive select)"); }, (st, index, value) -> st.setArray(index, st.getConnection().createArrayOf("INTEGER", value))); } private static void primitiveMapper(Class primitive, Class wrapped, String sqlType, SQLReader reader, SQLWriter writer) {