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.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"))
|
||||
|
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