WIP Lixfels command framework
Dieser Commit ist enthalten in:
Ursprung
7056089b3b
Commit
4d07fdf419
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
* /
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.command;
|
|
||||||
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
|
|
||||||
public interface Argument<T> {
|
|
||||||
|
|
||||||
T parse(String arg) throws InvalidArgumentException;
|
|
||||||
void checkConstraints(CommandSender sender, T argument) throws InvalidArgumentException;
|
|
||||||
|
|
||||||
List<String> tabComplete(CommandSender sender, String arg) throws InvalidArgumentException;
|
|
||||||
default BiPredicate<String, String> tabCompleteFilter() {
|
|
||||||
return String::startsWith;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class IntArgument implements Argument<Integer> {
|
|
||||||
@Override
|
|
||||||
public Integer parse(String arg) {
|
|
||||||
return Integer.parseInt(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class DoubleArgument implements Argument<Double> {
|
|
||||||
@Override
|
|
||||||
public Double parse(String arg) {
|
|
||||||
return Double.parseDouble(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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 <https://www.gnu.org/licenses/>.
|
|
||||||
* /
|
|
||||||
*/
|
|
||||||
|
|
||||||
package de.steamwar.command;
|
|
||||||
|
|
||||||
public class InvalidArgumentException extends Exception {
|
|
||||||
|
|
||||||
}
|
|
4
SpigotCore_Main/src/de/steamwar/SpigotCore.properties
Normale Datei
4
SpigotCore_Main/src/de/steamwar/SpigotCore.properties
Normale Datei
@ -0,0 +1,4 @@
|
|||||||
|
PREFIX=§eSteam§8War»
|
||||||
|
|
||||||
|
UNKNOWN_PLAYER=§cUnbekannter Spieler: {0}
|
||||||
|
UNKNOWN_SCHEMATIC=§cUnbekannte Schematic: {0}
|
@ -24,6 +24,7 @@ import de.steamwar.core.events.ChattingEvent;
|
|||||||
import de.steamwar.core.events.ChunkListener;
|
import de.steamwar.core.events.ChunkListener;
|
||||||
import de.steamwar.core.events.PlayerJoinedEvent;
|
import de.steamwar.core.events.PlayerJoinedEvent;
|
||||||
import de.steamwar.core.events.WorldLoadEvent;
|
import de.steamwar.core.events.WorldLoadEvent;
|
||||||
|
import de.steamwar.message.Message;
|
||||||
import de.steamwar.sql.SQL;
|
import de.steamwar.sql.SQL;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
@ -33,6 +34,8 @@ public class Core extends JavaPlugin{
|
|||||||
private static Core instance;
|
private static Core instance;
|
||||||
private static final int version;
|
private static final int version;
|
||||||
|
|
||||||
|
public static final Message MESSAGE = new Message("de.steamwar.SpigotCore", Core.class.getClassLoader());
|
||||||
|
|
||||||
static{
|
static{
|
||||||
String packageName = Bukkit.getServer().getClass().getPackage().getName();
|
String packageName = Bukkit.getServer().getClass().getPackage().getName();
|
||||||
if(packageName.contains("1_15"))
|
if(packageName.contains("1_15"))
|
||||||
|
92
SpigotCore_Main/src/de/steamwar/core/SWArgument.java
Normale Datei
92
SpigotCore_Main/src/de/steamwar/core/SWArgument.java
Normale Datei
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<T> {
|
||||||
|
public static final SWArgument<String> STRING = new SWArgument<>((sender, arg) -> arg);
|
||||||
|
public static final SWArgument<Player> 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<SteamwarUser> USER = new SWArgument<>((sender, arg) -> SteamwarUser.get(arg), Core.MESSAGE, "UNKNOWN_PLAYER", PLAYER.tabComplete);
|
||||||
|
public static final SWArgument<Schematic> SCHEMATIC = new SWArgument<>((sender, arg) -> Schematic.getSchemFromDB(arg, ((Player)sender).getUniqueId()), Core.MESSAGE, "UNKNOWN_SCHEMATIC");
|
||||||
|
|
||||||
|
private final BiFunction<CommandSender, String, T> parse;
|
||||||
|
private final BiFunction<CommandSender, String, List<String>> tabComplete;
|
||||||
|
|
||||||
|
private final Message message;
|
||||||
|
private final String errorMessage;
|
||||||
|
|
||||||
|
/*public SWArgument(Class<T extends Enum<T>> 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<CommandSender, String, T> parse){
|
||||||
|
this(parse, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SWArgument(BiFunction<CommandSender, String, T> parse, Message message, String errorMessage){
|
||||||
|
this(parse, message, errorMessage, (sender, arg) -> Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SWArgument(BiFunction<CommandSender, String, T> parse, BiFunction<CommandSender, String, List<String>> tabComplete){
|
||||||
|
this(parse, null, null, tabComplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SWArgument(BiFunction<CommandSender, String, T> parse, Message message, String errorMessage, BiFunction<CommandSender, String, List<String>> tabComplete){
|
||||||
|
this.parse = parse;
|
||||||
|
this.tabComplete = tabComplete;
|
||||||
|
this.message = message;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
145
SpigotCore_Main/src/de/steamwar/core/SWCommand.java
Normale Datei
145
SpigotCore_Main/src/de/steamwar/core/SWCommand.java
Normale Datei
@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<String, SWCommand> subcommands = new HashMap<>();
|
||||||
|
private final BiConsumer<CommandSender, Object[]> 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<CommandSender, Object[]> 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<String> 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<String> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren