SteamWar/SpigotCore
Archiviert
13
0

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

Dieser Commit ist enthalten in:
Lixfel 2021-12-02 08:47:54 +01:00
Commit 1c7224a89b
27 geänderte Dateien mit 2035 neuen und 407 gelöschten Zeilen

Datei anzeigen

@ -29,10 +29,9 @@ import com.sk89q.worldedit.world.registry.LegacyMapper;
import de.steamwar.sql.NoClipboardException; import de.steamwar.sql.NoClipboardException;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.io.ByteArrayOutputStream; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.*; import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -43,7 +42,7 @@ public class WorldEditWrapper14 implements WorldEditWrapper.IWorldEditWrapper {
private static final ClipboardFormat SCHEM = BuiltInClipboardFormat.SPONGE_SCHEMATIC; private static final ClipboardFormat SCHEM = BuiltInClipboardFormat.SPONGE_SCHEMATIC;
@Override @Override
public byte[] getPlayerClipboard(Player player, boolean schemFormat) { public InputStream getPlayerClipboard(Player player, boolean schemFormat) {
ClipboardHolder clipboardHolder; ClipboardHolder clipboardHolder;
try { try {
clipboardHolder = WorldEditWrapper.getWorldEditPlugin().getSession(player).getClipboard(); clipboardHolder = WorldEditWrapper.getWorldEditPlugin().getSession(player).getClipboard();
@ -55,21 +54,36 @@ public class WorldEditWrapper14 implements WorldEditWrapper.IWorldEditWrapper {
if(clipboard == null) if(clipboard == null)
throw new NoClipboardException(); throw new NoClipboardException();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PipedOutputStream outputStream = new PipedOutputStream();
try{ PipedInputStream inputStream;
if(schemFormat){ try {
ClipboardWriter writer = SCHEM.getWriter(outputStream); inputStream = new PipedInputStream(outputStream, 4096);
writer.write(clipboard);
writer.close();
}else{
SCHEMATIC.getWriter(outputStream).write(clipboard);
}
}catch(NullPointerException e){ }catch(NullPointerException e){
throw new RuntimeException(e.getMessage(), new IOException(e)); throw new RuntimeException(e.getMessage(), new IOException(e));
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e.getMessage(), e); throw new SecurityException("Could not init piped input stream", e);
} }
return outputStream.toByteArray();
new Thread(() -> {
try{
if(schemFormat){
ClipboardWriter writer = SCHEM.getWriter(outputStream);
writer.write(clipboard);
writer.close();
}else{
SCHEMATIC.getWriter(outputStream).write(clipboard);
}
}catch(NullPointerException | IOException e) {
Core.getInstance().getLogger().log(Level.SEVERE, "Could not write schematic", e);
}
try {
outputStream.close();
} catch (IOException e) {
Core.getInstance().getLogger().log(Level.SEVERE, "Could not close schem writer", e);
}
}, "SchemWriter").start();
return inputStream;
} }
@Override @Override

Datei anzeigen

@ -19,19 +19,18 @@ import com.sk89q.worldedit.world.registry.WorldData;
import de.steamwar.sql.NoClipboardException; import de.steamwar.sql.NoClipboardException;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.io.ByteArrayOutputStream; import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper { public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper {
@Override @Override
public byte[] getPlayerClipboard(Player player, boolean schemFormat) { public InputStream getPlayerClipboard(Player player, boolean schemFormat) {
ClipboardHolder clipboardHolder; ClipboardHolder clipboardHolder;
try { try {
clipboardHolder = WorldEditWrapper.getWorldEditPlugin().getSession(player).getClipboard(); clipboardHolder = WorldEditWrapper.getWorldEditPlugin().getSession(player).getClipboard();
@ -43,13 +42,28 @@ public class WorldEditWrapper8 implements WorldEditWrapper.IWorldEditWrapper {
if(clipboard == null) if(clipboard == null)
throw new NoClipboardException(); throw new NoClipboardException();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PipedOutputStream outputStream = new PipedOutputStream();
PipedInputStream inputStream;
try { try {
ClipboardFormat.SCHEMATIC.getWriter(outputStream).write(clipboard, clipboardHolder.getWorldData()); inputStream = new PipedInputStream(outputStream, 4096);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e.getMessage(), e); throw new SecurityException("Could not init piped input stream", e);
} }
return outputStream.toByteArray();
new Thread(() -> {
try {
ClipboardFormat.SCHEMATIC.getWriter(outputStream).write(clipboard, clipboardHolder.getWorldData());
} catch (IOException e) {
Core.getInstance().getLogger().log(Level.SEVERE, "Could not write schematic", e);
}
try {
outputStream.close();
} catch (IOException e) {
Core.getInstance().getLogger().log(Level.SEVERE, "Could not close schem writer", e);
}
}, "SchemWriter").start();
return inputStream;
} }
@Override @Override

Datei anzeigen

@ -46,6 +46,11 @@ dependencies {
compileOnly files("${project.rootDir}/lib/Spigot-1.15.jar") compileOnly files("${project.rootDir}/lib/Spigot-1.15.jar")
compileOnly files("${project.rootDir}/lib/WorldEdit-1.12.jar") compileOnly files("${project.rootDir}/lib/WorldEdit-1.12.jar")
implementation 'net.wesjd:anvilgui:1.4.0-SNAPSHOT' implementation 'net.wesjd:anvilgui:1.4.0-SNAPSHOT'
compileOnly 'org.projectlombok:lombok:1.18.6'
testCompileOnly 'org.projectlombok:lombok:1.18.6'
annotationProcessor 'org.projectlombok:lombok:1.18.6'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.6'
} }
processResources { processResources {

Datei anzeigen

@ -0,0 +1,55 @@
#
# 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/>.
#
SCHEM_SELECTOR_TITLE={0} auswählen: {1}
SCHEM_SELECTOR_BACK=§eZurück
SCHEM_SELECTOR_DIR=§9Ordner
SCHEM_SELECTOR_RANK=§8Rang {0}
SCHEM_SELECTOR_OWN=§7Eigene Schematics
SCHEM_SELECTOR_PUB=§7Public Schematics
SCHEM_SELECTOR_SEL_DIR=§7Ordner auswählen
SCHEM_SELECTOR_NEW_DIR=§7Neuer Ordner
SCHEM_SELECTOR_FILTER=§7Filter
SCHEM_SELECTOR_ITEM_NAME=§e{0}
SCHEM_SELECTOR_ITEM_NAME_FILTER=§7{0}
SCHEM_SELECTOR_ITEM_REPLACE=§e{0}§7
SCHEM_SELECTOR_ITEM_LORE_TYPE=§7{0}
SCHEM_SELECTOR_CREATE_DIR_TITLE=Ordner erstellen
SCHEM_SELECTOR_FILTER_TITLE=Filter
SCHEM_SELECTOR_FILTER_ENTER_NAME=Name eingeben
SCHEM_SELECTOR_FILTER_NAME=§7Nach Namen suchen...
SCHEM_SELECTOR_FILTER_NAME_SEARCH=§7Suchbegriff: §e{0}
SCHEM_SELECTOR_FILTER_ENTER_OWNER=Besitzer eingeben
SCHEM_SELECTOR_FILTER_OWNER=§7Nach Besitzer suchen...
SCHEM_SELECTOR_FILTER_OWNER_SEARCH=§7Besitzer: §e{0}
SCHEM_SELECTOR_FILTER_SEL_TYPE=Typ wählen...
SCHEM_SELECTOR_FILTER_TYPE=§7Nach Typ filtern...
SCHEM_SELECTOR_FILTER_TYPE_SEARCH=§7Typ: §e{0}
SCHEM_SELECTOR_FILTER_MAT=§7Nach Item filtern...
SCHEM_SELECTOR_FILTER_MAT_SEARCH=§7Item: §e{0}
SCHEM_SELECTOR_CANCEL=§eAbbrechen
SCHEM_SELECTOR_GO=§eSuchen...
SCHEM_SELECTOR_SCHEMATIC=Schematic
SCHEM_SELECTOR_DIRECTORY=Ordner
SCHEM_SELECTOR_SCHEMATIC_NODE=Schematic/Ordner
MATERIAL_SELECTOR_TITLE=Material auswählen

Datei anzeigen

@ -0,0 +1,26 @@
/*
* 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.command;
class CommandNoHelpException extends RuntimeException {
CommandNoHelpException() {
}
}

Datei anzeigen

@ -0,0 +1,26 @@
/*
* 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.command;
public enum GuardCheckType {
COMMAND,
HELP_COMMAND,
TAB_COMPLETE
}

Datei anzeigen

@ -0,0 +1,30 @@
/*
* 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.command;
import org.bukkit.command.CommandSender;
@FunctionalInterface
public interface GuardChecker {
/**
* While guarding the first parameter of the command the parameter s of this method is {@code null}
*/
GuardResult guard(CommandSender commandSender, GuardCheckType guardCheckType, String[] previousArguments, String s);
}

Datei anzeigen

@ -0,0 +1,26 @@
/*
* 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.command;
public enum GuardResult {
ALLOWED,
DENIED_WITH_HELP,
DENIED
}

Datei anzeigen

@ -19,14 +19,19 @@
package de.steamwar.command; package de.steamwar.command;
import de.steamwar.message.Message;
import lombok.Setter;
import net.md_5.bungee.api.chat.ClickEvent;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter; import java.lang.reflect.Parameter;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.IntPredicate; import java.util.function.IntPredicate;
import java.util.logging.Level; import java.util.logging.Level;
@ -39,6 +44,11 @@ public abstract class SWCommand {
private final List<SubCommand> commandList = new ArrayList<>(); private final List<SubCommand> commandList = new ArrayList<>();
private final List<SubCommand> commandHelpList = new ArrayList<>(); private final List<SubCommand> commandHelpList = new ArrayList<>();
private final Map<String, TypeMapper<?>> localTypeMapper = new HashMap<>(); private final Map<String, TypeMapper<?>> localTypeMapper = new HashMap<>();
private final Map<String, GuardChecker> localGuardChecker = new HashMap<>();
@Setter
private Message message = null;
private List<String> defaultHelpMessages = new ArrayList<>();
protected SWCommand(String command) { protected SWCommand(String command) {
this(command, new String[0]); this(command, new String[0]);
@ -51,8 +61,13 @@ public abstract class SWCommand {
if (!initialized) { if (!initialized) {
createMapping(); createMapping();
} }
if (commandList.stream().anyMatch(s -> s.invoke(sender, args))) return false; try {
commandHelpList.stream().anyMatch(s -> s.invoke(sender, args)); if (!commandList.stream().anyMatch(s -> s.invoke(sender, args))) {
commandHelpList.stream().anyMatch(s -> s.invoke(sender, args));
}
} catch (CommandNoHelpException e) {
// Ignored
}
return false; return false;
} }
@ -76,7 +91,7 @@ public abstract class SWCommand {
} }
private synchronized void createMapping() { private synchronized void createMapping() {
Method[] methods = getClass().getDeclaredMethods(); List<Method> methods = methods();
for (Method method : methods) { for (Method method : methods) {
addMapper(Mapper.class, method, i -> i == 0, false, TypeMapper.class, (anno, typeMapper) -> { addMapper(Mapper.class, method, i -> i == 0, false, TypeMapper.class, (anno, typeMapper) -> {
(anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value(), typeMapper); (anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value(), typeMapper);
@ -84,19 +99,26 @@ public abstract class SWCommand {
addMapper(ClassMapper.class, method, i -> i == 0, false, TypeMapper.class, (anno, typeMapper) -> { addMapper(ClassMapper.class, method, i -> i == 0, false, TypeMapper.class, (anno, typeMapper) -> {
(anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value().getTypeName(), typeMapper); (anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value().getTypeName(), typeMapper);
}); });
addGuard(Guard.class, method, i -> i == 0, false, GuardChecker.class, (anno, guardChecker) -> {
(anno.local() ? localGuardChecker : SWCommandUtils.GUARD_FUNCTIONS).putIfAbsent(anno.value(), guardChecker);
});
addGuard(ClassGuard.class, method, i -> i == 0, false, GuardChecker.class, (anno, guardChecker) -> {
(anno.local() ? localGuardChecker : SWCommandUtils.GUARD_FUNCTIONS).putIfAbsent(anno.value().getTypeName(), guardChecker);
});
add(Register.class, method, i -> i > 0, true, null, (anno, parameters) -> { add(Register.class, method, i -> i > 0, true, null, (anno, parameters) -> {
if (!anno.help()) return; if (!anno.help()) return;
if (parameters.length != 2) { if (parameters.length != 2) {
Bukkit.getLogger().log(Level.WARNING, "The method '" + method.toString() + "' is lacking parameters or has too many"); Bukkit.getLogger().log(Level.WARNING, () -> "The method '" + method.toString() + "' is lacking parameters or has too many");
} }
if (!parameters[parameters.length - 1].isVarArgs()) { if (!parameters[parameters.length - 1].isVarArgs()) {
Bukkit.getLogger().log(Level.WARNING, "The method '" + method.toString() + "' is lacking the varArgs parameters as last Argument"); Bukkit.getLogger().log(Level.WARNING, () -> "The method '" + method.toString() + "' is lacking the varArgs parameters as last Argument");
} }
if (parameters[parameters.length - 1].getType().getComponentType() != String.class) { if (parameters[parameters.length - 1].getType().getComponentType() != String.class) {
Bukkit.getLogger().log(Level.WARNING, "The method '" + method.toString() + "' is lacking the varArgs parameters of type '" + String.class.getTypeName() + "' as last Argument"); Bukkit.getLogger().log(Level.WARNING, () -> "The method '" + method.toString() + "' is lacking the varArgs parameters of type '" + String.class.getTypeName() + "' as last Argument");
return; return;
} }
commandHelpList.add(new SubCommand(this, method, anno.value(), new HashMap<>())); commandHelpList.add(new SubCommand(this, method, anno.value(), new HashMap<>(), localGuardChecker, true, null));
}); });
} }
for (Method method : methods) { for (Method method : methods) {
@ -114,11 +136,11 @@ public abstract class SWCommand {
} }
String name = mapper != null ? mapper.value() : clazz.getTypeName(); String name = mapper != null ? mapper.value() : clazz.getTypeName();
if (!SWCommandUtils.MAPPER_FUNCTIONS.containsKey(name) && !localTypeMapper.containsKey(name)) { if (!SWCommandUtils.MAPPER_FUNCTIONS.containsKey(name) && !localTypeMapper.containsKey(name)) {
Bukkit.getLogger().log(Level.WARNING, "The parameter '" + parameter.toString() + "' is using an unsupported Mapper of type '" + name + "'"); Bukkit.getLogger().log(Level.WARNING, () -> "The parameter '" + parameter.toString() + "' is using an unsupported Mapper of type '" + name + "'");
return; return;
} }
} }
commandList.add(new SubCommand(this, method, anno.value(), localTypeMapper)); commandList.add(new SubCommand(this, method, anno.value(), localTypeMapper, localGuardChecker, false, anno.description()));
}); });
this.commandList.sort((o1, o2) -> { this.commandList.sort((o1, o2) -> {
@ -130,7 +152,15 @@ public abstract class SWCommand {
o2.varArgType != null ? Integer.MAX_VALUE : o2.arguments.length); o2.varArgType != null ? Integer.MAX_VALUE : o2.arguments.length);
} }
}); });
commandHelpList.sort(Comparator.comparingInt(o -> -o.subCommand.length)); commandHelpList.sort((o1, o2) -> {
int compare = Integer.compare(-o1.subCommand.length, -o2.subCommand.length);
if (compare != 0) {
return compare;
} else {
return Integer.compare(o1.method.getDeclaringClass() == SWCommand.class ? 1 : 0,
o2.method.getDeclaringClass() == SWCommand.class ? 1 : 0);
}
});
} }
initialized = true; initialized = true;
} }
@ -141,15 +171,15 @@ public abstract class SWCommand {
Parameter[] parameters = method.getParameters(); Parameter[] parameters = method.getParameters();
if (!parameterTester.test(parameters.length)) { if (!parameterTester.test(parameters.length)) {
Bukkit.getLogger().log(Level.WARNING, "The method '" + method.toString() + "' is lacking parameters or has too many"); Bukkit.getLogger().log(Level.WARNING, () -> "The method '" + method.toString() + "' is lacking parameters or has too many");
return; return;
} }
if (firstParameter && !CommandSender.class.isAssignableFrom(parameters[0].getType())) { if (firstParameter && !CommandSender.class.isAssignableFrom(parameters[0].getType())) {
Bukkit.getLogger().log(Level.WARNING, "The method '" + method.toString() + "' is lacking the first parameter of type '" + CommandSender.class.getTypeName() + "'"); Bukkit.getLogger().log(Level.WARNING, () -> "The method '" + method.toString() + "' is lacking the first parameter of type '" + CommandSender.class.getTypeName() + "'");
return; return;
} }
if (returnType != null && method.getReturnType() != returnType) { if (returnType != null && method.getReturnType() != returnType) {
Bukkit.getLogger().log(Level.WARNING, "The method '" + method.toString() + "' is lacking the desired return type '" + returnType.getTypeName() + "'"); Bukkit.getLogger().log(Level.WARNING, () -> "The method '" + method.toString() + "' is lacking the desired return type '" + returnType.getTypeName() + "'");
return; return;
} }
Arrays.stream(anno).forEach(t -> consumer.accept(t, parameters)); Arrays.stream(anno).forEach(t -> consumer.accept(t, parameters));
@ -166,6 +196,27 @@ public abstract class SWCommand {
}); });
} }
private <T extends Annotation> void addGuard(Class<T> annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class<?> returnType, BiConsumer<T, GuardChecker> consumer) {
add(annotation, method, parameterTester, firstParameter, returnType, (anno, parameters) -> {
try {
method.setAccessible(true);
consumer.accept(anno, (GuardChecker) method.invoke(this));
} catch (Exception e) {
throw new SecurityException(e.getMessage(), e);
}
});
}
public void addDefaultHelpMessage(String message) {
defaultHelpMessages.add(message);
}
private List<Method> methods() {
List<Method> methods = new ArrayList<>(Arrays.asList(getClass().getDeclaredMethods()));
methods.addAll(Arrays.asList(SWCommand.class.getDeclaredMethods()));
return methods;
}
public void unregister() { public void unregister() {
SWCommandUtils.knownCommandMap.remove(command.getName()); SWCommandUtils.knownCommandMap.remove(command.getName());
command.getAliases().forEach(SWCommandUtils.knownCommandMap::remove); command.getAliases().forEach(SWCommandUtils.knownCommandMap::remove);
@ -176,6 +227,56 @@ public abstract class SWCommand {
SWCommandUtils.commandMap.register("steamwar", this.command); SWCommandUtils.commandMap.register("steamwar", this.command);
} }
@Register(help = true)
private void internalHelp(Player p, String... args) {
if (message == null) {
return;
}
try {
message.sendPrefixless("COMMAND_HELP_HEAD", p, command.getName());
defaultHelpMessages.forEach(s -> message.sendPrefixless(s, p));
} catch (Exception e) {
Bukkit.getLogger().log(Level.WARNING, "Failed to send help message", e);
return;
}
AtomicInteger atomicInteger = new AtomicInteger();
if (args.length != 0) {
commandList.forEach(subCommand -> {
List<String> tabCompletes = subCommand.tabComplete(p, args);
if (tabCompletes == null || tabCompletes.isEmpty()) {
atomicInteger.incrementAndGet();
return;
}
boolean hasTabCompletes = tabCompletes.stream()
.anyMatch(s -> s.toLowerCase().startsWith(args[args.length - 1].toLowerCase()));
if (hasTabCompletes) {
send(p, subCommand);
} else {
atomicInteger.incrementAndGet();
}
});
}
if (args.length == 0 || atomicInteger.get() == commandList.size()) {
commandList.forEach(subCommand -> {
if (subCommand.guardChecker == null || subCommand.guardChecker.guard(p, GuardCheckType.TAB_COMPLETE, new String[0], null) == GuardResult.ALLOWED) {
send(p, subCommand);
}
});
}
}
private void send(Player p, SubCommand subCommand) {
try {
for (String s : subCommand.description) {
String hover = "§8/§e" + command.getName() + " " + String.join(" ", subCommand.subCommand);
String suggest = "/" + command.getName() + " " + String.join(" ", subCommand.subCommand);
message.sendPrefixless(s, p, hover, new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, suggest));
}
} catch (Exception e) {
Bukkit.getLogger().log(Level.WARNING, "Failed to send description of registered method '" + subCommand.method + "' with description '" + subCommand.description + "'", e);
}
}
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD}) @Target({ElementType.METHOD})
@Repeatable(Register.Registeres.class) @Repeatable(Register.Registeres.class)
@ -184,6 +285,8 @@ public abstract class SWCommand {
boolean help() default false; boolean help() default false;
String[] description() default {};
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD}) @Target({ElementType.METHOD})
@interface Registeres { @interface Registeres {
@ -206,4 +309,20 @@ public abstract class SWCommand {
boolean local() default false; boolean local() default false;
} }
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.METHOD})
protected @interface Guard {
String value() default "";
boolean local() default false;
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
protected @interface ClassGuard {
Class<?> value();
boolean local() default false;
}
} }

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.command; package de.steamwar.command;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -44,6 +45,7 @@ public class SWCommandUtils {
} }
static final Map<String, TypeMapper<?>> MAPPER_FUNCTIONS = new HashMap<>(); static final Map<String, TypeMapper<?>> MAPPER_FUNCTIONS = new HashMap<>();
static final Map<String, GuardChecker> GUARD_FUNCTIONS = new HashMap<>();
static final TypeMapper<?> ERROR_FUNCTION = createMapper(s -> { static final TypeMapper<?> ERROR_FUNCTION = createMapper(s -> {
throw new SecurityException(); throw new SecurityException();
@ -71,6 +73,17 @@ public class SWCommandUtils {
return null; return null;
}, s -> Arrays.asList("s", "survival", "0", "c", "creative", "1", "sp", "spectator", "3", "a", "adventure", "2"))); }, s -> Arrays.asList("s", "survival", "0", "c", "creative", "1", "sp", "spectator", "3", "a", "adventure", "2")));
MAPPER_FUNCTIONS.put(SteamwarUser.class.getTypeName(), createMapper(SteamwarUser::get, s -> Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()))); MAPPER_FUNCTIONS.put(SteamwarUser.class.getTypeName(), createMapper(SteamwarUser::get, s -> Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList())));
MAPPER_FUNCTIONS.put(SchematicNode.class.getTypeName(), new TypeMapper<SchematicNode>() {
@Override
public List<String> tabCompletes(CommandSender commandSender, String[] strings, String s) {
return SchematicNode.getNodeTabcomplete(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
}
@Override
public SchematicNode map(CommandSender commandSender, String[] previousArguments, String s) {
return SchematicNode.getNodeFromPath(SteamwarUser.get(((Player) commandSender).getUniqueId()), s);
}
});
} }
private static void addMapper(Class<?> clazz, Class<?> alternativeClazz, TypeMapper<?> mapper) { private static void addMapper(Class<?> clazz, Class<?> alternativeClazz, TypeMapper<?> mapper) {
@ -100,7 +113,7 @@ public class SWCommandUtils {
} }
} }
static Object[] generateArgumentArray(CommandSender commandSender, TypeMapper<?>[] parameters, String[] args, Class<?> varArgType, String[] subCommand) throws CommandParseException { static Object[] generateArgumentArray(CommandSender commandSender, TypeMapper<?>[] parameters, GuardChecker[] guards, String[] args, Class<?> varArgType, String[] subCommand) throws CommandParseException {
Object[] arguments = new Object[parameters.length + 1]; Object[] arguments = new Object[parameters.length + 1];
int index = 0; int index = 0;
while (index < subCommand.length) { while (index < subCommand.length) {
@ -142,6 +155,14 @@ public class SWCommandUtils {
MAPPER_FUNCTIONS.putIfAbsent(name, mapper); MAPPER_FUNCTIONS.putIfAbsent(name, mapper);
} }
public static void addGuard(Class<?> clazz, GuardChecker guardChecker) {
addGuard(clazz.getTypeName(), guardChecker);
}
public static void addGuard(String name, GuardChecker guardChecker) {
GUARD_FUNCTIONS.putIfAbsent(name, guardChecker);
}
public static <T> TypeMapper<T> createMapper(Function<String, T> mapper, Function<String, List<String>> tabCompleter) { public static <T> TypeMapper<T> createMapper(Function<String, T> mapper, Function<String, List<String>> tabCompleter) {
return createMapper(mapper, (commandSender, s) -> tabCompleter.apply(s)); return createMapper(mapper, (commandSender, s) -> tabCompleter.apply(s));
} }

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.command; package de.steamwar.command;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -27,29 +28,38 @@ import java.lang.reflect.Parameter;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.logging.Level;
import static de.steamwar.command.SWCommandUtils.*; import static de.steamwar.command.SWCommandUtils.*;
class SubCommand { class SubCommand {
private SWCommand swCommand; private SWCommand swCommand;
private Method method; Method method;
String[] description;
String[] subCommand; String[] subCommand;
TypeMapper<?>[] arguments; TypeMapper<?>[] arguments;
GuardChecker[] guards;
private Predicate<CommandSender> commandSenderPredicate; private Predicate<CommandSender> commandSenderPredicate;
private Function<CommandSender, ?> commandSenderFunction; private Function<CommandSender, ?> commandSenderFunction;
GuardChecker guardChecker;
Class<?> varArgType = null; Class<?> varArgType = null;
private boolean help;
SubCommand(SWCommand swCommand, Method method, String[] subCommand, Map<String, TypeMapper<?>> localTypeMapper) { SubCommand(SWCommand swCommand, Method method, String[] subCommand, Map<String, TypeMapper<?>> localTypeMapper, Map<String, GuardChecker> localGuardChecker, boolean help, String[] description) {
this.swCommand = swCommand; this.swCommand = swCommand;
this.method = method; this.method = method;
this.help = help;
this.description = description;
Parameter[] parameters = method.getParameters(); Parameter[] parameters = method.getParameters();
commandSenderPredicate = sender -> parameters[0].getType().isAssignableFrom(sender.getClass()); commandSenderPredicate = sender -> parameters[0].getType().isAssignableFrom(sender.getClass());
commandSenderFunction = sender -> parameters[0].getType().cast(sender); commandSenderFunction = sender -> parameters[0].getType().cast(sender);
this.subCommand = subCommand; this.subCommand = subCommand;
guardChecker = getGuardChecker(parameters[0], localGuardChecker);
arguments = new TypeMapper[parameters.length - 1]; arguments = new TypeMapper[parameters.length - 1];
guards = new GuardChecker[parameters.length - 1];
for (int i = 1; i < parameters.length; i++) { for (int i = 1; i < parameters.length; i++) {
Parameter parameter = parameters[i]; Parameter parameter = parameters[i];
Class<?> clazz = parameter.getType(); Class<?> clazz = parameter.getType();
@ -76,9 +86,29 @@ class SubCommand {
arguments[i - 1] = localTypeMapper.containsKey(name) arguments[i - 1] = localTypeMapper.containsKey(name)
? localTypeMapper.get(name) ? localTypeMapper.get(name)
: MAPPER_FUNCTIONS.getOrDefault(name, ERROR_FUNCTION); : MAPPER_FUNCTIONS.getOrDefault(name, ERROR_FUNCTION);
guards[i - 1] = getGuardChecker(parameter, localGuardChecker);
} }
} }
private GuardChecker getGuardChecker(Parameter parameter, Map<String, GuardChecker> localGuardChecker) {
SWCommand.Guard guard = parameter.getAnnotation(SWCommand.Guard.class);
if (guard != null) {
if (guard.value() == null || guard.value().isEmpty()) {
String s = parameter.getType().getTypeName();
if (parameter.isVarArgs()) {
s = parameter.getType().getComponentType().getTypeName();
}
return localGuardChecker.getOrDefault(s, GUARD_FUNCTIONS.getOrDefault(s, null));
}
GuardChecker current = localGuardChecker.getOrDefault(guard.value(), GUARD_FUNCTIONS.getOrDefault(guard.value(), null));
if (current == null) {
Bukkit.getLogger().log(Level.WARNING, () -> "The guard checker with name '" + guard.value() + "' is neither a local guard checker nor a global one");
}
return current;
}
return null;
}
boolean invoke(CommandSender commandSender, String[] args) { boolean invoke(CommandSender commandSender, String[] args) {
if (args.length < arguments.length + subCommand.length - (varArgType != null ? 1 : 0)) { if (args.length < arguments.length + subCommand.length - (varArgType != null ? 1 : 0)) {
return false; return false;
@ -90,10 +120,38 @@ class SubCommand {
if (!commandSenderPredicate.test(commandSender)) { if (!commandSenderPredicate.test(commandSender)) {
return false; return false;
} }
Object[] objects = SWCommandUtils.generateArgumentArray(commandSender, arguments, args, varArgType, subCommand); Object[] objects = SWCommandUtils.generateArgumentArray(commandSender, arguments, guards, args, varArgType, subCommand);
objects[0] = commandSenderFunction.apply(commandSender); objects[0] = commandSenderFunction.apply(commandSender);
for (int i = subCommand.length; i < args.length; i++) {
GuardChecker current;
if (i == subCommand.length) {
current = guardChecker;
} else {
if (i >= objects.length + subCommand.length) {
current = guards[guards.length - 1];
} else {
current = guards[i - 1 - subCommand.length];
}
}
if (current != null) {
GuardResult guardResult;
if (i == 0) {
guardResult = current.guard(commandSender, help ? GuardCheckType.HELP_COMMAND : GuardCheckType.COMMAND, new String[0], null);
} else {
guardResult = current.guard(commandSender, help ? GuardCheckType.HELP_COMMAND : GuardCheckType.COMMAND, Arrays.copyOf(args, i - 1), args[i - 1]);
}
if (guardResult != GuardResult.ALLOWED) {
if (guardResult == GuardResult.DENIED) {
throw new CommandNoHelpException();
}
return false;
}
}
}
method.setAccessible(true); method.setAccessible(true);
method.invoke(swCommand, objects); method.invoke(swCommand, objects);
} catch (CommandNoHelpException e) {
throw e;
} catch (IllegalAccessException | RuntimeException | InvocationTargetException e) { } catch (IllegalAccessException | RuntimeException | InvocationTargetException e) {
throw new SecurityException(e.getMessage(), e); throw new SecurityException(e.getMessage(), e);
} catch (CommandParseException e) { } catch (CommandParseException e) {
@ -106,6 +164,9 @@ class SubCommand {
if (varArgType == null && args.length > arguments.length + subCommand.length) { if (varArgType == null && args.length > arguments.length + subCommand.length) {
return null; return null;
} }
if (guardChecker != null && guardChecker.guard(commandSender, GuardCheckType.TAB_COMPLETE, new String[0], null) != GuardResult.ALLOWED) {
return null;
}
int index = 0; int index = 0;
List<String> argsList = new LinkedList<>(Arrays.asList(args)); List<String> argsList = new LinkedList<>(Arrays.asList(args));
for (String value : subCommand) { for (String value : subCommand) {
@ -114,12 +175,19 @@ class SubCommand {
if (!value.equalsIgnoreCase(s)) return null; if (!value.equalsIgnoreCase(s)) return null;
index++; index++;
} }
int guardIndex = 0;
for (TypeMapper<?> argument : arguments) { for (TypeMapper<?> argument : arguments) {
String s = argsList.remove(0); String s = argsList.remove(0);
if (argsList.isEmpty()) { if (argsList.isEmpty()) {
if (guards[guardIndex] != null && guards[guardIndex].guard(commandSender, GuardCheckType.TAB_COMPLETE, Arrays.copyOf(args, args.length - 1), s) != GuardResult.ALLOWED) {
return null;
}
return argument.tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s); return argument.tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s);
} }
try { try {
if (guards[guardIndex] != null && guards[guardIndex].guard(commandSender, GuardCheckType.TAB_COMPLETE, Arrays.copyOf(args, index), s) != GuardResult.ALLOWED) {
return null;
}
if (argument.map(commandSender, Arrays.copyOf(args, index), s) == null) { if (argument.map(commandSender, Arrays.copyOf(args, index), s) == null) {
return null; return null;
} }
@ -127,14 +195,21 @@ class SubCommand {
return null; return null;
} }
index++; index++;
guardIndex++;
} }
if (varArgType != null && !argsList.isEmpty()) { if (varArgType != null && !argsList.isEmpty()) {
while (!argsList.isEmpty()) { while (!argsList.isEmpty()) {
String s = argsList.remove(0); String s = argsList.remove(0);
if (argsList.isEmpty()) { if (argsList.isEmpty()) {
if (guards[guards.length - 1] != null && guards[guards.length - 1].guard(commandSender, GuardCheckType.TAB_COMPLETE, Arrays.copyOf(args, args.length - 1), s) != GuardResult.ALLOWED) {
return null;
}
return arguments[arguments.length - 1].tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s); return arguments[arguments.length - 1].tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s);
} }
try { try {
if (guards[guards.length - 1] != null && guards[guards.length - 1].guard(commandSender, GuardCheckType.TAB_COMPLETE, Arrays.copyOf(args, index), s) != GuardResult.ALLOWED) {
return null;
}
if (arguments[arguments.length - 1].map(commandSender, Arrays.copyOf(args, index), s) == null) { if (arguments[arguments.length - 1].map(commandSender, Arrays.copyOf(args, index), s) == null) {
return null; return null;
} }

Datei anzeigen

@ -22,21 +22,29 @@ package de.steamwar.comms.packets;
import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteArrayDataOutput;
import de.steamwar.comms.PacketIdManager; import de.steamwar.comms.PacketIdManager;
import de.steamwar.sql.Schematic; import de.steamwar.sql.Schematic;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType; import de.steamwar.sql.SchematicType;
import de.steamwar.sql.SteamwarUser; import de.steamwar.sql.SteamwarUser;
public class PrepareSchemPacket extends SpigotPacket{ public class PrepareSchemPacket extends SpigotPacket{
private final SteamwarUser user; private final SteamwarUser user;
private final Schematic schematic; private final SchematicNode schematic;
private final SchematicType schematicType; private final SchematicType schematicType;
public PrepareSchemPacket(SteamwarUser user, Schematic schematic, SchematicType schematicType){ public PrepareSchemPacket(SteamwarUser user, SchematicNode schematic, SchematicType schematicType) {
this.user = user; this.user = user;
this.schematic = schematic; this.schematic = schematic;
this.schematicType = schematicType; this.schematicType = schematicType;
} }
@Deprecated
public PrepareSchemPacket(SteamwarUser user, Schematic schematic, SchematicType schematicType) {
this.user = user;
this.schematic = schematic.getNode();
this.schematicType = schematicType;
}
@Override @Override
public int getName() { public int getName() {
return PacketIdManager.PREPARE_SCHEM; return PacketIdManager.PREPARE_SCHEM;
@ -45,7 +53,7 @@ public class PrepareSchemPacket extends SpigotPacket{
@Override @Override
public void writeVars(ByteArrayDataOutput byteArrayDataOutput) { public void writeVars(ByteArrayDataOutput byteArrayDataOutput) {
byteArrayDataOutput.writeInt(user.getId()); byteArrayDataOutput.writeInt(user.getId());
byteArrayDataOutput.writeInt(schematic.getSchemID()); byteArrayDataOutput.writeInt(schematic.getId());
byteArrayDataOutput.writeUTF(schematicType.toDB()); byteArrayDataOutput.writeUTF(schematicType.toDB());
} }
} }

Datei anzeigen

@ -25,6 +25,7 @@ import de.steamwar.core.events.ChattingEvent;
import de.steamwar.core.events.ChunkListener; import de.steamwar.core.events.ChunkListener;
import de.steamwar.core.events.PlayerJoinedEvent; import de.steamwar.core.events.PlayerJoinedEvent;
import de.steamwar.core.events.WorldLoadEvent; import de.steamwar.core.events.WorldLoadEvent;
import de.steamwar.message.Message;
import de.steamwar.sql.SQL; import de.steamwar.sql.SQL;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -39,6 +40,7 @@ public class Core extends JavaPlugin{
private static Core instance; private static Core instance;
private static final int version; private static final int version;
public static Message MESSAGE;
static{ static{
String packageName = Bukkit.getServer().getClass().getPackage().getName(); String packageName = Bukkit.getServer().getClass().getPackage().getName();
@ -79,6 +81,8 @@ public class Core extends JavaPlugin{
} catch (IOException e) { } catch (IOException e) {
throw new SecurityException("Could not load Hostname", e); throw new SecurityException("Could not load Hostname", e);
} }
MESSAGE = new Message("SpigotCore", getClassLoader());
} }
@Override @Override

Datei anzeigen

@ -14,7 +14,7 @@ public class WorldEditWrapper {
public static final IWorldEditWrapper impl = VersionDependent.getVersionImpl(Core.getInstance()); public static final IWorldEditWrapper impl = VersionDependent.getVersionImpl(Core.getInstance());
public interface IWorldEditWrapper { public interface IWorldEditWrapper {
byte[] getPlayerClipboard(Player player, boolean schemFormat); InputStream getPlayerClipboard(Player player, boolean schemFormat);
void setPlayerClipboard(Player player, InputStream is, boolean schemFormat); void setPlayerClipboard(Player player, InputStream is, boolean schemFormat);
Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException; Clipboard getClipboard(InputStream is, boolean schemFormat) throws IOException;

Datei anzeigen

@ -20,6 +20,7 @@
package de.steamwar.inventory; package de.steamwar.inventory;
import de.steamwar.sql.Schematic; import de.steamwar.sql.Schematic;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType; import de.steamwar.sql.SchematicType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
@ -27,6 +28,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
public class SWListInv<T> extends SWInventory { public class SWListInv<T> extends SWInventory {
@ -115,26 +117,32 @@ public class SWListInv<T> extends SWInventory {
return onlinePlayers; return onlinePlayers;
} }
public static List<SWListEntry<Schematic>> getSchemList(SchematicType type, int steamwarUserId){ public static List<SWListEntry<SchematicNode>> getSchemnodeList(SchematicType type, int steamwarUserId){
List<SWListEntry<Schematic>> schemList = new ArrayList<>(); List<SWListEntry<SchematicNode>> schemList = new ArrayList<>();
List<Schematic> schems; List<SchematicNode> schems;
if(type == null) if(type == null)
schems = Schematic.getSchemsAccessibleByUser(steamwarUserId); schems = SchematicNode.getAllSchematicsAccessibleByUser(steamwarUserId);
else else
schems = Schematic.getSchemsOfType(steamwarUserId, type); schems = SchematicNode.getAllAccessibleSchematicsOfType(steamwarUserId, type.toDB());
for(Schematic s : schems){ for(SchematicNode s : schems){
Material m; Material m;
if(s.getItem().isEmpty()) if(s.getItem().isEmpty())
m = SWItem.getMaterial("CAULDRON_ITEM"); m = SWItem.getMaterial("CAULDRON_ITEM");
else else
m = SWItem.getMaterial(s.getItem()); m = SWItem.getMaterial(s.getItem());
SWItem item = new SWItem(m,"§e" + s.getSchemName()); SWItem item = new SWItem(m,"§e" + s.getName());
item.setEnchanted(s.isDir());
schemList.add(new SWListEntry<>(item, s)); schemList.add(new SWListEntry<>(item, s));
} }
return schemList; return schemList;
} }
@Deprecated
public static List<SWListEntry<Schematic>> getSchemList(SchematicType type, int steamwarUserId){
return getSchemnodeList(type, steamwarUserId).stream().map(schematicNodeSWListEntry -> new SWListEntry<Schematic>(schematicNodeSWListEntry.getItem(), Schematic.wrap(schematicNodeSWListEntry.getObject()))).collect(Collectors.toList());
}
private boolean sizeBiggerMax(){ private boolean sizeBiggerMax(){
return dynamicSize ? elements.size() > 54 : elements.size() > 45; return dynamicSize ? elements.size() > 54 : elements.size() > 45;

Datei anzeigen

@ -0,0 +1,429 @@
/*
* 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.inventory;
import de.steamwar.core.Core;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType;
import de.steamwar.sql.SteamwarUser;
import lombok.*;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
public class SchematicSelector {
@Getter
private final Player player;
@Getter
private SteamwarUser user;
@Getter
private final Consumer<SchematicNode> callback;
private final SelectorTarget target;
@Getter
private final SelectorFilter filter = new SelectorFilter();
private SchematicSelectorInjectable injectable = SchematicSelectorInjectable.DEFAULT;
@Setter
@Getter
private PublicMode publicMode = PublicMode.ALL;
@Setter
@Getter
private boolean singleDirOpen;
private boolean sdoTrigger = false;
public SchematicSelector(Player player, SelectorTarget target, Consumer<SchematicNode> callback) {
this.player = player;
this.user = SteamwarUser.get(player.getUniqueId());
this.target = target;
this.callback = callback;
this.singleDirOpen = !target.target.dirs;
}
public SchematicSelector(Player player, SelectorTarget target, SchematicSelectorInjectable injectable, Consumer<SchematicNode> callback) {
this(player, target, callback);
this.injectable = injectable;
}
public void open() {
injectable.onSelectorCreate(this);
if(publicMode == PublicMode.PUBLIC_ONLY) {
this.user = SteamwarUser.get(0);
}
openList(null);
}
private void openList(SchematicNode parent) {
List<SchematicNode> nodes = filter.isFilter()?getFilteredSchematics():getSchematicList(parent);
if(sdoTrigger) {
sdoTrigger = false;
return;
}
List<SWListInv.SWListEntry<SchematicNode>> list = new ArrayList<>();
if(parent != null) {
list.add(new SWListInv.SWListEntry<>(new SWItem(Material.ARROW, Core.MESSAGE.parse("SCHEM_SELECTOR_BACK", player), clickType -> {}), null));
}
for (SchematicNode node : nodes) {
if(node.getName().equals("//copy")) continue;
list.add(renderItem(node));
}
SWListInv<SchematicNode> inv = new SWListInv<>(player, MessageFormat.format(injectable.createTitle(player), target.target.getName(player), filter.getName() == null?(parent == null?"/":parent.generateBreadcrumbs(user)):filter.getName()), false, list, (clickType, node) -> handleClick(node, parent));
if(publicMode == PublicMode.ALL) {
if(user.getId() == 0) {
inv.setItem(48, Material.BUCKET, Core.MESSAGE.parse("SCHEM_SELECTOR_OWN", player), clickType -> {
this.user = SteamwarUser.get(player.getUniqueId());
openList(null);
});
} else {
inv.setItem(48, Material.GLASS, Core.MESSAGE.parse("SCHEM_SELECTOR_PUB", player), clickType -> {
this.user = SteamwarUser.get(0);
openList(null);
});
}
}
if(target.target.dirs) {
inv.setItem(49, SWItem.getDye(10), Core.MESSAGE.parse("SCHEM_SELECTOR_SEL_DIR", player), clickType -> {
player.closeInventory();
callback.accept(parent);
});
}
if(user.getId() != 0) {
inv.setItem(50, Material.CHEST, Core.MESSAGE.parse("SCHEM_SELECTOR_NEW_DIR", player), clickType -> createFolderIn(parent));
}
inv.setItem(51, Material.NAME_TAG, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER", player), clickType -> openFilter());
injectable.onListRender(this, inv, parent);
inv.open();
}
private void handleClick(SchematicNode node, SchematicNode parent) {
if(node == null) {
openList(getParent(parent));
return;
}
if(node.isDir()) {
if(filter.isFilter() && target.target.dirs) {
player.closeInventory();
callback.accept(node);
return;
}
filter.reset();
openList(node);
return;
}
player.closeInventory();
callback.accept(node);
}
private SWListInv.SWListEntry<SchematicNode> renderItem(SchematicNode node) {
Material m = SWItem.getMaterial(node.getItem());
String name = Core.MESSAGE.parse(filter.name == null?"SCHEM_SELECTOR_ITEM_NAME":"SCHEM_SELECTOR_ITEM_NAME_FILTER", player, node.getName());
if(filter.getName() != null) {
name = name.replace(filter.getName(), Core.MESSAGE.parse("SCHEM_SELECTOR_ITEM_REPLACE", player, filter.getName()));
}
SWItem item = new SWItem(m, name, Collections.singletonList(node.isDir() ? (Core.MESSAGE.parse("SCHEM_SELECTOR_DIR", player)) : Core.MESSAGE.parse("SCHEM_SELECTOR_ITEM_LORE_TYPE", player, node.getSchemtype().name())), !node.isDir() && !node.getSchemtype().writeable(), click -> {
});
if(!node.isDir() && node.getRank() > 0) {
item.setLore(Arrays.asList(Core.MESSAGE.parse("SCHEM_SELECTOR_ITEM_LORE_TYPE", player, node.getSchemtype().name()), Core.MESSAGE.parse("SCHEM_SELECTOR_RANK", player)));
}
return new SWListInv.SWListEntry<>(item, node);
}
private void createFolderIn(SchematicNode parent) {
SWAnvilInv inv = new SWAnvilInv(player, Core.MESSAGE.parse("SCHEM_SELECTOR_CREATE_DIR_TITLE", player));
inv.setItem(Material.CHEST);
inv.setCallback(s -> {
if(injectable.onFolderCreate(this, s)) {
SchematicNode.createSchematicDirectory(user.getId(), s, parent==null?0:parent.getId());
openList(parent);
}
});
inv.open();
}
private void openFilter() {
SWInventory inv = new SWInventory(player, 9, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_TITLE", player));
InvCallback nameCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setName(null);
openFilter();
} else {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_ENTER_NAME", player));
swAnvilInv.setItem(Material.NAME_TAG);
swAnvilInv.setCallback(s -> {
filter.setName(s);
openFilter();
});
swAnvilInv.open();
}
};
if(filter.getName() == null) {
inv.setItem(0, Material.NAME_TAG, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_NAME", player), nameCallback);
} else {
inv.setItem(0, Material.NAME_TAG, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_NAME", player), Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_NAME_SEARCH", player, filter.getName())), true, nameCallback);
}
InvCallback ownerCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setOwner(null);
openFilter();
} else {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_ENTER_OWNER", player));
swAnvilInv.setItem(Material.PLAYER_HEAD);
swAnvilInv.setCallback(s -> {
filter.setOwner(SteamwarUser.get(s).getId());
openFilter();
});
swAnvilInv.open();
}
};
if(filter.getOwner() == null) {
inv.setItem(1, Material.PLAYER_HEAD, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_OWNER", player), ownerCallback);
} else {
SteamwarUser tUser = SteamwarUser.get(filter.getOwner());
SWItem item = SWItem.getPlayerSkull(user.getUserName());
item.setName(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_OWNER", player));
item.setEnchanted(true);
item.setLore(Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_OWNER_SEARCH", player, tUser.getUserName())));
item.setCallback(ownerCallback);
inv.setItem(1, item);
}
if(target.target != Target.SCHEMATIC_TYPE) {
InvCallback schemTypeCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setType(null);
openFilter();
} else {
List<SWListInv.SWListEntry<SchematicType>> types = new ArrayList<>();
SchematicType.values().forEach(schematicType -> {
types.add(new SWListInv.SWListEntry<>(new SWItem(SWItem.getMaterial("STONE_BUTTON"), "§e" + schematicType.name(), Collections.emptyList(), schematicType.fightType(), n -> {}), schematicType));
});
SWListInv<SchematicType> listInv = new SWListInv<>(player, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_SEL_TYPE", player), types, (clickType1, schematicType) -> {
filter.setType(schematicType);
openFilter();
});
listInv.open();
}
};
if(filter.getType() == null) {
inv.setItem(2, SWItem.getMaterial("STONE_BUTTON"), Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_TYPE", player), schemTypeCallback);
} else {
inv.setItem(2, SWItem.getMaterial("STONE_BUTTON"), Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_TYPE", player), Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_TYPE_SEARCH", player, filter.getType().name())), true, schemTypeCallback);
}
}
InvCallback materialCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setItem(null);
openFilter();
} else {
UtilGui.openMaterialSelector(player, material -> {
filter.setItem(material);
openFilter();
});
}
};
final int iSlot = target.target == Target.SCHEMATIC_TYPE?2:3;
if(filter.getItem() == null) {
inv.setItem(iSlot, Material.STONE, Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_MAT", player), materialCallback);
} else {
inv.setItem(iSlot, filter.getItem(), Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_MAT", player), Collections.singletonList(Core.MESSAGE.parse("SCHEM_SELECTOR_FILTER_MAT_SEARCH", player, filter.getItem().name())), true, materialCallback);
}
inv.setItem(7, SWItem.getDye(1), Core.MESSAGE.parse("SCHEM_SELECTOR_CANCEL", player), clickType -> {
filter.reset();
openList(null);
});
inv.setItem(8, SWItem.getDye(10), Core.MESSAGE.parse("SCHEM_SELECTOR_GO", player), clickType -> {
filter.setFilter(true);
injectable.onFilterApply(this);
openList(null);
});
injectable.onFilterRender(this, inv);
inv.open();
}
private List<SchematicNode> getFilteredSchematics() {
List<SchematicNode> nodes = new ArrayList<>(SchematicNode.getAllSchematicsAccessibleByUser(user.getId()));
nodes.removeIf(node -> {
injectable.onNodeFilter(this, node);
return !filter.matches(node);
});
if(target.target == Target.DIRECTORY) {
nodes.removeIf(node -> !node.isDir());
}
if(target.target == Target.SCHEMATIC_TYPE) {
nodes.removeIf(node -> node.isDir() || !node.getType().equals(target.type.toDB()));
}
return nodes;
}
private List<SchematicNode> getSchematicList(SchematicNode parent) {
List<SchematicNode> nodes = new ArrayList<>();
switch (target.target) {
case DIRECTORY:
if(parent == null) {
nodes.addAll(SchematicNode.getSchematicsAccessibleByUser(user.getId(), null));
nodes.removeIf(node -> !node.isDir());
} else {
nodes.addAll(SchematicNode.getSchematicDirectoryInNode(parent.getId()));
}
break;
case SCHEMATIC_TYPE:
nodes.addAll(SchematicNode.getAccessibleSchematicsOfTypeInParent(user.getId(), target.type.toDB(), parent==null?0:parent.getId()));
if(target.rank >= 0) {
nodes.removeIf(node -> node.getRank() > target.rank);
}
break;
default:
nodes.addAll(SchematicNode.getSchematicsAccessibleByUser(user.getId(), parent == null?0:parent.getId()));
}
if(singleDirOpen && nodes.size() == 1 && nodes.get(0).isDir()) {
openList(nodes.get(0));
sdoTrigger = true;
}
return nodes;
}
private static SchematicNode getParent(SchematicNode node) {
if(node.getParent() == null) {
return null;
}
return node.getParentNode();
}
public static SelectorTarget selectSchematic() {
return new SelectorTarget(Target.SCHEMATIC, null, -1);
}
public static SelectorTarget selectDirectory() {
return new SelectorTarget(Target.DIRECTORY, null, -1);
}
public static SelectorTarget selectSchematicNode() {
return new SelectorTarget(Target.SCHEMATIC_NODE, null, -1);
}
public static SelectorTarget selectSchematicType(SchematicType type) {
return new SelectorTarget(Target.SCHEMATIC_TYPE, type, -1);
}
public static SelectorTarget selectSchematicTypeWithRank(SchematicType type, int rank) {
return new SelectorTarget(Target.SCHEMATIC_TYPE, type, rank);
}
@AllArgsConstructor
static class SelectorTarget {
private final Target target;
private final SchematicType type;
private final int rank;
}
@AllArgsConstructor
private enum Target {
SCHEMATIC("SCHEM_SELECTOR_SCHEMATIC", false),
DIRECTORY("SCHEM_SELECTOR_DIRECTORY", true),
SCHEMATIC_NODE("SCHEM_SELECTOR_SCHEMATIC_NODE", true),
SCHEMATIC_TYPE("SCHEM_SELECTOR_SCHEMATIC", false);
private String rawName;
private boolean dirs;
private String getName(Player player) {
return Core.MESSAGE.parse(rawName, player);
}
}
@NoArgsConstructor
@Getter
@Setter
public static class SelectorFilter {
private boolean filter;
private String name = null;
private Integer owner = null;
private SchematicType type = null;
private Material item = null;
public void reset() {
name = null;
owner = null;
type = null;
item = null;
filter = false;
}
public boolean matches(SchematicNode node) {
boolean matches = true;
if(name != null && !node.getName().contains(name)) {
matches = false;
}
if(owner != null && node.getOwner() != owner) {
matches = false;
}
if(type != null && (node.isDir() || !node.getSchemtype().equals(type))) {
matches = false;
}
if(item != null) {
String i;
if(node.getItem().isEmpty()) {
i = node.isDir()?"CHEST":"CAULDRON";
} else {
i = node.getItem();
}
if(!item.name().equals(i)) {
matches = false;
}
}
return matches;
}
}
public enum PublicMode {
ALL,
PRIVATE_ONLY,
PUBLIC_ONLY
}
}

Datei anzeigen

@ -0,0 +1,45 @@
/*
* 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.inventory;
import de.steamwar.core.Core;
import de.steamwar.sql.SchematicNode;
import org.bukkit.entity.Player;
public interface SchematicSelectorInjectable {
SchematicSelectorInjectable DEFAULT = new SchematicSelectorInjectable() {};
default String createTitle(Player player) {
return Core.MESSAGE.parse("SCHEM_SELECTOR_TITLE", player);
}
default void onSelectorCreate(SchematicSelector selector) {}
default void onListRender(SchematicSelector selector, SWListInv<SchematicNode> inv, SchematicNode parent) {}
default void onFilterRender(SchematicSelector selector, SWInventory inventory) {}
default void onFilterApply(SchematicSelector selector) {}
default boolean onFolderCreate(SchematicSelector selector, String name) {return true;}
default void onNodeFilter(SchematicSelector selector, SchematicNode node) {}
}

Datei anzeigen

@ -0,0 +1,54 @@
/*
* 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.inventory;
import de.steamwar.core.Core;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
@UtilityClass
public class UtilGui {
public static void openMaterialSelector(Player player, Consumer<Material> callback) {
openMaterialSelector(player, Core.MESSAGE.parse("MATERIAL_SELECTOR_TITLE", player), callback);
}
public static void openMaterialSelector(Player player, String title, Consumer<Material> callback) {
List<SWListInv.SWListEntry<Material>> materials = new LinkedList<>();
for(Material material : Material.values()){
if(material.name().startsWith(Material.LEGACY_PREFIX))
continue;
SWItem item = new SWItem(material, "§7" + material.name());
if(item.getItemMeta() != null && material.isItem()) {
materials.add(new SWListInv.SWListEntry<>(item, material));
}
}
SWListInv<Material> swListInv = new SWListInv<>(player, title, materials, (clickType3, material) -> callback.accept(material));
swListInv.open();
}
}

Datei anzeigen

@ -1,6 +1,6 @@
/* /*
This file is a part of the SteamWar software. This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@ -24,72 +24,86 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
public class CheckedSchematic { public class CheckedSchematic {
private static final SQL.Statement checkHistory = new SQL.Statement("SELECT * FROM CheckedSchematic WHERE SchemOwner = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC"); private static final SQL.Statement checkHistory = new SQL.Statement("SELECT * FROM CheckedSchematic WHERE NodeId IN (SELECT NodeId FROM SchematicNode WHERE NodeOwner = ?) AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' AND NodeId is not NULL ORDER BY EndTime DESC");
private static final SQL.Statement nodeHistory = new SQL.Statement("SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != '' AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
private static final SQL.Statement insert = new SQL.Statement("INSERT INTO CheckedSchematic (NodeId, NodeName, NodeOwner, Validator, StartTime, EndTime, DeclineReason) VALUES (?, ?, ?, ?, ?, ?, ?)");
private static final SQL.Statement setNodeNull = new SQL.Statement("UPDATE CheckedSchematic SET NodeId = NULL WHERE NodeId = ?");
private final String schemName; private final Integer node;
private final int schemOwner;
private final int validator; private final int validator;
private final Timestamp startTime; private final Timestamp startTime;
private final Timestamp endTime; private final Timestamp endTime;
private final String declineReason; private final String declineReason;
private CheckedSchematic(String schemName, int schemOwner, int validator, Timestamp startTime, Timestamp endTime, String declineReason, boolean insertDB){ private CheckedSchematic(int node, int validator, Timestamp startTime, Timestamp endTime, String declineReason, boolean insertDB){
this.schemName = schemName; this.node = node;
this.schemOwner = schemOwner;
this.validator = validator; this.validator = validator;
this.startTime = startTime; this.startTime = startTime;
this.endTime = endTime; this.endTime = endTime;
this.declineReason = declineReason; this.declineReason = declineReason;
if(insertDB) if(insertDB) {
insertDB(); insertDB();
}
} }
@Deprecated @Deprecated
public CheckedSchematic(String schemName, int schemOwner, int validator, Timestamp startTime, Timestamp endTime, String declineReason){ public CheckedSchematic(String schemName, int schemOwner, int validator, Timestamp startTime, Timestamp endTime, String declineReason){
this(schemName, schemOwner, validator, startTime, endTime, declineReason, true); this(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), validator, startTime, endTime, declineReason, true);
} }
@Deprecated @Deprecated
public CheckedSchematic(String schemName, UUID schemOwner, UUID validator, Timestamp startTime, Timestamp endTime, String declineReason){ public CheckedSchematic(String schemName, UUID schemOwner, UUID validator, Timestamp startTime, Timestamp endTime, String declineReason){
this(schemName, SteamwarUser.get(schemOwner).getId(), SteamwarUser.get(validator).getId(), startTime, endTime, declineReason, true); this(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), SteamwarUser.get(validator).getId(), startTime, endTime, declineReason, true);
} }
@Deprecated public CheckedSchematic(int node, int validator, Timestamp startTime, Timestamp endTime, String declineReason){
private void insertDB(){ this(node, validator, startTime, endTime, declineReason, true);
SQL.update("INSERT INTO CheckedSchematic" +
" (SchemName, SchemOwner, Validator, StartTime, EndTime, DeclineReason) VALUES (?, ?, ?, ?, ?, ?)",
schemName, schemOwner, validator, startTime, endTime, declineReason);
} }
public static List<CheckedSchematic> getLastDeclined(UUID schemOwner){ public CheckedSchematic(int node, UUID validator, Timestamp startTime, Timestamp endTime, String declineReason){
return getLastDelined(SteamwarUser.get(schemOwner).getId()); this(node, SteamwarUser.get(validator).getId(), startTime, endTime, declineReason, true);
}
private void insertDB() {
SchematicNode sNode = SchematicNode.getSchematicNode(node);
String nodeName = sNode.getName();
int nodeOwner = sNode.getOwner();
insert.update(node, nodeName, nodeOwner, validator, startTime, endTime, declineReason);
}
public static List<CheckedSchematic> getLastDeclinedOfNode(SchematicNode node){
return getLastDeclinedOfNode(node.getId());
}
public static List<CheckedSchematic> getLastDeclinedOfNode(int node){
return nodeHistory.select(rs -> {
List<CheckedSchematic> lastDeclined = new ArrayList<>();
while(rs.next()){
int validator = rs.getInt("Validator");
Timestamp startTime = rs.getTimestamp("StartTime");
Timestamp endTime = rs.getTimestamp("EndTime");
String declineReason = rs.getString("DeclineReason");
lastDeclined.add(new CheckedSchematic(node, validator, startTime, endTime, declineReason, false));
}
return lastDeclined;
}, node);
}
public static List<CheckedSchematic> getLastDeclined(UUID uuid){
return getLastDelined(SteamwarUser.get(uuid).getId());
} }
public static List<CheckedSchematic> getLastDelined(int schemOwner){ public static List<CheckedSchematic> getLastDelined(int schemOwner){
return checkHistory.select(rs -> { return checkHistory.select(rs -> {
List<CheckedSchematic> history = new ArrayList<>(); List<CheckedSchematic> history = new ArrayList<>();
while(rs.next()) while(rs.next())
history.add(new CheckedSchematic(rs.getString("SchemName"), schemOwner, rs.getInt("Validator"), rs.getTimestamp("StartTime"), rs.getTimestamp("EndTime"), rs.getString("DeclineReason"), false)); history.add(new CheckedSchematic(rs.getInt("NodeId"), rs.getInt("Validator"), rs.getTimestamp("StartTime"), rs.getTimestamp("EndTime"), rs.getString("DeclineReason"), false));
return history; return history;
}, schemOwner); }, schemOwner);
} }
@Deprecated
public void remove() {
SQL.update("DELETE FROM CheckedSchematic WHERE SchemOwner = ? AND SchemName = ?", schemOwner, schemName);
}
public String getSchemName() {
return schemName;
}
public int getSchemOwner() {
return schemOwner;
}
public int getValidator() { public int getValidator() {
return validator; return validator;
} }
@ -105,4 +119,20 @@ public class CheckedSchematic {
public String getDeclineReason() { public String getDeclineReason() {
return declineReason; return declineReason;
} }
public int getNode() {
return node;
}
public String getSchemName() {
return SchematicNode.getSchematicNode(node).getName();
}
public int getSchemOwner() {
return SchematicNode.getSchematicNode(node).getId();
}
public void remove() {
setNodeNull.update(node);
}
} }

Datei anzeigen

@ -19,30 +19,11 @@
package de.steamwar.sql; package de.steamwar.sql;
import com.google.common.io.BaseEncoding;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
public class DownloadSchematic { public class DownloadSchematic {
private DownloadSchematic(){} private DownloadSchematic(){}
private static final SQL.Statement createLink = new SQL.Statement("INSERT INTO SchemDownload (SchemID, Link) VALUES (?, ?) ON DUPLICATE KEY UPDATE Link = VALUES(Link)"); @Deprecated
private static final String BASE = "https://steamwar.de/download.php?schem=";
public static String getLink(Schematic schem){ public static String getLink(Schematic schem){
MessageDigest digest; return NodeDownload.getLink(schem.getNode());
try {
digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
throw new SecurityException(e);
}
digest.reset();
digest.update((Instant.now().toString() + schem.getSchemOwner() + schem.getSchemID()).getBytes());
String hash = BaseEncoding.base16().encode(digest.digest());
createLink.update(schem.getSchemID(), hash);
return BASE + hash;
} }
} }

Datei anzeigen

@ -0,0 +1,49 @@
/*
* 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 com.google.common.io.BaseEncoding;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
public class NodeDownload {
private static final SQL.Statement createLink = new SQL.Statement("INSERT INTO NodeDownload (NodeId, Link) VALUES (?, ?) ON DUPLICATE KEY UPDATE Link = VALUES(Link)");
private static final String BASE = "https://steamwar.de/download.php?schem=";
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 = BaseEncoding.base16().encode(digest.digest());
createLink.update(schem.getId(), hash);
return BASE + hash;
}
}

Datei anzeigen

@ -0,0 +1,85 @@
/*
* 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.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;
public class NodeMember {
private static final SQL.Statement getNodeMember = new SQL.Statement("SELECT * FROM NodeMember WHERE NodeId = ? AND UserId = ?");
private static final SQL.Statement getNodeMembers = new SQL.Statement("SELECT * FROM NodeMember WHERE NodeId = ?");
private static final SQL.Statement getSchematics = new SQL.Statement("SELECT * FROM NodeMember WHERE UserId = ?");
private static final SQL.Statement createNodeMember = new SQL.Statement("INSERT INTO NodeMember (NodeId, UserId) VALUES (?, ?)");
private static final SQL.Statement deleteNodeMember = new SQL.Statement("DELETE FROM NodeMember WHERE NodeId = ? AND UserId = ?");
public static NodeMember getNodeMember(int node, int member) {
return getNodeMember.select(rs -> {
if(!rs.next())
return null;
return new NodeMember(rs);
}, node, member);
}
public static Set<NodeMember> getNodeMembers(int node) {
return getNodeMembers.select(rs -> {
Set<NodeMember> members = new HashSet<>();
while (rs.next())
members.add(new NodeMember(rs));
return members;
}, node);
}
public static Set<NodeMember> getSchematics(int member) {
return getSchematics.select(rs -> {
Set<NodeMember> members = new HashSet<>();
while (rs.next())
members.add(new NodeMember(rs));
return members;
}, member);
}
public static NodeMember createNodeMember(int node, int member) {
createNodeMember.update(node, member);
return getNodeMember(node, member);
}
final int node;
final int member;
private NodeMember(ResultSet set) throws SQLException {
node = set.getInt("NodeId");
member = set.getInt("UserId");
}
public int getNode() {
return node;
}
public int getMember() {
return member;
}
public void delete() {
deleteNodeMember.update(node, member);
}
}

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.sql; package de.steamwar.sql;
import com.mysql.jdbc.exceptions.jdbc4.CommunicationsException;
import de.steamwar.core.Core; import de.steamwar.core.Core;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
@ -33,27 +34,27 @@ public class SQL {
private SQL(){} private SQL(){}
private static Connection con; private static Connection con;
private static String url; private static final String URL;
private static String user; private static final String USER;
private static String password; private static final String PASSWORD;
static{ static {
File file = new File(Core.getInstance().getDataFolder(), "MySQL.yml"); File file = new File(Core.getInstance().getDataFolder(), "MySQL.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(file); YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
if(!file.exists()) if(!file.exists())
throw new SecurityException("SQL-ConfigFile not found!"); throw new SecurityException("SQL-ConfigFile not found!");
url = "jdbc:mysql://" + config.getString("HOST") + ":" + config.getString("PORT") + "/" + config.getString("DATABASE"); URL = "jdbc:mysql://" + config.getString("HOST") + ":" + config.getString("PORT") + "/" + config.getString("DATABASE");
user = config.getString("USER"); USER = config.getString("USER");
password = config.getString("PASSWORD"); PASSWORD = config.getString("PASSWORD");
connect(); connect();
} }
private static void connect() { private static void connect() {
try { try {
con = DriverManager.getConnection(url + "?autoReconnect=true&useServerPrepStmts=true", user, password); con = DriverManager.getConnection(URL + "?useServerPrepStmts=true", USER, PASSWORD);
} catch (SQLException e) { } catch (SQLException e) {
throw new SecurityException("Could not start SQL connection", e); throw new SecurityException("Could not start SQL connection", e);
} }
@ -95,7 +96,8 @@ public class SQL {
return false; return false;
} }
} }
@Deprecated
static void update(String qry, Object... objects) { static void update(String qry, Object... objects) {
try { try {
prepare(qry, objects).executeUpdate(); prepare(qry, objects).executeUpdate();
@ -105,7 +107,8 @@ public class SQL {
} }
} }
static ResultSet select(String qry, Object... objects){ @Deprecated
static ResultSet select(String qry, Object... objects) {
try { try {
return prepare(qry, objects).executeQuery(); return prepare(qry, objects).executeQuery();
} catch (SQLException e) { } catch (SQLException e) {
@ -114,7 +117,8 @@ public class SQL {
} }
} }
static Blob blob(){ @Deprecated
static Blob blob() {
try { try {
return con.createBlob(); return con.createBlob();
} catch (SQLException e) { } catch (SQLException e) {
@ -123,7 +127,8 @@ public class SQL {
} }
} }
private static PreparedStatement prepare(String qry, Object... objects) throws SQLException{ @Deprecated
private static PreparedStatement prepare(String qry, Object... objects) throws SQLException {
PreparedStatement st = con.prepareStatement(qry); PreparedStatement st = con.prepareStatement(qry);
for(int i = 0; i < objects.length; i++){ for(int i = 0; i < objects.length; i++){
st.setObject(i+1, objects[i]); st.setObject(i+1, objects[i]);
@ -166,10 +171,15 @@ public class SQL {
private synchronized <T> T prepare(SQLRunnable<T> runnable, Object... objects) { private synchronized <T> T prepare(SQLRunnable<T> runnable, Object... objects) {
try { try {
setObjects(objects); try {
return runnable.run(); setObjects(objects);
return runnable.run();
} catch (CommunicationsException e) {
reset();
setObjects(objects);
return runnable.run();
}
} catch (SQLException e) { } catch (SQLException e) {
reset();
throw new SecurityException("Could not execute SQL statement", e); throw new SecurityException("Could not execute SQL statement", e);
} }
} }

Datei anzeigen

@ -1,6 +1,6 @@
/* /*
This file is a part of the SteamWar software. This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@ -26,232 +26,179 @@ import org.bukkit.entity.Player;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.sql.Blob;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.zip.GZIPInputStream; import java.util.stream.Collectors;
@Deprecated
public class Schematic { public class Schematic {
private static final SQL.Statement getSchemsOfType = new SQL.Statement("SELECT DISTINCT s.SchemID, s.SchemName, s.SchemOwner, s.Item, s.SchemType, s.Rank, s.SchemFormat FROM Schematic s LEFT JOIN SchemMember sm ON sm.SchemName = s.SchemName AND sm.SchemOwner = s.SchemOwner WHERE s.SchemType = ? AND (s.SchemOwner = ? OR sm.Member = ?) ORDER BY s.SchemName"); private static final SQL.Statement getSchemsOfType = new SQL.Statement("SELECT DISTINCT s.SchemID, s.SchemName, s.SchemOwner, s.Item, s.SchemType, s.Rank, s.SchemFormat FROM Schematic s LEFT JOIN SchemMember sm ON sm.SchemName = s.SchemName AND sm.SchemOwner = s.SchemOwner WHERE s.SchemType = ? AND (s.SchemOwner = ? OR sm.Member = ?) ORDER BY s.SchemName");
private final int schemID; private final SchematicNode node;
private final String schemName;
private final int schemOwner;
private boolean schemFormat;
private String item;
private int rank;
private SchematicType schemType;
private Schematic(ResultSet rs) throws SQLException { private Schematic(SchematicNode node) {
this.schemID = rs.getInt("SchemID"); this.node = node;
this.schemName = rs.getString("SchemName"); }
this.schemOwner = rs.getInt("SchemOwner");
this.item = rs.getString("Item");
this.rank = rs.getInt("Rank");
this.schemType = SchematicType.fromDB(rs.getString("SchemType"));
this.schemFormat = rs.getBoolean("SchemFormat");
}
private void updateDB(){ public static Schematic wrap(SchematicNode node) {
createSchem(schemName, schemOwner, item, schemType); return new Schematic(node);
} }
public static void createSchem(String schemName, UUID schemOwner, String item, SchematicType schemType){ public static void createSchem(String schemName, UUID schemOwner, String item, SchematicType schemType){
createSchem(schemName, SteamwarUser.get(schemOwner).getId(), item, schemType); createSchem(schemName, SteamwarUser.get(schemOwner).getId(), item, schemType);
} }
public static void createSchem(String schemName, int schemOwner, String item, SchematicType schemType){ public static void createSchem(String schemName, int schemOwner, String item, SchematicType schemType){
SQL.update("INSERT INTO Schematic (SchemName, SchemOwner, Item, SchemType) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE Item = VALUES(Item), SchemType = VALUES(SchemType)", SchematicNode.createSchematicNode(schemOwner, schemName, null, schemType.toDB(), item);
schemName, schemOwner, item, schemType.toDB()); }
}
public static Schematic getSchemFromDB(String schemName, UUID schemOwner){ public static Schematic getSchemFromDB(String schemName, UUID schemOwner){
return getSchemFromDB(schemName, SteamwarUser.get(schemOwner).getId()); return getSchemFromDB(schemName, SteamwarUser.get(schemOwner).getId());
} }
public static Schematic getSchemFromDB(String schemName, int schemOwner){ public static Schematic getSchemFromDB(String schemName, int schemOwner){
ResultSet schematic = SQL.select("SELECT SchemID, SchemName, SchemOwner, Item, SchemType, Rank, SchemFormat FROM Schematic WHERE SchemName = ? AND SchemOwner = ?", schemName, schemOwner); SchematicNode node = SchematicNode.getSchematicNode(schemOwner, schemName, 0);
try { if(node != null) {
if(schematic == null || !schematic.next()){ return new Schematic(node);
SchematicMember member = SchematicMember.getMemberBySchematic(schemName, schemOwner); } else {
if(member == null){ Optional<SchematicNode> n = SchematicNode.getSchematicsAccessibleByUser(schemOwner, 0).stream().filter(node1 -> node1.getName().equals(schemName)).findAny();
return null; if(n.isPresent()) {
} return new Schematic(n.get());
return getSchemFromDB(schemName, member.getSchemOwner()); }
} }
return new Schematic(schematic); return null;
} catch (SQLException e) { }
throw new SecurityException("Failed loading schematic", e);
}
}
public static Schematic getSchemFromDB(int schemID){ public static Schematic getSchemFromDB(int schemID){
ResultSet schematic = SQL.select("SELECT SchemID, SchemName, SchemOwner, Item, SchemType, Rank, SchemFormat FROM Schematic WHERE SchemID = ?", schemID); SchematicNode node = SchematicNode.getSchematicNode(schemID);
try { if(node != null) {
if(!schematic.next()) return new Schematic(node);
throw new SecurityException("Failed loading schematic " + schemID); } else {
return new Schematic(schematic); throw new SecurityException("Failed to load Schematics");
} catch (SQLException e) { }
throw new SecurityException("Failed loading schematic", e); }
}
}
public static List<Schematic> getSchemsAccessibleByUser(UUID schemOwner){ public static List<Schematic> getSchemsAccessibleByUser(UUID schemOwner){
return getSchemsAccessibleByUser(SteamwarUser.get(schemOwner).getId()); return getSchemsAccessibleByUser(SteamwarUser.get(schemOwner).getId());
} }
public static List<Schematic> getSchemsAccessibleByUser(int schemOwner){ public static List<Schematic> getSchemsAccessibleByUser(int schemOwner){
try{ List<Schematic> schematics = new ArrayList<>();
ResultSet schematic = SQL.select("SELECT DISTINCT s.SchemID, s.SchemName, s.SchemOwner, s.Item, s.SchemType, s.Rank, s.SchemFormat FROM Schematic s LEFT JOIN SchemMember sm ON sm.SchemName = s.SchemName AND sm.SchemOwner = s.SchemOwner WHERE s.SchemOwner = ? OR sm.Member = ? ORDER BY s.SchemName", schemOwner, schemOwner); SchematicNode.getSchematicsAccessibleByUser(schemOwner, null)
List<Schematic> schematics = new ArrayList<>(); .forEach(node1 -> {
while(schematic.next()) if (!node1.isDir()) schematics.add(new Schematic(node1));
schematics.add(new Schematic(schematic)); });
return schematics; return schematics;
}catch(SQLException e){ }
throw new SecurityException("Failed listing schematics", e);
}
}
public static List<Schematic> getSchemsOfType(UUID schemOwner, SchematicType schemType){ public static List<Schematic> getSchemsOfType(UUID schemOwner, SchematicType schemType){
return getSchemsOfType(SteamwarUser.get(schemOwner).getId(), schemType); return getSchemsOfType(SteamwarUser.get(schemOwner).getId(), schemType);
} }
public static List<Schematic> getSchemsOfType(int schemOwner, SchematicType schemType){ public static List<Schematic> getSchemsOfType(int schemOwner, SchematicType schemType){
return getSchemsOfType.select(rs -> { List<Schematic> schematics = new ArrayList<>();
List<Schematic> schematics = new ArrayList<>(); SchematicNode.getAllAccessibleSchematicsOfType(schemOwner, schemType.toDB())
while(rs.next()) .forEach(node1 -> {
schematics.add(new Schematic(rs)); if (!node1.isDir()) schematics.add(new Schematic(node1));
return schematics; });
}, schemType.toDB(), schemOwner, schemOwner); return schematics;
} }
public static List<Schematic> getAllSchemsOfType(SchematicType schemType){ public static List<Schematic> getAllSchemsOfType(SchematicType schemType){
try{ List<Schematic> schematics = new ArrayList<>();
ResultSet schematic = SQL.select("SELECT SchemID, SchemName, SchemOwner, Item, SchemType, Rank, SchemFormat FROM Schematic WHERE SchemType = ?", schemType.toDB()); SchematicNode.getAllSchematicsOfType(schemType.toDB())
List<Schematic> schematics = new ArrayList<>(); .forEach(node1 -> schematics.add(new Schematic(node1)));
while(schematic.next()){ return schematics;
schematics.add(new Schematic(schematic)); }
}
return schematics;
}catch(SQLException e){
throw new SecurityException("Failed loading all schems of type", e);
}
}
public int getSchemID() { public int getSchemID() {
return schemID; return node.getId();
} }
public String getSchemName() { public String getSchemName() {
return schemName; return node.getName();
} }
public int getSchemOwner() { public int getSchemOwner() {
return schemOwner; return node.getOwner();
} }
public int getRank(){ public int getRank(){
return rank; return node.getRank();
} }
public String getItem() { public String getItem() {
return item; return node.getItem();
} }
public void setItem(String item) { public void setItem(String item) {
this.item = item; node.setItem(item);
updateDB(); }
}
public void setRank(int rank){ public void setRank(int rank){
this.rank = rank; node.setRank(rank);
SQL.update("UPDATE Schematic SET Rank = ? WHERE SchemID = ?", rank, schemID); }
}
public SchematicType getSchemType() { public SchematicType getSchemType() {
return schemType; return node.getSchemtype();
} }
public void setSchemType(SchematicType schemType) { public void setSchemType(SchematicType schemType) {
this.schemType = schemType; node.setType(schemType.toDB());
updateDB(); }
}
public boolean availible(){ public boolean availible(){
return true; return true;
} }
public InputStream schemData() throws IOException { public InputStream schemData() throws IOException {
ResultSet rs = SQL.select("SELECT SchemData FROM Schematic WHERE SchemID = ?", schemID); return node.schemData();
try { }
rs.next();
Blob schemData = rs.getBlob("SchemData");
if(schemData == null)
throw new IOException("SchemData is null");
return new GZIPInputStream(schemData.getBinaryStream());
} catch (SQLException e) {
throw new IOException(e);
}
}
public static Clipboard clipboardFromStream(InputStream is, boolean schemFormat) { public static Clipboard clipboardFromStream(InputStream is, boolean schemFormat) {
try { try {
return WorldEditWrapper.impl.getClipboard(is, schemFormat); return WorldEditWrapper.impl.getClipboard(is, schemFormat);
} catch (IOException e) { } catch (IOException e) {
throw new SecurityException("Could not read schem", e); throw new SecurityException("Could not read schem", e);
} }
} }
public Clipboard load() throws IOException, NoClipboardException { public Clipboard load() throws IOException, NoClipboardException {
return clipboardFromStream(schemData(), schemFormat); return clipboardFromStream(schemData(), node.getSchemFormat());
} }
public void loadToPlayer(Player player) throws IOException, NoClipboardException { public void loadToPlayer(Player player) throws IOException, NoClipboardException {
InputStream is = schemData(); InputStream is = schemData();
WorldEditWrapper.impl.setPlayerClipboard(player, is, schemFormat); WorldEditWrapper.impl.setPlayerClipboard(player, is, node.getSchemFormat());
} }
public void saveOldFormatFromPlayer(Player player) throws IOException, NoClipboardException { public void saveOldFormatFromPlayer(Player player) throws IOException, NoClipboardException {
saveFromPlayer(player, false); saveFromPlayer(player, false);
} }
public void saveFromPlayer(Player player) throws IOException, NoClipboardException { public void saveFromPlayer(Player player) throws IOException, NoClipboardException {
saveFromPlayer(player, Core.getVersion() > 12); saveFromPlayer(player, Core.getVersion() > 12);
} }
public void saveFromBytes(byte[] bytes, boolean newFormat) { public void saveFromBytes(byte[] bytes, boolean newFormat) {
Blob blob = SQL.blob(); node.saveFromBytes(bytes, newFormat);
try { }
blob.setBytes(1, bytes);
updateDatabase(blob, newFormat);
} catch (SQLException e) {
throw new SecurityException(e);
}
}
private void saveFromPlayer(Player player, boolean newFormat) throws IOException, NoClipboardException { private void saveFromPlayer(Player player, boolean newFormat) throws IOException, NoClipboardException {
Blob blob = SQL.blob(); node.saveFromPlayer(player, newFormat);
try { }
blob.setBytes(1, WorldEditWrapper.impl.getPlayerClipboard(player, newFormat));
} catch (SQLException e) {
throw new SecurityException(e.getMessage(), e);
}
updateDatabase(blob, newFormat);
}
private void updateDatabase(Blob blob, boolean newFormat) { public void remove(){
SQL.update("UPDATE Schematic SET SchemData = ?, SchemFormat = ? WHERE SchemID = ?", blob, newFormat, schemID); node.delete();
schemFormat = newFormat; }
}
public void remove(){ public SchematicNode getNode() {
SQL.update("DELETE FROM SchemMember WHERE SchemOwner = ? AND SchemName = ?", schemOwner, schemName); return node;
SQL.update("DELETE FROM Schematic WHERE SchemOwner = ? AND SchemName = ?", schemOwner, schemName); }
}
public static class WrongVersionException extends Exception{} @Deprecated
public static class WrongVersionException extends Exception{}
} }

Datei anzeigen

@ -1,134 +1,96 @@
/* /*
This file is a part of the SteamWar software. This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details. GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.steamwar.sql; package de.steamwar.sql;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
@Deprecated
public class SchematicMember { public class SchematicMember {
private final int schemOwner;
private final String schemName;
private final int member;
private SchematicMember(String schemName, int schemOwner, int schemMember, boolean updateDB){ private final NodeMember member;
this.schemOwner = schemOwner;
member = schemMember;
this.schemName = schemName;
if(updateDB)
updateDB();
}
public SchematicMember(String schemName, int schemOwner, int schemMember){ private SchematicMember(NodeMember member){
this(schemName, schemOwner, schemMember, true); this.member = member;
} }
public SchematicMember(String schemName, UUID schemOwner, UUID schemMember){ public SchematicMember(String schemName, int schemOwner, int schemMember){
this(schemName, SteamwarUser.get(schemOwner).getId(), SteamwarUser.get(schemMember).getId(), true); this(NodeMember.createNodeMember(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), schemMember));
} }
private void updateDB(){ public SchematicMember(String schemName, UUID schemOwner, UUID schemMember){
SQL.update("INSERT INTO SchemMember (SchemName, SchemOwner, Member) VALUES (?, ?, ?)", schemName, schemOwner, member); this(NodeMember.createNodeMember(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), SteamwarUser.get(schemMember).getId()));
} }
public static SchematicMember getSchemMemberFromDB(String schemName, UUID schemOwner, UUID schemMember){ public static SchematicMember getSchemMemberFromDB(String schemName, UUID schemOwner, UUID schemMember){
return getSchemMemberFromDB(schemName, SteamwarUser.get(schemOwner).getId(), SteamwarUser.get(schemMember).getId()); return getSchemMemberFromDB(schemName, SteamwarUser.get(schemOwner).getId(), SteamwarUser.get(schemMember).getId());
} }
public static SchematicMember getSchemMemberFromDB(String schemName, int schemOwner, int schemMember){ public static SchematicMember getSchemMemberFromDB(String schemName, int schemOwner, int schemMember){
ResultSet schematicMember = SQL.select("SELECT * FROM SchemMember WHERE SchemName = ? AND SchemOwner = ? AND Member = ?", schemName, schemOwner, schemMember); NodeMember member = NodeMember.getNodeMember(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID(), schemMember);
try { if(member == null) {
if(schematicMember == null || !schematicMember.next()){ return null;
return null; }
} return new SchematicMember(member);
return new SchematicMember(schemName, schemOwner, schemMember, false); }
} catch (SQLException e) {
throw new SecurityException("Could not get schemmember", e);
}
}
public static SchematicMember getMemberBySchematic(String schemName, int schemMember){ public static SchematicMember getMemberBySchematic(String schemName, int schemMember){
ResultSet schematicMember = SQL.select("SELECT * FROM SchemMember WHERE SchemName = ? AND Member = ?", schemName, schemMember); Optional<NodeMember> nodeMember = NodeMember.getSchematics(schemMember)
try { .stream().filter(member1 -> SchematicNode.getSchematicNode(member1.getNode()).getName().equalsIgnoreCase(schemName)).findFirst();
if(schematicMember == null || !schematicMember.next()){ return nodeMember.map(SchematicMember::new).orElse(null);
return null; }
}
int schemOwner = schematicMember.getInt("SchemOwner");
return new SchematicMember(schemName, schemOwner, schemMember, false);
} catch (SQLException e) {
throw new SecurityException("Could not get member", e);
}
}
public static List<SchematicMember> getSchemMembers(String schemName, UUID schemOwner){ public static List<SchematicMember> getSchemMembers(String schemName, UUID schemOwner){
return getSchemMembers(schemName, SteamwarUser.get(schemOwner).getId()); return getSchemMembers(schemName, SteamwarUser.get(schemOwner).getId());
} }
public static List<SchematicMember> getSchemMembers(String schemName, int schemOwner){ public static List<SchematicMember> getSchemMembers(String schemName, int schemOwner){
ResultSet schematicMember = SQL.select("SELECT * FROM SchemMember WHERE SchemName = ? AND SchemOwner = ?", schemName, schemOwner); List<SchematicMember> members = new ArrayList<>();
try { NodeMember.getNodeMembers(Schematic.getSchemFromDB(schemName, schemOwner).getSchemID())
List<SchematicMember> schematicMembers = new ArrayList<>(); .forEach(member1 -> members.add(new SchematicMember(member1)));
while(schematicMember.next()){ return members;
int schemMember = schematicMember.getInt("Member"); }
schematicMembers.add(new SchematicMember(schemName, schemOwner, schemMember, false));
}
return schematicMembers;
} catch (SQLException e) {
throw new SecurityException("Could not get schemmembers", e);
}
}
public static List<SchematicMember> getAccessibleSchems(UUID schemMember){ public static List<SchematicMember> getAccessibleSchems(UUID schemMember){
return getAccessibleSchems(SteamwarUser.get(schemMember).getId()); return getAccessibleSchems(SteamwarUser.get(schemMember).getId());
} }
public static List<SchematicMember> getAccessibleSchems(int schemMember){ public static List<SchematicMember> getAccessibleSchems(int schemMember){
ResultSet schematicMember = SQL.select("SELECT * FROM SchemMember WHERE Member = ?", schemMember); List<SchematicMember> members = new ArrayList<>();
try { NodeMember.getSchematics(schemMember)
List<SchematicMember> schematicMembers = new ArrayList<>(); .forEach(member1 -> members.add(new SchematicMember(member1)));
while(schematicMember.next()){ return members;
String schemName = schematicMember.getString("SchemName"); }
int schemOwner = schematicMember.getInt("SchemOwner");
schematicMembers.add(new SchematicMember(schemName, schemOwner, schemMember, false));
}
return schematicMembers;
} catch (SQLException e) {
throw new SecurityException("Could not get accessible schems", e);
}
}
public int getSchemOwner() { public int getSchemOwner() {
return schemOwner; return SchematicNode.getSchematicNode(member.getNode()).getOwner();
} }
public String getSchemName() { public String getSchemName() {
return schemName; return SchematicNode.getSchematicNode(member.getNode()).getName();
} }
public int getMember() { public int getMember() {
return member; return member.getMember();
} }
public void remove(){ public void remove(){
SQL.update("DELETE FROM SchemMember WHERE SchemOwner = ? AND SchemName = ? AND Member = ?", schemOwner, schemName, member); member.delete();
} }
} }

Datei anzeigen

@ -0,0 +1,605 @@
/*
* 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 com.sk89q.worldedit.extent.clipboard.Clipboard;
import de.steamwar.core.Core;
import de.steamwar.core.WorldEditWrapper;
import de.steamwar.inventory.SWItem;
import org.bukkit.entity.Player;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.function.Predicate;
import java.util.zip.GZIPInputStream;
public class SchematicNode {
private static final SQL.Statement createNode = new SQL.Statement("INSERT INTO SchematicNode (NodeName, NodeOwner, ParentNode, NodeType, NodeItem) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE NodeName = VALUES(NodeName), ParentNode = VALUES(ParentNode), NodeItem = VALUES(NodeItem), NodeType = VALUES(NodeType), NodeItem = VALUES(NodeItem)");
private static final SQL.Statement getSchematicNode_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeName = ? AND ParentNode is NULL");
private static final SQL.Statement getSchematicNode = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeName = ? AND ParentNode = ?");
private static final SQL.Statement getSchematicsInNode_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode is NULL ORDER BY NodeName");
private static final SQL.Statement getSchematicsInNode = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode = ? ORDER BY NodeName");
private static final SQL.Statement getDirsInNode_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName");
private static final SQL.Statement getDirsInNode = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName");
private static final SQL.Statement getSchematicDirectory_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode is NULL ORDER BY NodeName");
private static final SQL.Statement getSchematicDirectory = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode = ? ORDER BY NodeName");
private static final SQL.Statement getSchematicNodeO_Null = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode is NULL ");
private static final SQL.Statement getSchematicNodeO = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeName = ? AND ParentNode = ? ORDER BY NodeName");
private static final SQL.Statement getSchematicNodeId = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ?");
private static final SQL.Statement getAllSchemsOfTypeOwner = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
private static final SQL.Statement getAllSchemsOfType = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeType = ? ORDER BY NodeName");
private static final SQL.Statement getAccessibleByUser = new SQL.Statement("SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND ((s.NodeOwner = ? AND s.ParentNode IS NULL) OR NOT s.NodeOwner = ?) GROUP BY s.NodeId ORDER BY s.NodeName");
private static final SQL.Statement getAccessibleByUserByTypeInNode = new SQL.Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ? ORDER BY NodeName");
private static final SQL.Statement getAccessibleByUserByTypeInNode_Null = new SQL.Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode is null ORDER BY NodeName");
private static final SQL.Statement getAccessibleByUserByType = new SQL.Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? ORDER BY NodeName");
private static final SQL.Statement getAllSchematicsAccessibleByUser = new SQL.Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
private static final SQL.Statement isSchematicAccessibleForUser = new SQL.Statement("WITH RECURSIVE RSN AS (SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.ParentNode, SN.NodeType, SN.NodeItem, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN LEFT Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1");
private static final SQL.Statement getAllParentsOfNode = new SQL.Statement("WITH RECURSIVE RSN AS (SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ? UNION SELECT SN.NodeId, SN.NodeName, SN.NodeOwner, SN.ParentNode, SN.NodeType, SN.NodeItem, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
private static final SQL.Statement countNodes = new SQL.Statement("SELECT COUNT(NodeId) AS 'count' FROM SchematicNode");
private static final SQL.Statement updateDB = new SQL.Statement("UPDATE SchematicNode SET NodeName = ?, NodeOwner = ?, ParentNode = ?, NodeItem = ?, NodeType = ?, NodeRank = ? WHERE NodeId = ?");
private static final SQL.Statement updateDatabase = new SQL.Statement("UPDATE SchematicNode SET NodeData = ?, NodeFormat = ? WHERE NodeId = ?");
private static final SQL.Statement selSchemData = new SQL.Statement("SELECT NodeData FROM SchematicNode WHERE NodeId = ?");
private static final SQL.Statement deleteNode = new SQL.Statement("DELETE FROM SchematicNode WHERE NodeId = ?");
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;
createNode.update(name, owner, parent, type, item);
return getSchematicNode(owner, name, parent);
}
public static SchematicNode getSchematicNode(int owner, String name, SchematicNode parent) {
return getSchematicNode(owner, name, parent.getId());
}
private SchematicNode(ResultSet set) throws SQLException {
id = set.getInt("NodeId");
owner = set.getInt("NodeOwner");
name = set.getString("NodeName");
parent = set.getInt("ParentNode");
if(set.wasNull()) {
parent = null;
}
item = set.getString("NodeItem");
type = set.getString("NodeType");
lastUpdate = set.getTimestamp("LastUpdate");
if (type != null) {
isDir = false;
rank = set.getInt("NodeRank");
schemFormat = set.getBoolean("NodeFormat");
} else {
isDir = true;
}
}
public static List<SchematicNode> getSchematicNodeInNode(SchematicNode parent) {
return getSchematicNodeInNode(parent.getId());
}
public static SchematicNode getSchematicDirectory(String name, SchematicNode parent) {
return getSchematicDirectory(name, parent.getId());
}
public static SchematicNode getSchematicNode(int owner, String name, Integer parent) {
if (parent != null && parent == 0) {
parent = null;
}
SQL.Statement.ResultSetUser<SchematicNode> user = rs -> {
if (rs.next()) {
return new SchematicNode(rs);
}
return null;
};
if(parent == null) {
return getSchematicNode_Null.select(user, owner, name);
} else {
return getSchematicNode.select(user, owner, name, parent);
}
}
public static List<SchematicNode> getSchematicNodeInNode(Integer parent) {
if(parent != null && parent == 0)
parent = null;
SQL.Statement.ResultSetUser<List<SchematicNode>> user = rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while (rs.next()) {
nodes.add(new SchematicNode(rs));
}
return nodes;
};
if(parent == null) {
return getSchematicsInNode_Null.select(user);
}else {
return getSchematicsInNode.select(user, parent);
}
}
public static List<SchematicNode> getSchematicDirectoryInNode(Integer parent) {
if(parent != null && parent == 0)
parent = null;
SQL.Statement.ResultSetUser<List<SchematicNode>> user = rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while (rs.next())
nodes.add(new SchematicNode(rs));
return nodes;
};
if(parent == null) {
return getDirsInNode_Null.select(user);
}else {
return getDirsInNode.select(user, parent);
}
}
public static SchematicNode getSchematicDirectory(String name, Integer parent) {
if(parent != null && parent == 0)
parent = null;
SQL.Statement.ResultSetUser<SchematicNode> user = rs -> {
while (rs.next()) {
SchematicNode node = new SchematicNode(rs);
if(node.isDir())
return node;
}
return null;
};
if(parent == null) {
return getSchematicDirectory_Null.select(user, name);
}else {
return getSchematicDirectory.select(user, name, parent);
}
}
public static SchematicNode getSchematicNode(String name, Integer parent) {
if(parent != null && parent == 0)
parent = null;
SQL.Statement.ResultSetUser<SchematicNode> user = rs -> {
while (rs.next()) {
return new SchematicNode(rs);
}
return null;
};
if(parent == null) {
return getSchematicNodeO_Null.select(user, name);
}else {
return getSchematicNodeO.select(user, name, parent);
}
}
public static SchematicNode getSchematicNode(int id) {
return getSchematicNodeId.select(rs -> {
if (!rs.next())
return null;
return new SchematicNode(rs);
}, id);
}
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
SQL.Statement.ResultSetUser<List<SchematicNode>> user = rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while (rs.next()) {
nodes.add(new SchematicNode(rs));
}
return nodes;
};
if(parent == null || parent == 0) {
return getAccessibleByUserByTypeInNode_Null.select(user, owner, owner, schemType);
} else {
return getAccessibleByUserByTypeInNode.select(user, owner, owner, schemType, parent);
}
}
public static List<SchematicNode> getAllAccessibleSchematicsOfType(int user, String schemType) {
return getAccessibleByUserByType.select(rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while (rs.next()) {
nodes.add(new SchematicNode(rs));
}
return nodes;
}, user, user, schemType);
}
public static List<SchematicNode> getAllSchematicsOfType(int owner, String schemType) {
return getAllSchemsOfTypeOwner.select(rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while (rs.next())
nodes.add(new SchematicNode(rs));
return nodes;
}, owner, schemType);
}
public static List<SchematicNode> getAllSchematicsOfType(String schemType) {
return getAllSchemsOfType.select(rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while (rs.next())
nodes.add(new SchematicNode(rs));
return nodes;
}, schemType);
}
public static List<SchematicNode> deepGet(Integer parent, Predicate<SchematicNode> filter) {
List<SchematicNode> finalList = new ArrayList<>();
List<SchematicNode> nodes = SchematicNode.getSchematicNodeInNode(parent);
nodes.forEach(node -> {
if (node.isDir()) {
finalList.addAll(deepGet(node.getId(), filter));
} else {
if (filter.test(node))
finalList.add(node);
}
});
return finalList;
}
public static List<SchematicNode> getSchematicsAccessibleByUser(int user, Integer parent) {
if (parent != null && parent != 0) {
if(Boolean.TRUE.equals(isSchematicAccessibleForUser.select(rs -> {
rs.next();
return rs.getInt("Accessible") > 0;
}, parent, user, user))) {
return getSchematicNodeInNode(parent);
}
} else {
return getAccessibleByUser.select(rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while(rs.next())
nodes.add(new SchematicNode(rs));
return nodes;
}, user, user, user, user);
}
return Collections.emptyList();
}
public static List<SchematicNode> getAllSchematicsAccessibleByUser(int user) {
return getAllSchematicsAccessibleByUser.select(rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while(rs.next()) {
nodes.add(new SchematicNode(rs));
}
return nodes;
}, user, user);
}
public static List<SchematicNode> getAllParentsOfNode(SchematicNode node) {
return getAllParentsOfNode(node.getId());
}
public static List<SchematicNode> getAllParentsOfNode(int node) {
return getAllParentsOfNode.select(rs -> {
List<SchematicNode> nodes = new ArrayList<>();
while(rs.next()) {
nodes.add(new SchematicNode(rs));
}
return nodes;
}, node);
}
public static SchematicNode getNodeFromPath(SteamwarUser user, String s) {
if (s.startsWith("/")) {
s = s.substring(1);
}
if (s.isEmpty()) {
return null;
}
if (s.contains("/")) {
String[] layers = s.split("/");
SchematicNode currentNode = null;
for (int i = 0; i < layers.length; i++) {
int finalI = i;
Optional<SchematicNode> node;
if (currentNode == null) {
node = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(layers[finalI])).findAny();
} else {
node = Optional.ofNullable(SchematicNode.getSchematicNode(layers[i], currentNode.getId()));
}
if (!node.isPresent()) {
return null;
} else {
currentNode = node.get();
if (!currentNode.isDir() && i != layers.length - 1) {
return null;
}
}
}
return currentNode;
} else {
String finalS = s;
return SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(finalS)).findAny().orElse(null);
}
}
private final int id;
private final int owner;
private String name;
private Integer parent;
private String item;
private String type;
private boolean schemFormat;
private int rank;
private Timestamp lastUpdate;
private final boolean isDir;
private Map<Integer, String> brCache = new HashMap<>();
public static List<SchematicNode> filterSchems(int user, Predicate<SchematicNode> filter) {
List<SchematicNode> finalList = new ArrayList<>();
List<SchematicNode> nodes = SchematicNode.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 static Integer countNodes() {
return countNodes.select(rs -> {
if (rs.next()) {
return rs.getInt("count");
}
return 0;
});
}
public int getId() {
return id;
}
public int getOwner() {
return owner;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
updateDB();
}
public Integer getParent() {
return parent;
}
public void setParent(Integer parent) {
this.parent = parent;
updateDB();
}
public String getItem() {
if (item.isEmpty()) {
return isDir ? "CHEST" : "CAULDRON_ITEM";
}
return item;
}
public void setItem(String item) {
this.item = item;
updateDB();
}
@Deprecated
public String getType() {
if(isDir)
throw new SecurityException("Node is Directory");
return type;
}
@Deprecated
public void setType(String type) {
if(isDir)
throw new SecurityException("Node is Directory");
this.type = type;
updateDB();
}
public boolean isDir() {
return isDir;
}
public boolean getSchemFormat() {
if(isDir)
throw new SecurityException("Node is Directory");
return schemFormat;
}
public int getRank() {
if(isDir)
throw new SecurityException("Node is Directory");
return rank;
}
public void setRank(int rank) {
if(isDir)
throw new SecurityException("Node is Directory");
this.rank = rank;
}
public SchematicType getSchemtype() {
if(isDir())
throw new RuntimeException("Is Directory");
return SchematicType.fromDB(type);
}
public void setSchemtype(SchematicType type) {
if(isDir())
throw new RuntimeException("Is Directory");
this.type = type.toDB();
updateDB();
}
public SchematicNode getParentNode() {
if(parent == null) return null;
return SchematicNode.getSchematicNode(parent);
}
public boolean accessibleByUser(int user) {
return NodeMember.getNodeMember(id, user) != null;
}
public Set<NodeMember> getMembers() {
return NodeMember.getNodeMembers(id);
}
public Timestamp getLastUpdate() {
return lastUpdate;
}
public String generateBreadcrumbs(SteamwarUser user) {
return brCache.computeIfAbsent(user.getId(), integer -> generateBreadcrumbs("/", user));
}
public String generateBreadcrumbs(String split, SteamwarUser user) {
StringBuilder builder = new StringBuilder(getName());
SchematicNode currentNode = this;
if (currentNode.isDir()) builder.append("/");
while (currentNode.getParentNode() != null) {
currentNode = currentNode.getParentNode();
builder.insert(0, split)
.insert(0, currentNode.getName());
if (currentNode.getMembers().stream().anyMatch(member -> member.getMember() == user.getId())) {
break;
}
}
return builder.toString();
}
private void updateDB() {
updateDB.update(name, owner, parent, item, type, rank, id);
this.lastUpdate = Timestamp.from(Instant.now());
this.brCache.clear();
}
public void delete() {
if (isDir()) {
getSchematicNodeInNode(getId()).forEach(SchematicNode::delete);
}
deleteNode.update(id);
}
public InputStream schemData() throws IOException {
try {
return selSchemData.select(rs -> {
rs.next();
Blob schemData = rs.getBlob("NodeData");
if(schemData == null) {
throw new SecurityException("SchemData is null");
}
try {
return new GZIPInputStream(schemData.getBinaryStream());
} catch (IOException e) {
throw new SecurityException("SchemData is wrong", e);
}
}, id);
} catch (Exception e) {
throw new IOException(e);
}
}
public Clipboard load() throws IOException, NoClipboardException {
if(isDir)
throw new SecurityException("Node is Directory");
return WorldEditWrapper.impl.getClipboard(schemData(), schemFormat);
}
public void loadToPlayer(Player player) throws IOException, NoClipboardException {
if(isDir)
throw new SecurityException("Node is Directory");
WorldEditWrapper.impl.setPlayerClipboard(player, schemData(), schemFormat);
}
public void saveFromPlayer(Player player) throws IOException, NoClipboardException {
if(isDir)
throw new SecurityException("Node is Directory");
saveFromPlayer(player, Core.getVersion() > 12);
}
public void saveFromBytes(byte[] bytes, boolean newFormat) {
if(isDir)
throw new SecurityException("Node is Directory");
updateDatabase(new ByteArrayInputStream(bytes), newFormat);
}
public void saveFromPlayer(Player player, boolean newFormat) throws IOException, NoClipboardException {
if(isDir)
throw new SecurityException("Node is Directory");
updateDatabase(WorldEditWrapper.impl.getPlayerClipboard(player, newFormat), newFormat);
}
private void updateDatabase(InputStream blob, boolean newFormat) {
updateDatabase.update(blob, newFormat, id);
schemFormat = newFormat;
}
public static Clipboard clipboardFromStream(InputStream is, boolean schemFormat) {
try {
return WorldEditWrapper.impl.getClipboard(is, schemFormat);
} catch (IOException e) {
throw new SecurityException("Could not read schem", e);
}
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SchematicNode))
return false;
SchematicNode node = (SchematicNode) obj;
return node.getId() == id;
}
public static List<String> getNodeTabcomplete(SteamwarUser user, String s) {
List<String> list = new ArrayList<>();
boolean sws = s.startsWith("/");
if (sws) {
s = s.substring(1);
}
if (s.contains("/")) {
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
if (pa == null) return Collections.emptyList();
List<SchematicNode> nodes = SchematicNode.getSchematicNodeInNode(pa);
nodes.forEach(node -> list.add((sws ? "/" : "") + node.generateBreadcrumbs(user)));
} else {
List<SchematicNode> nodes = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0);
nodes.forEach(node -> list.add((sws ? "/" : "") + node.getName() + (node.isDir() ? "/" : "")));
}
list.remove("//copy");
return list;
}
}