From da4362b356b0034bfbf11dd26dc228b70f0d63fd Mon Sep 17 00:00:00 2001 From: jojo Date: Wed, 30 Dec 2020 12:44:06 +0100 Subject: [PATCH] Revert "Simplify CommandFramework" This reverts commit 3687b4b2 --- .../src/de/steamwar/command/Argument.java | 119 ++++++++++++-- .../src/de/steamwar/command/ArgumentType.java | 43 +++++ .../de/steamwar/command/ArgumentUtils.java | 155 ++++++++++++++++++ .../src/de/steamwar/command/Executor.java | 4 +- .../src/de/steamwar/command/SWCommand.java | 33 ++-- .../de/steamwar/command/SWCommandBundle.java | 9 +- .../src/de/steamwar/commandn/Argument.java | 53 ++++++ .../InvalidArgumentException.java | 2 +- 8 files changed, 373 insertions(+), 45 deletions(-) create mode 100644 SpigotCore_Main/src/de/steamwar/command/ArgumentType.java create mode 100644 SpigotCore_Main/src/de/steamwar/command/ArgumentUtils.java create mode 100644 SpigotCore_Main/src/de/steamwar/commandn/Argument.java rename SpigotCore_Main/src/de/steamwar/{command => commandn}/InvalidArgumentException.java (96%) diff --git a/SpigotCore_Main/src/de/steamwar/command/Argument.java b/SpigotCore_Main/src/de/steamwar/command/Argument.java index 9ed1b57..0a6b106 100644 --- a/SpigotCore_Main/src/de/steamwar/command/Argument.java +++ b/SpigotCore_Main/src/de/steamwar/command/Argument.java @@ -21,34 +21,117 @@ package de.steamwar.command; -import org.bukkit.command.CommandSender; +import org.bukkit.*; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; -import java.util.List; -import java.util.function.BiPredicate; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; -public interface Argument { +public class Argument { - T parse(CommandSender sender, String arg) throws InvalidArgumentException; - default void checkConstraints(CommandSender sender, T argument) throws InvalidArgumentException { + public static final Argument BOOLEAN = new Argument<>(ArgumentType.BOOLEAN, bool -> true, "true", "false"); + public static final Argument INT = new Argument<>(ArgumentType.INT, integer -> true); + public static final Argument LONG = new Argument<>(ArgumentType.LONG, l -> true); + public static final Argument FLOAT = new Argument<>(ArgumentType.FLOAT, f -> true); + public static final Argument DOUBLE = new Argument<>(ArgumentType.DOUBLE, d -> true); + public static final Argument STRING = new Argument<>(ArgumentType.STRING, string -> true); + + public static final Argument PLAYER = new Argument<>(ArgumentType.STRING, string -> Bukkit.getPlayer(string) == null, Bukkit::getPlayer, () -> Bukkit.getOnlinePlayers().stream().map(Player::getName).toArray(String[]::new)); + + public static final Argument GAMEMODE = new Argument<>(ArgumentType.STRING, + string -> string.equalsIgnoreCase("creative") || string.equalsIgnoreCase("c") || string.equalsIgnoreCase("1") || + string.equalsIgnoreCase("survival") || string.equalsIgnoreCase("s") || string.equalsIgnoreCase("0") || + string.equalsIgnoreCase("spectator") || string.equalsIgnoreCase("sp") || string.equalsIgnoreCase("3") || + string.equalsIgnoreCase("adventure") || string.equalsIgnoreCase("a") || string.equalsIgnoreCase("2"), + s -> { + if (s.equalsIgnoreCase("creative") || s.equalsIgnoreCase("c") || s.equalsIgnoreCase("1")) return GameMode.CREATIVE; + if (s.equalsIgnoreCase("spectator") || s.equalsIgnoreCase("sp") || s.equalsIgnoreCase("3")) return GameMode.SPECTATOR; + if (s.equalsIgnoreCase("adventure") || s.equalsIgnoreCase("a") || s.equalsIgnoreCase("2")) return GameMode.ADVENTURE; + return GameMode.SURVIVAL; + }, () -> new String[]{"creative", "survival", "adventure", "spectator"}); + + private static final String[] materialArray = Arrays.stream(Material.values()).map(Enum::name).toArray(String[]::new); + public static final Argument MATERIAL = new Argument<>(ArgumentType.STRING, string -> Material.valueOf(string) != null, Material::valueOf, () -> materialArray); + + private static final String[] particleArray = Arrays.stream(Particle.values()).map(Enum::name).toArray(String[]::new); + public static final Argument PARTICLE = new Argument<>(ArgumentType.STRING, string -> Particle.valueOf(string) != null, Particle::valueOf, () -> particleArray); + + private static final String[] entityArray = Arrays.stream(EntityType.values()).map(Enum::name).toArray(String[]::new); + public static final Argument ENTITY = new Argument<>(ArgumentType.STRING, string -> EntityType.valueOf(string) != null, EntityType::valueOf, () -> entityArray); + + private static final String[] soundArray = Arrays.stream(Sound.values()).map(Enum::name).toArray(String[]::new); + public static final Argument SOUND = new Argument<>(ArgumentType.STRING, string -> Sound.valueOf(string) != null, Sound::valueOf, () -> soundArray); + + private static final String[] soundCategoryArray = Arrays.stream(SoundCategory.values()).map(Enum::name).toArray(String[]::new); + public static final Argument SOUND_CATEGORY = new Argument<>(ArgumentType.STRING, string -> SoundCategory.valueOf(string) != null, SoundCategory::valueOf, () -> soundCategoryArray); + + private ArgumentType argumentType; + private Predicate constraint; + private Function tabCompletes; + private Function valueMapper; + + public Argument(ArgumentType argumentType, Predicate constraint, String... tabCompletes) { + this(argumentType, constraint, o -> o, () -> tabCompletes); } - List tabComplete(CommandSender sender, String arg); - default BiPredicate tabCompleteFilter() { - return String::startsWith; + public Argument(ArgumentType argumentType, Predicate constraint, Supplier tabCompletes) { + this(argumentType, constraint, o -> o, tabCompletes); } - abstract class IntArgument implements Argument { - @Override - public Integer parse(CommandSender sender, String arg) { - return Integer.parseInt(arg); + public Argument(ArgumentType argumentType, Predicate constraint, Function tabCompletes) { + this(argumentType, constraint, o -> o, tabCompletes); + } + + public Argument(ArgumentType argumentType, Predicate constraint, Function valueMapper, Supplier tabCompletes) { + this(argumentType, constraint, valueMapper, s -> tabCompletes.get()); + } + + public Argument(ArgumentType argumentType, Predicate constraint, Function valueMapper, Function tabCompletes) { + this.argumentType = argumentType; + this.constraint = constraint; + this.valueMapper = valueMapper; + this.tabCompletes = tabCompletes; + } + + public Optional valueSupplier(String s) { + try { + T argumentMapped = argumentType.mapper.apply(s); + if (constraint.test(argumentMapped)) { + return Optional.ofNullable(valueMapper.apply(argumentMapped)); + } + } catch (NumberFormatException e) { + return Optional.empty(); + } catch (Exception e) { + throw new SecurityException(e); + } + return Optional.empty(); + } + + public Optional> tabCompleteSupplier(String s) { + try { + if (!s.isEmpty()) { + // Check if mappable + T argumentMapped = argumentType.mapper.apply(s); + // Check number constraints if needed + if (argumentType.number && !constraint.test(argumentMapped)) return Optional.empty(); + } + return Optional.of(Arrays.stream(tabCompletes.apply(s)).filter(t -> t.startsWith(s)).collect(Collectors.toList())); + } catch (NumberFormatException e) { + return Optional.empty(); + } catch (Exception e) { + throw new SecurityException(e); } } - abstract class DoubleArgument implements Argument { - @Override - public Double parse(CommandSender sender, String arg) { - return Double.parseDouble(arg); - } + @Override + public String toString() { + return "Argument{" + + "tabCompletes=" + Arrays.toString(tabCompletes.apply("")) + + '}'; } } diff --git a/SpigotCore_Main/src/de/steamwar/command/ArgumentType.java b/SpigotCore_Main/src/de/steamwar/command/ArgumentType.java new file mode 100644 index 0000000..9927841 --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/command/ArgumentType.java @@ -0,0 +1,43 @@ +/* + * + * 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.function.Function; + +public class ArgumentType { + + public static final ArgumentType BOOLEAN = new ArgumentType<>(Boolean::parseBoolean, false); + public static final ArgumentType INT = new ArgumentType<>(Integer::parseInt, true); + public static final ArgumentType LONG = new ArgumentType<>(Long::parseLong, true); + public static final ArgumentType FLOAT = new ArgumentType<>(Float::parseFloat, true); + public static final ArgumentType DOUBLE = new ArgumentType<>(Double::parseDouble, true); + public static final ArgumentType STRING = new ArgumentType<>(s -> s, false); + + Function mapper; + boolean number; + + private ArgumentType(Function mapper, boolean number) { + this.mapper = mapper; + this.number = number; + } + +} diff --git a/SpigotCore_Main/src/de/steamwar/command/ArgumentUtils.java b/SpigotCore_Main/src/de/steamwar/command/ArgumentUtils.java new file mode 100644 index 0000000..7e325cc --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/command/ArgumentUtils.java @@ -0,0 +1,155 @@ +/* + * + * 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.Arrays; +import java.util.function.Predicate; + +public class ArgumentUtils { + + private ArgumentUtils() { + throw new IllegalStateException("Utility class"); + } + + public static Argument of(String argument) { + return new Argument<>(ArgumentType.STRING, string -> string.equals(argument), argument); + } + + public static Argument of(String... arguments) { + return new Argument<>(ArgumentType.STRING, string -> { + for (String arg : arguments) { + if (string.equals(arg)) return true; + } + return false; + }, arguments); + } + + public static Argument of(String[] commands, String[] tabCompletes) { + return new Argument<>(ArgumentType.STRING, string -> { + for (String arg : commands){ + if (string.equals(arg)) return true; + } + return false; + }, s -> { + if (s.isEmpty()) { + return tabCompletes; + } + return commands; + }); + } + + public static Argument ofIgnoreCase(String argument) { + return new Argument<>(ArgumentType.STRING, string -> string.equalsIgnoreCase(argument), argument); + } + + public static Argument ofIgnoreCase(String... arguments) { + return new Argument<>(ArgumentType.STRING, string -> { + for (String arg : arguments) { + if (string.equalsIgnoreCase(arg)) return true; + } + return false; + }, arguments); + } + + public static Argument ofIgnoreCase(String[] commands, String[] tabCompletes) { + return new Argument<>(ArgumentType.STRING, string -> { + for (String arg : commands){ + if (string.equalsIgnoreCase(arg)) return true; + } + return false; + }, s -> { + if (s.isEmpty()) { + return tabCompletes; + } + return commands; + }); + } + + public static Argument above(int minValue, int... tabValues) { + return between(minValue, Integer.MAX_VALUE, tabValues); + } + + public static Argument below(int maxValue, int... tabValues) { + return between(Integer.MIN_VALUE, maxValue, tabValues); + } + + public static Argument between(int minValue, int maxValue, int... tabValues) { + Predicate predicate = i -> i >= minValue && i <= maxValue; + for (int tabValue : tabValues) { + if (!predicate.test(tabValue)) throw new IllegalArgumentException(); + } + return new Argument<>(ArgumentType.INT, predicate, Arrays.stream(tabValues).mapToObj(i -> i + "").toArray(String[]::new)); + } + + public static Argument above(long minValue, long... tabValues) { + return between(minValue, Long.MAX_VALUE, tabValues); + } + + public static Argument below(long maxValue, long... tabValues) { + return between(Long.MIN_VALUE, maxValue, tabValues); + } + + public static Argument between(long minValue, long maxValue, long... tabValues) { + Predicate predicate = l -> l >= minValue && l <= maxValue; + for (long tabValue : tabValues) { + if (!predicate.test(tabValue)) throw new IllegalArgumentException(); + } + return new Argument<>(ArgumentType.LONG, predicate, Arrays.stream(tabValues).mapToObj(l -> l + "").toArray(String[]::new)); + } + + public static Argument above(float minValue, float... tabValues) { + return between(minValue, Float.MAX_VALUE, tabValues); + } + + public static Argument below(float maxValue, float... tabValues) { + return between(Float.MIN_VALUE, maxValue, tabValues); + } + + public static Argument between(float minValue, float maxValue, float... tabValues) { + Predicate predicate = f -> f >= minValue && f <= maxValue; + for (float tabValue : tabValues) { + if (!predicate.test(tabValue)) throw new IllegalArgumentException(); + } + String[] strings = new String[tabValues.length]; + for (int i = 0; i < tabValues.length; i++) { + strings[i] = tabValues[i] + ""; + } + return new Argument<>(ArgumentType.FLOAT, predicate, strings); + } + + public static Argument above(double minValue, double... tabValues) { + return between(minValue, Double.MAX_VALUE, tabValues); + } + + public static Argument below(double maxValue, double... tabValues) { + return between(Double.MIN_VALUE, maxValue, tabValues); + } + + public static Argument between(double minValue, double maxValue, double... tabValues) { + Predicate predicate = d -> d >= minValue && d <= maxValue; + for (double tabValue : tabValues) { + if (!predicate.test(tabValue)) throw new IllegalArgumentException(); + } + return new Argument<>(ArgumentType.DOUBLE, predicate, Arrays.stream(tabValues).mapToObj(d -> d + "").toArray(String[]::new)); + } + +} diff --git a/SpigotCore_Main/src/de/steamwar/command/Executor.java b/SpigotCore_Main/src/de/steamwar/command/Executor.java index f089b51..26d6bdc 100644 --- a/SpigotCore_Main/src/de/steamwar/command/Executor.java +++ b/SpigotCore_Main/src/de/steamwar/command/Executor.java @@ -21,9 +21,9 @@ package de.steamwar.command; -import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; @FunctionalInterface public interface Executor { - void execute(CommandSender sender, ArgumentMap argumentMap); + void execute(Player player, ArgumentMap argumentMap); } diff --git a/SpigotCore_Main/src/de/steamwar/command/SWCommand.java b/SpigotCore_Main/src/de/steamwar/command/SWCommand.java index e92e7dc..95d0d27 100644 --- a/SpigotCore_Main/src/de/steamwar/command/SWCommand.java +++ b/SpigotCore_Main/src/de/steamwar/command/SWCommand.java @@ -21,50 +21,45 @@ package de.steamwar.command; -import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; -import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class SWCommand { - private Executor executor; private Argument[] arguments; + private Executor executor; public SWCommand(Executor executor, Argument... arguments) { - this.executor = executor; this.arguments = arguments; + this.executor = executor; } - public boolean execute(CommandSender sender, String[] args) { + public boolean execute(Player player, String[] args) { if (args.length != arguments.length) { return false; } Object[] objects = new Object[args.length]; for (int i = 0; i < args.length; i++) { - try { - objects[i] = arguments[i].parse(sender, args[i]); - } catch (InvalidArgumentException e) { - return false; - } + Optional optional = arguments[i].valueSupplier(args[i]); + if (!optional.isPresent()) return false; + objects[i] = optional.get(); } - executor.execute(sender, new ArgumentMap(objects)); + executor.execute(player, new ArgumentMap(objects)); return true; } - public List tabComplete(CommandSender sender, String[] args) { + public Optional> tabComplete(String[] args) { if (args.length > arguments.length) { - return new ArrayList<>(); + return Optional.empty(); } for (int i = 0; i < args.length - 1; i++) { - try { - arguments[i].parse(sender, args[i]); - } catch (InvalidArgumentException e) { - return new ArrayList<>(); - } + Optional optional = arguments[i].valueSupplier(args[i]); + if (!optional.isPresent()) return Optional.empty(); } int index = args.length - 1; - return arguments[index].tabComplete(sender, args[index]); + return arguments[index].tabCompleteSupplier(args[index]); } } diff --git a/SpigotCore_Main/src/de/steamwar/command/SWCommandBundle.java b/SpigotCore_Main/src/de/steamwar/command/SWCommandBundle.java index 1f0f1e1..d3e2590 100644 --- a/SpigotCore_Main/src/de/steamwar/command/SWCommandBundle.java +++ b/SpigotCore_Main/src/de/steamwar/command/SWCommandBundle.java @@ -21,7 +21,6 @@ package de.steamwar.command; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import java.util.ArrayList; @@ -49,17 +48,17 @@ public class SWCommandBundle { return this; } - public boolean execute(CommandSender sender, String[] args) { + public boolean execute(Player player, String[] args) { for (SWCommand swCommand : swCommandList) { - if (swCommand.execute(sender, args)) return true; + if (swCommand.execute(player, args)) return true; } return false; } - public List tabComplete(CommandSender sender, String[] args) { + public List tabComplete(String[] args) { List strings = new ArrayList<>(); for (SWCommand swCommand : swCommandList) { - strings.addAll(swCommand.tabComplete(sender, args)); + swCommand.tabComplete(args).ifPresent(strings::addAll); } return strings; } diff --git a/SpigotCore_Main/src/de/steamwar/commandn/Argument.java b/SpigotCore_Main/src/de/steamwar/commandn/Argument.java new file mode 100644 index 0000000..92eb7d4 --- /dev/null +++ b/SpigotCore_Main/src/de/steamwar/commandn/Argument.java @@ -0,0 +1,53 @@ +/* + * + * 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.commandn; + +import org.bukkit.command.CommandSender; + +import java.util.List; +import java.util.function.BiPredicate; + +public interface Argument { + + T parse(String arg) throws InvalidArgumentException; + void checkConstraints(CommandSender sender, T argument) throws InvalidArgumentException; + + List tabComplete(CommandSender sender, String arg) throws InvalidArgumentException; + default BiPredicate tabCompleteFilter() { + return String::startsWith; + } + + abstract class IntArgument implements Argument { + @Override + public Integer parse(String arg) { + return Integer.parseInt(arg); + } + } + + abstract class DoubleArgument implements Argument { + @Override + public Double parse(String arg) { + return Double.parseDouble(arg); + } + } + +} diff --git a/SpigotCore_Main/src/de/steamwar/command/InvalidArgumentException.java b/SpigotCore_Main/src/de/steamwar/commandn/InvalidArgumentException.java similarity index 96% rename from SpigotCore_Main/src/de/steamwar/command/InvalidArgumentException.java rename to SpigotCore_Main/src/de/steamwar/commandn/InvalidArgumentException.java index 8184b24..4c0fd78 100644 --- a/SpigotCore_Main/src/de/steamwar/command/InvalidArgumentException.java +++ b/SpigotCore_Main/src/de/steamwar/commandn/InvalidArgumentException.java @@ -19,7 +19,7 @@ * / */ -package de.steamwar.command; +package de.steamwar.commandn; public class InvalidArgumentException extends Exception {