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(); + } + } +}