Merge branch 'master' into schematic-node
Dieser Commit ist enthalten in:
Commit
4bd282b113
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.inventory;
|
package de.steamwar.inventory;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
import org.bukkit.inventory.meta.SkullMeta;
|
||||||
@ -269,7 +270,7 @@ class SWItem_14 {
|
|||||||
ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1);
|
ItemStack head = new ItemStack(Material.PLAYER_HEAD, 1);
|
||||||
SkullMeta headmeta = (SkullMeta) head.getItemMeta();
|
SkullMeta headmeta = (SkullMeta) head.getItemMeta();
|
||||||
assert headmeta != null;
|
assert headmeta != null;
|
||||||
headmeta.setOwner(player);
|
headmeta.setOwningPlayer(Bukkit.getOfflinePlayer(player));
|
||||||
headmeta.setDisplayName(player);
|
headmeta.setDisplayName(player);
|
||||||
head.setItemMeta(headmeta);
|
head.setItemMeta(headmeta);
|
||||||
return head;
|
return head;
|
||||||
|
33
SpigotCore_15/src/de/steamwar/authlib/AuthlibInjector_15.java
Normale Datei
33
SpigotCore_15/src/de/steamwar/authlib/AuthlibInjector_15.java
Normale Datei
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* 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.authlib;
|
||||||
|
|
||||||
|
import net.minecraft.server.v1_15_R1.MinecraftServer;
|
||||||
|
|
||||||
|
public class AuthlibInjector_15 {
|
||||||
|
|
||||||
|
static Class getMinecraftClass() {
|
||||||
|
return MinecraftServer.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object getMinecraftServerInstance() {
|
||||||
|
return MinecraftServer.getServer();
|
||||||
|
}
|
||||||
|
}
|
47
SpigotCore_Main/src/de/steamwar/authlib/AuthlibInjector.java
Normale Datei
47
SpigotCore_Main/src/de/steamwar/authlib/AuthlibInjector.java
Normale Datei
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* 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.authlib;
|
||||||
|
|
||||||
|
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
|
||||||
|
import de.steamwar.core.Core;
|
||||||
|
import de.steamwar.core.VersionedCallable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class AuthlibInjector {
|
||||||
|
|
||||||
|
public static void inject() {
|
||||||
|
if (Core.getVersion() != 15) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Class<?> minecraftServerClass = VersionedCallable.call(new VersionedCallable<>(() -> AuthlibInjector_15.getMinecraftClass(), 15));
|
||||||
|
Field repo = minecraftServerClass.getDeclaredField("gameProfileRepository");
|
||||||
|
repo.setAccessible(true);
|
||||||
|
Object instance = VersionedCallable.call(new VersionedCallable<>(() -> AuthlibInjector_15.getMinecraftServerInstance(), 15));
|
||||||
|
repo.set(instance, new SteamwarGameProfileRepository((YggdrasilGameProfileRepository) repo.get(instance)));
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.authlib;
|
||||||
|
|
||||||
|
import com.mojang.authlib.Agent;
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import com.mojang.authlib.GameProfileRepository;
|
||||||
|
import com.mojang.authlib.ProfileLookupCallback;
|
||||||
|
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SteamwarGameProfileRepository implements GameProfileRepository {
|
||||||
|
|
||||||
|
private final YggdrasilGameProfileRepository fallback;
|
||||||
|
|
||||||
|
public SteamwarGameProfileRepository(YggdrasilGameProfileRepository repository) {
|
||||||
|
fallback = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void findProfilesByNames(String[] strings, Agent agent, ProfileLookupCallback profileLookupCallback) {
|
||||||
|
if(agent == Agent.SCROLLS) {
|
||||||
|
fallback.findProfilesByNames(strings, agent, profileLookupCallback);
|
||||||
|
} else {
|
||||||
|
List<String> unknownNames = new ArrayList<>();
|
||||||
|
for (String name:strings) {
|
||||||
|
SteamwarUser user = SteamwarUser.get(name);
|
||||||
|
if(user == null) {
|
||||||
|
unknownNames.add(name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
profileLookupCallback.onProfileLookupSucceeded(new GameProfile(user.getUUID(), user.getUserName()));
|
||||||
|
}
|
||||||
|
if(!unknownNames.isEmpty()) {
|
||||||
|
fallback.findProfilesByNames(unknownNames.toArray(new String[0]), agent, profileLookupCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,20 +23,4 @@ public class CommandParseException extends Exception {
|
|||||||
|
|
||||||
public CommandParseException() {
|
public CommandParseException() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandParseException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandParseException(String message, Throwable cause) {
|
|
||||||
super(message, cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandParseException(Throwable cause) {
|
|
||||||
super(cause);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CommandParseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
|
||||||
super(message, cause, enableSuppression, writableStackTrace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -30,12 +30,13 @@ import java.util.*;
|
|||||||
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;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class SWCommand {
|
public abstract class SWCommand {
|
||||||
|
|
||||||
private final Command command;
|
private final Command command;
|
||||||
private final List<SubCommand> commandSet = new ArrayList<>();
|
private final List<SubCommand> commandList = new ArrayList<>();
|
||||||
private final List<SubCommand> commandHelpSet = 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<>();
|
||||||
|
|
||||||
protected SWCommand(String command) {
|
protected SWCommand(String command) {
|
||||||
@ -46,58 +47,36 @@ public abstract class SWCommand {
|
|||||||
this.command = new Command(command, "", "/" + command, Arrays.asList(aliases)) {
|
this.command = new Command(command, "", "/" + command, Arrays.asList(aliases)) {
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(CommandSender sender, String alias, String[] args) {
|
public boolean execute(CommandSender sender, String alias, String[] args) {
|
||||||
for (SubCommand subCommand : commandSet) {
|
if (commandList.stream().anyMatch(s -> s.invoke(sender, args))) return false;
|
||||||
if (subCommand.invoke(sender, args)) {
|
commandHelpList.stream().anyMatch(s -> s.invoke(sender, args));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (SubCommand subCommand : commandHelpSet) {
|
|
||||||
if (subCommand.invoke(sender, args)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
|
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
|
||||||
List<String> strings = new ArrayList<>();
|
String string = args[args.length - 1].toLowerCase();
|
||||||
for (SubCommand subCommand : commandSet) {
|
return commandList.stream()
|
||||||
List<String> tabCompletes = subCommand.tabComplete(sender, args);
|
.map(s -> s.tabComplete(sender, args))
|
||||||
if (tabCompletes != null) {
|
.filter(Objects::nonNull)
|
||||||
strings.addAll(tabCompletes);
|
.flatMap(Collection::stream)
|
||||||
}
|
.filter(s -> !s.isEmpty())
|
||||||
}
|
.filter(s -> s.toLowerCase().startsWith(string))
|
||||||
strings = new ArrayList<>(strings);
|
.collect(Collectors.toList());
|
||||||
for (int i = strings.size() - 1; i >= 0; i--) {
|
|
||||||
if (!strings.get(i).toLowerCase().startsWith(args[args.length - 1].toLowerCase())) {
|
|
||||||
strings.remove(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return strings;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
unregister();
|
||||||
register();
|
register();
|
||||||
|
|
||||||
for (Method method : getClass().getDeclaredMethods()) {
|
Method[] methods = getClass().getDeclaredMethods();
|
||||||
|
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) -> {
|
||||||
if (anno.local()) {
|
(anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value(), typeMapper);
|
||||||
localTypeMapper.put(anno.value(), typeMapper);
|
|
||||||
} else {
|
|
||||||
SWCommandUtils.addMapper(anno.value(), typeMapper);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
addMapper(ClassMapper.class, method, i -> i == 0, false, TypeMapper.class, (anno, typeMapper) -> {
|
addMapper(ClassMapper.class, method, i -> i == 0, false, TypeMapper.class, (anno, typeMapper) -> {
|
||||||
if (anno.local()) {
|
(anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value().getTypeName(), typeMapper);
|
||||||
localTypeMapper.put(anno.value().getTypeName(), typeMapper);
|
|
||||||
} else {
|
|
||||||
SWCommandUtils.addMapper(anno.value().getTypeName(), typeMapper);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
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()) {
|
if (!anno.help()) return;
|
||||||
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");
|
||||||
}
|
}
|
||||||
@ -108,14 +87,12 @@ public abstract class SWCommand {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
commandHelpSet.add(new SubCommand(this, method, anno.value()));
|
commandHelpList.add(new SubCommand(this, method, anno.value(), new HashMap<>()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (Method method : getClass().getDeclaredMethods()) {
|
for (Method method : methods) {
|
||||||
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()) {
|
if (anno.help()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
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();
|
||||||
@ -126,37 +103,31 @@ public abstract class SWCommand {
|
|||||||
if (clazz.isEnum() && mapper == null && !SWCommandUtils.MAPPER_FUNCTIONS.containsKey(clazz.getTypeName())) {
|
if (clazz.isEnum() && mapper == null && !SWCommandUtils.MAPPER_FUNCTIONS.containsKey(clazz.getTypeName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String name = clazz.getTypeName();
|
String name = mapper != null ? mapper.value() : clazz.getTypeName();
|
||||||
if (mapper != null) {
|
|
||||||
name = mapper.value();
|
|
||||||
}
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commandSet.add(new SubCommand(this, method, anno.value(), localTypeMapper));
|
commandList.add(new SubCommand(this, method, anno.value(), localTypeMapper));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.commandSet.sort((o1, o2) -> {
|
this.commandList.sort((o1, o2) -> {
|
||||||
int compare = Integer.compare(-o1.subCommand.length, -o2.subCommand.length);
|
int compare = Integer.compare(-o1.subCommand.length, -o2.subCommand.length);
|
||||||
if (compare != 0) {
|
if (compare != 0) {
|
||||||
return compare;
|
return compare;
|
||||||
} else {
|
} else {
|
||||||
int i1 = o1.varArgType != null ? Integer.MAX_VALUE : o1.arguments.length;
|
return Integer.compare(o1.varArgType != null ? Integer.MAX_VALUE : o1.arguments.length,
|
||||||
int i2 = o2.varArgType != null ? Integer.MAX_VALUE : o2.arguments.length;
|
o2.varArgType != null ? Integer.MAX_VALUE : o2.arguments.length);
|
||||||
return Integer.compare(i1, i2);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
commandHelpSet.sort(Comparator.comparingInt(o -> -o.subCommand.length));
|
commandHelpList.sort(Comparator.comparingInt(o -> -o.subCommand.length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Annotation> void add(Class<T> annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class<?> returnType, BiConsumer<T, Parameter[]> consumer) {
|
private <T extends Annotation> void add(Class<T> annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class<?> returnType, BiConsumer<T, Parameter[]> consumer) {
|
||||||
T anno = SWCommandUtils.getAnnotation(method, annotation);
|
T[] anno = SWCommandUtils.getAnnotation(method, annotation);
|
||||||
if (anno == null) {
|
if (anno == null || anno.length == 0) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Parameter[] parameters = method.getParameters();
|
Parameter[] parameters = method.getParameters();
|
||||||
if (!parameterTester.test(parameters.length)) {
|
if (!parameterTester.test(parameters.length)) {
|
||||||
@ -171,39 +142,43 @@ public abstract class SWCommand {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
consumer.accept(anno, parameters);
|
Arrays.stream(anno).forEach(t -> consumer.accept(t, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends Annotation> void addMapper(Class<T> annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class<?> returnType, BiConsumer<T, TypeMapper<?>> consumer) {
|
private <T extends Annotation> void addMapper(Class<T> annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class<?> returnType, BiConsumer<T, TypeMapper<?>> consumer) {
|
||||||
add(annotation, method, parameterTester, firstParameter, returnType, (anno, parameters) -> {
|
add(annotation, method, parameterTester, firstParameter, returnType, (anno, parameters) -> {
|
||||||
try {
|
try {
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
Object object = method.invoke(this);
|
consumer.accept(anno, (TypeMapper<?>) method.invoke(this));
|
||||||
consumer.accept(anno, (TypeMapper<?>) object);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new SecurityException(e.getMessage(), e);
|
throw new SecurityException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void unregister() {
|
public void unregister() {
|
||||||
SWCommandUtils.knownCommandMap.remove(command.getName());
|
SWCommandUtils.knownCommandMap.remove(command.getName());
|
||||||
for (String alias : command.getAliases()) {
|
command.getAliases().forEach(SWCommandUtils.knownCommandMap::remove);
|
||||||
SWCommandUtils.knownCommandMap.remove(alias);
|
|
||||||
}
|
|
||||||
command.unregister(SWCommandUtils.commandMap);
|
command.unregister(SWCommandUtils.commandMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void register() {
|
public void register() {
|
||||||
SWCommandUtils.commandMap.register("steamwar", this.command);
|
SWCommandUtils.commandMap.register("steamwar", this.command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({ElementType.METHOD})
|
@Target({ElementType.METHOD})
|
||||||
|
@Repeatable(Register.Registeres.class)
|
||||||
protected @interface Register {
|
protected @interface Register {
|
||||||
String[] value() default {};
|
String[] value() default {};
|
||||||
|
|
||||||
boolean help() default false;
|
boolean help() default false;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ElementType.METHOD})
|
||||||
|
@interface Registeres {
|
||||||
|
Register[] value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@ -50,10 +50,7 @@ public class SWCommandUtils {
|
|||||||
|
|
||||||
static final BiFunction<Class<Enum<?>>, String, Enum<?>> ENUM_MAPPER = (enumClass, s) -> {
|
static final BiFunction<Class<Enum<?>>, String, Enum<?>> ENUM_MAPPER = (enumClass, s) -> {
|
||||||
Enum<?>[] enums = enumClass.getEnumConstants();
|
Enum<?>[] enums = enumClass.getEnumConstants();
|
||||||
for (Enum<?> e : enums) {
|
return Arrays.stream(enums).filter(e -> e.name().equalsIgnoreCase(s)).findFirst().orElse(null);
|
||||||
if (e.name().equalsIgnoreCase(s)) return e;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -61,6 +58,7 @@ public class SWCommandUtils {
|
|||||||
addMapper(float.class, Float.class, createMapper(numberMapper(Float::parseFloat), numberCompleter(Float::parseFloat)));
|
addMapper(float.class, Float.class, createMapper(numberMapper(Float::parseFloat), numberCompleter(Float::parseFloat)));
|
||||||
addMapper(double.class, Double.class, createMapper(numberMapper(Double::parseDouble), numberCompleter(Double::parseDouble)));
|
addMapper(double.class, Double.class, createMapper(numberMapper(Double::parseDouble), numberCompleter(Double::parseDouble)));
|
||||||
addMapper(int.class, Integer.class, createMapper(numberMapper(Integer::parseInt), numberCompleter(Integer::parseInt)));
|
addMapper(int.class, Integer.class, createMapper(numberMapper(Integer::parseInt), numberCompleter(Integer::parseInt)));
|
||||||
|
addMapper(long.class, Long.class, createMapper(numberMapper(Long::parseLong), numberCompleter(Long::parseLong)));
|
||||||
MAPPER_FUNCTIONS.put(String.class.getTypeName(), createMapper(s -> s, Collections::singletonList));
|
MAPPER_FUNCTIONS.put(String.class.getTypeName(), createMapper(s -> s, Collections::singletonList));
|
||||||
MAPPER_FUNCTIONS.put(Player.class.getTypeName(), createMapper(Bukkit::getPlayer, s -> Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList())));
|
MAPPER_FUNCTIONS.put(Player.class.getTypeName(), createMapper(Bukkit::getPlayer, s -> Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList())));
|
||||||
MAPPER_FUNCTIONS.put(GameMode.class.getTypeName(), createMapper(s -> {
|
MAPPER_FUNCTIONS.put(GameMode.class.getTypeName(), createMapper(s -> {
|
||||||
@ -100,43 +98,37 @@ public class SWCommandUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object[] generateArgumentArray(TypeMapper<?>[] parameters, String[] args, Class<?> varArgType, String[] subCommand) throws CommandParseException {
|
static Object[] generateArgumentArray(CommandSender commandSender, TypeMapper<?>[] parameters, 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) {
|
||||||
if (!args[index].equalsIgnoreCase(subCommand[index])) {
|
if (!args[index].equalsIgnoreCase(subCommand[index])) throw new CommandParseException();
|
||||||
throw new CommandParseException();
|
|
||||||
}
|
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varArgType != null && index > args.length - 1) {
|
int length = 0;
|
||||||
Object varArgument = Array.newInstance(varArgType, 0);
|
if (varArgType != null) {
|
||||||
arguments[arguments.length - 1] = varArgument;
|
length = args.length - parameters.length - subCommand.length + 1;
|
||||||
} else {
|
arguments[arguments.length - 1] = Array.newInstance(varArgType, length);
|
||||||
for (int i = 0; i < parameters.length - (varArgType != null ? 1 : 0); i++) {
|
if (index > args.length - 1) return arguments;
|
||||||
arguments[i + 1] = parameters[i].map(Arrays.copyOf(args, index), args[index]);
|
|
||||||
index++;
|
|
||||||
if (arguments[i + 1] == null) {
|
|
||||||
throw new CommandParseException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < parameters.length - (varArgType != null ? 1 : 0); i++) {
|
||||||
|
arguments[i + 1] = parameters[i].map(commandSender, Arrays.copyOf(args, index), args[index]);
|
||||||
|
index++;
|
||||||
|
if (arguments[i + 1] == null) throw new CommandParseException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varArgType != null) {
|
if (varArgType != null) {
|
||||||
int length = args.length - parameters.length - subCommand.length + 1;
|
Object varArgument = arguments[arguments.length - 1];
|
||||||
Object varArgument = Array.newInstance(varArgType, length);
|
|
||||||
arguments[arguments.length - 1] = varArgument;
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
Object value = parameters[parameters.length - 1].map(Arrays.copyOf(args, index), args[index]);
|
Object value = parameters[parameters.length - 1].map(commandSender, Arrays.copyOf(args, index), args[index]);
|
||||||
if (value == null) {
|
if (value == null) throw new CommandParseException();
|
||||||
throw new CommandParseException();
|
|
||||||
}
|
|
||||||
Array.set(varArgument, i, value);
|
Array.set(varArgument, i, value);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +137,7 @@ public class SWCommandUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void addMapper(String name, TypeMapper<?> mapper) {
|
public static void addMapper(String name, TypeMapper<?> mapper) {
|
||||||
if (MAPPER_FUNCTIONS.containsKey(name)) return;
|
MAPPER_FUNCTIONS.putIfAbsent(name, mapper);
|
||||||
MAPPER_FUNCTIONS.put(name, mapper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -156,7 +147,7 @@ public class SWCommandUtils {
|
|||||||
public static <T> TypeMapper<T> createMapper(Function<String, T> mapper, BiFunction<CommandSender, String, List<String>> tabCompleter) {
|
public static <T> TypeMapper<T> createMapper(Function<String, T> mapper, BiFunction<CommandSender, String, List<String>> tabCompleter) {
|
||||||
return new TypeMapper<T>() {
|
return new TypeMapper<T>() {
|
||||||
@Override
|
@Override
|
||||||
public T map(String[] previous, String s) {
|
public T map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
return mapper.apply(s);
|
return mapper.apply(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,18 +169,13 @@ public class SWCommandUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Function<String, List<String>> numberCompleter(Function<String, ?> mapper) {
|
private static Function<String, List<String>> numberCompleter(Function<String, ?> mapper) {
|
||||||
return s -> {
|
return s -> numberMapper(mapper).apply(s) != null
|
||||||
try {
|
? Collections.singletonList(s)
|
||||||
mapper.apply(s);
|
: Collections.emptyList();
|
||||||
return Collections.singletonList(s);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static <T extends Annotation> T getAnnotation(Method method, Class<T> annotation) {
|
static <T extends Annotation> T[] getAnnotation(Method method, Class<T> annotation) {
|
||||||
if (method.getAnnotations().length != 1) return null;
|
if (method.getAnnotations().length != 1) return null;
|
||||||
return method.getAnnotation(annotation);
|
return method.getDeclaredAnnotationsByType(annotation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,9 @@ import java.lang.reflect.Method;
|
|||||||
import java.lang.reflect.Parameter;
|
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 static de.steamwar.command.SWCommandUtils.*;
|
||||||
|
|
||||||
class SubCommand {
|
class SubCommand {
|
||||||
|
|
||||||
@ -33,18 +36,16 @@ class SubCommand {
|
|||||||
private Method method;
|
private Method method;
|
||||||
String[] subCommand;
|
String[] subCommand;
|
||||||
TypeMapper<?>[] arguments;
|
TypeMapper<?>[] arguments;
|
||||||
|
private Predicate<CommandSender> commandSenderPredicate;
|
||||||
private Function<CommandSender, ?> commandSenderFunction;
|
private Function<CommandSender, ?> commandSenderFunction;
|
||||||
Class<?> varArgType = null;
|
Class<?> varArgType = null;
|
||||||
|
|
||||||
public SubCommand(SWCommand swCommand, Method method, String[] subCommand) {
|
SubCommand(SWCommand swCommand, Method method, String[] subCommand, Map<String, TypeMapper<?>> localTypeMapper) {
|
||||||
this(swCommand, method, subCommand, new HashMap<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
public SubCommand(SWCommand swCommand, Method method, String[] subCommand, Map<String, TypeMapper<?>> localTypeMapper) {
|
|
||||||
this.swCommand = swCommand;
|
this.swCommand = swCommand;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
|
||||||
Parameter[] parameters = method.getParameters();
|
Parameter[] parameters = method.getParameters();
|
||||||
|
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;
|
||||||
|
|
||||||
@ -58,13 +59,13 @@ class SubCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SWCommand.Mapper mapper = parameter.getAnnotation(SWCommand.Mapper.class);
|
SWCommand.Mapper mapper = parameter.getAnnotation(SWCommand.Mapper.class);
|
||||||
if (clazz.isEnum() && mapper == null && !SWCommandUtils.MAPPER_FUNCTIONS.containsKey(clazz.getTypeName()) && !localTypeMapper.containsKey(clazz.getTypeName())) {
|
if (clazz.isEnum() && mapper == null && !MAPPER_FUNCTIONS.containsKey(clazz.getTypeName()) && !localTypeMapper.containsKey(clazz.getTypeName())) {
|
||||||
Class<Enum<?>> enumClass = (Class<Enum<?>>) clazz;
|
Class<Enum<?>> enumClass = (Class<Enum<?>>) clazz;
|
||||||
List<String> tabCompletes = new ArrayList<>();
|
List<String> tabCompletes = new ArrayList<>();
|
||||||
for (Enum<?> enumConstant : enumClass.getEnumConstants()) {
|
for (Enum<?> enumConstant : enumClass.getEnumConstants()) {
|
||||||
tabCompletes.add(enumConstant.name().toLowerCase());
|
tabCompletes.add(enumConstant.name().toLowerCase());
|
||||||
}
|
}
|
||||||
arguments[i - 1] = SWCommandUtils.createMapper(s -> SWCommandUtils.ENUM_MAPPER.apply(enumClass, s), s -> tabCompletes);
|
arguments[i - 1] = SWCommandUtils.createMapper(s -> ENUM_MAPPER.apply(enumClass, s), s -> tabCompletes);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,11 +73,9 @@ class SubCommand {
|
|||||||
if (mapper != null) {
|
if (mapper != null) {
|
||||||
name = mapper.value();
|
name = mapper.value();
|
||||||
}
|
}
|
||||||
if (localTypeMapper.containsKey(name)) {
|
arguments[i - 1] = localTypeMapper.containsKey(name)
|
||||||
arguments[i - 1] = localTypeMapper.getOrDefault(name, SWCommandUtils.ERROR_FUNCTION);
|
? localTypeMapper.get(name)
|
||||||
} else {
|
: MAPPER_FUNCTIONS.getOrDefault(name, ERROR_FUNCTION);
|
||||||
arguments[i - 1] = SWCommandUtils.MAPPER_FUNCTIONS.getOrDefault(name, SWCommandUtils.ERROR_FUNCTION);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +87,10 @@ class SubCommand {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Object[] objects = SWCommandUtils.generateArgumentArray(arguments, args, varArgType, subCommand);
|
if (!commandSenderPredicate.test(commandSender)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Object[] objects = SWCommandUtils.generateArgumentArray(commandSender, arguments, args, varArgType, subCommand);
|
||||||
objects[0] = commandSenderFunction.apply(commandSender);
|
objects[0] = commandSenderFunction.apply(commandSender);
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
method.invoke(swCommand, objects);
|
method.invoke(swCommand, objects);
|
||||||
@ -114,9 +116,11 @@ class SubCommand {
|
|||||||
}
|
}
|
||||||
for (TypeMapper<?> argument : arguments) {
|
for (TypeMapper<?> argument : arguments) {
|
||||||
String s = argsList.remove(0);
|
String s = argsList.remove(0);
|
||||||
if (argsList.isEmpty()) return argument.tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s);
|
if (argsList.isEmpty()) {
|
||||||
|
return argument.tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (argument.map(Arrays.copyOf(args, index), s) == null) {
|
if (argument.map(commandSender, Arrays.copyOf(args, index), s) == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -127,9 +131,11 @@ class SubCommand {
|
|||||||
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()) return arguments[arguments.length - 1].tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s);
|
if (argsList.isEmpty()) {
|
||||||
|
return arguments[arguments.length - 1].tabCompletes(commandSender, Arrays.copyOf(args, args.length - 1), s);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (arguments[arguments.length - 1].map(Arrays.copyOf(args, index), s) == null) {
|
if (arguments[arguments.length - 1].map(commandSender, Arrays.copyOf(args, index), s) == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -24,7 +24,15 @@ import org.bukkit.command.CommandSender;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface TypeMapper<T> {
|
public interface TypeMapper<T> {
|
||||||
T map(String[] previousArguments, String s);
|
default T map(CommandSender commandSender, String[] previousArguments, String s) {
|
||||||
|
return map(previousArguments, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For backwards compatibility, can be removed later on
|
||||||
|
@Deprecated(since = "Use the other map Function without calling super!")
|
||||||
|
default T map(String[] previousArguments, String s) {
|
||||||
|
throw new SecurityException();
|
||||||
|
}
|
||||||
|
|
||||||
List<String> tabCompletes(CommandSender commandSender, String[] previousArguments, String s);
|
List<String> tabCompletes(CommandSender commandSender, String[] previousArguments, String s);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.core;
|
package de.steamwar.core;
|
||||||
|
|
||||||
|
import de.steamwar.authlib.AuthlibInjector;
|
||||||
import de.steamwar.comms.BungeeReceiver;
|
import de.steamwar.comms.BungeeReceiver;
|
||||||
import de.steamwar.core.events.ChattingEvent;
|
import de.steamwar.core.events.ChattingEvent;
|
||||||
import de.steamwar.core.events.ChunkListener;
|
import de.steamwar.core.events.ChunkListener;
|
||||||
@ -64,6 +65,7 @@ public class Core extends JavaPlugin{
|
|||||||
ErrorLogger.init();
|
ErrorLogger.init();
|
||||||
getServer().getMessenger().registerIncomingPluginChannel(this, "sw:bridge", new BungeeReceiver());
|
getServer().getMessenger().registerIncomingPluginChannel(this, "sw:bridge", new BungeeReceiver());
|
||||||
getServer().getMessenger().registerOutgoingPluginChannel(this, "sw:bridge");
|
getServer().getMessenger().registerOutgoingPluginChannel(this, "sw:bridge");
|
||||||
|
AuthlibInjector.inject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,21 +28,19 @@ public class Team {
|
|||||||
private final int teamId;
|
private final int teamId;
|
||||||
private final String teamKuerzel;
|
private final String teamKuerzel;
|
||||||
private final String teamName;
|
private final String teamName;
|
||||||
private final int teamLeader;
|
|
||||||
private final String teamColor;
|
private final String teamColor;
|
||||||
|
|
||||||
private static final Team pub = new Team(0, "PUB", "Öffentlich", 0, "8");
|
private static final Team pub = new Team(0, "PUB", "Öffentlich", "8");
|
||||||
|
|
||||||
private Team(int teamId, String teamKuerzel, String teamName, int teamLeader, String teamColor){
|
private Team(int teamId, String teamKuerzel, String teamName, String teamColor){
|
||||||
this.teamId = teamId;
|
this.teamId = teamId;
|
||||||
this.teamKuerzel = teamKuerzel;
|
this.teamKuerzel = teamKuerzel;
|
||||||
this.teamName = teamName;
|
this.teamName = teamName;
|
||||||
this.teamLeader = teamLeader;
|
|
||||||
this.teamColor = teamColor;
|
this.teamColor = teamColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Team(ResultSet rs) throws SQLException {
|
private Team(ResultSet rs) throws SQLException {
|
||||||
this(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getInt("TeamLeader"), rs.getString("TeamColor"));
|
this(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getString("TeamColor"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Team get(int id){
|
public static Team get(int id){
|
||||||
@ -70,10 +68,6 @@ public class Team {
|
|||||||
return teamName;
|
return teamName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTeamLeader() {
|
|
||||||
return teamLeader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTeamColor() {
|
public String getTeamColor() {
|
||||||
return teamColor;
|
return teamColor;
|
||||||
}
|
}
|
||||||
|
68
SpigotCore_Main/src/de/steamwar/sql/UserConfig.java
Normale Datei
68
SpigotCore_Main/src/de/steamwar/sql/UserConfig.java
Normale Datei
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* 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.UUID;
|
||||||
|
|
||||||
|
public class UserConfig {
|
||||||
|
|
||||||
|
private UserConfig() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getConfig(UUID player, String config) {
|
||||||
|
return getConfig(SteamwarUser.get(player).getId(), config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getConfig(int player, String config) {
|
||||||
|
ResultSet configResult = SQL.select("SELECT * FROM UserConfig WHERE User = ? AND Config = ?", player, config);
|
||||||
|
try {
|
||||||
|
if (!configResult.next()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return configResult.getString("Value");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new SecurityException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updatePlayerConfig(UUID uuid, String config, String value) {
|
||||||
|
updatePlayerConfig(SteamwarUser.get(uuid).getId(), config, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updatePlayerConfig(int id, String config, String value) {
|
||||||
|
if (value == null) {
|
||||||
|
removePlayerConfig(id, config);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SQL.update("INSERT INTO UserConfig (User, Config, Value) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE Value = VALUES(Value)", id, config, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removePlayerConfig(UUID uuid, String config) {
|
||||||
|
removePlayerConfig(SteamwarUser.get(uuid).getId(), config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removePlayerConfig(int id, String config) {
|
||||||
|
SQL.update("DELETE FROM UserConfig WHERE User = ? AND Config = ?", id, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren