diff --git a/SpigotCore_14/src/de/steamwar/command/Argument.java b/SpigotCore_14/src/de/steamwar/command/Argument.java
deleted file mode 100644
index f94200a..0000000
--- a/SpigotCore_14/src/de/steamwar/command/Argument.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *
- * 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 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_14/src/de/steamwar/command/InvalidArgumentException.java b/SpigotCore_14/src/de/steamwar/command/InvalidArgumentException.java
deleted file mode 100644
index 8184b24..0000000
--- a/SpigotCore_14/src/de/steamwar/command/InvalidArgumentException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *
- * 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;
-
-public class InvalidArgumentException extends Exception {
-
-}
diff --git a/SpigotCore_Main/src/de/steamwar/SpigotCore.properties b/SpigotCore_Main/src/de/steamwar/SpigotCore.properties
new file mode 100644
index 0000000..acfc93f
--- /dev/null
+++ b/SpigotCore_Main/src/de/steamwar/SpigotCore.properties
@@ -0,0 +1,4 @@
+PREFIX=§eSteam§8War»
+
+UNKNOWN_PLAYER=§cUnbekannter Spieler: {0}
+UNKNOWN_SCHEMATIC=§cUnbekannte Schematic: {0}
\ No newline at end of file
diff --git a/SpigotCore_Main/src/de/steamwar/core/Core.java b/SpigotCore_Main/src/de/steamwar/core/Core.java
index d9c59df..d7ab6ee 100644
--- a/SpigotCore_Main/src/de/steamwar/core/Core.java
+++ b/SpigotCore_Main/src/de/steamwar/core/Core.java
@@ -24,6 +24,7 @@ import de.steamwar.core.events.ChattingEvent;
import de.steamwar.core.events.ChunkListener;
import de.steamwar.core.events.PlayerJoinedEvent;
import de.steamwar.core.events.WorldLoadEvent;
+import de.steamwar.message.Message;
import de.steamwar.sql.SQL;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
@@ -33,6 +34,8 @@ public class Core extends JavaPlugin{
private static Core instance;
private static final int version;
+ public static final Message MESSAGE = new Message("de.steamwar.SpigotCore", Core.class.getClassLoader());
+
static{
String packageName = Bukkit.getServer().getClass().getPackage().getName();
if(packageName.contains("1_15"))
diff --git a/SpigotCore_Main/src/de/steamwar/core/SWArgument.java b/SpigotCore_Main/src/de/steamwar/core/SWArgument.java
new file mode 100644
index 0000000..1a45cfc
--- /dev/null
+++ b/SpigotCore_Main/src/de/steamwar/core/SWArgument.java
@@ -0,0 +1,92 @@
+/*
+ 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.core;
+
+import de.steamwar.message.Message;
+import de.steamwar.sql.Schematic;
+import de.steamwar.sql.SteamwarUser;
+import org.bukkit.Bukkit;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.HumanEntity;
+import org.bukkit.entity.Player;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+
+public class SWArgument {
+ public static final SWArgument STRING = new SWArgument<>((sender, arg) -> arg);
+ public static final SWArgument PLAYER = new SWArgument<>(
+ (sender, arg) -> Bukkit.getPlayer(arg),
+ Core.MESSAGE, "UNKNOWN_PLAYER",
+ (sender, arg) -> Bukkit.getOnlinePlayers().stream().map(HumanEntity::getName).filter(name -> name.startsWith(arg)).collect(Collectors.toList()));
+ public static final SWArgument USER = new SWArgument<>((sender, arg) -> SteamwarUser.get(arg), Core.MESSAGE, "UNKNOWN_PLAYER", PLAYER.tabComplete);
+ public static final SWArgument SCHEMATIC = new SWArgument<>((sender, arg) -> Schematic.getSchemFromDB(arg, ((Player)sender).getUniqueId()), Core.MESSAGE, "UNKNOWN_SCHEMATIC");
+
+ private final BiFunction parse;
+ private final BiFunction> tabComplete;
+
+ private final Message message;
+ private final String errorMessage;
+
+ /*public SWArgument(Class> swEnum) {
+ this((sender, arg) -> Enum.valueOf(swEnum, arg.toLowerCase()),
+ (sender, arg) -> Arrays.stream(swEnum.getEnumConstants()).map(Enum::name).filter(name -> name.startsWith(arg)).collect(Collectors.toList()));
+ }
+ TODO: Iterable
+ */
+
+ public SWArgument(BiFunction parse){
+ this(parse, null, null);
+ }
+
+ public SWArgument(BiFunction parse, Message message, String errorMessage){
+ this(parse, message, errorMessage, (sender, arg) -> Collections.emptyList());
+ }
+
+ public SWArgument(BiFunction parse, BiFunction> tabComplete){
+ this(parse, null, null, tabComplete);
+ }
+
+ public SWArgument(BiFunction parse, Message message, String errorMessage, BiFunction> tabComplete){
+ this.parse = parse;
+ this.tabComplete = tabComplete;
+ this.message = message;
+ this.errorMessage = errorMessage;
+ }
+
+ public List tabComplete(CommandSender sender, String arg){
+ return tabComplete.apply(sender, arg);
+ }
+
+ public T parse(CommandSender sender, String arg){
+ try{
+ T t = parse.apply(sender, arg);
+ if(t == null)
+ throw new IllegalArgumentException();
+ return t;
+ }catch(IllegalArgumentException e){
+ if(message != null)
+ message.send(errorMessage, sender, arg);
+ throw e;
+ }
+ }
+}
diff --git a/SpigotCore_Main/src/de/steamwar/core/SWCommand.java b/SpigotCore_Main/src/de/steamwar/core/SWCommand.java
new file mode 100644
index 0000000..acb7fc5
--- /dev/null
+++ b/SpigotCore_Main/src/de/steamwar/core/SWCommand.java
@@ -0,0 +1,145 @@
+/*
+ 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.core;
+
+import de.steamwar.message.Message;
+import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandMap;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.function.BiConsumer;
+
+public class SWCommand{
+
+ private static final CommandMap commandMap;
+
+ 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 not register.", exception);
+ }
+ }
+
+ private final HashMap subcommands = new HashMap<>();
+ private final BiConsumer command;
+
+ private final SWArgument>[] arguments;
+ protected boolean[] optional;
+
+ protected final Message message;
+ private final String usage;
+
+ protected boolean onlyPlayer = true;
+ protected boolean lastArgRepeatable = false;
+
+ protected SWCommand(BiConsumer command, Message message, String usage, SWArgument>... arguments){
+ this.command = command;
+ this.usage = usage;
+ this.arguments = arguments;
+ this.message = message;
+ this.optional = new boolean[arguments.length];
+ }
+
+ protected void register(String name, String... aliases){
+ commandMap.register("steamwar", new Command(name, "", "/" + name, Arrays.asList(aliases)) {
+ @Override
+ public boolean execute(CommandSender sender, String alias, String[] args) {
+ SWCommand.this.execute(sender, args);
+ return false;
+ }
+
+ @Override
+ public List tabComplete(CommandSender sender, String alias, String[] args) {
+ return SWCommand.this.tabComplete(sender, args);
+ }
+ });
+ }
+
+ protected void registerSubcommand(SWCommand command, String... name){
+ for(String alias : name)
+ subcommands.put(alias, command);
+ }
+
+ private void execute(CommandSender sender, String[] args){
+ if(onlyPlayer && !(sender instanceof Player))
+ return;
+
+ String firstArg = args[0].toLowerCase();
+ if(subcommands.containsKey(firstArg)){
+ subcommands.get(firstArg).execute(sender, Arrays.copyOfRange(args, 1, args.length));
+ return;
+ }
+
+ Object[] parsedArgs = new Object[arguments.length];
+ try{
+ for(int i = 0; i < (lastArgRepeatable ? arguments.length - 1 : arguments.length); i++){
+ parsedArgs[i] = parseArg(i, sender, args);
+ }
+
+ if(lastArgRepeatable){
+ Object[] lastArg = new Object[args.length - arguments.length + 1];
+ for(int i = arguments.length - 1; i < args.length; i++){
+ lastArg[i] = parseArg(i, sender, args);
+ }
+ parsedArgs[arguments.length - 1] = lastArg;
+ }
+ }catch(IllegalArgumentException e){
+ return;
+ }
+
+ command.accept(sender, parsedArgs);
+ }
+
+ private List tabComplete(CommandSender sender, String[] args){
+ String firstArg = args[0].toLowerCase();
+ if(subcommands.containsKey(firstArg))
+ return subcommands.get(firstArg).tabComplete(sender, Arrays.copyOfRange(args, 1, args.length));
+
+ if(args.length > arguments.length){
+ if(lastArgRepeatable)
+ return arguments[arguments.length - 1].tabComplete(sender, args[args.length - 1]);
+ else
+ return Collections.emptyList();
+ }
+ return arguments[args.length - 1].tabComplete(sender, args[args.length - 1]);
+ }
+
+ private Object parseArg(int i, CommandSender sender, String[] args){
+ if(i < args.length)
+ return arguments[i].parse(sender, args[i]);
+ else if(optional[i])
+ return null;
+ else{
+ Core.MESSAGE.send(usage, sender);
+ throw new IllegalArgumentException();
+ }
+ }
+}