forked from SteamWar/SteamWar
Add CommonCore module
This commit is contained in:
@@ -40,4 +40,18 @@ sourceSets {
|
|||||||
exclude("**/*.java", "**/*.kt")
|
exclude("**/*.java", "**/*.kt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
test {
|
||||||
|
java {
|
||||||
|
srcDirs("testsrc/")
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDirs("testsrc/")
|
||||||
|
exclude("**/*.java", "**/*.kt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly("org.projectlombok:lombok:1.18.32")
|
||||||
|
annotationProcessor("org.projectlombok:lombok:1.18.32")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
public class ImplementationProvider {
|
||||||
|
private ImplementationProvider() {}
|
||||||
|
|
||||||
|
public static <T> T getImpl(String className) {
|
||||||
|
try {
|
||||||
|
return (T) Class.forName(className).getDeclaredConstructor().newInstance();
|
||||||
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) {
|
||||||
|
throw new SecurityException("Could not load implementation", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.ANNOTATION_TYPE)
|
||||||
|
@Retention(RetentionPolicy.CLASS)
|
||||||
|
public @interface AllowedContexts {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The context in which this annotation is valid.
|
||||||
|
*/
|
||||||
|
Context[] value();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
public enum Context {
|
||||||
|
BUNGEE,
|
||||||
|
SPIGOT
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@AllowedContexts(Context.BUNGEE)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
public @interface EventMode {
|
||||||
|
Mode value();
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
enum Mode {
|
||||||
|
EventOnly(""),
|
||||||
|
NonEvent("!");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private String prefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.FieldBuilder;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
import de.steamwar.linkage.types.Plain_GENERIC;
|
||||||
|
import lombok.Cleanup;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
import javax.annotation.processing.*;
|
||||||
|
import javax.lang.model.SourceVersion;
|
||||||
|
import javax.lang.model.element.ElementKind;
|
||||||
|
import javax.lang.model.element.Modifier;
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
import javax.lang.model.element.VariableElement;
|
||||||
|
import javax.lang.model.type.DeclaredType;
|
||||||
|
import javax.lang.model.type.TypeMirror;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
import javax.tools.StandardLocation;
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@SupportedAnnotationTypes("de.steamwar.linkage.Linked")
|
||||||
|
public class LinkageProcessor extends AbstractProcessor {
|
||||||
|
|
||||||
|
private static Context context;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static String pluginMain;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
private Set<String> disabledFeatures = new HashSet<>();
|
||||||
|
|
||||||
|
private Messager messager;
|
||||||
|
private boolean processed = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latestSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
@Override
|
||||||
|
public synchronized void init(ProcessingEnvironment processingEnv) {
|
||||||
|
super.init(processingEnv);
|
||||||
|
|
||||||
|
name = new File(System.getProperty("user.dir")).getName().replaceAll("[^a-zA-Z]", "").toLowerCase();
|
||||||
|
|
||||||
|
messager = processingEnv.getMessager();
|
||||||
|
|
||||||
|
className = "LinkageUtils";
|
||||||
|
mainClass();
|
||||||
|
disabledFeatures();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private void mainClass() {
|
||||||
|
File file = new File(System.getProperty("user.dir"));
|
||||||
|
Optional<File> pluginYMLFile = Files.walk(file.toPath())
|
||||||
|
.map(Path::toFile)
|
||||||
|
.filter(File::isFile)
|
||||||
|
.filter(f -> f.getName().equals("plugin.yml") || f.getName().equals("bungee.yml"))
|
||||||
|
.findFirst();
|
||||||
|
if (!pluginYMLFile.isPresent()) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "Could not find plugin.yml or bungee.yml");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
context = pluginYMLFile.get().getName().equals("bungee.yml") ? Context.BUNGEE : Context.SPIGOT;
|
||||||
|
@Cleanup BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(pluginYMLFile.get())));
|
||||||
|
Optional<String> mainName = reader.lines()
|
||||||
|
.filter(line -> line.startsWith("main:"))
|
||||||
|
.map(line -> line.substring(line.indexOf(':') + 1).trim())
|
||||||
|
.findFirst();
|
||||||
|
if (mainName.isPresent()) {
|
||||||
|
pluginMain = mainName.get();
|
||||||
|
} else {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "Could not find main class in plugin.yml or bungee.yml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
|
if (processed) return false;
|
||||||
|
processed = true;
|
||||||
|
|
||||||
|
Writer writer = processingEnv.getFiler().createSourceFile("de.steamwar." + name + ".linkage.LinkageUtils").openWriter();
|
||||||
|
BuildPlan buildPlan = new BuildPlan("de.steamwar." + name + ".linkage", className);
|
||||||
|
|
||||||
|
Set<TypeElement> disabledElements = new HashSet<>();
|
||||||
|
|
||||||
|
Set<TypeElement> elements = roundEnv.getElementsAnnotatedWith(Linked.class).stream()
|
||||||
|
.filter(element -> element.getKind() == ElementKind.CLASS)
|
||||||
|
.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()))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
Map<Set<String>, List<TypeElement>> groupedByChecks = elements.stream()
|
||||||
|
.collect(Collectors.groupingBy(element -> checks(element, buildPlan)));
|
||||||
|
|
||||||
|
Map<String, TypeElement> neededFields = new HashMap<>();
|
||||||
|
Set<Runnable> fieldInjections = new HashSet<>();
|
||||||
|
for (TypeElement typeElement : elements) {
|
||||||
|
if (getLinkagesOfType(typeElement).size() > 1) {
|
||||||
|
neededFields.put(typeElement.getQualifiedName().toString(), typeElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<VariableElement> variableElements = typeElement.getEnclosedElements().stream()
|
||||||
|
.filter(e -> e.getKind() == ElementKind.FIELD)
|
||||||
|
.map(VariableElement.class::cast)
|
||||||
|
.filter(e -> e.getAnnotation(LinkedInstance.class) != null)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (variableElements.isEmpty()) continue;
|
||||||
|
|
||||||
|
for (VariableElement variableElement : variableElements) {
|
||||||
|
if (!variableElement.getModifiers().contains(Modifier.PUBLIC)) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be public", variableElement);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (variableElement.getModifiers().contains(Modifier.STATIC)) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be non static", variableElement);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (variableElement.getModifiers().contains(Modifier.FINAL)) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, "Field " + variableElement.getSimpleName() + " must be non final", variableElement);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
fieldInjections.add(() -> {
|
||||||
|
specialElements(typeElement, buildPlan, buildPlan::addStaticLine, () -> {
|
||||||
|
buildPlan.addStaticLine(getElement(typeElement, neededFields) + "." + variableElement.getSimpleName().toString() + " = " + getElement((TypeElement) ((DeclaredType) variableElement.asType()).asElement(), neededFields) + ";");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
neededFields.forEach((s, typeElement) -> {
|
||||||
|
if (disabledElements.contains(typeElement)) return;
|
||||||
|
buildPlan.addImport(typeElement.getQualifiedName().toString());
|
||||||
|
String t = typeElement.getSimpleName().toString();
|
||||||
|
t = t.substring(0, 1).toLowerCase() + t.substring(1);
|
||||||
|
buildPlan.addField(new FieldBuilder(typeElement.getSimpleName().toString(), t));
|
||||||
|
|
||||||
|
String finalT = t;
|
||||||
|
specialElements(typeElement, buildPlan, buildPlan::addStaticLine, () -> {
|
||||||
|
buildPlan.addStaticLine(finalT + " = new " + typeElement.getSimpleName().toString() + "();");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
fieldInjections.forEach(Runnable::run);
|
||||||
|
|
||||||
|
Map<String, MethodBuilder> methods = new HashMap<>();
|
||||||
|
for (Map.Entry<Set<String>, List<TypeElement>> entry : groupedByChecks.entrySet()) {
|
||||||
|
Map<String, Map<TypeElement, List<LinkageType>>> groupedByMethod = new HashMap<>();
|
||||||
|
for (TypeElement typeElement : entry.getValue()) {
|
||||||
|
for (Map.Entry<String, List<LinkageType>> linkages : getLinkagesOfType(typeElement).entrySet()) {
|
||||||
|
groupedByMethod.computeIfAbsent(linkages.getKey(), ignored -> new HashMap<>())
|
||||||
|
.put(typeElement, linkages.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, Map<TypeElement, List<LinkageType>>> group : groupedByMethod.entrySet()) {
|
||||||
|
MethodBuilder method = methods.computeIfAbsent(group.getKey(), s -> {
|
||||||
|
MethodBuilder methodBuilder = new MethodBuilder(s, "void");
|
||||||
|
buildPlan.addMethod(methodBuilder);
|
||||||
|
return methodBuilder;
|
||||||
|
});
|
||||||
|
|
||||||
|
boolean generated = false;
|
||||||
|
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();
|
||||||
|
String instance = getElement(typeElement, neededFields);
|
||||||
|
if (toGenerate.getValue().size() > 1 && instance.startsWith("new ")) {
|
||||||
|
method.addLine(typeElement.getSimpleName() + " local" + typeElement.getSimpleName().toString() + " = " + instance + ";");
|
||||||
|
instance = "local" + typeElement.getSimpleName().toString();
|
||||||
|
}
|
||||||
|
String finalInstance = instance;
|
||||||
|
toGenerate.getValue().forEach(linkageType -> {
|
||||||
|
buildPlan.addImport(typeElement.getQualifiedName().toString());
|
||||||
|
linkageType.generateCode(buildPlan, method, finalInstance, typeElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (generated && !entry.getKey().isEmpty()) method.addLine("}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedWriter bufferedWriter = new BufferedWriter(writer);
|
||||||
|
buildPlan.write(bufferedWriter);
|
||||||
|
bufferedWriter.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getElement(TypeElement typeElement, Map<String, TypeElement> neededFields) {
|
||||||
|
String s = typeElement.getSimpleName().toString();
|
||||||
|
if (neededFields.containsKey(typeElement.getQualifiedName().toString())) {
|
||||||
|
return s.substring(0, 1).toLowerCase() + s.substring(1);
|
||||||
|
}
|
||||||
|
return "new " + s + "()";
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> checks(TypeElement typeElement, BuildPlan buildPlan) {
|
||||||
|
Set<String> checks = new HashSet<>();
|
||||||
|
MinVersion minVersion = typeElement.getAnnotation(MinVersion.class);
|
||||||
|
MaxVersion maxVersion = typeElement.getAnnotation(MaxVersion.class);
|
||||||
|
EventMode eventMode = typeElement.getAnnotation(EventMode.class);
|
||||||
|
PluginCheck[] pluginChecks = typeElement.getAnnotationsByType(PluginCheck.class);
|
||||||
|
if (context == Context.SPIGOT) {
|
||||||
|
errorOnNonNull(typeElement, eventMode);
|
||||||
|
if (minVersion != null) {
|
||||||
|
buildPlan.addImport("de.steamwar.core.Core");
|
||||||
|
checks.add("Core.getVersion() >= " + minVersion.value());
|
||||||
|
}
|
||||||
|
if (maxVersion != null) {
|
||||||
|
buildPlan.addImport("de.steamwar.core.Core");
|
||||||
|
checks.add("Core.getVersion() <= " + maxVersion.value());
|
||||||
|
}
|
||||||
|
if (pluginChecks.length != 0) {
|
||||||
|
buildPlan.addImport("org.bukkit.Bukkit");
|
||||||
|
Arrays.stream(pluginChecks).map(pluginCheck -> {
|
||||||
|
return "Bukkit.getPluginManager().getPlugin(\"" + pluginCheck.value() + "\") " + (pluginCheck.has() == PluginCheck.Has.THIS ? "!" : "=") + "= null";
|
||||||
|
}).forEach(checks::add);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errorOnNonNull(typeElement, minVersion, maxVersion);
|
||||||
|
if (eventMode != null) {
|
||||||
|
buildPlan.addImport("de.steamwar.bungeecore.BungeeCore");
|
||||||
|
checks.add(eventMode.value().getPrefix() + "BungeeCore.EVENT_MODE");
|
||||||
|
}
|
||||||
|
if (pluginChecks.length != 0) {
|
||||||
|
buildPlan.addImport("net.md_5.bungee.BungeeCord");
|
||||||
|
Arrays.stream(pluginChecks).map(pluginCheck -> {
|
||||||
|
return "BungeeCord.getPluginManager().getPlugin(\"" + pluginCheck.value() + "\") " + (pluginCheck.has() == PluginCheck.Has.THIS ? "!" : "=") + "= null";
|
||||||
|
}).forEach(checks::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return checks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void specialElements(TypeElement typeElement, BuildPlan buildPlan, Consumer<String> stringConsumer, Runnable inner) {
|
||||||
|
Set<String> checks = checks(typeElement, buildPlan);
|
||||||
|
if (!checks.isEmpty()) stringConsumer.accept("if (" + String.join(" && ", checks) + ") {");
|
||||||
|
inner.run();
|
||||||
|
if (!checks.isEmpty()) stringConsumer.accept("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void errorOnNonNull(TypeElement typeElement, Annotation... annotations) {
|
||||||
|
for (Annotation annotation : annotations) {
|
||||||
|
if (annotation != null) {
|
||||||
|
messager.printMessage(Diagnostic.Kind.ERROR, annotation.annotationType().getSimpleName() + " is not supported in " + context.name(), typeElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Plain_GENERIC plain_GENERIC = new Plain_GENERIC();
|
||||||
|
|
||||||
|
private Map<String, List<LinkageType>> getLinkagesOfType(TypeElement typeElement) {
|
||||||
|
Map<String, List<LinkageType>> linkages = new HashMap<>();
|
||||||
|
Stream.concat(Stream.of(typeElement.getSuperclass()), typeElement.getInterfaces().stream())
|
||||||
|
.map(this::resolveSingle)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(linkageType -> linkages.computeIfAbsent(linkageType.method(), s -> new ArrayList<>()).add(linkageType));
|
||||||
|
if (linkages.size() == 1 && linkages.containsKey("unlink")) {
|
||||||
|
linkages.put(plain_GENERIC.method(), Collections.singletonList(plain_GENERIC));
|
||||||
|
}
|
||||||
|
return linkages;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LinkageType resolveSingle(TypeMirror typeMirror) {
|
||||||
|
String qualifier = typeMirror.toString();
|
||||||
|
if (qualifier.contains("<")) qualifier = qualifier.substring(0, qualifier.indexOf('<'));
|
||||||
|
qualifier = qualifier.substring(qualifier.lastIndexOf('.') + 1);
|
||||||
|
try {
|
||||||
|
return (LinkageType) Class.forName("de.steamwar.linkage.types." + qualifier + "_" + context.name()).getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return (LinkageType) Class.forName("de.steamwar.linkage.types." + qualifier + "_GENERIC").getDeclaredConstructor().newInstance();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public interface LinkageType {
|
||||||
|
|
||||||
|
default String getPluginMain() {
|
||||||
|
return LinkageProcessor.getPluginMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
String method();
|
||||||
|
|
||||||
|
void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement);
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
public @interface Linked {
|
||||||
|
String feature() default "";
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
public @interface LinkedInstance {
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@AllowedContexts(Context.SPIGOT)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
public @interface MaxVersion {
|
||||||
|
int value();
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@AllowedContexts(Context.SPIGOT)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
public @interface MinVersion {
|
||||||
|
int value();
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@AllowedContexts({Context.BUNGEE, Context.SPIGOT})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Repeatable(PluginCheck.PluginChecks.class)
|
||||||
|
public @interface PluginCheck {
|
||||||
|
Has has() default Has.THIS;
|
||||||
|
String value();
|
||||||
|
|
||||||
|
enum Has {
|
||||||
|
THIS,
|
||||||
|
NOT
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@interface PluginChecks {
|
||||||
|
@SuppressWarnings("unused") PluginCheck[] value() default {};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.api;
|
||||||
|
|
||||||
|
public interface Disable {
|
||||||
|
void disable();
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.api;
|
||||||
|
|
||||||
|
public interface Enable {
|
||||||
|
void enable();
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.api;
|
||||||
|
|
||||||
|
public interface Plain {
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.plan;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class BuildPlan {
|
||||||
|
|
||||||
|
private final String packageName;
|
||||||
|
private Set<String> imports = new HashSet<>();
|
||||||
|
private final String className;
|
||||||
|
|
||||||
|
private List<FieldBuilder> fieldBuilders = new ArrayList<>();
|
||||||
|
private Map<String, MethodBuilder> methodBuilderMap = new HashMap<>();
|
||||||
|
private List<String> staticLines = new ArrayList<>();
|
||||||
|
|
||||||
|
public void addImport(String importName) {
|
||||||
|
imports.add(importName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addField(FieldBuilder fieldBuilder) {
|
||||||
|
fieldBuilders.add(fieldBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMethod(MethodBuilder methodBuilder) {
|
||||||
|
methodBuilderMap.put(methodBuilder.getMethodName(), methodBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMethod(String methodName) {
|
||||||
|
return methodBuilderMap.containsKey(methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addStaticLine(String line) {
|
||||||
|
staticLines.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(BufferedWriter writer) throws IOException {
|
||||||
|
writer.write("package " + packageName + ";\n");
|
||||||
|
if (!imports.isEmpty()) {
|
||||||
|
writer.write("\n");
|
||||||
|
for (String importName : imports) {
|
||||||
|
writer.write("import " + importName + ";\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.write("\n");
|
||||||
|
writer.write("public class " + className + " {\n");
|
||||||
|
if (!fieldBuilders.isEmpty()) {
|
||||||
|
for (FieldBuilder fieldBuilder : fieldBuilders) {
|
||||||
|
fieldBuilder.write(writer);
|
||||||
|
}
|
||||||
|
writer.write("\n");
|
||||||
|
}
|
||||||
|
if (!staticLines.isEmpty()) {
|
||||||
|
writer.write(" static {\n");
|
||||||
|
for (String line : staticLines) {
|
||||||
|
writer.write(" " + line + "\n");
|
||||||
|
}
|
||||||
|
writer.write(" }\n");
|
||||||
|
writer.write("\n");
|
||||||
|
}
|
||||||
|
for (MethodBuilder methodBuilder : methodBuilderMap.values()) {
|
||||||
|
methodBuilder.write(writer);
|
||||||
|
writer.write("\n");
|
||||||
|
}
|
||||||
|
writer.write("}\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.plan;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FieldBuilder {
|
||||||
|
@Getter
|
||||||
|
private final String type;
|
||||||
|
private final String name;
|
||||||
|
private String initializer;
|
||||||
|
|
||||||
|
public String getFieldName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(BufferedWriter writer) throws IOException {
|
||||||
|
writer.write(" private static " + type + " " + getFieldName() + (initializer == null ? "" : " = " + initializer) + ";\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.plan;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class MethodBuilder {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String returnType;
|
||||||
|
private List<ParameterBuilder> parameters = new ArrayList<>();
|
||||||
|
private List<String> lines = new ArrayList<>();
|
||||||
|
private boolean isPrivate = false;
|
||||||
|
|
||||||
|
public void addParameter(ParameterBuilder parameterBuilder) {
|
||||||
|
parameters.add(parameterBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLine(String line) {
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethodName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrivate(boolean isPrivate) {
|
||||||
|
this.isPrivate = isPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(BufferedWriter writer) throws IOException {
|
||||||
|
writer.write(" " + (isPrivate ? "private" : "public") + " static " + returnType + " " + getMethodName() + "(");
|
||||||
|
for (int i = 0; i < parameters.size(); i++) {
|
||||||
|
parameters.get(i).write(writer);
|
||||||
|
if (i < parameters.size() - 1) {
|
||||||
|
writer.write(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.write(") {");
|
||||||
|
for (String line : lines) {
|
||||||
|
writer.write("\n");
|
||||||
|
writer.write(" " + line);
|
||||||
|
}
|
||||||
|
writer.write("\n");
|
||||||
|
writer.write(" }\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.plan;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class ParameterBuilder {
|
||||||
|
private String type;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public void write(BufferedWriter writer) throws IOException {
|
||||||
|
writer.write(type + " " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public class Disable_GENERIC implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "unlink";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
method.addLine(instance + ".disable();");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public class Enable_GENERIC implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "link";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
method.addLine(instance + ".enable();");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public class Listener_BUNGEE implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "link";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
buildPlan.addImport("net.md_5.bungee.api.ProxyServer");
|
||||||
|
buildPlan.addImport("de.steamwar.bungeecore.BungeeCore");
|
||||||
|
method.addLine("ProxyServer.getInstance().getPluginManager().registerListener(BungeeCore.get(), " + instance + ");");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.FieldBuilder;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
import de.steamwar.linkage.plan.ParameterBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.*;
|
||||||
|
import javax.lang.model.type.DeclaredType;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Listener_SPIGOT implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "link";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
Map<String, TypeElement> eventClasses = new HashMap<>();
|
||||||
|
Map<TypeElement, ExecutableElement> eventMethods = new HashMap<>();
|
||||||
|
|
||||||
|
typeElement.getEnclosedElements().stream().filter(e -> e.getKind() == ElementKind.METHOD).map(ExecutableElement.class::cast).filter(e -> {
|
||||||
|
return e.getAnnotationMirrors().stream().anyMatch(annotationMirror -> {
|
||||||
|
return annotationMirror.getAnnotationType().asElement().getSimpleName().toString().equals("EventHandler");
|
||||||
|
});
|
||||||
|
}).forEach(e -> {
|
||||||
|
TypeElement current = ((TypeElement)((DeclaredType) e.getParameters().get(0).asType()).asElement());
|
||||||
|
eventClasses.put(current.getQualifiedName().toString(), current);
|
||||||
|
eventMethods.put(current, e);
|
||||||
|
});
|
||||||
|
|
||||||
|
eventClasses.forEach((s, eventType) -> {
|
||||||
|
if (buildPlan.hasMethod(eventType.getSimpleName().toString())) return;
|
||||||
|
buildPlan.addImport("org.bukkit.event.HandlerList");
|
||||||
|
buildPlan.addImport("org.bukkit.event.Listener");
|
||||||
|
buildPlan.addImport("java.util.function.Consumer");
|
||||||
|
buildPlan.addImport("org.bukkit.event.EventPriority");
|
||||||
|
buildPlan.addImport("org.bukkit.plugin.RegisteredListener");
|
||||||
|
buildPlan.addImport("org.bukkit.plugin.EventExecutor");
|
||||||
|
buildPlan.addImport(s);
|
||||||
|
buildPlan.addField(new FieldBuilder("HandlerList", "handlerList" + eventType.getSimpleName()));
|
||||||
|
MethodBuilder methodBuilder = new MethodBuilder(eventType.getSimpleName().toString(), "void");
|
||||||
|
methodBuilder.addParameter(new ParameterBuilder("Listener", "listener"));
|
||||||
|
methodBuilder.addParameter(new ParameterBuilder("Consumer<" + eventType.getSimpleName() + ">", "consumer"));
|
||||||
|
methodBuilder.addParameter(new ParameterBuilder("EventPriority", "eventPriority"));
|
||||||
|
methodBuilder.addParameter(new ParameterBuilder("boolean", "ignoreCancelled"));
|
||||||
|
methodBuilder.setPrivate(true);
|
||||||
|
methodBuilder.addLine("EventExecutor eventExecutor = (l, event) -> {");
|
||||||
|
methodBuilder.addLine(" if (event instanceof " + eventType.getSimpleName() + ") {");
|
||||||
|
methodBuilder.addLine(" consumer.accept((" + eventType.getSimpleName() + ") event);");
|
||||||
|
methodBuilder.addLine(" }");
|
||||||
|
methodBuilder.addLine("};");
|
||||||
|
methodBuilder.addLine("handlerList" + eventType.getSimpleName() + ".register(new RegisteredListener(listener, eventExecutor, eventPriority, " + getPluginMain() + ".getInstance(), ignoreCancelled));");
|
||||||
|
buildPlan.addMethod(methodBuilder);
|
||||||
|
method.addLine("handlerList" + eventType.getSimpleName() + " = " + eventType.getSimpleName() + ".getHandlerList();");
|
||||||
|
});
|
||||||
|
|
||||||
|
String localInstance = "local" + typeElement.getSimpleName().toString();
|
||||||
|
if (!instance.startsWith("new ")) {
|
||||||
|
localInstance = instance;
|
||||||
|
} else {
|
||||||
|
method.addLine(typeElement.getSimpleName() + " " + localInstance + " = " + instance + ";");
|
||||||
|
}
|
||||||
|
String finalLocalInstance = localInstance;
|
||||||
|
eventMethods.forEach((type, executableElement) -> {
|
||||||
|
AnnotationMirror eventHandler = executableElement.getAnnotationMirrors().stream().filter(annotationMirror -> annotationMirror.getAnnotationType().asElement().getSimpleName().toString().equals("EventHandler")).findFirst().orElse(null);
|
||||||
|
if (eventHandler == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String priority = "NORMAL";
|
||||||
|
String ignoreCancelled = "false";
|
||||||
|
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : eventHandler.getElementValues().entrySet()) {
|
||||||
|
if (entry.getKey().getSimpleName().toString().equals("priority")) {
|
||||||
|
priority = entry.getValue().getValue().toString();
|
||||||
|
} else if (entry.getKey().getSimpleName().toString().equals("ignoreCancelled")) {
|
||||||
|
ignoreCancelled = entry.getValue().getValue().toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
method.addLine(type.getSimpleName().toString() + "(" + finalLocalInstance + ", " + finalLocalInstance + "::" + executableElement.getSimpleName().toString() + ", EventPriority." + priority + ", " + ignoreCancelled + ");");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public class PacketHandler_GENERIC implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "link";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
method.addLine(instance + ".register();");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public class Plain_GENERIC implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "link";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
if (instance.startsWith("new ")) method.addLine(instance + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public class SWCommand_BUNGEE implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "link";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
method.addLine(instance + ";");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.linkage.types;
|
||||||
|
|
||||||
|
import de.steamwar.linkage.LinkageType;
|
||||||
|
import de.steamwar.linkage.plan.BuildPlan;
|
||||||
|
import de.steamwar.linkage.plan.MethodBuilder;
|
||||||
|
|
||||||
|
import javax.lang.model.element.TypeElement;
|
||||||
|
|
||||||
|
public class SWCommand_SPIGOT implements LinkageType {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String method() {
|
||||||
|
return "link";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generateCode(BuildPlan buildPlan, MethodBuilder method, String instance, TypeElement typeElement) {
|
||||||
|
method.addLine(instance + ".setMessage(" + getPluginMain() + ".MESSAGE);");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets;
|
||||||
|
|
||||||
|
public interface MetaInfos {
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets;
|
||||||
|
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public abstract class NetworkPacket implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -3168992457669156473L;
|
||||||
|
private transient MetaInfos metaInfos;
|
||||||
|
|
||||||
|
public MetaInfos getMetaInfos() {
|
||||||
|
return metaInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public byte[] serialize() {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
|
oos.writeObject(this);
|
||||||
|
oos.flush();
|
||||||
|
return baos.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handle(byte[] data) {
|
||||||
|
PacketHandler.handlePacket(deserialize(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handle(MetaInfos metaInfos, byte[] data) {
|
||||||
|
NetworkPacket networkPacket = deserialize(data);
|
||||||
|
networkPacket.metaInfos = metaInfos;
|
||||||
|
PacketHandler.handlePacket(networkPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static NetworkPacket deserialize(byte[] data) {
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||||
|
return (NetworkPacket) ois.readObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets;
|
||||||
|
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public abstract class PacketHandler {
|
||||||
|
|
||||||
|
private static final List<PacketHandler> PACKET_HANDLERS = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Map<Class<? extends NetworkPacket>, Method> HANDLER_MAP = new HashMap<>();
|
||||||
|
|
||||||
|
public static void handlePacket(NetworkPacket packet) {
|
||||||
|
for (PacketHandler handler : PACKET_HANDLERS) {
|
||||||
|
handler.handle(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PacketHandler() {
|
||||||
|
Method[] methods = getClass().getMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
if(method.getParameterCount() != 1 || !NetworkPacket.class.isAssignableFrom(method.getParameterTypes()[0])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.isAnnotationPresent(Handler.class)) {
|
||||||
|
Class<? extends NetworkPacket> packetClass = (Class<? extends NetworkPacket>) method.getParameterTypes()[0];
|
||||||
|
HANDLER_MAP.put(packetClass, method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register() {
|
||||||
|
PACKET_HANDLERS.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unregister() {
|
||||||
|
PACKET_HANDLERS.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public void handle(NetworkPacket packet) {
|
||||||
|
Method method = HANDLER_MAP.get(packet.getClass());
|
||||||
|
if (method == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
method.invoke(this, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
protected @interface Handler {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.client;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class ExecuteCommandPacket extends NetworkPacket {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 6283457297487602016L;
|
||||||
|
private int playerId;
|
||||||
|
private String command;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.client;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class ImALobbyPacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = 8110246509205246654L;
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.client;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class InventoryCallbackPacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = -261823209186008718L;
|
||||||
|
@Builder.Default
|
||||||
|
private int position = -1;
|
||||||
|
private int owner;
|
||||||
|
private CallbackType type;
|
||||||
|
@Builder.Default
|
||||||
|
private ClickType clickType = ClickType.UNKNOWN;
|
||||||
|
|
||||||
|
public enum CallbackType {
|
||||||
|
CLICK,
|
||||||
|
CLOSE,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ClickType {
|
||||||
|
LEFT,
|
||||||
|
SHIFT_LEFT,
|
||||||
|
RIGHT,
|
||||||
|
SHIFT_RIGHT,
|
||||||
|
WINDOW_BORDER_LEFT,
|
||||||
|
WINDOW_BORDER_RIGHT,
|
||||||
|
MIDDLE,
|
||||||
|
NUMBER_KEY,
|
||||||
|
DOUBLE_CLICK,
|
||||||
|
DROP,
|
||||||
|
CONTROL_DROP,
|
||||||
|
CREATIVE,
|
||||||
|
UNKNOWN;
|
||||||
|
|
||||||
|
public boolean isKeyboardClick() {
|
||||||
|
return this == NUMBER_KEY || this == DROP || this == CONTROL_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCreativeAction() {
|
||||||
|
return this == MIDDLE || this == CREATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRightClick() {
|
||||||
|
return this == RIGHT || this == SHIFT_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLeftClick() {
|
||||||
|
return this == LEFT || this == SHIFT_LEFT || this == DOUBLE_CLICK || this == CREATIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isShiftClick() {
|
||||||
|
return this == SHIFT_LEFT || this == SHIFT_RIGHT || this == CONTROL_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClickType getByName(String name) {
|
||||||
|
for (ClickType type : values()) {
|
||||||
|
if (type.name().equalsIgnoreCase(name)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.client;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class PrepareSchemPacket extends NetworkPacket {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -4798561188105813349L;
|
||||||
|
private int player;
|
||||||
|
private int schem;
|
||||||
|
private String schemType;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.common;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class FightEndsPacket extends NetworkPacket {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1279352415549011332L;
|
||||||
|
private byte win;
|
||||||
|
private int blueSchem;
|
||||||
|
private int redSchem;
|
||||||
|
private List<Integer> bluePlayers;
|
||||||
|
private List<Integer> redPlayers;
|
||||||
|
private String gameMode;
|
||||||
|
private int duration;
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.common;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class FightInfoPacket extends NetworkPacket {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 7448644597856605853L;
|
||||||
|
private @With String serverName;
|
||||||
|
private String gameMode;
|
||||||
|
private String arena;
|
||||||
|
private String blueName;
|
||||||
|
private String redName;
|
||||||
|
private String fightState;
|
||||||
|
private int countdown;
|
||||||
|
private int blueLeader;
|
||||||
|
private int redLeader;
|
||||||
|
private int blueSchem;
|
||||||
|
private int redSchem;
|
||||||
|
private List<Integer> bluePlayers;
|
||||||
|
private List<Integer> redPlayers;
|
||||||
|
private List<Integer> spectators;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.server;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class BaumemberUpdatePacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = 6863118892424244051L;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.server;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class CloseInventoryPacket extends NetworkPacket {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -2191021190060504521L;
|
||||||
|
private int playerId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.server;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class InventoryPacket extends NetworkPacket {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 8071052544654047316L;
|
||||||
|
private String title;
|
||||||
|
private int player;
|
||||||
|
private int size;
|
||||||
|
private Map<Integer, String> items;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.server;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class LocaleInvalidationPacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = 1113963147008168582L;
|
||||||
|
private int playerId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.server;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class PingPacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = 714647343959550378L;
|
||||||
|
private int id;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.packets.server;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Getter
|
||||||
|
public class StartingServerPacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = 2808607245898121801L;
|
||||||
|
private int user;
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.Field;
|
||||||
|
import de.steamwar.sql.internal.SelectStatement;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class BannedUserIPs {
|
||||||
|
|
||||||
|
private static final Table<BannedUserIPs> table = new Table<>(BannedUserIPs.class);
|
||||||
|
|
||||||
|
private static final SelectStatement<BannedUserIPs> getByID = table.selectFields("UserID");
|
||||||
|
private static final SelectStatement<BannedUserIPs> getByIP = new SelectStatement<>(table, "SELECT * FROM BannedUserIPs WHERE IP = ? ORDER BY Timestamp DESC");
|
||||||
|
private static final Statement banIP = table.insertAll();
|
||||||
|
private static final Statement unbanIPs = table.deleteFields("UserID");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int userID;
|
||||||
|
@Getter
|
||||||
|
@Field(def = "CURRENT_TIMESTAMP")
|
||||||
|
private final Timestamp timestamp;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final String ip;
|
||||||
|
|
||||||
|
public static List<BannedUserIPs> get(int userID) {
|
||||||
|
return getByID.listSelect(userID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<BannedUserIPs> get(String ip) {
|
||||||
|
return getByIP.listSelect(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void banIP(int userID, String ip){
|
||||||
|
banIP.update(userID, Timestamp.from(Instant.now()), ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unbanIPs(int userID) {
|
||||||
|
unbanIPs.update(userID);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
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.Getter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class BauweltMember {
|
||||||
|
private static final Map<Integer, BauweltMember> memberCache = new HashMap<>();
|
||||||
|
|
||||||
|
public static void clear() {
|
||||||
|
memberCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<BauweltMember> table = new Table<>(BauweltMember.class);
|
||||||
|
private static final SelectStatement<BauweltMember> getMember = table.select(Table.PRIMARY);
|
||||||
|
private static final SelectStatement<BauweltMember> getMembers = table.selectFields("BauweltID");
|
||||||
|
private static final Statement update = table.insertAll();
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
|
||||||
|
public static void addMember(UUID ownerID, UUID memberID) {
|
||||||
|
new BauweltMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId(), false, false).updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BauweltMember getBauMember(UUID ownerID, UUID memberID){
|
||||||
|
return getBauMember(SteamwarUser.get(ownerID).getId(), SteamwarUser.get(memberID).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BauweltMember getBauMember(int ownerID, int memberID){
|
||||||
|
BauweltMember member = memberCache.get(memberID);
|
||||||
|
if(member != null && member.bauweltID == ownerID)
|
||||||
|
return member;
|
||||||
|
return getMember.select(ownerID, memberID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<BauweltMember> getMembers(UUID bauweltID){
|
||||||
|
return getMembers(SteamwarUser.get(bauweltID).getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<BauweltMember> getMembers(int bauweltID){
|
||||||
|
return getMembers.listSelect(bauweltID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int bauweltID;
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int memberID;
|
||||||
|
@Getter
|
||||||
|
@Field(def = "0")
|
||||||
|
private boolean worldEdit;
|
||||||
|
@Getter
|
||||||
|
@Field(def = "0")
|
||||||
|
private boolean world;
|
||||||
|
|
||||||
|
public BauweltMember(int bauweltID, int memberID, boolean worldEdit, boolean world) {
|
||||||
|
this.bauweltID = bauweltID;
|
||||||
|
this.memberID = memberID;
|
||||||
|
this.worldEdit = worldEdit;
|
||||||
|
this.world = world;
|
||||||
|
memberCache.put(memberID, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorldEdit(boolean worldEdit) {
|
||||||
|
this.worldEdit = worldEdit;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWorld(boolean world) {
|
||||||
|
this.world = world;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDB(){
|
||||||
|
update.update(bauweltID, memberID, worldEdit, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(){
|
||||||
|
delete.update(bauweltID, memberID);
|
||||||
|
memberCache.remove(memberID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBuild() {
|
||||||
|
return worldEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSupervisor() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBuild(boolean build) {
|
||||||
|
this.worldEdit = build;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupervisor(boolean supervisor) {
|
||||||
|
this.world = supervisor;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
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 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");
|
||||||
|
private static final SelectStatement<CheckedSchematic> nodeHistory = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
|
||||||
|
private static final Statement insert = table.insertAll();
|
||||||
|
|
||||||
|
public static void create(int nodeId, String name, int owner, int validator, Timestamp startTime, Timestamp endTime, String reason){
|
||||||
|
insert.update(nodeId, owner, name, validator, startTime, endTime, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void create(SchematicNode node, int validator, Timestamp startTime, Timestamp endTime, String reason){
|
||||||
|
create(node.getId(), node.getName(), node.getOwner(), validator, startTime, endTime, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<CheckedSchematic> getLastDeclinedOfNode(int node){
|
||||||
|
return statusOfNode.listSelect(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<CheckedSchematic> previousChecks(SchematicNode node) {
|
||||||
|
return nodeHistory.listSelect(node.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
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.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Event {
|
||||||
|
|
||||||
|
static {
|
||||||
|
SchematicType.Normal.name(); // Ensure SchematicType is loaded.
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<Event> table = new Table<>(Event.class);
|
||||||
|
|
||||||
|
private static final SelectStatement<Event> byCurrent = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start < now() AND End > now()");
|
||||||
|
private static final SelectStatement<Event> byId = table.select(Table.PRIMARY);
|
||||||
|
private static final SelectStatement<Event> byName = table.select("eventName");
|
||||||
|
private static final SelectStatement<Event> byComing = new SelectStatement<>(table, "SELECT * FROM Event WHERE Start > now()");
|
||||||
|
|
||||||
|
private static Event current = null;
|
||||||
|
|
||||||
|
public static Event get(){
|
||||||
|
if(current != null && current.now())
|
||||||
|
return current;
|
||||||
|
|
||||||
|
current = byCurrent.select();
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Event get(int eventID){
|
||||||
|
return byId.select(eventID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Event get(String eventName) {
|
||||||
|
return byName.select(eventName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Event> getComing() {
|
||||||
|
return byComing.listSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
private final int eventID;
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {"eventName"})
|
||||||
|
private final String eventName;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final Timestamp deadline;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final Timestamp start;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final Timestamp end;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final int maximumTeamMembers;
|
||||||
|
@Field(nullable = true)
|
||||||
|
private final SchematicType schemType;
|
||||||
|
@Field
|
||||||
|
private final boolean publicSchemsOnly;
|
||||||
|
@Deprecated
|
||||||
|
@Field
|
||||||
|
private final boolean spectateSystem;
|
||||||
|
|
||||||
|
public boolean publicSchemsOnly() {
|
||||||
|
return publicSchemsOnly;
|
||||||
|
}
|
||||||
|
public boolean spectateSystem(){
|
||||||
|
return spectateSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchematicType getSchematicType() {
|
||||||
|
return schemType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean now() {
|
||||||
|
Instant now = Instant.now();
|
||||||
|
return now.isAfter(start.toInstant()) && now.isBefore(end.toInstant());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
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 lombok.Getter;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static java.time.temporal.ChronoUnit.SECONDS;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class EventFight implements Comparable<EventFight> {
|
||||||
|
|
||||||
|
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> 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 setFight = table.update(Table.PRIMARY, "Fight");
|
||||||
|
|
||||||
|
private static final Queue<EventFight> fights = new PriorityQueue<>();
|
||||||
|
|
||||||
|
public static EventFight get(int 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
|
||||||
|
@Field
|
||||||
|
private final int eventID;
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
private final int fightID;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private Timestamp startTime;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final String spielmodus;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final String map;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final int teamBlue;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final int teamRed;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
@Deprecated
|
||||||
|
private final int kampfleiter;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final int spectatePort;
|
||||||
|
@Getter
|
||||||
|
@Field(def = "0")
|
||||||
|
private int ergebnis;
|
||||||
|
@Field(nullable = true)
|
||||||
|
private int fight;
|
||||||
|
|
||||||
|
public void setErgebnis(int winner) {
|
||||||
|
this.ergebnis = winner;
|
||||||
|
setResult.update(winner, fightID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFight(int fight) {
|
||||||
|
//Fight.FightID, not EventFight.FightID
|
||||||
|
this.fight = fight;
|
||||||
|
setFight.update(fight, fightID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasFinished() {
|
||||||
|
return fight != 0 || ergebnis != 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
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 lombok.Getter;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Fight {
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
public static List<Fight> getPage(int page, int elementsPerPage) {
|
||||||
|
List<Fight> fights = getPage.listSelect(page * elementsPerPage, elementsPerPage);
|
||||||
|
|
||||||
|
List<FightPlayer> fightPlayers = FightPlayer.batchGet(fights.stream().map(f -> f.fightID));
|
||||||
|
for(Fight fight : fights) {
|
||||||
|
fight.initPlayers(fightPlayers);
|
||||||
|
}
|
||||||
|
|
||||||
|
SteamwarUser.batchCache(fightPlayers.stream().map(FightPlayer::getUserID).collect(Collectors.toSet()));
|
||||||
|
return fights;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int create(String gamemode, String server, Timestamp starttime, int duration, int blueleader, int redleader, Integer blueschem, Integer redschem, int win, String wincondition){
|
||||||
|
return insert.insertGetKey(gamemode, server, starttime, duration, blueleader, redleader, blueschem, redschem, win, wincondition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
private final int fightID;
|
||||||
|
@Field
|
||||||
|
private final String gameMode;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final String server;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final Timestamp startTime;
|
||||||
|
@Field
|
||||||
|
private final int duration;
|
||||||
|
@Field
|
||||||
|
private final int blueLeader;
|
||||||
|
@Field
|
||||||
|
private final int redLeader;
|
||||||
|
@Field(nullable = true)
|
||||||
|
private final Integer blueSchem;
|
||||||
|
@Field(nullable = true)
|
||||||
|
private final Integer redSchem;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final int win;
|
||||||
|
@Field
|
||||||
|
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<>();
|
||||||
|
@Getter
|
||||||
|
private final List<FightPlayer> redPlayers = new ArrayList<>();
|
||||||
|
|
||||||
|
public SchematicType getSchemType() {
|
||||||
|
return SchematicType.fromDB(gameMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SteamwarUser getBlueLeader() {
|
||||||
|
return SteamwarUser.get(blueLeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SteamwarUser getRedLeader() {
|
||||||
|
return SteamwarUser.get(redLeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean replayAllowed() {
|
||||||
|
return replayExists() && replayAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean replayExists() {
|
||||||
|
return getSchemType() != null && replayAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPlayers(List<FightPlayer> fightPlayers) {
|
||||||
|
for(FightPlayer fp : fightPlayers) {
|
||||||
|
if(fp.getFightID() != fightID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(fp.getTeam() == 1)
|
||||||
|
bluePlayers.add(fp);
|
||||||
|
else
|
||||||
|
redPlayers.add(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
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 lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class FightPlayer {
|
||||||
|
|
||||||
|
private static final Table<FightPlayer> table = new Table<>(FightPlayer.class);
|
||||||
|
private static final Statement create = table.insertAll();
|
||||||
|
private static final SelectStatement<FightPlayer> batchGet = new SelectStatement<>(table, "SELECT * FROM FightPlayer WHERE FightID IN ?");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int fightID;
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int userID;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final int team;
|
||||||
|
@Field
|
||||||
|
private final String kit;
|
||||||
|
@Field
|
||||||
|
private final int kills;
|
||||||
|
@Field
|
||||||
|
private final boolean isOut;
|
||||||
|
|
||||||
|
public static void create(int fightID, int userID, boolean blue, String kit, int kills, boolean isOut) {
|
||||||
|
create.update(fightID, userID, blue ? 1 : 2, kit, kills, isOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<FightPlayer> batchGet(Stream<Integer> fightIds) {
|
||||||
|
try (SelectStatement<FightPlayer> batch = new SelectStatement<>(table, "SELECT * FROM FightPlayer WHERE FightID IN (" + fightIds.map(Object::toString).collect(Collectors.joining(", ")) + ")")) {
|
||||||
|
return batch.listSelect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.Field;
|
||||||
|
import de.steamwar.sql.internal.SelectStatement;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class IgnoreSystem {
|
||||||
|
|
||||||
|
private static final Table<IgnoreSystem> table = new Table<>(IgnoreSystem.class, "IgnoredPlayers");
|
||||||
|
private static final SelectStatement<IgnoreSystem> select = table.select(Table.PRIMARY);
|
||||||
|
private static final Statement insert = table.insertAll();
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int ignorer;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int ignored;
|
||||||
|
|
||||||
|
public static boolean isIgnored(UUID ignorer, UUID ignored){
|
||||||
|
return isIgnored(SteamwarUser.get(ignorer), SteamwarUser.get(ignored));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isIgnored(SteamwarUser ignorer, SteamwarUser ignored) {
|
||||||
|
return select.select(ResultSet::next, ignorer.getId(), ignored.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ignore(SteamwarUser ignorer, SteamwarUser ignored) {
|
||||||
|
insert.update(ignorer.getId(), ignored.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unIgnore(SteamwarUser ignorer, SteamwarUser ignored) {
|
||||||
|
delete.update(ignorer.getId(), ignored.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class NoClipboardException extends RuntimeException {
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class NodeData {
|
||||||
|
|
||||||
|
static {
|
||||||
|
new SqlTypeMapper<>(PipedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("PipedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
|
||||||
|
new SqlTypeMapper<>(ByteArrayInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("ByteArrayInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
|
||||||
|
new SqlTypeMapper<>(BufferedInputStream.class, "BLOB", (rs, identifier) -> { throw new SecurityException("BufferedInputStream is write only datatype"); }, PreparedStatement::setBinaryStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<NodeData> table = new Table<>(NodeData.class);
|
||||||
|
|
||||||
|
private static final Statement updateDatabase = new Statement("INSERT INTO NodeData(NodeId, NodeFormat, SchemData) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE NodeFormat = VALUES(NodeFormat), SchemData = VALUES(SchemData)");
|
||||||
|
private static final Statement selSchemData = new Statement("SELECT SchemData FROM NodeData WHERE NodeId = ?");
|
||||||
|
|
||||||
|
private static final SelectStatement<NodeData> get = table.select(Table.PRIMARY);
|
||||||
|
|
||||||
|
public static NodeData get(SchematicNode node) {
|
||||||
|
if(node.isDir())
|
||||||
|
throw new IllegalArgumentException("Node is a directory");
|
||||||
|
return get.select(rs -> {
|
||||||
|
if(rs.next()) {
|
||||||
|
return new NodeData(node.getId(), rs.getBoolean("NodeFormat"));
|
||||||
|
} else {
|
||||||
|
return new NodeData(node.getId(), false);
|
||||||
|
}
|
||||||
|
}, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int nodeId;
|
||||||
|
|
||||||
|
@Field
|
||||||
|
private boolean nodeFormat;
|
||||||
|
|
||||||
|
public InputStream schemData() throws IOException {
|
||||||
|
try {
|
||||||
|
return selSchemData.select(rs -> {
|
||||||
|
rs.next();
|
||||||
|
InputStream schemData = rs.getBinaryStream("SchemData");
|
||||||
|
try {
|
||||||
|
if(rs.wasNull() || schemData.available() == 0) {
|
||||||
|
throw new SecurityException("SchemData is null");
|
||||||
|
}
|
||||||
|
return new GZIPInputStream(schemData);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SecurityException("SchemData is wrong", e);
|
||||||
|
}
|
||||||
|
}, nodeId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveFromStream(InputStream blob, boolean newFormat) {
|
||||||
|
updateDatabase.update(nodeId, newFormat, blob);
|
||||||
|
nodeFormat = newFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getNodeFormat() {
|
||||||
|
return nodeFormat;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.sql.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) & 0xF]).append(HEX[b & 0xF]);
|
||||||
|
return hexBuffer.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* 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.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class NodeMember {
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
// enforce class initialization
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<NodeMember> table = new Table<>(NodeMember.class);
|
||||||
|
private static final SelectStatement<NodeMember> getNodeMember = table.select(Table.PRIMARY);
|
||||||
|
private static final SelectStatement<NodeMember> getNodeMembers = table.selectFields("NodeId");
|
||||||
|
private static final SelectStatement<NodeMember> getSchematics = table.selectFields("UserId");
|
||||||
|
private static final Statement create = table.insert(Table.PRIMARY);
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
private static final Statement updateParent = table.update(Table.PRIMARY, "ParentId");
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int nodeId;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int userId;
|
||||||
|
@Field(nullable = true, def = "null")
|
||||||
|
private Integer parentId;
|
||||||
|
|
||||||
|
public int getNode() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMember() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getParent() {
|
||||||
|
return Optional.ofNullable(parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
delete.update(nodeId, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeMember createNodeMember(int node, int member) {
|
||||||
|
create.update(node, member);
|
||||||
|
return new NodeMember(node, member, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeMember getNodeMember(int node, int member) {
|
||||||
|
return getNodeMember.select(node, member);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<NodeMember> getNodeMembers(int node) {
|
||||||
|
return new HashSet<>(getNodeMembers.listSelect(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<NodeMember> getSchematics(int member) {
|
||||||
|
return new HashSet<>(getSchematics.listSelect(member));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setParentId(Integer parentId) {
|
||||||
|
this.parentId = parentId;
|
||||||
|
updateParent.update(this.parentId, nodeId, userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.Field;
|
||||||
|
import de.steamwar.sql.internal.SelectStatement;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PollAnswer {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private static String currentPoll;
|
||||||
|
|
||||||
|
private static final Table<PollAnswer> table = new Table<>(PollAnswer.class);
|
||||||
|
|
||||||
|
private static final SelectStatement<PollAnswer> get = table.select(Table.PRIMARY);
|
||||||
|
private static final Statement getResults = new Statement("SELECT Count(UserID) AS Times, Answer FROM PollAnswer WHERE Question = ? GROUP BY Answer ORDER BY Times ASC");
|
||||||
|
private static final Statement insert = table.insertAll();
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int userID;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final String question;
|
||||||
|
@Field(def = "0")
|
||||||
|
private int answer;
|
||||||
|
|
||||||
|
public static PollAnswer get(int userID) {
|
||||||
|
PollAnswer answer = get.select(userID, currentPoll);
|
||||||
|
if(answer == null)
|
||||||
|
return new PollAnswer(userID, currentPoll, 0);
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Integer, Integer> getCurrentResults() {
|
||||||
|
return getResults.select(rs -> {
|
||||||
|
Map<Integer, Integer> retMap = new HashMap<>();
|
||||||
|
while (rs.next())
|
||||||
|
retMap.put(rs.getInt("Answer")-1, rs.getInt("Times"));
|
||||||
|
return retMap;
|
||||||
|
}, currentPoll);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAnswered(){
|
||||||
|
return answer != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAnswer(int answer){
|
||||||
|
this.answer = answer;
|
||||||
|
insert.update(userID, question, answer);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* 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.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Punishment {
|
||||||
|
|
||||||
|
static {
|
||||||
|
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 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> 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)
|
||||||
|
private final int punishmentId;
|
||||||
|
@Field
|
||||||
|
@Getter
|
||||||
|
private final int userId;
|
||||||
|
@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;
|
||||||
|
|
||||||
|
@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
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@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"),
|
||||||
|
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 String teamMessage;
|
||||||
|
private final String playerMessagePerma;
|
||||||
|
private final String playerMessageUntil;
|
||||||
|
private final String usageNotPunished;
|
||||||
|
private final String unpunishmentMessage;
|
||||||
|
private boolean multi = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 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 Referee {
|
||||||
|
|
||||||
|
private static final Table<Referee> table = new Table<>(Referee.class);
|
||||||
|
private static final SelectStatement<Referee> byEvent = table.selectFields("eventID");
|
||||||
|
|
||||||
|
public static Set<Integer> get(int eventID) {
|
||||||
|
return byEvent.listSelect(eventID).stream().map(referee -> referee.userID).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field(keys = {"eventReferee"})
|
||||||
|
private final int eventID;
|
||||||
|
@Field(keys = {"eventReferee"})
|
||||||
|
private final int userID;
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* 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.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Replay {
|
||||||
|
|
||||||
|
static {
|
||||||
|
new SqlTypeMapper<>(File.class, "BLOB", (rs, identifier) -> {
|
||||||
|
try {
|
||||||
|
File file = File.createTempFile("replay", ".replay");
|
||||||
|
file.deleteOnExit();
|
||||||
|
Files.copy(rs.getBinaryStream(identifier), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
return file;
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SQLException(e);
|
||||||
|
}
|
||||||
|
}, (st, index, value) -> {
|
||||||
|
try {
|
||||||
|
st.setBinaryStream(index, new FileInputStream(value));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new SQLException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<Replay> table = new Table<>(Replay.class);
|
||||||
|
private static final SelectStatement<Replay> get = table.select(Table.PRIMARY);
|
||||||
|
|
||||||
|
public static final Statement insert = table.insertAll();
|
||||||
|
|
||||||
|
public static Replay get(int fightID) {
|
||||||
|
return get.select(fightID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void save(int fightID, File file) {
|
||||||
|
insert.update(fightID, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int fightID;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private final File replay;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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.ImplementationProvider;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface SQLWrapper {
|
||||||
|
SQLWrapper impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLWrapperImpl");
|
||||||
|
|
||||||
|
void loadSchemTypes(List<SchematicType> tmpTypes, Map<String, SchematicType> tmpFromDB);
|
||||||
|
|
||||||
|
void additionalExceptionMetadata(StringBuilder builder);
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SWException {
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
// force class initialialisation
|
||||||
|
}
|
||||||
|
|
||||||
|
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.insertFields(true, "server", "message", "stacktrace");
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
private final int id;
|
||||||
|
@Field(def = "CURRENT_TIMESTAMP")
|
||||||
|
private final Timestamp time;
|
||||||
|
@Field
|
||||||
|
private final String server;
|
||||||
|
@Field
|
||||||
|
private final String message;
|
||||||
|
@Field
|
||||||
|
private final String stacktrace;
|
||||||
|
|
||||||
|
public static void log(String message, String stacktrace){
|
||||||
|
insert.update(SERVER_NAME, generateMessage(message), stacktrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int logGetId(String message, String stacktrace) {
|
||||||
|
return insert.insertGetKey(SERVER_NAME, generateMessage(message), stacktrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generateMessage(String message) {
|
||||||
|
StringBuilder msgBuilder = new StringBuilder(message);
|
||||||
|
SQLWrapper.impl.additionalExceptionMetadata(msgBuilder);
|
||||||
|
msgBuilder.append("\nCWD: ").append(CWD);
|
||||||
|
return msgBuilder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* 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.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SchemElo {
|
||||||
|
private static final int ELO_DEFAULT = 1000;
|
||||||
|
|
||||||
|
private static final Table<SchemElo> table = new Table<>(SchemElo.class);
|
||||||
|
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})
|
||||||
|
private final int schemId;
|
||||||
|
@Field
|
||||||
|
private final int elo;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int season;
|
||||||
|
}
|
||||||
@@ -0,0 +1,559 @@
|
|||||||
|
/*
|
||||||
|
* 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.Getter;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class SchematicNode {
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<Integer, Map<String, List<String>>> TAB_CACHE = new HashMap<>();
|
||||||
|
public static void clear() {
|
||||||
|
TAB_CACHE.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String nodeSelector = "SELECT NodeId, NodeOwner, NodeOwner AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode ";
|
||||||
|
|
||||||
|
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
|
||||||
|
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
|
||||||
|
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
|
||||||
|
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table, nodeSelector + "WHERE NodeId = ?");
|
||||||
|
private static final SelectStatement<SchematicNode> byOwnerNameParent = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?");
|
||||||
|
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay 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> 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 RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||||
|
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> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
|
||||||
|
|
||||||
|
static {
|
||||||
|
NodeMember.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
private final int nodeId;
|
||||||
|
@Field(keys = {"OwnerNameParent"})
|
||||||
|
private final int nodeOwner;
|
||||||
|
@Field(def = "0")
|
||||||
|
@Getter
|
||||||
|
private final int effectiveOwner;
|
||||||
|
@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;
|
||||||
|
|
||||||
|
private String brCache;
|
||||||
|
|
||||||
|
public SchematicNode(
|
||||||
|
int nodeId,
|
||||||
|
int nodeOwner,
|
||||||
|
int effectiveOwner,
|
||||||
|
String nodeName,
|
||||||
|
Integer parentNode,
|
||||||
|
Timestamp lastUpdate,
|
||||||
|
String nodeItem,
|
||||||
|
SchematicType nodeType,
|
||||||
|
int nodeRank,
|
||||||
|
boolean replaceColor,
|
||||||
|
boolean allowReplay
|
||||||
|
) {
|
||||||
|
this.nodeId = nodeId;
|
||||||
|
this.nodeOwner = nodeOwner;
|
||||||
|
this.effectiveOwner = effectiveOwner;
|
||||||
|
this.nodeName = nodeName;
|
||||||
|
this.parentNode = parentNode;
|
||||||
|
this.nodeItem = nodeItem;
|
||||||
|
this.nodeType = nodeType;
|
||||||
|
this.lastUpdate = lastUpdate;
|
||||||
|
this.nodeRank = nodeRank;
|
||||||
|
this.replaceColor = replaceColor;
|
||||||
|
this.allowReplay = allowReplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> getAll(SteamwarUser user) {
|
||||||
|
return all.listSelect(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Integer, List<SchematicNode>> getAllMap(SteamwarUser user) {
|
||||||
|
return map(getAll(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> list(SteamwarUser user, Integer schematicId) {
|
||||||
|
return list.listSelect(user, schematicId, user, user, schematicId, user, schematicId, schematicId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SchematicNode byParentName(SteamwarUser user, Integer schematicId, String name) {
|
||||||
|
return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
|
||||||
|
return accessibleByUserType.listSelect(user, user, user, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Integer, List<SchematicNode>> accessibleByUserTypeMap(SteamwarUser user, SchematicType type) {
|
||||||
|
return map(accessibleByUserType(user, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean schematicAccessibleForUser(SteamwarUser user, Integer schematicId) {
|
||||||
|
return schematicAccessibleForUser.select(user, schematicId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
|
||||||
|
return accessibleByUserTypeInParent.listSelect(user, user, type, user, parentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SchematicNode byIdAndUser(SteamwarUser user, Integer id) {
|
||||||
|
return byIdAndUser.select(user, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> parentsOfNode(SteamwarUser user, Integer id) {
|
||||||
|
return allParentsOfNode.listSelect(id, user, user, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, List<SchematicNode>> map(List<SchematicNode> in) {
|
||||||
|
Map<Integer, List<SchematicNode>> map = new HashMap<>();
|
||||||
|
for (SchematicNode effectiveSchematicNode : in) {
|
||||||
|
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>()).add(effectiveSchematicNode);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, item, type);
|
||||||
|
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) {
|
||||||
|
return byOwnerNameParent.select(owner, name, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> getSchematicNodeInNode(SchematicNode parent) {
|
||||||
|
return getSchematicNodeInNode(parent.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> getSchematicNodeInNode(Integer parent) {
|
||||||
|
return byParent.listSelect(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> getSchematicDirectoryInNode(Integer parent) {
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
return accessibleByUserTypeParent(SteamwarUser.get(owner), SchematicType.fromDB(schemType), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> getAllAccessibleSchematicsOfType(int user, String schemType) {
|
||||||
|
return accessibleByUserType(SteamwarUser.get(user), SchematicType.fromDB(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static List<SchematicNode> getSchematicsAccessibleByUser(int user, Integer parent) {
|
||||||
|
return list(SteamwarUser.get(user), parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static List<SchematicNode> getAllSchematicsAccessibleByUser(int user) {
|
||||||
|
return getAll(SteamwarUser.get(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.endsWith("/")) {
|
||||||
|
s = s.substring(0, s.length() - 1);
|
||||||
|
}
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (s.contains("/")) {
|
||||||
|
String[] layers = s.split("/");
|
||||||
|
Optional<SchematicNode> currentNode = Optional.ofNullable(SchematicNode.byParentName(user, null, layers[0]));
|
||||||
|
for (int i = 1; i < layers.length; i++) {
|
||||||
|
int finalI = i;
|
||||||
|
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
|
||||||
|
if (!node.isPresent()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
currentNode = node;
|
||||||
|
if (!currentNode.map(SchematicNode::isDir).orElse(false) && i != layers.length - 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentNode.orElse(null);
|
||||||
|
} else {
|
||||||
|
return SchematicNode.byParentName(user, null, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Optional<Integer> getOptionalParent() {
|
||||||
|
return Optional.ofNullable(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public boolean getSchemFormat() {
|
||||||
|
if(isDir())
|
||||||
|
throw new SecurityException("Node is Directory");
|
||||||
|
return NodeData.get(this).getNodeFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
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(nodeName, parentNode, nodeItem, nodeType, nodeRank, replaceColor, allowReplay, nodeId);
|
||||||
|
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 byIdAndUser(user, nodeId).generateBreadcrumbs();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateBreadcrumbs(String split, SteamwarUser user) {
|
||||||
|
return byIdAndUser(user, nodeId).generateBreadcrumbs(split);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateBreadcrumbs() {
|
||||||
|
if(brCache == null) {
|
||||||
|
brCache = generateBreadcrumbs("/");
|
||||||
|
}
|
||||||
|
return brCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateBreadcrumbs(String split) {
|
||||||
|
StringBuilder builder = new StringBuilder(getName());
|
||||||
|
Optional<SchematicNode> currentNode = Optional.of(this);
|
||||||
|
if(currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||||
|
builder.append(split);
|
||||||
|
}
|
||||||
|
while (currentNode.isPresent()) {
|
||||||
|
currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode);
|
||||||
|
currentNode.ifPresent(node -> builder.insert(0, split).insert(0, node.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 new ArrayList<>();
|
||||||
|
List<SchematicNode> nodes = SchematicNode.list(user, pa.getId());
|
||||||
|
String br = pa.generateBreadcrumbs();
|
||||||
|
nodes.forEach(node -> list.add((sws ? "/" : "") + br + node.getName() + (node.isDir() ? "/" : "")));
|
||||||
|
} else {
|
||||||
|
List<SchematicNode> nodes = SchematicNode.list(user, null);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
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.SqlTypeMapper;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class SchematicType {
|
||||||
|
|
||||||
|
public static final SchematicType Normal = new SchematicType("Normal", "", Type.NORMAL, null, "STONE_BUTTON", false);
|
||||||
|
|
||||||
|
private static final Map<String, SchematicType> fromDB;
|
||||||
|
private static final List<SchematicType> types;
|
||||||
|
|
||||||
|
static {
|
||||||
|
List<SchematicType> tmpTypes = new LinkedList<>();
|
||||||
|
Map<String, SchematicType> tmpFromDB = new HashMap<>();
|
||||||
|
|
||||||
|
tmpTypes.add(Normal);
|
||||||
|
tmpFromDB.put(Normal.name().toLowerCase(), Normal);
|
||||||
|
|
||||||
|
SQLWrapper.impl.loadSchemTypes(tmpTypes, tmpFromDB);
|
||||||
|
|
||||||
|
fromDB = Collections.unmodifiableMap(tmpFromDB);
|
||||||
|
types = Collections.unmodifiableList(tmpTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
new SqlTypeMapper<>(SchematicType.class, "VARCHAR(16)", (rs, identifier) -> {
|
||||||
|
String t = rs.getString(identifier);
|
||||||
|
return t != null ? fromDB.get(t) : null;
|
||||||
|
}, (st, index, value) -> st.setString(index, value.toDB()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
@Getter
|
||||||
|
private final String kuerzel;
|
||||||
|
private final Type type;
|
||||||
|
private final SchematicType checkType;
|
||||||
|
@Getter
|
||||||
|
private final String material;
|
||||||
|
@Getter
|
||||||
|
private final Date deadline;
|
||||||
|
@Getter
|
||||||
|
private final boolean manualCheck;
|
||||||
|
|
||||||
|
SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material, boolean manualCheck){
|
||||||
|
this(name, kuerzel, type, checkType, material, null, manualCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
SchematicType(String name, String kuerzel, Type type, SchematicType checkType, String material, Date deadline, boolean manualCheck){
|
||||||
|
this.name = name;
|
||||||
|
this.kuerzel = kuerzel;
|
||||||
|
this.type = type;
|
||||||
|
this.checkType = checkType;
|
||||||
|
this.material = material;
|
||||||
|
this.deadline = deadline;
|
||||||
|
this.manualCheck = manualCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAssignable(){
|
||||||
|
return type == Type.NORMAL || (type == Type.FIGHT_TYPE && checkType != null) || !manualCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SchematicType checkType(){
|
||||||
|
if (!manualCheck) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return checkType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean check(){
|
||||||
|
return type == Type.CHECK_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean fightType(){
|
||||||
|
return type == Type.FIGHT_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean writeable(){
|
||||||
|
return type == Type.NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name(){
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toDB(){
|
||||||
|
return name.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SchematicType fromDB(String input){
|
||||||
|
return fromDB.get(input.toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicType> values(){
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Type{
|
||||||
|
NORMAL,
|
||||||
|
CHECK_TYPE,
|
||||||
|
FIGHT_TYPE
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 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();
|
||||||
|
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){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.Field;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Session {
|
||||||
|
|
||||||
|
private static final Table<Session> table = new Table<>(Session.class);
|
||||||
|
private static final Statement insert = table.insert(Table.PRIMARY);
|
||||||
|
|
||||||
|
public static void insertSession(int userID, Timestamp startTime){
|
||||||
|
insert.update(userID, startTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private int userId;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private Timestamp startTime;
|
||||||
|
@Field(def = "CURRENT_TIMESTAMP")
|
||||||
|
private Timestamp endTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,362 @@
|
|||||||
|
/*
|
||||||
|
* 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.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
import javax.crypto.SecretKeyFactory;
|
||||||
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.security.spec.InvalidKeySpecException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class SteamwarUser {
|
||||||
|
private static final SecureRandom random = new SecureRandom();
|
||||||
|
private static final SecretKeyFactory factory;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
throw new SecurityException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
new SqlTypeMapper<>(UUID.class, "CHAR(36)", (rs, identifier) -> UUID.fromString(rs.getString(identifier)), (st, index, value) -> st.setString(index, value.toString()));
|
||||||
|
new SqlTypeMapper<>(Locale.class, "VARCHAR(32)", (rs, identifier) -> {
|
||||||
|
String l = rs.getString(identifier);
|
||||||
|
return l != null ? Locale.forLanguageTag(l) : null;
|
||||||
|
}, (st, index, value) -> st.setString(index, value.toLanguageTag()));
|
||||||
|
new SqlTypeMapper<>(SteamwarUser.class, null, (rs, identifier) -> { throw new SecurityException("SteamwarUser cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<SteamwarUser> table = new Table<>(SteamwarUser.class, "UserData");
|
||||||
|
private static final Statement insert = table.insertFields("UUID", "UserName");
|
||||||
|
private static final SelectStatement<SteamwarUser> byID = table.selectFields("id");
|
||||||
|
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 updatePassword = table.update(Table.PRIMARY, "Password");
|
||||||
|
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 updateLeader = table.update(Table.PRIMARY, "Leader");
|
||||||
|
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<UUID, SteamwarUser> usersByUUID = new HashMap<>();
|
||||||
|
private static final Map<String, SteamwarUser> usersByName = new HashMap<>();
|
||||||
|
private static final Map<Long, SteamwarUser> usersByDiscord = new HashMap<>();
|
||||||
|
public static void clear() {
|
||||||
|
usersById.clear();
|
||||||
|
usersByName.clear();
|
||||||
|
usersByUUID.clear();
|
||||||
|
usersByDiscord.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void invalidate(int userId) {
|
||||||
|
SteamwarUser user = usersById.remove(userId);
|
||||||
|
if (user == null)
|
||||||
|
return;
|
||||||
|
usersByName.remove(user.getUserName());
|
||||||
|
usersByUUID.remove(user.getUUID());
|
||||||
|
usersByDiscord.remove(user.getDiscordId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SteamwarUser get(String userName){
|
||||||
|
SteamwarUser user = usersByName.get(userName.toLowerCase());
|
||||||
|
if(user != null)
|
||||||
|
return user;
|
||||||
|
return byName.select(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SteamwarUser get(UUID uuid){
|
||||||
|
SteamwarUser user = usersByUUID.get(uuid);
|
||||||
|
if(user != null)
|
||||||
|
return user;
|
||||||
|
return byUUID.select(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SteamwarUser get(int id) {
|
||||||
|
SteamwarUser user = usersById.get(id);
|
||||||
|
if(user != null)
|
||||||
|
return user;
|
||||||
|
return byID.select(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SteamwarUser get(Long discordId) {
|
||||||
|
if(usersByDiscord.containsKey(discordId))
|
||||||
|
return usersByDiscord.get(discordId);
|
||||||
|
return byDiscord.select(discordId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SteamwarUser getOrCreate(UUID uuid, String name, Consumer<UUID> newPlayer, BiConsumer<String, String> nameUpdate) {
|
||||||
|
SteamwarUser user = get(uuid);
|
||||||
|
|
||||||
|
if (user != null) {
|
||||||
|
if (!user.userName.equals(name)) {
|
||||||
|
updateName.update(name, user.id);
|
||||||
|
nameUpdate.accept(user.userName, name);
|
||||||
|
user.userName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
} else {
|
||||||
|
insert.update(uuid, name);
|
||||||
|
newPlayer.accept(uuid);
|
||||||
|
return get(uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SteamwarUser> getServerTeam() {
|
||||||
|
return getServerTeam.listSelect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SteamwarUser> getTeam(int teamId) {
|
||||||
|
return byTeam.listSelect(teamId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void batchCache(Set<Integer> ids) {
|
||||||
|
ids.removeIf(usersById::containsKey);
|
||||||
|
if(ids.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
try (SelectStatement<SteamwarUser> batch = new SelectStatement<>(table, "SELECT * FROM UserData WHERE id IN (" + ids.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")")) {
|
||||||
|
batch.listSelect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
private final int id;
|
||||||
|
@Field(keys = {"uuid"})
|
||||||
|
private final UUID uuid;
|
||||||
|
@Getter
|
||||||
|
@Field
|
||||||
|
private String userName;
|
||||||
|
@Field(nullable = true)
|
||||||
|
private String password;
|
||||||
|
@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 Map<Punishment.PunishmentType, Punishment> punishments = null;
|
||||||
|
private Set<UserPerm> permissions = null;
|
||||||
|
private UserPerm.Prefix prefix = null;
|
||||||
|
|
||||||
|
public SteamwarUser(int id, UUID uuid, String userName, String password, int team, boolean leader, Locale locale, boolean manualLocale, Long discordId) {
|
||||||
|
this.id = id;
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.userName = userName;
|
||||||
|
this.password = password;
|
||||||
|
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 Punishment getPunishment(Punishment.PunishmentType type) {
|
||||||
|
initPunishments();
|
||||||
|
return punishments.getOrDefault(type, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPunished(Punishment.PunishmentType punishment) {
|
||||||
|
initPunishments();
|
||||||
|
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 boolean hasPerm(UserPerm perm) {
|
||||||
|
initPerms();
|
||||||
|
return permissions.contains(perm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<UserPerm> perms() {
|
||||||
|
initPerms();
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserPerm.Prefix prefix() {
|
||||||
|
initPerms();
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
initPunishments();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
try {
|
||||||
|
byte[] salt = new byte[16];
|
||||||
|
random.nextBytes(salt);
|
||||||
|
String saltString = Base64.getEncoder().encodeToString(salt);
|
||||||
|
|
||||||
|
byte[] hash = generateHash(password, salt);
|
||||||
|
String hashString = Base64.getEncoder().encodeToString(hash);
|
||||||
|
this.password = hashString + ":" + saltString;
|
||||||
|
updatePassword.update(this.password, id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new SecurityException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean verifyPassword(String password) {
|
||||||
|
try {
|
||||||
|
if (this.password == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = this.password.split(":");
|
||||||
|
if (parts.length != 2) {
|
||||||
|
SQLConfig.impl.getLogger().log(Level.SEVERE ,"Invalid password hash for user {0} ({1})", new Object[]{userName, id});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String hashString = parts[0];
|
||||||
|
byte[] realHash = Base64.getDecoder().decode(hashString);
|
||||||
|
String saltString = parts[1];
|
||||||
|
byte[] salt = Base64.getDecoder().decode(saltString);
|
||||||
|
byte[] hash = generateHash(password, salt);
|
||||||
|
return Arrays.equals(realHash, hash);
|
||||||
|
} catch (Exception e) {
|
||||||
|
SQLConfig.impl.getLogger().log(Level.SEVERE, "Error while verifying password for user " + userName + " (" + id + ")", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] generateHash(String password, byte[] salt)
|
||||||
|
throws InvalidKeySpecException {
|
||||||
|
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 512);
|
||||||
|
return factory.generateSecret(spec).getEncoded();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPunishments() {
|
||||||
|
if(punishments != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
punishments = Punishment.getPunishmentsOfPlayer(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initPerms() {
|
||||||
|
if(permissions != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
permissions = UserPerm.getPerms(id);
|
||||||
|
prefix = permissions.stream().filter(UserPerm.prefixes::containsKey).findAny().map(UserPerm.prefixes::get).orElse(UserPerm.emptyPrefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
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 lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Team {
|
||||||
|
|
||||||
|
private static final Map<Integer, Team> teamCache = new HashMap<>();
|
||||||
|
|
||||||
|
public static void clear() {
|
||||||
|
teamCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<Team> table = new Table<>(Team.class);
|
||||||
|
private static final SelectStatement<Team> byId = table.select(Table.PRIMARY);
|
||||||
|
private static final SelectStatement<Team> byName = new SelectStatement<>(table, "SELECT * FROM Team WHERE (lower(TeamName) = ? OR lower(TeamKuerzel) = ?) AND NOT TeamDeleted");
|
||||||
|
private static final SelectStatement<Team> all = table.selectFields("TeamDeleted");
|
||||||
|
private static final Statement insert = table.insertFields("TeamKuerzel", "TeamName");
|
||||||
|
private static final Statement update = table.update(Table.PRIMARY, "TeamKuerzel", "TeamName", "TeamColor", "Address", "Port");
|
||||||
|
private static final Statement delete = table.update(Table.PRIMARY, "TeamDeleted");
|
||||||
|
private static final Statement getSize = new Statement("SELECT COUNT(id) FROM UserData WHERE Team = ?");
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
@Getter
|
||||||
|
private final int teamId;
|
||||||
|
@Field
|
||||||
|
@Getter
|
||||||
|
private String teamKuerzel;
|
||||||
|
@Field
|
||||||
|
@Getter
|
||||||
|
private String teamName;
|
||||||
|
@Field(def = "'8'")
|
||||||
|
@Getter
|
||||||
|
private String teamColor;
|
||||||
|
@Field(nullable = true)
|
||||||
|
@Getter
|
||||||
|
private String address;
|
||||||
|
@Field(def = "'25565'")
|
||||||
|
@Getter
|
||||||
|
private int port;
|
||||||
|
@Field(def = "0")
|
||||||
|
private boolean teamDeleted;
|
||||||
|
|
||||||
|
public static void create(String kuerzel, String name){
|
||||||
|
insert.update(kuerzel, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Team get(int id) {
|
||||||
|
return teamCache.computeIfAbsent(id, byId::select);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Team get(String name){
|
||||||
|
// No cache lookup due to low frequency use
|
||||||
|
name = name.toLowerCase();
|
||||||
|
return byName.select(name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Team> getAll(){
|
||||||
|
clear();
|
||||||
|
List<Team> teams = all.listSelect(false);
|
||||||
|
teams.forEach(team -> teamCache.put(team.getTeamId(), team));
|
||||||
|
return teams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getMembers(){
|
||||||
|
return SteamwarUser.getTeam(teamId).stream().map(SteamwarUser::getId).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size(){
|
||||||
|
return getSize.select(rs -> {
|
||||||
|
rs.next();
|
||||||
|
return rs.getInt("COUNT(id)");
|
||||||
|
}, teamId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disband(SteamwarUser user){
|
||||||
|
user.setLeader(false);
|
||||||
|
delete.update(true, teamId);
|
||||||
|
teamCache.remove(teamId);
|
||||||
|
TeamTeilnahme.deleteFuture(teamId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTeamKuerzel(String teamKuerzel) {
|
||||||
|
this.teamKuerzel = teamKuerzel;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTeamName(String teamName) {
|
||||||
|
this.teamName = teamName;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTeamColor(String teamColor) {
|
||||||
|
this.teamColor = teamColor;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAddress(String address) {
|
||||||
|
this.address = address;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPort(int port) {
|
||||||
|
this.port = port;
|
||||||
|
updateDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDB(){
|
||||||
|
update.update(teamKuerzel, teamName, teamColor, address, port, teamId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* 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.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");
|
||||||
|
private static final Statement insert = table.insert(Table.PRIMARY);
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
private static final Statement deleteFuture = new Statement("DELETE t FROM TeamTeilnahme t INNER JOIN Event e ON t.EventID = e.EventID WHERE t.TeamID = ? AND e.Start > NOW()");
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int teamId;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int eventId;
|
||||||
|
|
||||||
|
public static boolean nimmtTeil(int teamID, int eventID){
|
||||||
|
return select.select(teamID, eventID) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void teilnehmen(int teamID, int eventID){
|
||||||
|
insert.update(teamID, eventID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void notTeilnehmen(int teamID, int eventID){
|
||||||
|
delete.update(teamID, eventID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deleteFuture(int teamID) {
|
||||||
|
deleteFuture.update(teamID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Team> getTeams(int eventID){
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.Field;
|
||||||
|
import de.steamwar.sql.internal.SelectStatement;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@ToString
|
||||||
|
public class Token {
|
||||||
|
private static final Table<Token> table = new Table<>(Token.class);
|
||||||
|
private static final Statement insert = table.insertFields(true, "Name", "Owner", "Hash");
|
||||||
|
private static final SelectStatement<Token> get = table.select(Table.PRIMARY);
|
||||||
|
private static final SelectStatement<Token> listUser = table.selectFields("owner");
|
||||||
|
private static final SelectStatement<Token> getHash = table.selectFields("hash");
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
private static String getHash(String code) {
|
||||||
|
return Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-512").digest(code.getBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static String createToken(String name, SteamwarUser owner) {
|
||||||
|
SecureRandom random = new SecureRandom();
|
||||||
|
byte[] bytes = new byte[20];
|
||||||
|
random.nextBytes(bytes);
|
||||||
|
|
||||||
|
String code = Base64.getEncoder().encodeToString(bytes);
|
||||||
|
|
||||||
|
String hash = getHash(code);
|
||||||
|
create(name, owner, hash);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Token getTokenByCode(String code) {
|
||||||
|
String hash = getHash(code);
|
||||||
|
return get(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Token create(String name, SteamwarUser owner, String hash) {
|
||||||
|
int id = insert.insertGetKey(name, owner, hash);
|
||||||
|
return get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Token get(int id) {
|
||||||
|
return get.select(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Token> listUser(SteamwarUser owner) {
|
||||||
|
return listUser.listSelect(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Token get(String hash) {
|
||||||
|
return getHash.select(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void delete(Token id) {
|
||||||
|
delete.update(id.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Field(keys = Table.PRIMARY, autoincrement = true)
|
||||||
|
private final int id;
|
||||||
|
@Field(keys = "NameOwner")
|
||||||
|
private final String name;
|
||||||
|
@Field(keys = "NameOwner")
|
||||||
|
private final int owner;
|
||||||
|
@Field
|
||||||
|
private final Timestamp created;
|
||||||
|
@Field
|
||||||
|
private final String hash;
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
delete(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SteamwarUser getOwner() {
|
||||||
|
return SteamwarUser.get(owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.Field;
|
||||||
|
import de.steamwar.sql.internal.SelectStatement;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Tutorial {
|
||||||
|
|
||||||
|
private static final Table<Tutorial> table = new Table<>(Tutorial.class);
|
||||||
|
private static final SelectStatement<Tutorial> by_popularity = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.Released = ? GROUP BY t.TutorialID ORDER BY SUM(r.Stars) DESC LIMIT ?, ?");
|
||||||
|
private static final SelectStatement<Tutorial> own = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.Creator = ? GROUP BY t.TutorialID ORDER BY t.TutorialID ASC LIMIT ?, ?");
|
||||||
|
private static final SelectStatement<Tutorial> by_creator_name = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.Creator = ? AND t.Name = ? GROUP BY t.TutorialID");
|
||||||
|
private static final SelectStatement<Tutorial> by_id = new SelectStatement<>(table, "SELECT t.*, AVG(r.Stars) AS Stars FROM Tutorial t LEFT OUTER JOIN TutorialRating r ON t.TutorialID = r.TutorialID WHERE t.TutorialID = ? GROUP BY t.TutorialID");
|
||||||
|
private static final Statement rate = new Statement("INSERT INTO TutorialRating (TutorialID, UserID, Stars) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Stars = VALUES(Stars)");
|
||||||
|
private static final Statement create = new Statement("INSERT INTO Tutorial (Creator, Name, Item) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Item = VALUES(Item), Released = 0");
|
||||||
|
private static final Statement release = table.update(Table.PRIMARY, "released");
|
||||||
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
|
||||||
|
public static List<Tutorial> getPage(int page, int elementsPerPage, boolean released) {
|
||||||
|
List<Tutorial> tutorials = by_popularity.listSelect(released, page * elementsPerPage, elementsPerPage);
|
||||||
|
SteamwarUser.batchCache(tutorials.stream().map(tutorial -> tutorial.creator).collect(Collectors.toSet()));
|
||||||
|
return tutorials;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Tutorial> getOwn(int user, int page, int elementsPerPage) {
|
||||||
|
return own.listSelect(user, page * elementsPerPage, elementsPerPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tutorial create(int creator, String name, String item) {
|
||||||
|
create.update(creator, name, item);
|
||||||
|
return by_creator_name.select(creator, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Tutorial get(int id) {
|
||||||
|
return by_id.select(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
|
private final int tutorialId;
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {"CreatorName"})
|
||||||
|
private final int creator;
|
||||||
|
@Getter
|
||||||
|
@Field(keys = {"CreatorName"})
|
||||||
|
private final String name;
|
||||||
|
@Getter
|
||||||
|
@Field(def = "'BOOK'")
|
||||||
|
private final String item;
|
||||||
|
@Getter
|
||||||
|
@Field(def = "0")
|
||||||
|
private final boolean released;
|
||||||
|
@Getter
|
||||||
|
@Field(def = "0") // Not really a field, but necessary for select generation
|
||||||
|
private final double stars;
|
||||||
|
|
||||||
|
public void release() {
|
||||||
|
release.update(1, tutorialId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
delete.update(tutorialId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rate(int user, int rating) {
|
||||||
|
rate.update(tutorialId, user, rating);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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) {
|
||||||
|
UserConfig value = select.select(player, config);
|
||||||
|
return value != null ? value.value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.sql;
|
||||||
|
|
||||||
|
import de.steamwar.sql.internal.Field;
|
||||||
|
import de.steamwar.sql.internal.SelectStatement;
|
||||||
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserElo {
|
||||||
|
|
||||||
|
private static final int ELO_DEFAULT = 0;
|
||||||
|
|
||||||
|
private static final Map<String, Map<Integer, Optional<Integer>>> gameModeUserEloCache = new ConcurrentHashMap<>();
|
||||||
|
private static final Map<Integer, String> emblemCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public static void clear() {
|
||||||
|
gameModeUserEloCache.clear();
|
||||||
|
emblemCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<UserElo> table = new Table<>(UserElo.class);
|
||||||
|
private static final SelectStatement<UserElo> getElo = table.select(Table.PRIMARY);
|
||||||
|
private static final Statement setElo = table.insertAll();
|
||||||
|
|
||||||
|
private static final Statement place = new Statement("SELECT COUNT(*) AS Place FROM UserElo WHERE GameMode = ? AND Elo > ? AND Season = ?");
|
||||||
|
private static final Statement fightsOfSeason = new Statement("SELECT COUNT(*) AS Fights FROM FightPlayer INNER JOIN Fight F on FightPlayer.FightID = F.FightID WHERE UserID = ? AND GameMode = ? AND UNIX_TIMESTAMP(StartTime) + Duration >= UNIX_TIMESTAMP(?)");
|
||||||
|
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int season;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final String gameMode;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int userId;
|
||||||
|
@Field
|
||||||
|
private final int elo;
|
||||||
|
|
||||||
|
public static int getEloOrDefault(int userID, String gameMode) {
|
||||||
|
return getElo(userID, gameMode).orElse(ELO_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<Integer> getElo(int userID, String gameMode) {
|
||||||
|
return gameModeUserEloCache.computeIfAbsent(gameMode, gm -> new HashMap<>()).computeIfAbsent(userID, uid -> Optional.ofNullable(getElo.select(Season.getSeason(), gameMode, userID)).map(userElo -> userElo.elo));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getFightsOfSeason(int userID, String gameMode) {
|
||||||
|
return fightsOfSeason.select(rs -> {
|
||||||
|
if (rs.next())
|
||||||
|
return rs.getInt("Fights");
|
||||||
|
return 0;
|
||||||
|
}, userID, gameMode, Season.getSeasonStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setElo(int userId, String gameMode, int elo) {
|
||||||
|
emblemCache.remove(userId);
|
||||||
|
|
||||||
|
int oldPlacement = getPlacement(getElo(userId, gameMode).orElse(0), gameMode);
|
||||||
|
int newPlacement = getPlacement(elo, gameMode);
|
||||||
|
|
||||||
|
gameModeUserEloCache.getOrDefault(gameMode, Collections.emptyMap()).remove(userId);
|
||||||
|
if (oldPlacement <= 3 || newPlacement <= 3) {
|
||||||
|
emblemCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
setElo.update(Season.getSeason(), gameMode, userId, elo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getPlacement(int elo, String gameMode) {
|
||||||
|
return place.select(rs -> {
|
||||||
|
if (rs.next())
|
||||||
|
return rs.getInt("Place") + 1;
|
||||||
|
return -1;
|
||||||
|
}, gameMode, elo, Season.getSeason());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEmblem(SteamwarUser user, List<String> rankedModes) {
|
||||||
|
return emblemCache.computeIfAbsent(user.getId(), userId -> {
|
||||||
|
int emblemProgression = -1;
|
||||||
|
for (String mode : rankedModes) {
|
||||||
|
if (UserElo.getFightsOfSeason(userId, mode) == 0) continue;
|
||||||
|
int progression = getProgression(userId, mode);
|
||||||
|
if (progression > emblemProgression) {
|
||||||
|
emblemProgression = progression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toEmblem(emblemProgression);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getEmblemProgression(String gameMode, int userId) {
|
||||||
|
switch (getProgression(userId, gameMode)) {
|
||||||
|
case -1:
|
||||||
|
return "§f/ §8∨ ∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||||
|
case 0:
|
||||||
|
return "§8/ §6∨ §8∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||||
|
case 1:
|
||||||
|
return "§8/ ∨ §6∧ §8∨ ∧ ∨ ∧ ❂ III II I";
|
||||||
|
case 2:
|
||||||
|
return "§8/ ∨ ∧ §7∨ §8∧ ∨ ∧ ❂ III II I";
|
||||||
|
case 3:
|
||||||
|
return "§8/ ∨ ∧ ∨ §7∧ §8∨ ∧ ❂ III II I";
|
||||||
|
case 4:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ §e∨ §8∧ ❂ III II I";
|
||||||
|
case 5:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ ∨ §e∧ §8❂ III II I";
|
||||||
|
case 6:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ §5❂ §8III II I";
|
||||||
|
case 7:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ §5III §8II I";
|
||||||
|
case 8:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III §5II §8I";
|
||||||
|
case 9:
|
||||||
|
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III II §5I";
|
||||||
|
default:
|
||||||
|
throw new SecurityException("Progression is not in range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getProgression(int userId, String gameMode) {
|
||||||
|
int elo = getElo(userId, gameMode).orElse(-1);
|
||||||
|
if (elo < 0) return -1;
|
||||||
|
|
||||||
|
if (elo <= 100) return 0;
|
||||||
|
if (elo <= 200) return 1;
|
||||||
|
if (elo <= 400) return 2;
|
||||||
|
if (elo <= 600) return 3;
|
||||||
|
if (elo <= 900) return 4;
|
||||||
|
if (elo <= 1200) return 5;
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* 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.SqlTypeMapper;
|
||||||
|
import de.steamwar.sql.internal.Table;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public enum UserPerm {
|
||||||
|
PREFIX_NONE, // special value, not stored in database
|
||||||
|
PREFIX_YOUTUBER,
|
||||||
|
PREFIX_GUIDE,
|
||||||
|
PREFIX_BUILDER,
|
||||||
|
PREFIX_SUPPORTER,
|
||||||
|
PREFIX_MODERATOR,
|
||||||
|
PREFIX_DEVELOPER,
|
||||||
|
PREFIX_ADMIN,
|
||||||
|
|
||||||
|
RESTRICTED_MODS,
|
||||||
|
COLOR_CHAT,
|
||||||
|
TEAM,
|
||||||
|
TICKET_LOG,
|
||||||
|
BUILD,
|
||||||
|
CHECK,
|
||||||
|
MODERATION,
|
||||||
|
ADMINISTRATION;
|
||||||
|
|
||||||
|
public static final Map<UserPerm, Prefix> prefixes;
|
||||||
|
public static final Prefix emptyPrefix;
|
||||||
|
static {
|
||||||
|
SqlTypeMapper.nameEnumMapper(UserPerm.class);
|
||||||
|
Map<UserPerm, Prefix> p = new EnumMap<>(UserPerm.class);
|
||||||
|
emptyPrefix = new Prefix("§7", "");
|
||||||
|
p.put(PREFIX_NONE, emptyPrefix);
|
||||||
|
p.put(PREFIX_YOUTUBER, new Prefix("§7", "YT"));
|
||||||
|
p.put(PREFIX_GUIDE, new Prefix("§a", "Guide"));
|
||||||
|
|
||||||
|
p.put(PREFIX_SUPPORTER, new Prefix("§6", "Sup"));
|
||||||
|
p.put(PREFIX_MODERATOR, new Prefix("§6", "Mod"));
|
||||||
|
p.put(PREFIX_BUILDER, new Prefix("§e", "Arch"));
|
||||||
|
p.put(PREFIX_DEVELOPER, new Prefix("§e", "Dev"));
|
||||||
|
p.put(PREFIX_ADMIN, new Prefix("§e", "Admin"));
|
||||||
|
prefixes = Collections.unmodifiableMap(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Table<UserPermTable> table = new Table<>(UserPermTable.class, "UserPerm");
|
||||||
|
private static final SelectStatement<UserPermTable> getPerms = table.selectFields("user");
|
||||||
|
|
||||||
|
public static Set<UserPerm> getPerms(int user) {
|
||||||
|
return getPerms.listSelect(user).stream().map(up -> up.perm).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class Prefix {
|
||||||
|
private final String colorCode;
|
||||||
|
private final String chatPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class UserPermTable {
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final int user;
|
||||||
|
@Field(keys = {Table.PRIMARY})
|
||||||
|
private final UserPerm perm;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Field {
|
||||||
|
String[] keys() default {};
|
||||||
|
String def() default "";
|
||||||
|
boolean nullable() default false;
|
||||||
|
boolean autoincrement() default false;
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import de.steamwar.ImplementationProvider;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public interface SQLConfig {
|
||||||
|
SQLConfig impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLConfigImpl");
|
||||||
|
|
||||||
|
Logger getLogger();
|
||||||
|
|
||||||
|
int maxConnections();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class SelectStatement<T> extends Statement {
|
||||||
|
private final Table<T> table;
|
||||||
|
|
||||||
|
SelectStatement(Table<T> table, String... kfields) {
|
||||||
|
this(table, "SELECT " + Arrays.stream(table.fields).map(f -> f.identifier).collect(Collectors.joining(", ")) + " FROM " + table.name + " WHERE " + Arrays.stream(kfields).map(f -> f + " = ?").collect(Collectors.joining(" AND ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelectStatement(Table<T> table, String sql) {
|
||||||
|
super(sql);
|
||||||
|
this.table = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T select(Object... values) {
|
||||||
|
return select(rs -> {
|
||||||
|
if (rs.next())
|
||||||
|
return read(rs);
|
||||||
|
return null;
|
||||||
|
}, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> listSelect(Object... values) {
|
||||||
|
return select(rs -> {
|
||||||
|
List<T> result = new ArrayList<>();
|
||||||
|
while (rs.next())
|
||||||
|
result.add(read(rs));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
private T read(ResultSet rs) throws SQLException {
|
||||||
|
Object[] params = new Object[table.fields.length];
|
||||||
|
for(int i = 0; i < params.length; i++) {
|
||||||
|
params[i] = table.fields[i].read(rs);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return table.constructor.newInstance(params);
|
||||||
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new SecurityException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public final class SqlTypeMapper<T> {
|
||||||
|
private static final Map<Class<?>, SqlTypeMapper<?>> mappers = new IdentityHashMap<>();
|
||||||
|
|
||||||
|
public static <T> SqlTypeMapper<T> getMapper(Class<?> 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) {
|
||||||
|
T[] enumConstants = type.getEnumConstants();
|
||||||
|
new SqlTypeMapper<>(
|
||||||
|
type,
|
||||||
|
"INTEGER(" + (int)Math.ceil(enumConstants.length/256.0) + ")",
|
||||||
|
(rs, identifier) -> enumConstants[rs.getInt(identifier)],
|
||||||
|
(st, index, value) -> st.setInt(index, value.ordinal())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Enum<T>> void nameEnumMapper(Class<T> type) {
|
||||||
|
new SqlTypeMapper<>(
|
||||||
|
type,
|
||||||
|
"VARCHAR(" + Arrays.stream(type.getEnumConstants()).map(e -> e.name().length()).max(Integer::compareTo).orElse(0) + ")",
|
||||||
|
(rs, identifier) -> Enum.valueOf(type, rs.getString(identifier)),
|
||||||
|
(st, index, value) -> st.setString(index, value.name())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
primitiveMapper(boolean.class, Boolean.class, "BOOLEAN", ResultSet::getBoolean, PreparedStatement::setBoolean);
|
||||||
|
primitiveMapper(byte.class, Byte.class, "INTEGER(1)", ResultSet::getByte, PreparedStatement::setByte);
|
||||||
|
primitiveMapper(short.class, Short.class, "INTEGER(2)", ResultSet::getShort, PreparedStatement::setShort);
|
||||||
|
primitiveMapper(int.class, Integer.class, "INTEGER", ResultSet::getInt, PreparedStatement::setInt);
|
||||||
|
primitiveMapper(long.class, Long.class, "INTEGER(8)", ResultSet::getLong, PreparedStatement::setLong);
|
||||||
|
primitiveMapper(float.class, Float.class, "REAL", ResultSet::getFloat, PreparedStatement::setFloat);
|
||||||
|
primitiveMapper(double.class, Double.class, "REAL", ResultSet::getDouble, PreparedStatement::setDouble);
|
||||||
|
new SqlTypeMapper<>(String.class, "TEXT", ResultSet::getString, PreparedStatement::setString);
|
||||||
|
new SqlTypeMapper<>(Timestamp.class, "TIMESTAMP", ResultSet::getTimestamp, PreparedStatement::setTimestamp);
|
||||||
|
new SqlTypeMapper<>(InputStream.class, "BLOB", ResultSet::getBinaryStream, PreparedStatement::setBinaryStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> void primitiveMapper(Class<T> primitive, Class<T> wrapped, String sqlType, SQLReader<T> reader, SQLWriter<T> writer) {
|
||||||
|
new SqlTypeMapper<>(primitive, sqlType, reader, writer);
|
||||||
|
new SqlTypeMapper<>(wrapped, sqlType, (rs, identifier) -> {
|
||||||
|
T value = reader.read(rs, identifier);
|
||||||
|
return rs.wasNull() ? null : value;
|
||||||
|
}, writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String sqlType;
|
||||||
|
private final SQLReader<T> reader;
|
||||||
|
private final SQLWriter<T> writer;
|
||||||
|
|
||||||
|
public SqlTypeMapper(Class<T> clazz, String sqlType, SQLReader<T> reader, SQLWriter<T> writer) {
|
||||||
|
this.sqlType = sqlType;
|
||||||
|
this.reader = reader;
|
||||||
|
this.writer = writer;
|
||||||
|
mappers.put(clazz, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T read(ResultSet rs, String identifier) throws SQLException {
|
||||||
|
return reader.read(rs, identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(PreparedStatement st, int index, Object value) throws SQLException {
|
||||||
|
writer.write(st, index, (T) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String sqlType() {
|
||||||
|
return sqlType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface SQLReader<T> {
|
||||||
|
T read(ResultSet rs, String identifier) throws SQLException;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface SQLWriter<T> {
|
||||||
|
void write(PreparedStatement st, int index, T value) throws SQLException;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
public class Statement implements AutoCloseable {
|
||||||
|
|
||||||
|
private static final Logger logger = SQLConfig.impl.getLogger();
|
||||||
|
|
||||||
|
private static final List<Statement> statements = new ArrayList<>();
|
||||||
|
private static final Deque<Connection> connections = new ArrayDeque<>();
|
||||||
|
private static final int MAX_CONNECTIONS;
|
||||||
|
private static final Supplier<Connection> conProvider;
|
||||||
|
static final Consumer<Table<?>> schemaCreator;
|
||||||
|
static final String ON_DUPLICATE_KEY;
|
||||||
|
static final UnaryOperator<String> upsertWrapper;
|
||||||
|
public static final String NULL_SAFE_EQUALS;
|
||||||
|
|
||||||
|
private static final boolean MYSQL_MODE;
|
||||||
|
private static final boolean PRODUCTION_DATABASE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
File file = new File(System.getProperty("user.home"), "mysql.properties");
|
||||||
|
MYSQL_MODE = file.exists();
|
||||||
|
|
||||||
|
if(MYSQL_MODE) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
try {
|
||||||
|
properties.load(new FileReader(file));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new SecurityException("Could not load SQL connection", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
String url = "jdbc:mysql://" + properties.getProperty("host") + ":" + properties.getProperty("port") + "/" + properties.getProperty("database") + "?useServerPrepStmts=true";
|
||||||
|
String user = properties.getProperty("user");
|
||||||
|
String password = properties.getProperty("password");
|
||||||
|
|
||||||
|
PRODUCTION_DATABASE = "core".equals(properties.getProperty("database"));
|
||||||
|
MAX_CONNECTIONS = SQLConfig.impl.maxConnections();
|
||||||
|
conProvider = () -> {
|
||||||
|
try {
|
||||||
|
return DriverManager.getConnection(url, user, password);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new SecurityException("Could not create MySQL connection", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
schemaCreator = table -> {};
|
||||||
|
ON_DUPLICATE_KEY = " ON DUPLICATE KEY UPDATE ";
|
||||||
|
upsertWrapper = f -> f + " = VALUES(" + f + ")";
|
||||||
|
NULL_SAFE_EQUALS = " <=> ";
|
||||||
|
} else {
|
||||||
|
Connection connection;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class.forName("org.sqlite.JDBC");
|
||||||
|
connection = DriverManager.getConnection("jdbc:sqlite:" + System.getProperty("user.home") + "/standalone.db");
|
||||||
|
} catch (SQLException | ClassNotFoundException e) {
|
||||||
|
throw new SecurityException("Could not create sqlite connection", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
PRODUCTION_DATABASE = false;
|
||||||
|
MAX_CONNECTIONS = 1;
|
||||||
|
conProvider = () -> connection;
|
||||||
|
schemaCreator = Table::ensureExistanceInSqlite;
|
||||||
|
ON_DUPLICATE_KEY = " ON CONFLICT DO UPDATE SET ";
|
||||||
|
upsertWrapper = f -> f + " = " + f;
|
||||||
|
NULL_SAFE_EQUALS = " IS ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static volatile int connectionBudget = MAX_CONNECTIONS;
|
||||||
|
|
||||||
|
public static void closeAll() {
|
||||||
|
synchronized (connections) {
|
||||||
|
while(connectionBudget < MAX_CONNECTIONS) {
|
||||||
|
if(connections.isEmpty())
|
||||||
|
waitOnConnections();
|
||||||
|
else
|
||||||
|
closeConnection(aquireConnection());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean mysqlMode() {
|
||||||
|
return MYSQL_MODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean productionDatabase() {
|
||||||
|
return PRODUCTION_DATABASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean returnGeneratedKeys;
|
||||||
|
private final String sql;
|
||||||
|
private final Map<Connection, PreparedStatement> cachedStatements = new HashMap<>();
|
||||||
|
|
||||||
|
public Statement(String sql) {
|
||||||
|
this(sql, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement(String sql, boolean returnGeneratedKeys) {
|
||||||
|
this.sql = sql;
|
||||||
|
this.returnGeneratedKeys = returnGeneratedKeys;
|
||||||
|
synchronized (statements) {
|
||||||
|
statements.add(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T select(ResultSetUser<T> user, Object... objects) {
|
||||||
|
return withConnection(st -> {
|
||||||
|
boolean res = st.execute();
|
||||||
|
if(!res) {
|
||||||
|
throw new SecurityException("No result set for select statement");
|
||||||
|
}
|
||||||
|
ResultSet rs = st.getResultSet();
|
||||||
|
T result = user.use(rs);
|
||||||
|
rs.close();
|
||||||
|
return result;
|
||||||
|
}, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(Object... objects) {
|
||||||
|
withConnection(PreparedStatement::executeUpdate, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int insertGetKey(Object... objects) {
|
||||||
|
return withConnection(st -> {
|
||||||
|
st.executeUpdate();
|
||||||
|
ResultSet rs = st.getGeneratedKeys();
|
||||||
|
rs.next();
|
||||||
|
return rs.getInt(1);
|
||||||
|
}, objects);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSql() {
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T withConnection(SQLRunnable<T> runnable, Object... objects) {
|
||||||
|
Connection connection = aquireConnection();
|
||||||
|
T result;
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = tryWithConnection(connection, runnable, objects);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
if(connectionInvalid(connection)) {
|
||||||
|
closeConnection(connection);
|
||||||
|
|
||||||
|
return withConnection(runnable, objects);
|
||||||
|
} else {
|
||||||
|
synchronized (connections) {
|
||||||
|
connections.push(connection);
|
||||||
|
connections.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SecurityException("Failing sql statement", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (connections) {
|
||||||
|
connections.push(connection);
|
||||||
|
connections.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean connectionInvalid(Connection connection) {
|
||||||
|
try {
|
||||||
|
return connection.isClosed() || !connection.isValid(1);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.log(Level.INFO, "Could not check SQL connection status", e); // No database logging possible at this state
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T tryWithConnection(Connection connection, SQLRunnable<T> runnable, Object... objects) throws SQLException {
|
||||||
|
PreparedStatement st = cachedStatements.get(connection);
|
||||||
|
if(st == null) {
|
||||||
|
if(returnGeneratedKeys)
|
||||||
|
st = connection.prepareStatement(sql, java.sql.Statement.RETURN_GENERATED_KEYS);
|
||||||
|
else
|
||||||
|
st = connection.prepareStatement(sql);
|
||||||
|
cachedStatements.put(connection, st);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < objects.length; i++) {
|
||||||
|
Object o = objects[i];
|
||||||
|
if(o != null)
|
||||||
|
SqlTypeMapper.getMapper(o.getClass()).write(st, i+1, o);
|
||||||
|
else
|
||||||
|
st.setNull(i+1, Types.NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return runnable.run(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
cachedStatements.values().forEach(st -> closeStatement(st, false));
|
||||||
|
cachedStatements.clear();
|
||||||
|
synchronized (statements) {
|
||||||
|
statements.remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close(Connection connection) {
|
||||||
|
PreparedStatement st = cachedStatements.remove(connection);
|
||||||
|
if(st != null)
|
||||||
|
closeStatement(st, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Connection aquireConnection() {
|
||||||
|
synchronized (connections) {
|
||||||
|
while(connections.isEmpty() && connectionBudget <= 0)
|
||||||
|
waitOnConnections();
|
||||||
|
|
||||||
|
if(!connections.isEmpty()) {
|
||||||
|
return connections.pop();
|
||||||
|
} else {
|
||||||
|
Connection connection = conProvider.get();
|
||||||
|
connectionBudget--;
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void closeConnection(Connection connection) {
|
||||||
|
synchronized (statements) {
|
||||||
|
for (Statement statement : statements) {
|
||||||
|
statement.close(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
logger.log(Level.INFO, "Could not close connection", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (connections) {
|
||||||
|
connectionBudget++;
|
||||||
|
connections.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void waitOnConnections() {
|
||||||
|
synchronized (connections) {
|
||||||
|
try {
|
||||||
|
connections.wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void closeStatement(PreparedStatement st, boolean silent) {
|
||||||
|
try {
|
||||||
|
st.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
if(!silent)
|
||||||
|
logger.log(Level.INFO, "Could not close statement", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ResultSetUser<T> {
|
||||||
|
T use(ResultSet rs) throws SQLException;
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface SQLRunnable<T> {
|
||||||
|
T run(PreparedStatement st) throws SQLException;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* 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.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class Table<T> {
|
||||||
|
public static final String PRIMARY = "primary";
|
||||||
|
|
||||||
|
final String name;
|
||||||
|
final TableField<?>[] fields;
|
||||||
|
private final Map<String, TableField<?>> fieldsByIdentifier = new HashMap<>();
|
||||||
|
final Constructor<T> constructor;
|
||||||
|
|
||||||
|
private final Map<String, Table.TableField<?>[]> keys;
|
||||||
|
|
||||||
|
|
||||||
|
public Table(Class<T> clazz) {
|
||||||
|
this(clazz, clazz.getSimpleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Table(Class<T> clazz, String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.fields = Arrays.stream(clazz.getDeclaredFields()).filter(field -> field.isAnnotationPresent(Field.class)).map(TableField::new).toArray(TableField[]::new);
|
||||||
|
try {
|
||||||
|
this.constructor = clazz.getDeclaredConstructor(Arrays.stream(clazz.getDeclaredFields()).filter(field -> field.isAnnotationPresent(Field.class)).map(java.lang.reflect.Field::getType).toArray(Class[]::new));
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new SecurityException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
keys = Arrays.stream(fields).flatMap(field -> Arrays.stream(field.field.keys())).distinct().collect(Collectors.toMap(Function.identity(), key -> Arrays.stream(fields).filter(field -> Arrays.asList(field.field.keys()).contains(key)).toArray(TableField[]::new)));
|
||||||
|
|
||||||
|
for (TableField<?> field : fields) {
|
||||||
|
fieldsByIdentifier.put(field.identifier.toLowerCase(), field);
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement.schemaCreator.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelectStatement<T> select(String name) {
|
||||||
|
return selectFields(keyFields(name));
|
||||||
|
}
|
||||||
|
public SelectStatement<T> selectFields(String... kfields) {
|
||||||
|
return new SelectStatement<>(this, kfields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement update(String name, String... fields) {
|
||||||
|
return updateFields(fields, keyFields(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement updateField(String field, String... kfields) {
|
||||||
|
return updateFields(new String[]{field}, kfields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement updateFields(String[] fields, String... kfields) {
|
||||||
|
return new Statement("UPDATE " + name + " SET " + Arrays.stream(fields).map(f -> f + " = ?").collect(Collectors.joining(", ")) + " WHERE " + Arrays.stream(kfields).map(f -> f + " = ?").collect(Collectors.joining(" AND ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement insert(String name) {
|
||||||
|
return insertFields(keyFields(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement insertAll() {
|
||||||
|
return insertFields(false, Arrays.stream(fields).map(f -> f.identifier).toArray(String[]::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement insertFields(String... fields) {
|
||||||
|
return insertFields(false, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement insertFields(boolean returnGeneratedKeys, String... fields) {
|
||||||
|
List<String> nonKeyFields = Arrays.stream(fields).filter(f -> fieldsByIdentifier.get(f.toLowerCase()).field.keys().length == 0).collect(Collectors.toList());
|
||||||
|
return new Statement("INSERT INTO " + name + " (" + String.join(", ", fields) + ") VALUES (" + Arrays.stream(fields).map(f -> "?").collect(Collectors.joining(", ")) + ")" + (nonKeyFields.isEmpty() ? "" : Statement.ON_DUPLICATE_KEY + nonKeyFields.stream().map(Statement.upsertWrapper).collect(Collectors.joining(", "))), returnGeneratedKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement delete(String name) {
|
||||||
|
return deleteFields(keyFields(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Statement deleteFields(String... kfields) {
|
||||||
|
return new Statement("DELETE FROM " + name + " WHERE " + Arrays.stream(kfields).map(f -> f + " = ?").collect(Collectors.joining(" AND ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensureExistanceInSqlite() {
|
||||||
|
try (Statement statement = new Statement(
|
||||||
|
"CREATE TABLE IF NOT EXISTS " + name + "(" +
|
||||||
|
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())).collect(Collectors.joining(", ")) +
|
||||||
|
keys.entrySet().stream().map(key -> (key.getKey().equals(PRIMARY) ? ", PRIMARY KEY(" : ", UNIQUE (") + Arrays.stream(key.getValue()).map(field -> field.identifier).collect(Collectors.joining(", ")) + ")").collect(Collectors.joining(" ")) +
|
||||||
|
")")) {
|
||||||
|
statement.update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] keyFields(String name) {
|
||||||
|
return Arrays.stream(keys.get(name)).map(f -> f.identifier).toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TableField<T> {
|
||||||
|
|
||||||
|
final String identifier;
|
||||||
|
|
||||||
|
final SqlTypeMapper<T> mapper;
|
||||||
|
private final Field field;
|
||||||
|
|
||||||
|
private TableField(java.lang.reflect.Field field) {
|
||||||
|
this.identifier = field.getName();
|
||||||
|
this.mapper = SqlTypeMapper.getMapper(field.getType());
|
||||||
|
this.field = field.getAnnotation(Field.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
T read(ResultSet rs) throws SQLException {
|
||||||
|
return mapper.read(rs, identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class RandomGenerator {
|
||||||
|
|
||||||
|
private static final Random random = new Random();
|
||||||
|
private static final Map<Class<?>, Function<Class<?>, ?>> generators = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
generators.put(Integer.class, (clazz) -> random.nextInt());
|
||||||
|
generators.put(int.class, (clazz) -> random.nextInt());
|
||||||
|
generators.put(Double.class, (clazz) -> random.nextDouble());
|
||||||
|
generators.put(double.class, (clazz) -> random.nextInt());
|
||||||
|
generators.put(Boolean.class, (clazz) -> random.nextBoolean());
|
||||||
|
generators.put(boolean.class, (clazz) -> random.nextBoolean());
|
||||||
|
generators.put(Byte.class, (clazz) -> (byte) random.nextInt(127));
|
||||||
|
generators.put(byte.class, (clazz) -> (byte) random.nextInt(127));
|
||||||
|
|
||||||
|
generators.put(List.class, aClass -> {
|
||||||
|
int length = random.nextInt(10);
|
||||||
|
List<Object> list = new ArrayList<>();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
list.add(generators.get(Integer.class).apply(Integer.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
|
||||||
|
generators.put(String.class, aClass -> {
|
||||||
|
int length = random.nextInt(10);
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
builder.append(random.nextInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
generators.put(Map.class, aClass -> {
|
||||||
|
int length = random.nextInt(10);
|
||||||
|
Map<Object, Object> map = new HashMap<>();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
map.put(generators.get(Integer.class).apply(Integer.class), generators.get(String.class).apply(String.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T generateRandom(Class<T> clazz) {
|
||||||
|
if(clazz.isEnum()) {
|
||||||
|
return generateRandomEnum(clazz);
|
||||||
|
} else {
|
||||||
|
return (T) generators.get(clazz).apply(clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T generateRandomEnum(Class<T> clazz) {
|
||||||
|
return clazz.getEnumConstants()[random.nextInt(clazz.getEnumConstants().length)];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* 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.network;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import de.steamwar.network.packets.client.ExecuteCommandPacket;
|
||||||
|
import de.steamwar.network.packets.client.ImALobbyPacket;
|
||||||
|
import de.steamwar.network.packets.client.InventoryCallbackPacket;
|
||||||
|
import de.steamwar.network.packets.client.PrepareSchemPacket;
|
||||||
|
import de.steamwar.network.packets.common.FightEndsPacket;
|
||||||
|
import de.steamwar.network.packets.common.FightInfoPacket;
|
||||||
|
import de.steamwar.network.packets.server.*;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static de.steamwar.RandomGenerator.*;
|
||||||
|
|
||||||
|
public class AllPackets {
|
||||||
|
|
||||||
|
public static final Class<? extends NetworkPacket>[] packets = new Class[]{
|
||||||
|
ExecuteCommandPacket.class,
|
||||||
|
ImALobbyPacket.class,
|
||||||
|
InventoryCallbackPacket.class,
|
||||||
|
PrepareSchemPacket.class,
|
||||||
|
FightEndsPacket.class,
|
||||||
|
FightInfoPacket.class,
|
||||||
|
BaumemberUpdatePacket.class,
|
||||||
|
CloseInventoryPacket.class,
|
||||||
|
InventoryPacket.class,
|
||||||
|
PingPacket.class,
|
||||||
|
StartingServerPacket.class
|
||||||
|
};
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public static List<NetworkPacket> getAllPackets() {
|
||||||
|
List<NetworkPacket> packets = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Class<? extends NetworkPacket> packet : AllPackets.packets) {
|
||||||
|
Constructor<? extends NetworkPacket> longConstructor = (Constructor<? extends NetworkPacket>) packet.getConstructors()[0];
|
||||||
|
for (Constructor<?> constructor : packet.getConstructors()) {
|
||||||
|
if (constructor.getParameterCount() > longConstructor.getParameterCount()) {
|
||||||
|
longConstructor = (Constructor<? extends NetworkPacket>) constructor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Object[] args = new Object[longConstructor.getParameterCount()];
|
||||||
|
Parameter[] parameters = longConstructor.getParameters();
|
||||||
|
for (int i = 0; i < parameters.length; i++) {
|
||||||
|
Parameter parameter = parameters[i];
|
||||||
|
parameter.getName();
|
||||||
|
args[i] = generateRandom(parameter.getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkPacket packetInstance = longConstructor.newInstance(args);
|
||||||
|
packets.add(packetInstance);
|
||||||
|
}
|
||||||
|
return packets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.network;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.PacketHandler;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.*;
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
|
||||||
|
public class PacketHandlerTest {
|
||||||
|
|
||||||
|
TestPacketHandler packetHandler;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
packetHandler = new TestPacketHandler();
|
||||||
|
packetHandler.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPacketHandler() {
|
||||||
|
TestPacket packet = new TestPacket();
|
||||||
|
try {
|
||||||
|
PacketHandler.handlePacket(packet);
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertThat(e, instanceOf(InvocationTargetException.class));
|
||||||
|
assertThat(e.getCause(), instanceOf(SecurityException.class));
|
||||||
|
assertThat(e.getCause().getMessage(), equalTo(packet.getClass().getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* 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.network;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.*;
|
||||||
|
import static org.hamcrest.MatcherAssert.*;
|
||||||
|
|
||||||
|
public class PacketTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPacketSerialization() {
|
||||||
|
for (NetworkPacket allPacket : AllPackets.getAllPackets()) {
|
||||||
|
byte[] data = allPacket.serialize();
|
||||||
|
NetworkPacket deserializedPacket = NetworkPacket.deserialize(data);
|
||||||
|
assertThat("Packet: " + allPacket.getClass().getName() + " is not correctly deserialized", allPacket, equalTo(deserializedPacket));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.network;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TestPacket extends NetworkPacket {
|
||||||
|
private static final long serialVersionUID = -9079104421295590626L;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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.network;
|
||||||
|
|
||||||
|
import de.steamwar.network.packets.PacketHandler;
|
||||||
|
|
||||||
|
public class TestPacketHandler extends PacketHandler {
|
||||||
|
|
||||||
|
@Handler
|
||||||
|
public void handle(TestPacket packet) {
|
||||||
|
throw new SecurityException(packet.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user