Full CommonDB untested
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
Lixfel 2022-09-20 16:41:07 +02:00
Ursprung c1e175c3e8
Commit 1758fc4297
15 geänderte Dateien mit 1167 neuen und 5 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,71 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <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.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.sql.Timestamp;
import java.util.List;
@AllArgsConstructor
public class CheckedSchematic {
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");
public static List<CheckedSchematic> getLastDeclinedOfNode(int node){
return statusOfNode.listSelect(node);
}
@Field(nullable = true)
private final Integer nodeId;
@Field
private final int nodeOwner;
@Field
private final String nodeName;
@Getter
@Field
private final int validator;
@Getter
@Field
private final Timestamp startTime;
@Getter
@Field
private final Timestamp endTime;
@Getter
@Field
private final String declineReason;
public int getNode() {
return nodeId;
}
public String getSchemName() {
return nodeName;
}
public int getSchemOwner() {
return nodeOwner;
}
}

Datei anzeigen

@ -0,0 +1,69 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 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.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Timestamp;
import java.time.Instant;
@AllArgsConstructor
public class NodeDownload {
private static final char[] HEX = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private static final String LINK_BASE = "https://steamwar.de/download.php?schem=";
private static final Table<NodeDownload> table = new Table<>(NodeDownload.class);
private static final Statement insert = table.insertFields("NodeId", "Link");
@Field(keys = {Table.PRIMARY})
private final int nodeId;
@Field
private final String link;
@Field(def = "CURRENT_TIMESTAMP")
private final Timestamp timestamp;
public static String getLink(SchematicNode schem){
if(schem.isDir())
throw new SecurityException("Can not Download Directorys");
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
throw new SecurityException(e);
}
digest.reset();
digest.update((Instant.now().toString() + schem.getOwner() + schem.getId()).getBytes());
String hash = base16encode(digest.digest());
insert.update(schem.getId(), hash);
return LINK_BASE + hash;
}
public static String base16encode(byte[] byteArray) {
StringBuilder hexBuffer = new StringBuilder(byteArray.length * 2);
for (byte b : byteArray)
hexBuffer.append(HEX[b >> 4]).append(HEX[b & 0xF]);
return hexBuffer.toString();
}
}

Datei anzeigen

@ -0,0 +1,119 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <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.SqlTypeMapper;
import de.steamwar.sql.internal.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.sql.Timestamp;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@AllArgsConstructor
public class Punishment {
static {
SqlTypeMapper.nameEnumMapper(PunishmentType.class);
}
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> getPunishment = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1");
@Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int punishmentId;
@Field
@Getter
private final int user;
@Field
@Getter
private final int punisher;
@Field
@Getter
private final PunishmentType type;
@Field
@Getter
private final Timestamp startTime;
@Field
@Getter
private final Timestamp endTime;
@Field
@Getter
private final boolean perma;
@Field
@Getter
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
public String getBantime(Timestamp endTime, boolean perma) {
if (perma) {
return "permanent";
} else {
return endTime.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"));
}
}
public boolean isCurrent() {
return isPerma() || getEndTime().after(new Date());
}
@AllArgsConstructor
@Getter
public enum PunishmentType {
Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"),
Mute( false, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE"),
NoSchemReceiving(false, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"),
NoSchemSharing(false, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"),
NoSchemSubmitting(true, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"),
NoDevServer(true, "NODEVSERVER_TEAM", "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", "UNNODEVSERVER");
private final boolean needsAdmin;
private final String teamMessage;
private final String playerMessagePerma;
private final String playerMessageUntil;
private final String usageNotPunished;
private final String unpunishmentMessage;
}
}

Datei anzeigen

@ -28,4 +28,6 @@ public interface SQLWrapper {
SQLWrapper impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLWrapperImpl");
void loadSchemTypes(List<SchematicType> tmpTypes, Map<String, SchematicType> tmpFromDB);
void additionalExceptionMetadata(StringBuilder builder);
}

Datei anzeigen

@ -0,0 +1,52 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <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.io.File;
@AllArgsConstructor
public class SWException {
private static final String CWD = System.getProperty("user.dir");
private static final String SERVER_NAME = new File(CWD).getName();
private static final Table<SWException> table = new Table<>(SWException.class, "Exception");
private static final Statement insert = table.insertAll();
@Field
private final String server;
@Field
private final String message;
@Field
private final String stacktrace;
public static void log(String message, String stacktrace){
StringBuilder msgBuilder = new StringBuilder(message);
SQLWrapper.impl.additionalExceptionMetadata(msgBuilder);
msgBuilder.append("\nCWD: ").append(CWD);
insert.update(SERVER_NAME, msgBuilder.toString(), stacktrace);
}
}

Datei anzeigen

@ -0,0 +1,43 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <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.Table;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class SchemElo {
private static final Table<SchemElo> table = new Table<>(SchemElo.class);
private static final SelectStatement<SchemElo> select = table.select(Table.PRIMARY);
@Field(keys = {Table.PRIMARY})
private final int schemId;
@Field
private final int elo;
@Field(keys = {Table.PRIMARY})
private final int season;
public static int getElo(SchematicNode node, int season) {
return select.select(node, season).elo;
}
}

Datei anzeigen

@ -0,0 +1,543 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.sql;
import de.steamwar.sql.internal.*;
import lombok.AccessLevel;
import lombok.Setter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public class SchematicNode {
static {
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId));
}
private static final Map<Integer, Map<String, List<String>>> TAB_CACHE = new HashMap<>();
public static void clear() {
TAB_CACHE.clear();
}
private static final String[] fields = {"NodeId", "NodeOwner", "NodeName", "ParentNode", "LastUpdate", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay", "NodeFormat"};
private static String nodeSelectCreator(String itemPrefix) {
return "SELECT " + Arrays.stream(fields).map(s -> itemPrefix + s).collect(Collectors.joining(", ")) + " FROM SchematicNode ";
}
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 update = table.insertAll();
private static final Statement delete = table.delete(Table.PRIMARY);
private static final SelectStatement<SchematicNode> byId = table.select(Table.PRIMARY);
private static final SelectStatement<SchematicNode> byOwnerNameParent = table.select("OwnerNameParent");
private static final SelectStatement<SchematicNode> byOwnerNameParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode is NULL");
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL ORDER BY NodeName");
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName");
private static final SelectStatement<SchematicNode> dirsByParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byParentName = table.selectFields("NodeName", "ParentNode");
private static final SelectStatement<SchematicNode> byParentName_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeName = ? AND ParentNode is NULL");
private static final SelectStatement<SchematicNode> accessibleByUserTypeParent = new SelectStatement<>(table, "WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? UNION " + nodeSelectCreator("SN.") + "AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> accessibleByUserTypeParent_Null = new SelectStatement<>(table, "WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? UNION " + nodeSelectCreator("SN.") + "AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode is null ORDER BY NodeName");
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeType = ? ORDER BY NodeName");
private static final SelectStatement<SchematicNode> accessibleByUser = new SelectStatement<>(table, nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND ((s.NodeOwner = ? AND s.ParentNode IS NULL) OR NOT s.NodeOwner = ?) GROUP BY s.NodeId ORDER BY s.NodeName");
private static final Statement schematicAccessibleForUser = new Statement("WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN LEFT Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1");
private static final SelectStatement<SchematicNode> allAccessibleByUser = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
@Field(keys = {Table.PRIMARY}, autoincrement = true)
private final int nodeId;
@Field(keys = {"OwnerNameParent"})
private final int nodeOwner;
@Field(keys = {"OwnerNameParent"})
private String nodeName;
@Field(keys = {"OwnerNameParent"}, nullable = true)
private Integer parentNode;
@Field(def = "CURRENT_TIMESTAMP")
private Timestamp lastUpdate;
@Field(def = "''")
private String nodeItem;
@Field(def = "'normal'", nullable = true)
private SchematicType nodeType;
@Field(def = "0")
private int nodeRank;
@Field(def = "1")
private boolean replaceColor;
@Field(def = "1")
private boolean allowReplay;
@Setter(AccessLevel.PACKAGE)
@Field(def = "1")
private boolean nodeFormat;
private final Map<Integer, String> brCache = new HashMap<>();
public SchematicNode(
int nodeId,
int nodeOwner,
String nodeName,
Integer parentNode,
Timestamp lastUpdate,
String nodeItem,
SchematicType nodeType,
int nodeRank,
boolean replaceColor,
boolean allowReplay,
boolean nodeFormat
) {
this.nodeId = nodeId;
this.nodeOwner = nodeOwner;
this.nodeName = nodeName;
this.parentNode = parentNode;
this.nodeItem = nodeItem;
this.nodeType = nodeType;
this.lastUpdate = lastUpdate;
this.nodeRank = nodeRank;
this.replaceColor = replaceColor;
this.allowReplay = allowReplay;
this.nodeFormat = nodeFormat;
}
public static SchematicNode createSchematic(int owner, String name, Integer parent) {
return createSchematicNode(owner, name, parent, SchematicType.Normal.toDB(), "");
}
public static SchematicNode createSchematicDirectory(int owner, String name, Integer parent) {
return createSchematicNode(owner, name, parent, null, "");
}
public static SchematicNode createSchematicNode(int owner, String name, Integer parent, String type, String item) {
if (parent != null && parent == 0)
parent = null;
int nodeId = create.insertGetKey(owner, name, parent, type, item);
return getSchematicNode(nodeId);
}
public static SchematicNode getSchematicNode(int owner, String name, SchematicNode parent) {
return getSchematicNode(owner, name, parent.getId());
}
public static SchematicNode getSchematicNode(int owner, String name, Integer parent) {
if (parent == null || parent == 0)
return byOwnerNameParent_null.select(owner, name);
return byOwnerNameParent.select(owner, name, parent);
}
public static List<SchematicNode> getSchematicNodeInNode(SchematicNode parent) {
return getSchematicNodeInNode(parent.getId());
}
public static List<SchematicNode> getSchematicNodeInNode(Integer parent) {
if(parent == null || parent == 0) {
rootWarning();
return byParent_null.listSelect();
}
return byParent.listSelect(parent);
}
public static List<SchematicNode> getSchematicDirectoryInNode(Integer parent) {
if(parent == null || parent == 0) {
rootWarning();
return dirsByParent_null.listSelect();
}
return dirsByParent.listSelect(parent);
}
@Deprecated
public static SchematicNode getSchematicDirectory(String name, SchematicNode parent) {
return getSchematicNode(name, parent.getId());
}
@Deprecated
public static SchematicNode getSchematicDirectory(String name, Integer parent) {
return getSchematicNode(name, parent);
}
public static SchematicNode getSchematicNode(String name, Integer parent) {
if(parent == null || parent == 0) {
rootWarning();
return byParentName_null.select(name);
}
return byParentName.select(name, parent);
}
public static SchematicNode getSchematicNode(int id) {
return byId.select(id);
}
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
if(parent == null || parent == 0)
return accessibleByUserTypeParent_Null.listSelect(owner, owner, schemType);
return accessibleByUserTypeParent.listSelect(owner, owner, schemType, parent);
}
public static List<SchematicNode> getAllAccessibleSchematicsOfType(int user, String schemType) {
return accessibleByUserType.listSelect(user, user, schemType);
}
public static List<SchematicNode> getAllSchematicsOfType(int owner, String schemType) {
return byOwnerType.listSelect(owner, schemType);
}
@Deprecated
public static List<SchematicNode> getAllSchematicsOfType(String schemType) {
return byType.listSelect(schemType);
}
public static List<SchematicNode> getAllSchematicsOfType(SchematicType schemType) {
return byType.listSelect(schemType);
}
public static List<SchematicNode> deepGet(Integer parent, Predicate<SchematicNode> filter) {
List<SchematicNode> finalList = new ArrayList<>();
List<SchematicNode> nodes = SchematicNode.getSchematicNodeInNode(parent);
nodes.forEach(node -> {
if (node.isDir()) {
finalList.addAll(deepGet(node.getId(), filter));
} else {
if (filter.test(node))
finalList.add(node);
}
});
return finalList;
}
public static List<SchematicNode> getSchematicsAccessibleByUser(int user, Integer parent) {
if (parent == null || parent == 0)
return accessibleByUser.listSelect(user, user, user, user);
if(schematicAccessibleForUser.select(rs -> {
rs.next();
return rs.getInt("Accessible") > 0;
}, parent, user, user))
return getSchematicNodeInNode(parent);
return Collections.emptyList();
}
public static List<SchematicNode> getAllSchematicsAccessibleByUser(int user) {
return allAccessibleByUser.listSelect(user, user);
}
public static List<SchematicNode> getAllParentsOfNode(SchematicNode node) {
return getAllParentsOfNode(node.getId());
}
public static List<SchematicNode> getAllParentsOfNode(int node) {
return allParentsOfNode.listSelect(node);
}
public static SchematicNode getNodeFromPath(SteamwarUser user, String s) {
if (s.startsWith("/")) {
s = s.substring(1);
}
if (s.isEmpty()) {
return null;
}
if (s.contains("/")) {
String[] layers = s.split("/");
SchematicNode currentNode = null;
for (int i = 0; i < layers.length; i++) {
int finalI = i;
Optional<SchematicNode> node;
if (currentNode == null) {
node = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(layers[finalI])).findAny();
} else {
node = Optional.ofNullable(SchematicNode.getSchematicNode(layers[i], currentNode.getId()));
}
if (!node.isPresent()) {
return null;
} else {
currentNode = node.get();
if (!currentNode.isDir() && i != layers.length - 1) {
return null;
}
}
}
return currentNode;
} else {
String finalS = s;
return SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(finalS)).findAny().orElse(null);
}
}
public static List<SchematicNode> filterSchems(int user, Predicate<SchematicNode> filter) {
List<SchematicNode> finalList = new ArrayList<>();
List<SchematicNode> nodes = getSchematicsAccessibleByUser(user, null);
nodes.forEach(node -> {
if (node.isDir()) {
finalList.addAll(deepGet(node.getId(), filter));
} else {
if (filter.test(node))
finalList.add(node);
}
});
return finalList;
}
@Deprecated
public static Integer countNodes() {
return -1;
}
public int getId() {
return nodeId;
}
public int getOwner() {
return nodeOwner;
}
public String getName() {
return nodeName;
}
public void setName(String name) {
this.nodeName = name;
updateDB();
}
public Integer getParent() {
return parentNode;
}
public void setParent(Integer parent) {
this.parentNode = parent;
updateDB();
}
public String getItem() {
if (nodeItem.isEmpty()) {
return isDir() ? "CHEST" : "CAULDRON_ITEM";
}
return nodeItem;
}
public void setItem(String item) {
this.nodeItem = item;
updateDB();
}
@Deprecated
public String getType() {
return nodeType.name();
}
@Deprecated
public void setType(String type) {
if(isDir())
throw new SecurityException("Node is Directory");
this.nodeType = SchematicType.fromDB(type);
updateDB();
}
public boolean isDir() {
return nodeType == null;
}
public boolean getSchemFormat() {
if(isDir())
throw new SecurityException("Node is Directory");
return nodeFormat;
}
public int getRank() {
if(isDir())
throw new SecurityException("Node is Directory");
return nodeRank;
}
@Deprecated
public int getRankUnsafe() {
return nodeRank;
}
public void setRank(int rank) {
if(isDir())
throw new SecurityException("Node is Directory");
this.nodeRank = rank;
}
public SchematicType getSchemtype() {
if(isDir())
throw new SecurityException("Is Directory");
return nodeType;
}
public void setSchemtype(SchematicType type) {
if(isDir())
throw new SecurityException("Is Directory");
this.nodeType = type;
updateDB();
}
public boolean replaceColor() {
return replaceColor;
}
public void setReplaceColor(boolean replaceColor) {
if(isDir())
throw new SecurityException("Is Directory");
this.replaceColor = replaceColor;
updateDB();
}
public boolean allowReplay() {
return allowReplay;
}
public void setAllowReplay(boolean allowReplay) {
if(isDir())
throw new SecurityException("Is Directory");
this.allowReplay = allowReplay;
updateDB();
}
public SchematicNode getParentNode() {
if(parentNode == null) return null;
return SchematicNode.getSchematicNode(parentNode);
}
public int getElo(int season) {
return SchemElo.getElo(this, season);
}
public boolean accessibleByUser(int user) {
return NodeMember.getNodeMember(nodeId, user) != null;
}
public Set<NodeMember> getMembers() {
return NodeMember.getNodeMembers(nodeId);
}
public Timestamp getLastUpdate() {
return lastUpdate;
}
private void updateDB() {
this.lastUpdate = Timestamp.from(Instant.now());
update.update(nodeId, nodeOwner, nodeName, parentNode, nodeItem, nodeType, lastUpdate, nodeRank, replaceColor, allowReplay, nodeFormat);
this.brCache.clear();
TAB_CACHE.clear();
}
public void delete() {
delete.update(nodeId);
}
@Override
public int hashCode() {
return nodeId;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SchematicNode))
return false;
return ((SchematicNode) obj).getId() == nodeId;
}
public String generateBreadcrumbs(SteamwarUser user) {
return brCache.computeIfAbsent(user.getId(), integer -> generateBreadcrumbs("/", user));
}
public String generateBreadcrumbs(String split, SteamwarUser user) {
StringBuilder builder = new StringBuilder(getName());
SchematicNode currentNode = this;
if (currentNode.isDir()) builder.append("/");
final Set<NodeMember> nodeMembers = NodeMember.getSchematics(user.getId());
AtomicInteger i = new AtomicInteger();
i.set(currentNode.getId());
while (currentNode.getParentNode() != null && nodeMembers.stream().noneMatch(nodeMember -> nodeMember.getNode() == i.get())) {
currentNode = currentNode.getParentNode();
i.set(currentNode.getId());
builder.insert(0, split)
.insert(0, currentNode.getName());
}
return builder.toString();
}
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
public static boolean invalidSchemName(String[] layers) {
for (String layer : layers) {
if (layer.isEmpty()) {
return true;
}
if (layer.contains("/") ||
layer.contains("\\") ||
layer.contains("<") ||
layer.contains(">") ||
layer.contains("^") ||
layer.contains("°") ||
layer.contains("'") ||
layer.contains("\"") ||
layer.contains(" ")) {
return true;
}
if(FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
return true;
}
}
return false;
}
public static List<String> getNodeTabcomplete(SteamwarUser user, String s) {
boolean sws = s.startsWith("/");
if (sws) {
s = s.substring(1);
}
int index = s.lastIndexOf("/");
String cacheKey = index == -1 ? "" : s.substring(0, index);
if(TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
return new ArrayList<>(TAB_CACHE.get(user.getId()).get(cacheKey));
}
List<String> list = new ArrayList<>();
if (s.contains("/")) {
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
if (pa == null) return Collections.emptyList();
List<SchematicNode> nodes = SchematicNode.getSchematicNodeInNode(pa);
nodes.forEach(node -> list.add((sws ? "/" : "") + node.generateBreadcrumbs(user)));
} else {
List<SchematicNode> nodes = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0);
nodes.forEach(node -> list.add((sws ? "/" : "") + node.getName() + (node.isDir() ? "/" : "")));
}
list.remove("//copy");
TAB_CACHE.computeIfAbsent(user.getId(), integer -> new HashMap<>()).putIfAbsent(cacheKey, list);
return list;
}
private static void rootWarning() {
ByteArrayOutputStream stacktraceOutput = new ByteArrayOutputStream();
new Throwable().printStackTrace(new PrintStream(stacktraceOutput));
SWException.log("PERFORMANCE!!! Getting all/weird subset of schematic nodes with parent NULL", stacktraceOutput.toString());
}
}

Datei anzeigen

@ -101,7 +101,7 @@ public class SchematicType {
}
public static SchematicType fromDB(String input){
return fromDB.getOrDefault(input.toLowerCase(), null);
return fromDB.get(input.toLowerCase());
}
public static List<SchematicType> values(){

Datei anzeigen

@ -0,0 +1,54 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.sql;
import java.util.Calendar;
public class Season {
private Season() {}
public static int getSeason() {
Calendar calendar = Calendar.getInstance();
int yearIndex = calendar.get(Calendar.MONTH) / 4;
return (calendar.get(Calendar.YEAR) * 3 + yearIndex);
}
public static String getSeasonStart() {
Calendar calendar = Calendar.getInstance();
return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) / 4 * 3 + 1) + "-1";
}
public static String convertSeasonToString(int season){
if (season == -1) return "";
int yearSeason = season % 3;
int year = (season - yearSeason) / 3;
return String.format("%d-%d", year, yearSeason);
}
public static int convertSeasonToNumber(String season){
if (season.isEmpty()) return -1;
String[] split = season.split("-");
try {
return Integer.parseInt(split[0]) * 3 + Integer.parseInt(split[1]);
} catch (NumberFormatException e) {
return -1;
}
}
}

Datei anzeigen

@ -42,6 +42,7 @@ public class SteamwarUser {
private static final SelectStatement<SteamwarUser> byUUID = table.selectFields("UUID");
private static final SelectStatement<SteamwarUser> byName = table.selectFields("UserName");
private static final SelectStatement<SteamwarUser> byDiscord = table.selectFields("DiscordId");
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 Statement updateName = table.update(Table.PRIMARY, "UserName");
private static final Statement updateLocale = table.update(Table.PRIMARY, "Locale", "ManualLocale");
@ -147,7 +148,15 @@ public class SteamwarUser {
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

@ -0,0 +1,61 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <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.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.List;
import java.util.stream.Collectors;
@AllArgsConstructor
public class Team {
private static final Table<Team> table = new Table<>(Team.class);
private static final SelectStatement<Team> select = table.select(Table.PRIMARY);
@Field(keys = {Table.PRIMARY})
@Getter
private final int teamId;
@Field
@Getter
private final String teamKuerzel;
@Field
@Getter
private final String teamName;
@Field(def = "'8'")
@Getter
private final String teamColor;
private static final Team pub = new Team(0, "PUB", "Öffentlich", "8");
public static Team get(int id) {
if(id == 0)
return pub;
return select.select(id);
}
public List<Integer> getMembers(){
return SteamwarUser.getTeam(teamId).stream().map(SteamwarUser::getId).collect(Collectors.toList());
}
}

Datei anzeigen

@ -0,0 +1,54 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <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.Table;
import lombok.AllArgsConstructor;
import java.util.Set;
import java.util.stream.Collectors;
@AllArgsConstructor
public class TeamTeilnahme {
private static final Table<TeamTeilnahme> table = new Table<>(TeamTeilnahme.class);
private static final SelectStatement<TeamTeilnahme> select = table.select(Table.PRIMARY);
private static final SelectStatement<TeamTeilnahme> selectTeams = table.selectFields("EventID");
private static final SelectStatement<TeamTeilnahme> selectEvents = table.selectFields("TeamID");
@Field(keys = {Table.PRIMARY})
private final int teamId;
@Field(keys = {Table.PRIMARY})
private final int eventId;
public static boolean nimmtTeil(int teamID, int eventID){
return select.select(teamID, eventID) != null;
}
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)
}
public static Set<Event> getEvents(int teamID){
return selectEvents.listSelect(teamID).stream().map(tt -> Event.get(tt.eventId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries)
}
}

Datei anzeigen

@ -0,0 +1,72 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <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.UUID;
@AllArgsConstructor
public class UserConfig {
private static final Table<UserConfig> table = new Table<>(UserConfig.class);
private static final SelectStatement<UserConfig> 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 user;
@Field(keys = {Table.PRIMARY})
private final String config;
@Field
private final String value;
public static String getConfig(UUID player, String config) {
return getConfig(SteamwarUser.get(player).getId(), config);
}
public static String getConfig(int player, String config) {
return select.select(player, config).value;
}
public static void updatePlayerConfig(UUID uuid, String config, String value) {
updatePlayerConfig(SteamwarUser.get(uuid).getId(), config, value);
}
public static void updatePlayerConfig(int id, String config, String value) {
if (value == null) {
removePlayerConfig(id, config);
return;
}
insert.update(id, config, value);
}
public static void removePlayerConfig(UUID uuid, String config) {
removePlayerConfig(SteamwarUser.get(uuid).getId(), config);
}
public static void removePlayerConfig(int id, String config) {
delete.update(id, config);
}
}

Datei anzeigen

@ -39,10 +39,14 @@ public class Statement implements AutoCloseable {
private static final Supplier<Connection> conProvider;
static final Consumer<Table<?>> schemaCreator;
private static final boolean mysqlMode;
private static final boolean productionDatabase;
static {
File file = new File(System.getProperty("user.home"), "mysql.properties");
mysqlMode = file.exists();
if(file.exists()) {
if(mysqlMode) {
Properties properties = new Properties();
try {
properties.load(new FileReader(file));
@ -54,6 +58,7 @@ public class Statement implements AutoCloseable {
String user = properties.getProperty("user");
String password = properties.getProperty("password");
productionDatabase = "core".equals(properties.getProperty("database"));
MAX_CONNECTIONS = SQLConfig.impl.maxConnections();
conProvider = () -> {
try {
@ -64,7 +69,6 @@ public class Statement implements AutoCloseable {
};
schemaCreator = table -> {};
} else {
MAX_CONNECTIONS = 1;
Connection connection;
try {
@ -74,6 +78,8 @@ public class Statement implements AutoCloseable {
throw new SecurityException("Could not create sqlite connection", e);
}
productionDatabase = false;
MAX_CONNECTIONS = 1;
conProvider = () -> connection;
schemaCreator = Table::ensureExistanceInSqlite;
}
@ -92,6 +98,14 @@ public class Statement implements AutoCloseable {
}
}
public static boolean mysqlMode() {
return mysqlMode;
}
public static boolean productionDatabase() {
return productionDatabase;
}
private final boolean returnGeneratedKeys;
private final String sql;
private final Map<Connection, PreparedStatement> cachedStatements = new HashMap<>();

Datei anzeigen

@ -59,7 +59,6 @@ public class Table<T> {
Statement.schemaCreator.accept(this);
}
public SelectStatement<T> select(String name) {
return selectFields(keyFields(name));
}
@ -108,7 +107,7 @@ public class Table<T> {
List<TableField<?>> primaryKey = keys.containsKey(PRIMARY) ? Arrays.asList(keys.get(PRIMARY)) : Collections.emptyList();
try (Statement statement = new Statement(
"CREATE TABLE IF NOT EXISTS " + name + "(" +
Arrays.stream(fields).map(field -> field.identifier + " " + field.mapper.sqlType() + (field.field.nullable() ? "" : " NOT NULL DEFAULT NULL") + (!field.field.nullable() && field.field.def().equals("") ? "" : " DEFAULT " + field.field.def()) + (primaryKey.contains(field) ? " PRIMARY KEY" : "") + (field.field.autoincrement() ? " AUTOINCREMENT" : "")).collect(Collectors.joining(", ")) +
Arrays.stream(fields).map(field -> field.identifier + " " + field.mapper.sqlType() + (field.field.nullable() ? " DEFAULT NULL" : " NOT NULL") + (field.field.nullable() || field.field.def().equals("") ? "" : " DEFAULT " + field.field.def()) + (primaryKey.contains(field) ? " PRIMARY KEY" : "") + (field.field.autoincrement() ? " AUTOINCREMENT" : "")).collect(Collectors.joining(", ")) +
keys.entrySet().stream().filter(entry -> !entry.getKey().equals(PRIMARY)).map(key -> ", UNIQUE (" + Arrays.stream(key.getValue()).map(field -> field.identifier).collect(Collectors.joining(", ")) + ")").collect(Collectors.joining(" ")) +
") STRICT, WITHOUT ROWID")) {
statement.update();