Merge branch 'master' into LinkageOptimizations
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
yoyosource 2023-02-25 14:34:54 +01:00
Commit 567187ea88
23 geänderte Dateien mit 1314 neuen und 148 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,67 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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.time.Instant;
import java.util.List;
@AllArgsConstructor
public class BannedUserIPs {
private static final Table<BannedUserIPs> table = new Table<>(BannedUserIPs.class);
private static final SelectStatement<BannedUserIPs> getByID = table.selectFields("UserID");
private static final SelectStatement<BannedUserIPs> getByIP = new SelectStatement<>(table, "SELECT * FROM BannedUserIPs WHERE IP = ? ORDER BY Timestamp DESC");
private static final Statement banIP = table.insertAll();
private static final Statement unbanIPs = table.deleteFields("UserID");
@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<BannedUserIPs> get(int userID) {
return getByID.listSelect(userID);
}
public static List<BannedUserIPs> get(String ip) {
return getByIP.listSelect(ip);
}
public static void banIP(int userID, String ip){
banIP.update(userID, Timestamp.from(Instant.now()), ip);
}
public static void unbanIPs(int userID) {
unbanIPs.update(userID);
}
}

Datei anzeigen

@ -21,6 +21,7 @@ package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement; import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table; import de.steamwar.sql.internal.Table;
import lombok.Getter; import lombok.Getter;
@ -36,6 +37,12 @@ public class BauweltMember {
private static final Table<BauweltMember> table = new Table<>(BauweltMember.class); private static final Table<BauweltMember> table = new Table<>(BauweltMember.class);
private static final SelectStatement<BauweltMember> getMember = table.select(Table.PRIMARY); private static final SelectStatement<BauweltMember> getMember = table.select(Table.PRIMARY);
private static final SelectStatement<BauweltMember> getMembers = table.selectFields("BauweltID"); private static final SelectStatement<BauweltMember> getMembers = table.selectFields("BauweltID");
private static final Statement update = table.insertAll();
private static final Statement delete = table.delete(Table.PRIMARY);
public static void addMember(UUID ownerID, UUID memberID) {
new BauweltMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId(), false, false).updateDB();
}
public static BauweltMember getBauMember(UUID ownerID, UUID memberID){ public static BauweltMember getBauMember(UUID ownerID, UUID memberID){
return getBauMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId()); return getBauMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId());
@ -43,7 +50,7 @@ public class BauweltMember {
public static BauweltMember getBauMember(int ownerID, int memberID){ public static BauweltMember getBauMember(int ownerID, int memberID){
BauweltMember member = memberCache.get(memberID); BauweltMember member = memberCache.get(memberID);
if(member != null) if(member != null && member.bauweltID == ownerID)
return member; return member;
return getMember.select(ownerID, memberID); return getMember.select(ownerID, memberID);
} }
@ -63,11 +70,11 @@ public class BauweltMember {
@Field(keys = {Table.PRIMARY}) @Field(keys = {Table.PRIMARY})
private final int memberID; private final int memberID;
@Getter @Getter
@Field @Field(def = "0")
private final boolean worldEdit; private boolean worldEdit;
@Getter @Getter
@Field @Field(def = "0")
private final boolean world; private boolean world;
public BauweltMember(int bauweltID, int memberID, boolean worldEdit, boolean world) { public BauweltMember(int bauweltID, int memberID, boolean worldEdit, boolean world) {
this.bauweltID = bauweltID; this.bauweltID = bauweltID;
@ -76,4 +83,22 @@ public class BauweltMember {
this.world = world; this.world = world;
memberCache.put(memberID, this); memberCache.put(memberID, this);
} }
public void setWorldEdit(boolean worldEdit) {
this.worldEdit = worldEdit;
updateDB();
}
public void setWorld(boolean world) {
this.world = world;
updateDB();
}
private void updateDB(){
update.update(bauweltID, memberID, worldEdit, world);
}
public void remove(){
delete.update(bauweltID, memberID);
}
} }

Datei anzeigen

@ -21,6 +21,7 @@ package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement; import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table; import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -33,11 +34,25 @@ public class CheckedSchematic {
private static final Table<CheckedSchematic> table = new Table<>(CheckedSchematic.class); private static final Table<CheckedSchematic> table = new Table<>(CheckedSchematic.class);
private static final SelectStatement<CheckedSchematic> statusOfNode = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC"); private static final SelectStatement<CheckedSchematic> statusOfNode = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
private static final SelectStatement<CheckedSchematic> nodeHistory = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
private static final Statement insert = table.insertAll();
public static void create(int nodeId, String name, int owner, int validator, Timestamp startTime, Timestamp endTime, String reason){
insert.update(nodeId, owner, name, validator, startTime, endTime, reason);
}
public static void create(SchematicNode node, int validator, Timestamp startTime, Timestamp endTime, String reason){
create(node.getId(), node.getName(), node.getOwner(), validator, startTime, endTime, reason);
}
public static List<CheckedSchematic> getLastDeclinedOfNode(int node){ public static List<CheckedSchematic> getLastDeclinedOfNode(int node){
return statusOfNode.listSelect(node); return statusOfNode.listSelect(node);
} }
public static List<CheckedSchematic> previousChecks(SchematicNode node) {
return nodeHistory.listSelect(node.getId());
}
@Field(nullable = true) @Field(nullable = true)
private final Integer nodeId; private final Integer nodeId;
@Field @Field

Datei anzeigen

@ -26,17 +26,41 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.Instant;
import java.util.List;
@AllArgsConstructor @AllArgsConstructor
public class Event { public class Event {
private static final Table<Event> table = new Table<>(Event.class); private static final Table<Event> table = new Table<>(Event.class);
private static final SelectStatement<Event> byCurrent = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start < now() AND End > now()");
private static final SelectStatement<Event> byId = table.select(Table.PRIMARY); private static final SelectStatement<Event> byId = table.select(Table.PRIMARY);
private static final SelectStatement<Event> byName = table.select("eventName");
private static final SelectStatement<Event> 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){ public static Event get(int eventID){
return byId.select(eventID); return byId.select(eventID);
} }
public static Event get(String eventName) {
return byName.select(eventName);
}
public static List<Event> getComing() {
return byComing.listSelect();
}
@Getter @Getter
@Field(keys = {Table.PRIMARY}, autoincrement = true) @Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int eventID; private final int eventID;
@ -72,4 +96,9 @@ public class Event {
public SchematicType getSchematicType() { public SchematicType getSchematicType() {
return schemType; return schemType;
} }
private boolean now() {
Instant now = Instant.now();
return now.isAfter(start.toInstant()) && now.isBefore(end.toInstant());
}
} }

Datei anzeigen

@ -26,18 +26,41 @@ import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import java.sql.Timestamp;
import java.util.*;
import static java.time.temporal.ChronoUnit.SECONDS;
@AllArgsConstructor @AllArgsConstructor
public class EventFight { public class EventFight implements Comparable<EventFight> {
private static final Table<EventFight> table = new Table<>(EventFight.class); private static final Table<EventFight> table = new Table<>(EventFight.class);
private static final SelectStatement<EventFight> byId = table.select(Table.PRIMARY); private static final SelectStatement<EventFight> byId = table.select(Table.PRIMARY);
private static final SelectStatement<EventFight> allComing = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE StartTime > now() ORDER BY StartTime ASC");
private static final SelectStatement<EventFight> event = new SelectStatement<>(table, "SELECT * FROM EventFight WHERE EventID = ? ORDER BY StartTime ASC");
private static final Statement reschedule = table.update(Table.PRIMARY, "StartTime");
private static final Statement setResult = table.update(Table.PRIMARY, "Ergebnis"); private static final Statement setResult = table.update(Table.PRIMARY, "Ergebnis");
private static final Statement setFight = table.update(Table.PRIMARY, "Fight"); private static final Statement setFight = table.update(Table.PRIMARY, "Fight");
private static final Queue<EventFight> fights = new PriorityQueue<>();
public static EventFight get(int fightID) { public static EventFight get(int fightID) {
return byId.select(fightID); return byId.select(fightID);
} }
public static void loadAllComingFights() {
fights.clear();
fights.addAll(allComing.listSelect());
}
public static List<EventFight> getEvent(int eventID) {
return event.listSelect(eventID);
}
public static Queue<EventFight> getFights() {
return fights;
}
@Getter @Getter
@Field @Field
private final int eventID; private final int eventID;
@ -46,6 +69,15 @@ public class EventFight {
private final int fightID; private final int fightID;
@Getter @Getter
@Field @Field
private Timestamp startTime;
@Getter
@Field
private final String spielmodus;
@Getter
@Field
private final String map;
@Getter
@Field
private final int teamBlue; private final int teamBlue;
@Getter @Getter
@Field @Field
@ -69,4 +101,32 @@ public class EventFight {
this.fight = fight; this.fight = fight;
setFight.update(fight, fightID); setFight.update(fight, fightID);
} }
public boolean hasFinished() {
return fight != 0;
}
public void reschedule() {
startTime = Timestamp.from(new Date().toInstant().plus(30, SECONDS));
reschedule.update(startTime, fightID);
}
@Override
public int hashCode(){
return fightID;
}
@Override
public boolean equals(Object o){
if(o == null)
return false;
if(!(o instanceof EventFight))
return false;
return fightID == ((EventFight) o).fightID;
}
@Override
public int compareTo(EventFight o) {
return startTime.compareTo(o.startTime);
}
} }

Datei anzeigen

@ -20,24 +20,49 @@
package de.steamwar.sql; package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement; import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table; import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@AllArgsConstructor @AllArgsConstructor
public class Fight { public class Fight {
private static final Table<Fight> table = new Table<>(Fight.class); private static final Table<Fight> table = new Table<>(Fight.class);
private static final SelectStatement<Fight> getPage = new SelectStatement<>(table, "SELECT f.*, (b.NodeId IS NULL OR b.AllowReplay) AND (r.NodeId IS NULL OR r.AllowReplay) AS ReplayAllowed, (SELECT COUNT(1) FROM Replay WHERE Replay.FightID = f.FightID) as ReplayAvailable FROM Fight f LEFT OUTER JOIN SchematicNode b ON f.BlueSchem = b.NodeId LEFT OUTER JOIN SchematicNode r ON f.RedSchem = r.NodeId ORDER BY FightID DESC LIMIT ?, ?");
private static final Statement insert = table.insertFields(true, "GameMode", "Server", "StartTime", "Duration", "BlueLeader", "RedLeader", "BlueSchem", "RedSchem", "Win", "WinCondition"); private static final Statement insert = table.insertFields(true, "GameMode", "Server", "StartTime", "Duration", "BlueLeader", "RedLeader", "BlueSchem", "RedSchem", "Win", "WinCondition");
public static List<Fight> getPage(int page, int elementsPerPage) {
List<Fight> fights = getPage.listSelect(page * elementsPerPage, elementsPerPage);
List<FightPlayer> fightPlayers = FightPlayer.batchGet(fights.stream().map(f -> f.fightID));
for(Fight fight : fights) {
fight.initPlayers(fightPlayers);
}
SteamwarUser.batchCache(fightPlayers.stream().map(FightPlayer::getUserID).collect(Collectors.toSet()));
return fights;
}
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);
}
@Getter
@Field(keys = {Table.PRIMARY}, autoincrement = true) @Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int fightID; private final int fightID;
@Field @Field
private final String gameMode; private final String gameMode;
@Getter
@Field @Field
private final String server; private final String server;
@Getter
@Field @Field
private final Timestamp startTime; private final Timestamp startTime;
@Field @Field
@ -50,12 +75,50 @@ public class Fight {
private final Integer blueSchem; private final Integer blueSchem;
@Field(nullable = true) @Field(nullable = true)
private final Integer redSchem; private final Integer redSchem;
@Getter
@Field @Field
private final int win; private final int win;
@Field @Field
private final String wincondition; private final String wincondition;
@Field // Virtual field for easy select
private final boolean replayAllowed;
@Field // Virtual field for easy select
private final boolean replayAvailable;
public static int create(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition){ @Getter
return insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition); private final List<FightPlayer> bluePlayers = new ArrayList<>();
@Getter
private final List<FightPlayer> redPlayers = new ArrayList<>();
public SchematicType getSchemType() {
return SchematicType.fromDB(gameMode);
}
public SteamwarUser getBlueLeader() {
return SteamwarUser.get(blueLeader);
}
public SteamwarUser getRedLeader() {
return SteamwarUser.get(redLeader);
}
public boolean replayAllowed() {
return replayExists() && replayAllowed;
}
public boolean replayExists() {
return getSchemType() != null && replayAvailable;
}
private void initPlayers(List<FightPlayer> fightPlayers) {
for(FightPlayer fp : fightPlayers) {
if(fp.getFightID() != fightID)
continue;
if(fp.getTeam() == 1)
bluePlayers.add(fp);
else
redPlayers.add(fp);
}
} }
} }

Datei anzeigen

@ -20,20 +20,30 @@
package de.steamwar.sql; package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement; import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table; import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@AllArgsConstructor @AllArgsConstructor
public class FightPlayer { public class FightPlayer {
private static final Table<FightPlayer> table = new Table<>(FightPlayer.class); private static final Table<FightPlayer> table = new Table<>(FightPlayer.class);
private static final Statement create = table.insertAll(); private static final Statement create = table.insertAll();
private static final SelectStatement<FightPlayer> batchGet = new SelectStatement<>(table, "SELECT * FROM FightPlayer WHERE FightID IN ?");
@Getter
@Field(keys = {Table.PRIMARY}) @Field(keys = {Table.PRIMARY})
private final int fightID; private final int fightID;
@Getter
@Field(keys = {Table.PRIMARY}) @Field(keys = {Table.PRIMARY})
private final int userID; private final int userID;
@Getter
@Field @Field
private final int team; private final int team;
@Field @Field
@ -46,4 +56,10 @@ public class FightPlayer {
public static void create(int fightID, int userID, boolean blue, String kit, int kills, 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); create.update(fightID, userID, blue ? 1 : 2, kit, kills, isOut);
} }
public static List<FightPlayer> batchGet(Stream<Integer> fightIds) {
try (SelectStatement<FightPlayer> batch = new SelectStatement<>(table, "SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.map(Object::toString).collect(Collectors.joining(", ")) + ")")) {
return batch.listSelect();
}
}
} }

Datei anzeigen

@ -0,0 +1,59 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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 java.sql.ResultSet;
import java.util.UUID;
@AllArgsConstructor
public class IgnoreSystem {
private static final Table<IgnoreSystem> table = new Table<>(IgnoreSystem.class, "IgnoredPlayers");
private static final SelectStatement<IgnoreSystem> select = table.select(Table.PRIMARY);
private static final Statement insert = table.insertAll();
private static final Statement delete = table.delete(Table.PRIMARY);
@Field(keys = {Table.PRIMARY})
private final int ignorer;
@Field(keys = {Table.PRIMARY})
private final int ignored;
public static boolean isIgnored(UUID ignorer, UUID ignored){
return isIgnored(SteamwarUser.get(ignorer), SteamwarUser.get(ignored));
}
public static boolean isIgnored(SteamwarUser ignorer, SteamwarUser ignored) {
return select.select(ResultSet::next, ignorer.getId(), ignored.getId());
}
public static void ignore(SteamwarUser ignorer, SteamwarUser ignored) {
insert.update(ignorer.getId(), ignored.getId());
}
public static void unIgnore(SteamwarUser ignorer, SteamwarUser ignored) {
delete.update(ignorer.getId(), ignored.getId());
}
}

101
src/de/steamwar/sql/Mod.java Normale Datei
Datei anzeigen

@ -0,0 +1,101 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.sql;
import de.steamwar.sql.internal.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.List;
@AllArgsConstructor
public class Mod {
static {
SqlTypeMapper.ordinalEnumMapper(Platform.class);
SqlTypeMapper.ordinalEnumMapper(ModType.class);
}
private static final Table<Mod> table = new Table<>(Mod.class, "Mods");
private static final SelectStatement<Mod> get = table.select(Table.PRIMARY);
private static final SelectStatement<Mod> findFirst = new SelectStatement<>(table, "SELECT * FROM Mods WHERE ModType = 0 LIMIT 1");
private static final SelectStatement<Mod> getPageOfType = new SelectStatement<>(table, "SELECT * FROM Mods WHERE ModType = ? ORDER BY ModName DESC LIMIT ?, ?");
private static final Statement insert = table.insert(Table.PRIMARY);
private static final Statement set = table.update(Table.PRIMARY, "ModType");
public static Mod get(String name, Platform platform) {
return get.select(platform, name);
}
public static Mod getOrCreate(String name, Platform platform) {
Mod mod = get(name, platform);
if(mod != null)
return mod;
insert.update(platform, name);
return new Mod(platform, name, ModType.UNKLASSIFIED);
}
public static List<Mod> getAllModsFiltered(int page, int elementsPerPage, Mod.ModType filter) {
return Mod.getPageOfType.listSelect(filter, page * elementsPerPage, elementsPerPage);
}
public static Mod findFirstMod() {
return findFirst.select();
}
@Getter
@Field(keys = {Table.PRIMARY})
private final Platform platform;
@Getter
@Field(keys = {Table.PRIMARY})
private final String modName;
@Getter
@Field(def = "0")
private ModType modType;
public void setModType(Mod.ModType modType) {
set.update(modType, platform, modName);
this.modType = modType;
}
public enum Platform {
FORGE,
LABYMOD,
FABRIC
}
public enum ModType {
UNKLASSIFIED("7"),
GREEN("a"),
YELLOW("e"),
RED("c"),
YOUTUBER_ONLY("6");
ModType(String colorcode) {
this.colorcode = colorcode;
}
private final String colorcode;
public String getColorCode() {
return colorcode;
}
}
}

Datei anzeigen

@ -0,0 +1,92 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.sql;
import de.steamwar.sql.internal.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.*;
import java.sql.PreparedStatement;
import java.util.zip.GZIPInputStream;
@AllArgsConstructor
public class NodeData {
static {
new SqlTypeMapper<>(PipedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("PipedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
new SqlTypeMapper<>(ByteArrayInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("ByteArrayInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
new SqlTypeMapper<>(BufferedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("BufferedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
}
private static final Table<NodeData> table = new Table<>(NodeData.class);
private static final Statement updateDatabase = new Statement("INSERT INTO NodeData(NodeId, NodeFormat, SchemData) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE NodeFormat = VALUES(NodeFormat), SchemData = VALUES(SchemData)");
private static final Statement selSchemData = new Statement("SELECT SchemData FROM NodeData WHERE NodeId = ?");
private static final SelectStatement<NodeData> get = table.select(Table.PRIMARY);
public static NodeData get(SchematicNode node) {
if(node.isDir())
throw new IllegalArgumentException("Node is a directory");
return get.select(rs -> {
if(rs.next()) {
return new NodeData(node.getId(), rs.getBoolean("NodeFormat"));
} else {
return new NodeData(node.getId(), false);
}
}, node);
}
@Getter
@Field(keys = {Table.PRIMARY})
private final int nodeId;
@Field
private boolean nodeFormat;
public InputStream schemData() throws IOException {
try {
return selSchemData.select(rs -> {
rs.next();
InputStream schemData = rs.getBinaryStream("SchemData");
try {
if(rs.wasNull() || schemData.available() == 0) {
throw new SecurityException("SchemData is null");
}
return new GZIPInputStream(schemData);
} catch (IOException e) {
throw new SecurityException("SchemData is wrong", e);
}
}, nodeId);
} catch (Exception e) {
throw new IOException(e);
}
}
public void saveFromStream(InputStream blob, boolean newFormat) {
updateDatabase.update(nodeId, newFormat, blob);
nodeFormat = newFormat;
}
public boolean getNodeFormat() {
return nodeFormat;
}
}

Datei anzeigen

@ -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 <https://www.gnu.org/licenses/>.
*/
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<PollAnswer> table = new Table<>(PollAnswer.class);
private static final SelectStatement<PollAnswer> 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<Integer, Integer> getCurrentResults() {
return getResults.select(rs -> {
Map<Integer, Integer> 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);
}
}

Datei anzeigen

@ -19,16 +19,16 @@
package de.steamwar.sql; package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.*;
import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.SqlTypeMapper;
import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.Instant;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -40,13 +40,48 @@ public class Punishment {
SqlTypeMapper.nameEnumMapper(PunishmentType.class); SqlTypeMapper.nameEnumMapper(PunishmentType.class);
} }
public static final Timestamp PERMA_TIME = Timestamp.from(Instant.ofEpochSecond(946674800));
private static final Table<Punishment> table = new Table<>(Punishment.class, "Punishments"); private static final Table<Punishment> table = new Table<>(Punishment.class, "Punishments");
private static final SelectStatement<Punishment> getPunishments = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE PunishmentId IN (SELECT MAX(PunishmentId) FROM Punishments WHERE UserId = ? GROUP BY Type)"); private static final SelectStatement<Punishment> getPunishments = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE PunishmentId IN (SELECT MAX(PunishmentId) FROM Punishments WHERE UserId = ? GROUP BY Type)");
private static final SelectStatement<Punishment> getPunishment = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1"); private static final SelectStatement<Punishment> getPunishment = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1");
private static final SelectStatement<Punishment> getAllPunishments = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE UserId = ? ORDER BY `PunishmentId` DESC");
private static final Statement insert = table.insertFields(true, "UserId", "Punisher", "Type", "EndTime", "Perma", "Reason");
public static Punishment getPunishmentOfPlayer(int user, PunishmentType type) {
return getPunishment.select(user, type);
}
public static Map<PunishmentType, Punishment> getPunishmentsOfPlayer(int user) {
return getPunishments.listSelect(user).stream().collect(Collectors.toMap(Punishment::getType, punishment -> punishment));
}
public static List<Punishment> getAllPunishmentsOfPlayer(int user) {
return getAllPunishments.listSelect(user);
}
public static boolean isPunished(SteamwarUser user, Punishment.PunishmentType type, Consumer<Punishment> callback) {
Punishment punishment = Punishment.getPunishmentOfPlayer(user.getId(), type);
if(punishment == null || !punishment.isCurrent()) {
return false;
} else {
callback.accept(punishment);
return true;
}
}
public static Punishment createPunishment(int user, int executor, PunishmentType type, String reason, Timestamp endTime, boolean perma) {
if(perma && !endTime.equals(PERMA_TIME)) {
throw new IllegalArgumentException("Permanent punishments must have an end time of `Punishment.PERMA_TIME`");
}
int punishmentId = insert.insertGetKey(user, executor, type.name(), endTime, perma, reason);
return new Punishment(punishmentId, user, executor, type, Timestamp.from(Instant.now()), endTime, perma, reason);
}
@Field(keys = {Table.PRIMARY}, autoincrement = true) @Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int punishmentId; private final int punishmentId;
@Field @Field
@Getter
private final int userId; private final int userId;
@Field @Field
@Getter @Getter
@ -67,24 +102,6 @@ public class Punishment {
@Getter @Getter
private final String reason; private final String reason;
public static Punishment getPunishmentOfPlayer(int user, PunishmentType type) {
return getPunishment.select(user, type);
}
public static Map<PunishmentType, Punishment> getPunishmentsOfPlayer(int user) {
return getPunishments.listSelect(user).stream().collect(Collectors.toMap(Punishment::getType, punishment -> punishment));
}
public static boolean isPunished(SteamwarUser user, Punishment.PunishmentType type, Consumer<Punishment> callback) {
Punishment punishment = Punishment.getPunishmentOfPlayer(user.getId(), type);
if(punishment == null || !punishment.isCurrent()) {
return false;
} else {
callback.accept(punishment);
return true;
}
}
@Deprecated // Not multiling, misleading title @Deprecated // Not multiling, misleading title
public String getBantime(Timestamp endTime, boolean perma) { public String getBantime(Timestamp endTime, boolean perma) {
if (perma) { if (perma) {
@ -94,15 +111,12 @@ public class Punishment {
} }
} }
public int getUserId() {
return userId;
}
public boolean isCurrent() { public boolean isCurrent() {
return isPerma() || getEndTime().after(new Date()); return isPerma() || getEndTime().after(new Date());
} }
@AllArgsConstructor @AllArgsConstructor
@RequiredArgsConstructor
@Getter @Getter
public enum PunishmentType { public enum PunishmentType {
Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"), Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"),
@ -110,7 +124,10 @@ public class Punishment {
NoSchemReceiving(false, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"), NoSchemReceiving(false, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"),
NoSchemSharing(false, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"), NoSchemSharing(false, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"),
NoSchemSubmitting(true, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"), NoSchemSubmitting(true, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"),
NoDevServer(true, "NODEVSERVER_TEAM", "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", "UNNODEVSERVER"); NoDevServer(true, "NODEVSERVER_TEAM", "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", "UNNODEVSERVER"),
NoFightServer(false, "NOFIGHTSERVER_TEAM", "NOFIGHTSERVER_PERMA", "NOFIGHTSERVER_UNTIL", "UNNOFIGHTSERVER_ERROR", "UNNOFIGHTSERVER"),
NoTeamServer(true, "NOTEAMSERVER_TEAM", "NOTEAMSERVER_PERMA", "NOTEAMSERVER_UNTIL", "UNNOTEAMSERVER_ERROR", "UNNOTEAMSERVER"),
Note(false, "NOTE_TEAM", null, null, null, null, true);
private final boolean needsAdmin; private final boolean needsAdmin;
private final String teamMessage; private final String teamMessage;
@ -118,5 +135,6 @@ public class Punishment {
private final String playerMessageUntil; private final String playerMessageUntil;
private final String usageNotPunished; private final String usageNotPunished;
private final String unpunishmentMessage; private final String unpunishmentMessage;
private boolean multi = false;
} }
} }

Datei anzeigen

@ -21,14 +21,31 @@ package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement; import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table; import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@AllArgsConstructor @AllArgsConstructor
public class SchemElo { public class SchemElo {
private static final int ELO_DEFAULT = 1000;
private static final Table<SchemElo> table = new Table<>(SchemElo.class); private static final Table<SchemElo> table = new Table<>(SchemElo.class);
private static final SelectStatement<SchemElo> select = table.select(Table.PRIMARY); private static final SelectStatement<SchemElo> select = table.select(Table.PRIMARY);
private static final Statement setElo = table.insertAll();
public static int getElo(SchematicNode node, int season) {
SchemElo elo = select.select(node, season);
return elo != null ? elo.elo : 0;
}
public static int getCurrentElo(int schemID) {
SchemElo elo = select.select(schemID, Season.getSeason());
return elo != null ? elo.elo : ELO_DEFAULT;
}
public static void setElo(int schemID, int elo) {
setElo.update(schemID, elo, Season.getSeason());
}
@Field(keys = {Table.PRIMARY}) @Field(keys = {Table.PRIMARY})
private final int schemId; private final int schemId;
@ -36,9 +53,4 @@ public class SchemElo {
private final int elo; private final int elo;
@Field(keys = {Table.PRIMARY}) @Field(keys = {Table.PRIMARY})
private final int season; private final int season;
public static int getElo(SchematicNode node, int season) {
SchemElo elo = select.select(node, season);
return elo != null ? elo.elo : 0;
}
} }

Datei anzeigen

@ -40,11 +40,11 @@ public class SchematicNode {
TAB_CACHE.clear(); TAB_CACHE.clear();
} }
private static final String nodeSelector = "SELECT NodeId, NodeOwner, NodeOwner AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay, NodeFormat FROM SchematicNode "; private static final String nodeSelector = "SELECT NodeId, NodeOwner, NodeOwner AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode ";
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class); private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType"); private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay", "NodeFormat"); private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
private static final Statement delete = table.delete(Table.PRIMARY); private static final Statement delete = table.delete(Table.PRIMARY);
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table, nodeSelector + "WHERE NodeId = ?"); private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table, nodeSelector + "WHERE NodeId = ?");
@ -54,13 +54,13 @@ public class SchematicNode {
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName"); private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelector + "WHERE NodeType = ? ORDER BY NodeName"); private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName"); private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay, NodeFormat FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay, NodeFormat FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName"); private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay, NodeFormat FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay, NodeFormat FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?"); private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?");
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?"); private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeType = ? AND EffectiveOwner = ? UNION SELECT SN.NodeId, SN.ParentNode FROM RSN, EffectiveSchematicNode SN WHERE SN.NodeId = RSN.ParentNode AND EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, RSN.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay, SN.NodeFormat FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE RSN.ParentNode" + Statement.NULL_SAFE_EQUALS + "?"); private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeType = ? AND EffectiveOwner = ? UNION SELECT SN.NodeId, SN.ParentNode FROM RSN, EffectiveSchematicNode SN WHERE SN.NodeId = RSN.ParentNode AND EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, RSN.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE RSN.ParentNode" + Statement.NULL_SAFE_EQUALS + "?");
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeType = ?"); private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeType = ?");
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table, "SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay, NodeFormat FROM SchematicNode WHERE NodeId = ?"); private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table, "SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?");
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay, SN.NodeFormat FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId"); private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
static { static {
NodeMember.init(); NodeMember.init();
@ -89,9 +89,6 @@ public class SchematicNode {
private boolean replaceColor; private boolean replaceColor;
@Field(def = "1") @Field(def = "1")
private boolean allowReplay; private boolean allowReplay;
@Setter(AccessLevel.PACKAGE)
@Field(def = "1")
private boolean nodeFormat;
private String brCache; private String brCache;
@ -106,8 +103,7 @@ public class SchematicNode {
SchematicType nodeType, SchematicType nodeType,
int nodeRank, int nodeRank,
boolean replaceColor, boolean replaceColor,
boolean allowReplay, boolean allowReplay
boolean nodeFormat
) { ) {
this.nodeId = nodeId; this.nodeId = nodeId;
this.nodeOwner = nodeOwner; this.nodeOwner = nodeOwner;
@ -120,7 +116,6 @@ public class SchematicNode {
this.nodeRank = nodeRank; this.nodeRank = nodeRank;
this.replaceColor = replaceColor; this.replaceColor = replaceColor;
this.allowReplay = allowReplay; this.allowReplay = allowReplay;
this.nodeFormat = nodeFormat;
} }
public static List<SchematicNode> getAll(SteamwarUser user) { public static List<SchematicNode> getAll(SteamwarUser user) {
@ -381,10 +376,11 @@ public class SchematicNode {
return nodeType == null; return nodeType == null;
} }
@Deprecated
public boolean getSchemFormat() { public boolean getSchemFormat() {
if(isDir()) if(isDir())
throw new SecurityException("Node is Directory"); throw new SecurityException("Node is Directory");
return nodeFormat; return NodeData.get(this).getNodeFormat();
} }
public int getRank() { public int getRank() {
@ -462,7 +458,7 @@ public class SchematicNode {
private void updateDB() { private void updateDB() {
this.lastUpdate = Timestamp.from(Instant.now()); this.lastUpdate = Timestamp.from(Instant.now());
update.update(nodeName, parentNode, nodeItem, nodeType, nodeRank, replaceColor, allowReplay, nodeFormat, nodeId); update.update(nodeName, parentNode, nodeItem, nodeType, nodeRank, replaceColor, allowReplay, nodeId);
TAB_CACHE.clear(); TAB_CACHE.clear();
} }
@ -549,7 +545,7 @@ public class SchematicNode {
if (s.contains("/")) { if (s.contains("/")) {
String preTab = s.substring(0, s.lastIndexOf("/") + 1); String preTab = s.substring(0, s.lastIndexOf("/") + 1);
SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab); SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
if (pa == null) return Collections.emptyList(); if (pa == null) return new ArrayList<>();
List<SchematicNode> nodes = SchematicNode.list(user, pa.getId()); List<SchematicNode> nodes = SchematicNode.list(user, pa.getId());
String br = pa.generateBreadcrumbs(); String br = pa.generateBreadcrumbs();
nodes.forEach(node -> list.add((sws ? "/" : "") + br + node.getName() + (node.isDir() ? "/" : ""))); nodes.forEach(node -> list.add((sws ? "/" : "") + br + node.getName() + (node.isDir() ? "/" : "")));

Datei anzeigen

@ -20,6 +20,7 @@
package de.steamwar.sql; package de.steamwar.sql;
import de.steamwar.sql.internal.SqlTypeMapper; import de.steamwar.sql.internal.SqlTypeMapper;
import lombok.Getter;
import java.util.*; import java.util.*;
@ -51,17 +52,26 @@ public class SchematicType {
} }
private final String name; private final String name;
@Getter
private final String kuerzel; private final String kuerzel;
private final Type type; private final Type type;
private final SchematicType checkType; private final SchematicType checkType;
@Getter
private final String material; private final String material;
@Getter
private final Date deadline;
SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material){ SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material){
this(name, kuerzel, type, checkType, material, null);
}
SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material, Date deadline){
this.name = name; this.name = name;
this.kuerzel = kuerzel; this.kuerzel = kuerzel;
this.type = type; this.type = type;
this.checkType = checkType; this.checkType = checkType;
this.material = material; this.material = material;
this.deadline = deadline;
} }
public boolean isAssignable(){ public boolean isAssignable(){
@ -88,14 +98,6 @@ public class SchematicType {
return name; return name;
} }
public String getKuerzel() {
return kuerzel;
}
public String getMaterial() {
return material;
}
public String toDB(){ public String toDB(){
return name.toLowerCase(); return name.toLowerCase();
} }

Datei anzeigen

@ -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 <https://www.gnu.org/licenses/>.
*/
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<Session> 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;
}

Datei anzeigen

@ -22,7 +22,11 @@ package de.steamwar.sql;
import de.steamwar.sql.internal.*; import de.steamwar.sql.internal.*;
import lombok.Getter; import lombok.Getter;
import java.sql.Timestamp;
import java.util.*; import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;
public class SteamwarUser { public class SteamwarUser {
@ -44,12 +48,16 @@ public class SteamwarUser {
private static final SelectStatement<SteamwarUser> byDiscord = table.selectFields("DiscordId"); private static final SelectStatement<SteamwarUser> byDiscord = table.selectFields("DiscordId");
private static final SelectStatement<SteamwarUser> byTeam = table.selectFields("Team"); private static final SelectStatement<SteamwarUser> byTeam = table.selectFields("Team");
private static final SelectStatement<SteamwarUser> getServerTeam = new SelectStatement<>(table, "SELECT * FROM UserData WHERE UserGroup != 'Member' AND UserGroup != 'YouTuber'"); private static final SelectStatement<SteamwarUser> 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 updateName = table.update(Table.PRIMARY, "UserName");
private static final Statement updateLocale = table.update(Table.PRIMARY, "Locale", "ManualLocale"); 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 updateTeam = table.update(Table.PRIMARY, "Team");
private static final Statement updateLeader = table.update(Table.PRIMARY, "Leader"); private static final Statement updateLeader = table.update(Table.PRIMARY, "Leader");
private static final Statement updateDiscord = table.update(Table.PRIMARY, "DiscordId"); private static final Statement updateDiscord = table.update(Table.PRIMARY, "DiscordId");
private static final Statement getPlaytime = new Statement("SELECT SUM(UNIX_TIMESTAMP(EndTime) - UNIX_TIMESTAMP(StartTime)) as Playtime FROM Session WHERE UserID = ?");
private static final Statement getFirstjoin = new Statement("SELECT MIN(StartTime) AS FirstJoin FROM Session WHERE UserID = ?");
private static final Map<Integer, SteamwarUser> usersById = new HashMap<>(); private static final Map<Integer, SteamwarUser> usersById = new HashMap<>();
private static final Map<UUID, SteamwarUser> usersByUUID = new HashMap<>(); private static final Map<UUID, SteamwarUser> usersByUUID = new HashMap<>();
private static final Map<String, SteamwarUser> usersByName = new HashMap<>(); private static final Map<String, SteamwarUser> usersByName = new HashMap<>();
@ -67,6 +75,83 @@ public class SteamwarUser {
return; return;
usersByName.remove(user.getUserName()); usersByName.remove(user.getUserName());
usersByUUID.remove(user.getUUID()); usersByUUID.remove(user.getUUID());
usersByDiscord.remove(user.getDiscordId());
}
public static SteamwarUser get(String userName){
SteamwarUser user = usersByName.get(userName.toLowerCase());
if(user != null)
return user;
return loadPunishments(byName.select(userName));
}
public static SteamwarUser get(UUID uuid){
SteamwarUser user = usersByUUID.get(uuid);
if(user != null)
return user;
return loadPunishments(byUUID.select(uuid));
}
public static SteamwarUser get(int id) {
SteamwarUser user = usersById.get(id);
if(user != null)
return user;
return loadPunishments(byID.select(id));
}
public static SteamwarUser get(Long discordId) {
if(usersByDiscord.containsKey(discordId))
return usersByDiscord.get(discordId);
return loadPunishments(byDiscord.select(discordId));
}
public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer, BiConsumer<String, String> nameUpdate) {
SteamwarUser user = get(uuid);
if (user != null) {
if (!user.userName.equals(name)) {
updateName.update(name, user.id);
nameUpdate.accept(user.userName, name);
user.userName = name;
}
return user;
} else {
insert.update(uuid, name);
newPlayer.accept(uuid);
return get(uuid);
}
}
public static List<SteamwarUser> getServerTeam() {
return loadPunishments(getServerTeam.listSelect());
}
public static List<SteamwarUser> getTeam(int teamId) {
return loadPunishments(byTeam.listSelect(teamId));
}
public static void batchCache(Set<Integer> ids) {
ids.removeIf(usersById::containsKey);
if(ids.isEmpty())
return;
try (SelectStatement<SteamwarUser> batch = new SelectStatement<>(table, "SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")")) {
loadPunishments(batch.listSelect());
}
}
private static List<SteamwarUser> loadPunishments(List<SteamwarUser> users) {
users.forEach(user -> user.punishments = Punishment.getPunishmentsOfPlayer(user.getId()));
return users;
}
private static SteamwarUser loadPunishments(SteamwarUser user) {
if(user == null)
return null;
user.punishments = Punishment.getPunishmentsOfPlayer(user.getId());
return user;
} }
@Getter @Getter
@ -83,15 +168,19 @@ public class SteamwarUser {
@Getter @Getter
@Field(def = "0") @Field(def = "0")
private int team; private int team;
@Getter
@Field(def = "0") @Field(def = "0")
private boolean leader; private boolean leader;
@Field(nullable = true) @Field(nullable = true)
private Locale locale; private Locale locale;
@Field(def = "0") @Field(def = "0")
private boolean manualLocale; private boolean manualLocale;
@Getter
@Field(keys = {"discordId"}, nullable = true) @Field(keys = {"discordId"}, nullable = true)
private Long discordId; private Long discordId;
private Map<Punishment.PunishmentType, Punishment> punishments;
public SteamwarUser(int id, UUID uuid, String userName, UserGroup userGroup, int team, boolean leader, Locale locale, boolean manualLocale, 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.id = id;
this.uuid = uuid; this.uuid = uuid;
@ -121,6 +210,56 @@ public class SteamwarUser {
return Locale.getDefault(); return Locale.getDefault();
} }
public Punishment getPunishment(Punishment.PunishmentType type) {
return punishments.getOrDefault(type, null);
}
public boolean isPunished(Punishment.PunishmentType punishment) {
if (!punishments.containsKey(punishment)) {
return false;
}
if (!punishments.get(punishment).isCurrent()) {
if (punishment == Punishment.PunishmentType.Ban) {
BannedUserIPs.unbanIPs(id);
}
punishments.remove(punishment);
return false;
}
return true;
}
public double getOnlinetime() {
return getPlaytime.select(rs -> {
if (rs.next() && rs.getBigDecimal("Playtime") != null)
return rs.getBigDecimal("Playtime").doubleValue();
return 0.0;
}, id);
}
public Timestamp getFirstjoin() {
return getFirstjoin.select(rs -> {
if (rs.next())
return rs.getTimestamp("FirstJoin");
return null;
}, id);
}
public void punish(Punishment.PunishmentType punishment, Timestamp time, String banReason, int from, boolean perma) {
punishments.remove(punishment);
punishments.put(punishment, Punishment.createPunishment(id, from, punishment, banReason, time, perma));
}
public void setTeam(int team) {
this.team = team;
updateTeam.update(team, id);
setLeader(false);
}
public void setLeader(boolean leader) {
this.leader = leader;
updateLeader.update(leader, id);
}
public void setLocale(Locale locale, boolean manualLocale) { public void setLocale(Locale locale, boolean manualLocale) {
if (locale == null || (this.manualLocale && !manualLocale)) if (locale == null || (this.manualLocale && !manualLocale))
return; return;
@ -130,42 +269,12 @@ public class SteamwarUser {
updateLocale.update(locale.toLanguageTag(), manualLocale, id); updateLocale.update(locale.toLanguageTag(), manualLocale, id);
} }
public static SteamwarUser get(String userName){ public void setDiscordId(Long discordId) {
SteamwarUser user = usersByName.get(userName.toLowerCase()); usersByDiscord.remove(this.discordId);
if(user != null) this.discordId = discordId;
return user; updateDiscord.update(discordId, id);
return byName.select(userName); if (discordId != null) {
} usersByDiscord.put(discordId, this);
}
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 void createOrUpdateUsername(UUID uuid, String userName) {
insert.update(uuid, userName);
}
public static List<SteamwarUser> getServerTeam() {
return getServerTeam.listSelect();
}
public static List<SteamwarUser> getTeam(int teamId) {
return byTeam.listSelect(teamId);
} }
} }

Datei anzeigen

@ -21,41 +21,120 @@ package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement; import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table; import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@AllArgsConstructor @AllArgsConstructor
public class Team { public class Team {
private static final Table<Team> table = new Table<>(Team.class); private static final Map<Integer, Team> teamCache = new HashMap<>();
private static final SelectStatement<Team> select = table.select(Table.PRIMARY);
@Field(keys = {Table.PRIMARY}) public static void clear() {
teamCache.clear();
}
private static final Table<Team> table = new Table<>(Team.class);
private static final SelectStatement<Team> byId = table.select(Table.PRIMARY);
private static final SelectStatement<Team> byName = new SelectStatement<>(table, "SELECT * FROM Team WHERE (lower(TeamName) = ? OR lower(TeamKuerzel) = ?) AND NOT TeamDeleted");
private static final SelectStatement<Team> all = table.selectFields("TeamDeleted");
private static final Statement insert = table.insertFields("TeamKuerzel", "TeamName");
private static final Statement update = table.update(Table.PRIMARY, "TeamKuerzel", "TeamName", "TeamColor", "Address", "Port");
private static final Statement delete = table.update(Table.PRIMARY, "TeamDeleted");
private static final Statement getSize = new Statement("SELECT COUNT(id) FROM UserData WHERE Team = ?");
@Field(keys = {Table.PRIMARY}, autoincrement = true)
@Getter @Getter
private final int teamId; private final int teamId;
@Field @Field
@Getter @Getter
private final String teamKuerzel; private String teamKuerzel;
@Field @Field
@Getter @Getter
private final String teamName; private String teamName;
@Field(def = "'8'") @Field(def = "'8'")
@Getter @Getter
private final String teamColor; private String teamColor;
@Field(nullable = true)
@Getter
private String address;
@Field(def = "'25565'")
@Getter
private int port;
@Field(def = "0")
private boolean teamDeleted;
private static final Team pub = new Team(0, "PUB", "Öffentlich", "8"); public static void create(String kuerzel, String name){
insert.update(kuerzel, name);
}
public static Team get(int id) { public static Team get(int id) {
if(id == 0) return teamCache.computeIfAbsent(id, byId::select);
return pub; }
return select.select(id);
public static Team get(String name){
// No cache lookup due to low frequency use
name = name.toLowerCase();
return byName.select(name, name);
}
public static List<Team> getAll(){
clear();
List<Team> teams = all.listSelect(false);
teams.forEach(team -> teamCache.put(team.getTeamId(), team));
return teams;
} }
public List<Integer> getMembers(){ public List<Integer> getMembers(){
return SteamwarUser.getTeam(teamId).stream().map(SteamwarUser::getId).collect(Collectors.toList()); return SteamwarUser.getTeam(teamId).stream().map(SteamwarUser::getId).collect(Collectors.toList());
} }
public int size(){
return getSize.select(rs -> {
rs.next();
return rs.getInt("COUNT(id)");
}, teamId);
}
public void disband(SteamwarUser user){
user.setLeader(false);
delete.update(true, teamId);
teamCache.remove(teamId);
TeamTeilnahme.deleteFuture(teamId);
}
public void setTeamKuerzel(String teamKuerzel) {
this.teamKuerzel = teamKuerzel;
updateDB();
}
public void setTeamName(String teamName) {
this.teamName = teamName;
updateDB();
}
public void setTeamColor(String teamColor) {
this.teamColor = teamColor;
updateDB();
}
public void setAddress(String address) {
this.address = address;
updateDB();
}
public void setPort(int port) {
this.port = port;
updateDB();
}
private void updateDB(){
update.update(teamKuerzel, teamName, teamColor, address, port, teamId);
}
} }

Datei anzeigen

@ -21,6 +21,7 @@ package de.steamwar.sql;
import de.steamwar.sql.internal.Field; import de.steamwar.sql.internal.Field;
import de.steamwar.sql.internal.SelectStatement; import de.steamwar.sql.internal.SelectStatement;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.internal.Table; import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -34,6 +35,9 @@ public class TeamTeilnahme {
private static final SelectStatement<TeamTeilnahme> select = table.select(Table.PRIMARY); private static final SelectStatement<TeamTeilnahme> select = table.select(Table.PRIMARY);
private static final SelectStatement<TeamTeilnahme> selectTeams = table.selectFields("EventID"); private static final SelectStatement<TeamTeilnahme> selectTeams = table.selectFields("EventID");
private static final SelectStatement<TeamTeilnahme> selectEvents = table.selectFields("TeamID"); private static final SelectStatement<TeamTeilnahme> 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}) @Field(keys = {Table.PRIMARY})
private final int teamId; private final int teamId;
@ -44,6 +48,18 @@ public class TeamTeilnahme {
return select.select(teamID, eventID) != null; 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<Team> getTeams(int eventID){ public static Set<Team> getTeams(int eventID){
return selectTeams.listSelect(eventID).stream().map(tt -> Team.get(tt.teamId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries) return selectTeams.listSelect(eventID).stream().map(tt -> Team.get(tt.teamId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries)
} }

Datei anzeigen

@ -0,0 +1,94 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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.List;
import java.util.stream.Collectors;
@AllArgsConstructor
public class Tutorial {
private static final Table<Tutorial> table = new Table<>(Tutorial.class);
private static final SelectStatement<Tutorial> by_popularity = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.Released = ? GROUP BY t.TutorialID ORDER BY SUM(r.Stars) DESC LIMIT ?, ?");
private static final SelectStatement<Tutorial> own = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.Creator = ? GROUP BY t.TutorialID ORDER BY t.TutorialID ASC LIMIT ?, ?");
private static final SelectStatement<Tutorial> by_creator_name = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.Creator = ? AND t.Name = ? GROUP BY t.TutorialID");
private static final SelectStatement<Tutorial> by_id = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.TutorialID = ? GROUP BY t.TutorialID");
private static final Statement rate = new Statement("INSERT INTO TutorialRating (TutorialID, UserID, Stars) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Stars = VALUES(Stars)");
private static final Statement create = new Statement("INSERT INTO Tutorial (Creator, Name, Item) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Item = VALUES(Item), Released = 0");
private static final Statement release = table.update(Table.PRIMARY, "released");
private static final Statement delete = table.delete(Table.PRIMARY);
public static List<Tutorial> getPage(int page, int elementsPerPage, boolean released) {
List<Tutorial> tutorials = by_popularity.listSelect(released, page * elementsPerPage, elementsPerPage);
SteamwarUser.batchCache(tutorials.stream().map(tutorial -> tutorial.creator).collect(Collectors.toSet()));
return tutorials;
}
public static List<Tutorial> getOwn(int user, int page, int elementsPerPage) {
return own.listSelect(user, page * elementsPerPage, elementsPerPage);
}
public static Tutorial create(int creator, String name, String item) {
create.update(creator, name, item);
return by_creator_name.select(creator, name);
}
public static Tutorial get(int id) {
return by_id.select(id);
}
@Getter
@Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int tutorialId;
@Getter
@Field(keys = {"CreatorName"})
private final int creator;
@Getter
@Field(keys = {"CreatorName"})
private final String name;
@Getter
@Field(def = "'BOOK'")
private final String item;
@Getter
@Field(def = "0")
private final boolean released;
@Getter
@Field(def = "0") // Not really a field, but necessary for select generation
private final double stars;
public void release() {
release.update(1, tutorialId);
}
public void delete() {
delete.update(tutorialId);
}
public void rate(int user, int rating) {
rate.update(tutorialId, user, rating);
}
}

Datei anzeigen

@ -0,0 +1,178 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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 java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
@AllArgsConstructor
public class UserElo {
private static final int ELO_DEFAULT = 1000;
private static final Map<String, Map<Integer, Optional<Integer>>> gameModeUserEloCache = new ConcurrentHashMap<>();
private static final Map<String, Integer> maxEloCache = new ConcurrentHashMap<>();
private static final Map<Integer, String> emblemCache = new ConcurrentHashMap<>();
public static void clear() {
gameModeUserEloCache.clear();
maxEloCache.clear();
emblemCache.clear();
}
private static final Table<UserElo> table = new Table<>(UserElo.class);
private static final SelectStatement<UserElo> getElo = table.select(Table.PRIMARY);
private static final Statement setElo = table.insertAll();
private static final Statement maxElo = new Statement("SELECT MAX(Elo) AS MaxElo FROM UserElo WHERE Season = ? AND GameMode = ?");
private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM UserElo WHERE GameMode = ? AND Elo > ? AND Season = ?");
private static final Statement fightsOfSeason = new Statement("SELECT COUNT(*) AS Fights FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID WHERE UserID = ? AND GameMode = ? AND UNIX_TIMESTAMP(StartTime) + Duration >= UNIX_TIMESTAMP(?)");
@Field(keys = {Table.PRIMARY})
private final int season;
@Field(keys = {Table.PRIMARY})
private final String gameMode;
@Field(keys = {Table.PRIMARY})
private final int userId;
@Field
private final int elo;
public static int getEloOrDefault(int userID, String gameMode) {
return getElo(userID, gameMode).orElse(ELO_DEFAULT);
}
public static Optional<Integer> getElo(int userID, String gameMode) {
return gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).computeIfAbsent(userID, uid -> Optional.ofNullable(getElo.select(Season.getSeason(), gameMode, userID)).map(userElo -> userElo.elo));
}
public static int getFightsOfSeason(int userID, String gameMode) {
return fightsOfSeason.select(rs -> {
if (rs.next())
return rs.getInt("Fights");
return 0;
}, userID, gameMode, Season.getSeasonStart());
}
private static int getMaxElo(String gameMode) {
return maxEloCache.computeIfAbsent(gameMode, gm -> maxElo.select(rs -> {
if (rs.next())
return rs.getInt("MaxElo");
return 0;
}, Season.getSeason(), gameMode));
}
public static void setElo(int userId, String gameMode, int elo) {
emblemCache.remove(userId);
Optional<Integer> oldElo = Optional.ofNullable(gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).put(userId, Optional.of(elo))).orElse(Optional.empty());
int maxElo = getMaxElo(gameMode);
if (elo > maxElo || (oldElo.isPresent() && oldElo.get() == maxElo)) {
maxEloCache.remove(gameMode);
emblemCache.clear();
}
setElo.update(Season.getSeason(), gameMode, userId, elo);
}
public static int getPlacement(int elo, String gameMode) {
return place.select(rs -> {
if (rs.next())
return rs.getInt("Place") + 1;
return -1;
}, gameMode, elo, Season.getSeason());
}
public static String getEmblem(SteamwarUser user, List<String> rankedModes) {
return emblemCache.computeIfAbsent(user.getId(), userId -> {
switch(
rankedModes.stream().filter(
mode -> UserElo.getFightsOfSeason(user.getId(), mode) >= 10
).map(
mode -> getProgression(user.getId(), mode)
).max(Integer::compareTo).orElse(0)
) {
case 0:
return "";
case 1:
return "§7✧ ";
case 2:
return "§f✦ ";
case 3:
return "§e✶ ";
case 4:
return "§a✷ ";
case 5:
return "§b✸ ";
case 6:
return "§c✹ ";
case 7:
return "§5❂ ";
default:
throw new SecurityException("Progression out of range");
}
});
}
public static String getEmblemProgression(String gameMode, int userId) {
switch (getProgression(userId, gameMode)) {
case 0:
return "§8✧ ✦ ✶ ✷ ✸ ✹ ❂";
case 1:
return "§7✧ §8✦ ✶ ✷ ✸ ✹ ❂";
case 2:
return "§8✧ §f✦ §8✶ ✷ ✸ ✹ ❂";
case 3:
return "§8✧ ✦ §e✶ §8✷ ✸ ✹ ❂";
case 4:
return "§8✧ ✦ ✶ §a✷ §8✸ ✹ ❂";
case 5:
return "§8✧ ✦ ✶ ✷ §b✸ §8✹ ❂";
case 6:
return "§8✧ ✦ ✶ ✷ ✸ §c✹ §8❂";
case 7:
return "§8✧ ✦ ✶ ✷ ✸ ✹ §5❂";
default:
throw new SecurityException("Progression is not in range");
}
}
private static int getProgression(int userId, String gameMode) {
int elo = getElo(userId, gameMode).orElse(0);
if(elo == 0)
return 0;
int maxElo = getMaxElo(gameMode);
if (elo > maxElo * 0.99) return 7;
if (elo > maxElo * 0.97) return 6;
if (elo > maxElo * 0.94) return 5;
if (elo > maxElo * 0.88) return 4;
if (elo > maxElo * 0.76) return 3;
if (elo > maxElo * 0.51) return 2;
return 1;
}
}

Datei anzeigen

@ -1,21 +1,21 @@
/* /*
This file is a part of the SteamWar software. * This file is a part of the SteamWar software.
*
Copyright (C) 2020 SteamWar.de-Serverteam * Copyright (C) 2023 SteamWar.de-Serverteam
*
This program is free software: you can redistribute it and/or modify * 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 * 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 * the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. * (at your option) any later version.
*
This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
*
You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.steamwar.sql; package de.steamwar.sql;
@ -24,22 +24,35 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum UserGroup { public enum UserGroup {
Admin("§4", "§e", true, true, true), Admin("§4", "§e", "Admin", true, true, true, true),
Developer("§3", "§f", true, true, true), Developer("§3", "§f", "Dev", true, true, true, true),
Moderator("§c", "§f", true, true, true), Moderator("§c", "§f", "Mod", true, true, true, true),
Supporter("§9", "§f", false, true, true), Supporter("§9", "§f", "Sup", false, true, true, true),
Builder("§2", "§f", false, true, false), Builder("§2", "§f", "Arch", false, true, false, true),
YouTuber("§5", "§f", false, false, false), YouTuber("§5", "§f", "YT", false, false, false, true),
Member("§7", "§7", false, false, false); Member("§7", "§7", "", false, false, false, false);
@Getter @Getter
private final String colorCode; private final String colorCode;
@Getter @Getter
private final String chatColorCode; private final String chatColorCode;
@Getter @Getter
private final boolean adminGroup; private final String chatPrefix;
@Getter @Getter
private final boolean teamGroup; private final boolean adminGroup;
@Getter @Getter
private final boolean checkSchematics; 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);
}
} }

Datei anzeigen

@ -95,7 +95,7 @@ public class Statement implements AutoCloseable {
} }
} }
private static int connectionBudget = MAX_CONNECTIONS; private static volatile int connectionBudget = MAX_CONNECTIONS;
public static void closeAll() { public static void closeAll() {
synchronized (connections) { synchronized (connections) {
@ -234,7 +234,7 @@ public class Statement implements AutoCloseable {
private static Connection aquireConnection() { private static Connection aquireConnection() {
synchronized (connections) { synchronized (connections) {
while(connections.isEmpty() && connectionBudget == 0) while(connections.isEmpty() && connectionBudget <= 0)
waitOnConnections(); waitOnConnections();
if(!connections.isEmpty()) { if(!connections.isEmpty()) {