Dieser Commit ist enthalten in:
Commit
e604991cfd
@ -36,6 +36,7 @@ import javax.lang.model.element.VariableElement;
|
|||||||
import javax.lang.model.type.DeclaredType;
|
import javax.lang.model.type.DeclaredType;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import javax.tools.Diagnostic;
|
import javax.tools.Diagnostic;
|
||||||
|
import javax.tools.StandardLocation;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
@ -56,6 +57,8 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
private String name;
|
private String name;
|
||||||
private String className;
|
private String className;
|
||||||
|
|
||||||
|
private Set<String> disabledFeatures = new HashSet<>();
|
||||||
|
|
||||||
private Messager messager;
|
private Messager messager;
|
||||||
private boolean processed = false;
|
private boolean processed = false;
|
||||||
|
|
||||||
@ -75,6 +78,7 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
|
|
||||||
className = "LinkageUtils";
|
className = "LinkageUtils";
|
||||||
mainClass();
|
mainClass();
|
||||||
|
disabledFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@ -102,6 +106,18 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private void disabledFeatures() {
|
||||||
|
File file = new File(System.getProperty("user.dir"), "disabled-features.txt");
|
||||||
|
if (!file.exists()) return;
|
||||||
|
@Cleanup BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
|
||||||
|
reader.lines()
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(line -> !line.isEmpty())
|
||||||
|
.filter(line -> !line.startsWith("#"))
|
||||||
|
.forEach(disabledFeatures::add);
|
||||||
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
@ -111,9 +127,27 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
Writer writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter();
|
Writer writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter();
|
||||||
BuildPlan buildPlan = new BuildPlan("de.steamwar." + name + ".linkage", className);
|
BuildPlan buildPlan = new BuildPlan("de.steamwar." + name + ".linkage", className);
|
||||||
|
|
||||||
|
Set<TypeElement> disabledElements = new HashSet<>();
|
||||||
|
|
||||||
Set<TypeElement> elements = roundEnv.getElementsAnnotatedWith(Linked.class).stream()
|
Set<TypeElement> elements = roundEnv.getElementsAnnotatedWith(Linked.class).stream()
|
||||||
.filter(element -> element.getKind() == ElementKind.CLASS)
|
.filter(element -> element.getKind() == ElementKind.CLASS)
|
||||||
.map(TypeElement.class::cast)
|
.map(TypeElement.class::cast)
|
||||||
|
.peek(element -> {
|
||||||
|
String featureName = element.getAnnotation(Linked.class).feature();
|
||||||
|
if (featureName.isEmpty()) {
|
||||||
|
String tempName = element.getQualifiedName().toString();
|
||||||
|
if (tempName.contains(".features.")) {
|
||||||
|
tempName = tempName.substring(tempName.indexOf(".features.") + 10);
|
||||||
|
featureName = tempName.substring(0, tempName.indexOf('.'));
|
||||||
|
} else {
|
||||||
|
tempName = tempName.substring(0, tempName.lastIndexOf('.'));
|
||||||
|
featureName = tempName.substring(tempName.lastIndexOf('.') + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (disabledFeatures.contains(featureName) || disabledFeatures.contains("*")) {
|
||||||
|
disabledElements.add(element);
|
||||||
|
}
|
||||||
|
})
|
||||||
.peek(typeElement -> System.out.println("Found element: " + typeElement.getQualifiedName().toString()))
|
.peek(typeElement -> System.out.println("Found element: " + typeElement.getQualifiedName().toString()))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
@ -147,8 +181,14 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be non final", variableElement);
|
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be non final", variableElement);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
neededFields.put(typeElement.getQualifiedName().toString(), typeElement);
|
|
||||||
TypeElement fieldType = (TypeElement) ((DeclaredType) variableElement.asType()).asElement();
|
TypeElement fieldType = (TypeElement) ((DeclaredType) variableElement.asType()).asElement();
|
||||||
|
if (disabledElements.contains(fieldType)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (disabledElements.contains(typeElement)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
neededFields.put(typeElement.getQualifiedName().toString(), typeElement);
|
||||||
neededFields.put(fieldType.getQualifiedName().toString(), fieldType);
|
neededFields.put(fieldType.getQualifiedName().toString(), fieldType);
|
||||||
|
|
||||||
fieldInjections.add(() -> {
|
fieldInjections.add(() -> {
|
||||||
@ -159,6 +199,7 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
neededFields.forEach((s, typeElement) -> {
|
neededFields.forEach((s, typeElement) -> {
|
||||||
|
if (disabledElements.contains(typeElement)) return;
|
||||||
buildPlan.addImport(typeElement.getQualifiedName().toString());
|
buildPlan.addImport(typeElement.getQualifiedName().toString());
|
||||||
String t = typeElement.getSimpleName().toString();
|
String t = typeElement.getSimpleName().toString();
|
||||||
t = t.substring(0, 1).toLowerCase() + t.substring(1);
|
t = t.substring(0, 1).toLowerCase() + t.substring(1);
|
||||||
@ -188,8 +229,13 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
return methodBuilder;
|
return methodBuilder;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!entry.getKey().isEmpty()) method.addLine("if (" + String.join(" && ", entry.getKey()) + ") {");
|
boolean generated = false;
|
||||||
for (Map.Entry<TypeElement, List<LinkageType>> toGenerate : group.getValue().entrySet()) {
|
for (Map.Entry<TypeElement, List<LinkageType>> toGenerate : group.getValue().entrySet()) {
|
||||||
|
if (disabledElements.contains(toGenerate.getKey())) continue;
|
||||||
|
if (!generated && !entry.getKey().isEmpty()) {
|
||||||
|
method.addLine("if (" + String.join(" && ", entry.getKey()) + ") {");
|
||||||
|
generated = true;
|
||||||
|
}
|
||||||
TypeElement typeElement = toGenerate.getKey();
|
TypeElement typeElement = toGenerate.getKey();
|
||||||
String instance = getElement(typeElement, neededFields);
|
String instance = getElement(typeElement, neededFields);
|
||||||
if (toGenerate.getValue().size() > 1 && instance.startsWith("new ")) {
|
if (toGenerate.getValue().size() > 1 && instance.startsWith("new ")) {
|
||||||
@ -202,7 +248,7 @@ public class LinkageProcessor extends AbstractProcessor {
|
|||||||
linkageType.generateCode(buildPlan, method, finalInstance, typeElement);
|
linkageType.generateCode(buildPlan, method, finalInstance, typeElement);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!entry.getKey().isEmpty()) method.addLine("}");
|
if (generated && !entry.getKey().isEmpty()) method.addLine("}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,4 +24,5 @@ import java.lang.annotation.*;
|
|||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Target({ElementType.TYPE})
|
@Target({ElementType.TYPE})
|
||||||
public @interface Linked {
|
public @interface Linked {
|
||||||
|
String feature() default "";
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ package de.steamwar.network.packets.client;
|
|||||||
|
|
||||||
import de.steamwar.network.packets.NetworkPacket;
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class ImALobbyPacket extends NetworkPacket {
|
public class ImALobbyPacket extends NetworkPacket {
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.client;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class RequestSchematicSearchPacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = -6525229932332581648L;
|
||||||
|
|
||||||
|
private int playerId;
|
||||||
|
private int schematicId;
|
||||||
|
private boolean ignoreBlockData;
|
||||||
|
private boolean ignoreAir;
|
||||||
|
private boolean airAsAny;
|
||||||
|
|
||||||
|
}
|
@ -38,4 +38,5 @@ public class FightEndsPacket extends NetworkPacket {
|
|||||||
private List<Integer> bluePlayers;
|
private List<Integer> bluePlayers;
|
||||||
private List<Integer> redPlayers;
|
private List<Integer> redPlayers;
|
||||||
private String gameMode;
|
private String gameMode;
|
||||||
|
private int duration;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,10 @@ import java.util.List;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class Event {
|
public class Event {
|
||||||
|
|
||||||
|
static {
|
||||||
|
SchematicType.Normal.name(); // Ensure SchematicType is loaded.
|
||||||
|
}
|
||||||
|
|
||||||
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> byCurrent = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start < now() AND End > now()");
|
||||||
|
@ -26,7 +26,7 @@ import lombok.AllArgsConstructor;
|
|||||||
|
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@ -20,9 +20,7 @@
|
|||||||
package de.steamwar.sql;
|
package de.steamwar.sql;
|
||||||
|
|
||||||
import de.steamwar.sql.internal.*;
|
import de.steamwar.sql.internal.*;
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -32,6 +30,7 @@ import java.util.function.Predicate;
|
|||||||
public class SchematicNode {
|
public class SchematicNode {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
SchematicType.Normal.name(); // Ensure SchematicType is loaded.
|
||||||
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));
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +56,8 @@ public class SchematicNode {
|
|||||||
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> 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 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> 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 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 RSASN AS (WITH RSAN AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSA WHERE RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN INNER JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSASN WHERE SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN INNER JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId" + 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, "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?");
|
||||||
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> 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 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");
|
||||||
|
|
||||||
@ -135,7 +134,7 @@ public class SchematicNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<SchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
|
public static List<SchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
|
||||||
return accessibleByUserType.listSelect(user, type);
|
return accessibleByUserType.listSelect(user, user, user, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<Integer, List<SchematicNode>> accessibleByUserTypeMap(SteamwarUser user, SchematicType type) {
|
public static Map<Integer, List<SchematicNode>> accessibleByUserTypeMap(SteamwarUser user, SchematicType type) {
|
||||||
@ -147,7 +146,7 @@ public class SchematicNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
|
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
|
||||||
return accessibleByUserTypeInParent.listSelect(type, user, user, user, parentId);
|
return accessibleByUserTypeInParent.listSelect(user, user, type, user, parentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SchematicNode byIdAndUser(SteamwarUser user, Integer id) {
|
public static SchematicNode byIdAndUser(SteamwarUser user, Integer id) {
|
||||||
|
84
src/de/steamwar/sql/Script.java
Normale Datei
84
src/de/steamwar/sql/Script.java
Normale Datei
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public class Script {
|
||||||
|
|
||||||
|
private static final Table<Script> table = new Table<>(Script.class);
|
||||||
|
|
||||||
|
private static final SelectStatement<Script> byId = table.select(Table.PRIMARY);
|
||||||
|
private static final SelectStatement<Script> byUserName = table.select("nameUser");
|
||||||
|
private static final SelectStatement<Script> byUser = table.selectFields("userId");
|
||||||
|
|
||||||
|
private static final Statement insert = table.insertFields(true, "userId", "name", "code");
|
||||||
|
private static final Statement updateName = table.update(Table.PRIMARY, "name");
|
||||||
|
private static final Statement updateCode = table.update(Table.PRIMARY, "code");
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
|
||||||
|
public static Script get(int id) {
|
||||||
|
return byId.select(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Script get(SteamwarUser user, String name) {
|
||||||
|
return byUserName.select(user, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Script create(SteamwarUser user, String name, String code) {
|
||||||
|
return new Script(insert.insertGetKey(user, name, code), user.getId(), name, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Script> list(SteamwarUser user) {
|
||||||
|
return byUser.listSelect(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field(keys = Table.PRIMARY, autoincrement = true)
|
||||||
|
private final int id;
|
||||||
|
@Field(keys = "nameUser")
|
||||||
|
private final int userId;
|
||||||
|
@Field(keys = "nameUser")
|
||||||
|
private String name;
|
||||||
|
@Field
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
updateName.update(name, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCode(String code) {
|
||||||
|
this.code = code;
|
||||||
|
updateCode.update(code, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
delete.update(id);
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,14 @@ public class Season {
|
|||||||
|
|
||||||
public static String getSeasonStart() {
|
public static String getSeasonStart() {
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) / 4 * 3 + 1) + "-1";
|
int month = calendar.get(Calendar.MONTH);
|
||||||
|
if (month <= 3) {
|
||||||
|
return calendar.get(Calendar.YEAR) + "-1-1";
|
||||||
|
} else if (month <= 7) {
|
||||||
|
return calendar.get(Calendar.YEAR) + "-5-1";
|
||||||
|
} else {
|
||||||
|
return calendar.get(Calendar.YEAR) + "-9-1";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String convertSeasonToString(int season){
|
public static String convertSeasonToString(int season){
|
||||||
|
@ -25,30 +25,25 @@ 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 java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserElo {
|
public class UserElo {
|
||||||
private static final int ELO_DEFAULT = 1000;
|
|
||||||
|
private static final int ELO_DEFAULT = 0;
|
||||||
|
|
||||||
private static final Map<String, Map<Integer, Optional<Integer>>> gameModeUserEloCache = new ConcurrentHashMap<>();
|
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<>();
|
private static final Map<Integer, String> emblemCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static void clear() {
|
public static void clear() {
|
||||||
gameModeUserEloCache.clear();
|
gameModeUserEloCache.clear();
|
||||||
maxEloCache.clear();
|
|
||||||
emblemCache.clear();
|
emblemCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Table<UserElo> table = new Table<>(UserElo.class);
|
private static final Table<UserElo> table = new Table<>(UserElo.class);
|
||||||
private static final SelectStatement<UserElo> getElo = table.select(Table.PRIMARY);
|
private static final SelectStatement<UserElo> getElo = table.select(Table.PRIMARY);
|
||||||
private static final Statement setElo = table.insertAll();
|
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 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(?)");
|
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(?)");
|
||||||
@ -78,21 +73,14 @@ public class UserElo {
|
|||||||
}, userID, gameMode, Season.getSeasonStart());
|
}, 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) {
|
public static void setElo(int userId, String gameMode, int elo) {
|
||||||
emblemCache.remove(userId);
|
emblemCache.remove(userId);
|
||||||
|
|
||||||
Optional<Integer> oldElo = Optional.ofNullable(gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).put(userId, Optional.of(elo))).orElse(Optional.empty());
|
int oldPlacement = getPlacement(getElo(userId, gameMode).orElse(0), gameMode);
|
||||||
int maxElo = getMaxElo(gameMode);
|
int newPlacement = getPlacement(elo, gameMode);
|
||||||
if (elo > maxElo || (oldElo.isPresent() && oldElo.get() == maxElo)) {
|
|
||||||
maxEloCache.remove(gameMode);
|
gameModeUserEloCache.getOrDefault(gameMode, Collections.emptyMap()).remove(userId);
|
||||||
|
if (oldPlacement <= 3 || newPlacement <= 3) {
|
||||||
emblemCache.clear();
|
emblemCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,70 +97,92 @@ public class UserElo {
|
|||||||
|
|
||||||
public static String getEmblem(SteamwarUser user, List<String> rankedModes) {
|
public static String getEmblem(SteamwarUser user, List<String> rankedModes) {
|
||||||
return emblemCache.computeIfAbsent(user.getId(), userId -> {
|
return emblemCache.computeIfAbsent(user.getId(), userId -> {
|
||||||
switch(
|
int emblemProgression = -1;
|
||||||
rankedModes.stream().filter(
|
for (String mode : rankedModes) {
|
||||||
mode -> UserElo.getFightsOfSeason(user.getId(), mode) >= 10
|
if (UserElo.getFightsOfSeason(userId, mode) == 0) continue;
|
||||||
).map(
|
int progression = getProgression(userId, mode);
|
||||||
mode -> getProgression(user.getId(), mode)
|
if (progression > emblemProgression) {
|
||||||
).max(Integer::compareTo).orElse(0)
|
emblemProgression = progression;
|
||||||
) {
|
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return toEmblem(emblemProgression);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getEmblemProgression(String gameMode, int userId) {
|
public static String getEmblemProgression(String gameMode, int userId) {
|
||||||
switch (getProgression(userId, gameMode)) {
|
switch (getProgression(userId, gameMode)) {
|
||||||
|
case -1:
|
||||||
|
return "§f/ §8∨ ∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||||
case 0:
|
case 0:
|
||||||
return "§8✧ ✦ ✶ ✷ ✸ ✹ ❂";
|
return "§8/ §6∨ §8∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||||
case 1:
|
case 1:
|
||||||
return "§7✧ §8✦ ✶ ✷ ✸ ✹ ❂";
|
return "§8/ ∨ §6∧ §8∨ ∧ ∨ ∧ ❂ III II I";
|
||||||
case 2:
|
case 2:
|
||||||
return "§8✧ §f✦ §8✶ ✷ ✸ ✹ ❂";
|
return "§8/ ∨ ∧ §7∨ §8∧ ∨ ∧ ❂ III II I";
|
||||||
case 3:
|
case 3:
|
||||||
return "§8✧ ✦ §e✶ §8✷ ✸ ✹ ❂";
|
return "§8/ ∨ ∧ ∨ §7∧ §8∨ ∧ ❂ III II I";
|
||||||
case 4:
|
case 4:
|
||||||
return "§8✧ ✦ ✶ §a✷ §8✸ ✹ ❂";
|
return "§8/ ∨ ∧ ∨ ∧ §e∨ §8∧ ❂ III II I";
|
||||||
case 5:
|
case 5:
|
||||||
return "§8✧ ✦ ✶ ✷ §b✸ §8✹ ❂";
|
return "§8/ ∨ ∧ ∨ ∧ ∨ §e∧ §8❂ III II I";
|
||||||
case 6:
|
case 6:
|
||||||
return "§8✧ ✦ ✶ ✷ ✸ §c✹ §8❂";
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ §5❂ §8III II I";
|
||||||
case 7:
|
case 7:
|
||||||
return "§8✧ ✦ ✶ ✷ ✸ ✹ §5❂";
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ §5III §8II I";
|
||||||
|
case 8:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III §5II §8I";
|
||||||
|
case 9:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III II §5I";
|
||||||
default:
|
default:
|
||||||
throw new SecurityException("Progression is not in range");
|
throw new SecurityException("Progression is not in range");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getProgression(int userId, String gameMode) {
|
public static int getProgression(int userId, String gameMode) {
|
||||||
int elo = getElo(userId, gameMode).orElse(0);
|
int elo = getElo(userId, gameMode).orElse(-1);
|
||||||
if(elo == 0)
|
if (elo < 0) return -1;
|
||||||
return 0;
|
|
||||||
int maxElo = getMaxElo(gameMode);
|
|
||||||
|
|
||||||
if (elo > maxElo * 0.99) return 7;
|
if (elo <= 100) return 0;
|
||||||
if (elo > maxElo * 0.97) return 6;
|
if (elo <= 200) return 1;
|
||||||
if (elo > maxElo * 0.94) return 5;
|
if (elo <= 400) return 2;
|
||||||
if (elo > maxElo * 0.88) return 4;
|
if (elo <= 600) return 3;
|
||||||
if (elo > maxElo * 0.76) return 3;
|
if (elo <= 900) return 4;
|
||||||
if (elo > maxElo * 0.51) return 2;
|
if (elo <= 1200) return 5;
|
||||||
return 1;
|
|
||||||
|
int placement = getPlacement(elo, gameMode);
|
||||||
|
if (placement == 1) return 9;
|
||||||
|
if (placement == 2) return 8;
|
||||||
|
if (placement == 3) return 7;
|
||||||
|
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toEmblem(int progression) {
|
||||||
|
switch(progression) {
|
||||||
|
case -1:
|
||||||
|
return "";
|
||||||
|
case 0:
|
||||||
|
return "§6∨ ";
|
||||||
|
case 1:
|
||||||
|
return "§6∧ ";
|
||||||
|
case 2:
|
||||||
|
return "§7∨ ";
|
||||||
|
case 3:
|
||||||
|
return "§7∧ ";
|
||||||
|
case 4:
|
||||||
|
return "§e∨ ";
|
||||||
|
case 5:
|
||||||
|
return "§e∧ ";
|
||||||
|
case 6:
|
||||||
|
return "§5❂ ";
|
||||||
|
case 7:
|
||||||
|
return "§5III ";
|
||||||
|
case 8:
|
||||||
|
return "§5II ";
|
||||||
|
case 9:
|
||||||
|
return "§5I ";
|
||||||
|
default:
|
||||||
|
throw new SecurityException("Progression out of range");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,12 @@ public final class SqlTypeMapper<T> {
|
|||||||
private static final Map<Class<?>, SqlTypeMapper<?>> mappers = new IdentityHashMap<>();
|
private static final Map<Class<?>, SqlTypeMapper<?>> mappers = new IdentityHashMap<>();
|
||||||
|
|
||||||
public static <T> SqlTypeMapper<T> getMapper(Class<?> clazz) {
|
public static <T> SqlTypeMapper<T> getMapper(Class<?> clazz) {
|
||||||
return (SqlTypeMapper<T>) mappers.get(clazz);
|
SqlTypeMapper<T> result = (SqlTypeMapper<T>) mappers.get(clazz);
|
||||||
|
|
||||||
|
if(result == null)
|
||||||
|
throw new SecurityException("Unregistered mapper requested: " + clazz.getName());
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Enum<T>> void ordinalEnumMapper(Class<T> type) {
|
public static <T extends Enum<T>> void ordinalEnumMapper(Class<T> type) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren