WIP CommonDB: Milestone SWUser
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Lixfel 2023-02-21 18:22:06 +01:00
Ursprung fbb07b1733
Commit 8dbf62e560
8 geänderte Dateien mit 541 neuen und 98 gelöschten Zeilen

Datei anzeigen

@ -37,6 +37,7 @@ public class BannedUserIPs {
private static final SelectStatement<BannedUserIPs> getByID = table.selectFields("UserID"); 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 SelectStatement<BannedUserIPs> getByIP = new SelectStatement<>(table, "SELECT * FROM BannedUserIPs WHERE IP = ? ORDER BY Timestamp DESC");
private static final Statement banIP = table.insert(Table.PRIMARY); private static final Statement banIP = table.insert(Table.PRIMARY);
private static final Statement unbanIPs = table.deleteFields("UserID");
@Getter @Getter
@Field(keys = {Table.PRIMARY}) @Field(keys = {Table.PRIMARY})
@ -58,4 +59,8 @@ public class BannedUserIPs {
public static void banIP(int userID, String ip){ public static void banIP(int userID, String ip){
banIP.update(userID, ip); banIP.update(userID, ip);
} }
public static void unbanIPs(int userID) {
unbanIPs.update(userID);
}
} }

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,26 +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.ArrayList;
import java.util.List; 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).toArray(Integer[]::new));
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
@ -52,15 +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;
@Getter
private final List<FightPlayer> bluePlayers = new ArrayList<>(); private final List<FightPlayer> bluePlayers = new ArrayList<>();
@Getter
private final List<FightPlayer> redPlayers = new ArrayList<>(); private final List<FightPlayer> 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){ public SchematicType getSchemType() {
return insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition); 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);
}
} }
} }

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

@ -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,32 @@ 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 {
public 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 +54,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

@ -22,7 +22,10 @@ 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;
public class SteamwarUser { public class SteamwarUser {
@ -44,12 +47,17 @@ 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 SelectStatement<SteamwarUser> batchGet = new SelectStatement<>(table, "SELECT * FROM UserData WHERE id IN ?");
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<>();
@ -69,67 +77,6 @@ public class SteamwarUser {
usersByUUID.remove(user.getUUID()); usersByUUID.remove(user.getUUID());
} }
@Getter
@Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int id;
@Field(keys = {"uuid"})
private final UUID uuid;
@Getter
@Field
private String userName;
@Getter
@Field(def = "'Member'")
private final UserGroup userGroup;
@Getter
@Field(def = "0")
private int team;
@Field(def = "0")
private boolean leader;
@Field(nullable = true)
private Locale locale;
@Field(def = "0")
private boolean manualLocale;
@Field(keys = {"discordId"}, nullable = true)
private Long discordId;
public SteamwarUser(int id, UUID uuid, String userName, UserGroup userGroup, int team, boolean leader, Locale locale, boolean manualLocale, Long discordId) {
this.id = id;
this.uuid = uuid;
this.userName = userName;
this.userGroup = userGroup;
this.team = team;
this.leader = leader;
this.locale = locale;
this.manualLocale = manualLocale;
this.discordId = discordId != null && discordId != 0 ? discordId : null;
usersById.put(id, this);
usersByName.put(userName.toLowerCase(), this);
usersByUUID.put(uuid, this);
if (this.discordId != null) {
usersByDiscord.put(discordId, this);
}
}
public UUID getUUID() {
return uuid;
}
public Locale getLocale() {
if(locale != null)
return locale;
return Locale.getDefault();
}
public void setLocale(Locale locale, boolean manualLocale) {
if (locale == null || (this.manualLocale && !manualLocale))
return;
this.locale = locale;
this.manualLocale = manualLocale;
updateLocale.update(locale.toLanguageTag(), manualLocale, id);
}
public static SteamwarUser get(String userName){ public static SteamwarUser get(String userName){
SteamwarUser user = usersByName.get(userName.toLowerCase()); SteamwarUser user = usersByName.get(userName.toLowerCase());
if(user != null) if(user != null)
@ -157,8 +104,22 @@ public class SteamwarUser {
return byDiscord.select(discordId); return byDiscord.select(discordId);
} }
public static void createOrUpdateUsername(UUID uuid, String userName) { public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer, BiConsumer<String, String> nameUpdate) {
insert.update(uuid, userName); SteamwarUser user = SteamwarUser.get(uuid);
if (user != null) {
if (!user.userName.equals(name)) {
updateName.update(name, user.id);
nameUpdate.accept(user.userName, name);
user.userName = name;
}
} else {
insert.update(uuid, name);
newPlayer.accept(uuid);
return get(uuid);
}
return user;
} }
public static List<SteamwarUser> getServerTeam() { public static List<SteamwarUser> getServerTeam() {
@ -168,4 +129,137 @@ public class SteamwarUser {
public static List<SteamwarUser> getTeam(int teamId) { public static List<SteamwarUser> getTeam(int teamId) {
return byTeam.listSelect(teamId); return byTeam.listSelect(teamId);
} }
public static void batchCache(Set<Integer> ids) {
ids.removeIf(usersById::containsKey);
if(ids.isEmpty())
return;
batchGet.listSelect((Object) ids.toArray());
}
@Getter
@Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int id;
@Field(keys = {"uuid"})
private final UUID uuid;
@Getter
@Field
private String userName;
@Getter
@Field(def = "'Member'")
private final UserGroup userGroup;
@Getter
@Field(def = "0")
private int team;
@Getter
@Field(def = "0")
private boolean leader;
@Field(nullable = true)
private Locale locale;
@Field(def = "0")
private boolean manualLocale;
@Getter
@Field(keys = {"discordId"}, nullable = true)
private Long discordId;
private final 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) {
this.id = id;
this.uuid = uuid;
this.userName = userName;
this.userGroup = userGroup;
this.team = team;
this.leader = leader;
this.locale = locale;
this.manualLocale = manualLocale;
this.discordId = discordId != null && discordId != 0 ? discordId : null;
usersById.put(id, this);
usersByName.put(userName.toLowerCase(), this);
usersByUUID.put(uuid, this);
if (this.discordId != null) {
usersByDiscord.put(discordId, this);
}
punishments = Punishment.getPunishmentsOfPlayer(id); //TODO load always on Subservers?
}
public UUID getUUID() {
return uuid;
}
public Locale getLocale() {
if(locale != null)
return locale;
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) {
if (locale == null || (this.manualLocale && !manualLocale))
return;
this.locale = locale;
this.manualLocale = manualLocale;
updateLocale.update(locale.toLanguageTag(), manualLocale, id);
}
public void setDiscordId(Long discordId) {
usersByDiscord.remove(this.discordId);
this.discordId = discordId;
updateDiscord.update(discordId, id);
if (discordId != null) {
usersByDiscord.put(discordId, this);
}
}
} }

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 id;
@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, id);
}
public void delete() {
delete.update(id);
}
public void rate(int user, int rating) {
rate.update(id, user, rating);
}
}