first commit
Build AsminVoicechat / prepare-release (push) Successful in 14s
Build AsminVoicechat / build-and-test (17) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (18) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (19) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (20) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (21) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (22) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (23) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (24) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (25) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (26) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (27-ea) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (16) (push) Canceled after 38s
Build AsminVoicechat / prepare-release (push) Successful in 14s
Build AsminVoicechat / build-and-test (17) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (18) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (19) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (20) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (21) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (22) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (23) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (24) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (25) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (26) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (27-ea) (push) Canceled after 0s
Build AsminVoicechat / build-and-test (16) (push) Canceled after 38s
This commit is contained in:
commit
bbccd4a815
454 files changed
+45050
No files matched your search
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.mojang.brigadier.Command
|
||||
* com.mojang.brigadier.suggestion.SuggestionProvider
|
||||
* com.mojang.brigadier.tree.ArgumentCommandNode
|
||||
* com.mojang.brigadier.tree.CommandNode
|
||||
* com.mojang.brigadier.tree.LiteralCommandNode
|
||||
* com.mojang.brigadier.tree.RootCommandNode
|
||||
* org.bukkit.command.Command
|
||||
* org.bukkit.command.PluginCommand
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.tree.ArgumentCommandNode;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import com.mojang.brigadier.tree.RootCommandNode;
|
||||
import de.maxhenkel.voicechat.commodore.Commodore;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
|
||||
abstract class AbstractCommodore
|
||||
implements Commodore {
|
||||
protected static final Field CUSTOM_SUGGESTIONS_FIELD;
|
||||
protected static final Field COMMAND_EXECUTE_FUNCTION_FIELD;
|
||||
protected static final Field CHILDREN_FIELD;
|
||||
protected static final Field LITERALS_FIELD;
|
||||
protected static final Field ARGUMENTS_FIELD;
|
||||
protected static final Field[] CHILDREN_FIELDS;
|
||||
protected static final Command<?> DUMMY_COMMAND;
|
||||
protected static final SuggestionProvider<?> DUMMY_SUGGESTION_PROVIDER;
|
||||
|
||||
AbstractCommodore() {
|
||||
}
|
||||
|
||||
protected static void removeChild(RootCommandNode root, String name) {
|
||||
try {
|
||||
for (Field field : CHILDREN_FIELDS) {
|
||||
Map children = (Map)field.get(root);
|
||||
children.remove(name);
|
||||
}
|
||||
}
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected static void setRequiredHackyFieldsRecursively(CommandNode<?> node, SuggestionProvider<?> suggestionProvider) {
|
||||
try {
|
||||
COMMAND_EXECUTE_FUNCTION_FIELD.set(node, DUMMY_COMMAND);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (suggestionProvider != null && node instanceof ArgumentCommandNode) {
|
||||
ArgumentCommandNode argumentNode = (ArgumentCommandNode)node;
|
||||
try {
|
||||
CUSTOM_SUGGESTIONS_FIELD.set(argumentNode, suggestionProvider);
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (CommandNode child : node.getChildren()) {
|
||||
AbstractCommodore.setRequiredHackyFieldsRecursively(child, suggestionProvider);
|
||||
}
|
||||
}
|
||||
|
||||
protected static <S> LiteralCommandNode<S> renameLiteralNode(LiteralCommandNode<S> node, String newLiteral) {
|
||||
LiteralCommandNode clone = new LiteralCommandNode(newLiteral, node.getCommand(), node.getRequirement(), node.getRedirect(), node.getRedirectModifier(), node.isFork());
|
||||
for (CommandNode child : node.getChildren()) {
|
||||
clone.addChild(child);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
protected static Collection<String> getAliases(org.bukkit.command.Command command) {
|
||||
Objects.requireNonNull(command, "command");
|
||||
Stream<String> aliasesStream = Stream.concat(Stream.of(command.getLabel()), command.getAliases().stream());
|
||||
if (command instanceof PluginCommand) {
|
||||
String fallbackPrefix = ((PluginCommand)command).getPlugin().getName().toLowerCase().trim();
|
||||
aliasesStream = aliasesStream.flatMap(alias -> Stream.of(alias, fallbackPrefix + ":" + alias));
|
||||
}
|
||||
return aliasesStream.distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
CUSTOM_SUGGESTIONS_FIELD = ArgumentCommandNode.class.getDeclaredField("customSuggestions");
|
||||
CUSTOM_SUGGESTIONS_FIELD.setAccessible(true);
|
||||
COMMAND_EXECUTE_FUNCTION_FIELD = CommandNode.class.getDeclaredField("command");
|
||||
COMMAND_EXECUTE_FUNCTION_FIELD.setAccessible(true);
|
||||
CHILDREN_FIELD = CommandNode.class.getDeclaredField("children");
|
||||
LITERALS_FIELD = CommandNode.class.getDeclaredField("literals");
|
||||
ARGUMENTS_FIELD = CommandNode.class.getDeclaredField("arguments");
|
||||
for (Field field : CHILDREN_FIELDS = new Field[]{CHILDREN_FIELD, LITERALS_FIELD, ARGUMENTS_FIELD}) {
|
||||
field.setAccessible(true);
|
||||
}
|
||||
DUMMY_COMMAND = ctx -> {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
DUMMY_SUGGESTION_PROVIDER = (context, builder) -> {
|
||||
throw new UnsupportedOperationException();
|
||||
};
|
||||
}
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore;
|
||||
|
||||
public final class BrigadierUnsupportedException
|
||||
extends UnsupportedOperationException {
|
||||
BrigadierUnsupportedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.mojang.brigadier.builder.LiteralArgumentBuilder
|
||||
* com.mojang.brigadier.tree.LiteralCommandNode
|
||||
* org.bukkit.command.Command
|
||||
* org.bukkit.entity.Player
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface Commodore {
|
||||
public void register(Command var1, LiteralCommandNode<?> var2, Predicate<? super Player> var3);
|
||||
|
||||
default public void register(Command command, LiteralArgumentBuilder<?> argumentBuilder, Predicate<? super Player> permissionTest) {
|
||||
Objects.requireNonNull(command, "command");
|
||||
Objects.requireNonNull(argumentBuilder, "argumentBuilder");
|
||||
Objects.requireNonNull(permissionTest, "permissionTest");
|
||||
this.register(command, argumentBuilder.build(), permissionTest);
|
||||
}
|
||||
|
||||
default public void register(Command command, LiteralCommandNode<?> node) {
|
||||
Objects.requireNonNull(command, "command");
|
||||
Objects.requireNonNull(node, "node");
|
||||
this.register(command, node, arg_0 -> ((Command)command).testPermissionSilent(arg_0));
|
||||
}
|
||||
|
||||
default public void register(Command command, LiteralArgumentBuilder<?> argumentBuilder) {
|
||||
Objects.requireNonNull(command, "command");
|
||||
Objects.requireNonNull(argumentBuilder, "argumentBuilder");
|
||||
this.register(command, argumentBuilder.build());
|
||||
}
|
||||
|
||||
public void register(LiteralCommandNode<?> var1);
|
||||
|
||||
default public void register(LiteralArgumentBuilder<?> argumentBuilder) {
|
||||
Objects.requireNonNull(argumentBuilder, "argumentBuilder");
|
||||
this.register(argumentBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* org.bukkit.plugin.Plugin
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore;
|
||||
|
||||
import de.maxhenkel.voicechat.commodore.BrigadierUnsupportedException;
|
||||
import de.maxhenkel.voicechat.commodore.Commodore;
|
||||
import de.maxhenkel.voicechat.commodore.PaperCommodore;
|
||||
import de.maxhenkel.voicechat.commodore.ReflectionCommodore;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public final class CommodoreProvider {
|
||||
private static final Function<Plugin, Commodore> PROVIDER = CommodoreProvider.checkSupported();
|
||||
|
||||
private CommodoreProvider() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private static Function<Plugin, Commodore> checkSupported() {
|
||||
try {
|
||||
Class.forName("com.mojang.brigadier.CommandDispatcher");
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommodoreProvider.printDebugInfo(e);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
PaperCommodore.ensureSetup();
|
||||
return PaperCommodore::new;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
CommodoreProvider.printDebugInfo(e);
|
||||
try {
|
||||
ReflectionCommodore.ensureSetup();
|
||||
return ReflectionCommodore::new;
|
||||
}
|
||||
catch (Throwable e2) {
|
||||
CommodoreProvider.printDebugInfo(e2);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void printDebugInfo(Throwable e) {
|
||||
if (System.getProperty("commodore.debug") != null) {
|
||||
System.err.println("Exception while initialising commodore:");
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isSupported() {
|
||||
return PROVIDER != null;
|
||||
}
|
||||
|
||||
public static Commodore getCommodore(Plugin plugin) throws BrigadierUnsupportedException {
|
||||
Objects.requireNonNull(plugin, "plugin");
|
||||
if (PROVIDER == null) {
|
||||
throw new BrigadierUnsupportedException("Brigadier is not supported by the server. Set -Dcommodore.debug=true for debug info.");
|
||||
}
|
||||
return PROVIDER.apply(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent
|
||||
* com.mojang.brigadier.builder.LiteralArgumentBuilder
|
||||
* com.mojang.brigadier.tree.LiteralCommandNode
|
||||
* com.mojang.brigadier.tree.RootCommandNode
|
||||
* org.bukkit.command.Command
|
||||
* org.bukkit.entity.Player
|
||||
* org.bukkit.event.EventHandler
|
||||
* org.bukkit.event.Listener
|
||||
* org.bukkit.plugin.Plugin
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore;
|
||||
|
||||
import com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import com.mojang.brigadier.tree.RootCommandNode;
|
||||
import de.maxhenkel.voicechat.commodore.AbstractCommodore;
|
||||
import de.maxhenkel.voicechat.commodore.Commodore;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
final class PaperCommodore
|
||||
extends AbstractCommodore
|
||||
implements Commodore,
|
||||
Listener {
|
||||
private final List<CommodoreCommand> commands = new ArrayList<CommodoreCommand>();
|
||||
|
||||
PaperCommodore(Plugin plugin) {
|
||||
plugin.getServer().getPluginManager().registerEvents((Listener)this, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(LiteralCommandNode<?> node) {
|
||||
Objects.requireNonNull(node, "node");
|
||||
this.commands.add(new CommodoreCommand(node, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Command command, LiteralCommandNode<?> node, Predicate<? super Player> permissionTest) {
|
||||
Objects.requireNonNull(command, "command");
|
||||
Objects.requireNonNull(node, "node");
|
||||
Objects.requireNonNull(permissionTest, "permissionTest");
|
||||
try {
|
||||
PaperCommodore.setRequiredHackyFieldsRecursively(node, DUMMY_SUGGESTION_PROVIDER);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Collection<String> aliases = PaperCommodore.getAliases(command);
|
||||
if (!aliases.contains(node.getLiteral())) {
|
||||
node = PaperCommodore.renameLiteralNode(node, command.getName());
|
||||
}
|
||||
for (String alias : aliases) {
|
||||
if (node.getLiteral().equals(alias)) {
|
||||
this.commands.add(new CommodoreCommand(node, permissionTest));
|
||||
continue;
|
||||
}
|
||||
LiteralCommandNode redirectNode = ((LiteralArgumentBuilder)LiteralArgumentBuilder.literal((String)alias).redirect(node)).build();
|
||||
this.commands.add(new CommodoreCommand(redirectNode, permissionTest));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerSendCommandsEvent(AsyncPlayerSendCommandsEvent<?> event) {
|
||||
if (event.isAsynchronous() || !event.hasFiredAsync()) {
|
||||
for (CommodoreCommand command : this.commands) {
|
||||
command.apply(event.getPlayer(), event.getCommandNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ensureSetup() {
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent");
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new UnsupportedOperationException("Not running on modern Paper!", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CommodoreCommand {
|
||||
private final LiteralCommandNode<?> node;
|
||||
private final Predicate<? super Player> permissionTest;
|
||||
|
||||
private CommodoreCommand(LiteralCommandNode<?> node, Predicate<? super Player> permissionTest) {
|
||||
this.node = node;
|
||||
this.permissionTest = permissionTest;
|
||||
}
|
||||
|
||||
public void apply(Player player, RootCommandNode<?> root) {
|
||||
if (this.permissionTest != null && !this.permissionTest.test((Player)player)) {
|
||||
return;
|
||||
}
|
||||
AbstractCommodore.removeChild(root, this.node.getName());
|
||||
root.addChild(this.node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.mojang.brigadier.CommandDispatcher
|
||||
* com.mojang.brigadier.builder.LiteralArgumentBuilder
|
||||
* com.mojang.brigadier.suggestion.SuggestionProvider
|
||||
* com.mojang.brigadier.tree.CommandNode
|
||||
* com.mojang.brigadier.tree.LiteralCommandNode
|
||||
* com.mojang.brigadier.tree.RootCommandNode
|
||||
* org.bukkit.Bukkit
|
||||
* org.bukkit.command.Command
|
||||
* org.bukkit.entity.Player
|
||||
* org.bukkit.event.EventHandler
|
||||
* org.bukkit.event.Listener
|
||||
* org.bukkit.event.player.PlayerCommandSendEvent
|
||||
* org.bukkit.event.server.ServerLoadEvent
|
||||
* org.bukkit.plugin.Plugin
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.suggestion.SuggestionProvider;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import com.mojang.brigadier.tree.RootCommandNode;
|
||||
import de.maxhenkel.voicechat.commodore.AbstractCommodore;
|
||||
import de.maxhenkel.voicechat.commodore.Commodore;
|
||||
import de.maxhenkel.voicechat.commodore.ReflectionUtil;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandSendEvent;
|
||||
import org.bukkit.event.server.ServerLoadEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
final class ReflectionCommodore
|
||||
extends AbstractCommodore
|
||||
implements Commodore {
|
||||
private static final Field CONSOLE_FIELD;
|
||||
private static final Method GET_COMMAND_DISPATCHER_METHOD;
|
||||
private static final Method GET_BRIGADIER_DISPATCHER_METHOD;
|
||||
private static final Constructor<?> COMMAND_WRAPPER_CONSTRUCTOR;
|
||||
private final Plugin plugin;
|
||||
private final List<LiteralCommandNode<?>> registeredNodes = new ArrayList();
|
||||
|
||||
ReflectionCommodore(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.plugin.getServer().getPluginManager().registerEvents((Listener)new ServerReloadListener(this), this.plugin);
|
||||
}
|
||||
|
||||
private CommandDispatcher<?> getDispatcher() {
|
||||
try {
|
||||
Object mcServerObject = CONSOLE_FIELD.get(Bukkit.getServer());
|
||||
Object commandDispatcherObject = GET_COMMAND_DISPATCHER_METHOD.invoke(mcServerObject, new Object[0]);
|
||||
return (CommandDispatcher)GET_BRIGADIER_DISPATCHER_METHOD.invoke(commandDispatcherObject, new Object[0]);
|
||||
}
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(LiteralCommandNode<?> node) {
|
||||
Objects.requireNonNull(node, "node");
|
||||
CommandDispatcher<?> dispatcher = this.getDispatcher();
|
||||
RootCommandNode root = dispatcher.getRoot();
|
||||
ReflectionCommodore.removeChild(root, node.getName());
|
||||
root.addChild(node);
|
||||
this.registeredNodes.add(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(Command command, LiteralCommandNode<?> node, Predicate<? super Player> permissionTest) {
|
||||
Objects.requireNonNull(command, "command");
|
||||
Objects.requireNonNull(node, "node");
|
||||
Objects.requireNonNull(permissionTest, "permissionTest");
|
||||
try {
|
||||
SuggestionProvider wrapper = (SuggestionProvider)COMMAND_WRAPPER_CONSTRUCTOR.newInstance(this.plugin.getServer(), command);
|
||||
ReflectionCommodore.setRequiredHackyFieldsRecursively(node, wrapper);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Collection<String> aliases = ReflectionCommodore.getAliases(command);
|
||||
if (!aliases.contains(node.getLiteral())) {
|
||||
node = ReflectionCommodore.renameLiteralNode(node, command.getName());
|
||||
}
|
||||
for (String alias : aliases) {
|
||||
if (node.getLiteral().equals(alias)) {
|
||||
this.register(node);
|
||||
continue;
|
||||
}
|
||||
this.register(((LiteralArgumentBuilder)LiteralArgumentBuilder.literal((String)alias).redirect(node)).build());
|
||||
}
|
||||
this.plugin.getServer().getPluginManager().registerEvents((Listener)new CommandDataSendListener(command, permissionTest), this.plugin);
|
||||
}
|
||||
|
||||
static void ensureSetup() {
|
||||
}
|
||||
|
||||
static {
|
||||
try {
|
||||
Class<?> commandDispatcher;
|
||||
Class<?> minecraftServer;
|
||||
if (ReflectionUtil.minecraftVersion() >= 19) {
|
||||
throw new UnsupportedOperationException("ReflectionCommodore is not supported on MC 1.19 or above. Switch to Paper :)");
|
||||
}
|
||||
if (ReflectionUtil.minecraftVersion() > 16) {
|
||||
minecraftServer = ReflectionUtil.mcClass("server.MinecraftServer");
|
||||
commandDispatcher = ReflectionUtil.mcClass("commands.CommandDispatcher");
|
||||
} else {
|
||||
minecraftServer = ReflectionUtil.nmsClass("MinecraftServer");
|
||||
commandDispatcher = ReflectionUtil.nmsClass("CommandDispatcher");
|
||||
}
|
||||
Class<?> craftServer = ReflectionUtil.obcClass("CraftServer");
|
||||
CONSOLE_FIELD = craftServer.getDeclaredField("console");
|
||||
CONSOLE_FIELD.setAccessible(true);
|
||||
GET_COMMAND_DISPATCHER_METHOD = Arrays.stream(minecraftServer.getDeclaredMethods()).filter(method -> method.getParameterCount() == 0).filter(method -> commandDispatcher.isAssignableFrom(method.getReturnType())).findFirst().orElseThrow(NoSuchMethodException::new);
|
||||
GET_COMMAND_DISPATCHER_METHOD.setAccessible(true);
|
||||
GET_BRIGADIER_DISPATCHER_METHOD = Arrays.stream(commandDispatcher.getDeclaredMethods()).filter(method -> method.getParameterCount() == 0).filter(method -> CommandDispatcher.class.isAssignableFrom(method.getReturnType())).findFirst().orElseThrow(NoSuchMethodException::new);
|
||||
GET_BRIGADIER_DISPATCHER_METHOD.setAccessible(true);
|
||||
Class<?> commandWrapperClass = ReflectionUtil.obcClass("command.BukkitCommandWrapper");
|
||||
COMMAND_WRAPPER_CONSTRUCTOR = commandWrapperClass.getConstructor(craftServer, Command.class);
|
||||
}
|
||||
catch (ReflectiveOperationException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ServerReloadListener
|
||||
implements Listener {
|
||||
private final ReflectionCommodore commodore;
|
||||
|
||||
private ServerReloadListener(ReflectionCommodore commodore) {
|
||||
this.commodore = commodore;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLoad(ServerLoadEvent e) {
|
||||
CommandDispatcher dispatcher = this.commodore.getDispatcher();
|
||||
RootCommandNode root = dispatcher.getRoot();
|
||||
for (LiteralCommandNode node : this.commodore.registeredNodes) {
|
||||
AbstractCommodore.removeChild(root, node.getName());
|
||||
root.addChild((CommandNode)node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class CommandDataSendListener
|
||||
implements Listener {
|
||||
private final Set<String> aliases;
|
||||
private final Set<String> minecraftPrefixedAliases;
|
||||
private final Predicate<? super Player> permissionTest;
|
||||
|
||||
CommandDataSendListener(Command pluginCommand, Predicate<? super Player> permissionTest) {
|
||||
this.aliases = new HashSet<String>(AbstractCommodore.getAliases(pluginCommand));
|
||||
this.minecraftPrefixedAliases = this.aliases.stream().map(alias -> "minecraft:" + alias).collect(Collectors.toSet());
|
||||
this.permissionTest = permissionTest;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCommandSend(PlayerCommandSendEvent e) {
|
||||
e.getCommands().removeAll(this.minecraftPrefixedAliases);
|
||||
if (!this.permissionTest.test((Player)e.getPlayer())) {
|
||||
e.getCommands().removeAll(this.aliases);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* org.bukkit.Bukkit
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
final class ReflectionUtil {
|
||||
private static final String SERVER_VERSION = ReflectionUtil.getServerVersion();
|
||||
|
||||
private static String getServerVersion() {
|
||||
Class<?> server = Bukkit.getServer().getClass();
|
||||
if (!server.getSimpleName().equals("CraftServer")) {
|
||||
return ".";
|
||||
}
|
||||
if (server.getName().equals("org.bukkit.craftbukkit.CraftServer")) {
|
||||
return ".";
|
||||
}
|
||||
String version = server.getName().substring("org.bukkit.craftbukkit".length());
|
||||
return version.substring(0, version.length() - "CraftServer".length());
|
||||
}
|
||||
|
||||
public static String mc(String name) {
|
||||
return "net.minecraft." + name;
|
||||
}
|
||||
|
||||
public static String nms(String className) {
|
||||
return "net.minecraft.server" + SERVER_VERSION + className;
|
||||
}
|
||||
|
||||
public static Class<?> mcClass(String className) throws ClassNotFoundException {
|
||||
return Class.forName(ReflectionUtil.mc(className));
|
||||
}
|
||||
|
||||
public static Class<?> nmsClass(String className) throws ClassNotFoundException {
|
||||
return Class.forName(ReflectionUtil.nms(className));
|
||||
}
|
||||
|
||||
public static String obc(String className) {
|
||||
return "org.bukkit.craftbukkit" + SERVER_VERSION + className;
|
||||
}
|
||||
|
||||
public static Class<?> obcClass(String className) throws ClassNotFoundException {
|
||||
return Class.forName(ReflectionUtil.obc(className));
|
||||
}
|
||||
|
||||
public static int minecraftVersion() {
|
||||
try {
|
||||
Matcher matcher = Pattern.compile("\\(MC: (\\d)\\.(\\d+)\\.?(\\d+?)?( .*)?\\)").matcher(Bukkit.getVersion());
|
||||
if (matcher.find()) {
|
||||
return Integer.parseInt(matcher.toMatchResult().group(2), 10);
|
||||
}
|
||||
throw new IllegalArgumentException(String.format("No match found in '%s'", Bukkit.getVersion()));
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
throw new RuntimeException("Failed to determine Minecraft version", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private ReflectionUtil() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
abstract class AbstractIterator<T>
|
||||
implements Iterator<T> {
|
||||
private State state = State.NOT_READY;
|
||||
private T next;
|
||||
|
||||
protected AbstractIterator() {
|
||||
}
|
||||
|
||||
protected abstract T computeNext() throws Exception;
|
||||
|
||||
protected final T endOfData() {
|
||||
this.state = State.DONE;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean hasNext() {
|
||||
if (this.state == State.FAILED) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
switch (this.state) {
|
||||
case DONE: {
|
||||
return false;
|
||||
}
|
||||
case READY: {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return this.tryToComputeNext();
|
||||
}
|
||||
|
||||
private boolean tryToComputeNext() {
|
||||
this.state = State.FAILED;
|
||||
try {
|
||||
this.next = this.computeNext();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException("Exception whilst computing next value", e);
|
||||
}
|
||||
if (this.state != State.DONE) {
|
||||
this.state = State.READY;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final T next() {
|
||||
if (!this.hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
this.state = State.NOT_READY;
|
||||
T result = this.next;
|
||||
this.next = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
public final T peek() {
|
||||
if (!this.hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
return this.next;
|
||||
}
|
||||
|
||||
private static enum State {
|
||||
READY,
|
||||
NOT_READY,
|
||||
DONE,
|
||||
FAILED;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.mojang.brigadier.arguments.ArgumentType
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import de.maxhenkel.voicechat.commodore.file.ParseException;
|
||||
import de.maxhenkel.voicechat.commodore.file.TokenStream;
|
||||
|
||||
public interface ArgumentTypeParser {
|
||||
public boolean canParse(String var1, String var2);
|
||||
|
||||
public ArgumentType<?> parse(String var1, String var2, TokenStream var3) throws ParseException;
|
||||
}
|
||||
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.mojang.brigadier.arguments.ArgumentType
|
||||
* com.mojang.brigadier.arguments.BoolArgumentType
|
||||
* com.mojang.brigadier.arguments.DoubleArgumentType
|
||||
* com.mojang.brigadier.arguments.FloatArgumentType
|
||||
* com.mojang.brigadier.arguments.IntegerArgumentType
|
||||
* com.mojang.brigadier.arguments.LongArgumentType
|
||||
* com.mojang.brigadier.arguments.StringArgumentType
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.arguments.BoolArgumentType;
|
||||
import com.mojang.brigadier.arguments.DoubleArgumentType;
|
||||
import com.mojang.brigadier.arguments.FloatArgumentType;
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.arguments.LongArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import de.maxhenkel.voicechat.commodore.file.ArgumentTypeParser;
|
||||
import de.maxhenkel.voicechat.commodore.file.ParseException;
|
||||
import de.maxhenkel.voicechat.commodore.file.Token;
|
||||
import de.maxhenkel.voicechat.commodore.file.TokenStream;
|
||||
|
||||
public class BrigadierArgumentTypeParser
|
||||
implements ArgumentTypeParser {
|
||||
public static final BrigadierArgumentTypeParser INSTANCE = new BrigadierArgumentTypeParser();
|
||||
|
||||
private BrigadierArgumentTypeParser() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canParse(String namespace, String name) {
|
||||
if (!namespace.equals("brigadier")) {
|
||||
return false;
|
||||
}
|
||||
switch (name) {
|
||||
case "bool":
|
||||
case "string":
|
||||
case "integer":
|
||||
case "long":
|
||||
case "float":
|
||||
case "double": {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType<?> parse(String namespace, String name, TokenStream tokens) throws ParseException {
|
||||
switch (name) {
|
||||
case "bool": {
|
||||
return BoolArgumentType.bool();
|
||||
}
|
||||
case "string": {
|
||||
return BrigadierArgumentTypeParser.parseStringArgumentType(tokens);
|
||||
}
|
||||
case "integer": {
|
||||
return BrigadierArgumentTypeParser.parseIntegerArgumentType(tokens);
|
||||
}
|
||||
case "long": {
|
||||
return BrigadierArgumentTypeParser.parseLongArgumentType(tokens);
|
||||
}
|
||||
case "float": {
|
||||
return BrigadierArgumentTypeParser.parseFloatArgumentType(tokens);
|
||||
}
|
||||
case "double": {
|
||||
return BrigadierArgumentTypeParser.parseDoubleArgumentType(tokens);
|
||||
}
|
||||
}
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
private static StringArgumentType parseStringArgumentType(TokenStream tokens) throws ParseException {
|
||||
String stringType;
|
||||
Token token = tokens.next();
|
||||
if (!(token instanceof Token.StringToken)) {
|
||||
throw tokens.createException("Expected string token for string type but got " + token);
|
||||
}
|
||||
switch (stringType = ((Token.StringToken)token).getString()) {
|
||||
case "single_word": {
|
||||
return StringArgumentType.word();
|
||||
}
|
||||
case "quotable_phrase": {
|
||||
return StringArgumentType.string();
|
||||
}
|
||||
case "greedy_phrase": {
|
||||
return StringArgumentType.greedyString();
|
||||
}
|
||||
}
|
||||
throw tokens.createException("Unknown string type: " + stringType);
|
||||
}
|
||||
|
||||
private static IntegerArgumentType parseIntegerArgumentType(TokenStream tokens) throws ParseException {
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
int min = BrigadierArgumentTypeParser.parseInt(tokens);
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
int max = BrigadierArgumentTypeParser.parseInt(tokens);
|
||||
return IntegerArgumentType.integer((int)min, (int)max);
|
||||
}
|
||||
return IntegerArgumentType.integer((int)min);
|
||||
}
|
||||
return IntegerArgumentType.integer();
|
||||
}
|
||||
|
||||
private static LongArgumentType parseLongArgumentType(TokenStream tokens) throws ParseException {
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
long min = BrigadierArgumentTypeParser.parseLong(tokens);
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
long max = BrigadierArgumentTypeParser.parseLong(tokens);
|
||||
return LongArgumentType.longArg((long)min, (long)max);
|
||||
}
|
||||
return LongArgumentType.longArg((long)min);
|
||||
}
|
||||
return LongArgumentType.longArg();
|
||||
}
|
||||
|
||||
private static FloatArgumentType parseFloatArgumentType(TokenStream tokens) throws ParseException {
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
float min = BrigadierArgumentTypeParser.parseFloat(tokens);
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
float max = BrigadierArgumentTypeParser.parseFloat(tokens);
|
||||
return FloatArgumentType.floatArg((float)min, (float)max);
|
||||
}
|
||||
return FloatArgumentType.floatArg((float)min);
|
||||
}
|
||||
return FloatArgumentType.floatArg();
|
||||
}
|
||||
|
||||
private static DoubleArgumentType parseDoubleArgumentType(TokenStream tokens) throws ParseException {
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
double min = BrigadierArgumentTypeParser.parseDouble(tokens);
|
||||
if (tokens.peek() instanceof Token.StringToken) {
|
||||
double max = BrigadierArgumentTypeParser.parseDouble(tokens);
|
||||
return DoubleArgumentType.doubleArg((double)min, (double)max);
|
||||
}
|
||||
return DoubleArgumentType.doubleArg((double)min);
|
||||
}
|
||||
return DoubleArgumentType.doubleArg();
|
||||
}
|
||||
|
||||
private static int parseInt(TokenStream tokens) throws ParseException {
|
||||
Token token = tokens.next();
|
||||
if (!(token instanceof Token.StringToken)) {
|
||||
throw tokens.createException("Expected string token for integer but got " + token);
|
||||
}
|
||||
String value = ((Token.StringToken)token).getString();
|
||||
if (value.equals("min")) {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
if (value.equals("max")) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw tokens.createException("Expected int but got " + value, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static long parseLong(TokenStream tokens) throws ParseException {
|
||||
Token token = tokens.next();
|
||||
if (!(token instanceof Token.StringToken)) {
|
||||
throw tokens.createException("Expected string token for long but got " + token);
|
||||
}
|
||||
String value = ((Token.StringToken)token).getString();
|
||||
if (value.equals("min")) {
|
||||
return Long.MIN_VALUE;
|
||||
}
|
||||
if (value.equals("max")) {
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw tokens.createException("Expected long but got " + value, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static float parseFloat(TokenStream tokens) throws ParseException {
|
||||
Token token = tokens.next();
|
||||
if (!(token instanceof Token.StringToken)) {
|
||||
throw tokens.createException("Expected string token for float but got " + token);
|
||||
}
|
||||
String value = ((Token.StringToken)token).getString();
|
||||
if (value.equals("min")) {
|
||||
return Float.MIN_VALUE;
|
||||
}
|
||||
if (value.equals("max")) {
|
||||
return Float.MAX_VALUE;
|
||||
}
|
||||
try {
|
||||
return Float.parseFloat(value);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw tokens.createException("Expected float but got " + value, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static double parseDouble(TokenStream tokens) throws ParseException {
|
||||
Token token = tokens.next();
|
||||
if (!(token instanceof Token.StringToken)) {
|
||||
throw tokens.createException("Expected string token for double but got " + token);
|
||||
}
|
||||
String value = ((Token.StringToken)token).getString();
|
||||
if (value.equals("min")) {
|
||||
return Double.MIN_VALUE;
|
||||
}
|
||||
if (value.equals("max")) {
|
||||
return Double.MAX_VALUE;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(value);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw tokens.createException("Expected double but got " + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.mojang.brigadier.tree.LiteralCommandNode
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import de.maxhenkel.voicechat.commodore.file.ArgumentTypeParser;
|
||||
import de.maxhenkel.voicechat.commodore.file.BrigadierArgumentTypeParser;
|
||||
import de.maxhenkel.voicechat.commodore.file.Lexer;
|
||||
import de.maxhenkel.voicechat.commodore.file.ParseException;
|
||||
import de.maxhenkel.voicechat.commodore.file.Parser;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class CommodoreFileReader {
|
||||
public static final CommodoreFileReader INSTANCE = CommodoreFileReader.builder().withArgumentTypeParser(BrigadierArgumentTypeParser.INSTANCE).build();
|
||||
private final List<ArgumentTypeParser> argumentTypeParsers;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
CommodoreFileReader(List<ArgumentTypeParser> argumentTypeParsers) {
|
||||
this.argumentTypeParsers = Collections.unmodifiableList(argumentTypeParsers);
|
||||
}
|
||||
|
||||
public <S> LiteralCommandNode<S> parse(Reader reader) throws IOException {
|
||||
try {
|
||||
return new Parser(new Lexer(reader), this.argumentTypeParsers).parse();
|
||||
}
|
||||
catch (ParseException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
throw (IOException)e.getCause();
|
||||
}
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public <S> LiteralCommandNode<S> parse(InputStream inputStream) throws IOException {
|
||||
try (InputStreamReader reader = new InputStreamReader(inputStream);){
|
||||
LiteralCommandNode<S> literalCommandNode = this.parse(reader);
|
||||
return literalCommandNode;
|
||||
}
|
||||
}
|
||||
|
||||
public <S> LiteralCommandNode<S> parse(Path path) throws IOException {
|
||||
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);){
|
||||
LiteralCommandNode<S> literalCommandNode = this.parse(reader);
|
||||
return literalCommandNode;
|
||||
}
|
||||
}
|
||||
|
||||
public <S> LiteralCommandNode<S> parse(File file) throws IOException {
|
||||
return this.parse(file.toPath());
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private final List<ArgumentTypeParser> argumentTypeParsers = new ArrayList<ArgumentTypeParser>();
|
||||
|
||||
Builder() {
|
||||
}
|
||||
|
||||
public Builder withArgumentTypeParser(ArgumentTypeParser argumentTypeParser) {
|
||||
Objects.requireNonNull(argumentTypeParser, "argumentTypeParser");
|
||||
this.argumentTypeParsers.add(argumentTypeParser);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommodoreFileReader build() {
|
||||
return new CommodoreFileReader(new ArrayList<ArgumentTypeParser>(this.argumentTypeParsers));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
import de.maxhenkel.voicechat.commodore.file.AbstractIterator;
|
||||
import de.maxhenkel.voicechat.commodore.file.ParseException;
|
||||
import de.maxhenkel.voicechat.commodore.file.Token;
|
||||
import de.maxhenkel.voicechat.commodore.file.TokenStream;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StreamTokenizer;
|
||||
|
||||
class Lexer
|
||||
extends AbstractIterator<Token>
|
||||
implements TokenStream {
|
||||
private final StreamTokenizer tokenizer;
|
||||
private boolean end = false;
|
||||
|
||||
Lexer(Reader reader) {
|
||||
this.tokenizer = new StreamTokenizer(reader);
|
||||
this.tokenizer.resetSyntax();
|
||||
this.tokenizer.wordChars(33, 126);
|
||||
this.tokenizer.quoteChar(34);
|
||||
this.tokenizer.whitespaceChars(0, 32);
|
||||
"{};".chars().forEach(this.tokenizer::ordinaryChar);
|
||||
this.tokenizer.slashSlashComments(true);
|
||||
this.tokenizer.slashStarComments(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Token computeNext() throws ParseException {
|
||||
if (this.end) {
|
||||
return (Token)this.endOfData();
|
||||
}
|
||||
try {
|
||||
int token = this.tokenizer.nextToken();
|
||||
switch (token) {
|
||||
case -1: {
|
||||
this.end = true;
|
||||
return Token.ConstantToken.EOF;
|
||||
}
|
||||
case -3: {
|
||||
return new Token.StringToken(this.tokenizer.sval);
|
||||
}
|
||||
case 123: {
|
||||
return Token.ConstantToken.OPEN_BRACKET;
|
||||
}
|
||||
case 125: {
|
||||
return Token.ConstantToken.CLOSE_BRACKET;
|
||||
}
|
||||
case 59: {
|
||||
return Token.ConstantToken.SEMICOLON;
|
||||
}
|
||||
}
|
||||
throw this.createException("Unknown token: " + (char)token + "(" + token + ")");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw this.createException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParseException createException(String message) {
|
||||
return new ParseException(message, this.tokenizer.lineno());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParseException createException(Throwable cause) {
|
||||
return new ParseException(cause, this.tokenizer.lineno());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParseException createException(String message, Throwable cause) {
|
||||
return new ParseException(message, cause, this.tokenizer.lineno());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
public final class ParseException
|
||||
extends Exception {
|
||||
ParseException(String message, int currentLine) {
|
||||
super(message + " (at line " + currentLine + ")");
|
||||
}
|
||||
|
||||
ParseException(Throwable cause, int currentLine) {
|
||||
super("At line " + currentLine, cause);
|
||||
}
|
||||
|
||||
ParseException(String message, Throwable cause, int currentLine) {
|
||||
super(message + " (at line " + currentLine + ")", cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*
|
||||
* Could not load the following classes:
|
||||
* com.mojang.brigadier.arguments.ArgumentType
|
||||
* com.mojang.brigadier.builder.LiteralArgumentBuilder
|
||||
* com.mojang.brigadier.builder.RequiredArgumentBuilder
|
||||
* com.mojang.brigadier.tree.CommandNode
|
||||
* com.mojang.brigadier.tree.LiteralCommandNode
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import de.maxhenkel.voicechat.commodore.file.ArgumentTypeParser;
|
||||
import de.maxhenkel.voicechat.commodore.file.Lexer;
|
||||
import de.maxhenkel.voicechat.commodore.file.ParseException;
|
||||
import de.maxhenkel.voicechat.commodore.file.Token;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
class Parser<S> {
|
||||
private final Lexer lexer;
|
||||
private final Collection<ArgumentTypeParser> argumentTypeParsers;
|
||||
|
||||
Parser(Lexer lexer, Collection<ArgumentTypeParser> argumentTypeParsers) {
|
||||
this.lexer = lexer;
|
||||
this.argumentTypeParsers = argumentTypeParsers;
|
||||
}
|
||||
|
||||
LiteralCommandNode<S> parse() throws ParseException {
|
||||
CommandNode<S> node = this.parseNode();
|
||||
if (!(node instanceof LiteralCommandNode)) {
|
||||
throw this.lexer.createException("Root command node is not a literal command node");
|
||||
}
|
||||
if (this.lexer.peek() != Token.ConstantToken.EOF) {
|
||||
throw this.lexer.createException("Expected end of file but got " + this.lexer.peek());
|
||||
}
|
||||
return (LiteralCommandNode)node;
|
||||
}
|
||||
|
||||
private CommandNode<S> parseNode() throws ParseException {
|
||||
Token token = (Token)this.lexer.next();
|
||||
if (!(token instanceof Token.StringToken)) {
|
||||
throw this.lexer.createException("Expected string token for node name but got " + token);
|
||||
}
|
||||
String name = ((Token.StringToken)token).getString();
|
||||
Object node = this.lexer.peek() instanceof Token.StringToken ? RequiredArgumentBuilder.argument((String)name, this.parseArgumentType()) : LiteralArgumentBuilder.literal((String)name);
|
||||
if (this.lexer.peek() == Token.ConstantToken.OPEN_BRACKET) {
|
||||
this.lexer.next();
|
||||
while (this.lexer.peek() != Token.ConstantToken.CLOSE_BRACKET) {
|
||||
CommandNode<S> child = this.parseNode();
|
||||
node.then(child);
|
||||
}
|
||||
this.lexer.next();
|
||||
} else {
|
||||
if (this.lexer.peek() != Token.ConstantToken.SEMICOLON) {
|
||||
throw this.lexer.createException("Node definition not ended with semicolon, got " + this.lexer.peek());
|
||||
}
|
||||
this.lexer.next();
|
||||
}
|
||||
return node.build();
|
||||
}
|
||||
|
||||
private ArgumentType<?> parseArgumentType() throws ParseException {
|
||||
Token token = (Token)this.lexer.next();
|
||||
if (!(token instanceof Token.StringToken)) {
|
||||
throw this.lexer.createException("Expected string token for argument type but got " + token);
|
||||
}
|
||||
String argumentType = ((Token.StringToken)token).getString();
|
||||
Object[] key = argumentType.split(":");
|
||||
if (key.length != 2) {
|
||||
throw this.lexer.createException("Invalid key for argument type: " + Arrays.toString(key));
|
||||
}
|
||||
for (ArgumentTypeParser parser : this.argumentTypeParsers) {
|
||||
if (!parser.canParse((String)key[0], (String)key[1])) continue;
|
||||
return parser.parse((String)key[0], (String)key[1], this.lexer);
|
||||
}
|
||||
throw this.lexer.createException("Unable to parse argument type: " + argumentType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
public interface Token {
|
||||
|
||||
public static final class StringToken
|
||||
implements Token {
|
||||
private final String string;
|
||||
|
||||
StringToken(String string) {
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString() {
|
||||
return this.string;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum ConstantToken implements Token
|
||||
{
|
||||
OPEN_BRACKET,
|
||||
CLOSE_BRACKET,
|
||||
SEMICOLON,
|
||||
EOF;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Decompiled with CFR 0.152.
|
||||
*/
|
||||
package de.maxhenkel.voicechat.commodore.file;
|
||||
|
||||
import de.maxhenkel.voicechat.commodore.file.ParseException;
|
||||
import de.maxhenkel.voicechat.commodore.file.Token;
|
||||
|
||||
public interface TokenStream {
|
||||
public boolean hasNext();
|
||||
|
||||
public Token next();
|
||||
|
||||
public Token peek();
|
||||
|
||||
public ParseException createException(String var1);
|
||||
|
||||
public ParseException createException(Throwable var1);
|
||||
|
||||
public ParseException createException(String var1, Throwable var2);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user