7 Commits

Author SHA1 Message Date
39055270e2 fix gradle file 2023-07-10 23:28:34 -05:00
67816f2785 Merge remote-tracking branch 'origin/master' into brigadier 2023-07-10 23:08:04 -05:00
0cdd4ca6a7 remove testing methods 2023-07-10 20:48:37 -07:00
7477fa3f7a remove failing comment 2023-07-10 20:47:52 -07:00
c39a758aea Merge branch 'master' into brigadier
# Conflicts:
#	server/build.gradle
2023-07-10 20:42:52 -07:00
4b2a6916e4 start admin chat, except there is a bug where we have to now add optional arguments 2023-07-10 20:41:18 -07:00
33195260a1 begin brigadier support, arguments aren't supported yet 2023-07-07 22:14:56 -07:00
14 changed files with 849 additions and 8 deletions

View File

@ -33,6 +33,11 @@ subprojects {
} }
} }
maven {
url = uri("https://libraries.minecraft.net")
}
mavenCentral() mavenCentral()
} }

View File

@ -13,9 +13,11 @@ dependencies {
library "com.zaxxer:HikariCP:5.0.1" library "com.zaxxer:HikariCP:5.0.1"
library "org.apache.maven.resolver:maven-resolver-transport-http:1.9.13" library "org.apache.maven.resolver:maven-resolver-transport-http:1.9.13"
compileOnly "io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT" compileOnly "io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT"
compileOnly "io.papermc.paper:paper-mojangapi:1.20.1-R0.1-SNAPSHOT"
compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") { compileOnly("com.github.MilkBowl:VaultAPI:1.7.1") {
exclude group: "org.bukkit", module: "bukkit" exclude group: "org.bukkit", module: "bukkit"
} }
compileOnly "com.mojang:brigadier:1.0.18"
implementation "org.bstats:bstats-base:3.0.2" implementation "org.bstats:bstats-base:3.0.2"
implementation "org.bstats:bstats-bukkit:3.0.2" implementation "org.bstats:bstats-bukkit:3.0.2"
} }

View File

@ -4,6 +4,8 @@ import dev.plex.admin.Admin;
import dev.plex.admin.AdminList; import dev.plex.admin.AdminList;
import dev.plex.cache.DataUtils; import dev.plex.cache.DataUtils;
import dev.plex.cache.PlayerCache; import dev.plex.cache.PlayerCache;
import dev.plex.command.PlexBrigadierCommand;
import dev.plex.command.impl.brigadier.PlexBrigadierCMD;
import dev.plex.config.Config; import dev.plex.config.Config;
import dev.plex.handlers.CommandHandler; import dev.plex.handlers.CommandHandler;
import dev.plex.handlers.ListenerHandler; import dev.plex.handlers.ListenerHandler;
@ -178,6 +180,7 @@ public class Plex extends JavaPlugin
new ListenerHandler(); new ListenerHandler();
new CommandHandler(); new CommandHandler();
new PlexBrigadierCMD();
rankManager = new RankManager(); rankManager = new RankManager();
rankManager.generateDefaultRanks(); rankManager.generateDefaultRanks();

View File

@ -0,0 +1,571 @@
package dev.plex.command;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import com.google.common.collect.Maps;
import com.google.gson.GsonBuilder;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.*;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import dev.plex.Plex;
import dev.plex.cache.DataUtils;
import dev.plex.command.annotation.*;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import dev.plex.util.PlexLog;
import dev.plex.util.PlexUtils;
import dev.plex.util.ReflectionsUtil;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.lang.System;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
/**
* @author Taah
* @since 2:27 PM [07-07-2023]
*/
public abstract class PlexBrigadierCommand
{
protected final Plex plugin;
private CommandDispatcher<BukkitBrigadierCommandSource> commandDispatcher;
public PlexBrigadierCommand()
{
this.plugin = Plex.get();
try
{
final Object dedicatedServer = ReflectionsUtil.callFunction(getCraftServer(), "getServer");
final Object minecraftServer = Class.forName("net.minecraft.server.MinecraftServer").cast(dedicatedServer);
final Object serverFunctionsManager = ReflectionsUtil.callFunction(minecraftServer, "aA");
this.commandDispatcher = ReflectionsUtil.callFunction(serverFunctionsManager, "b");
}
catch (ClassNotFoundException e)
{
this.commandDispatcher = null;
PlexLog.error("Disabling commands as brigadier could not properly be located.");
}
if (!this.getClass().isAnnotationPresent(CommandName.class))
{
if (this.commandDispatcher != null)
{
this.commandDispatcher.register(execute());
}
return;
}
String[] commandName = this.getClass().getAnnotation(CommandName.class).value();
final HashMap<String, Method> subcommands = Maps.newHashMap();
Method defaultMethod = null;
for (Method declaredMethod : this.getClass().getDeclaredMethods())
{
if (declaredMethod.isAnnotationPresent(SubCommand.class))
{
String subcommand = declaredMethod.getAnnotation(SubCommand.class).value();
subcommands.put(subcommand.toLowerCase(), declaredMethod);
}
if (declaredMethod.isAnnotationPresent(Default.class))
{
if (defaultMethod != null)
{
PlexLog.error("There cannot be more than one default execution.");
continue;
}
defaultMethod = declaredMethod;
}
}
if (this.commandDispatcher != null)
{
for (String name : commandName)
{
LiteralArgumentBuilder<BukkitBrigadierCommandSource> builder = LiteralArgumentBuilder.literal(name.toLowerCase());
for (Map.Entry<String, Method> stringMethodEntry : subcommands.entrySet())
{
String[] subCommandArgs = stringMethodEntry.getKey().split(" ");
LinkedList<LiteralArgumentBuilder<BukkitBrigadierCommandSource>> builders = new LinkedList<>();
for (int i = 0; i < subCommandArgs.length; i++)
{
LiteralArgumentBuilder<BukkitBrigadierCommandSource> newNode = LiteralArgumentBuilder.literal(subCommandArgs[i]);
builders.addLast(newNode);
}
if (builders.size() == 1)
{
LiteralArgumentBuilder<BukkitBrigadierCommandSource> parent = builders.removeFirst();
LinkedList<RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> argumentBuilders = new LinkedList<>();
LinkedHashMap<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> arguments = getArguments(stringMethodEntry.getValue());
for (Map.Entry<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> parameterArgumentBuilderEntry : arguments.entrySet())
{
argumentBuilders.addLast(parameterArgumentBuilderEntry.getValue());
}
boolean setExecution = false;
CommandNode<BukkitBrigadierCommandSource> parentArg = null;
CommandNode<BukkitBrigadierCommandSource> currArg = null;
while (!argumentBuilders.isEmpty())
{
if (parentArg == null)
{
RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?> newParent = argumentBuilders.removeFirst();
if (argumentBuilders.isEmpty())
{
newParent.executes(context -> execute(stringMethodEntry.getValue(), context, arguments.keySet()));
setExecution = true;
}
parentArg = newParent.build();
parent.then(parentArg);
currArg = parentArg;
}
else
{
RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?> newCurr = argumentBuilders.removeFirst();
if (argumentBuilders.isEmpty())
{
newCurr.executes(context -> execute(stringMethodEntry.getValue(), context, arguments.keySet()));
setExecution = true;
}
CommandNode<BukkitBrigadierCommandSource> newCurrNode = newCurr.build();
currArg.addChild(newCurrNode);
currArg = newCurrNode;
}
}
if (!setExecution)
{
parent.executes(context -> execute(stringMethodEntry.getValue(), context, arguments.keySet()));
}
builder.then(parent);
}
else if (builders.size() > 1)
{
LiteralCommandNode<BukkitBrigadierCommandSource> parent = builders.removeFirst().build();
LiteralCommandNode<BukkitBrigadierCommandSource> curr = null;
while (!builders.isEmpty())
{
LiteralArgumentBuilder<BukkitBrigadierCommandSource> newCurr = builders.removeFirst();
PlexLog.debug("Adding subcommand " + newCurr.getLiteral());
if (builders.isEmpty())
{
LinkedList<RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> argumentBuilders = new LinkedList<>();
LinkedHashMap<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> arguments = getArguments(stringMethodEntry.getValue());
for (Map.Entry<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> parameterArgumentBuilderEntry : arguments.entrySet())
{
argumentBuilders.addLast(parameterArgumentBuilderEntry.getValue());
}
boolean setExecution = false;
CommandNode<BukkitBrigadierCommandSource> parentArg = null;
CommandNode<BukkitBrigadierCommandSource> currArg = null;
while (!argumentBuilders.isEmpty())
{
if (parentArg == null)
{
RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?> newParent = argumentBuilders.removeFirst();
if (argumentBuilders.isEmpty())
{
newParent.executes(context -> execute(stringMethodEntry.getValue(), context, arguments.keySet()));
setExecution = true;
}
parentArg = newParent.build();
newCurr.then(parentArg);
currArg = parentArg;
}
else
{
RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?> newCurrArg = argumentBuilders.removeFirst();
if (argumentBuilders.isEmpty())
{
newCurrArg.executes(context -> execute(stringMethodEntry.getValue(), context, arguments.keySet()));
setExecution = true;
}
CommandNode<BukkitBrigadierCommandSource> newCurrNode = newCurrArg.build();
currArg.addChild(newCurrNode);
currArg = newCurrNode;
}
}
if (!setExecution)
{
newCurr.executes(context -> execute(stringMethodEntry.getValue(), context, arguments.keySet()));
}
}
if (curr == null)
{
LiteralCommandNode<BukkitBrigadierCommandSource> temp = newCurr.build();
parent.addChild(temp);
curr = temp;
}
else
{
LiteralCommandNode<BukkitBrigadierCommandSource> temp = newCurr.build();
curr.addChild(temp);
curr = temp;
}
}
builder.then(parent);
}
PlexLog.debug("Overall Builder: " + new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(builder));
}
if (defaultMethod != null)
{
LinkedList<RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> argumentBuilders = new LinkedList<>();
LinkedHashMap<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> arguments = getArguments(defaultMethod);
for (Map.Entry<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> parameterArgumentBuilderEntry : arguments.entrySet())
{
argumentBuilders.addLast(parameterArgumentBuilderEntry.getValue());
}
boolean setExecution = false;
CommandNode<BukkitBrigadierCommandSource> parentArg = null;
CommandNode<BukkitBrigadierCommandSource> currArg = null;
while (!argumentBuilders.isEmpty())
{
if (parentArg == null)
{
RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?> newParent = argumentBuilders.removeFirst();
if (argumentBuilders.isEmpty())
{
Method finalDefaultMethod = defaultMethod;
newParent.executes(context -> execute(finalDefaultMethod, context, arguments.keySet()));
setExecution = true;
}
parentArg = newParent.build();
builder.then(parentArg);
currArg = parentArg;
}
else
{
RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?> newCurrArg = argumentBuilders.removeFirst();
if (argumentBuilders.isEmpty())
{
Method finalDefaultMethod1 = defaultMethod;
newCurrArg.executes(context -> execute(finalDefaultMethod1, context, arguments.keySet()));
setExecution = true;
}
CommandNode<BukkitBrigadierCommandSource> newCurrNode = newCurrArg.build();
currArg.addChild(newCurrNode);
currArg = newCurrNode;
}
}
if (!setExecution)
{
Method finalDefaultMethod2 = defaultMethod;
builder.executes(context -> execute(finalDefaultMethod2, context, arguments.keySet()));
}
}
this.commandDispatcher.register(builder);
}
this.commandDispatcher.register(LiteralArgumentBuilder.<BukkitBrigadierCommandSource>literal("testing")
.then(RequiredArgumentBuilder.<BukkitBrigadierCommandSource, Integer>argument("test0", IntegerArgumentType.integer())
.then(RequiredArgumentBuilder.<BukkitBrigadierCommandSource, String>argument("test", StringArgumentType.word())
.then(RequiredArgumentBuilder.<BukkitBrigadierCommandSource, String>argument("test1", StringArgumentType.word())
.executes(context ->
{
send(context, context.getArgument("test", String.class));
send(context, context.getArgument("test1", String.class));
return 1;
})))));
}
}
public LiteralArgumentBuilder<BukkitBrigadierCommandSource> execute()
{
return LiteralArgumentBuilder.literal(this.getClass().getName().toLowerCase());
}
/**
* Gets a PlexPlayer from Player object
*
* @param player The player object
* @return PlexPlayer Object
* @see PlexPlayer
*/
protected PlexPlayer getPlexPlayer(@NotNull Player player)
{
return DataUtils.getPlayer(player.getUniqueId());
}
protected void send(Audience audience, Component component)
{
audience.sendMessage(component);
}
/**
* Sends a message to an Audience
*
* @param audience The Audience to send the message to
* @param s The message to send
*/
protected void send(Audience audience, String s)
{
audience.sendMessage(componentFromString(s));
}
/**
* Sends a message to a CommandSender
*
* @param context The Command Context's sender to send the message to
* @param s The message to send
*/
protected void send(CommandContext<BukkitBrigadierCommandSource> context, String s)
{
context.getSource().getBukkitSender().sendMessage(componentFromString(s));
}
/**
* Sends a message to a CommandSender
*
* @param context The Command Context's sender to send the message to
* @param component The Component to send
*/
protected void send(CommandContext<BukkitBrigadierCommandSource> context, Component component)
{
context.getSource().getBukkitSender().sendMessage(component);
}
/**
* Converts a String to a MiniMessage Component
*
* @param s The String to convert
* @return A Kyori Component
*/
protected Component mmString(String s)
{
return PlexUtils.mmDeserialize(s);
}
/**
* Converts a String to a legacy Kyori Component
*
* @param s The String to convert
* @return A Kyori component
*/
protected Component componentFromString(String s)
{
return LegacyComponentSerializer.legacyAmpersand().deserialize(s).colorIfAbsent(NamedTextColor.GRAY);
}
/**
* Checks if a player is an admin
*
* @param plexPlayer The PlexPlayer object
* @return true if the player is an admin
* @see PlexPlayer
*/
protected boolean isAdmin(PlexPlayer plexPlayer)
{
return Plex.get().getRankManager().isAdmin(plexPlayer);
}
/**
* Checks if a sender is an admin
*
* @param sender A command sender
* @return true if the sender is an admin or if console
*/
protected boolean isAdmin(CommandSender sender)
{
if (!(sender instanceof Player player))
{
return true;
}
PlexPlayer plexPlayer = getPlexPlayer(player);
return plugin.getRankManager().isAdmin(plexPlayer);
}
/**
* Checks if a username is an admin
*
* @param name The username
* @return true if the username is an admin
*/
protected boolean isAdmin(String name)
{
PlexPlayer plexPlayer = DataUtils.getPlayer(name);
return plugin.getRankManager().isAdmin(plexPlayer);
}
/**
* Checks if a sender is a senior admin
*
* @param sender A command sender
* @return true if the sender is a senior admin or if console
*/
protected boolean isSeniorAdmin(CommandSender sender)
{
if (!(sender instanceof Player player))
{
return true;
}
PlexPlayer plexPlayer = getPlexPlayer(player);
return plugin.getRankManager().isSeniorAdmin(plexPlayer);
}
/**
* Gets the UUID of the sender
*
* @param sender A command sender
* @return A unique ID or null if the sender is console
* @see UUID
*/
protected UUID getUUID(CommandSender sender)
{
if (!(sender instanceof Player player))
{
return null;
}
return player.getUniqueId();
}
private LinkedHashMap<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> getArguments(Method method)
{
LinkedHashMap<Parameter, RequiredArgumentBuilder<BukkitBrigadierCommandSource, ?>> result = new LinkedHashMap<>();
if (!method.canAccess(this))
{
method.setAccessible(true);
}
for (Parameter parameter : method.getParameters())
{
if (parameter.isAnnotationPresent(Argument.class))
{
Argument argument = parameter.getAnnotation(Argument.class);
if (String.class.isAssignableFrom(parameter.getType()))
{
result.put(parameter, RequiredArgumentBuilder.argument(argument.value(), argument.argumentType() == StringArgumentType.StringType.SINGLE_WORD ? StringArgumentType.word() : StringArgumentType.greedyString()));
}
else if (int.class.isAssignableFrom(parameter.getType()))
{
result.put(parameter, RequiredArgumentBuilder.argument(argument.value(), IntegerArgumentType.integer(argument.min() == Double.MIN_VALUE ? Integer.MIN_VALUE : (int) argument.min(), argument.max() == Double.MAX_VALUE ? Integer.MAX_VALUE : (int) argument.max())));
}
else if (double.class.isAssignableFrom(parameter.getType()))
{
result.put(parameter, RequiredArgumentBuilder.argument(argument.value(), DoubleArgumentType.doubleArg(argument.min(), argument.max())));
}
else if (float.class.isAssignableFrom(parameter.getType()))
{
result.put(parameter, RequiredArgumentBuilder.argument(argument.value(), FloatArgumentType.floatArg(argument.min() == Double.MIN_VALUE ? Float.MIN_VALUE : (int) argument.min(), argument.max() == Double.MAX_VALUE ? Float.MAX_VALUE : (int) argument.max())));
}
else if (boolean.class.isAssignableFrom(parameter.getType()))
{
result.put(parameter, RequiredArgumentBuilder.argument(argument.value(), BoolArgumentType.bool()));
}
else if (long.class.isAssignableFrom(parameter.getType()))
{
result.put(parameter, RequiredArgumentBuilder.argument(argument.value(), LongArgumentType.longArg(argument.min() == Double.MIN_VALUE ? Long.MIN_VALUE : (int) argument.min(), argument.max() == Double.MAX_VALUE ? Long.MAX_VALUE : (int) argument.max())));
}
}
}
return result;
}
private Object getArgument(Class<?> clazz, CommandContext<BukkitBrigadierCommandSource> context, String name)
{
if (String.class.isAssignableFrom(clazz))
{
return StringArgumentType.getString(context, name);
}
else if (int.class.isAssignableFrom(clazz))
{
return IntegerArgumentType.getInteger(context, name);
}
else if (double.class.isAssignableFrom(clazz))
{
return DoubleArgumentType.getDouble(context, name);
}
else if (float.class.isAssignableFrom(clazz))
{
return FloatArgumentType.getFloat(context, name);
}
else if (boolean.class.isAssignableFrom(clazz))
{
return BoolArgumentType.getBool(context, name);
}
else if (long.class.isAssignableFrom(clazz))
{
return LongArgumentType.getLong(context, name);
}
return null;
}
private int execute(Method method, CommandContext<BukkitBrigadierCommandSource> context, Set<Parameter> arguments)
{
if (method.isAnnotationPresent(CommandPermission.class))
{
String permission = method.getAnnotation(CommandPermission.class).value();
if (!context.getSource().getBukkitSender().hasPermission(permission))
{
send(context, PlexUtils.messageComponent("noPermissionNode", permission));
return 1;
}
}
try
{
List<Object> params = arguments
.stream().map(bukkitBrigadierCommandSourceArgumentBuilder -> getArgument(bukkitBrigadierCommandSourceArgumentBuilder.getType(), context, bukkitBrigadierCommandSourceArgumentBuilder.getAnnotation(Argument.class).value())).toList();
LinkedList<Object> parameters = new LinkedList<>(params);
// parameters.addFirst(context.getSource().getBukkitSender());
if (method.isAnnotationPresent(CommandSource.class)) {
RequiredCommandSource commandSource = method.getAnnotation(CommandSource.class).value();
if (commandSource == RequiredCommandSource.IN_GAME) {
if (!(context.getSource().getBukkitSender() instanceof Player player)) {
send(context, PlexUtils.messageComponent("noPermissionConsole"));
return 1;
} else {
parameters.addFirst(player);
}
} else if (commandSource == RequiredCommandSource.CONSOLE) {
if (context.getSource().getBukkitSender() instanceof Player) {
send(context, PlexUtils.messageComponent("noPermissionInGame"));
return 1;
}
parameters.addFirst(context.getSource().getBukkitSender());
} else {
parameters.addFirst(context.getSource().getBukkitSender());
}
}
System.out.println(Arrays.toString(parameters.stream().map(Object::getClass).map(Class::getName).toArray()));
System.out.println(Arrays.toString(Arrays.stream(method.getParameterTypes()).map(Class::getName).toArray()));
method.invoke(this, parameters.toArray());
return 1;
}
catch (Exception e)
{
PlexLog.error(e.getMessage());
for (StackTraceElement stackTraceElement : e.getStackTrace())
{
PlexLog.error(stackTraceElement.toString());
}
return 0;
}
}
private Object getCraftServer()
{
String nmsVersion = Bukkit.getServer().getClass().getPackage().getName();
nmsVersion = nmsVersion.substring(nmsVersion.lastIndexOf('.') + 1);
try
{
Class<?> craftServer = Class.forName("org.bukkit.craftbukkit." + nmsVersion + ".CraftServer");
return craftServer.cast(Bukkit.getServer());
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,24 @@
package dev.plex.command.annotation;
import com.mojang.brigadier.arguments.StringArgumentType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Taah
* @since 4:31 AM [08-07-2023]
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Argument
{
String value();
StringArgumentType.StringType argumentType() default StringArgumentType.StringType.SINGLE_WORD;
double min() default Double.MIN_VALUE;
double max() default Double.MAX_VALUE;
}

View File

@ -0,0 +1,18 @@
package dev.plex.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Taah
* @since 4:54 PM [07-07-2023]
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CommandName
{
String[] value();
}

View File

@ -0,0 +1,18 @@
package dev.plex.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Taah
* @since 4:54 PM [07-07-2023]
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CommandPermission
{
String value();
}

View File

@ -0,0 +1,19 @@
package dev.plex.command.annotation;
import dev.plex.command.source.RequiredCommandSource;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Taah
* @since 7:08 AM [09-07-2023]
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface CommandSource
{
RequiredCommandSource value() default RequiredCommandSource.ANY;
}

View File

@ -0,0 +1,17 @@
package dev.plex.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Taah
* @since 4:54 PM [07-07-2023]
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Default
{
}

View File

@ -0,0 +1,18 @@
package dev.plex.command.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Taah
* @since 4:46 PM [07-07-2023]
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SubCommand
{
String value();
}

View File

@ -29,6 +29,9 @@ import java.util.stream.Collectors;
@CommandParameters(name = "plex", usage = "/<command> [reload | redis | modules [reload]]", description = "Show information about Plex or reload it") @CommandParameters(name = "plex", usage = "/<command> [reload | redis | modules [reload]]", description = "Show information about Plex or reload it")
public class PlexCMD extends PlexCommand public class PlexCMD extends PlexCommand
{ {
public PlexCMD() {
super(false);
}
// Don't modify this command // Don't modify this command
@Override @Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args) protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, String[] args)
@ -73,14 +76,7 @@ public class PlexCMD extends PlexCommand
else if (args[0].equalsIgnoreCase("redis")) else if (args[0].equalsIgnoreCase("redis"))
{ {
checkRank(sender, Rank.SENIOR_ADMIN, "plex.redis"); checkRank(sender, Rank.SENIOR_ADMIN, "plex.redis");
if (!plugin.getRedisConnection().isEnabled())
{
throw new CommandFailException("&cRedis is not enabled.");
}
plugin.getRedisConnection().getJedis().set("test", "123");
send(sender, "Set test to 123. Now outputting key test...");
send(sender, plugin.getRedisConnection().getJedis().get("test"));
plugin.getRedisConnection().getJedis().close();
return null; return null;
} }
else if (args[0].equalsIgnoreCase("modules")) else if (args[0].equalsIgnoreCase("modules"))

View File

@ -0,0 +1,31 @@
package dev.plex.command.impl.brigadier;
import dev.plex.cache.DataUtils;
import dev.plex.command.PlexBrigadierCommand;
import dev.plex.command.annotation.CommandName;
import dev.plex.command.annotation.CommandPermission;
import dev.plex.command.annotation.CommandSource;
import dev.plex.command.annotation.Default;
import dev.plex.command.source.RequiredCommandSource;
import dev.plex.player.PlexPlayer;
import org.apache.commons.lang3.BooleanUtils;
import org.bukkit.entity.Player;
import static dev.plex.util.PlexUtils.messageComponent;
/**
* @author Taah
* @since 6:54 AM [09-07-2023]
*/
@CommandName({"adminchat", "o", "sc", "ac", "staffchat"})
public class AdminChatCMD extends PlexBrigadierCommand
{
@Default
@CommandPermission("plex.adminchat")
@CommandSource(RequiredCommandSource.IN_GAME)
public void toggle(Player sender) {
PlexPlayer player = DataUtils.getPlayer(sender.getUniqueId());
player.setStaffChat(!player.isStaffChat());
send(sender, messageComponent("adminChatToggled", BooleanUtils.toStringOnOff(player.isStaffChat())));
}
}

View File

@ -0,0 +1,90 @@
package dev.plex.command.impl.brigadier;
import com.mojang.brigadier.arguments.StringArgumentType;
import dev.plex.command.PlexBrigadierCommand;
import dev.plex.command.annotation.*;
import dev.plex.command.exception.CommandFailException;
import dev.plex.module.PlexModule;
import dev.plex.module.PlexModuleFile;
import dev.plex.util.BuildInfo;
import dev.plex.util.TimeUtils;
import org.apache.commons.lang3.StringUtils;
import org.bukkit.command.CommandSender;
import java.util.stream.Collectors;
/**
* @author Taah
* @since 3:46 PM [07-07-2023]
*/
@CommandName({"plex", "pplexx"})
public class PlexBrigadierCMD extends PlexBrigadierCommand
{
@SubCommand("reload")
@CommandPermission("plex.reload")
public void reloadPlex(CommandSender sender)
{
plugin.config.load();
send(sender, "Reloaded config file");
plugin.messages.load();
send(sender, "Reloaded messages file");
plugin.indefBans.load(false);
plugin.getPunishmentManager().mergeIndefiniteBans();
send(sender, "Reloaded indefinite bans");
plugin.commands.load();
send(sender, "Reloaded blocked commands file");
plugin.getRankManager().importDefaultRanks();
send(sender, "Imported ranks");
plugin.setSystem(plugin.config.getString("system"));
if (plugin.getSystem().equalsIgnoreCase("permissions") && !plugin.getServer().getPluginManager().isPluginEnabled("Vault"))
{
throw new RuntimeException("Vault is required to run on the server if you use permissions!");
}
plugin.getServiceManager().endServices();
plugin.getServiceManager().startServices();
send(sender, "Restarted services.");
TimeUtils.TIMEZONE = plugin.config.getString("server.timezone");
send(sender, "Set timezone to: " + TimeUtils.TIMEZONE);
send(sender, "Plex successfully reloaded.");
}
@SubCommand("redis")
@CommandPermission("plex.redis")
public void testRedis(CommandSender sender)
{
if (!plugin.getRedisConnection().isEnabled())
{
throw new CommandFailException("&cRedis is not enabled.");
}
plugin.getRedisConnection().getJedis().set("test", "123");
send(sender, "Set test to 123. Now outputting key test...");
send(sender, plugin.getRedisConnection().getJedis().get("test"));
plugin.getRedisConnection().getJedis().close();
}
@SubCommand("modules")
@CommandPermission("plex.modules")
public void viewModules(CommandSender sender)
{
send(sender, mmString("<gold>Modules (" + plugin.getModuleManager().getModules().size() + "): <yellow>" + StringUtils.join(plugin.getModuleManager().getModules().stream().map(PlexModule::getPlexModuleFile).map(PlexModuleFile::getName).collect(Collectors.toList()), ", ")));
}
@SubCommand("modules reload")
@CommandPermission("plex.modules.reload")
public void reloadModules(CommandSender sender)
{
plugin.getModuleManager().reloadModules();
send(sender, mmString("<green>All modules reloaded!"));
}
@Default
public void defaultCommand(CommandSender sender)
{
send(sender, mmString("<light_purple>Plex - A new freedom plugin."));
send(sender, mmString("<light_purple>Plugin version: <gold>" + plugin.getPluginMeta().getVersion() + " #" + BuildInfo.getNumber() + " <light_purple>Git: <gold>" + BuildInfo.getHead()));
send(sender, mmString("<light_purple>Authors: <gold>Telesphoreo, Taahh"));
send(sender, mmString("<light_purple>Built by: <gold>" + BuildInfo.getAuthor() + " <light_purple>on <gold>" + BuildInfo.getDate()));
send(sender, mmString("<light_purple>Run <gold>/plex modules <light_purple>to see a list of modules."));
plugin.getUpdateChecker().getUpdateStatusMessage(sender, true, 2);
}
}

View File

@ -5,6 +5,8 @@ import com.google.common.reflect.ClassPath;
import dev.plex.Plex; import dev.plex.Plex;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -54,4 +56,31 @@ public class ReflectionsUtil
}); });
return Collections.unmodifiableSet(classes); return Collections.unmodifiableSet(classes);
} }
public static void callVoid(Object obj, String function, Object... params) {
try
{
Method method = obj.getClass().getMethod(function, Arrays.stream(params).map(Object::getClass).toArray(Class[]::new));
method.setAccessible(true);
method.invoke(obj, params);
}
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
public static <T> T callFunction(Object obj, String function, Object... params) {
try
{
Method method = obj.getClass().getMethod(function, Arrays.stream(params).map(Object::getClass).toArray(Class[]::new));
method.setAccessible(true);
return (T) method.invoke(obj, params);
}
catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e)
{
throw new RuntimeException(e);
}
}
} }