diff --git a/CommandFramework-Old/build.gradle.kts b/CommandFramework-Old/build.gradle.kts new file mode 100644 index 00000000..61fbf34e --- /dev/null +++ b/CommandFramework-Old/build.gradle.kts @@ -0,0 +1,27 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +plugins { + steamwar.java +} + +dependencies { + testImplementation(libs.junit) + testImplementation(libs.hamcrest) +} \ No newline at end of file diff --git a/CommandFramework/src/de/steamwar/command/AbstractSWCommand.java b/CommandFramework-Old/src/de/steamwar/command/AbstractSWCommand.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/AbstractSWCommand.java rename to CommandFramework-Old/src/de/steamwar/command/AbstractSWCommand.java diff --git a/CommandFramework/src/de/steamwar/command/AbstractTypeMapper.java b/CommandFramework-Old/src/de/steamwar/command/AbstractTypeMapper.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/AbstractTypeMapper.java rename to CommandFramework-Old/src/de/steamwar/command/AbstractTypeMapper.java diff --git a/CommandFramework/src/de/steamwar/command/AbstractValidator.java b/CommandFramework-Old/src/de/steamwar/command/AbstractValidator.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/AbstractValidator.java rename to CommandFramework-Old/src/de/steamwar/command/AbstractValidator.java diff --git a/CommandFramework/src/de/steamwar/command/CommandFrameworkException.java b/CommandFramework-Old/src/de/steamwar/command/CommandFrameworkException.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/CommandFrameworkException.java rename to CommandFramework-Old/src/de/steamwar/command/CommandFrameworkException.java diff --git a/CommandFramework/src/de/steamwar/command/CommandMetaData.java b/CommandFramework-Old/src/de/steamwar/command/CommandMetaData.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/CommandMetaData.java rename to CommandFramework-Old/src/de/steamwar/command/CommandMetaData.java diff --git a/CommandFramework/src/de/steamwar/command/CommandParseException.java b/CommandFramework-Old/src/de/steamwar/command/CommandParseException.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/CommandParseException.java rename to CommandFramework-Old/src/de/steamwar/command/CommandParseException.java diff --git a/CommandFramework/src/de/steamwar/command/CommandPart.java b/CommandFramework-Old/src/de/steamwar/command/CommandPart.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/CommandPart.java rename to CommandFramework-Old/src/de/steamwar/command/CommandPart.java diff --git a/CommandFramework/src/de/steamwar/command/PreviousArguments.java b/CommandFramework-Old/src/de/steamwar/command/PreviousArguments.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/PreviousArguments.java rename to CommandFramework-Old/src/de/steamwar/command/PreviousArguments.java diff --git a/CommandFramework/src/de/steamwar/command/SWCommandUtils.java b/CommandFramework-Old/src/de/steamwar/command/SWCommandUtils.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/SWCommandUtils.java rename to CommandFramework-Old/src/de/steamwar/command/SWCommandUtils.java diff --git a/CommandFramework/src/de/steamwar/command/SWTypeMapperCreator.java b/CommandFramework-Old/src/de/steamwar/command/SWTypeMapperCreator.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/SWTypeMapperCreator.java rename to CommandFramework-Old/src/de/steamwar/command/SWTypeMapperCreator.java diff --git a/CommandFramework/src/de/steamwar/command/SubCommand.java b/CommandFramework-Old/src/de/steamwar/command/SubCommand.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/SubCommand.java rename to CommandFramework-Old/src/de/steamwar/command/SubCommand.java diff --git a/CommandFramework/src/de/steamwar/command/TabCompletionCache.java b/CommandFramework-Old/src/de/steamwar/command/TabCompletionCache.java similarity index 100% rename from CommandFramework/src/de/steamwar/command/TabCompletionCache.java rename to CommandFramework-Old/src/de/steamwar/command/TabCompletionCache.java diff --git a/CommandFramework/testsrc/de/steamwar/AssertionUtils.java b/CommandFramework-Old/testsrc/de/steamwar/AssertionUtils.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/AssertionUtils.java rename to CommandFramework-Old/testsrc/de/steamwar/AssertionUtils.java diff --git a/CommandFramework/testsrc/de/steamwar/command/ArgumentCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/ArgumentCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/ArgumentCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/ArgumentCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/ArgumentCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/ArgumentCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/ArgumentCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/ArgumentCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/BetterExceptionCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/BetterExceptionCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/BetterExceptionCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/BetterExceptionCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/BetterExceptionCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/BetterExceptionCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/BetterExceptionCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/BetterExceptionCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/CacheCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/CacheCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/CacheCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/CacheCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/CacheCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/CacheCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/CacheCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/CacheCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/NullMapperCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/NullMapperCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/NullMapperCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/NullMapperCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/NullMapperCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/NullMapperCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/NullMapperCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/NullMapperCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/NumberValidatorCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/NumberValidatorCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/NumberValidatorCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/NumberValidatorCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/NumberValidatorCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/NumberValidatorCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/NumberValidatorCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/NumberValidatorCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/PartOfCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/PartOfCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/PartOfCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/PartOfCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/PartOfCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/PartOfCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/PartOfCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/PartOfCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/PreviousArgumentCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/PreviousArgumentCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/PreviousArgumentCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/PreviousArgumentCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/PreviousArgumentCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/PreviousArgumentCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/PreviousArgumentCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/PreviousArgumentCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/SimpleCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/SimpleCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/SimpleCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/SimpleCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/SimpleCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/SimpleCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/SimpleCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/SimpleCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/StaticValueCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/StaticValueCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/StaticValueCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/StaticValueCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/StaticValueCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/StaticValueCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/StaticValueCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/StaticValueCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/SubCMDSortingCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/SubCMDSortingCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/SubCMDSortingCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/SubCMDSortingCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/SubCMDSortingCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/SubCMDSortingCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/SubCMDSortingCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/SubCMDSortingCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/TypeMapperCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/TypeMapperCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/TypeMapperCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/TypeMapperCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/TypeMapperCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/TypeMapperCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/TypeMapperCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/TypeMapperCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/ValidatorCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/ValidatorCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/ValidatorCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/ValidatorCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/ValidatorCommandTest.java b/CommandFramework-Old/testsrc/de/steamwar/command/ValidatorCommandTest.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/ValidatorCommandTest.java rename to CommandFramework-Old/testsrc/de/steamwar/command/ValidatorCommandTest.java diff --git a/CommandFramework/testsrc/de/steamwar/command/ValidatorInvertCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/ValidatorInvertCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/ValidatorInvertCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/ValidatorInvertCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/dto/ExecutionIdentifier.java b/CommandFramework-Old/testsrc/de/steamwar/command/dto/ExecutionIdentifier.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/dto/ExecutionIdentifier.java rename to CommandFramework-Old/testsrc/de/steamwar/command/dto/ExecutionIdentifier.java diff --git a/CommandFramework/testsrc/de/steamwar/command/dto/TestSWCommand.java b/CommandFramework-Old/testsrc/de/steamwar/command/dto/TestSWCommand.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/dto/TestSWCommand.java rename to CommandFramework-Old/testsrc/de/steamwar/command/dto/TestSWCommand.java diff --git a/CommandFramework/testsrc/de/steamwar/command/dto/TestTypeMapper.java b/CommandFramework-Old/testsrc/de/steamwar/command/dto/TestTypeMapper.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/dto/TestTypeMapper.java rename to CommandFramework-Old/testsrc/de/steamwar/command/dto/TestTypeMapper.java diff --git a/CommandFramework/testsrc/de/steamwar/command/dto/TestValidator.java b/CommandFramework-Old/testsrc/de/steamwar/command/dto/TestValidator.java similarity index 100% rename from CommandFramework/testsrc/de/steamwar/command/dto/TestValidator.java rename to CommandFramework-Old/testsrc/de/steamwar/command/dto/TestValidator.java diff --git a/CommandFramework/CommandFrameworkBase/build.gradle.kts b/CommandFramework/CommandFrameworkBase/build.gradle.kts new file mode 100644 index 00000000..fbe578e4 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/build.gradle.kts @@ -0,0 +1,27 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +plugins { + steamwar.java +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} \ No newline at end of file diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java new file mode 100644 index 00000000..2c297a97 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractCommand.java @@ -0,0 +1,216 @@ +/* + * 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.command; + +import de.steamwar.command.graph.NodeData; +import de.steamwar.command.graph.RootNode; +import de.steamwar.command.utils.Pair; +import de.steamwar.command.utils.Triple; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +public abstract class AbstractCommand { + + private static final Map>, Map, Function>> EXECUTOR_MAPPER = new HashMap<>(); + + public static void addExecutorMapper(Class> wrapper, Class executorType, Function mapper) { + EXECUTOR_MAPPER.computeIfAbsent(wrapper, __ -> new HashMap<>()) + .putIfAbsent(executorType, mapper); + } + + protected final String command; + protected final String permission; + private final Consumer> initializer; + protected final String[] aliases; + protected final List descriptions = new ArrayList<>(); + + private boolean initialized = false; + protected final RootNode rootNode = new RootNode<>(); + + private final Map> localTypeMapper = new HashMap<>(); + private final Map> localValidators = new HashMap<>(); + private final Map> localSupplier = new HashMap<>(); + + protected AbstractCommand(String command, Consumer> initializer, String... aliases) { + this(command, null, initializer, aliases); + } + + protected AbstractCommand(String command, String permission, Consumer> initializer, String... aliases) { + this.command = command; + this.permission = permission; + this.initializer = initializer; + this.aliases = aliases; + initCommand(); + unregister(); + register(); + } + + protected synchronized void initCommand() { + } + + public abstract void unregister(); + + public abstract void register(); + + protected void commandSystemError(T sender, CommandFrameworkException e) { + Logger.getGlobal().log(Level.WARNING, "An unexpected error occurred", e); + } + + protected void sendMessage(T sender, String message, Object[] args) { + } + + public final void execute(T sender, String alias, String[] args) { + initialize(); + List errors = new ArrayList<>(); + try { + boolean executed = rootNode.execute(sender, new NodeData(alias, fixArgs(args), (s, args1) -> { + errors.add(() -> sendMessage(sender, s, args1)); + })); + if (executed) return; + if (!errors.isEmpty()) { + errors.forEach(Runnable::run); + return; + } + descriptions.forEach(s -> sendMessage(sender, s, new Object[0])); + } catch (CommandFrameworkException e) { + commandSystemError(sender, e); + } + } + + public final List tabComplete(T sender, String alias, String[] args) throws IllegalArgumentException { + initialize(); + List> tabCompletes = new ArrayList<>(); + rootNode.tabComplete(sender, new NodeData(alias, fixArgs(args), (s, args1) -> {}), tabCompletes); + return tabCompletes.stream() + .filter(Objects::nonNull) + .flatMap(Collection::stream) + .filter(Objects::nonNull) + .filter(s -> !s.isEmpty()) + .distinct() + .collect(Collectors.toList()); + } + + private String[] fixArgs(String[] args) { + int removedCount = 0; + for (int i = 0; i < args.length; i++) { + String arg = args[i]; + if (arg.isEmpty() && i != args.length - 1) { + removedCount++; + continue; + } + args[i] = args[i - removedCount]; + } + if (removedCount != 0) { + args = Arrays.copyOf(args, args.length - removedCount); + } + if (args.length == 0) { + return new String[]{""}; + } + return args; + } + + private synchronized void initialize() { + if (initialized) return; + + List commandObjects = new ArrayList<>(); + initializer.accept(new CommandLoader<>() { + @Override + public AbstractCommand get() { + return AbstractCommand.this; + } + + @Override + public void add(Object command) { + commandObjects.add(command); + } + }); + + List> methods = new ArrayList<>(); + for (Object commandObject : commandObjects) { + DataImpl dataImpl = new DataImpl(this, commandObject, rootNode, EXECUTOR_MAPPER.getOrDefault(this.getClass(), Collections.emptyMap()), (Map) localTypeMapper, CommandUtils.MAPPER_FUNCTIONS, (Map) localValidators, CommandUtils.VALIDATOR_FUNCTIONS, (Map) localSupplier, CommandUtils.SUPPLIER_FUNCTIONS); + methods(commandObject).stream() + .filter(method -> Arrays.stream(method.getAnnotations()).anyMatch(anno -> anno.annotationType().isAnnotationPresent(Handler.Implementation.class))) + .forEach(method -> methods.add(new Pair<>(dataImpl, method))); + } + + Map, List>>> handlerMap = new HashMap<>(); + for (Pair commandMethod : methods) { + List annotations = CommandUtils.getAnnotations(commandMethod.b); + for (Annotation annotation : annotations) { + Handler.Implementation handler = annotation.annotationType().getAnnotation(Handler.Implementation.class); + Handler handlerObject; + try { + handlerObject = handler.value().getConstructor().newInstance(); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException e) { + throw new UnsupportedOperationException("Handler " + handler.value().getName() + " cannot be used to check the argument validity", e); + } + if (!(handlerObject instanceof Handler.HandlerMethod)) { + throw new UnsupportedOperationException("Handler " + handlerObject.getClass().getName() + " is not a HandlerMethod"); + } + handlerMap.computeIfAbsent(((Handler.HandlerMethod) handlerObject).getRunPriority(), k -> new LinkedHashMap<>()) + .computeIfAbsent(new Triple<>(commandMethod.a, commandMethod.b, annotation), k -> new ArrayList<>()) + .add((Handler.HandlerMethod) handlerObject); + } + } + + List runPriorities = new ArrayList<>(handlerMap.keySet()); + runPriorities.sort(Comparator.naturalOrder()); + for (int runPriority : runPriorities) { + handlerMap.get(runPriority).forEach((dataMethodAnnotationTriple, handlerMethods) -> { + handlerMethods.forEach(annotationHandlerMethod -> { + try { + annotationHandlerMethod.check(dataMethodAnnotationTriple.c, dataMethodAnnotationTriple.b, dataMethodAnnotationTriple.a); + } catch (Exception e) { + throw new UnsupportedOperationException("Method check failed for " + dataMethodAnnotationTriple.b.getName(), e); + } + annotationHandlerMethod.run(dataMethodAnnotationTriple.c, dataMethodAnnotationTriple.b, dataMethodAnnotationTriple.a); + }); + }); + } + rootNode.sort(); + initialized = true; + } + + // TODO: Implement this when Message System is ready + /* + public void addDefaultHelpMessage(String message) { + defaultHelpMessages.add(message); + } + */ + + private List methods(Object commandObject) { + List methods = new ArrayList<>(); + Class current = commandObject.getClass(); + while (current != null) { + methods.addAll(Arrays.asList(current.getDeclaredMethods())); + current = current.getSuperclass(); + } + return methods; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeMapper.java new file mode 100644 index 00000000..a9076eb1 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeMapper.java @@ -0,0 +1,48 @@ +/* + * 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.command; + +import java.util.Collection; + +public interface AbstractTypeMapper { + + /** + * The CommandSender can be null! + */ + T map(K sender, PreviousArguments previousArguments, String s); + + Collection tabComplete(K sender, PreviousArguments previousArguments, String s); + + /** + * @return true if the next element should be appended to the current tab complete. + */ + default boolean appendNextElementTabCompletions() { + return false; + } + + /** + * Normalize the cache key by sender and user provided argument.
+ * Note: The CommandSender can be null if the cache is defined as a global cache!
+ * Returning null and the empty string are equivalent. + */ + default String normalize(K sender, String s) { + return null; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeSupplier.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeSupplier.java new file mode 100644 index 00000000..b648a884 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeSupplier.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +public interface AbstractTypeSupplier { + + T get(K sender, PreviousArguments previousArguments); +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeValidator.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeValidator.java new file mode 100644 index 00000000..cb9de530 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/AbstractTypeValidator.java @@ -0,0 +1,62 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import java.util.function.BooleanSupplier; + +@FunctionalInterface +public interface AbstractTypeValidator { + + /** + * Validates the given value. + * + * @param sender The sender of the command. + * @param value The value to validate or null if mapping returned null. + * @param messageSender The message sender to send messages to the player. Never send messages directly to the player. + * @return The result of the validation. + */ + boolean validate(K sender, T value, MessageSender messageSender); + + default AbstractTypeValidator and(AbstractTypeValidator other) { + return (sender, value, messageSender) -> validate(sender, value, messageSender) && other.validate(sender, value, messageSender); + } + + default AbstractTypeValidator or(AbstractTypeValidator other) { + return (sender, value, messageSender) -> validate(sender, value, messageSender) || other.validate(sender, value, messageSender); + } + + default AbstractTypeValidator not() { + return (sender, value, messageSender) -> !validate(sender, value, messageSender); + } + + @FunctionalInterface + interface MessageSender { + void send(String s, Object... args); + + default boolean send(boolean condition, String s, Object... args) { + if (condition) send(s, args); + return condition; + } + + default boolean send(BooleanSupplier condition, String s, Object... args) { + return send(condition.getAsBoolean(), s, args); + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandFrameworkException.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandFrameworkException.java new file mode 100644 index 00000000..cf8e7ee3 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandFrameworkException.java @@ -0,0 +1,93 @@ +/* + * 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.command; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.function.Function; +import java.util.stream.Stream; + +public class CommandFrameworkException extends RuntimeException { + + private Function causeMessage; + private Throwable cause; + private Function stackTraceExtractor; + private String extraStackTraces; + + private String message; + + public CommandFrameworkException(InvocationTargetException invocationTargetException, String alias, String[] args) { + this(e -> { + StringBuilder st = new StringBuilder(); + st.append(e.getCause().getClass().getTypeName()); + if (e.getCause().getMessage() != null) { + st.append(": ").append(e.getCause().getMessage()); + } + if (alias != null && !alias.isEmpty()) { + st.append("\n").append("Performed command: " + alias + " " + String.join(" ", args)); + } + return st.toString(); + }, invocationTargetException, e -> { + StackTraceElement[] stackTraceElements = e.getCause().getStackTrace(); + return Arrays.stream(stackTraceElements).limit(stackTraceElements.length - e.getStackTrace().length); + }, null); + } + + private CommandFrameworkException(Function causeMessage, T cause, Function> stackTraceExtractor, String extraStackTraces) { + super(causeMessage.apply(cause), cause); + this.causeMessage = causeMessage; + this.cause = cause; + this.stackTraceExtractor = stackTraceExtractor; + this.extraStackTraces = extraStackTraces; + } + + public synchronized String getBuildStackTrace() { + if (message != null) { + return message; + } + StringBuilder st = new StringBuilder(); + st.append(causeMessage.apply(cause)).append("\n"); + ((Stream) stackTraceExtractor.apply(cause)).forEach(stackTraceElement -> { + st.append("\tat ").append(stackTraceElement.toString()).append("\n"); + }); + if (extraStackTraces != null) { + st.append("\tat ").append(extraStackTraces).append("\n"); + } + message = st.toString(); + return message; + } + + @Override + public void printStackTrace() { + printStackTrace(System.err); + } + + @Override + public void printStackTrace(PrintStream s) { + s.print(getBuildStackTrace()); + } + + @Override + public void printStackTrace(PrintWriter s) { + s.print(getBuildStackTrace()); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandLoader.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandLoader.java new file mode 100644 index 00000000..b937eba6 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandLoader.java @@ -0,0 +1,26 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +public interface CommandLoader { + + AbstractCommand get(); + void add(Object command); +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandUtils.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandUtils.java new file mode 100644 index 00000000..be9dc2e0 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/CommandUtils.java @@ -0,0 +1,148 @@ +/* + * 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.command; + +import de.steamwar.command.mapper.BooleanMapper; +import de.steamwar.command.mapper.NumberMapper; +import lombok.experimental.UtilityClass; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Repeatable; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.util.*; +import java.util.function.ToIntFunction; + +@UtilityClass +public class CommandUtils { + + final Map> MAPPER_FUNCTIONS = new HashMap<>(); + + final Map> VALIDATOR_FUNCTIONS = new HashMap<>(); + + final Map> SUPPLIER_FUNCTIONS = new HashMap<>(); + + static final AbstractTypeMapper STRING_MAPPER = new AbstractTypeMapper<>() { + @Override + public String map(Object sender, PreviousArguments previousArguments, String s) { + return s; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + + static { + addMapper(boolean.class, Boolean.class, new BooleanMapper()); + addMapper(int.class, Integer.class, new NumberMapper(Integer::parseInt, false)); + addMapper(long.class, Long.class, new NumberMapper(Long::parseLong, false)); + addMapper(float.class, Float.class, new NumberMapper(Float::parseFloat, true)); + addMapper(double.class, Double.class, new NumberMapper(Double::parseDouble, true)); + MAPPER_FUNCTIONS.put(String.class.getTypeName(), STRING_MAPPER); + } + + private static void addMapper(Class clazz, Class alternativeClazz, AbstractTypeMapper mapper) { + MAPPER_FUNCTIONS.put(clazz.getTypeName(), mapper); + MAPPER_FUNCTIONS.put(alternativeClazz.getTypeName(), mapper); + } + + public static void addMapper(Class clazz, AbstractTypeMapper mapper) { + addMapper(clazz.getTypeName(), mapper); + } + + public static void addMapper(String name, AbstractTypeMapper mapper) { + MAPPER_FUNCTIONS.putIfAbsent(name, mapper); + } + + public static void addValidator(Class clazz, AbstractTypeValidator validator) { + addValidator(clazz.getTypeName(), validator); + } + + public static void addValidator(String name, AbstractTypeValidator validator) { + VALIDATOR_FUNCTIONS.putIfAbsent(name, validator); + } + + public static void addSupplier(Class clazz, AbstractTypeSupplier supplier) { + addSupplier(clazz.getTypeName(), supplier); + } + + public static void addSupplier(String name, AbstractTypeSupplier supplier) { + SUPPLIER_FUNCTIONS.putIfAbsent(name, supplier); + } + + public static List getAnnotations(AnnotatedElement annotatedElement) { + List annotationList = new ArrayList<>(); + for (Annotation annotation : annotatedElement.getAnnotations()) { + try { + Method method = annotation.annotationType().getMethod("value"); + Class returnType = method.getReturnType(); + if (!returnType.isArray()) { + annotationList.add(annotation); + continue; + } + Class innerReturnType = returnType.getComponentType(); + if (!(innerReturnType.isAnnotation() && innerReturnType.isAnnotationPresent(Repeatable.class))) { + annotationList.add(annotation); + continue; + } + Repeatable repeatable = innerReturnType.getAnnotation(Repeatable.class); + Class containerType = repeatable.value(); + if (containerType == returnType) { + throw new UnsupportedOperationException("Repeatable annotation must have a container annotation"); + } + try { + Annotation[] innerAnnotations = (Annotation[]) method.invoke(annotation); + Collections.addAll(annotationList, innerAnnotations); + } catch (Exception e) { + annotationList.add(annotation); + } + } catch (NoSuchMethodException e) { + annotationList.add(annotation); + } + } + annotationList.removeIf(anno -> !anno.annotationType().isAnnotationPresent(Handler.Implementation.class)); + return annotationList; + } + + public static List getAnnotations(AnnotatedElement annotatedElement, Class type) { + List annotations = getAnnotations(annotatedElement); + annotations.removeIf(annotation -> { + Handler.Implementation implementation = annotation.annotationType().getAnnotation(Handler.Implementation.class); + return implementation == null || !type.isAssignableFrom(implementation.value()); + }); + return annotations; + } + + public static ToIntFunction createComparator(String type, Class clazz, int iValue, long lValue, float fValue, double dValue) { + if (clazz == int.class || clazz == Integer.class) { + return number -> Integer.compare(number.intValue(), iValue); + } else if (clazz == long.class || clazz == Long.class) { + return number -> Long.compare(number.longValue(), lValue); + } else if (clazz == float.class || clazz == Float.class) { + return number -> Float.compare(number.floatValue(), fValue); + } else if (clazz == double.class || clazz == Double.class) { + return number -> Double.compare(number.doubleValue(), dValue); + } else { + throw new IllegalArgumentException(type + " annotation is not supported for " + clazz); + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/DataImpl.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/DataImpl.java new file mode 100644 index 00000000..ba0d8800 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/DataImpl.java @@ -0,0 +1,186 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import de.steamwar.command.annotations.Supplier; +import de.steamwar.command.graph.*; +import de.steamwar.command.handler.GreedyHandler; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +class DataImpl implements Handler.DataCheckable, Handler.DataReadable, Handler.DataWritable { + + private final AbstractCommand container; + private final Object self; + private final RootNode node; + private final Map, Function> executorMapper; + private final Map> mapper; + private final Map> globalMapper; + private final Map> validator; + private final Map> globalValidator; + private final Map> supplier; + private final Map> globalSupplier; + + private final Map cache = new HashMap<>(); + + DataImpl(AbstractCommand container, Object self, RootNode node, Map, Function> executorMapper, Map> mapper, Map> globalMapper, Map> validator, Map> globalValidator, Map> supplier, Map> globalSupplier) { + this.container = container; + this.self = self; + this.node = node; + this.executorMapper = executorMapper; + this.mapper = mapper; + this.globalMapper = globalMapper; + this.validator = validator; + this.globalValidator = globalValidator; + this.supplier = supplier; + this.globalSupplier = globalSupplier; + } + + @Override + public boolean hasExecutorMapper(Class clazz) { + return getExecutorMapper(clazz) != null; + } + + @Override + public Function getExecutorMapper(Class clazz) { + for (Map.Entry, Function> entry : executorMapper.entrySet()) { + if (entry.getKey().isAssignableFrom(clazz)) { + return entry.getValue(); + } + } + return null; + } + + @Override + public boolean hasMapper(String key) { + return mapper.containsKey(key) || globalMapper.containsKey(key); + } + + @Override + public AbstractTypeMapper getMapper(String key) { + return (AbstractTypeMapper) mapper.getOrDefault(key, globalMapper.get(key)); + } + + @Override + public void addMapper(String key, boolean local, AbstractTypeMapper mapper) { + if (local) { + this.mapper.put(key, mapper); + } else { + this.globalMapper.putIfAbsent(key, mapper); + } + } + + @Override + public boolean hasValidator(String key) { + return validator.containsKey(key) || globalValidator.containsKey(key); + } + + @Override + public AbstractTypeValidator getValidator(String key) { + return (AbstractTypeValidator) validator.getOrDefault(key, globalValidator.get(key)); + } + + @Override + public void addValidator(String key, boolean local, AbstractTypeValidator validator) { + if (local) { + this.validator.put(key, validator); + } else { + this.globalValidator.putIfAbsent(key, validator); + } + } + + @Override + public boolean hasSupplier(String key) { + return supplier.containsKey(key) || globalSupplier.containsKey(key); + } + + @Override + public AbstractTypeSupplier getSupplier(String key) { + return (AbstractTypeSupplier) supplier.getOrDefault(key, globalSupplier.get(key)); + } + + @Override + public void addSupplier(String key, boolean local, AbstractTypeSupplier supplier) { + if (local) { + this.supplier.put(key, supplier); + } else { + this.globalSupplier.putIfAbsent(key, supplier); + } + } + + /** + * Invoking the same method twice will result in the exact same result. + */ + @Override + public T invoke(Method method) { + return (T) cache.computeIfAbsent(method, m -> { + try { + return m.invoke(self); + } catch (IllegalAccessException | InvocationTargetException e) { + return null; + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } + + @Override + public void addCommand(Method method, String[] subCommand, String[] description, boolean noTabComplete) { + Node temp = node; + container.descriptions.addAll(Arrays.asList(description)); + if (noTabComplete) { + temp = temp.addChild(null, new NoTabCompleteNode<>()); + } + for (int i = 0; i < subCommand.length; i++) { + temp = temp.addChild(null, new LiteralNode<>(subCommand[i])); + } + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + if (i == 0) { + temp = temp.addChild(parameter, new ExecutorTypeNode<>(parameter, i, this)); + continue; + } + if (parameter.isAnnotationPresent(Supplier.class)) { + temp = temp.addChild(parameter, new SupplierNode<>(parameter, this)); + continue; + } + Class type = parameter.getType(); + boolean isArray = parameter.isVarArgs() || type.isArray(); + if (!isArray) { + temp = temp.addChild(parameter, new TypeNode<>(parameter, i, this)); + continue; + } + boolean greedy = parameter.isVarArgs() || GreedyHandler.isGreedy(parameter); + if (greedy) { + temp = temp.addChild(parameter, new GreedyArrayNode<>(parameter, i, this)); + } else { + temp = temp.addChild(parameter, new NonGreedyArrayNode<>(parameter, i, this)); + } + } + temp.addChild(null, new ExecuteNode<>(self, method)); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java new file mode 100644 index 00000000..667c0375 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/Handler.java @@ -0,0 +1,121 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import java.lang.annotation.*; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Optional; +import java.util.function.Function; + +public interface Handler { + + default Optional> getGenericTypeOfReturn(Method method) { + Type type; + try { + type = method.getGenericReturnType(); + } catch (Exception e) { + return Optional.empty(); + } + if (!(type instanceof ParameterizedType)) { + return Optional.empty(); + } + ParameterizedType parameterizedType = (ParameterizedType) type; + Type[] generics = parameterizedType.getActualTypeArguments(); + if (generics.length != 1 && generics.length != 2) { + return Optional.empty(); + } + Type genericType = generics[generics.length - 1]; + try { + return Optional.of(Class.forName(genericType.getTypeName())); + } catch (Exception e) { + return Optional.empty(); + } + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.ANNOTATION_TYPE) + @interface Implementation { + Class value(); + } + + interface DataCheckable { + boolean hasExecutorMapper(Class clazz); + boolean hasMapper(String key); + boolean hasValidator(String key); + boolean hasSupplier(String key); + } + + interface DataReadable { + Function getExecutorMapper(Class clazz); + AbstractTypeMapper getMapper(String key); + AbstractTypeValidator getValidator(String key); + AbstractTypeSupplier getSupplier(String key); + } + + interface DataWritable { + Function getExecutorMapper(Class clazz); + + void addMapper(String key, boolean local, AbstractTypeMapper mapper); + void addValidator(String key, boolean local, AbstractTypeValidator validator); + void addSupplier(String key, boolean local, AbstractTypeSupplier supplier); + /** + * Invoking the same method twice will result in the exact same result. + */ + T invoke(Method method); + void addCommand(Method method, String[] subCommand, String[] description, boolean noTabComplete); + } + + interface HandlerMethod extends Handler { + void check(T annotation, Method method, DataCheckable dataCheckable) throws Exception; + + int getRunPriority(); + + void run(T annotation, Method method, DataWritable dataWritable); + } + + interface HandlerParameter extends Handler { + void check(T annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception; + + default boolean needsParentTypeMapper() { + return false; + } + + /** + * Null values are allowed to be returned. + */ + default AbstractTypeMapper getTypeMapper(T annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + return null; + } + + default int getValidatorPriority() { + return 0; + } + + /** + * Null values are allowed to be returned. + */ + default AbstractTypeValidator getValidator(T annotation, Parameter parameter, int index, DataReadable dataReadable) { + return null; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/OptionEnum.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/OptionEnum.java new file mode 100644 index 00000000..69c6b1b8 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/OptionEnum.java @@ -0,0 +1,30 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import java.util.Arrays; +import java.util.List; + +public interface OptionEnum & OptionEnum> { + default List getTabCompletes() { + return Arrays.asList("-" + ((T) this).name().toLowerCase()); + } + T[] getRemoved(); +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/PreviousArguments.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/PreviousArguments.java new file mode 100644 index 00000000..6458c6c1 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/PreviousArguments.java @@ -0,0 +1,96 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2022 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import lombok.NonNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +public class PreviousArguments { + + public final String[] userArgs; + public final Object[] mappedArgs; + public final boolean hasMoreArguments; + private final Function getByNameFunction; + private boolean usedOptionalValue = false; + + public PreviousArguments(String[] userArgs, Object[] mappedArgs, boolean hasMoreArguments, Function getByNameFunction) { + this.userArgs = userArgs; + this.mappedArgs = mappedArgs; + this.hasMoreArguments = hasMoreArguments; + this.getByNameFunction = getByNameFunction; + } + + public boolean hasUsedOptionalValue() { + return usedOptionalValue; + } + + public void usedOptionalValue() { + this.usedOptionalValue = true; + } + + public String getUserArg(int index) { + return userArgs[userArgs.length - index - 1]; + } + + public T getMappedArg(int index) { + return (T) mappedArgs[mappedArgs.length - index - 1]; + } + + public Optional getFirst(Class clazz) { + for (Object o : mappedArgs) { + if (clazz.isInstance(o)) { + return Optional.of((T) o); + } + } + return Optional.empty(); + } + + public List getAll(Class clazz) { + List list = new ArrayList<>(); + for (Object o : mappedArgs) { + if (clazz.isInstance(o)) { + list.add((T) o); + } + if (o == null) { + continue; + } + if (o.getClass().isArray()) { + Object[] array = (Object[]) o; + if (array.length == 0) { + continue; + } + for (Object o1 : array) { + if (clazz.isInstance(o1)) { + list.add((T) o1); + } + } + } + } + return list; + } + + public T getByName(@NonNull String name) { + return (T) getByNameFunction.apply(name); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/TabCompletionCache.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/TabCompletionCache.java new file mode 100644 index 00000000..231b5116 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/TabCompletionCache.java @@ -0,0 +1,109 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import de.steamwar.command.mapper.internal.DelegatingMapper; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.experimental.UtilityClass; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +@UtilityClass +public class TabCompletionCache { + + private final Map tabCompletionCache = new ConcurrentHashMap<>(); + + Set> cached = new HashSet<>(); + Set> global = new HashSet<>(); + Map, Long> cacheDuration = new HashMap<>(); + + static { + Thread thread = new Thread(() -> { + while (true) { + Set toRemove = new HashSet<>(); + for (Map.Entry tabCompletionsEntry : tabCompletionCache.entrySet()) { + if (System.currentTimeMillis() - tabCompletionsEntry.getValue().timestamp > cacheDuration.get(tabCompletionsEntry.getKey().typeMapper)) { + toRemove.add(tabCompletionsEntry.getKey()); + } + } + for (Key key : toRemove) { + tabCompletionCache.remove(key); + } + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + }); + thread.setName("TabCompletionCache Invalidator"); + thread.setDaemon(true); + thread.start(); + } + + public void add(AbstractTypeMapper typeMapper, boolean global, long cacheDuration, TimeUnit timeUnit) { + TabCompletionCache.cached.add(typeMapper); + if (global) TabCompletionCache.global.add(typeMapper); + TabCompletionCache.cacheDuration.put(typeMapper, timeUnit.toMillis(cacheDuration)); + } + + public AbstractTypeMapper cached(AbstractTypeMapper dataMapper, AbstractTypeMapper toBeCached) { + if (!cached.contains(dataMapper)) return toBeCached; + boolean global = TabCompletionCache.global.contains(dataMapper); + long cacheDuration = TabCompletionCache.cacheDuration.get(dataMapper); + + return new DelegatingMapper<>(toBeCached, null) { + @Override + public Collection tabComplete(A sender, PreviousArguments previousArguments, String s) { + String normalizedArg = dataMapper.normalize(global ? null : sender, s); + if (normalizedArg == null) normalizedArg = ""; + Key key = new Key(global ? null : sender, normalizedArg, dataMapper); + + TabCompletions tabCompletions = tabCompletionCache.computeIfAbsent(key, ignore -> { + return new TabCompletions(System.currentTimeMillis(), toBeCached.tabComplete(sender, previousArguments, s)); + }); + + if (System.currentTimeMillis() - tabCompletions.timestamp > cacheDuration) { + tabCompletions.tabCompletions = toBeCached.tabComplete(sender, previousArguments, s); + } + tabCompletions.timestamp = System.currentTimeMillis(); + return tabCompletions.tabCompletions; + } + }; + } + + @EqualsAndHashCode + @AllArgsConstructor + private static class Key { + private Object sender; + private String arg; + private AbstractTypeMapper typeMapper; + } + + @AllArgsConstructor + private static class TabCompletions { + private long timestamp; + private Collection tabCompletions; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/AllowNull.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/AllowNull.java new file mode 100644 index 00000000..944b96e8 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/AllowNull.java @@ -0,0 +1,37 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.AllowNullHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to allow null values passed to the command. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(AllowNullHandler.Impl.class) +public @interface AllowNull { +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ArrayLength.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ArrayLength.java new file mode 100644 index 00000000..3398f695 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ArrayLength.java @@ -0,0 +1,53 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.ArrayLengthHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define a minimum and maximum length the supplied array can have. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(ArrayLengthHandler.Impl.class) +public @interface ArrayLength { + /** + * Inclusive + */ + int min() default 0; + + /** + * Inclusive + */ + int max() default Integer.MAX_VALUE; + + /** + * Error message if too few Elements got parsed. There are 2 arguments provided to the message. + * The first is the number of elements that got parsed as a number and the second one is how many + * should have been parsed, so the min number of elements expected. + */ + String error() default ""; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Cached.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Cached.java new file mode 100644 index 00000000..d0940384 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Cached.java @@ -0,0 +1,52 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.handler.CachedHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.concurrent.TimeUnit; + +/** + * This annotation is used to register a or {@link Mapper} + * on registration as being cached. Only TabCompletions are cached for the duration + * denoted by {@link #timeUnit()} and {@link #cacheDuration()} using + * {@link TimeUnit#toMillis(long)}. If {@link #global()} is {@code true}, the + * cache will not be created per player but for everyone. This is useful for + * commands that are not player specific. + *

+ * To calculate the cache key for a {@link AbstractTypeMapper} the + * {@link AbstractTypeMapper#normalize(Object, String)} method is called. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +@Handler.Implementation(CachedHandler.Impl.class) +public @interface Cached { + long cacheDuration() default 5; + + TimeUnit timeUnit() default TimeUnit.SECONDS; + + boolean global() default false; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ClassMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ClassMapper.java new file mode 100644 index 00000000..3743b24d --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ClassMapper.java @@ -0,0 +1,56 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.handler.ClassMapperHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for registering a method as a class mapper. + * The annotated method will be executed while {@link #initialize()} + * is evaluated. The result of this method will be cached under the + * name {@link ClassMapper#value()} converted to a {@link String} using + * {@link Class#getTypeName()}. {@link AbstractTypeMapper} will be used + * as the default mapper if the type this mapper is registered for is + * found as a parameter of any command method annotated with {@link Register}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +@Handler.Implementation(ClassMapperHandler.Impl.class) +@Deprecated +@DeprecationInfo("Use @Mapper instead") +public @interface ClassMapper { + + /** + * The type this mapper is registered for. + */ + Class value(); + + /** + * If {@code true}, the mapper will only be used in the current command class. + */ + boolean local() default true; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ClassValidator.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ClassValidator.java new file mode 100644 index 00000000..86fc23a4 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ClassValidator.java @@ -0,0 +1,53 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.ClassValidatorHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for registering a method as a class validator. + * The annotated method will be executed while {@link #initialize()} + * is evaluated. The result of this method will be cached under the + * name {@link ClassValidator#value()} converted to a {@link String} using + * {@link Class#getTypeName()}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +@Handler.Implementation(ClassValidatorHandler.Impl.class) +@Deprecated +@DeprecationInfo("Use @Validator instead") +public @interface ClassValidator { + + /** + * The type this validator is registered for. + */ + Class value(); + + /** + * If {@code true}, the validator will only be used in the current command class. + */ + boolean local() default true; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/DeprecationInfo.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/DeprecationInfo.java new file mode 100644 index 00000000..9877b162 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/DeprecationInfo.java @@ -0,0 +1,28 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface DeprecationInfo { + String value(); +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/EndsWith.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/EndsWith.java new file mode 100644 index 00000000..5537359d --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/EndsWith.java @@ -0,0 +1,38 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.EndsWithHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(EndsWithHandler.Impl.class) +public @interface EndsWith { + + String value(); + + String error() default ""; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ErrorMessage.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ErrorMessage.java new file mode 100644 index 00000000..6d77133e --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/ErrorMessage.java @@ -0,0 +1,48 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.ErrorMessageHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define an error message for a parameter. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(ErrorMessageHandler.Impl.class) +public @interface ErrorMessage { + /** + * Error message to be displayed when the parameter is invalid. + */ + String value(); + + /** + * This is the short form for 'allowEmptyArrays'. + */ + @Deprecated + @DeprecationInfo("Use @ArrayLength instead of this flag") + boolean allowEAs() default true; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Greedy.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Greedy.java new file mode 100644 index 00000000..59102376 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Greedy.java @@ -0,0 +1,46 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.GreedyHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation can have a huge performance impact. Both positive and negative. + * You can design your command to be more flexible and allow performance improvements if used correctly. + *

+ * The more restrictive the underlying array type is, the more performance can be gained. + *

+ * Using this annotation on the varargs parameter of a command will not have any effect, since they are already treated as greedy arrays. + *

+ * The {@link #backTrackingDepth()} can be used to limit the amount of backtracking that is done. This can be used to improve performance. + * For varargs parameters, this value is defaulted to 0, since they are at the end of the parameter list. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(GreedyHandler.Impl.class) +public @interface Greedy { + int backTrackingDepth() default Integer.MAX_VALUE; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Length.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Length.java new file mode 100644 index 00000000..f48d9265 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Length.java @@ -0,0 +1,46 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.LengthHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define a minimum and maximum length the supplied string can have. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(LengthHandler.Impl.class) +public @interface Length { + /** + * Inclusive + */ + int min() default 0; + + /** + * Inclusive + */ + int max() default Integer.MAX_VALUE; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Mapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Mapper.java new file mode 100644 index 00000000..0fd84fa5 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Mapper.java @@ -0,0 +1,58 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.handler.MapperHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation for registering a method as a mapper. The annotated method will + * be executed while {@link #initialize()} is evaluated. The result of this + * method will be cached under either {@link Mapper#value()} or {@link Mapper#value()}. + * If {@link Mapper#type()} is used any parameter using that type will be using + * this {@link AbstractTypeMapper} implicitly. While using this annotation on + * a method it can be possible to not supply any type. On a parameter you can + * only use this annotation using the {@link Mapper#value()} value. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER, ElementType.METHOD}) +@Handler.Implementation(MapperHandler.Impl.class) +public @interface Mapper { + /** + * The name this mapper is registered for. + */ + String value() default ""; + + /** + * The type this mapper is registered for. + */ + Class type() default void.class; + + /** + * If {@code true}, the mapper will only be used in the current command class. + */ + boolean local() default true; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Max.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Max.java new file mode 100644 index 00000000..ff792c0b --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Max.java @@ -0,0 +1,70 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.MaxHandler; +import de.steamwar.command.handler.MaxReferenceHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define a maximum number value for a parameter. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(MaxHandler.Impl.class) +public @interface Max { + int intValue() default Integer.MAX_VALUE; + + long longValue() default Long.MAX_VALUE; + + float floatValue() default Float.MAX_VALUE; + + double doubleValue() default Double.MAX_VALUE; + + boolean inclusive() default true; + + /** + * Error message to be displayed when the argument supplied is bigger than this allows. + * Two arguments are supplied to the error message. The first is the number that got parsed + * and the second is the max this annotation allows. + */ + String error() default ""; + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + @Handler.Implementation(MaxReferenceHandler.Impl.class) + @interface Reference { + String value(); + + boolean inclusive() default true; + + /** + * Error message to be displayed when the argument supplied is smaller than this allows. + * Two arguments are supplied to the error message. The first is the number that got parsed + * and the second is the min this annotation allows. + */ + String error() default ""; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Min.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Min.java new file mode 100644 index 00000000..41edc8b4 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Min.java @@ -0,0 +1,70 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.MinHandler; +import de.steamwar.command.handler.MinReferenceHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define a minimum number value for a parameter. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(MinHandler.Impl.class) +public @interface Min { + int intValue() default Integer.MIN_VALUE; + + long longValue() default Long.MIN_VALUE; + + float floatValue() default Float.MIN_VALUE; + + double doubleValue() default Double.MIN_VALUE; + + boolean inclusive() default true; + + /** + * Error message to be displayed when the argument supplied is smaller than this allows. + * Two arguments are supplied to the error message. The first is the number that got parsed + * and the second is the min this annotation allows. + */ + String error() default ""; + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + @Handler.Implementation(MinReferenceHandler.Impl.class) + @interface Reference { + String value(); + + boolean inclusive() default true; + + /** + * Error message to be displayed when the argument supplied is smaller than this allows. + * Two arguments are supplied to the error message. The first is the number that got parsed + * and the second is the min this annotation allows. + */ + String error() default ""; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Name.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Name.java new file mode 100644 index 00000000..a1dbfa73 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Name.java @@ -0,0 +1,31 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +public @interface Name { + String value(); +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/OptionalValue.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/OptionalValue.java new file mode 100644 index 00000000..d893218b --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/OptionalValue.java @@ -0,0 +1,46 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.OptionalValueHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define a default value for a parameter. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(OptionalValueHandler.Impl.class) +public @interface OptionalValue { + /** + * Will pe parsed against the TypeMapper specified by the parameter or annotation. + */ + String value(); + + /** + * The method name stands for 'onlyUseIfNoneIsGiven'. + */ + boolean onlyUINIG() default false; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Regex.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Regex.java new file mode 100644 index 00000000..7c261781 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Regex.java @@ -0,0 +1,38 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.RegexHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(RegexHandler.Impl.class) +public @interface Regex { + + String value(); + + String error() default ""; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Register.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Register.java new file mode 100644 index 00000000..8483bf83 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Register.java @@ -0,0 +1,57 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.RegisterHandler; + +import java.lang.annotation.*; + +/** + * Annotation for registering a method as a command. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +@Repeatable(Register.Registers.class) +@Handler.Implementation(RegisterHandler.Impl.class) +public @interface Register { + + /** + * Identifier of subcommand. + */ + String[] value() default {}; + + /** + * Description of subcommand. + */ + String[] description() default {}; + + /** + * If {@code true}, the command will not be tab completed. + */ + boolean noTabComplete() default false; + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.METHOD}) + @Handler.Implementation(RegisterHandler.Impl.class) + @interface Registers { + Register[] value(); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/StartsWith.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/StartsWith.java new file mode 100644 index 00000000..9f1af0a8 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/StartsWith.java @@ -0,0 +1,38 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.StartsWithHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(StartsWithHandler.Impl.class) +public @interface StartsWith { + + String value(); + + String error() default ""; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/StaticValue.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/StaticValue.java new file mode 100644 index 00000000..7eefa873 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/StaticValue.java @@ -0,0 +1,58 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.StaticValueHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define static values for a parameter like an enum just without the enum. + * You can use this annotation on a parameter of type {@link String} or {@link int}, {@link long} and + * {@link boolean}. While using an int, the value will represent the index into the value array. While + * using a boolean, the {@link #falseValues()} defines which indices are considered {@code false} or + * {@code true}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(StaticValueHandler.Impl.class) +@Deprecated +@DeprecationInfo("Use @Values instead") +public @interface StaticValue { + String[] value(); + + /** + * This is the short form for 'allowImplicitSwitchExpressions' + * and can be set to true if you want to allow int as well as boolean as annotated parameter types. + * The value array needs to be at least 2 long for this flag to be considered. + * While using an int, the value will represent the index into the value array. + * While using a boolean, the {@link #falseValues()} defines which indices are + * considered {@code false} or {@code true}. + */ + @Deprecated + @DeprecationInfo("Dont need to set this to true") + boolean allowISE() default false; + + int[] falseValues() default {0}; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Supplier.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Supplier.java new file mode 100644 index 00000000..b0b7b2f8 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Supplier.java @@ -0,0 +1,48 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.SupplierHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER, ElementType.METHOD}) +@Handler.Implementation(SupplierHandler.Impl.class) +public @interface Supplier { + /** + * The name this supplier is registered for. + */ + String value() default ""; + + /** + * The type this supplier is registered for. + */ + Class type() default void.class; + + /** + * If {@code true}, the supplier will only be used in the current command class. + */ + boolean local() default true; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/TabFilter.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/TabFilter.java new file mode 100644 index 00000000..3d0e9af1 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/TabFilter.java @@ -0,0 +1,40 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.TabFilterHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation defines per Parameter how the TabCompletions should be filtered and displayed by the client. + * There are 3 modes further described by {@link TabFilterType}. If this annotation is not present the default + * {@link TabFilterType#STARTS_WITH} is used. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(TabFilterHandler.Impl.class) +public @interface TabFilter { + TabFilterType value(); +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/TabFilterType.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/TabFilterType.java new file mode 100644 index 00000000..af9ef427 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/TabFilterType.java @@ -0,0 +1,41 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +public enum TabFilterType { + + /** + * This value defines that, the starts with tab-completion filter is used.
+ * see: {@link de.steamwar.command.mapper.internal.StartsWithFilter} for more. + */ + STARTS_WITH, + + /** + * This value defines that, the contains tab-completions filter is used. + * see: {@link de.steamwar.command.mapper.internal.ContainsFilter} for more. + */ + CONTAINS, + + /** + * This value disables any tab-completion filters and just returns anything you + * specified inside the TypeMapper. + */ + NONE +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Unique.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Unique.java new file mode 100644 index 00000000..ae25575c --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Unique.java @@ -0,0 +1,37 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.UniqueHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define an array with unique values. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(UniqueHandler.Impl.class) +public @interface Unique { +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Validator.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Validator.java new file mode 100644 index 00000000..2b2e9f49 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Validator.java @@ -0,0 +1,68 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.ValidatorHandler; + +import java.lang.annotation.*; + +/** + * Annotation for registering a method as a validator. + * The annotated method will be executed while {@link #initialize()} + * is evaluated. The result of this method will be cached under the + * name {@link ClassValidator#value()} converted to a {@link String} using + * {@link Class#getTypeName()}. + * This annotation can also be used on parameters to apply a validator to them. + * You can leave the {@link #value()} empty here to use the type of the parameter. + * For registering you should never leave {@link #value()} empty. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER, ElementType.METHOD}) +@Handler.Implementation(ValidatorHandler.Impl.class) +@Repeatable(Validator.Validators.class) +public @interface Validator { + /** + * The name this validator is registered for. + */ + String value() default ""; + + /** + * The type this validator is registered for. + */ + Class type() default void.class; + + /** + * If {@code true}, the validator will only be used in the current command class. + */ + boolean local() default true; + + /** + * If {@code true}, the validator will be inverted for parameter usage. + */ + boolean invert() default false; + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + @Handler.Implementation(ValidatorHandler.Impl.class) + @interface Validators { + Validator[] value(); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Values.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Values.java new file mode 100644 index 00000000..a00864f4 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/annotations/Values.java @@ -0,0 +1,52 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.annotations; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.ValuesHandler; +import de.steamwar.command.handler.ValuesReferenceHandler; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation is used to define static values for a parameter like an enum just without the enum. + * You can use this annotation on a parameter of type {@link String} or {@link int}, {@link long} and + * {@link boolean}. While using an int, the value will represent the index into the value array. While + * using a boolean, the {@link #falseValues()} defines which indices are considered {@code false} or + * {@code true}. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +@Handler.Implementation(ValuesHandler.Impl.class) +public @interface Values { + String[] value(); + + int[] falseValues() default {0}; + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.PARAMETER}) + @Handler.Implementation(ValuesReferenceHandler.Impl.class) + @interface Reference { + String value(); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractArrayNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractArrayNode.java new file mode 100644 index 00000000..7ba207cd --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractArrayNode.java @@ -0,0 +1,110 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.handler.ArrayLengthHandler; +import de.steamwar.command.handler.UniqueHandler; +import de.steamwar.command.utils.Triple; + +import java.lang.reflect.Array; +import java.lang.reflect.Parameter; +import java.util.*; + +public abstract class AbstractArrayNode extends AbstractTypeNode { + + protected final boolean unique; + protected final int minArrayLength; + protected final int maxArrayLength; + protected final String error; + + protected AbstractArrayNode(Parameter parameter, int index, Handler.DataReadable dataReadable) { + super(parameter, index, dataReadable); + + this.unique = UniqueHandler.isPresent(parameter); + this.minArrayLength = ArrayLengthHandler.getMin(parameter); + this.maxArrayLength = ArrayLengthHandler.getMax(parameter); + this.error = ArrayLengthHandler.getError(parameter); + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + Object array = Array.newInstance(type, Math.min(nodeData.unparsedArgumentsSize(), maxArrayLength)); + + int i = 0; + while (!nodeData.hasOneLeft()) { + if (i >= minArrayLength) { + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + } + + nodeData.add(name, arrayCopy(array, i)); + Triple argument = argument(executor, nodeData); + nodeData.remove(); + + if (!argument.b) { + for (; i > 0; i--) nodeData.unconsume(); + return; + } + nodeData.consume(); + Array.set(array, i, argument.a); + i++; + } + nodeData.add(name, arrayCopy(array, i)); + if (i < maxArrayLength) { + PreviousArguments previousArguments = nodeData.toPreviousArguments(); + if (unique) { + Map> mapped = new HashMap<>(); + for (String s : typeMapper.tabComplete(executor, previousArguments, nodeData.current())) { + mapped.computeIfAbsent(typeMapper.map(executor, previousArguments, s), object -> new ArrayList<>()) + .add(s); + } + for (int j = 0; j < i; j++) { + mapped.remove(Array.get(array, j)); + } + mapped.forEach((object, strings) -> { + completions.add(strings); + }); + } else { + completions.add(typeMapper.tabComplete(executor, previousArguments, nodeData.current())); + } + } + if (i >= minArrayLength) { + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + } + nodeData.remove(); + for (; i > 0; i--) nodeData.unconsume(); + } + + protected Object arrayCopy(Object array, int newLength) { + Object newArray = Array.newInstance(type, newLength); + System.arraycopy(array, 0, newArray, 0, Math.min(Array.getLength(array), newLength)); + return newArray; + } + + @Override + public int nodeCost() { + return minArrayLength * 2 + super.nodeCost(); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractTypeNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractTypeNode.java new file mode 100644 index 00000000..d9f527ab --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractTypeNode.java @@ -0,0 +1,145 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.*; +import de.steamwar.command.annotations.TabFilterType; +import de.steamwar.command.handler.TabFilterHandler; +import de.steamwar.command.mapper.EnumMapper; +import de.steamwar.command.mapper.OptionEnumMapper; +import de.steamwar.command.mapper.internal.ContainsFilter; +import de.steamwar.command.mapper.internal.StartsWithFilter; +import de.steamwar.command.utils.Pair; +import de.steamwar.command.utils.Triple; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Parameter; +import java.util.List; + +public abstract class AbstractTypeNode extends AbstractValidationNode { + + protected Class type; + protected AbstractTypeMapper typeMapper; + + protected AbstractTypeNode(Parameter parameter, int index, Handler.DataReadable dataReadable) { + super(parameter, index, dataReadable); + + type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + + initializeTypeMapper(handlerParameters, parameter, index, dataReadable); + } + + private AbstractTypeMapper getTypeMapper(Handler.DataReadable dataReadable) { + AbstractTypeMapper typeMapper = dataReadable.getMapper(type.getTypeName()); + if (typeMapper == null && type.isEnum()) { + if (OptionEnum.class.isAssignableFrom(type)) { + typeMapper = (AbstractTypeMapper) new OptionEnumMapper((Class) type); + } else { + typeMapper = (AbstractTypeMapper) new EnumMapper((Class) type); + } + } + return typeMapper; + } + + private void initializeTypeMapper(List> pairs, Parameter parameter, int index, Handler.DataReadable dataReadable) { + AbstractTypeMapper typeMapper = getTypeMapper(dataReadable); + boolean isStillDefault = true; + for (Pair pair : pairs) { + if (pair.b.needsParentTypeMapper()) { + continue; + } + if (!isStillDefault) { + throw new UnsupportedOperationException("Only one HandlerParameter can be used without a parent TypeMapper"); + } + AbstractTypeMapper temp = pair.b.getTypeMapper(pair.a, parameter, index, dataReadable, null); + if (temp != null) { + typeMapper = temp; + isStillDefault = false; + } + } + + AbstractTypeMapper current = typeMapper; + for (Pair pair : pairs) { + if (!pair.b.needsParentTypeMapper()) { + continue; + } + AbstractTypeMapper temp = pair.b.getTypeMapper(pair.a, parameter, index, dataReadable, typeMapper); + if (temp != null) { + typeMapper = temp; + } + } + + current = TabCompletionCache.cached(current, typeMapper); + + TabFilterType tabFilterType = TabFilterHandler.getTabFilterType(parameter); + switch (tabFilterType) { + case NONE: + this.typeMapper = current; + break; + case STARTS_WITH: + this.typeMapper = new StartsWithFilter<>(current); + break; + case CONTAINS: + this.typeMapper = new ContainsFilter<>(current); + break; + } + } + + protected Triple argument(E executor, NodeData nodeData) { + Object value; + boolean usedOptional; + try { + PreviousArguments previousArguments = nodeData.toPreviousArguments(); + value = typeMapper.map(executor, previousArguments, nodeData.current()); + usedOptional = previousArguments.hasUsedOptionalValue(); + } catch (Exception e) { + return new Triple<>(null, false, false); + } + if (validate(executor, value, nodeData)) { + return new Triple<>(value, true, usedOptional); + } else { + return new Triple<>(null, false, false); + } + } + + protected boolean validate(E executor, Object value, NodeData nodeData) { + for (AbstractTypeValidator validator : validators) { + try { + if (!validator.validate(executor, value, nodeData)) { + return false; + } + } catch (ClassCastException e) { + // Ignore + } catch (Throwable e) { + return false; + } + } + return true; + } + + @Override + public boolean equals(Parameter parameter, Node children) { + if (!(children instanceof AbstractTypeNode)) { + return false; + } + return super.equals(parameter, children); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractValidationNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractValidationNode.java new file mode 100644 index 00000000..265e3aa9 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/AbstractValidationNode.java @@ -0,0 +1,109 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.CommandUtils; +import de.steamwar.command.Handler; +import de.steamwar.command.handler.AllowNullHandler; +import de.steamwar.command.utils.Pair; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Parameter; +import java.util.*; + +public abstract class AbstractValidationNode extends Node { + + private static final AbstractTypeValidator NON_NULL_VALIDATOR = (AbstractTypeValidator) (sender, value, messageSender) -> value != null; + + protected final List annotations; + protected final List> handlerParameters; + protected final List> validators = new ArrayList<>(); + + protected AbstractValidationNode(Parameter parameter, int index, Handler.DataReadable dataReadable) { + super(parameter); + annotations = CommandUtils.getAnnotations(parameter, Handler.HandlerParameter.class); + List> pairs = new ArrayList<>(); + for (Annotation annotation : annotations) { + Handler.Implementation implementation = annotation.annotationType().getAnnotation(Handler.Implementation.class); + try { + pairs.add(new Pair<>(annotation, (Handler.HandlerParameter) implementation.value().getConstructor().newInstance())); + } catch (Exception e) { + throw new SecurityException(e); + } + } + handlerParameters = pairs; + + initializeValidators(handlerParameters, parameter, index, dataReadable); + } + + private void initializeValidators(List> pairs, Parameter parameter, int index, Handler.DataReadable dataReadable) { + pairs.sort(Comparator.comparingInt(p -> p.b.getValidatorPriority())); + for (Pair pair : pairs) { + AbstractTypeValidator validator = pair.b.getValidator(pair.a, parameter, index, dataReadable); + if (validator != null) { + validators.add(validator); + } + } + + if (!AllowNullHandler.isPresent(parameter)) { + validators.add((AbstractTypeValidator) NON_NULL_VALIDATOR); + } + } + + @Override + public boolean equals(Parameter parameter, Node children) { + if (this.parameter.getType() != parameter.getType()) { + return false; + } + + Annotation[] annotations = this.parameter.getAnnotations(); + Annotation[] currentAnnotations = parameter.getAnnotations(); + + if (annotations.length == 0 && currentAnnotations.length == 0) { + return true; + } + + if (annotations.length != currentAnnotations.length) { + return false; + } + + Map, Annotation> annotationMap = new HashMap<>(); + boolean duplicate = false; + for (Annotation annotation : annotations) { + if (annotationMap.put(annotation.annotationType(), annotation) != null) { + duplicate = true; + break; + } + } + if (duplicate) { + return false; + } + + for (Annotation annotation : currentAnnotations) { + Annotation other = annotationMap.get(annotation.annotationType()); + if (!annotation.equals(other)) { + continue; + } + annotationMap.remove(annotation.annotationType()); + } + return annotationMap.isEmpty(); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/ExecuteNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/ExecuteNode.java new file mode 100644 index 00000000..791c3a4f --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/ExecuteNode.java @@ -0,0 +1,89 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.CommandFrameworkException; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public class ExecuteNode extends Node { + + private final Object self; + private final Method method; + + public ExecuteNode(Object self, Method method) { + super(null); + this.self = self; + this.method = method; + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + for (Node child : children) { + if (child.execute(executor, nodeData)) { + return true; + } + } + + if (nodeData.hasMore()) { + return false; + } + + try { + method.invoke(self, nodeData.mapped()); + return true; + } catch (InvocationTargetException e) { + throw new CommandFrameworkException(e, nodeData.alias(), nodeData.args()); + } catch (IllegalAccessException | RuntimeException e) { + return false; + } + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + } + + @Override + public boolean equals(Parameter parameter, Node children) { + if (children instanceof ExecuteNode) { + String parameters = Arrays.stream(method.getParameters()).map(par -> { + String annotations = Arrays.stream(par.getAnnotations()) + .map(annotation -> "@" + annotation.getClass().getSimpleName()) + .collect(Collectors.joining(" ")); + if (par.isVarArgs()) { + return annotations + (annotations.isEmpty() ? "" : " ") + par.getType().componentType().getSimpleName() + "..."; + } else { + return annotations + (annotations.isEmpty() ? "" : " ") + par.getType().getSimpleName(); + } + }).collect(Collectors.joining(", ")); + throw new UnsupportedOperationException("Command with parameters " + parameters + " is already defined in " + self.getClass().getName()); + } + return children instanceof ExecuteNode; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/ExecutorTypeNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/ExecutorTypeNode.java new file mode 100644 index 00000000..7bc189c1 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/ExecutorTypeNode.java @@ -0,0 +1,95 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.Handler; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.List; +import java.util.function.Function; + +public class ExecutorTypeNode extends AbstractValidationNode { + + protected final Function executorMapper; + + public ExecutorTypeNode(Parameter parameter, int index, Handler.DataReadable dataReadable) { + super(parameter, index, dataReadable); + this.executorMapper = (Function) dataReadable.getExecutorMapper(parameter.getType()); + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + Object mappedExecutor = executorMapper.apply(executor); + if (mappedExecutor == null) return false; + for (AbstractTypeValidator validator : validators) { + try { + if (!validator.validate(executor, executor, nodeData)) { + return false; + } + } catch (ClassCastException e) { + // Ignore + } catch (Throwable e) { + return false; + } + } + nodeData.add(name, mappedExecutor); + for (Node child : children) { + if (child.execute(executor, nodeData)) return true; + } + nodeData.remove(); + return false; + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + Object mappedExecutor = executorMapper.apply(executor); + if (mappedExecutor == null) return; + for (AbstractTypeValidator validator : validators) { + try { + if (!validator.validate(executor, executor, nodeData)) { + return; + } + } catch (ClassCastException e) { + // Ignore + } catch (Throwable e) { + return; + } + } + nodeData.add(name, mappedExecutor); + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + nodeData.remove(); + } + + @Override + public boolean equals(Parameter parameter, Node children) { + if (!(children instanceof ExecutorTypeNode)) { + return false; + } + ExecutorTypeNode other = (ExecutorTypeNode) children; + if (executorMapper != other.executorMapper) { + return false; + } + return super.equals(parameter, children); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/GreedyArrayNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/GreedyArrayNode.java new file mode 100644 index 00000000..2c02d480 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/GreedyArrayNode.java @@ -0,0 +1,98 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.Handler; +import de.steamwar.command.handler.GreedyHandler; +import de.steamwar.command.utils.Triple; + +import java.lang.reflect.Array; +import java.lang.reflect.Parameter; +import java.util.HashSet; +import java.util.Set; + +public class GreedyArrayNode extends AbstractArrayNode { + + protected final int backTrackingDepth; + + public GreedyArrayNode(Parameter parameter, int index, Handler.DataReadable dataReadable) { + super(parameter, index, dataReadable); + this.backTrackingDepth = GreedyHandler.getBackTrackingDepth(parameter); + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + int min = Math.min(nodeData.unparsedArgumentsSize(), minArrayLength); + int max = Math.min(nodeData.unparsedArgumentsSize(), maxArrayLength); + if (max < minArrayLength) { + nodeData.send(error, 0, minArrayLength); + return false; + } + + Object array = Array.newInstance(type, max); + Set seen = new HashSet<>(); + + int i = 0; + for (; i < max; i++) { + nodeData.add(name, arrayCopy(array, i)); + Triple argument = argument(executor, nodeData); + nodeData.remove(); + + if (!argument.b || (unique && !seen.add(argument.a))) { + if (i < minArrayLength) { + nodeData.send(error, i, minArrayLength); + for (; i > 0; i--) nodeData.unconsume(); + return false; + } + break; + } + Array.set(array, i, argument.a); + nodeData.consume(); + } + + int backTrackingDepth = i - this.backTrackingDepth; + for (; i >= min; i--) { + Object copiedArray = arrayCopy(array, i); + nodeData.add(name, copiedArray); + if (validate(executor, copiedArray, nodeData)) { + for (Node child : children) { + if (child.execute(executor, nodeData)) { + return true; + } + } + } + nodeData.remove(); + if (i <= backTrackingDepth) { + break; + } + if (i > 0) { + nodeData.unconsume(); + } + } + if (i < minArrayLength) nodeData.send(error, i, minArrayLength); + for (; i > 0; i--) nodeData.unconsume(); + return false; + } + + @Override + public int nodeCost() { + return -1; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/LiteralNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/LiteralNode.java new file mode 100644 index 00000000..b00d176d --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/LiteralNode.java @@ -0,0 +1,75 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.List; + +public class LiteralNode extends Node { + + protected final String literal; + + public LiteralNode(String literal) { + super(null); + this.literal = literal; + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + if (!nodeData.hasMore()) return false; + if (nodeData.current().equalsIgnoreCase(literal)) { + nodeData.consume(); + for (Node child : children) { + if (child.execute(executor, nodeData)) { + return true; + } + } + nodeData.unconsume(); + } + return false; + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + if (nodeData.hasOneLeft()) { + if (literal.startsWith(nodeData.current())) { + completions.add(List.of(literal)); + } + return; + } + + if (nodeData.current().equalsIgnoreCase(literal)) { + nodeData.consume(); + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + nodeData.unconsume(); + } + } + + @Override + public boolean equals(Parameter parameter, Node children) { + if (!(children instanceof LiteralNode)) { + return false; + } + return literal.equalsIgnoreCase(((LiteralNode) children).literal); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NoTabCompleteNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NoTabCompleteNode.java new file mode 100644 index 00000000..d59760c7 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NoTabCompleteNode.java @@ -0,0 +1,49 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.List; + +public class NoTabCompleteNode extends Node { + + public NoTabCompleteNode() { + super(null); + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + for (Node child : children) { + if (child.execute(executor, nodeData)) return true; + } + return false; + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + // Do nothing + } + + @Override + public boolean equals(Parameter parameter, Node children) { + return children instanceof NoTabCompleteNode; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/Node.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/Node.java new file mode 100644 index 00000000..7080d9f4 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/Node.java @@ -0,0 +1,83 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.annotations.Name; + +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +public abstract class Node { + + protected final Parameter parameter; + protected final String name; + protected final List> children = new ArrayList<>(); + + protected Node(Parameter parameter) { + this.parameter = parameter; + if (parameter == null) { + this.name = null; + return; + } + + Name name = parameter.getAnnotation(Name.class); + if (name == null) { + this.name = parameter.getName(); + } else { + this.name = name.value(); + } + } + + public abstract boolean execute(E executor, NodeData nodeData); + public abstract void tabComplete(E executor, NodeData nodeData, List> completions); + + public final Node addChild(Parameter parameter, Node child) { + for (Node currentChild : children) { + if (currentChild.equals(parameter, child)) { + return currentChild; + } + } + children.add(child); + return child; + } + + public abstract boolean equals(Parameter parameter, Node children); + + public int nodeCost() { + return 2; + } + + public final int sort() { + AtomicInteger max = new AtomicInteger(0); + if (children.size() == 1) { + return children.get(0).sort() + nodeCost(); + } + children.sort(Comparator.comparingInt(value -> { + int sort = value.sort(); + if (sort > max.get()) max.set(sort); + return -sort; + })); + return max.get() + nodeCost(); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NodeData.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NodeData.java new file mode 100644 index 00000000..7966b25a --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NodeData.java @@ -0,0 +1,120 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.PreviousArguments; +import lombok.NonNull; + +import java.util.Arrays; +import java.util.LinkedList; + +public class NodeData implements AbstractTypeValidator.MessageSender { + + private final String alias; + private final LinkedList parsedArguments = new LinkedList<>(); + private final LinkedList unparsedArguments; + private final LinkedList mapped = new LinkedList<>(); + private final LinkedList names = new LinkedList<>(); + private final AbstractTypeValidator.MessageSender messageSender; + + public NodeData(String alias, String[] args, AbstractTypeValidator.MessageSender messageSender) { + this.alias = alias; + this.unparsedArguments = new LinkedList<>(Arrays.asList(args)); + this.messageSender = messageSender; + } + + public String[] args() { + return parsedArguments.toArray(String[]::new); + } + + public String alias() { + return alias; + } + + public String current() { + if (unparsedArguments.isEmpty()) return null; + return unparsedArguments.getFirst(); + } + + public boolean hasMore() { + return !unparsedArguments.isEmpty(); + } + + public boolean hasOneLeft() { + return unparsedArguments.size() == 1; + } + + void consume() { + parsedArguments.addLast(unparsedArguments.removeFirst()); + } + + void unconsume() { + unparsedArguments.addFirst(parsedArguments.removeLast()); + } + + void add(String name, Object mapped) { + this.names.addLast(name); + this.mapped.addLast(mapped); + } + + void remove() { + this.names.removeLast(); + this.mapped.removeLast(); + } + + public Object getByName(@NonNull String name) { + for (int i = mapped.size() - 1; i >= 0; i--) { + if (name.equals(names.get(i))) { + return mapped.get(i); + } + } + return null; + } + + public Object[] mapped() { + return mapped.toArray(); + } + + public int unparsedArgumentsSize() { + return unparsedArguments.size(); + } + + @Override + public void send(String s, Object... args) { + if (s == null || s.isEmpty()) return; + messageSender.send(s, args); + } + + PreviousArguments toPreviousArguments() { + return new PreviousArguments(args(), mapped(), hasMore(), this::getByName); + } + + @Override + public String toString() { + return "NodeData{" + + "alias='" + alias + '\'' + + ", parsedArguments=" + parsedArguments + " (" + parsedArguments.size() + ")" + + ", unparsedArguments=" + unparsedArguments + " (" + unparsedArguments.size() + ")" + + ", mapped=" + mapped + " (" + mapped.size() + ")" + + ", names=" + names + " (" + names.size() + ")" + + '}'; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NonGreedyArrayNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NonGreedyArrayNode.java new file mode 100644 index 00000000..e2bafc1c --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/NonGreedyArrayNode.java @@ -0,0 +1,83 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.Handler; +import de.steamwar.command.utils.Triple; + +import java.lang.reflect.Array; +import java.lang.reflect.Parameter; +import java.util.HashSet; +import java.util.Set; + +public class NonGreedyArrayNode extends AbstractArrayNode { + + public NonGreedyArrayNode(Parameter parameter, int index, Handler.DataReadable dataReadable) { + super(parameter, index, dataReadable); + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + int min = Math.max(nodeData.unparsedArgumentsSize(), minArrayLength); + int max = Math.min(nodeData.unparsedArgumentsSize(), maxArrayLength); + if (max < minArrayLength) { + nodeData.send(error, 0, minArrayLength); + return false; + } + Object array = Array.newInstance(type, max); + Set seen = new HashSet<>(); + + int i = 0; + do { + Object copiedArray = arrayCopy(array, i); + nodeData.add(name, copiedArray); + if (i >= min && validate(executor, copiedArray, nodeData)) { + for (Node child : children) { + if (child.execute(executor, nodeData)) return true; + } + } + + Triple argument = argument(executor, nodeData); + nodeData.remove(); + if (!argument.b || (unique && !seen.add(argument.a))) { + if (i < minArrayLength) nodeData.send(error, i, minArrayLength); + for (; i > 0; i--) nodeData.unconsume(); + return false; + } + nodeData.consume(); + Array.set(array, i, argument.a); + i++; + } while (i < max); + + if (i >= min) { + Object copiedArray = arrayCopy(array, i); + nodeData.add(name, copiedArray); + if (validate(executor, copiedArray, nodeData)) { + for (Node child : children) { + if (child.execute(executor, nodeData)) return true; + } + } + nodeData.remove(); + } + if (i < minArrayLength) nodeData.send(error, i, minArrayLength); + for (; i > 0; i--) nodeData.unconsume(); + return false; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/RootNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/RootNode.java new file mode 100644 index 00000000..7030fbb2 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/RootNode.java @@ -0,0 +1,51 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.List; + +public class RootNode extends Node { + + public RootNode() { + super(null); + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + for (Node child : children) { + if (child.execute(executor, nodeData)) return true; + } + return false; + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + } + + @Override + public boolean equals(Parameter parameter, Node children) { + return children instanceof RootNode; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/SupplierNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/SupplierNode.java new file mode 100644 index 00000000..e1da7416 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/SupplierNode.java @@ -0,0 +1,100 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.AbstractTypeSupplier; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Supplier; +import de.steamwar.command.handler.AllowNullHandler; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.List; + +public class SupplierNode extends Node { + + protected final AbstractTypeSupplier typeSupplier; + protected final boolean allowNull; + + public SupplierNode(Parameter parameter, Handler.DataReadable dataReadable) { + super(parameter); + + Supplier annotation = parameter.getAnnotation(Supplier.class); + String s = annotation.value() != null && !annotation.value().isEmpty() ? annotation.value() : parameter.getType().getTypeName(); + typeSupplier = dataReadable.getSupplier(s); + + allowNull = AllowNullHandler.isPresent(parameter); + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + PreviousArguments previousArguments = nodeData.toPreviousArguments(); + Object value; + try { + value = typeSupplier.get(executor, previousArguments); + } catch (Exception e) { + return false; + } + + if (!allowNull && value == null) { + return false; + } + nodeData.add(name, value); + + for (Node child : children) { + if (child.execute(executor, nodeData)) return true; + } + + nodeData.remove(); + return false; + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + PreviousArguments previousArguments = nodeData.toPreviousArguments(); + Object value; + try { + value = typeSupplier.get(executor, previousArguments); + } catch (Exception e) { + return; + } + + if (!allowNull && value == null) { + return; + } + nodeData.add(name, value); + + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + + nodeData.remove(); + } + + @Override + public boolean equals(Parameter parameter, Node children) { + if (children instanceof SupplierNode) { + SupplierNode supplierNode = (SupplierNode) children; + return allowNull == supplierNode.allowNull && typeSupplier == supplierNode.typeSupplier; + } + return false; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/TypeNode.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/TypeNode.java new file mode 100644 index 00000000..0c9fefbb --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/graph/TypeNode.java @@ -0,0 +1,84 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.graph; + +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.utils.Triple; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.List; + +public class TypeNode extends AbstractTypeNode { + + public TypeNode(Parameter parameter, int index, Handler.DataReadable dataReadable) { + super(parameter, index, dataReadable); + } + + @Override + public boolean execute(E executor, NodeData nodeData) { + Triple argument = argument(executor, nodeData); + if (!argument.b) return false; + nodeData.add(name, argument.a); + if (!argument.c) nodeData.consume(); + + for (Node child : children) { + if (child.execute(executor, nodeData)) return true; + } + + nodeData.remove(); + if (!argument.c) nodeData.unconsume(); + return false; + } + + @Override + public void tabComplete(E executor, NodeData nodeData, List> completions) { + if (nodeData.hasOneLeft()) { + PreviousArguments previousArguments = nodeData.toPreviousArguments(); + Collection tabCompletions = typeMapper.tabComplete(executor, previousArguments, nodeData.current()); + completions.add(tabCompletions); + + if (typeMapper.appendNextElementTabCompletions()) { + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + } + return; + } + + Triple argument = argument(executor, nodeData); + if (!argument.b) return; + nodeData.add(name, argument.a); + if (!argument.c) nodeData.consume(); + + for (Node child : children) { + child.tabComplete(executor, nodeData, completions); + } + + nodeData.remove(); + if (!argument.c) nodeData.unconsume(); + } + + @Override + public int nodeCost() { + return type == String.class ? 1 : 2; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/AllowNullHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/AllowNullHandler.java new file mode 100644 index 00000000..dd170378 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/AllowNullHandler.java @@ -0,0 +1,48 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.AllowNull; + +import java.lang.reflect.Parameter; + +/** + * This special Handler is just for validating the AllowNull annotation. + */ +public final class AllowNullHandler { + + public static boolean isPresent(Parameter parameter) { + return parameter.isAnnotationPresent(AllowNull.class); + } + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(AllowNull annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("AllowNull annotation cannot be used on the first parameter"); + } + if (parameter.getType().isPrimitive()) { + throw new UnsupportedOperationException("AllowNull annotation cannot be used on primitive types"); + } + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ArrayLengthHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ArrayLengthHandler.java new file mode 100644 index 00000000..487d13b9 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ArrayLengthHandler.java @@ -0,0 +1,62 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.ArrayLength; + +import java.lang.reflect.Parameter; + +public final class ArrayLengthHandler { + + public static int getMin(Parameter parameter) { + ArrayLength arrayLength = parameter.getAnnotation(ArrayLength.class); + if (arrayLength == null) return 0; + return arrayLength.min(); + } + + public static int getMax(Parameter parameter) { + ArrayLength arrayLength = parameter.getAnnotation(ArrayLength.class); + if (arrayLength == null) return Integer.MAX_VALUE; + return arrayLength.max(); + } + + public static String getError(Parameter parameter) { + ArrayLength arrayLength = parameter.getAnnotation(ArrayLength.class); + if (arrayLength == null) return ""; + return arrayLength.error(); + } + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(ArrayLength arrayLength, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("ArrayLength annotation cannot be used on first parameter"); + } + if (!parameter.getType().isArray()) { + throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable().getName() + " is not an array"); + } + if (arrayLength.min() > arrayLength.max()) { + throw new UnsupportedOperationException("Min ArrayLength cannot be smaller than Max ArrayLength"); + } + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/CachedHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/CachedHandler.java new file mode 100644 index 00000000..59ac3522 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/CachedHandler.java @@ -0,0 +1,54 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.TabCompletionCache; +import de.steamwar.command.annotations.Cached; + +import java.lang.reflect.Method; + +public final class CachedHandler { + + public static final class Impl implements Handler.HandlerMethod { + + @Override + public void check(Cached annotation, Method method, DataCheckable dataCheckable) throws Exception { + if (method.getParameterCount() != 0) { + throw new UnsupportedOperationException("Cached method must have no parameters"); + } + if (!AbstractTypeMapper.class.isAssignableFrom(method.getReturnType())) { + throw new UnsupportedOperationException("Cached method must return AbstractTypeMapper"); + } + } + + @Override + public int getRunPriority() { + return Integer.MIN_VALUE; + } + + @Override + public void run(Cached annotation, Method method, DataWritable dataWritable) { + AbstractTypeMapper abstractTypeMapper = dataWritable.invoke(method); + TabCompletionCache.add(abstractTypeMapper, annotation.global(), annotation.cacheDuration(), annotation.timeUnit()); + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassMapperHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassMapperHandler.java new file mode 100644 index 00000000..ab31acb1 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassMapperHandler.java @@ -0,0 +1,54 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.ClassMapper; + +import java.lang.reflect.Method; + +@Deprecated +public final class ClassMapperHandler { + + public static final class Impl implements Handler.HandlerMethod { + + @Override + public void check(ClassMapper annotation, Method method, DataCheckable dataCheckable) throws Exception { + if (method.getParameterCount() != 0) { + throw new UnsupportedOperationException("ClassMapper method must have no parameters"); + } + if (!AbstractTypeMapper.class.isAssignableFrom(method.getReturnType())) { + throw new UnsupportedOperationException("ClassMapper method must return AbstractTypeMapper"); + } + } + + @Override + public int getRunPriority() { + return Integer.MIN_VALUE; + } + + @Override + public void run(ClassMapper annotation, Method method, DataWritable dataWritable) { + AbstractTypeMapper abstractTypeMapper = dataWritable.invoke(method); + dataWritable.addMapper(annotation.value().getName(), annotation.local(), abstractTypeMapper); + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassValidatorHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassValidatorHandler.java new file mode 100644 index 00000000..a8d64e82 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ClassValidatorHandler.java @@ -0,0 +1,54 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.ClassValidator; + +import java.lang.reflect.Method; + +@Deprecated +public final class ClassValidatorHandler { + + public static final class Impl implements Handler.HandlerMethod { + + @Override + public void check(ClassValidator annotation, Method method, DataCheckable dataCheckable) throws Exception { + if (method.getParameterCount() != 0) { + throw new UnsupportedOperationException("ClassValidator method must have no parameters"); + } + if (!AbstractTypeValidator.class.isAssignableFrom(method.getReturnType())) { + throw new UnsupportedOperationException("ClassValidator method must return AbstractValidator"); + } + } + + @Override + public int getRunPriority() { + return Integer.MIN_VALUE; + } + + @Override + public void run(ClassValidator annotation, Method method, DataWritable dataWritable) { + AbstractTypeValidator abstractTypeValidator = dataWritable.invoke(method); + dataWritable.addValidator(annotation.value().getName(), annotation.local(), abstractTypeValidator); + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/EndsWithHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/EndsWithHandler.java new file mode 100644 index 00000000..37ea29ee --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/EndsWithHandler.java @@ -0,0 +1,84 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.EndsWith; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.stream.Collectors; + +public final class EndsWithHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(EndsWith annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("EndsWith annotation cannot be used on first parameter"); + } + if (parameter.getType() != String.class) { + throw new UnsupportedOperationException("EndsWith annotation cannot be used on String parameter"); + } + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(EndsWith annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + String endsWith = annotation.value(); + + return new DelegatingMapper<>(parentTypeMapper, annotation) { + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return super.tabComplete(sender, previousArguments, s).stream().map(s1 -> { + if (s1.startsWith(endsWith)) return s1; + return s1 + endsWith; + }).collect(Collectors.toList()); + } + }; + } + + @Override + public int getValidatorPriority() { + return 0; + } + + @Override + public AbstractTypeValidator getValidator(EndsWith annotation, Parameter parameter, int index, DataReadable dataReadable) { + String endsWith = annotation.value(); + String error = annotation.error(); + return (sender, value, messageSender) -> { + if (value == null) return true; + if (value.endsWith(endsWith)) return true; + messageSender.send(error); + return false; + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ErrorMessageHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ErrorMessageHandler.java new file mode 100644 index 00000000..df5a278e --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ErrorMessageHandler.java @@ -0,0 +1,60 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.ErrorMessage; + +import java.lang.reflect.Array; +import java.lang.reflect.Parameter; + +public final class ErrorMessageHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(ErrorMessage errorMessage, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("ErrorMessage annotation cannot be used on first parameter"); + } + if (!errorMessage.allowEAs() && !(parameter.isVarArgs() || parameter.getType().isArray())) { + throw new UnsupportedOperationException("ErrorMessage allowESs cannot be used on non array or varargs parameter"); + } + } + + @Override + public int getValidatorPriority() { + return Integer.MAX_VALUE; + } + + @Override + public AbstractTypeValidator getValidator(ErrorMessage errorMessage, Parameter parameter, int index, DataReadable dataReadable) { + return (sender, value, messageSender) -> { + if (value == null) messageSender.send(errorMessage.value()); + if (!errorMessage.allowEAs() && value != null && value.getClass().isArray() && Array.getLength(value) == 0) { + messageSender.send(errorMessage.value()); + return false; + } + return value != null; + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/GreedyHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/GreedyHandler.java new file mode 100644 index 00000000..1eaa20a0 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/GreedyHandler.java @@ -0,0 +1,53 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.Greedy; + +import java.lang.reflect.Parameter; + +/** + * This special Handler is just for validating the Greedy annotation. + */ +public final class GreedyHandler { + + public static boolean isGreedy(Parameter parameter) { + return parameter.isAnnotationPresent(Greedy.class); + } + + public static int getBackTrackingDepth(Parameter parameter) { + Greedy greedy = parameter.getAnnotation(Greedy.class); + if (greedy == null || parameter.isVarArgs()) { + return 0; + } + return greedy.backTrackingDepth(); + } + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Greedy annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (!parameter.getType().isArray() || parameter.isVarArgs()) { + throw new UnsupportedOperationException("Greedy annotation cannot be used on non array parameters"); + } + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/LengthHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/LengthHandler.java new file mode 100644 index 00000000..9d6ba906 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/LengthHandler.java @@ -0,0 +1,76 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Length; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public final class LengthHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Length annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Length annotation cannot be used on first parameter"); + } + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(Length length, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + int min = length.min(); + int max = length.max(); + + return new DelegatingMapper<>(parentTypeMapper, length) { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + if (s.length() < min || s.length() > max) return null; + return delegate.map(sender, previousArguments, s); + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + List tabCompletes = delegate.tabComplete(sender, previousArguments, s) + .stream() + .filter(str -> str.length() >= min) + .map(str -> str.substring(0, Math.min(str.length(), max))) + .collect(Collectors.toList()); + if (s.length() < min) { + tabCompletes.add(0, s); + } + return tabCompletes; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java new file mode 100644 index 00000000..a01392c1 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MapperHandler.java @@ -0,0 +1,96 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.Mapper; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Optional; + +public final class MapperHandler { + + public static final class Impl implements Handler.HandlerMethod, Handler.HandlerParameter { + + @Override + public void check(Mapper annotation, Method method, DataCheckable dataCheckable) throws Exception { + if (method.getParameterCount() != 0) { + throw new UnsupportedOperationException("Mapper method must have no parameters"); + } + if (!AbstractTypeMapper.class.isAssignableFrom(method.getReturnType())) { + throw new UnsupportedOperationException("Mapper method must return AbstractTypeMapper"); + } + + if (annotation.value() != null && !annotation.value().isEmpty()) { + return; + } + + Optional> genericType = getGenericTypeOfReturn(method); + if (annotation.type() == void.class) { + if (genericType.isEmpty()) { + throw new UnsupportedOperationException("Please supply a class type to the Mapper"); + } + } else { + if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) { + throw new UnsupportedOperationException("Supplied type does not conform to actual type"); + } + } + } + + @Override + public int getRunPriority() { + return Integer.MIN_VALUE; + } + + @Override + public void run(Mapper annotation, Method method, DataWritable dataWritable) { + AbstractTypeMapper abstractTypeMapper = dataWritable.invoke(method); + if (annotation.value() != null && !annotation.value().isEmpty()) { + dataWritable.addMapper(annotation.value(), annotation.local(), abstractTypeMapper); + } else { + Class type = annotation.type(); + if (type == void.class) type = getGenericTypeOfReturn(method).get(); + dataWritable.addMapper(type.getName(), annotation.local(), abstractTypeMapper); + } + } + + @Override + public void check(Mapper annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Mapper annotation cannot be used on first parameter"); + } + if (!dataCheckable.hasMapper(annotation.value())) { + throw new UnsupportedOperationException("Mapper '" + annotation.value() + "' not found"); + } + } + + @Override + public AbstractTypeMapper getTypeMapper(Mapper annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + String s = annotation.value(); + AbstractTypeMapper abstractTypeMapper = dataReadable.getMapper(s); + if (abstractTypeMapper == null) { + throw new IllegalArgumentException("No mapper found for " + s); + } + return abstractTypeMapper; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxHandler.java new file mode 100644 index 00000000..a44d985c --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxHandler.java @@ -0,0 +1,172 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.*; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.ToIntFunction; + +public final class MaxHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Max max, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Max annotation cannot be used on first parameter"); + } + Class type = parameter.getType(); + if (parameter.isVarArgs()) type = type.getComponentType(); + + if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != float.class && type != Float.class && type != double.class && type != Double.class) { + throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number."); + } + + if (!parameter.isAnnotationPresent(Min.class)) { + return; + } + + Min min = parameter.getAnnotation(Min.class); + + Number minValue; + if (type.equals(int.class) || type.equals(Integer.class)) { + minValue = min.intValue(); + } else if (type.equals(long.class) || type.equals(Long.class)) { + minValue = min.longValue(); + } else if (type.equals(float.class) || type.equals(Float.class)) { + minValue = min.floatValue(); + } else if (type.equals(double.class) || type.equals(Double.class)) { + minValue = min.doubleValue(); + } else { + throw new SecurityException(); + } + + ToIntFunction maxComparator = CommandUtils.createComparator("Max", type, max.intValue(), max.longValue(), max.floatValue(), max.doubleValue()); + if (!(min.inclusive() && max.inclusive()) && maxComparator.applyAsInt(minValue) == 0) { + throw new UnsupportedOperationException("Min and Max cannot be equal if not both are inclusive"); + } else if (maxComparator.applyAsInt(minValue) > 0) { + throw new UnsupportedOperationException("Max must be bigger then Min"); + } + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(Max max, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + Class type = parameter.getType(); + if (parameter.isVarArgs()) type = type.getComponentType(); + + int compareValue = max.inclusive() ? 0 : -1; + ToIntFunction comparator = CommandUtils.createComparator("Max", type, max.intValue(), max.longValue(), max.floatValue(), max.doubleValue()); + boolean onlyNegative = comparator.applyAsInt(0) >= 0; + + Min min = parameter.getAnnotation(Min.class); + + Number minValue; + Number maxValue; + if (type.equals(int.class) || type.equals(Integer.class)) { + minValue = min != null ? min.intValue() : null; + maxValue = max.intValue(); + } else if (type.equals(long.class) || type.equals(Long.class)) { + minValue = min != null ? min.longValue() : null; + maxValue = max.longValue(); + } else if (type.equals(float.class) || type.equals(Float.class)) { + minValue = min != null ? min.floatValue() : null; + maxValue = max.floatValue(); + } else if (type.equals(double.class) || type.equals(Double.class)) { + minValue = min != null ? min.doubleValue() : null; + maxValue = max.doubleValue(); + } else { + throw new SecurityException(); + } + + return new DelegatingMapper<>(parentTypeMapper, max) { + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + Collection tabCompletions = new ArrayList<>(super.tabComplete(sender, previousArguments, s)); + tabCompletions.removeIf(tabCompletion -> { + if (onlyNegative && !tabCompletion.startsWith("-")) return true; + Number value = super.map(sender, previousArguments, tabCompletion); + if (value == null) { + return false; + } + return comparator.applyAsInt(value) > compareValue; + }); + if (tabCompletions.isEmpty()) { + if (minValue != null && min.inclusive()) { + tabCompletions.add(minValue.toString()); + } + if (max.inclusive()) { + tabCompletions.add(maxValue.toString()); + } + } + return tabCompletions; + } + }; + } + + @Override + public int getValidatorPriority() { + return 2; + } + + @Override + public AbstractTypeValidator getValidator(Max max, Parameter parameter, int index, DataReadable dataReadable) { + Class type = parameter.getType(); + if (parameter.isVarArgs()) type = type.getComponentType(); + + Number maxValue; + if (type.equals(int.class) || type.equals(Integer.class)) { + maxValue = max.intValue(); + } else if (type.equals(long.class) || type.equals(Long.class)) { + maxValue = max.longValue(); + } else if (type.equals(float.class) || type.equals(Float.class)) { + maxValue = max.floatValue(); + } else if (type.equals(double.class) || type.equals(Double.class)) { + maxValue = max.doubleValue(); + } else { + throw new SecurityException(); + } + + int compareValue = max.inclusive() ? 0 : -1; + ToIntFunction comparator = CommandUtils.createComparator("Max", type, max.intValue(), max.longValue(), max.floatValue(), max.doubleValue()); + + return (sender, value, messageSender) -> { + if (value == null) return true; + if (comparator.applyAsInt(value) <= compareValue) { + return true; + } else { + String error = max.error(); + if (error != null && !error.isEmpty()) messageSender.send(error, value, maxValue); + return false; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxReferenceHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxReferenceHandler.java new file mode 100644 index 00000000..05ae49c2 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MaxReferenceHandler.java @@ -0,0 +1,143 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.*; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Name; +import de.steamwar.command.graph.NodeData; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.function.ToIntFunction; + +public final class MaxReferenceHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Max.Reference annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Max.Reference annotation cannot be used on first parameter"); + } + + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != float.class && type != Float.class && type != double.class && type != Double.class) { + throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number."); + } + + Parameter[] parameters = parameter.getDeclaringExecutable().getParameters(); + for (int i = index - 1; i >= 1; i--) { + Parameter toCheck = parameters[i]; + Name name = toCheck.getAnnotation(Name.class); + String parameterName; + if (name == null) { + parameterName = toCheck.getName(); + } else { + parameterName = name.value(); + } + if (!parameterName.equals(annotation.value())) { + continue; + } + Class parameterType = toCheck.getType(); + if (!type.isAssignableFrom(parameterType)) { + throw new UnsupportedOperationException("Parameter type being referenced cannot be assigned here!"); + } else { + return; + } + } + throw new UnsupportedOperationException("Parameter with name '" + annotation.value() + "' does not exist."); + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(Max.Reference maxReference, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + Class finalType = type; + + String name = maxReference.value(); + int compareValue = maxReference.inclusive() ? 0 : -1; + + return new DelegatingMapper<>(parentTypeMapper, maxReference) { + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + Number number = previousArguments.getByName(name); + if (number == null) return Collections.emptyList(); + + ToIntFunction comparator = CommandUtils.createComparator("Max.Reference", finalType, number.intValue(), number.longValue(), number.floatValue(), number.doubleValue()); + boolean onlyNegative = comparator.applyAsInt(0) >= 0; + + Collection tabCompletions = new ArrayList<>(super.tabComplete(sender, previousArguments, s)); + tabCompletions.removeIf(tabCompletion -> { + if (onlyNegative && !tabCompletion.startsWith("-")) return true; + Number value = super.map(sender, previousArguments, tabCompletion); + if (value == null) { + return false; + } + return comparator.applyAsInt(value) > compareValue; + }); + if (tabCompletions.isEmpty() && maxReference.inclusive()) { + tabCompletions.add(number + ""); + } + return tabCompletions; + } + }; + } + + @Override + public int getValidatorPriority() { + return 2; + } + + @Override + public AbstractTypeValidator getValidator(Max.Reference maxReference, Parameter parameter, int index, DataReadable dataReadable) { + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + Class finalType = type; + + String name = maxReference.value(); + int compareValue = maxReference.inclusive() ? 0 : -1; + + return (sender, value, messageSender) -> { + Number number = (Number)((NodeData) messageSender).getByName(name); + if (number == null) return false; + + ToIntFunction comparator = CommandUtils.createComparator("Max.Reference", finalType, number.intValue(), number.longValue(), number.floatValue(), number.doubleValue()); + if (value == null) return true; + if (comparator.applyAsInt(value) <= compareValue) { + return true; + } else { + String error = maxReference.error(); + if (error != null && !error.isEmpty()) messageSender.send(error, value, number); + return false; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinHandler.java new file mode 100644 index 00000000..97ca3bbb --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinHandler.java @@ -0,0 +1,147 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.*; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.ToIntFunction; + +public final class MinHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Min min, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Min annotation cannot be used on first parameter"); + } + Class type = parameter.getType(); + if (parameter.isVarArgs()) type = type.getComponentType(); + if (type == int.class || type == Integer.class) return; + if (type == long.class || type == Long.class) return; + if (type == float.class || type == Float.class) return; + if (type == double.class || type == Double.class) return; + throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number."); + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(Min min, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + Class type = parameter.getType(); + if (parameter.isVarArgs()) type = type.getComponentType(); + + int compareValue = min.inclusive() ? 0 : 1; + ToIntFunction comparator = CommandUtils.createComparator("Min", type, min.intValue(), min.longValue(), min.floatValue(), min.doubleValue()); + boolean onlyPositive = comparator.applyAsInt(0) < 0; + + Max max = parameter.getAnnotation(Max.class); + + Number minValue; + Number maxValue; + if (type.equals(int.class) || type.equals(Integer.class)) { + minValue = min.intValue(); + maxValue = max != null ? max.intValue() : null; + } else if (type.equals(long.class) || type.equals(Long.class)) { + minValue = min.longValue(); + maxValue = max != null ? max.longValue() : null; + } else if (type.equals(float.class) || type.equals(Float.class)) { + minValue = min.floatValue(); + maxValue = max != null ? max.floatValue() : null; + } else if (type.equals(double.class) || type.equals(Double.class)) { + minValue = min.doubleValue(); + maxValue = max != null ? max.doubleValue() : null; + } else { + throw new SecurityException(); + } + + return new DelegatingMapper<>(parentTypeMapper, min) { + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + Collection tabCompletions = new ArrayList<>(super.tabComplete(sender, previousArguments, s)); + tabCompletions.removeIf(tabCompletion -> { + if (onlyPositive && tabCompletion.startsWith("-")) return true; + Number value = super.map(sender, previousArguments, tabCompletion); + if (value == null) { + return false; + } + return comparator.applyAsInt(value) < compareValue; + }); + if (tabCompletions.isEmpty()) { + if (min.inclusive()) { + tabCompletions.add(minValue.toString()); + } + if (maxValue != null && max.inclusive()) { + tabCompletions.add(maxValue.toString()); + } + } + return tabCompletions; + } + }; + } + + @Override + public int getValidatorPriority() { + return 2; + } + + @Override + public AbstractTypeValidator getValidator(Min min, Parameter parameter, int index, DataReadable dataReadable) { + Class type = parameter.getType(); + if (parameter.isVarArgs()) type = type.getComponentType(); + + Number minValue; + if (type.equals(int.class) || type.equals(Integer.class)) { + minValue = min.intValue(); + } else if (type.equals(long.class) || type.equals(Long.class)) { + minValue = min.longValue(); + } else if (type.equals(float.class) || type.equals(Float.class)) { + minValue = min.floatValue(); + } else if (type.equals(double.class) || type.equals(Double.class)) { + minValue = min.doubleValue(); + } else { + throw new SecurityException(); + } + + int compareValue = min.inclusive() ? 0 : 1; + ToIntFunction comparator = CommandUtils.createComparator("Min", type, min.intValue(), min.longValue(), min.floatValue(), min.doubleValue()); + + return (sender, value, messageSender) -> { + if (value == null) return true; + if (comparator.applyAsInt(value) >= compareValue) { + return true; + } else { + String error = min.error(); + if (error != null && !error.isEmpty()) messageSender.send(error, value, minValue); + return false; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinReferenceHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinReferenceHandler.java new file mode 100644 index 00000000..3b0faaf0 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/MinReferenceHandler.java @@ -0,0 +1,143 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.*; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Name; +import de.steamwar.command.graph.NodeData; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.function.ToIntFunction; + +public final class MinReferenceHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Min.Reference annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Min.Reference annotation cannot be used on first parameter"); + } + + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != float.class && type != Float.class && type != double.class && type != Double.class) { + throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a number."); + } + + Parameter[] parameters = parameter.getDeclaringExecutable().getParameters(); + for (int i = index - 1; i >= 1; i--) { + Parameter toCheck = parameters[i]; + Name name = toCheck.getAnnotation(Name.class); + String parameterName; + if (name == null) { + parameterName = toCheck.getName(); + } else { + parameterName = name.value(); + } + if (!parameterName.equals(annotation.value())) { + continue; + } + Class parameterType = toCheck.getType(); + if (!type.isAssignableFrom(parameterType)) { + throw new UnsupportedOperationException("Parameter type being referenced cannot be assigned here!"); + } else { + return; + } + } + throw new UnsupportedOperationException("Parameter with name '" + annotation.value() + "' does not exist."); + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(Min.Reference minReference, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + Class finalType = type; + + String name = minReference.value(); + int compareValue = minReference.inclusive() ? 0 : 1; + + return new DelegatingMapper<>(parentTypeMapper, minReference) { + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + Number number = previousArguments.getByName(name); + if (number == null) return Collections.emptyList(); + + ToIntFunction comparator = CommandUtils.createComparator("Min.Reference", finalType, number.intValue(), number.longValue(), number.floatValue(), number.doubleValue()); + boolean onlyPositive = comparator.applyAsInt(0) < 0; + + Collection tabCompletions = new ArrayList<>(super.tabComplete(sender, previousArguments, s)); + tabCompletions.removeIf(tabCompletion -> { + if (onlyPositive && tabCompletion.startsWith("-")) return true; + Number value = super.map(sender, previousArguments, tabCompletion); + if (value == null) { + return false; + } + return comparator.applyAsInt(value) < compareValue; + }); + if (tabCompletions.isEmpty() && minReference.inclusive()) { + tabCompletions.add(number + ""); + } + return tabCompletions; + } + }; + } + + @Override + public int getValidatorPriority() { + return 2; + } + + @Override + public AbstractTypeValidator getValidator(Min.Reference minReference, Parameter parameter, int index, DataReadable dataReadable) { + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + Class finalType = type; + + String name = minReference.value(); + int compareValue = minReference.inclusive() ? 0 : 1; + + return (sender, value, messageSender) -> { + Number number = (Number)((NodeData) messageSender).getByName(name); + if (number == null) return false; + + ToIntFunction comparator = CommandUtils.createComparator("Min.Reference", finalType, number.intValue(), number.longValue(), number.floatValue(), number.doubleValue()); + if (value == null) return true; + if (comparator.applyAsInt(value) >= compareValue) { + return true; + } else { + String error = minReference.error(); + if (error != null && !error.isEmpty()) messageSender.send(error, value, number); + return false; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/OptionalValueHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/OptionalValueHandler.java new file mode 100644 index 00000000..722300d7 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/OptionalValueHandler.java @@ -0,0 +1,80 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.OptionalValue; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; + +/** + * This special Handler is just for validating the OptionalValue annotation. + */ +public final class OptionalValueHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(OptionalValue annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("OptionalValue annotation cannot be used on the first parameter"); + } + if (parameter.isVarArgs() || parameter.getType().isArray()) { + throw new UnsupportedOperationException("OptionalValue annotation cannot be used on varargs or array parameters"); + } + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(OptionalValue annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + String defaultValue = annotation.value(); + boolean onlyUseIfNoneIsGiven = annotation.onlyUINIG(); + + return new DelegatingMapper<>(parentTypeMapper, annotation) { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + if (s != null) { + Object value = delegate.map(sender, previousArguments, s); + if (value != null) { + return value; + } + } + if (previousArguments.hasMoreArguments && onlyUseIfNoneIsGiven) { + return null; + } + previousArguments.usedOptionalValue(); + return delegate.map(sender, previousArguments, defaultValue); + } + + @Override + public boolean appendNextElementTabCompletions() { + return !onlyUseIfNoneIsGiven; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegexHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegexHandler.java new file mode 100644 index 00000000..39b16ff7 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegexHandler.java @@ -0,0 +1,60 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.Regex; + +import java.lang.reflect.Parameter; +import java.util.regex.Pattern; + +public final class RegexHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Regex annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Regex annotation cannot be used on first parameter"); + } + if (parameter.getType() != String.class) { + throw new UnsupportedOperationException("Regex annotation cannot be used on String parameter"); + } + } + + @Override + public int getValidatorPriority() { + return 0; + } + + @Override + public AbstractTypeValidator getValidator(Regex annotation, Parameter parameter, int index, DataReadable dataReadable) { + Pattern regex = Pattern.compile(annotation.value()); + String error = annotation.error(); + return (sender, value, messageSender) -> { + if (value == null) return true; + if (regex.matcher(value).matches()) return true; + messageSender.send(error); + return false; + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegisterHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegisterHandler.java new file mode 100644 index 00000000..03e26b5a --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/RegisterHandler.java @@ -0,0 +1,97 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.CommandUtils; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.Register; + +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.List; + +public final class RegisterHandler { + + public static final class Impl implements Handler.HandlerMethod { + + @Override + public void check(de.steamwar.command.annotations.Register annotation, Method method, DataCheckable dataCheckable) throws Exception { + if (method.getParameterCount() == 0) { + throw new UnsupportedOperationException("Register method must have at least one parameter"); + } + if (method.getReturnType() != void.class) { + throw new UnsupportedOperationException("Register method must return void"); + } + if (!dataCheckable.hasExecutorMapper(method.getParameterTypes()[0])) { + throw new UnsupportedOperationException("Register method first parameter must have a executor mapper registered"); + } + + Parameter[] parameters = method.getParameters(); + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + List annotationList = CommandUtils.getAnnotations(parameter); + if (annotationList.isEmpty()) { + if (i == 0) { + continue; + } + + Class type = parameter.getType(); + if (type.isArray()) { + type = type.getComponentType(); + } + if (!type.isEnum() && !dataCheckable.hasMapper(type.getName())) { + throw new UnsupportedOperationException("Register method parameter " + parameter.getName() + " must be annotated or have a type mapper"); + } + } else { + for (Annotation annotation1 : annotationList) { + getParameterHandler(annotation1).check(annotation1, parameter, i, dataCheckable); + } + } + } + } + + public static HandlerParameter getParameterHandler(Annotation annotation) { + Implementation handler = annotation.annotationType().getAnnotation(Implementation.class); + Handler handlerObject; + try { + handlerObject = handler.value().getConstructor().newInstance(); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | + InvocationTargetException e) { + throw new UnsupportedOperationException("Handler " + handler.value().getName() + " cannot be used to check the argument validity", e); + } + if (!(handlerObject instanceof HandlerParameter)) { + throw new UnsupportedOperationException("Handler " + handlerObject.getClass().getName() + " is not a HandlerParameter"); + } + return (HandlerParameter) handlerObject; + } + + @Override + public int getRunPriority() { + return Integer.MAX_VALUE; + } + + @Override + public void run(de.steamwar.command.annotations.Register annotation, Method method, DataWritable dataWritable) { + dataWritable.addCommand(method, annotation.value(), annotation.description(), annotation.noTabComplete()); + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StartsWithHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StartsWithHandler.java new file mode 100644 index 00000000..1cdeb6e0 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StartsWithHandler.java @@ -0,0 +1,84 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.StartsWith; +import de.steamwar.command.mapper.internal.DelegatingMapper; + +import java.lang.reflect.Parameter; +import java.util.Collection; +import java.util.stream.Collectors; + +public final class StartsWithHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(StartsWith annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("StartsWith annotation cannot be used on first parameter"); + } + if (parameter.getType() != String.class) { + throw new UnsupportedOperationException("StartsWith annotation cannot be used on String parameter"); + } + } + + @Override + public boolean needsParentTypeMapper() { + return true; + } + + @Override + public AbstractTypeMapper getTypeMapper(StartsWith annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + String startsWith = annotation.value(); + + return new DelegatingMapper<>(parentTypeMapper, annotation) { + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return super.tabComplete(sender, previousArguments, s).stream().map(s1 -> { + if (s1.startsWith(startsWith)) return s1; + return startsWith + s1; + }).collect(Collectors.toList()); + } + }; + } + + @Override + public int getValidatorPriority() { + return 0; + } + + @Override + public AbstractTypeValidator getValidator(StartsWith annotation, Parameter parameter, int index, DataReadable dataReadable) { + String startsWith = annotation.value(); + String error = annotation.error(); + return (sender, value, messageSender) -> { + if (value == null) return true; + if (value.startsWith(startsWith)) return true; + messageSender.send(error); + return false; + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StaticValueHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StaticValueHandler.java new file mode 100644 index 00000000..3f0de9dd --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/StaticValueHandler.java @@ -0,0 +1,105 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.StaticValue; +import de.steamwar.command.mapper.SimpleMapper; + +import java.lang.reflect.Parameter; +import java.util.*; + +@Deprecated +public final class StaticValueHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(StaticValue annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("StaticValue annotation cannot be used on first parameter"); + } + Class type = parameter.getType(); + if (type == String.class) return; + if (type == int.class || type == Integer.class) return; + if (type == long.class || type == Long.class) return; + if (type == boolean.class || type == Boolean.class) return; + throw new UnsupportedOperationException("StaticValue parameter must be String, int, long or boolean"); + } + + @Override + public AbstractTypeMapper getTypeMapper(StaticValue annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + Class type = parameter.getType(); + if (type == String.class) { + return (AbstractTypeMapper) new SimpleMapper(annotation.value()); + } + + List tabCompletes = new ArrayList<>(Arrays.asList(annotation.value())); + if (type == boolean.class || type == Boolean.class) { + Set falseValues = new HashSet<>(); + for (int i : annotation.falseValues()) { + falseValues.add(i); + } + return new AbstractTypeMapper<>() { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + int index = tabCompletes.indexOf(s); + return index == -1 ? null : !falseValues.contains(index); + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return tabCompletes; + } + }; + } + + if (type == long.class || type == Long.class) { + return new AbstractTypeMapper<>() { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + long index = tabCompletes.indexOf(s); + return index == -1L ? null : index; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return tabCompletes; + } + }; + } + + return new AbstractTypeMapper<>() { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + int index = tabCompletes.indexOf(s); + return index == -1 ? null : index; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return tabCompletes; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java new file mode 100644 index 00000000..a620b34c --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/SupplierHandler.java @@ -0,0 +1,99 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.AbstractTypeSupplier; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.AllowNull; +import de.steamwar.command.annotations.Name; +import de.steamwar.command.annotations.Supplier; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Arrays; +import java.util.Optional; + +public final class SupplierHandler { + + public static final class Impl implements Handler.HandlerMethod, Handler.HandlerParameter { + + @Override + public void check(Supplier annotation, Method method, DataCheckable dataCheckable) throws Exception { + if (method.getParameterCount() != 0) { + throw new UnsupportedOperationException("Supplier method must have no parameters"); + } + if (!AbstractTypeMapper.class.isAssignableFrom(method.getReturnType())) { + throw new UnsupportedOperationException("Supplier method must return AbstractTypeMapper"); + } + + if (annotation.value() != null && !annotation.value().isEmpty()) { + return; + } + + Optional> genericType = getGenericTypeOfReturn(method); + if (annotation.type() == void.class) { + if (genericType.isEmpty()) { + throw new UnsupportedOperationException("Please supply a class type to the Supplier"); + } + } else { + if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) { + throw new UnsupportedOperationException("Supplied type does not conform to actual type"); + } + } + } + + @Override + public int getRunPriority() { + return Integer.MIN_VALUE; + } + + @Override + public void run(Supplier annotation, Method method, DataWritable dataWritable) { + AbstractTypeSupplier abstractTypeSupplier = dataWritable.invoke(method); + if (annotation.value() != null && !annotation.value().isEmpty()) { + dataWritable.addSupplier(annotation.value(), annotation.local(), abstractTypeSupplier); + } else { + Class type = annotation.type(); + if (type == void.class) type = getGenericTypeOfReturn(method).get(); + dataWritable.addSupplier(type.getName(), annotation.local(), abstractTypeSupplier); + } + } + + @Override + public void check(Supplier annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Supplier annotation cannot be used on the first parameter"); + } + String s = annotation.value() != null && !annotation.value().isEmpty() ? annotation.value() : parameter.getType().getTypeName(); + if (!dataCheckable.hasSupplier(s)) { + throw new UnsupportedOperationException("Supplier '" + annotation.value() + "' not found"); + } + boolean hasDisallowedAnnotations = Arrays.stream(parameter.getAnnotations()) + .filter(anno -> !(anno instanceof Supplier)) + .filter(anno -> !(anno instanceof AllowNull)) + .filter(anno -> !(anno instanceof Name)) + .anyMatch(anno -> anno.getClass().isAnnotationPresent(Implementation.class)); + if (hasDisallowedAnnotations) { + throw new UnsupportedOperationException("Only AllowNull or Name can be used in conjunction with Supplier annotation"); + } + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/TabFilterHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/TabFilterHandler.java new file mode 100644 index 00000000..8c42ee1b --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/TabFilterHandler.java @@ -0,0 +1,49 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.TabFilter; +import de.steamwar.command.annotations.TabFilterType; + +import java.lang.reflect.Parameter; + +/** + * This special Handler is just for validating the TabFilter annotation. + */ +public final class TabFilterHandler { + + public static TabFilterType getTabFilterType(Parameter parameter) { + if (!parameter.isAnnotationPresent(TabFilter.class)) { + return TabFilterType.STARTS_WITH; + } + return parameter.getAnnotation(TabFilter.class).value(); + } + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(TabFilter annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("TabFilter annotation cannot be used on first parameter"); + } + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/UniqueHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/UniqueHandler.java new file mode 100644 index 00000000..a659ed3b --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/UniqueHandler.java @@ -0,0 +1,48 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.Unique; + +import java.lang.reflect.Parameter; + +/** + * This special Handler is just for validating the Unique annotation. + */ +public final class UniqueHandler { + + public static boolean isPresent(Parameter parameter) { + return parameter.isAnnotationPresent(Unique.class); + } + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Unique annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Unique annotation cannot be used on the first parameter"); + } + if (!parameter.getType().isArray() && !parameter.isVarArgs()) { + throw new UnsupportedOperationException("Unique annotation cannot be used on non array types"); + } + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java new file mode 100644 index 00000000..ed1f3889 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValidatorHandler.java @@ -0,0 +1,94 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeValidator; +import de.steamwar.command.Handler; +import de.steamwar.command.annotations.Validator; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Optional; + +public final class ValidatorHandler { + + public static final class Impl implements Handler.HandlerMethod, Handler.HandlerParameter { + + @Override + public void check(Validator annotation, Method method, DataCheckable dataCheckable) throws Exception { + if (method.getParameterCount() != 0) { + throw new UnsupportedOperationException("Validator method must have no parameters"); + } + if (!AbstractTypeValidator.class.isAssignableFrom(method.getReturnType())) { + throw new UnsupportedOperationException("Validator method must return AbstractValidator"); + } + + if (annotation.value() != null && !annotation.value().isEmpty()) { + return; + } + + Optional> genericType = getGenericTypeOfReturn(method); + if (annotation.type() == void.class) { + if (genericType.isEmpty()) { + throw new UnsupportedOperationException("Please supply a class type to the Validator"); + } + } else { + if (genericType.isPresent() && !annotation.type().isAssignableFrom(genericType.get())) { + throw new UnsupportedOperationException("Supplied type does not conform to actual type"); + } + } + } + + @Override + public int getRunPriority() { + return Integer.MIN_VALUE; + } + + @Override + public void run(Validator annotation, Method method, DataWritable dataWritable) { + AbstractTypeValidator abstractTypeValidator = dataWritable.invoke(method); + if (annotation.value() != null && !annotation.value().isEmpty()) { + dataWritable.addValidator(annotation.value(), annotation.local(), abstractTypeValidator); + } else { + Class type = annotation.type(); + if (type == void.class) type = getGenericTypeOfReturn(method).get(); + dataWritable.addValidator(type.getName(), annotation.local(), abstractTypeValidator); + } + } + + @Override + public void check(Validator annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + String s = annotation.value() != null && !annotation.value().isEmpty() ? annotation.value() : parameter.getType().getTypeName(); + if (!dataCheckable.hasValidator(s)) { + throw new UnsupportedOperationException("Validator '" + annotation.value() + "' not found"); + } + } + + @Override + public AbstractTypeValidator getValidator(Validator annotation, Parameter parameter, int index, DataReadable dataReadable) { + String s = annotation.value() != null && !annotation.value().isEmpty() ? annotation.value() : parameter.getType().getTypeName(); + AbstractTypeValidator abstractTypeValidator = dataReadable.getValidator(s); + if (abstractTypeValidator == null) { + throw new IllegalArgumentException("No validator found for '" + s + "'"); + } + return annotation.invert() ? abstractTypeValidator.not() : abstractTypeValidator; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesHandler.java new file mode 100644 index 00000000..6a50d803 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesHandler.java @@ -0,0 +1,104 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Values; +import de.steamwar.command.mapper.SimpleMapper; + +import java.lang.reflect.Parameter; +import java.util.*; + +public final class ValuesHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Values annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Values annotation cannot be used on first parameter"); + } + Class type = parameter.getType(); + if (type == String.class) return; + if (type == int.class || type == Integer.class) return; + if (type == long.class || type == Long.class) return; + if (type == boolean.class || type == Boolean.class) return; + throw new UnsupportedOperationException("Values parameter must be String, int, long or boolean"); + } + + @Override + public AbstractTypeMapper getTypeMapper(Values annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + Class type = parameter.getType(); + if (type == String.class) { + return (AbstractTypeMapper) new SimpleMapper(annotation.value()); + } + + List tabCompletes = new ArrayList<>(Arrays.asList(annotation.value())); + if (type == boolean.class || type == Boolean.class) { + Set falseValues = new HashSet<>(); + for (int i : annotation.falseValues()) { + falseValues.add(i); + } + return new AbstractTypeMapper<>() { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + int index = tabCompletes.indexOf(s); + return index == -1 ? null : !falseValues.contains(index); + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return tabCompletes; + } + }; + } + + if (type == long.class || type == Long.class) { + return new AbstractTypeMapper<>() { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + long index = tabCompletes.indexOf(s); + return index == -1L ? null : index; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return tabCompletes; + } + }; + } + + return new AbstractTypeMapper<>() { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + int index = tabCompletes.indexOf(s); + return index == -1 ? null : index; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return tabCompletes; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesReferenceHandler.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesReferenceHandler.java new file mode 100644 index 00000000..653e723d --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/handler/ValuesReferenceHandler.java @@ -0,0 +1,159 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.handler; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.Handler; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Name; +import de.steamwar.command.annotations.Values; +import de.steamwar.command.mapper.internal.DelegatingMapper; +import de.steamwar.command.utils.ClassEquality; + +import java.lang.reflect.Parameter; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +public class ValuesReferenceHandler { + + public static final class Impl implements Handler.HandlerParameter { + + @Override + public void check(Values.Reference annotation, Parameter parameter, int index, DataCheckable dataCheckable) throws Exception { + if (index == 0) { + throw new UnsupportedOperationException("Values.Reference annotation cannot be used on first parameter"); + } + + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + if (type != int.class && type != Integer.class && type != long.class && type != Long.class && type != String.class) { + throw new UnsupportedOperationException("Parameter " + index + " of " + parameter.getDeclaringExecutable() + " is not a String or Int or Long."); + } + + Parameter[] parameters = parameter.getDeclaringExecutable().getParameters(); + for (int i = index - 1; i >= 1; i--) { + Parameter toCheck = parameters[i]; + Name name = toCheck.getAnnotation(Name.class); + String parameterName; + if (name == null) { + parameterName = toCheck.getName(); + } else { + parameterName = name.value(); + } + if (!parameterName.equals(annotation.value())) { + continue; + } + Class toCheckType = toCheck.getType(); + if (toCheckType.isArray()) toCheckType = toCheckType.getComponentType(); + if (!ClassEquality.classEquals(type, toCheckType)) { + throw new UnsupportedOperationException("Parameter type being referenced cannot be assigned here!"); + } else { + return; + } + } + throw new UnsupportedOperationException("Parameter with name '" + annotation.value() + "' does not exist."); + } + + @Override + public AbstractTypeMapper getTypeMapper(Values.Reference annotation, Parameter parameter, int index, DataReadable dataReadable, AbstractTypeMapper parentTypeMapper) { + Class type = parameter.getType(); + if (type.isArray()) type = type.getComponentType(); + + String name = annotation.value(); + + AbstractTypeMapper tabCompleter = new AbstractTypeMapper<>() { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + return null; // This is not implemented since the delegators will override it + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + Object valueOrValues = previousArguments.getByName(name); + if (valueOrValues instanceof String) { + return Collections.singleton((String) valueOrValues); + } + if (valueOrValues instanceof String[]) { + return Arrays.asList((String[]) valueOrValues); + } + return null; + } + }; + + if (type == String.class) { + return new DelegatingMapper<>(tabCompleter, null) { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + Object valueOrValues = previousArguments.getByName(name); + if (valueOrValues instanceof String) { + if (s.equalsIgnoreCase((String) valueOrValues)) return s; + else return null; + } + + if (!(valueOrValues instanceof String[])) return null; + for (String t : (String[]) valueOrValues) { + if (s.equalsIgnoreCase(t)) return s; + } + return null; + } + }; + } + + if (type == long.class || type == Long.class) { + return new DelegatingMapper<>(tabCompleter, null) { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + Object valueOrValues = previousArguments.getByName(name); + if (valueOrValues instanceof String) { + if (s.equalsIgnoreCase((String) valueOrValues)) return 0L; + else return null; + } + + if (!(valueOrValues instanceof String[])) return null; + String[] strings = (String[]) valueOrValues; + for (int i = 0; i < strings.length; i++) { + if (s.equalsIgnoreCase(strings[i])) return (long) i; + } + return null; + } + }; + } + + return new DelegatingMapper<>(tabCompleter, null) { + @Override + public Object map(Object sender, PreviousArguments previousArguments, String s) { + Object valueOrValues = previousArguments.getByName(name); + if (valueOrValues instanceof String) { + if (s.equalsIgnoreCase((String) valueOrValues)) return 0; + else return null; + } + + if (!(valueOrValues instanceof String[])) return null; + String[] strings = (String[]) valueOrValues; + for (int i = 0; i < strings.length; i++) { + if (s.equalsIgnoreCase(strings[i])) return i; + } + return null; + } + }; + } + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/BooleanMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/BooleanMapper.java new file mode 100644 index 00000000..0128f70f --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/BooleanMapper.java @@ -0,0 +1,41 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.PreviousArguments; + +import java.util.Arrays; +import java.util.Collection; + +public class BooleanMapper implements AbstractTypeMapper { + + @Override + public Boolean map(Object sender, PreviousArguments previousArguments, String s) { + if (s.equalsIgnoreCase("true")) return true; + if (s.equalsIgnoreCase("false")) return false; + return null; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return Arrays.asList("true", "false"); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/EnumMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/EnumMapper.java new file mode 100644 index 00000000..b09ffa0b --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/EnumMapper.java @@ -0,0 +1,50 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.PreviousArguments; + +import java.util.*; + +public class EnumMapper implements AbstractTypeMapper> { + + private Map> enumMap; + private Set tabCompletions = new HashSet<>(); + + public EnumMapper(Class> enumClass) { + Map> enumMap = new HashMap<>(); + for (Enum e : enumClass.getEnumConstants()) { + enumMap.put(e.name().toLowerCase(), e); + tabCompletions.add(e.name()); + } + this.enumMap = enumMap; + } + + @Override + public Enum map(Object sender, PreviousArguments previousArguments, String s) { + return enumMap.get(s.toLowerCase()); + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return tabCompletions; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/NumberMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/NumberMapper.java new file mode 100644 index 00000000..0817f095 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/NumberMapper.java @@ -0,0 +1,95 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.PreviousArguments; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class NumberMapper implements AbstractTypeMapper { + + private Function function; + private boolean comma; + + public NumberMapper(Function function, boolean comma) { + this.function = function; + this.comma = comma; + } + + @Override + public Number map(Object sender, PreviousArguments previousArguments, String s) { + if (s.equalsIgnoreCase("nan")) return null; + try { + return function.apply(s); + } catch (NumberFormatException e) { + // Ignored + } + if (!comma) return null; + try { + return function.apply(s.replace(',', '.')); + } catch (NumberFormatException e) { + return null; + } + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + List strings = new ArrayList<>(); + strings.add(s); + for (int i = 0; i < 10; i++) { + strings.add(s + i); + } + strings = strings.stream() + .map(t -> { + Number number = map(sender, previousArguments, t); + if (number == null) return null; + String value = number + ""; + if (value.endsWith(".0")) return value.substring(0, value.length() - 2); + return value; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + if (comma) { + Number number = map(sender, previousArguments, s + "."); + if (number != null) { + String value = number + ""; + if (value.endsWith(".0")) { + strings.add(value.substring(0, value.length() - 1)); + } else { + strings.add(value); + } + } + } + if (s.isEmpty()) { + strings.add("-"); + } + strings = strings.stream() + .distinct() + .collect(Collectors.toList()); + strings.remove("-0"); + return strings; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/OptionEnumMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/OptionEnumMapper.java new file mode 100644 index 00000000..df72601c --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/OptionEnumMapper.java @@ -0,0 +1,80 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.OptionEnum; +import de.steamwar.command.PreviousArguments; + +import java.util.*; + +public class OptionEnumMapper implements AbstractTypeMapper> { + + private Class> enumClass; + private List> optionEnums = new ArrayList<>(); + + public & OptionEnum> OptionEnumMapper(Class enumClass) { + this.enumClass = (Class) enumClass; + + for (Enum enumConstant : enumClass.getEnumConstants()) { + optionEnums.add((OptionEnum) enumConstant); + } + } + + private Set> getRemoved(PreviousArguments previousArguments) { + Set> removed = new HashSet<>(); + for (OptionEnum optionEnum : previousArguments.getAll(enumClass)) { + removed.add(optionEnum); + Collections.addAll(removed, (OptionEnum[]) optionEnum.getRemoved()); + } + return removed; + } + + @Override + public Enum map(Object sender, PreviousArguments previousArguments, String s) { + Set> removed = getRemoved(previousArguments); + + for (OptionEnum optionEnum : optionEnums) { + if (removed.contains(optionEnum)) { + continue; + } + List strings = optionEnum.getTabCompletes(); + for (String string : strings) { + if (string.equalsIgnoreCase(s)) { + return (Enum) optionEnum; + } + } + } + return null; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + Set> removed = getRemoved(previousArguments); + + List tabCompletes = new ArrayList<>(); + for (OptionEnum optionEnum : optionEnums) { + if (!removed.contains(optionEnum)) { + tabCompletes.addAll(optionEnum.getTabCompletes()); + } + } + return tabCompletes; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/SimpleMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/SimpleMapper.java new file mode 100644 index 00000000..be0dc16b --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/SimpleMapper.java @@ -0,0 +1,56 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.PreviousArguments; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class SimpleMapper implements AbstractTypeMapper { + + private List elements; + private Set checkElements; + + public SimpleMapper(List elements) { + this.elements = elements; + this.checkElements = elements.stream() + .map(String::toLowerCase) + .collect(Collectors.toSet()); + } + + public SimpleMapper(String... elements) { + this(List.of(elements)); + } + + @Override + public String map(Object sender, PreviousArguments previousArguments, String s) { + if (checkElements.contains(s.toLowerCase())) return s; + return null; + } + + @Override + public Collection tabComplete(Object sender, PreviousArguments previousArguments, String s) { + return elements; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/ContainsFilter.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/ContainsFilter.java new file mode 100644 index 00000000..847f4abd --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/ContainsFilter.java @@ -0,0 +1,44 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper.internal; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.PreviousArguments; + +import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; + +public class ContainsFilter extends DelegatingMapper { + + public ContainsFilter(AbstractTypeMapper delegate) { + super(delegate, null); + } + + @Override + public Collection tabComplete(T sender, PreviousArguments previousArguments, String s) { + Collection tabCompletes = super.tabComplete(sender, previousArguments, s); + if (tabCompletes == null) return Collections.emptyList(); + String t = s.toLowerCase(); + return tabCompletes.stream() + .filter(tabComplete -> tabComplete.toLowerCase().contains(t)) + .collect(Collectors.toList()); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/DelegatingMapper.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/DelegatingMapper.java new file mode 100644 index 00000000..062e8804 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/DelegatingMapper.java @@ -0,0 +1,57 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper.internal; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.PreviousArguments; + +import java.lang.annotation.Annotation; +import java.util.Collection; + +public class DelegatingMapper implements AbstractTypeMapper { + + protected final AbstractTypeMapper delegate; + protected final Annotation annotation; + + public DelegatingMapper(AbstractTypeMapper delegate, Annotation annotation) { + this.delegate = delegate; + this.annotation = annotation; + } + + @Override + public T map(K sender, PreviousArguments previousArguments, String s) { + return delegate.map(sender, previousArguments, s); + } + + @Override + public Collection tabComplete(K sender, PreviousArguments previousArguments, String s) { + return delegate.tabComplete(sender, previousArguments, s); + } + + @Override + public boolean appendNextElementTabCompletions() { + return delegate.appendNextElementTabCompletions(); + } + + @Override + public String normalize(K sender, String s) { + return delegate.normalize(sender, s); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/StartsWithFilter.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/StartsWithFilter.java new file mode 100644 index 00000000..8ec31d2f --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/mapper/internal/StartsWithFilter.java @@ -0,0 +1,43 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper.internal; + +import de.steamwar.command.AbstractTypeMapper; +import de.steamwar.command.PreviousArguments; + +import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; + +public class StartsWithFilter extends DelegatingMapper { + + public StartsWithFilter(AbstractTypeMapper delegate) { + super(delegate, null); + } + + @Override + public Collection tabComplete(T sender, PreviousArguments previousArguments, String s) { + Collection tabCompletes = super.tabComplete(sender, previousArguments, s); + if (tabCompletes == null) return Collections.emptyList(); + return tabCompletes.stream() + .filter(tabComplete -> tabComplete.toLowerCase().startsWith(s.toLowerCase()) || s.toLowerCase().startsWith(tabComplete.toLowerCase())) + .collect(Collectors.toList()); + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/ClassEquality.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/ClassEquality.java new file mode 100644 index 00000000..7c17cb76 --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/ClassEquality.java @@ -0,0 +1,47 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.utils; + +public class ClassEquality { + + public static boolean classEquals(Class first, Class second) { + if (first.isPrimitive() && second.isPrimitive()) return first == second; + if (!first.isPrimitive() && !second.isPrimitive()) return first.isAssignableFrom(second); + first = toPrimitive(first); + second = toPrimitive(second); + if (first.isPrimitive() && second.isPrimitive()) return first == second; + return false; + } + + public static Class toPrimitive(Class clazz) { + if (clazz == Boolean.class) { + return boolean.class; + } else if (clazz == Integer.class) { + return int.class; + } else if (clazz == Long.class) { + return long.class; + } else if (clazz == Float.class) { + return float.class; + } else if (clazz == Double.class) { + return double.class; + } + return clazz; + } +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/Pair.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/Pair.java new file mode 100644 index 00000000..43f2648d --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/Pair.java @@ -0,0 +1,30 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.utils; + +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@ToString +@RequiredArgsConstructor +public class Pair { + public final A a; + public final B b; +} diff --git a/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/Triple.java b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/Triple.java new file mode 100644 index 00000000..a091995e --- /dev/null +++ b/CommandFramework/CommandFrameworkBase/src/de/steamwar/command/utils/Triple.java @@ -0,0 +1,31 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.utils; + +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +@ToString +@RequiredArgsConstructor +public class Triple { + public final A a; + public final B b; + public final C c; +} diff --git a/CommandFramework/CommandFrameworkSpigot/build.gradle.kts b/CommandFramework/CommandFrameworkSpigot/build.gradle.kts new file mode 100644 index 00000000..df5f969b --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/build.gradle.kts @@ -0,0 +1,33 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +plugins { + steamwar.java +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + implementation(project(":CommandFramework:CommandFrameworkBase", "default")) + + implementation(libs.spigotapi) +} \ No newline at end of file diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommand.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommand.java new file mode 100644 index 00000000..204acb51 --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommand.java @@ -0,0 +1,156 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import de.steamwar.command.mapper.GameModeMapper; +import de.steamwar.command.mapper.PlayerMapper; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Level; + +public class SpigotCommand extends AbstractCommand { + + static { + CommandUtils.addMapper(Player.class, new PlayerMapper()); + CommandUtils.addMapper(GameMode.class, new GameModeMapper()); + addExecutorMapper(SpigotCommand.class, CommandSender.class, Function.identity()); + } + + private Command command; + + /* + @Setter + private Message message = null; + */ + private List defaultHelpMessages = new ArrayList<>(); + + public SpigotCommand(String command, Consumer> initializer, String... aliases) { + super(command, initializer, aliases); + } + + public SpigotCommand(String command, String permission, Consumer> initializer, String... aliases) { + super(command, permission, initializer, aliases); + } + + @Override + protected synchronized void initCommand() { + this.command = new Command(SpigotCommand.super.command, "", "/" + command, Arrays.asList(aliases)) { + @Override + public boolean execute(CommandSender sender, String alias, String[] args) { + SpigotCommand.this.execute(sender, alias, args); + return false; + } + + @Override + public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { + return SpigotCommand.this.tabComplete(sender, alias, args); + } + }; + this.command.setPermission(permission); + } + + @Override + public void unregister() { + SpigotCommandRegistering.unregister(this.command); + } + + @Override + public void register() { + SpigotCommandRegistering.register(this.command); + } + + @Override + protected void commandSystemError(CommandSender sender, CommandFrameworkException e) { + Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e); + // TODO: Core.MESSAGE.sendPrefixless("COMMAND_SYSTEM_ERROR", sender); + } + + public void addDefaultHelpMessage(String message) { + defaultHelpMessages.add(message); + } + + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + // TODO: this.message.send(message, sender, args); + sender.sendMessage(MessageFormat.format(message, args)); + } + + /* TODO + @Register(noTabComplete = true) + public void internalHelp(Player p, String... args) { + if (message == null) { + return; + } + try { + message.sendPrefixless("COMMAND_HELP_HEAD", p, command.getName().substring(0, 1).toUpperCase() + command.getName().substring(1)); + 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 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.validator == null || subCommand.validator.validate(p, p, (s, args1) -> {})) { + 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); + } + } + */ +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommandFrameworkPlugin.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommandFrameworkPlugin.java new file mode 100644 index 00000000..ccd68be4 --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommandFrameworkPlugin.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import org.bukkit.plugin.java.JavaPlugin; + +public class SpigotCommandFrameworkPlugin extends JavaPlugin { +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommandRegistering.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommandRegistering.java new file mode 100644 index 00000000..8b059937 --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotCommandRegistering.java @@ -0,0 +1,65 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import lombok.experimental.UtilityClass; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandMap; +import org.bukkit.command.SimpleCommandMap; + +import java.lang.reflect.Field; +import java.util.Map; + +@UtilityClass +class SpigotCommandRegistering { + + private static final CommandMap commandMap; + private static final Map knownCommandMap; + + static { + try { + final Field commandMapField = Bukkit.getServer().getClass().getDeclaredField("commandMap"); + commandMapField.setAccessible(true); + commandMap = (CommandMap) commandMapField.get(Bukkit.getServer()); + } catch (NoSuchFieldException | IllegalAccessException exception) { + Bukkit.shutdown(); + throw new SecurityException("Oh shit. Commands cannot be registered.", exception); + } + try { + final Field knownCommandsField = SimpleCommandMap.class.getDeclaredField("knownCommands"); + knownCommandsField.setAccessible(true); + knownCommandMap = (Map) knownCommandsField.get(commandMap); + } catch (NoSuchFieldException | IllegalAccessException exception) { + Bukkit.shutdown(); + throw new SecurityException("Oh shit. Commands cannot be registered.", exception); + } + } + + static void unregister(Command command) { + knownCommandMap.remove(command.getName()); + command.getAliases().forEach(knownCommandMap::remove); + command.unregister(commandMap); + } + + static void register(Command command) { + commandMap.register("command_framework", command); + } +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeMapper.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeMapper.java new file mode 100644 index 00000000..ed87bede --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeMapper.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import org.bukkit.command.CommandSender; + +public interface SpigotTypeMapper extends AbstractTypeMapper { +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeSupplier.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeSupplier.java new file mode 100644 index 00000000..40c2dd88 --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeSupplier.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import org.bukkit.command.CommandSender; + +public interface SpigotTypeSupplier extends AbstractTypeSupplier { +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeValidator.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeValidator.java new file mode 100644 index 00000000..01839a77 --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/SpigotTypeValidator.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import org.bukkit.command.CommandSender; + +public interface SpigotTypeValidator extends AbstractTypeValidator { +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/mapper/GameModeMapper.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/mapper/GameModeMapper.java new file mode 100644 index 00000000..671e2777 --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/mapper/GameModeMapper.java @@ -0,0 +1,46 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.SpigotTypeMapper; +import org.bukkit.GameMode; +import org.bukkit.command.CommandSender; + +import java.util.Arrays; +import java.util.Collection; + +public class GameModeMapper implements SpigotTypeMapper { + + @Override + public GameMode map(CommandSender sender, PreviousArguments previousArguments, String s) { + s = s.toLowerCase(); + if (s.equals("s") || s.equals("survival") || s.equals("0")) return GameMode.SURVIVAL; + if (s.equals("c") || s.equals("creative") || s.equals("1")) return GameMode.CREATIVE; + if (s.equals("sp") || s.equals("spectator") || s.equals("3")) return GameMode.SPECTATOR; + if (s.equals("a") || s.equals("adventure") || s.equals("2")) return GameMode.ADVENTURE; + return null; + } + + @Override + public Collection tabComplete(CommandSender sender, PreviousArguments previousArguments, String s) { + return Arrays.asList("s", "survival", "0", "c", "creative", "1", "sp", "spectator", "3", "a", "adventure", "2"); + } +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/mapper/PlayerMapper.java b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/mapper/PlayerMapper.java new file mode 100644 index 00000000..fc155dfc --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/de/steamwar/command/mapper/PlayerMapper.java @@ -0,0 +1,44 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.SpigotTypeMapper; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.Collection; +import java.util.stream.Collectors; + +public class PlayerMapper implements SpigotTypeMapper { + + @Override + public Player map(CommandSender sender, PreviousArguments previousArguments, String s) { + return Bukkit.getPlayer(s); + } + + @Override + public Collection tabComplete(CommandSender sender, PreviousArguments previousArguments, String s) { + return Bukkit.getOnlinePlayers().stream() + .map(Player::getName) + .collect(Collectors.toList()); + } +} diff --git a/CommandFramework/CommandFrameworkSpigot/src/plugin.yml b/CommandFramework/CommandFrameworkSpigot/src/plugin.yml new file mode 100644 index 00000000..b5155ede --- /dev/null +++ b/CommandFramework/CommandFrameworkSpigot/src/plugin.yml @@ -0,0 +1,4 @@ +name: CommandFramework +main: de.steamwar.command.SpigotCommandFrameworkPlugin +version: 1.0 +author: YoyoNow diff --git a/CommandFramework/CommandFrameworkTests/build.gradle.kts b/CommandFramework/CommandFrameworkTests/build.gradle.kts new file mode 100644 index 00000000..dbe13757 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/build.gradle.kts @@ -0,0 +1,34 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +plugins { + steamwar.java +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + testImplementation(libs.junit) + testImplementation(libs.hamcrest) + + testImplementation(project(":CommandFramework:CommandFrameworkBase", "default")) +} \ No newline at end of file diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/AssertionUtils.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/AssertionUtils.java new file mode 100644 index 00000000..f376652c --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/AssertionUtils.java @@ -0,0 +1,124 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar; + +import de.steamwar.command.CommandFrameworkException; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestCommand; +import lombok.AllArgsConstructor; +import lombok.experimental.UtilityClass; + +import java.util.Arrays; +import java.util.List; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +@UtilityClass +public class AssertionUtils { + + @AllArgsConstructor + public static class SimpleAssertion { + + private T value; + + public SimpleAssertion assertNoInitialize(String message) { + try { + value.initialize(); + } catch (UnsupportedOperationException e) { + if (e.getCause() == null) { + assertThat(e.getMessage(), is(message)); + } else { + assertThat(e.getCause(), instanceOf(UnsupportedOperationException.class)); + assertThat(e.getCause().getMessage(), is(message)); + } + } catch (Exception e) { + error(value.getClass().getSimpleName() + " had an unexpected error while initializing"); + } + return this; + } + + public SimpleAssertion assertExecute(String message, String... arguments) { + try { + value.execute("", "", arguments); + error(value.getClass().getSimpleName() + " was not parsed."); + } catch (Exception e) { + assertCMDFramework(e, ExecutionIdentifier.class, message); + } + return this; + } + + public SimpleAssertion assertNoExecute(String... arguments) { + try { + value.execute("", "", arguments); + } catch (Exception e) { + error(value.getClass().getSimpleName() + " was parsed. It should not have been.", e); + } + return this; + } + + public SimpleAssertion assertTabCompletion(String[] expectedTabCompletions, String... arguments) { + return assertTabCompletion("", expectedTabCompletions, arguments); + } + + public SimpleAssertion assertTabCompletion(String sender, String[] expectedTabCompletions, String... arguments) { + try { + List tabCompletions = value.tabComplete(sender, "", arguments); + assertTabCompletes(tabCompletions, expectedTabCompletions); + } catch (Exception e) { + error(value.getClass().getSimpleName() + " tab-completion failed.", e); + } + return this; + } + } + + public static SimpleAssertion with(Object... commandObjects) { + return new SimpleAssertion<>(new TestCommand(stringCommandLoader -> { + for (Object commandObject : commandObjects) { + stringCommandLoader.add(commandObject); + } + })); + } + + public static void error(String message) { + throw new AssertionError(message); + } + + public static void error(String message, Throwable cause) { + throw new AssertionError(message, cause); + } + + public static void assertCMDFramework(Exception e, Class clazz, String message) { + if (clazz.isInstance(e)) { + assertThat(e.getMessage(), is(message)); + } else { + assertThat(e, is(instanceOf(CommandFrameworkException.class))); + assertThat(e.getCause().getCause(), is(instanceOf(clazz))); + assertThat(e.getCause().getCause().getMessage(), is(message)); + } + } + + public static void assertTabCompletes(List list, T... elements) { + assertThat(Arrays.asList(elements) + " -> " + list, list.size(), is(elements.length)); + if (elements.length > 0) { + assertThat(list, containsInAnyOrder(elements)); + } + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/ExecutionIdentifier.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/ExecutionIdentifier.java new file mode 100644 index 00000000..32397e1a --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/ExecutionIdentifier.java @@ -0,0 +1,26 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.impl; + +public class ExecutionIdentifier extends RuntimeException { + public ExecutionIdentifier(String message) { + super(message); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestCommand.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestCommand.java new file mode 100644 index 00000000..9169d674 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestCommand.java @@ -0,0 +1,76 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.impl; + +import de.steamwar.command.AbstractCommand; +import de.steamwar.command.CommandFrameworkException; +import de.steamwar.command.CommandLoader; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.function.Consumer; +import java.util.function.Function; + +public class TestCommand extends AbstractCommand { + + static { + addExecutorMapper(TestCommand.class, String.class, Function.identity()); + } + + public TestCommand(Consumer> initializer) { + super("", initializer); + } + + public void initialize() { + try { + Method method = AbstractCommand.class.getDeclaredMethod("initialize"); + method.setAccessible(true); + method.invoke(this); + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new SecurityException(e.getMessage()); + } catch (InvocationTargetException e) { + Throwable throwable = e.getTargetException(); + if (throwable instanceof RuntimeException) { + throw (RuntimeException) throwable; + } else { + throw new SecurityException(throwable); + } + } + } + + + @Override + protected void sendMessage(String sender, String message, Object[] args) { + throw new ExecutionIdentifier(message); + } + + @Override + public void unregister() { + } + + @Override + public void register() { + } + + @Override + protected void commandSystemError(String sender, CommandFrameworkException e) { + throw e; + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeMapper.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeMapper.java new file mode 100644 index 00000000..0b7d32fc --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeMapper.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.impl; + +import de.steamwar.command.AbstractTypeMapper; + +public interface TestTypeMapper extends AbstractTypeMapper { +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeSupplier.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeSupplier.java new file mode 100644 index 00000000..4a067fde --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeSupplier.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.impl; + +import de.steamwar.command.AbstractTypeSupplier; + +public interface TestTypeSupplier extends AbstractTypeSupplier { +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeValidator.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeValidator.java new file mode 100644 index 00000000..48dd7258 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/impl/TestTypeValidator.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.impl; + +import de.steamwar.command.AbstractTypeValidator; + +public interface TestTypeValidator extends AbstractTypeValidator { +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/allownull/AllowNullTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/allownull/AllowNullTest.java new file mode 100644 index 00000000..fac7813d --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/allownull/AllowNullTest.java @@ -0,0 +1,57 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.allownull; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.AllowNull; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class AllowNullTest { + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, @AllowNull Integer value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, @AllowNull int value) { + } + } + + @Test + public void testExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0", "0") + .assertExecute("null", "a"); + } + + @Test + public void testInitializePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoInitialize("AllowNull annotation cannot be used on primitive types"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMaxTest.java new file mode 100644 index 00000000..2d9ca3a5 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMaxTest.java @@ -0,0 +1,111 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.number; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3) int... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3, error = "Specify at most 3 argument") int... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[]") + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "a"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[]") + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "b"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMinMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMinMaxTest.java new file mode 100644 index 00000000..a5ac4298 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMinMaxTest.java @@ -0,0 +1,113 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.number; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyMinMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3) int... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3, error = "Specify at least 1 argument") int... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute() + .assertNoExecute("0", "a") + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "a"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument") + .assertNoExecute("0", "b") + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "b"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMinTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMinTest.java new file mode 100644 index 00000000..27d3ef30 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/GreedyMinTest.java @@ -0,0 +1,77 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.number; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyMinTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1) int... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, error = "Specify at least 1 argument") int... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute() + .assertNoExecute("0", "a"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument") + .assertNoExecute("0", "b"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMaxTest.java new file mode 100644 index 00000000..7c6f4be5 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMaxTest.java @@ -0,0 +1,111 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.number; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3) int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3, error = "Specify at most 3 argument") int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[]") + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "a"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[]") + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "b"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMinMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMinMaxTest.java new file mode 100644 index 00000000..a6afcb6c --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMinMaxTest.java @@ -0,0 +1,113 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.number; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyMinMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3) int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3, error = "Specify at least 1 argument") int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute() + .assertNoExecute("0", "a") + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "a"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument") + .assertNoExecute("0", "b") + .assertNoExecute("0", "1", "2", "3") + .assertNoExecute("0", "1", "2", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "0", "1") + .assertTabCompletion(new String[]{"2", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29"}, "0", "1", "2"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "0", "1", "2", "3") + .assertTabCompletion(new String[]{}, "0", "1", "2", "b"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMinTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMinTest.java new file mode 100644 index 00000000..a481e4b6 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/number/NonGreedyMinTest.java @@ -0,0 +1,77 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.number; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyMinTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1) int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, error = "Specify at least 1 argument") int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute() + .assertNoExecute("0", "a"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument") + .assertNoExecute("0", "b"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMaxTest.java new file mode 100644 index 00000000..8e5bad1d --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMaxTest.java @@ -0,0 +1,109 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.string; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3) String... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3, error = "Specify at most 3 argument") String... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[]") + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[]") + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMinMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMinMaxTest.java new file mode 100644 index 00000000..1c418488 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMinMaxTest.java @@ -0,0 +1,109 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.string; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyMinMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3) String... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3, error = "Specify at least 1 argument") String... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute() + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument") + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMinTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMinTest.java new file mode 100644 index 00000000..97530e72 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/GreedyMinTest.java @@ -0,0 +1,77 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.string; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyMinTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1) String... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, error = "Specify at least 1 argument") String... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute(); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMaxTest.java new file mode 100644 index 00000000..cd77e6af --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMaxTest.java @@ -0,0 +1,109 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.string; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3) String[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(max = 3, error = "Specify at most 3 argument") String[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[]") + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[]") + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMinMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMinMaxTest.java new file mode 100644 index 00000000..4a399b3a --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMinMaxTest.java @@ -0,0 +1,109 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.string; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyMinMaxTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3) String[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, max = 3, error = "Specify at least 1 argument") String[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute() + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument") + .assertNoExecute("a", "b", "c", "d"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}) + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"b"}, "a", "b") + .assertTabCompletion(new String[]{"c"}, "a", "b", "c"); + } + + @Test + public void testNoTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{}, "a", "b", "c", "d"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMinTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMinTest.java new file mode 100644 index 00000000..65aaef6a --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/arraylength/string/NonGreedyMinTest.java @@ -0,0 +1,77 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.arraylength.string; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyMinTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1) String[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @ArrayLength(min = 1, error = "Specify at least 1 argument") String[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute(); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("[a]", "a") + .assertExecute("[a, b]", "a", "b") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0, 1, 2]", "0", "1", "2"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Specify at least 1 argument"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/CacheKeyTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/CacheKeyTest.java new file mode 100644 index 00000000..29294741 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/CacheKeyTest.java @@ -0,0 +1,75 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.cached; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Cached; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collection; + +public class CacheKeyTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Mapper("cacheKey") String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper("cacheKey") + @Cached(global = true) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Arrays.asList("Hello", "Hallo", "Hugo", "Help", "World", "Welt", "Welp", s); + } + + @Override + public String normalize(String sender, String s) { + if (s.isEmpty()) return null; + return s.substring(0, 1); + } + }; + } + } + + @Test + public void testCacheKey() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"Hello", "Hallo", "Hugo", "Help", "H"}, "H") + .assertTabCompletion(new String[]{"Hello", "Help", "H"}, "He") + .assertTabCompletion(new String[]{"World", "Welt", "Welp", "W"}, "W") + .assertTabCompletion(new String[]{"Welt", "Welp", "W"}, "We") + .assertTabCompletion(new String[]{"Hello", "Hallo", "Hugo", "Help", "World", "Welt", "Welp"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/DurationTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/DurationTest.java new file mode 100644 index 00000000..c8dab7a9 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/DurationTest.java @@ -0,0 +1,76 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.cached; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Cached; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; +import java.util.concurrent.TimeUnit; + +public class DurationTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Mapper("cachedDuration") String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper("cachedDuration") + @Cached(cacheDuration = 100, timeUnit = TimeUnit.MILLISECONDS) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + @Test + @SuppressWarnings("java:S2925") + public void testDuration() { + AssertionUtils.with(new SenderSpecificTest.Command()) + .assertTabCompletion(new String[]{"Hello"}, "Hello") + .assertTabCompletion(new String[]{"Hello"}, "Hel"); + try { + Thread.sleep(200); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + AssertionUtils.with(new SenderSpecificTest.Command()) + .assertTabCompletion(new String[]{"World"}, "World") + .assertTabCompletion(new String[]{"World"}, "Wor"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/GlobalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/GlobalTest.java new file mode 100644 index 00000000..d16a8b29 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/GlobalTest.java @@ -0,0 +1,75 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.cached; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Cached; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +public class GlobalTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Mapper("cachedGlobal") String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper("cachedGlobal") + @Cached(global = true) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + @Test + public void testCached() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"Hello"}, "Hello") + .assertTabCompletion(new String[]{"Hello"}, "Hel"); + } + + @Test + public void testDifferentSenders() { + AssertionUtils.with(new Command()) + .assertTabCompletion("a", new String[]{"Hello"}, "Hello") + .assertTabCompletion("a", new String[]{"Hello"}, "Hel") + .assertTabCompletion("b", new String[]{"Hello"}, "Hel") + .assertTabCompletion("b", new String[]{"Hello"}, "H"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/SenderSpecificTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/SenderSpecificTest.java new file mode 100644 index 00000000..34f8fc3b --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/cached/SenderSpecificTest.java @@ -0,0 +1,75 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.cached; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Cached; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +public class SenderSpecificTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Mapper("cachedSenderSpecific") String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper("cachedSenderSpecific") + @Cached + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + @Test + public void testCached() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"Hello"}, "Hello") + .assertTabCompletion(new String[]{"Hello"}, "Hel"); + } + + @Test + public void testDifferentSenders() { + AssertionUtils.with(new Command()) + .assertTabCompletion("a", new String[]{"Hello"}, "Hello") + .assertTabCompletion("a", new String[]{"Hello"}, "Hel") + .assertTabCompletion("b", new String[]{"Hel"}, "Hel") + .assertTabCompletion("b", new String[]{"Hel"}, "H"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/GlobalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/GlobalTest.java new file mode 100644 index 00000000..4917d42a --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/GlobalTest.java @@ -0,0 +1,71 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.classmapper; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.ClassMapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Collection; +import java.util.Collections; + +@Deprecated +public class GlobalTest { + + public static class FirstCommand { + + @ClassMapper(value = BigInteger.class, local = false) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public BigInteger map(String sender, PreviousArguments previousArguments, String s) { + return new BigInteger(s); + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, BigInteger b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testGlobalMapper() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertExecute("0", "0"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/LocalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/LocalTest.java new file mode 100644 index 00000000..1f207349 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/LocalTest.java @@ -0,0 +1,104 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.classmapper; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.ClassMapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Collections; + +@Deprecated +public class LocalTest { + + public static class FirstCommand { + + @Register + public void genericCommand(String sender, String b) { + throw new ExecutionIdentifier(b); + } + + @ClassMapper(String.class) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return "#" + s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, BigDecimal b) { + throw new ExecutionIdentifier(b.toString()); + } + + @ClassMapper(value = BigDecimal.class) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public BigDecimal map(String sender, PreviousArguments previousArguments, String s) { + return new BigDecimal(s); + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class ThirdCommand { + + @Register + public void genericCommand(String sender, BigDecimal b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testLocalMapper() { + AssertionUtils.with(new FirstCommand()) + .assertExecute("#Hello", "Hello"); + } + + @Test + public void testLocalMapperOutside() { + AssertionUtils.with(new SecondCommand()) + .assertExecute("0", "0"); + AssertionUtils.with(new ThirdCommand()) + .assertNoInitialize("Register method parameter arg1 must be annotated or have a type mapper"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/OverrideTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/OverrideTest.java new file mode 100644 index 00000000..f3e8bca4 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classmapper/OverrideTest.java @@ -0,0 +1,64 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.classmapper; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.ClassMapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +@Deprecated +public class OverrideTest { + + public static class Command { + + @Register + public void genericCommand(String sender, String b) { + throw new ExecutionIdentifier(b); + } + + @ClassMapper(value = String.class, local = false) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return "#" + s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + @Test + public void testOverrideMapper() { + AssertionUtils.with(new Command()) + .assertExecute("Hello", "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classvalidator/GlobalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classvalidator/GlobalTest.java new file mode 100644 index 00000000..711fad60 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classvalidator/GlobalTest.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.classvalidator; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ClassValidator; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Validator; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeValidator; +import org.junit.Test; + +import java.math.BigInteger; + +@Deprecated +public class GlobalTest { + + public static class FirstCommand { + + @ClassValidator(value = BigInteger.class, local = false) + public TestTypeValidator globalValidator() { + return (sender, value, messageSender) -> { + return false; + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Validator BigInteger b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testGlobalValidator() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertNoExecute("0"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classvalidator/LocalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classvalidator/LocalTest.java new file mode 100644 index 00000000..9ed3caa3 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/classvalidator/LocalTest.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.classvalidator; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ClassValidator; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Validator; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeValidator; +import org.junit.Test; + +import java.math.BigInteger; + +@Deprecated +public class LocalTest { + + public static class FirstCommand { + + @ClassValidator(BigInteger.class) + public TestTypeValidator localValidator() { + return (sender, value, messageSender) -> { + return false; + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Validator String b) { + throw new ExecutionIdentifier(b); + } + } + + @Test + public void testGlobalValidator() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertNoInitialize("Validator '' not found"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/endswith/EndsWithTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/endswith/EndsWithTest.java new file mode 100644 index 00000000..af518bcd --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/endswith/EndsWithTest.java @@ -0,0 +1,87 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.endswith; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.EndsWith; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class EndsWithTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @EndsWith("Hello") String t) { + throw new ExecutionIdentifier(t); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @EndsWith(value = "Hello", error = "Hello must be the suffix") String t) { + throw new ExecutionIdentifier(t); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("Hello", "Hello") + .assertExecute("TestHello", "TestHello"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute("Test") + .assertNoExecute("Hugo"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{"Hello"}, "Hello") + .assertTabCompletion(new String[]{"TestHello"}, "Test"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Hello", "Hello") + .assertExecute("TestHello", "TestHello"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Hello must be the suffix", "Test") + .assertExecute("Hello must be the suffix", "Hugo"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{"Hello"}, "Hello") + .assertTabCompletion(new String[]{"TestHello"}, "Test"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/errormessage/AllowEASTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/errormessage/AllowEASTest.java new file mode 100644 index 00000000..e884759b --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/errormessage/AllowEASTest.java @@ -0,0 +1,64 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.errormessage; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ErrorMessage; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +@Deprecated +public class AllowEASTest { + + public static class GreedyCommand { + + @Register + public void genericCommand(String sender, @ErrorMessage(value = "Empty array", allowEAs = false) String... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + public static class NonGreedyCommand { + + @Register + public void genericCommand(String sender, @ErrorMessage(value = "Empty array", allowEAs = false) String[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecuteGreedy() { + AssertionUtils.with(new GreedyCommand()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("Empty array"); + } + + @Test + public void testExecuteNonGreedy() { + AssertionUtils.with(new NonGreedyCommand()) + .assertExecute("[0]", "0") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("Empty array"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/errormessage/ErrorMessageTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/errormessage/ErrorMessageTest.java new file mode 100644 index 00000000..030f849a --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/errormessage/ErrorMessageTest.java @@ -0,0 +1,44 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.errormessage; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ErrorMessage; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class ErrorMessageTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @ErrorMessage("No Number") int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("0", "0") + .assertExecute("No Number", "a"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/BackTrackingDepthTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/BackTrackingDepthTest.java new file mode 100644 index 00000000..04d71eab --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/BackTrackingDepthTest.java @@ -0,0 +1,71 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.greedy; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Greedy; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class BackTrackingDepthTest { + + public static class CommandDepth1 { + + @Register + public void genericCommand(String sender, @Greedy(backTrackingDepth = 1) int[] args_1, @ArrayLength(min = 2) int[] args_2) { + throw new ExecutionIdentifier(Arrays.toString(args_1) + " " + Arrays.toString(args_2)); + } + } + + public static class CommandDepth2 { + + @Register + public void genericCommand(String sender, @Greedy(backTrackingDepth = 2) int[] args_1, @ArrayLength(min = 2) int[] args_2) { + throw new ExecutionIdentifier(Arrays.toString(args_1) + " " + Arrays.toString(args_2)); + } + } + + @Test + public void testDepth1NoExecute() { + AssertionUtils.with(new CommandDepth1()) + .assertNoExecute("0") + .assertNoExecute() + .assertNoExecute("0", "1", "2"); + } + + @Test + public void testDepth2Execute() { + AssertionUtils.with(new CommandDepth2()) + .assertExecute("[0, 1] [2, 3]", "0", "1", "2", "3") + .assertExecute("[0, 1, 2] [3, 4]", "0", "1", "2", "3", "4") + .assertExecute("[] [0, 1]", "0", "1"); + } + + @Test + public void testDepth2NoExecute() { + AssertionUtils.with(new CommandDepth2()) + .assertNoExecute("0") + .assertNoExecute(); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/BackTrackingTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/BackTrackingTest.java new file mode 100644 index 00000000..dee50076 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/BackTrackingTest.java @@ -0,0 +1,55 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.greedy; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.ArrayLength; +import de.steamwar.command.annotations.Greedy; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class BackTrackingTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Greedy int[] args_1, @ArrayLength(min = 2) int[] args_2) { + throw new ExecutionIdentifier(Arrays.toString(args_1) + " " + Arrays.toString(args_2)); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("[0, 1] [2, 3]", "0", "1", "2", "3") + .assertExecute("[0, 1, 2] [3, 4]", "0", "1", "2", "3", "4") + .assertExecute("[] [0, 1]", "0", "1"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("0") + .assertNoExecute(); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/GreedyTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/GreedyTest.java new file mode 100644 index 00000000..bc07eec1 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/greedy/GreedyTest.java @@ -0,0 +1,71 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.greedy; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Greedy; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Greedy int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("[0, 1, 2]", "0", "1", "2") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0]", "0") + .assertExecute("[]"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("0", "1", "b") + .assertNoExecute("0", "b") + .assertNoExecute("b"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "") + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "0", ""); + } + + @Test + public void testNoTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "0", "b") + .assertTabCompletion(new String[]{}, "b", "0", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MaxTest.java new file mode 100644 index 00000000..369f1a24 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MaxTest.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.length; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Length; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class MaxTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Length(max = 3) String string) { + throw new ExecutionIdentifier(string); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("He", "He") + .assertExecute("H", "H") + .assertExecute("", ""); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("Hello") + .assertNoExecute("World") + .assertNoExecute("This") + .assertNoExecute("Works"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "") + .assertTabCompletion(new String[]{"Hel"}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MinMaxTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MinMaxTest.java new file mode 100644 index 00000000..0aefe41f --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MinMaxTest.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.length; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Length; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class MinMaxTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Length(min = 3, max = 5) String string) { + throw new ExecutionIdentifier(string); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("Hel", "Hel") + .assertExecute("Hello", "Hello") + .assertExecute("Hugo", "Hugo"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("He") + .assertNoExecute("HelloWorld") + .assertNoExecute("ThisWorks"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "") + .assertTabCompletion(new String[]{"Hello"}, "Hello") + .assertTabCompletion(new String[]{"Hello"}, "HelloWorld"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MinTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MinTest.java new file mode 100644 index 00000000..cde120ab --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/length/MinTest.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.length; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Length; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class MinTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Length(min = 3) String string) { + throw new ExecutionIdentifier(string); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("Hello", "Hello") + .assertExecute("World", "World") + .assertExecute("This", "This") + .assertExecute("Works", "Works"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("He") + .assertNoExecute("H") + .assertNoExecute(""); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "") + .assertTabCompletion(new String[]{"Hello"}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/GlobalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/GlobalTest.java new file mode 100644 index 00000000..5aef5b5e --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/GlobalTest.java @@ -0,0 +1,70 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.mapper.type; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Collection; +import java.util.Collections; + +public class GlobalTest { + + public static class FirstCommand { + + @Mapper(type = BigInteger.class, local = false) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public BigInteger map(String sender, PreviousArguments previousArguments, String s) { + return new BigInteger(s); + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, BigInteger b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testGlobalMapper() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertExecute("0", "0"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/LocalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/LocalTest.java new file mode 100644 index 00000000..80402e36 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/LocalTest.java @@ -0,0 +1,103 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.mapper.type; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.Collection; +import java.util.Collections; + +public class LocalTest { + + public static class FirstCommand { + + @Register + public void genericCommand(String sender, String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper(type = String.class) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return "#" + s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, BigDecimal b) { + throw new ExecutionIdentifier(b.toString()); + } + + @Mapper(type = BigDecimal.class) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public BigDecimal map(String sender, PreviousArguments previousArguments, String s) { + return new BigDecimal(s); + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class ThirdCommand { + + @Register + public void genericCommand(String sender, BigDecimal b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testLocalMapper() { + AssertionUtils.with(new FirstCommand()) + .assertExecute("#Hello", "Hello"); + } + + @Test + public void testLocalMapperOutside() { + AssertionUtils.with(new SecondCommand()) + .assertExecute("0", "0"); + AssertionUtils.with(new ThirdCommand()) + .assertNoInitialize("Register method parameter arg1 must be annotated or have a type mapper"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/OverrideTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/OverrideTest.java new file mode 100644 index 00000000..3708a761 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/type/OverrideTest.java @@ -0,0 +1,63 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.mapper.type; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +public class OverrideTest { + + public static class Command { + + @Register + public void genericCommand(String sender, String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper(type = String.class, local = false) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return "#" + s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + @Test + public void testOverrideMapper() { + AssertionUtils.with(new Command()) + .assertExecute("Hello", "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/GlobalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/GlobalTest.java new file mode 100644 index 00000000..fca4c8f4 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/GlobalTest.java @@ -0,0 +1,69 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.mapper.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +public class GlobalTest { + + public static class FirstCommand { + + @Mapper(value = "globalMapper", local = false) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return "#" + s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Mapper("globalMapper") String b) { + throw new ExecutionIdentifier(b); + } + } + + @Test + public void testGlobalMapper() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertExecute("#Test", "Test"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/LocalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/LocalTest.java new file mode 100644 index 00000000..ca6a5cb0 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/LocalTest.java @@ -0,0 +1,103 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.mapper.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Collection; +import java.util.Collections; + +public class LocalTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Mapper("localMapper") String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper("localMapper") + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return "#" + s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Mapper("bigInteger") BigInteger b) { + throw new ExecutionIdentifier(b.toString()); + } + + @Mapper("bigInteger") + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public BigInteger map(String sender, PreviousArguments previousArguments, String s) { + return new BigInteger(s); + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class ThirdCommand { + + @Register + public void genericCommand(String sender, @Mapper("bigInteger") BigInteger b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testLocalMapper() { + AssertionUtils.with(new Command()) + .assertExecute("#Hello", "Hello"); + } + + @Test + public void testLocalMapperOutside() { + AssertionUtils.with(new SecondCommand()) + .assertExecute("0", "0"); + AssertionUtils.with(new ThirdCommand()) + .assertNoInitialize("Mapper 'bigInteger' not found"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/OverrideTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/OverrideTest.java new file mode 100644 index 00000000..3b24e00c --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/mapper/value/OverrideTest.java @@ -0,0 +1,63 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.mapper.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; + +public class OverrideTest { + + public static class Command { + + @Register + public void genericCommand(String sender, String b) { + throw new ExecutionIdentifier(b); + } + + @Mapper(value = "java.lang.String", local = false) + public TestTypeMapper typeMapper() { + return new TestTypeMapper<>() { + @Override + public String map(String sender, PreviousArguments previousArguments, String s) { + return "#" + s; + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + @Test + public void testOverrideMapper() { + AssertionUtils.with(new Command()) + .assertExecute("Hello", "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/reference/.gitkeep b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/reference/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/DoubleTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/DoubleTest.java new file mode 100644 index 00000000..9381fe1c --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/DoubleTest.java @@ -0,0 +1,119 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.max.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class DoubleTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Max(doubleValue = 10.2) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Max(doubleValue = 10.2, inclusive = false) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Max(doubleValue = 10.2, error = "Bigger than Max") double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10.0", "10") + .assertExecute("10.2", "10.2") + .assertExecute("9.0", "9"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("19") + .assertNoExecute("10.3") + .assertNoExecute("100"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("9.0", "9") + .assertExecute("10.1", "10.1") + .assertExecute("-1.0", "-1"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10.2") + .assertNoExecute("11"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("10.0", "10") + .assertExecute("9.0", "9") + .assertExecute("-1.0", "-1"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Bigger than Max", "10.3") + .assertExecute("Bigger than Max", "11") + .assertExecute("Bigger than Max", "19"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/FloatTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/FloatTest.java new file mode 100644 index 00000000..ef298ff3 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/FloatTest.java @@ -0,0 +1,119 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.max.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class FloatTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Max(floatValue = 10.2f) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Max(floatValue = 10.2f, inclusive = false) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Max(floatValue = 10.2f, error = "Bigger than Max") float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10.0", "10") + .assertExecute("10.2", "10.2") + .assertExecute("9.0", "9"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("19") + .assertNoExecute("10.3") + .assertNoExecute("100"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("9.0", "9") + .assertExecute("10.1", "10.1") + .assertExecute("-1.0", "-1"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10.2") + .assertNoExecute("11"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("10.0", "10") + .assertExecute("9.0", "9") + .assertExecute("-1.0", "-1"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Bigger than Max", "10.3") + .assertExecute("Bigger than Max", "11") + .assertExecute("Bigger than Max", "19"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/IntTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/IntTest.java new file mode 100644 index 00000000..5738dbf0 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/IntTest.java @@ -0,0 +1,114 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.max.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class IntTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Max(intValue = 10) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Max(intValue = 10, inclusive = false) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Max(intValue = 10, error = "Bigger than Max") int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10", "10") + .assertExecute("9", "9"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("19") + .assertNoExecute("100"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("9", "9") + .assertExecute("-1", "-1"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("11"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10", "10") + .assertExecute("9", "9") + .assertExecute("-1", "-1"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Bigger than Max", "11") + .assertExecute("Bigger than Max", "19"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/LongTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/LongTest.java new file mode 100644 index 00000000..fd920aaf --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/max/value/LongTest.java @@ -0,0 +1,114 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.max.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class LongTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Max(longValue = 10) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Max(longValue = 10, inclusive = false) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Max(longValue = 10, error = "Bigger than Max") long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10", "10") + .assertExecute("9", "9"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("19") + .assertNoExecute("100"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("9", "9") + .assertExecute("-1", "-1"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("11"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10", "10") + .assertExecute("9", "9") + .assertExecute("-1", "-1"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Bigger than Max", "11") + .assertExecute("Bigger than Max", "19"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/DoubleTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/DoubleTest.java new file mode 100644 index 00000000..fa6dcc4d --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/DoubleTest.java @@ -0,0 +1,115 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.min.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class DoubleTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2, inclusive = false) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2, error = "Smaller than Min") double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("19.0", "19"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10.2"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("11.0", "11") + .assertExecute("19.0", "19"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("11.0", "11") + .assertExecute("19.0", "19"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10.2"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/FloatTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/FloatTest.java new file mode 100644 index 00000000..c3e94617 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/FloatTest.java @@ -0,0 +1,115 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.min.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class FloatTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f, inclusive = false) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f, error = "Smaller than Min") float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("19.0", "19"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10.2"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("11.0", "11") + .assertExecute("19.0", "19"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("11.0", "11") + .assertExecute("19.0", "19"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10.2"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/IntTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/IntTest.java new file mode 100644 index 00000000..7cf7597d --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/IntTest.java @@ -0,0 +1,115 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.min.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class IntTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(intValue = 10) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Min(intValue = 10, inclusive = false) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(intValue = 10, error = "Smaller than Min") int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10", "10") + .assertExecute("19", "19"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("11", "11") + .assertExecute("19", "19"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10", "10") + .assertExecute("11", "11") + .assertExecute("19", "19"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/LongTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/LongTest.java new file mode 100644 index 00000000..aece4967 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/min/value/LongTest.java @@ -0,0 +1,115 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.min.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class LongTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(longValue = 10) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveCommand { + + @Register + public void test(String sender, @Min(longValue = 10, inclusive = false) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(longValue = 10, error = "Smaller than Min") long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10", "10") + .assertExecute("19", "19"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10"}, ""); + } + + @Test + public void testNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertExecute("11", "11") + .assertExecute("19", "19"); + } + + @Test + public void testNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("9") + .assertNoExecute("-1"); + } + + @Test + public void testNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10", "10") + .assertExecute("11", "11") + .assertExecute("19", "19"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/DoubleTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/DoubleTest.java new file mode 100644 index 00000000..2b328f29 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/DoubleTest.java @@ -0,0 +1,247 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 18.8f23 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.command.tests.annotations.minmax; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class DoubleTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2) @Max(doubleValue = 18.8) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndInclusiveCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2, inclusive = false) @Max(doubleValue = 18.8) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class InclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2) @Max(doubleValue = 18.8, inclusive = false) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2, inclusive = false) @Max(doubleValue = 18.8, inclusive = false) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10.2, error = "Smaller than Min") @Max(doubleValue = 18.8, error = "Bigger than Max") double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameCommand { + + @Register + public void test(String sender, @Min(doubleValue = 10) @Max(doubleValue = 10) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive1Command { + + @Register + public void test(String sender, @Min(doubleValue = 10, inclusive = false) @Max(doubleValue = 10) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive2Command { + + @Register + public void test(String sender, @Min(doubleValue = 10) @Max(doubleValue = 10, inclusive = false) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive3Command { + + @Register + public void test(String sender, @Min(doubleValue = 10, inclusive = false) @Max(doubleValue = 10, inclusive = false) double i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("18.8", "18.8"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("21") + .assertNoExecute("25") + .assertNoExecute("19") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10.2", "18.8"}, ""); + } + + @Test + public void testNonInclusiveAndInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertExecute("11.0", "11") + .assertExecute("18.8", "18.8"); + } + + @Test + public void testNonInclusiveAndInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertNoExecute("10.2") + .assertNoExecute("9") + .assertNoExecute("19") + .assertNoExecute("-1") + .assertNoExecute("21"); + } + + @Test + public void testNonInclusiveAndInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertTabCompletion(new String[]{"18.8"}, ""); + } + + @Test + public void testInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("15.2", "15.2"); + } + + @Test + public void testInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertNoExecute("9") + .assertNoExecute("-1") + .assertNoExecute("19") + .assertNoExecute("18.8"); + } + + @Test + public void testInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{"10.2"}, ""); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertExecute("11.0", "11") + .assertExecute("15.0", "15"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertNoExecute("10.2") + .assertNoExecute("-1") + .assertNoExecute("19") + .assertNoExecute("18.8"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("11.0", "11") + .assertExecute("18.8", "18.8"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1") + .assertExecute("Bigger than Max", "19") + .assertExecute("Bigger than Max", "21") + .assertExecute("Bigger than Max", "50"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10.2", "18.8"}, ""); + } + + @Test + public void testSameValidExecute() { + AssertionUtils.with(new SameCommand()) + .assertExecute("10.0", "10"); + } + + @Test + public void testSameValidNoExecute() { + AssertionUtils.with(new SameCommand()) + .assertNoExecute("9") + .assertNoExecute("11"); + } + + @Test + public void testSameNonInclusive1() { + AssertionUtils.with(new SameNonInclusive1Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive2() { + AssertionUtils.with(new SameNonInclusive2Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive3() { + AssertionUtils.with(new SameNonInclusive3Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/FloatTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/FloatTest.java new file mode 100644 index 00000000..2eaa3bdf --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/FloatTest.java @@ -0,0 +1,247 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 18.8f23 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.command.tests.annotations.minmax; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class FloatTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f) @Max(floatValue = 18.8f) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndInclusiveCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f, inclusive = false) @Max(floatValue = 18.8f) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class InclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f) @Max(floatValue = 18.8f, inclusive = false) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f, inclusive = false) @Max(floatValue = 18.8f, inclusive = false) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(floatValue = 10.2f, error = "Smaller than Min") @Max(floatValue = 18.8f, error = "Bigger than Max") float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameCommand { + + @Register + public void test(String sender, @Min(floatValue = 10) @Max(floatValue = 10) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive1Command { + + @Register + public void test(String sender, @Min(floatValue = 10, inclusive = false) @Max(floatValue = 10) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive2Command { + + @Register + public void test(String sender, @Min(floatValue = 10) @Max(floatValue = 10, inclusive = false) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive3Command { + + @Register + public void test(String sender, @Min(floatValue = 10, inclusive = false) @Max(floatValue = 10, inclusive = false) float i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("18.8", "18.8"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("21") + .assertNoExecute("25") + .assertNoExecute("19") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10.2", "18.8"}, ""); + } + + @Test + public void testNonInclusiveAndInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertExecute("11.0", "11") + .assertExecute("18.8", "18.8"); + } + + @Test + public void testNonInclusiveAndInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertNoExecute("10.2") + .assertNoExecute("9") + .assertNoExecute("19") + .assertNoExecute("-1") + .assertNoExecute("21"); + } + + @Test + public void testNonInclusiveAndInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertTabCompletion(new String[]{"18.8"}, ""); + } + + @Test + public void testInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("15.2", "15.2"); + } + + @Test + public void testInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertNoExecute("9") + .assertNoExecute("-1") + .assertNoExecute("19") + .assertNoExecute("18.8"); + } + + @Test + public void testInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{"10.2"}, ""); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertExecute("11.0", "11") + .assertExecute("15.0", "15"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertNoExecute("10.2") + .assertNoExecute("-1") + .assertNoExecute("19") + .assertNoExecute("18.8"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10.2", "10.2") + .assertExecute("11.0", "11") + .assertExecute("18.8", "18.8"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1") + .assertExecute("Bigger than Max", "19") + .assertExecute("Bigger than Max", "21") + .assertExecute("Bigger than Max", "50"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10.2", "18.8"}, ""); + } + + @Test + public void testSameValidExecute() { + AssertionUtils.with(new SameCommand()) + .assertExecute("10.0", "10"); + } + + @Test + public void testSameValidNoExecute() { + AssertionUtils.with(new SameCommand()) + .assertNoExecute("9") + .assertNoExecute("11"); + } + + @Test + public void testSameNonInclusive1() { + AssertionUtils.with(new SameNonInclusive1Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive2() { + AssertionUtils.with(new SameNonInclusive2Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive3() { + AssertionUtils.with(new SameNonInclusive3Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/IntTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/IntTest.java new file mode 100644 index 00000000..6978cdb3 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/IntTest.java @@ -0,0 +1,245 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.minmax; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class IntTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(intValue = 10) @Max(intValue = 20) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndInclusiveCommand { + + @Register + public void test(String sender, @Min(intValue = 10, inclusive = false) @Max(intValue = 20) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class InclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(intValue = 10) @Max(intValue = 20, inclusive = false) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(intValue = 10, inclusive = false) @Max(intValue = 20, inclusive = false) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(intValue = 10, error = "Smaller than Min") @Max(intValue = 20, error = "Bigger than Max") int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameCommand { + + @Register + public void test(String sender, @Min(intValue = 10) @Max(intValue = 10) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive1Command { + + @Register + public void test(String sender, @Min(intValue = 10, inclusive = false) @Max(intValue = 10) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive2Command { + + @Register + public void test(String sender, @Min(intValue = 10) @Max(intValue = 10, inclusive = false) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive3Command { + + @Register + public void test(String sender, @Min(intValue = 10, inclusive = false) @Max(intValue = 10, inclusive = false) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10", "10") + .assertExecute("19", "19") + .assertExecute("20", "20"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("21") + .assertNoExecute("25") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10", "20"}, ""); + } + + @Test + public void testNonInclusiveAndInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertExecute("11", "11") + .assertExecute("19", "19") + .assertExecute("20", "20"); + } + + @Test + public void testNonInclusiveAndInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("9") + .assertNoExecute("-1") + .assertNoExecute("21"); + } + + @Test + public void testNonInclusiveAndInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertTabCompletion(new String[]{"20"}, ""); + } + + @Test + public void testInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertExecute("10", "10") + .assertExecute("19", "19"); + } + + @Test + public void testInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertNoExecute("9") + .assertNoExecute("-1") + .assertNoExecute("20"); + } + + @Test + public void testInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{"10"}, ""); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertExecute("11", "11") + .assertExecute("19", "19"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("-1") + .assertNoExecute("20"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10", "10") + .assertExecute("11", "11") + .assertExecute("19", "19") + .assertExecute("20", "20"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1") + .assertExecute("Bigger than Max", "21") + .assertExecute("Bigger than Max", "50"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10", "20"}, ""); + } + + @Test + public void testSameValidExecute() { + AssertionUtils.with(new SameCommand()) + .assertExecute("10", "10"); + } + + @Test + public void testSameValidNoExecute() { + AssertionUtils.with(new SameCommand()) + .assertNoExecute("9") + .assertNoExecute("11"); + } + + @Test + public void testSameNonInclusive1() { + AssertionUtils.with(new SameNonInclusive1Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive2() { + AssertionUtils.with(new SameNonInclusive2Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive3() { + AssertionUtils.with(new SameNonInclusive3Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/LongTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/LongTest.java new file mode 100644 index 00000000..10d278f6 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/minmax/LongTest.java @@ -0,0 +1,245 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.minmax; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Max; +import de.steamwar.command.annotations.Min; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class LongTest { + + public static class BaseCommand { + + @Register + public void test(String sender, @Min(longValue = 10) @Max(longValue = 20) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndInclusiveCommand { + + @Register + public void test(String sender, @Min(longValue = 10, inclusive = false) @Max(longValue = 20) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class InclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(longValue = 10) @Max(longValue = 20, inclusive = false) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class NonInclusiveAndNonInclusiveCommand { + + @Register + public void test(String sender, @Min(longValue = 10, inclusive = false) @Max(longValue = 20, inclusive = false) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class ErrorMessageCommand { + + @Register + public void test(String sender, @Min(longValue = 10, error = "Smaller than Min") @Max(longValue = 20, error = "Bigger than Max") long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameCommand { + + @Register + public void test(String sender, @Min(longValue = 10) @Max(longValue = 10) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive1Command { + + @Register + public void test(String sender, @Min(longValue = 10, inclusive = false) @Max(longValue = 10) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive2Command { + + @Register + public void test(String sender, @Min(longValue = 10) @Max(longValue = 10, inclusive = false) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + public static class SameNonInclusive3Command { + + @Register + public void test(String sender, @Min(longValue = 10, inclusive = false) @Max(longValue = 10, inclusive = false) long i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testBaseValueValidExecute() { + AssertionUtils.with(new BaseCommand()) + .assertExecute("10", "10") + .assertExecute("19", "19") + .assertExecute("20", "20"); + } + + @Test + public void testBaseValueNoExecute() { + AssertionUtils.with(new BaseCommand()) + .assertNoExecute("9") + .assertNoExecute("21") + .assertNoExecute("25") + .assertNoExecute("-1"); + } + + @Test + public void testBaseValueTabComplete() { + AssertionUtils.with(new BaseCommand()) + .assertTabCompletion(new String[]{"10", "20"}, ""); + } + + @Test + public void testNonInclusiveAndInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertExecute("11", "11") + .assertExecute("19", "19") + .assertExecute("20", "20"); + } + + @Test + public void testNonInclusiveAndInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("9") + .assertNoExecute("-1") + .assertNoExecute("21"); + } + + @Test + public void testNonInclusiveAndInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndInclusiveCommand()) + .assertTabCompletion(new String[]{"20"}, ""); + } + + @Test + public void testInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertExecute("10", "10") + .assertExecute("19", "19"); + } + + @Test + public void testInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertNoExecute("9") + .assertNoExecute("-1") + .assertNoExecute("20"); + } + + @Test + public void testInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new InclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{"10"}, ""); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueValidExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertExecute("11", "11") + .assertExecute("19", "19"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueNoExecute() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertNoExecute("10") + .assertNoExecute("-1") + .assertNoExecute("20"); + } + + @Test + public void testNonInclusiveAndNonInclusiveValueTabComplete() { + AssertionUtils.with(new NonInclusiveAndNonInclusiveCommand()) + .assertTabCompletion(new String[]{}, ""); + } + + @Test + public void testErrorMessageValueValidExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("10", "10") + .assertExecute("11", "11") + .assertExecute("19", "19") + .assertExecute("20", "20"); + } + + @Test + public void testErrorMessageValueNoExecute() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertExecute("Smaller than Min", "9") + .assertExecute("Smaller than Min", "-1") + .assertExecute("Bigger than Max", "21") + .assertExecute("Bigger than Max", "50"); + } + + @Test + public void testErrorMessageValueTabComplete() { + AssertionUtils.with(new ErrorMessageCommand()) + .assertTabCompletion(new String[]{"10", "20"}, ""); + } + + @Test + public void testSameValidExecute() { + AssertionUtils.with(new SameCommand()) + .assertExecute("10", "10"); + } + + @Test + public void testSameValidNoExecute() { + AssertionUtils.with(new SameCommand()) + .assertNoExecute("9") + .assertNoExecute("11"); + } + + @Test + public void testSameNonInclusive1() { + AssertionUtils.with(new SameNonInclusive1Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive2() { + AssertionUtils.with(new SameNonInclusive2Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } + + @Test + public void testSameNonInclusive3() { + AssertionUtils.with(new SameNonInclusive3Command()) + .assertNoInitialize("Min and Max cannot be equal if not both are inclusive"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/optionalvalue/OnlyUseIfNoneIsGivenTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/optionalvalue/OnlyUseIfNoneIsGivenTest.java new file mode 100644 index 00000000..988c0f09 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/optionalvalue/OnlyUseIfNoneIsGivenTest.java @@ -0,0 +1,60 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.optionalvalue; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.OptionalValue; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class OnlyUseIfNoneIsGivenTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @OptionalValue(value = "0", onlyUINIG = true) int i, @OptionalValue(value = "true") boolean b) { + throw new ExecutionIdentifier(i + " " + b); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("1 false", "1", "false") + .assertExecute("0 true") + .assertExecute("10 false", "10", "false") + .assertExecute("10 true", "10") + .assertExecute("10 true", "10", "true"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("true"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"true", "false"}, "0", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/optionalvalue/OptionalValueTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/optionalvalue/OptionalValueTest.java new file mode 100644 index 00000000..3b0c9321 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/optionalvalue/OptionalValueTest.java @@ -0,0 +1,61 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.optionalvalue; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.OptionalValue; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class OptionalValueTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @OptionalValue("0") int i, boolean b) { + throw new ExecutionIdentifier(i + " " + b); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("1 false", "1", "false") + .assertExecute("0 false", "false") + .assertExecute("10 false", "10", "false") + .assertExecute("10 true", "10", "true") + .assertExecute("0 true", "true"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("10") + .assertNoExecute(); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "true", "false"}, "") + .assertTabCompletion(new String[]{"true", "false"}, "0", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/partof/PartOfInitializationTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/partof/PartOfInitializationTest.java new file mode 100644 index 00000000..4f429cbd --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/partof/PartOfInitializationTest.java @@ -0,0 +1,50 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.partof; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class PartOfInitializationTest { + + public static class Command1 { + + @Register + public void test(String sender) { + throw new ExecutionIdentifier("Running"); + } + } + + public static class Command2 { + + @Register + public void test(String sender) { + throw new ExecutionIdentifier("Running"); + } + } + + @Test + public void testCommand() { + AssertionUtils.with(new Command1(), new Command2()) + .assertNoInitialize("Command with parameters String is already defined in de.steamwar.command.tests.annotations.partof.PartOfInitializationTest$Command1"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/partof/PartOfTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/partof/PartOfTest.java new file mode 100644 index 00000000..39e706df --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/partof/PartOfTest.java @@ -0,0 +1,78 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.partof; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.PreviousArguments; +import de.steamwar.command.annotations.Mapper; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeMapper; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.Collection; +import java.util.Collections; + +public class PartOfTest { + + public static class Command1 { + + @Mapper(type = BigInteger.class) + public TestTypeMapper bigInteger() { + return new TestTypeMapper<>() { + @Override + public BigInteger map(String sender, PreviousArguments previousArguments, String s) { + return new BigInteger(s); + } + + @Override + public Collection tabComplete(String sender, PreviousArguments previousArguments, String s) { + return Collections.singletonList(s); + } + }; + } + } + + public static class Command2 { + + @Register + public void test(String sender) { + throw new ExecutionIdentifier("Running"); + } + + @Register + public void test2(String sender, BigInteger bigInteger) { + throw new ExecutionIdentifier("Running " + bigInteger); + } + } + + @Test + public void testCommand() { + AssertionUtils.with(new Command1(), new Command2()) + .assertExecute("Running"); + } + + @Test + public void testCommandWithArguments() { + AssertionUtils.with(new Command1(), new Command2()) + .assertExecute("Running 0", "0"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/regex/RegexTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/regex/RegexTest.java new file mode 100644 index 00000000..5b7b5e35 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/regex/RegexTest.java @@ -0,0 +1,86 @@ + +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.regex; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Regex; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class RegexTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @Regex("H+") String t) { + throw new ExecutionIdentifier(t); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @Regex(value = "H+", error = "Any number of H was expected") String t) { + throw new ExecutionIdentifier(t); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("HHH", "HHH") + .assertExecute("HHHHHHHHHHHH", "HHHHHHHHHHHH"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute("AA") + .assertNoExecute("B"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{"H"}, "H"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("HH", "HH") + .assertExecute("HHHHH", "HHHHH"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Any number of H was expected", "A") + .assertExecute("Any number of H was expected", "BB"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{"H"}, "H"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/DescriptionTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/DescriptionTest.java new file mode 100644 index 00000000..7bea3925 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/DescriptionTest.java @@ -0,0 +1,49 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.register; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class DescriptionTest { + + public static class Command { + + @Register(description = "Hello World") + public void genericCommand(String sender, boolean b) { + throw new ExecutionIdentifier(b + ""); + } + } + + @Test + public void testExecuteDescription() { + AssertionUtils.with(new Command()) + .assertExecute("Hello World"); + } + + @Test + public void testExecuteNoDescription() { + AssertionUtils.with(new Command()) + .assertExecute("true", "true") + .assertExecute("false", "false"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/MultiRegisterTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/MultiRegisterTest.java new file mode 100644 index 00000000..0646e21b --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/MultiRegisterTest.java @@ -0,0 +1,49 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.register; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class MultiRegisterTest { + + public static class Command { + + @Register("value1") + @Register("value2") + public void genericCommand(String s) { + throw new ExecutionIdentifier(""); + } + } + + @Test + public void testExecuteFirstRegister() { + AssertionUtils.with(new Command()) + .assertExecute("", "value1"); + } + + @Test + public void testExecuteSecondRegister() { + AssertionUtils.with(new Command()) + .assertExecute("", "value2"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/NoTabCompleteTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/NoTabCompleteTest.java new file mode 100644 index 00000000..c298bf77 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/NoTabCompleteTest.java @@ -0,0 +1,53 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.register; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import org.junit.Test; + +public class NoTabCompleteTest { + + public static class SubCommand { + + @Register(value = "test", noTabComplete = true) + public void genericCommand(String s) { + } + } + + public static class ArgumentCommand { + + @Register(noTabComplete = true) + public void genericCommand(String sender, boolean b) { + } + } + + @Test + public void testTabCompletionSub() { + AssertionUtils.with(new SubCommand()) + .assertTabCompletion(new String[]{}, "t"); + } + + @Test + public void testTabCompletionArgument() { + AssertionUtils.with(new ArgumentCommand()) + .assertTabCompletion(new String[]{}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/SubCommandTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/SubCommandTest.java new file mode 100644 index 00000000..99d4cc14 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/register/SubCommandTest.java @@ -0,0 +1,106 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.register; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class SubCommandTest { + + public static class SingleCommand { + + @Register("test") + public void genericCommand(String s) { + throw new ExecutionIdentifier("test"); + } + } + + public static class MultiCommand { + + @Register({"test1", "test2"}) + public void genericCommand(String s) { + throw new ExecutionIdentifier("test1->test2"); + } + } + + @Test + public void testExecuteSingleValid() { + AssertionUtils.with(new SingleCommand()) + .assertExecute("test", "test"); + } + + @Test + public void testExecuteSingleInvalid() { + AssertionUtils.with(new SingleCommand()) + .assertNoExecute("t"); + } + + @Test + public void testTabCompletionsSingleValid() { + AssertionUtils.with(new SingleCommand()) + .assertTabCompletion(new String[]{"test"}, "") + .assertTabCompletion(new String[]{"test"}, "t"); + } + + @Test + public void testTabCompletionsSingleInvalid() { + AssertionUtils.with(new SingleCommand()) + .assertTabCompletion(new String[]{}, "a"); + } + + @Test + public void testExecuteMultiValid() { + AssertionUtils.with(new MultiCommand()) + .assertExecute("test1->test2", "test1", "test2"); + } + + @Test + public void testExecuteMultiInvalid() { + AssertionUtils.with(new MultiCommand()) + .assertNoExecute("test") + .assertNoExecute("test1", "test"); + } + + @Test + public void testTabCompletionsMultiValid() { + AssertionUtils.with(new MultiCommand()) + .assertTabCompletion(new String[]{"test1"}, "") + .assertTabCompletion(new String[]{"test1"}, "t") + .assertTabCompletion(new String[]{"test1"}, "te") + .assertTabCompletion(new String[]{"test1"}, "tes") + .assertTabCompletion(new String[]{"test1"}, "test") + .assertTabCompletion(new String[]{"test1"}, "test1") + .assertTabCompletion(new String[]{"test2"}, "test1", "") + .assertTabCompletion(new String[]{"test2"}, "test1", "t") + .assertTabCompletion(new String[]{"test2"}, "test1", "te") + .assertTabCompletion(new String[]{"test2"}, "test1", "tes") + .assertTabCompletion(new String[]{"test2"}, "test1", "test") + .assertTabCompletion(new String[]{"test2"}, "test1", "test2"); + } + + @Test + public void testTabCompletionsMultiInvalid() { + AssertionUtils.with(new MultiCommand()) + .assertTabCompletion(new String[]{}, "test2") + .assertTabCompletion(new String[]{}, "test1", "test1"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/startswith/StartsWithTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/startswith/StartsWithTest.java new file mode 100644 index 00000000..3f35a863 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/startswith/StartsWithTest.java @@ -0,0 +1,86 @@ + +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.startswith; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.StartsWith; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class StartsWithTest { + + public static final class CommandWithoutError { + + @Register + public void genericCommand(String sender, @StartsWith("Hello") String t) { + throw new ExecutionIdentifier(t); + } + } + + public static final class CommandWithError { + + @Register + public void genericCommand(String sender, @StartsWith(value = "Hello", error = "Hello must be the prefix") String t) { + throw new ExecutionIdentifier(t); + } + } + + @Test + public void testExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertExecute("Hello", "Hello") + .assertExecute("HelloTest", "HelloTest"); + } + + @Test + public void testNoExecuteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertNoExecute("Test") + .assertNoExecute("Hugo"); + } + + @Test + public void testTabCompleteWithoutError() { + AssertionUtils.with(new CommandWithoutError()) + .assertTabCompletion(new String[]{"Hello"}, "Hello"); + } + + @Test + public void testExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Hello", "Hello") + .assertExecute("HelloTest", "HelloTest"); + } + + @Test + public void testNoExecuteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertExecute("Hello must be the prefix", "Test") + .assertExecute("Hello must be the prefix", "Hugo"); + } + + @Test + public void testTabCompleteWithError() { + AssertionUtils.with(new CommandWithError()) + .assertTabCompletion(new String[]{"Hello"}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/BooleanTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/BooleanTest.java new file mode 100644 index 00000000..fba9fa59 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/BooleanTest.java @@ -0,0 +1,120 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.staticvalue; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.StaticValue; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +@Deprecated +public class BooleanTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, @StaticValue({"a", "b", "c"}) boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, @StaticValue({"a", "b", "c"}) Boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class CustomFalsePrimitiveCommand { + + @Register + public void genericCommand(String sender, @StaticValue(value = {"a", "b", "c"}, falseValues = {1, 2}) boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class CustomFalseObjectCommand { + + @Register + public void genericCommand(String sender, @StaticValue(value = {"a", "b", "c"}, falseValues = {1, 2}) Boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("false", "a") + .assertExecute("true", "b") + .assertExecute("true", "c"); + } + + @Test + public void testNoExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompletePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("false", "a") + .assertExecute("true", "b") + .assertExecute("true", "c"); + } + + @Test + public void testNoExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompleteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecutePrimitiveCustomFalse() { + AssertionUtils.with(new CustomFalsePrimitiveCommand()) + .assertExecute("true", "a") + .assertExecute("false", "b") + .assertExecute("false", "c"); + } + + @Test + public void testExecuteObjectCustomFalse() { + AssertionUtils.with(new CustomFalseObjectCommand()) + .assertExecute("true", "a") + .assertExecute("false", "b") + .assertExecute("false", "c"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/IntTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/IntTest.java new file mode 100644 index 00000000..baa506d4 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/IntTest.java @@ -0,0 +1,88 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.staticvalue; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.StaticValue; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +@Deprecated +public class IntTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, @StaticValue({"a", "b", "c"}) int value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, @StaticValue({"a", "b", "c"}) Integer value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompletePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompleteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/LongTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/LongTest.java new file mode 100644 index 00000000..176f53e8 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/LongTest.java @@ -0,0 +1,88 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.staticvalue; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.StaticValue; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +@Deprecated +public class LongTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, @StaticValue({"a", "b", "c"}) long value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, @StaticValue({"a", "b", "c"}) Long value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompletePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompleteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/StringTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/StringTest.java new file mode 100644 index 00000000..c8d28b33 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/staticvalue/StringTest.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.staticvalue; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.StaticValue; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +@Deprecated +public class StringTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @StaticValue({"a", "b", "c"}) String value) { + throw new ExecutionIdentifier(value); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("a", "a") + .assertExecute("b", "b") + .assertExecute("c", "c"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/supplier/type/.gitkeep b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/supplier/type/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/supplier/value/.gitkeep b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/supplier/value/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterContainsTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterContainsTest.java new file mode 100644 index 00000000..769fabc3 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterContainsTest.java @@ -0,0 +1,79 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.tabfilter; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.TabFilter; +import de.steamwar.command.annotations.TabFilterType; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class TabFilterContainsTest { + + public static class Command { + + @Register + public void test(String sender, @TabFilter(TabFilterType.CONTAINS) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testExecuteValid() { + AssertionUtils.with(new Command()) + .assertExecute("0", "0") + .assertExecute("1", "1") + .assertExecute("-1", "-1") + .assertExecute(Integer.MIN_VALUE + "", Integer.MIN_VALUE + "") + .assertExecute(Integer.MAX_VALUE + "", Integer.MAX_VALUE + ""); + } + + @Test + public void testExecuteInvalid() { + AssertionUtils.with(new Command()) + .assertNoExecute("invalid") + .assertNoExecute("-") + .assertNoExecute("0.0") + .assertNoExecute("-0.0") + .assertNoExecute(Integer.MIN_VALUE + "0") + .assertNoExecute(Integer.MAX_VALUE + "0"); + } + + @Test + public void testTabCompletionValid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1"); + } + + @Test + public void testTabCompletionInvalid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "-0") + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterNoneTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterNoneTest.java new file mode 100644 index 00000000..c9db1270 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterNoneTest.java @@ -0,0 +1,79 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.tabfilter; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.TabFilter; +import de.steamwar.command.annotations.TabFilterType; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class TabFilterNoneTest { + + public static class Command { + + @Register + public void test(String sender, @TabFilter(TabFilterType.NONE) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testExecuteValid() { + AssertionUtils.with(new Command()) + .assertExecute("0", "0") + .assertExecute("1", "1") + .assertExecute("-1", "-1") + .assertExecute(Integer.MIN_VALUE + "", Integer.MIN_VALUE + "") + .assertExecute(Integer.MAX_VALUE + "", Integer.MAX_VALUE + ""); + } + + @Test + public void testExecuteInvalid() { + AssertionUtils.with(new Command()) + .assertNoExecute("invalid") + .assertNoExecute("-") + .assertNoExecute("0.0") + .assertNoExecute("-0.0") + .assertNoExecute(Integer.MIN_VALUE + "0") + .assertNoExecute(Integer.MAX_VALUE + "0"); + } + + @Test + public void testTabCompletionValid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"0", "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1") + .assertTabCompletion(new String[]{"0", "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "01"); + } + + @Test + public void testTabCompletionInvalid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterStartsWithTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterStartsWithTest.java new file mode 100644 index 00000000..f5d45f1e --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/tabfilter/TabFilterStartsWithTest.java @@ -0,0 +1,79 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.tabfilter; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.TabFilter; +import de.steamwar.command.annotations.TabFilterType; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class TabFilterStartsWithTest { + + public static class Command { + + @Register + public void test(String sender, @TabFilter(TabFilterType.STARTS_WITH) int i) { + throw new ExecutionIdentifier(i + ""); + } + } + + @Test + public void testExecuteValid() { + AssertionUtils.with(new Command()) + .assertExecute("0", "0") + .assertExecute("1", "1") + .assertExecute("-1", "-1") + .assertExecute(Integer.MIN_VALUE + "", Integer.MIN_VALUE + "") + .assertExecute(Integer.MAX_VALUE + "", Integer.MAX_VALUE + ""); + } + + @Test + public void testExecuteInvalid() { + AssertionUtils.with(new Command()) + .assertNoExecute("invalid") + .assertNoExecute("-") + .assertNoExecute("0.0") + .assertNoExecute("-0.0") + .assertNoExecute(Integer.MIN_VALUE + "0") + .assertNoExecute(Integer.MAX_VALUE + "0"); + } + + @Test + public void testTabCompletionValid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1"); + } + + @Test + public void testTabCompletionInvalid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "-0") + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/unique/GreedyUniqueTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/unique/GreedyUniqueTest.java new file mode 100644 index 00000000..fe3cca3a --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/unique/GreedyUniqueTest.java @@ -0,0 +1,73 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.unique; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Greedy; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Unique; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyUniqueTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Greedy @Unique int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("[0, 1, 2]", "0", "1", "2") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0]", "0") + .assertExecute("[]"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("0", "1", "2", "2") + .assertNoExecute("0", "1", "1", "2") + .assertNoExecute("0", "0", "1", "2"); + } + + @Test + public void testTabCompletion() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "") + .assertTabCompletion(new String[]{"2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "1", "") + .assertTabCompletion(new String[]{"3", "4", "5", "6", "7", "8", "9", "-"}, "0", "1", "2", "") + .assertTabCompletion(new String[]{"4", "5", "6", "7", "8", "9", "-"}, "0", "1", "2", "3", "") + .assertTabCompletion(new String[]{"5", "6", "7", "8", "9", "-"}, "0", "1", "2", "3", "4", "") + .assertTabCompletion(new String[]{"6", "7", "8", "9", "-"}, "0", "1", "2", "3", "4", "5", "") + .assertTabCompletion(new String[]{"7", "8", "9", "-"}, "0", "1", "2", "3", "4", "5", "6", "") + .assertTabCompletion(new String[]{"8", "9", "-"}, "0", "1", "2", "3", "4", "5", "6", "7", "") + .assertTabCompletion(new String[]{"9", "-"}, "0", "1", "2", "3", "4", "5", "6", "7", "8", "") + .assertTabCompletion(new String[]{"-"}, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/unique/NonGreedyUniqueTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/unique/NonGreedyUniqueTest.java new file mode 100644 index 00000000..37635cb9 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/unique/NonGreedyUniqueTest.java @@ -0,0 +1,72 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.unique; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Unique; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyUniqueTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Unique int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("[0, 1, 2]", "0", "1", "2") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0]", "0") + .assertExecute("[]"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("0", "1", "2", "2") + .assertNoExecute("0", "1", "1", "2") + .assertNoExecute("0", "0", "1", "2"); + } + + @Test + public void testTabCompletion() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "") + .assertTabCompletion(new String[]{"2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "1", "") + .assertTabCompletion(new String[]{"3", "4", "5", "6", "7", "8", "9", "-"}, "0", "1", "2", "") + .assertTabCompletion(new String[]{"4", "5", "6", "7", "8", "9", "-"}, "0", "1", "2", "3", "") + .assertTabCompletion(new String[]{"5", "6", "7", "8", "9", "-"}, "0", "1", "2", "3", "4", "") + .assertTabCompletion(new String[]{"6", "7", "8", "9", "-"}, "0", "1", "2", "3", "4", "5", "") + .assertTabCompletion(new String[]{"7", "8", "9", "-"}, "0", "1", "2", "3", "4", "5", "6", "") + .assertTabCompletion(new String[]{"8", "9", "-"}, "0", "1", "2", "3", "4", "5", "6", "7", "") + .assertTabCompletion(new String[]{"9", "-"}, "0", "1", "2", "3", "4", "5", "6", "7", "8", "") + .assertTabCompletion(new String[]{"-"}, "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/type/GlobalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/type/GlobalTest.java new file mode 100644 index 00000000..7b99193e --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/type/GlobalTest.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.validator.type; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Validator; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeValidator; +import org.junit.Test; + +import java.math.BigInteger; + +public class GlobalTest { + + public static class FirstCommand { + + @Validator(type = BigInteger.class, local = false) + public TestTypeValidator globalValidator() { + return (sender, value, messageSender) -> { + return false; + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Validator BigInteger b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testGlobalValidator() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertNoExecute("0"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/type/LocalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/type/LocalTest.java new file mode 100644 index 00000000..0561fee1 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/type/LocalTest.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.validator.type; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Validator; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeValidator; +import org.junit.Test; + +import java.math.BigInteger; + +public class LocalTest { + + public static class FirstCommand { + + @Validator(type = BigInteger.class) + public TestTypeValidator localValidator() { + return (sender, value, messageSender) -> { + return false; + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Validator String b) { + throw new ExecutionIdentifier(b); + } + } + + @Test + public void testGlobalValidator() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertNoInitialize("Validator '' not found"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/GlobalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/GlobalTest.java new file mode 100644 index 00000000..2b5154b7 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/GlobalTest.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.validator.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Validator; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeValidator; +import org.junit.Test; + +import java.math.BigInteger; + +public class GlobalTest { + + public static class FirstCommand { + + @Validator(value = "globalValidator", local = false) + public TestTypeValidator globalValidator() { + return (sender, value, messageSender) -> { + return false; + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Validator("globalValidator") BigInteger b) { + throw new ExecutionIdentifier(b.toString()); + } + } + + @Test + public void testGlobalValidator() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertNoExecute("0"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/LocalTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/LocalTest.java new file mode 100644 index 00000000..0d71baab --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/LocalTest.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.validator.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Validator; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeValidator; +import org.junit.Test; + +import java.math.BigInteger; + +public class LocalTest { + + public static class FirstCommand { + + @Validator(value = "localValidator") + public TestTypeValidator localValidator() { + return (sender, value, messageSender) -> { + return false; + }; + } + } + + public static class SecondCommand { + + @Register + public void genericCommand(String sender, @Validator("localValidator") String b) { + throw new ExecutionIdentifier(b); + } + } + + @Test + public void testGlobalValidator() { + AssertionUtils.with(new FirstCommand()) + .assertNoExecute(""); + + AssertionUtils.with(new SecondCommand()) + .assertNoInitialize("Validator 'localValidator' not found"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/MultiTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/MultiTest.java new file mode 100644 index 00000000..be8bd949 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/validator/value/MultiTest.java @@ -0,0 +1,84 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.validator.value; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Validator; +import de.steamwar.command.impl.ExecutionIdentifier; +import de.steamwar.command.impl.TestTypeValidator; +import org.junit.Test; + +public class MultiTest { + + public static class Command { + + private boolean validator_1; + private boolean validator_2; + + public Command(boolean validator_1, boolean validator_2) { + this.validator_1 = validator_1; + this.validator_2 = validator_2; + } + + @Register + public void genericCommand(String sender, @Validator("validator_1") @Validator("validator_2") String s) { + throw new ExecutionIdentifier(s); + } + + @Validator(value = "validator_1") + public TestTypeValidator validator_1() { + return (sender, value, messageSender) -> { + return validator_1; + }; + } + + @Validator(value = "validator_2") + public TestTypeValidator validator_2() { + return (sender, value, messageSender) -> { + return validator_2; + }; + } + } + + @Test + public void testMultiValidatorTrueTrue() { + AssertionUtils.with(new Command(true, true)) + .assertExecute("Hello", "Hello"); + } + + @Test + public void testMultiValidatorTrueFalse() { + AssertionUtils.with(new Command(true, false)) + .assertNoExecute("Hello"); + } + + @Test + public void testMultiValidatorFalseTrue() { + AssertionUtils.with(new Command(false, true)) + .assertNoExecute("Hello"); + } + + @Test + public void testMultiValidatorFalseFalse() { + AssertionUtils.with(new Command(false, false)) + .assertNoExecute("Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/BooleanTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/BooleanTest.java new file mode 100644 index 00000000..4f29ee55 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/BooleanTest.java @@ -0,0 +1,119 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.values; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Values; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class BooleanTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, @Values({"a", "b", "c"}) boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, @Values({"a", "b", "c"}) Boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class CustomFalsePrimitiveCommand { + + @Register + public void genericCommand(String sender, @Values(value = {"a", "b", "c"}, falseValues = {1, 2}) boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class CustomFalseObjectCommand { + + @Register + public void genericCommand(String sender, @Values(value = {"a", "b", "c"}, falseValues = {1, 2}) Boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("false", "a") + .assertExecute("true", "b") + .assertExecute("true", "c"); + } + + @Test + public void testNoExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompletePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("false", "a") + .assertExecute("true", "b") + .assertExecute("true", "c"); + } + + @Test + public void testNoExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompleteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecutePrimitiveCustomFalse() { + AssertionUtils.with(new CustomFalsePrimitiveCommand()) + .assertExecute("true", "a") + .assertExecute("false", "b") + .assertExecute("false", "c"); + } + + @Test + public void testExecuteObjectCustomFalse() { + AssertionUtils.with(new CustomFalseObjectCommand()) + .assertExecute("true", "a") + .assertExecute("false", "b") + .assertExecute("false", "c"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/IntTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/IntTest.java new file mode 100644 index 00000000..cc5e9937 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/IntTest.java @@ -0,0 +1,87 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.values; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Values; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class IntTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, @Values({"a", "b", "c"}) int value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, @Values({"a", "b", "c"}) Integer value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompletePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompleteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/LongTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/LongTest.java new file mode 100644 index 00000000..0eef62db --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/LongTest.java @@ -0,0 +1,87 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.values; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Values; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class LongTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, @Values({"a", "b", "c"}) long value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, @Values({"a", "b", "c"}) Long value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecutePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompletePrimitive() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } + + @Test + public void testExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0", "a") + .assertExecute("1", "b") + .assertExecute("2", "c"); + } + + @Test + public void testNoExecuteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabCompleteObject() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/StringTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/StringTest.java new file mode 100644 index 00000000..d01dca92 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/annotations/values/StringTest.java @@ -0,0 +1,58 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.annotations.values; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Values; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class StringTest { + + public static class Command { + + @Register + public void genericCommand(String sender, @Values({"a", "b", "c"}) String value) { + throw new ExecutionIdentifier(value); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("a", "a") + .assertExecute("b", "b") + .assertExecute("c", "c"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("ab") + .assertNoExecute("d"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"a", "b", "c"}, ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/array/GreedyTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/array/GreedyTest.java new file mode 100644 index 00000000..3332ced6 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/array/GreedyTest.java @@ -0,0 +1,70 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.array; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class GreedyTest { + + public static class Command { + + @Register + public void genericCommand(String sender, int... args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("[0, 1, 2]", "0", "1", "2") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0]", "0") + .assertExecute("[]"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("0", "1", "b") + .assertNoExecute("0", "b") + .assertNoExecute("b"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "") + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "0", ""); + } + + @Test + public void testNoTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "0", "b") + .assertTabCompletion(new String[]{}, "b", "0", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/array/NonGreedyTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/array/NonGreedyTest.java new file mode 100644 index 00000000..453c3add --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/array/NonGreedyTest.java @@ -0,0 +1,70 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.array; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +import java.util.Arrays; + +public class NonGreedyTest { + + public static class Command { + + @Register + public void genericCommand(String sender, int[] args) { + throw new ExecutionIdentifier(Arrays.toString(args)); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("[0, 1, 2]", "0", "1", "2") + .assertExecute("[0, 1]", "0", "1") + .assertExecute("[0]", "0") + .assertExecute("[]"); + } + + @Test + public void testNoExecute() { + AssertionUtils.with(new Command()) + .assertNoExecute("0", "1", "b") + .assertNoExecute("0", "b") + .assertNoExecute("b"); + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "") + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "0", "0", ""); + } + + @Test + public void testNoTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "0", "b") + .assertTabCompletion(new String[]{}, "b", "0", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/enumeration/EnumTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/enumeration/EnumTest.java new file mode 100644 index 00000000..db482d63 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/enumeration/EnumTest.java @@ -0,0 +1,99 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.enumeration; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class EnumTest { + + public static class Command { + + @Register + public void genericCommand(String sender, TestEnum value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public enum TestEnum { + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY, + SUNDAY + } + + @Test + public void testExecuteValid() { + AssertionUtils.with(new Command()) + .assertExecute("MONDAY", "MONDAY") + .assertExecute("MONDAY", "monday") + .assertExecute("TUESDAY", "TUESDAY") + .assertExecute("TUESDAY", "tUeSdAY") + .assertExecute("WEDNESDAY", "WEDNESDAY") + .assertExecute("WEDNESDAY", "wedNesDay") + .assertExecute("THURSDAY", "THURSDAY") + .assertExecute("THURSDAY", "THURSDAY") + .assertExecute("THURSDAY", "THuRSdAY") + .assertExecute("FRIDAY", "FRIDAY") + .assertExecute("FRIDAY", "FRidAY") + .assertExecute("SATURDAY", "SATURDAY") + .assertExecute("SATURDAY", "SaTuRDaY") + .assertExecute("SUNDAY", "SUNDAY") + .assertExecute("SUNDAY", "SUnDAY"); + } + + @Test + public void testExecuteInvalid() { + AssertionUtils.with(new Command()) + .assertNoExecute("m") + .assertNoExecute("mon") + .assertNoExecute("monday2") + .assertNoExecute("0Monday"); + } + + @Test + public void testTabCompletionsValid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"}, "") + .assertTabCompletion(new String[]{"MONDAY"}, "m") + .assertTabCompletion(new String[]{"TUESDAY", "THURSDAY"}, "t") + .assertTabCompletion(new String[]{"TUESDAY"}, "tu") + .assertTabCompletion(new String[]{"THURSDAY"}, "th") + .assertTabCompletion(new String[]{"WEDNESDAY"}, "w") + .assertTabCompletion(new String[]{"FRIDAY"}, "f") + .assertTabCompletion(new String[]{"SATURDAY", "SUNDAY"}, "s") + .assertTabCompletion(new String[]{"SATURDAY"}, "sa") + .assertTabCompletion(new String[]{"SUNDAY"}, "su"); + } + + @Test + public void testTabCompletionsInvalid() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "mu") + .assertTabCompletion(new String[]{}, "m0") + .assertTabCompletion(new String[]{}, "tuel") + .assertTabCompletion(new String[]{}, "tes"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/enumeration/OptionEnumTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/enumeration/OptionEnumTest.java new file mode 100644 index 00000000..f9456ddc --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/enumeration/OptionEnumTest.java @@ -0,0 +1,208 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.enumeration; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.OptionEnum; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class OptionEnumTest { + + public static class SingleCommand { + + @Register + public void genericCommand(String sender, TestEnum value1) { + throw new ExecutionIdentifier(value1 + ""); + } + } + + public static class MultiCommand { + + @Register + public void genericCommand(String sender, TestEnum value1, TestEnum value2) { + throw new ExecutionIdentifier(value1 + ":" + value2); + } + } + + public enum TestEnum implements OptionEnum { + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY, + SUNDAY; + + + @Override + public TestEnum[] getRemoved() { + return new TestEnum[]{ + MONDAY, + TUESDAY + }; + } + } + + @Test + public void testExecuteSingleValid() { + AssertionUtils.with(new SingleCommand()) + .assertExecute("MONDAY", "-monday") + .assertExecute("TUESDAY", "-tuesday") + .assertExecute("WEDNESDAY", "-wednesday") + .assertExecute("THURSDAY", "-thursday") + .assertExecute("FRIDAY", "-friday") + .assertExecute("SATURDAY", "-saturday") + .assertExecute("SUNDAY", "-sunday"); + } + + + @Test + public void testExecuteSingleInvalid() { + AssertionUtils.with(new SingleCommand()) + .assertNoExecute("-m") + .assertNoExecute("-mon") + .assertNoExecute("-monday2") + .assertNoExecute("-0Monday"); + } + + @Test + public void testTabCompletionsSingleValid() { + AssertionUtils.with(new SingleCommand()) + .assertTabCompletion(new String[]{"-monday", "-tuesday", "-wednesday", "-thursday", "-friday", "-saturday", "-sunday"}, "") + .assertTabCompletion(new String[]{"-monday", "-tuesday", "-wednesday", "-thursday", "-friday", "-saturday", "-sunday"}, "-") + .assertTabCompletion(new String[]{"-monday"}, "-m") + .assertTabCompletion(new String[]{"-tuesday", "-thursday"}, "-t") + .assertTabCompletion(new String[]{"-tuesday"}, "-tu") + .assertTabCompletion(new String[]{"-thursday"}, "-th") + .assertTabCompletion(new String[]{"-wednesday"}, "-w") + .assertTabCompletion(new String[]{"-friday"}, "-f") + .assertTabCompletion(new String[]{"-saturday", "-sunday"}, "-s") + .assertTabCompletion(new String[]{"-saturday"}, "-sa") + .assertTabCompletion(new String[]{"-sunday"}, "-su"); + } + + @Test + public void testTabCompletionsSingleInvalid() { + AssertionUtils.with(new SingleCommand()) + .assertTabCompletion(new String[]{}, "-mu") + .assertTabCompletion(new String[]{}, "-m0") + .assertTabCompletion(new String[]{}, "-tuel") + .assertTabCompletion(new String[]{}, "-tes"); + } + + @Test + public void testExecuteMultiValid() { + AssertionUtils.with(new MultiCommand()) + .assertExecute("MONDAY:WEDNESDAY", "-monday", "-wednesday") + .assertExecute("MONDAY:THURSDAY", "-monday", "-thursday") + .assertExecute("MONDAY:FRIDAY", "-monday", "-friday") + .assertExecute("MONDAY:SATURDAY", "-monday", "-saturday") + .assertExecute("MONDAY:SUNDAY", "-monday", "-sunday") + .assertExecute("TUESDAY:WEDNESDAY", "-tuesday", "-wednesday") + .assertExecute("TUESDAY:THURSDAY", "-tuesday", "-thursday") + .assertExecute("TUESDAY:FRIDAY", "-tuesday", "-friday") + .assertExecute("TUESDAY:SATURDAY", "-tuesday", "-saturday") + .assertExecute("TUESDAY:SUNDAY", "-tuesday", "-sunday") + .assertExecute("WEDNESDAY:THURSDAY", "-wednesday", "-thursday") + .assertExecute("WEDNESDAY:FRIDAY", "-wednesday", "-friday") + .assertExecute("WEDNESDAY:SATURDAY", "-wednesday", "-saturday") + .assertExecute("WEDNESDAY:SUNDAY", "-wednesday", "-sunday") + .assertExecute("THURSDAY:WEDNESDAY", "-thursday", "-wednesday") + .assertExecute("THURSDAY:FRIDAY", "-thursday", "-friday") + .assertExecute("THURSDAY:SATURDAY", "-thursday", "-saturday") + .assertExecute("THURSDAY:SUNDAY", "-thursday", "-sunday") + .assertExecute("FRIDAY:WEDNESDAY", "-friday", "-wednesday") + .assertExecute("FRIDAY:THURSDAY", "-friday", "-thursday") + .assertExecute("FRIDAY:SATURDAY", "-friday", "-saturday") + .assertExecute("FRIDAY:SUNDAY", "-friday", "-sunday") + .assertExecute("SATURDAY:WEDNESDAY", "-saturday", "-wednesday") + .assertExecute("SATURDAY:THURSDAY", "-saturday", "-thursday") + .assertExecute("SATURDAY:FRIDAY", "-saturday", "-friday") + .assertExecute("SATURDAY:SUNDAY", "-saturday", "-sunday") + .assertExecute("SUNDAY:WEDNESDAY", "-sunday", "-wednesday") + .assertExecute("SUNDAY:THURSDAY", "-sunday", "-thursday") + .assertExecute("SUNDAY:FRIDAY", "-sunday", "-friday") + .assertExecute("SUNDAY:SATURDAY", "-sunday", "-saturday"); + } + + @Test + public void testExecuteMultiInvalid() { + AssertionUtils.with(new MultiCommand()) + .assertNoExecute("-monday", "-monday") + .assertNoExecute("-monday", "-tuesday") + .assertNoExecute("-tuesday", "-monday") + .assertNoExecute("-tuesday", "-tuesday") + .assertNoExecute("-wednesday", "-monday") + .assertNoExecute("-wednesday", "-tuesday") + .assertNoExecute("-wednesday", "-wednesday") + .assertNoExecute("-thursday", "-monday") + .assertNoExecute("-thursday", "-tuesday") + .assertNoExecute("-thursday", "-thursday") + .assertNoExecute("-friday", "-monday") + .assertNoExecute("-friday", "-tuesday") + .assertNoExecute("-friday", "-friday") + .assertNoExecute("-saturday", "-monday") + .assertNoExecute("-saturday", "-tuesday") + .assertNoExecute("-saturday", "-saturday") + .assertNoExecute("-sunday", "-monday") + .assertNoExecute("-sunday", "-tuesday") + .assertNoExecute("-sunday", "-sunday"); + } + + @Test + public void testTabCompletionsMultiValid() { + AssertionUtils.with(new MultiCommand()) + .assertTabCompletion(new String[]{"-wednesday", "-thursday", "-friday", "-saturday", "-sunday"}, "-monday", "") + .assertTabCompletion(new String[]{"-wednesday", "-thursday", "-friday", "-saturday", "-sunday"}, "-monday", "-") + .assertTabCompletion(new String[]{"-wednesday", "-friday", "-saturday", "-sunday"}, "-thursday", "") + .assertTabCompletion(new String[]{"-wednesday", "-friday", "-saturday", "-sunday"}, "-thursday", "-") + .assertTabCompletion(new String[]{"-wednesday"}, "-thursday", "-w") + .assertTabCompletion(new String[]{"-friday"}, "-thursday", "-f") + .assertTabCompletion(new String[]{"-saturday", "-sunday"}, "-thursday", "-s") + .assertTabCompletion(new String[]{"-saturday"}, "-thursday", "-sa") + .assertTabCompletion(new String[]{"-sunday"}, "-thursday", "-su"); + } + + @Test + public void testTabCompletionsMultiInvalid() { + AssertionUtils.with(new MultiCommand()) + .assertTabCompletion(new String[]{}, "-monday", "-m") + .assertTabCompletion(new String[]{}, "-monday", "-tu") + .assertTabCompletion(new String[]{}, "-tuesday", "-m") + .assertTabCompletion(new String[]{}, "-tuesday", "-tu") + .assertTabCompletion(new String[]{}, "-wednesday", "-m") + .assertTabCompletion(new String[]{}, "-wednesday", "-tu") + .assertTabCompletion(new String[]{}, "-wednesday", "-w") + .assertTabCompletion(new String[]{}, "-thursday", "-m") + .assertTabCompletion(new String[]{}, "-thursday", "-tu") + .assertTabCompletion(new String[]{}, "-thursday", "-th") + .assertTabCompletion(new String[]{}, "-friday", "-m") + .assertTabCompletion(new String[]{}, "-friday", "-tu") + .assertTabCompletion(new String[]{}, "-friday", "-f") + .assertTabCompletion(new String[]{}, "-saturday", "-m") + .assertTabCompletion(new String[]{}, "-saturday", "-tu") + .assertTabCompletion(new String[]{}, "-saturday", "-sa") + .assertTabCompletion(new String[]{}, "-sunday", "-m") + .assertTabCompletion(new String[]{}, "-sunday", "-tu") + .assertTabCompletion(new String[]{}, "-sunday", "-su"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/other/DoubleSpaceTabCompletionTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/other/DoubleSpaceTabCompletionTest.java new file mode 100644 index 00000000..b3d7d1b2 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/other/DoubleSpaceTabCompletionTest.java @@ -0,0 +1,45 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.other; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.annotations.Values; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class DoubleSpaceTabCompletionTest { + + public static class Command { + + @Register + public void test(String sender, @Values({"Hello", "World"}) String s) { + throw new ExecutionIdentifier(s); + } + } + + @Test + public void testTabComplete() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{"Hello", "World"}, "") + .assertTabCompletion(new String[]{"Hello", "World"}, "", "") + .assertTabCompletion(new String[]{"Hello", "World"}, "", "", ""); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/BooleanTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/BooleanTest.java new file mode 100644 index 00000000..bb7d2209 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/BooleanTest.java @@ -0,0 +1,116 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.primitive; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class BooleanTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, Boolean value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testPrimitiveExecuteValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("true", "true") + .assertExecute("false", "false"); + } + + @Test + public void testPrimitiveExecuteInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("invalid"); + } + + @Test + public void testPrimitiveTabCompletionValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"true", "false"}, "") + .assertTabCompletion(new String[]{"true"}, "t") + .assertTabCompletion(new String[]{"true"}, "tr") + .assertTabCompletion(new String[]{"true"}, "tru") + .assertTabCompletion(new String[]{"true"}, "true") + .assertTabCompletion(new String[]{"false"}, "f") + .assertTabCompletion(new String[]{"false"}, "fa") + .assertTabCompletion(new String[]{"false"}, "fal") + .assertTabCompletion(new String[]{"false"}, "fals") + .assertTabCompletion(new String[]{"false"}, "false"); + } + + @Test + public void testPrimitiveTabCompletionInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{}, "h") + .assertTabCompletion(new String[]{}, "u") + .assertTabCompletion(new String[]{}, "a"); + } + + @Test + public void testObjectExecuteValid() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("true", "true") + .assertExecute("false", "false"); + } + + @Test + public void testObjectExecuteInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("invalid"); + } + + @Test + public void testObjectTabCompletionValid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"true", "false"}, "") + .assertTabCompletion(new String[]{"true"}, "t") + .assertTabCompletion(new String[]{"true"}, "tr") + .assertTabCompletion(new String[]{"true"}, "tru") + .assertTabCompletion(new String[]{"true"}, "true") + .assertTabCompletion(new String[]{"false"}, "f") + .assertTabCompletion(new String[]{"false"}, "fa") + .assertTabCompletion(new String[]{"false"}, "fal") + .assertTabCompletion(new String[]{"false"}, "fals") + .assertTabCompletion(new String[]{"false"}, "false"); + } + + @Test + public void testObjectTabCompletionInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{}, "h") + .assertTabCompletion(new String[]{}, "u") + .assertTabCompletion(new String[]{}, "a"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/DoubleTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/DoubleTest.java new file mode 100644 index 00000000..9c6ea976 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/DoubleTest.java @@ -0,0 +1,124 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.primitive; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class DoubleTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, double value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, Double value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testPrimitiveExecuteValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0.0", "0") + .assertExecute("0.5", "0.5") + .assertExecute("1.0", "1") + .assertExecute("1.5", "1.5") + .assertExecute("-1.0", "-1") + .assertExecute("-1.5", "-1.5") + .assertExecute(Double.MIN_VALUE + "", Double.MIN_VALUE + "") + .assertExecute(Double.MIN_NORMAL + "", Double.MIN_NORMAL + "") + .assertExecute(Double.MAX_VALUE + "", Double.MAX_VALUE + ""); + } + + @Test + public void testPrimitiveExecuteInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("invalid"); + } + + @Test + public void testPrimitiveTabCompletionValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0", "0."}, "0") + .assertTabCompletion(new String[]{"1", "1.", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-1.", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1") + .assertTabCompletion(new String[]{"-0."}, "-0"); + } + + @Test + public void testPrimitiveTabCompletionInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } + + @Test + public void testObjectExecuteValid() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0.0", "0") + .assertExecute("0.5", "0.5") + .assertExecute("1.0", "1") + .assertExecute("1.5", "1.5") + .assertExecute("-1.0", "-1") + .assertExecute("-1.5", "-1.5") + .assertExecute(Double.MIN_VALUE + "", Double.MIN_VALUE + "") + .assertExecute(Double.MIN_NORMAL + "", Double.MIN_NORMAL + "") + .assertExecute(Double.MAX_VALUE + "", Double.MAX_VALUE + ""); + } + + @Test + public void testObjectExecuteInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("invalid"); + } + + @Test + public void testObjectTabCompletionValid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0", "0."}, "0") + .assertTabCompletion(new String[]{"1", "1.", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-1.", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1") + .assertTabCompletion(new String[]{"-0."}, "-0"); + } + + @Test + public void testObjectTabCompletionInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/FloatTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/FloatTest.java new file mode 100644 index 00000000..b7518c32 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/FloatTest.java @@ -0,0 +1,124 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.primitive; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class FloatTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, float value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, Float value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testPrimitiveExecuteValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0.0", "0") + .assertExecute("0.5", "0.5") + .assertExecute("1.0", "1") + .assertExecute("1.5", "1.5") + .assertExecute("-1.0", "-1") + .assertExecute("-1.5", "-1.5") + .assertExecute(Float.MIN_VALUE + "", Float.MIN_VALUE + "") + .assertExecute(Float.MIN_NORMAL + "", Float.MIN_NORMAL + "") + .assertExecute(Float.MAX_VALUE + "", Float.MAX_VALUE + ""); + } + + @Test + public void testPrimitiveExecuteInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("invalid"); + } + + @Test + public void testPrimitiveTabCompletionValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[] {"0", "0."}, "0") + .assertTabCompletion(new String[] {"1", "1.", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[] {"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[] {"-1", "-1.", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1") + .assertTabCompletion(new String[] {"-0."}, "-0"); + } + + @Test + public void testPrimitiveTabCompletionInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[] {}, "01") + .assertTabCompletion(new String[] {}, "NaN") + .assertTabCompletion(new String[] {}, "a") + .assertTabCompletion(new String[] {}, "Hello"); + } + + @Test + public void testObjectExecuteValid() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0.0", "0") + .assertExecute("0.5", "0.5") + .assertExecute("1.0", "1") + .assertExecute("1.5", "1.5") + .assertExecute("-1.0", "-1") + .assertExecute("-1.5", "-1.5") + .assertExecute(Float.MIN_VALUE + "", Float.MIN_VALUE + "") + .assertExecute(Float.MIN_NORMAL + "", Float.MIN_NORMAL + "") + .assertExecute(Float.MAX_VALUE + "", Float.MAX_VALUE + ""); + } + + @Test + public void testObjectExecuteInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("invalid"); + } + + @Test + public void testObjectTabCompletionValid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0", "0."}, "0") + .assertTabCompletion(new String[]{"1", "1.", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-1.", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1") + .assertTabCompletion(new String[]{"-0."}, "-0"); + } + + @Test + public void testObjectTabCompletionInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/IntTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/IntTest.java new file mode 100644 index 00000000..843481e1 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/IntTest.java @@ -0,0 +1,126 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.primitive; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class IntTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, int value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, Integer value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testPrimitiveExecuteValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0", "0") + .assertExecute("1", "1") + .assertExecute("-1", "-1") + .assertExecute(Integer.MIN_VALUE + "", Integer.MIN_VALUE + "") + .assertExecute(Integer.MAX_VALUE + "", Integer.MAX_VALUE + ""); + } + + @Test + public void testPrimitiveExecuteInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("invalid") + .assertNoExecute("-") + .assertNoExecute("0.0") + .assertNoExecute("-0.0") + .assertNoExecute(Integer.MIN_VALUE + "0") + .assertNoExecute(Integer.MAX_VALUE + "0"); + } + + @Test + public void testPrimitiveTabCompletionValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1"); + } + + @Test + public void testPrimitiveTabCompletionInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertTabCompletion(new String[]{}, "-0") + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } + + @Test + public void testObjectExecuteValid() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0", "0") + .assertExecute("1", "1") + .assertExecute("-1", "-1") + .assertExecute(Integer.MIN_VALUE + "", Integer.MIN_VALUE + "") + .assertExecute(Integer.MAX_VALUE + "", Integer.MAX_VALUE + ""); + } + + @Test + public void testObjectExecuteInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("invalid") + .assertNoExecute("-") + .assertNoExecute("0.0") + .assertNoExecute("-0.0") + .assertNoExecute(Integer.MIN_VALUE + "0") + .assertNoExecute(Integer.MAX_VALUE + "0"); + } + + @Test + public void testObjectTabCompletionValid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1"); + } + + @Test + public void testObjectTabCompletionInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertTabCompletion(new String[]{}, "-0") + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/LongTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/LongTest.java new file mode 100644 index 00000000..da510402 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/LongTest.java @@ -0,0 +1,126 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.primitive; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class LongTest { + + public static class PrimitiveCommand { + + @Register + public void genericCommand(String sender, long value) { + throw new ExecutionIdentifier(value + ""); + } + } + + public static class ObjectCommand { + + @Register + public void genericCommand(String sender, Long value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testPrimitiveExecuteValid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertExecute("0", "0") + .assertExecute("1", "1") + .assertExecute("-1", "-1") + .assertExecute(Long.MIN_VALUE + "", Long.MIN_VALUE + "") + .assertExecute(Long.MAX_VALUE + "", Long.MAX_VALUE + ""); + } + + @Test + public void testPrimitiveExecuteInvalid() { + AssertionUtils.with(new PrimitiveCommand()) + .assertNoExecute("invalid") + .assertNoExecute("-") + .assertNoExecute("0.0") + .assertNoExecute("-0.0") + .assertNoExecute(Long.MIN_VALUE + "0") + .assertNoExecute(Long.MAX_VALUE + "0"); + } + + @Test + public void testPrimitiveTabCompletionValid() { + AssertionUtils.with(new IntTest.PrimitiveCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1"); + } + + @Test + public void testPrimitiveTabCompletionInvalid() { + AssertionUtils.with(new IntTest.PrimitiveCommand()) + .assertTabCompletion(new String[]{}, "-0") + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } + + @Test + public void testObjectExecuteValid() { + AssertionUtils.with(new ObjectCommand()) + .assertExecute("0", "0") + .assertExecute("1", "1") + .assertExecute("-1", "-1") + .assertExecute(Long.MIN_VALUE + "", Long.MIN_VALUE + "") + .assertExecute(Long.MAX_VALUE + "", Long.MAX_VALUE + ""); + } + + @Test + public void testObjectExecuteInvalid() { + AssertionUtils.with(new ObjectCommand()) + .assertNoExecute("invalid") + .assertNoExecute("-") + .assertNoExecute("0.0") + .assertNoExecute("-0.0") + .assertNoExecute(Long.MIN_VALUE + "0") + .assertNoExecute(Long.MAX_VALUE + "0"); + } + + @Test + public void testObjectTabCompletionValid() { + AssertionUtils.with(new IntTest.ObjectCommand()) + .assertTabCompletion(new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-"}, "") + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"1", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"}, "1") + .assertTabCompletion(new String[]{"-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9"}, "-") + .assertTabCompletion(new String[]{"-1", "-10", "-11", "-12", "-13", "-14", "-15", "-16", "-17", "-18", "-19"}, "-1"); + } + + @Test + public void testObjectTabCompletionInvalid() { + AssertionUtils.with(new IntTest.ObjectCommand()) + .assertTabCompletion(new String[]{}, "-0") + .assertTabCompletion(new String[]{}, "01") + .assertTabCompletion(new String[]{}, "NaN") + .assertTabCompletion(new String[]{}, "a") + .assertTabCompletion(new String[]{}, "Hello"); + } +} diff --git a/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/StringTest.java b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/StringTest.java new file mode 100644 index 00000000..c1af9810 --- /dev/null +++ b/CommandFramework/CommandFrameworkTests/testsrc/de/steamwar/command/tests/primitive/StringTest.java @@ -0,0 +1,65 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.tests.primitive; + +import de.steamwar.AssertionUtils; +import de.steamwar.command.annotations.Register; +import de.steamwar.command.impl.ExecutionIdentifier; +import org.junit.Test; + +public class StringTest { + + public static class Command { + + @Register + public void genericCommand(String sender, String value) { + throw new ExecutionIdentifier(value + ""); + } + } + + @Test + public void testExecute() { + AssertionUtils.with(new Command()) + .assertExecute("Hello", "Hello") + .assertExecute("s", "s") + .assertExecute("0", "0") + .assertExecute("_", "_") + .assertExecute("-", "-") + .assertExecute("/", "/") + .assertExecute("@", "@") + .assertExecute("\\", "\\") + .assertExecute("\"", "\""); + } + + @Test + public void testTabCompletion() { + AssertionUtils.with(new Command()) + .assertTabCompletion(new String[]{}, "") + .assertTabCompletion(new String[]{"a"}, "a") + .assertTabCompletion(new String[]{"Hello"}, "Hello") + .assertTabCompletion(new String[]{"0"}, "0") + .assertTabCompletion(new String[]{"_"}, "_") + .assertTabCompletion(new String[]{"-"}, "-") + .assertTabCompletion(new String[]{"/"}, "/") + .assertTabCompletion(new String[]{"@"}, "@") + .assertTabCompletion(new String[]{"\\"}, "\\") + .assertTabCompletion(new String[]{"\""}, "\""); + } +} diff --git a/CommandFramework/CommandFrameworkVelocity/build.gradle.kts b/CommandFramework/CommandFrameworkVelocity/build.gradle.kts new file mode 100644 index 00000000..1d9c00b7 --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/build.gradle.kts @@ -0,0 +1,34 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +plugins { + steamwar.java +} + +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +dependencies { + implementation(project(":CommandFramework:CommandFrameworkBase", "default")) + + annotationProcessor(libs.velocityapi) + compileOnly(libs.velocity) +} \ No newline at end of file diff --git a/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommand.java b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommand.java new file mode 100644 index 00000000..f64a2f2e --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommand.java @@ -0,0 +1,152 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import de.steamwar.command.mapper.ProxiedPlayerMapper; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Command; +import net.md_5.bungee.api.plugin.TabExecutor; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.logging.Level; + +public class VelocityCommand extends AbstractCommand { + + static { + CommandUtils.addMapper(ProxiedPlayer.class, new ProxiedPlayerMapper()); + addExecutorMapper(VelocityCommand.class, CommandSender.class, Function.identity()); + } + + private Command command; + + private List defaultHelpMessages = new ArrayList<>(); + + public VelocityCommand(String command, Consumer> initializer, String... aliases) { + super(command, initializer, aliases); + } + + public VelocityCommand(String command, String permission, Consumer> initializer, String... aliases) { + super(command, permission, initializer, aliases); + } + + private abstract static class TabCompletableCommand extends Command implements TabExecutor { + public TabCompletableCommand(String name, String permission, String... aliases) { + super(name, permission, aliases); + } + } + + @Override + protected synchronized void initCommand() { + if (command != null) return; + command = new TabCompletableCommand(VelocityCommand.super.command, permission, aliases) { + @Override + public void execute(CommandSender commandSender, String[] strings) { + VelocityCommand.this.execute(commandSender, null, strings); + } + + @Override + public Iterable onTabComplete(CommandSender commandSender, String[] strings) { + return VelocityCommand.this.tabComplete(commandSender, null, strings); + } + }; + } + + @Override + public void unregister() { + VelocityCommandRegistering.unregister(command); + } + + @Override + public void register() { + VelocityCommandRegistering.register(command); + } + + @Override + protected void commandSystemError(CommandSender sender, CommandFrameworkException e) { + ProxyServer.getInstance().getLogger().log(Level.SEVERE, e.getMessage(), e); + // TODO: ChatSender.of(sender).prefixless("COMMAND_SYSTEM_ERROR"); + } + + public void addDefaultHelpMessage(String message) { + defaultHelpMessages.add(message); + } + + @Override + protected void sendMessage(CommandSender sender, String message, Object[] args) { + // TODO: ChatSender.of(sender).system(message, args); + sender.sendMessage(MessageFormat.format(message, args)); + } + + /* TODO + @Register(noTabComplete = true) + public void internalHelp(ProxiedPlayer p, String... args) { + ChatSender chatSender = ChatSender.of(p); + try { + chatSender.prefixless("COMMAND_HELP_HEAD", command.getName()); + defaultHelpMessages.forEach(chatSender::prefixless); + } catch (Exception e) { + BungeeCore.get().getLogger().log(Level.WARNING, "Failed to send help message", e); + return; + } + AtomicInteger atomicInteger = new AtomicInteger(); + if (args.length != 0) { + commandList.forEach(subCommand -> { + List 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(chatSender, subCommand); + } else { + atomicInteger.incrementAndGet(); + } + }); + } + if (args.length == 0 || atomicInteger.get() == commandList.size()) { + commandList.forEach(subCommand -> { + if (subCommand.validator == null || subCommand.validator.validate(p, p, (s, args1) -> {})) { + send(chatSender, subCommand); + } + }); + } + } + + private void send(ChatSender chatSender, 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); + chatSender.prefixless(s, new Message("PLAIN_STRING", hover), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, suggest)); + } + } catch (Exception e) { + BungeeCore.get().getLogger().log(Level.WARNING, "Failed to send description of registered method '" + subCommand.method + "' with description '" + subCommand.description + "'", e); + } + } + */ +} diff --git a/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommandFrameworkPlugin.java b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommandFrameworkPlugin.java new file mode 100644 index 00000000..e3741ab6 --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommandFrameworkPlugin.java @@ -0,0 +1,29 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import com.velocitypowered.api.plugin.Plugin; + +@Plugin( + id = "commandframework", + name = "CommandFramework" +) +public class VelocityCommandFrameworkPlugin { +} diff --git a/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommandRegistering.java b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommandRegistering.java new file mode 100644 index 00000000..0fba8190 --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityCommandRegistering.java @@ -0,0 +1,39 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import lombok.experimental.UtilityClass; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.plugin.Command; +import net.md_5.bungee.api.plugin.Plugin; + +@UtilityClass +class VelocityCommandRegistering { + + private static final Plugin plugin = ProxyServer.getInstance().getPluginManager().getPlugins().iterator().next(); + + static void unregister(Command command) { + ProxyServer.getInstance().getPluginManager().unregisterCommand(command); + } + + static void register(Command command) { + ProxyServer.getInstance().getPluginManager().registerCommand(plugin, command); + } +} \ No newline at end of file diff --git a/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeMapper.java b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeMapper.java new file mode 100644 index 00000000..830da003 --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeMapper.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import net.md_5.bungee.api.CommandSender; + +public interface VelocityTypeMapper extends AbstractTypeMapper { +} diff --git a/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeSupplier.java b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeSupplier.java new file mode 100644 index 00000000..69b1e733 --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeSupplier.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import net.md_5.bungee.api.CommandSender; + +public interface VelocityTypeSupplier extends AbstractTypeSupplier { +} diff --git a/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeValidator.java b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeValidator.java new file mode 100644 index 00000000..a0b82800 --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/VelocityTypeValidator.java @@ -0,0 +1,25 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command; + +import net.md_5.bungee.api.CommandSender; + +public interface VelocityTypeValidator extends AbstractTypeValidator { +} diff --git a/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/mapper/ProxiedPlayerMapper.java b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/mapper/ProxiedPlayerMapper.java new file mode 100644 index 00000000..99afe8b3 --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/de/steamwar/command/mapper/ProxiedPlayerMapper.java @@ -0,0 +1,44 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.command.mapper; + +import de.steamwar.command.VelocityTypeMapper; +import de.steamwar.command.PreviousArguments; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +import java.util.Collection; +import java.util.stream.Collectors; + +public class ProxiedPlayerMapper implements VelocityTypeMapper { + + @Override + public ProxiedPlayer map(CommandSender sender, PreviousArguments previousArguments, String s) { + return ProxyServer.getInstance().getPlayer(s); + } + + @Override + public Collection tabComplete(CommandSender sender, PreviousArguments previousArguments, String s) { + return ProxyServer.getInstance().getPlayers().stream() + .map(ProxiedPlayer::getName) + .collect(Collectors.toList()); + } +} diff --git a/CommandFramework/CommandFrameworkVelocity/src/plugin.yml b/CommandFramework/CommandFrameworkVelocity/src/plugin.yml new file mode 100644 index 00000000..1780d83b --- /dev/null +++ b/CommandFramework/CommandFrameworkVelocity/src/plugin.yml @@ -0,0 +1,4 @@ +name: CommandFramework +main: de.steamwar.command.BungeeCommandFrameworkPlugin +version: 1.0 +author: YoyoNow diff --git a/settings.gradle.kts b/settings.gradle.kts index fc08ed92..edcca187 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -187,7 +187,13 @@ include( "BauSystem:BauSystem_RegionFixed" ) -include("CommandFramework") +include( + "CommandFramework", + "CommandFramework:CommandFrameworkBase", + "CommandFramework:CommandFrameworkSpigot", + "CommandFramework:CommandFrameworkTests", + "CommandFramework:CommandFrameworkVelocity", +) include( "CommonCore",