diff --git a/SpigotCore_Main/src/de/steamwar/command/CommandParseException.java b/SpigotCore_Main/src/de/steamwar/command/CommandParseException.java index b47cace..21e68bb 100644 --- a/SpigotCore_Main/src/de/steamwar/command/CommandParseException.java +++ b/SpigotCore_Main/src/de/steamwar/command/CommandParseException.java @@ -23,20 +23,4 @@ public class CommandParseException extends Exception { 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); - } } diff --git a/SpigotCore_Main/src/de/steamwar/command/SWCommand.java b/SpigotCore_Main/src/de/steamwar/command/SWCommand.java index ae31780..ab72fc5 100644 --- a/SpigotCore_Main/src/de/steamwar/command/SWCommand.java +++ b/SpigotCore_Main/src/de/steamwar/command/SWCommand.java @@ -30,12 +30,13 @@ import java.util.*; import java.util.function.BiConsumer; import java.util.function.IntPredicate; import java.util.logging.Level; +import java.util.stream.Collectors; public abstract class SWCommand { private final Command command; - private final List commandSet = new ArrayList<>(); - private final List commandHelpSet = new ArrayList<>(); + private final List commandList = new ArrayList<>(); + private final List commandHelpList = new ArrayList<>(); private final Map> localTypeMapper = new HashMap<>(); protected SWCommand(String command) { @@ -46,58 +47,36 @@ public abstract class SWCommand { this.command = new Command(command, "", "/" + command, Arrays.asList(aliases)) { @Override public boolean execute(CommandSender sender, String alias, String[] args) { - for (SubCommand subCommand : commandSet) { - if (subCommand.invoke(sender, args)) { - return false; - } - } - for (SubCommand subCommand : commandHelpSet) { - if (subCommand.invoke(sender, args)) { - return false; - } - } + if (commandList.stream().anyMatch(s -> s.invoke(sender, args))) return false; + commandHelpList.stream().anyMatch(s -> s.invoke(sender, args)); return false; } @Override public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { - List strings = new ArrayList<>(); - for (SubCommand subCommand : commandSet) { - List tabCompletes = subCommand.tabComplete(sender, args); - if (tabCompletes != null) { - strings.addAll(tabCompletes); - } - } - strings = new ArrayList<>(strings); - 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; + String string = args[args.length - 1].toLowerCase(); + return commandList.stream() + .map(s -> s.tabComplete(sender, args)) + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .filter(s -> !s.isEmpty()) + .filter(s -> s.toLowerCase().startsWith(string)) + .collect(Collectors.toList()); } }; + unregister(); 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) -> { - if (anno.local()) { - localTypeMapper.put(anno.value(), typeMapper); - } else { - SWCommandUtils.addMapper(anno.value(), typeMapper); - } + (anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value(), typeMapper); }); addMapper(ClassMapper.class, method, i -> i == 0, false, TypeMapper.class, (anno, typeMapper) -> { - if (anno.local()) { - localTypeMapper.put(anno.value().getTypeName(), typeMapper); - } else { - SWCommandUtils.addMapper(anno.value().getTypeName(), typeMapper); - } + (anno.local() ? localTypeMapper : SWCommandUtils.MAPPER_FUNCTIONS).putIfAbsent(anno.value().getTypeName(), typeMapper); }); add(Register.class, method, i -> i > 0, true, null, (anno, parameters) -> { - if (!anno.help()) { - return; - } + if (!anno.help()) return; if (parameters.length != 2) { 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"); 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) -> { - if (anno.help()) { - return; - } + if (anno.help()) return; for (int i = 1; i < parameters.length; i++) { Parameter parameter = parameters[i]; Class clazz = parameter.getType(); @@ -126,37 +103,31 @@ public abstract class SWCommand { if (clazz.isEnum() && mapper == null && !SWCommandUtils.MAPPER_FUNCTIONS.containsKey(clazz.getTypeName())) { continue; } - String name = clazz.getTypeName(); - if (mapper != null) { - name = mapper.value(); - } + String name = mapper != null ? mapper.value() : clazz.getTypeName(); 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 + "'"); 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); if (compare != 0) { return compare; } else { - int i1 = o1.varArgType != null ? Integer.MAX_VALUE : o1.arguments.length; - int i2 = o2.varArgType != null ? Integer.MAX_VALUE : o2.arguments.length; - return Integer.compare(i1, i2); + return Integer.compare(o1.varArgType != null ? Integer.MAX_VALUE : o1.arguments.length, + o2.varArgType != null ? Integer.MAX_VALUE : o2.arguments.length); } }); - commandHelpSet.sort(Comparator.comparingInt(o -> -o.subCommand.length)); + commandHelpList.sort(Comparator.comparingInt(o -> -o.subCommand.length)); } } private void add(Class annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class returnType, BiConsumer consumer) { - T anno = SWCommandUtils.getAnnotation(method, annotation); - if (anno == null) { - return; - } + T[] anno = SWCommandUtils.getAnnotation(method, annotation); + if (anno == null || anno.length == 0) return; Parameter[] parameters = method.getParameters(); if (!parameterTester.test(parameters.length)) { @@ -171,15 +142,14 @@ public abstract class SWCommand { Bukkit.getLogger().log(Level.WARNING, "The method '" + method.toString() + "' is lacking the desired return type '" + returnType.getTypeName() + "'"); return; } - consumer.accept(anno, parameters); + Arrays.stream(anno).forEach(t -> consumer.accept(t, parameters)); } private void addMapper(Class annotation, Method method, IntPredicate parameterTester, boolean firstParameter, Class returnType, BiConsumer> consumer) { add(annotation, method, parameterTester, firstParameter, returnType, (anno, parameters) -> { try { method.setAccessible(true); - Object object = method.invoke(this); - consumer.accept(anno, (TypeMapper) object); + consumer.accept(anno, (TypeMapper) method.invoke(this)); } catch (Exception e) { throw new SecurityException(e.getMessage(), e); } @@ -188,9 +158,7 @@ public abstract class SWCommand { public void unregister() { SWCommandUtils.knownCommandMap.remove(command.getName()); - for (String alias : command.getAliases()) { - SWCommandUtils.knownCommandMap.remove(alias); - } + command.getAliases().forEach(SWCommandUtils.knownCommandMap::remove); command.unregister(SWCommandUtils.commandMap); } @@ -200,10 +168,17 @@ public abstract class SWCommand { @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) + @Repeatable(Register.Registeres.class) protected @interface Register { String[] value() default {}; boolean help() default false; + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.METHOD}) + @interface Registeres { + Register[] value(); + } } @Retention(RetentionPolicy.RUNTIME) diff --git a/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java b/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java index 0d09c7f..64c735d 100644 --- a/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java +++ b/SpigotCore_Main/src/de/steamwar/command/SWCommandUtils.java @@ -19,6 +19,7 @@ package de.steamwar.command; +import de.steamwar.sql.SteamwarUser; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.command.Command; @@ -50,10 +51,7 @@ public class SWCommandUtils { static final BiFunction>, String, Enum> ENUM_MAPPER = (enumClass, s) -> { Enum[] enums = enumClass.getEnumConstants(); - for (Enum e : enums) { - if (e.name().equalsIgnoreCase(s)) return e; - } - return null; + return Arrays.stream(enums).filter(e -> e.name().equalsIgnoreCase(s)).findFirst().orElse(null); }; static { @@ -61,6 +59,7 @@ public class SWCommandUtils { 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(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(Player.class.getTypeName(), createMapper(Bukkit::getPlayer, s -> Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()))); MAPPER_FUNCTIONS.put(GameMode.class.getTypeName(), createMapper(s -> { @@ -71,6 +70,7 @@ public class SWCommandUtils { if (s.equals("a") || s.equals("adventure") || s.equals("2")) return GameMode.ADVENTURE; return null; }, 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()))); } private static void addMapper(Class clazz, Class alternativeClazz, TypeMapper mapper) { @@ -104,37 +104,31 @@ public class SWCommandUtils { Object[] arguments = new Object[parameters.length + 1]; int index = 0; while (index < subCommand.length) { - if (!args[index].equalsIgnoreCase(subCommand[index])) { - throw new CommandParseException(); - } + if (!args[index].equalsIgnoreCase(subCommand[index])) throw new CommandParseException(); index++; } - if (varArgType != null && index > args.length - 1) { - Object varArgument = Array.newInstance(varArgType, 0); - arguments[arguments.length - 1] = varArgument; - } else { - 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]); + int length = 0; + if (varArgType != null) { + length = args.length - parameters.length - subCommand.length + 1; + arguments[arguments.length - 1] = Array.newInstance(varArgType, length); + if (index > args.length - 1) return arguments; + } + + 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) { + Object varArgument = arguments[arguments.length - 1]; + + for (int i = 0; i < length; i++) { + Object value = parameters[parameters.length - 1].map(commandSender, Arrays.copyOf(args, index), args[index]); + if (value == null) throw new CommandParseException(); + Array.set(varArgument, i, value); index++; - if (arguments[i + 1] == null) { - throw new CommandParseException(); - } - } - - if (varArgType != null) { - int length = args.length - parameters.length - subCommand.length + 1; - Object varArgument = Array.newInstance(varArgType, length); - arguments[arguments.length - 1] = varArgument; - - for (int i = 0; i < length; i++) { - Object value = parameters[parameters.length - 1].map(commandSender, Arrays.copyOf(args, index), args[index]); - if (value == null) { - throw new CommandParseException(); - } - Array.set(varArgument, i, value); - index++; - } } } return arguments; @@ -145,8 +139,7 @@ public class SWCommandUtils { } public static void addMapper(String name, TypeMapper mapper) { - if (MAPPER_FUNCTIONS.containsKey(name)) return; - MAPPER_FUNCTIONS.put(name, mapper); + MAPPER_FUNCTIONS.putIfAbsent(name, mapper); } public static TypeMapper createMapper(Function mapper, Function> tabCompleter) { @@ -178,18 +171,13 @@ public class SWCommandUtils { } private static Function> numberCompleter(Function mapper) { - return s -> { - try { - mapper.apply(s); - return Collections.singletonList(s); - } catch (Exception e) { - return Collections.emptyList(); - } - }; + return s -> numberMapper(mapper).apply(s) != null + ? Collections.singletonList(s) + : Collections.emptyList(); } - static T getAnnotation(Method method, Class annotation) { + static T[] getAnnotation(Method method, Class annotation) { if (method.getAnnotations().length != 1) return null; - return method.getAnnotation(annotation); + return method.getDeclaredAnnotationsByType(annotation); } } diff --git a/SpigotCore_Main/src/de/steamwar/command/SubCommand.java b/SpigotCore_Main/src/de/steamwar/command/SubCommand.java index 86cfdc7..15dad9a 100644 --- a/SpigotCore_Main/src/de/steamwar/command/SubCommand.java +++ b/SpigotCore_Main/src/de/steamwar/command/SubCommand.java @@ -28,6 +28,8 @@ import java.util.*; import java.util.function.Function; import java.util.function.Predicate; +import static de.steamwar.command.SWCommandUtils.*; + class SubCommand { private SWCommand swCommand; @@ -38,11 +40,7 @@ class SubCommand { private Function commandSenderFunction; Class varArgType = null; - public SubCommand(SWCommand swCommand, Method method, String[] subCommand) { - this(swCommand, method, subCommand, new HashMap<>()); - } - - public SubCommand(SWCommand swCommand, Method method, String[] subCommand, Map> localTypeMapper) { + SubCommand(SWCommand swCommand, Method method, String[] subCommand, Map> localTypeMapper) { this.swCommand = swCommand; this.method = method; @@ -61,13 +59,13 @@ class SubCommand { } 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> enumClass = (Class>) clazz; List tabCompletes = new ArrayList<>(); for (Enum enumConstant : enumClass.getEnumConstants()) { 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; } @@ -75,11 +73,9 @@ class SubCommand { if (mapper != null) { name = mapper.value(); } - if (localTypeMapper.containsKey(name)) { - arguments[i - 1] = localTypeMapper.getOrDefault(name, SWCommandUtils.ERROR_FUNCTION); - } else { - arguments[i - 1] = SWCommandUtils.MAPPER_FUNCTIONS.getOrDefault(name, SWCommandUtils.ERROR_FUNCTION); - } + arguments[i - 1] = localTypeMapper.containsKey(name) + ? localTypeMapper.get(name) + : MAPPER_FUNCTIONS.getOrDefault(name, ERROR_FUNCTION); } } @@ -120,7 +116,9 @@ class SubCommand { } for (TypeMapper argument : arguments) { 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 { if (argument.map(commandSender, Arrays.copyOf(args, index), s) == null) { return null; @@ -133,7 +131,9 @@ class SubCommand { if (varArgType != null && !argsList.isEmpty()) { while (!argsList.isEmpty()) { 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 { if (arguments[arguments.length - 1].map(commandSender, Arrays.copyOf(args, index), s) == null) { return null; diff --git a/SpigotCore_Main/src/de/steamwar/comms/BungeeReceiver.java b/SpigotCore_Main/src/de/steamwar/comms/BungeeReceiver.java index 96e9e3a..594e82b 100644 --- a/SpigotCore_Main/src/de/steamwar/comms/BungeeReceiver.java +++ b/SpigotCore_Main/src/de/steamwar/comms/BungeeReceiver.java @@ -51,6 +51,7 @@ public class BungeeReceiver implements PluginMessageListener { } }); + registerHandler(PacketIdManager.BAUMEMBER_UPDATE, byteArrayDataInput -> BauweltMember.clear()); registerHandler(PacketIdManager.INVENTORY_PACKET, new InventoryHandler()); registerHandler(PacketIdManager.INVENTORY_CLOSE_PACKET, byteArrayDataInput -> { Player player = Bukkit.getPlayer(SteamwarUser.get(byteArrayDataInput.readInt()).getUUID()); diff --git a/SpigotCore_Main/src/de/steamwar/comms/PacketIdManager.java b/SpigotCore_Main/src/de/steamwar/comms/PacketIdManager.java index 97a7d9b..b326674 100644 --- a/SpigotCore_Main/src/de/steamwar/comms/PacketIdManager.java +++ b/SpigotCore_Main/src/de/steamwar/comms/PacketIdManager.java @@ -25,6 +25,7 @@ public class PacketIdManager { public final static byte PING_PACKET = 0x01; public final static byte TABLIST_NAME = 0x02; public static final byte PREPARE_SCHEM = 0x03; + public final static byte BAUMEMBER_UPDATE = 0x04; //0x1(X) Bungee Inventory public final static byte INVENTORY_PACKET = 0x10; public final static byte INVENTORY_CALLBACK_PACKET = 0x11; diff --git a/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java b/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java index 4e0ed39..622b545 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java +++ b/SpigotCore_Main/src/de/steamwar/sql/BauweltMember.java @@ -34,6 +34,10 @@ public class BauweltMember{ private static final List members = new ArrayList<>(); + public static void clear() { + members.clear(); + } + private BauweltMember(int ownerID, int memberID, boolean worldEdit, boolean world, boolean updateDB){ bauweltID = ownerID; this.memberID = memberID; diff --git a/SpigotCore_Main/src/de/steamwar/sql/SWException.java b/SpigotCore_Main/src/de/steamwar/sql/SWException.java index 0bbfb8b..efee8ad 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/SWException.java +++ b/SpigotCore_Main/src/de/steamwar/sql/SWException.java @@ -35,7 +35,6 @@ public class SWException { static { List reasons = new ArrayList<>(); - reasons.add("Initializing Legacy Material Support."); reasons.add("Could not save the list after adding a user."); reasons.add("Could not save spigot.yml"); reasons.add("Failed to save operators list:"); @@ -68,6 +67,9 @@ public class SWException { reasons.add("Ignoring unknown attribute"); reasons.add("Skipping player strafe phase because no player was found"); reasons.add("Couldn't save chunk; already in use by another instance of Minecraft?"); + reasons.add("Failed to save player data for "); + reasons.add("Failed to check session lock for world located at"); + reasons.add("Saving oversized chunk "); ignorereasons = Collections.unmodifiableList(reasons); } diff --git a/SpigotCore_Main/src/de/steamwar/sql/UserConfig.java b/SpigotCore_Main/src/de/steamwar/sql/UserConfig.java new file mode 100644 index 0000000..b7a87c3 --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/sql/UserConfig.java @@ -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 . + */ + +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); + } + +}