From f781d03d75cc5faa87c890ff110a7f34cd6da090 Mon Sep 17 00:00:00 2001 From: Adrian Date: Fri, 17 Mar 2023 11:28:48 -0500 Subject: [PATCH 1/3] feat: Implement Command Abstraction --- build.gradle.kts | 2 +- debuggery-bukkit/build.gradle.kts | 2 +- .../io/zachbr/debuggery/BukkitLogger.java | 8 +- .../io/zachbr/debuggery/DebuggeryBukkit.java | 10 +- .../debuggery/commands/BlockCommand.java | 13 +- .../debuggery/commands/ChunkCommand.java | 13 +- .../debuggery/commands/DebugCommand.java | 73 ++++---- .../debuggery/commands/DebuggeryCommand.java | 19 +- .../debuggery/commands/EntityCommand.java | 29 +-- .../debuggery/commands/EventCommand.java | 27 +-- .../commands/EventRemoveCommand.java | 15 +- .../debuggery/commands/ItemCommand.java | 13 +- .../debuggery/commands/PlayerCommand.java | 13 +- .../commands/SelectEntityCommand.java | 18 +- .../debuggery/commands/ServerCommand.java | 13 +- .../debuggery/commands/WorldCommand.java | 13 +- .../base/BukkitCommandReflection.java | 39 ++++ .../bukkit/input/InventoryInputHandler.java | 28 ++- debuggery-common/build.gradle.kts | 5 + .../debuggery/commands/CommandBase.java | 82 +++++++++ .../debuggery/util/FancyExceptionWrapper.java | 4 +- debuggery-velocity/build.gradle.kts | 5 +- .../zachbr/debuggery/DebuggeryVelocity.java | 4 +- .../commands/ProxyPlayerCommand.java | 11 +- .../commands/ProxyServerCommand.java | 11 +- .../commands/ServerConnectionCommand.java | 11 +- .../commands/base/CommandReflection.java | 173 ------------------ .../base/VelocityCommandReflection.java | 39 ++++ 28 files changed, 333 insertions(+), 360 deletions(-) create mode 100644 debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java create mode 100644 debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java rename {debuggery-bukkit => debuggery-common}/src/main/java/io/zachbr/debuggery/util/FancyExceptionWrapper.java (93%) delete mode 100644 debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandReflection.java create mode 100644 debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java diff --git a/build.gradle.kts b/build.gradle.kts index 6f86ea0..88677d0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,7 @@ subprojects { withType { options.encoding = Charsets.UTF_8.name() } - withType { + processResources { filteringCharset = Charsets.UTF_8.name() } } diff --git a/debuggery-bukkit/build.gradle.kts b/debuggery-bukkit/build.gradle.kts index e87597a..fc04259 100644 --- a/debuggery-bukkit/build.gradle.kts +++ b/debuggery-bukkit/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } tasks { - withType { + processResources { filesMatching("plugin.yml") { expand("version" to project.version) } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/BukkitLogger.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/BukkitLogger.java index 45bb877..48c2dde 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/BukkitLogger.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/BukkitLogger.java @@ -17,17 +17,17 @@ package io.zachbr.debuggery; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.logger.slf4j.ComponentLogger; -import org.bukkit.command.CommandSender; import java.util.HashSet; import java.util.Set; public class BukkitLogger implements Logger { private final ComponentLogger pluginLogger; - private final Set debugListeners = new HashSet<>(); + private final Set debugListeners = new HashSet<>(); BukkitLogger(ComponentLogger logger) { this.pluginLogger = logger; @@ -57,12 +57,12 @@ public void debug(String str) { final Component colorOut = Component.text( "[DEBUG] " + str, NamedTextColor.GOLD); pluginLogger.info(colorOut); - for (CommandSender sender : debugListeners) { + for (Audience sender : debugListeners) { sender.sendMessage(colorOut); } } - public Set getDebugListeners() { + public Set getDebugListeners() { return this.debugListeners; } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java index fd5154e..ea9b0fa 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java @@ -18,7 +18,7 @@ package io.zachbr.debuggery; import io.zachbr.debuggery.commands.*; -import io.zachbr.debuggery.commands.base.CommandBase; +import io.zachbr.debuggery.commands.base.BukkitCommandBase; import io.zachbr.debuggery.reflection.types.handlers.bukkit.BukkitBootstrap; import io.zachbr.debuggery.util.EventDebugger; import org.bukkit.Bukkit; @@ -34,7 +34,7 @@ public class DebuggeryBukkit extends DebuggeryBase { @Nullable private UUID targetedEntity; private final DebuggeryJavaPlugin javaPlugin; - private final Map commands = new HashMap<>(); + private final Map commands = new HashMap<>(); DebuggeryBukkit(DebuggeryJavaPlugin plugin, Logger logger) { super(logger); @@ -67,7 +67,7 @@ private void registerCommands() { this.registerCommand(new EventCommand(this)); this.registerCommand(new EventRemoveCommand(this)); - for (CommandBase c : commands.values()) { + for (BukkitCommandBase c : commands.values()) { PluginCommand bukkitCmd = this.getJavaPlugin().getCommand(c.getName()); if (bukkitCmd == null) { throw new IllegalStateException("Unable to register " + c.getName() + ". Command not registered in plugin.yml?"); @@ -77,11 +77,11 @@ private void registerCommands() { } } - private void registerCommand(final CommandBase command) { + private void registerCommand(final BukkitCommandBase command) { this.commands.put(command.getName(), command); } - public Map getAllCommands() { + public Map getAllCommands() { return Collections.unmodifiableMap(commands); } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java index 08f356f..4db9877 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java @@ -18,23 +18,22 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; +import net.kyori.adventure.audience.Audience; import org.bukkit.block.Block; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -public class BlockCommand extends CommandReflection { +public class BlockCommand extends BukkitCommandReflection { public BlockCommand(DebuggeryBukkit debuggery) { - super("dblock", "debuggery.block", true, Block.class, debuggery); + super("dblock", "debuggery.block", true, true, Block.class, debuggery); } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; Block block = player.getTargetBlock(null, 50); - return doReflectionLookups(sender, args, block); + return getCommandReflection().doReflectionLookups(sender, args, block); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java index 46ea54f..b41a4f6 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java @@ -18,22 +18,21 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; +import net.kyori.adventure.audience.Audience; import org.bukkit.Chunk; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -public class ChunkCommand extends CommandReflection { +public class ChunkCommand extends BukkitCommandReflection { public ChunkCommand(DebuggeryBukkit debuggery) { - super("dchunk", "debuggery.chunk", true, Chunk.class, debuggery); + super("dchunk", "debuggery.chunk", true, true, Chunk.class, debuggery); } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; - return doReflectionLookups(sender, args, player.getLocation().getChunk()); + return getCommandReflection().doReflectionLookups(sender, args, player.getLocation().getChunk()); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java index da10b1f..a667e56 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java @@ -19,11 +19,11 @@ import io.zachbr.debuggery.BukkitLogger; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandBase; +import io.zachbr.debuggery.commands.base.BukkitCommandBase; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.identity.Identity; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; @@ -31,13 +31,12 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; import static net.kyori.adventure.text.Component.text; -public class DebugCommand extends CommandBase { +public class DebugCommand extends BukkitCommandBase { private final DebuggeryBukkit plugin; - private final Set debugListeners; + private final Set debugListeners; public DebugCommand(DebuggeryBukkit debuggery) { super("ddebug", "debuggery.debug", false, false); @@ -47,7 +46,7 @@ public DebugCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { // no debug mode, no debug command if (!DebuggeryBukkit.isDebugMode()) { sender.sendMessage(text("Debuggery Debug Mode is not enabled!", NamedTextColor.RED)); @@ -68,23 +67,16 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab } switch (subCommand) { - case "subscribe": - this.subOrUnsub(sender, subArgs, true); - break; - case "unsubscribe": - this.subOrUnsub(sender, subArgs, false); - break; - case "info": - this.sendSystemInfo(sender); - break; - default: - sender.sendMessage(text("Unknown sub-command", NamedTextColor.RED)); + case "subscribe" -> this.subOrUnsub(sender, subArgs, true); + case "unsubscribe" -> this.subOrUnsub(sender, subArgs, false); + case "info" -> this.sendSystemInfo(sender); + default -> sender.sendMessage(text("Unknown sub-command", NamedTextColor.RED)); } return true; } - private void subOrUnsub(CommandSender sender, String[] args, boolean add) { - CommandSender target = null; + private void subOrUnsub(Audience sender, String[] args, boolean add) { + Audience target = null; if (args.length >= 1) { Player search = Bukkit.getPlayer(args[0]); @@ -107,20 +99,21 @@ private void subOrUnsub(CommandSender sender, String[] args, boolean add) { } final boolean contains = this.debugListeners.contains(target); + final String name = target.get(Identity.NAME).orElse("UNKNOWN"); if (add) { if (contains) { - sender.sendMessage(text(target.getName() + " is already subscribed to debug messages")); + sender.sendMessage(text(name + " is already subscribed to debug messages")); } else { this.debugListeners.add(target); - sender.sendMessage(text("Subscribed " + target.getName() + " to debug messages")); + sender.sendMessage(text("Subscribed " + name + " to debug messages")); } } else { if (contains) { this.debugListeners.remove(target); - sender.sendMessage(text("Unsubscribed " + target.getName() + " to debug messages")); + sender.sendMessage(text("Unsubscribed " + name + " to debug messages")); } else { - sender.sendMessage(text(target.getName() + " is not subscribed to debug messages")); + sender.sendMessage(text(name + " is not subscribed to debug messages")); } } } @@ -130,33 +123,31 @@ private void subOrUnsub(CommandSender sender, String[] args, boolean add) { * * @param sender what to send to */ - private void sendSystemInfo(CommandSender sender) { + private void sendSystemInfo(Audience sender) { for (String line : plugin.getSystemInfo()) { sender.sendMessage(text(line, NamedTextColor.GOLD)); } } @Override - protected boolean helpLogic(CommandSender sender, String[] args) { + protected boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(text("Exposes the internal systems state of the Debuggery plugin")); return true; } @Override - protected List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args) { - switch (args.length) { - case 1: - return List.of("subscribe", "unsubscribe", "info"); - case 2: - switch (args[0].toLowerCase()) { - case "subscribe": - case "unsubscribe": - return Bukkit.getOnlinePlayers().stream().map(HumanEntity::getName).collect(Collectors.toList()); - default: - return Collections.emptyList(); - } - default: - return Collections.emptyList(); - } + protected List tabCompleteLogic(Audience sender, String[] args) { + return switch (args.length) { + case 1 -> List.of("subscribe", "unsubscribe", "info"); + case 2 -> switch (args[0].toLowerCase()) { + case "subscribe", "unsubscribe" -> + Bukkit.getOnlinePlayers() + .stream() + .map(HumanEntity::getName) + .toList(); + default -> Collections.emptyList(); + }; + default -> Collections.emptyList(); + }; } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java index 7fe4c78..f13a186 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java @@ -18,11 +18,10 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandBase; +import io.zachbr.debuggery.commands.base.BukkitCommandBase; import io.zachbr.debuggery.util.CommandUtil; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import java.util.Collections; import java.util.List; @@ -31,7 +30,7 @@ import static net.kyori.adventure.text.Component.text; -public class DebuggeryCommand extends CommandBase { +public class DebuggeryCommand extends BukkitCommandBase { private final DebuggeryBukkit debuggery; public DebuggeryCommand(DebuggeryBukkit debuggery) { @@ -40,7 +39,7 @@ public DebuggeryCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { if (args.length == 0) { sender.sendMessage(text("=== Debuggery v" + debuggery.getJavaPlugin().getDescription().getVersion() + " ===", NamedTextColor.GOLD)); sender.sendMessage(text("Debuggery is designed to expose API values at runtime.")); @@ -56,7 +55,7 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab return true; } - CommandBase target = debuggery.getAllCommands().get(arg); + BukkitCommandBase target = debuggery.getAllCommands().get(arg); return target.showHelpText(sender, args); } @@ -65,7 +64,7 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab } @Override - protected boolean helpLogic(CommandSender sender, String[] args) { + protected boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(text("Displays general information about the plugin.")); sender.sendMessage(text("Also shows more specific help for each command when entered")); sender.sendMessage(text("Try using tab completion to see all available subtopics.")); @@ -73,14 +72,14 @@ protected boolean helpLogic(CommandSender sender, String[] args) { } @Override - protected List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args) { + protected List tabCompleteLogic(Audience sender, String[] args) { if (args.length > 1) { return Collections.emptyList(); } List commands = debuggery.getAllCommands().values().stream() - .filter(CommandBase::shouldShowInHelp) - .map(CommandBase::getName) + .filter(BukkitCommandBase::shouldShowInHelp) + .map(BukkitCommandBase::getName) .collect(Collectors.toList()); return CommandUtil.getCompletionsMatching(args, commands); diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java index 76128f1..206ed83 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java @@ -18,26 +18,27 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; import io.zachbr.debuggery.util.PlatformUtil; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; import java.util.List; -public class EntityCommand extends CommandReflection { +public class EntityCommand extends BukkitCommandReflection { + private final DebuggeryBukkit plugin; public EntityCommand(DebuggeryBukkit debuggery) { - super("dentity", "debuggery.entity", true, Entity.class, debuggery); + super("dentity", "debuggery.entity", true, true, Entity.class, debuggery); + this.plugin = debuggery; } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; Entity target = this.getTarget(player); if (target == null) { @@ -45,29 +46,29 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab return true; } - return doReflectionLookups(sender, args, target); + return getCommandReflection().doReflectionLookups(sender, args, target); } @Override - public List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args) { + public List tabCompleteLogic(Audience sender, String[] args) { Entity target = this.getTarget((Player) sender); if (target == null) { - clearReflectionClass(); + getCommandReflection().clearReflectionClass(); return List.of("NOT FOUND"); } else { - updateReflectionClass(target.getClass()); + getCommandReflection().updateReflectionClass(target.getClass()); } - return super.tabCompleteLogic(sender, command, alias, args); + return super.tabCompleteLogic(sender, args); } @Nullable private Entity getTarget(Player player) { Entity entity = null; - if (this.debuggery.getTargetedEntity() != null) { - entity = Bukkit.getEntity(this.debuggery.getTargetedEntity()); + if (this.plugin.getTargetedEntity() != null) { + entity = Bukkit.getEntity(this.plugin.getTargetedEntity()); if (entity == null) { - this.debuggery.setTargetedEntity(null); + this.plugin.setTargetedEntity(null); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java index 243d457..a1c169c 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java @@ -18,26 +18,27 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.event.Event; import java.util.Arrays; import java.util.List; -public class EventCommand extends CommandReflection { +public class EventCommand extends BukkitCommandReflection { + private final DebuggeryBukkit plugin; public EventCommand(DebuggeryBukkit debuggery) { - super("devent", "debuggery.devent", true, Entity.class, debuggery); + super("devent", "debuggery.devent", true, true, Entity.class, debuggery); + this.plugin = debuggery; } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { if (args.length == 0) { return true; } @@ -46,7 +47,7 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab try { Class event = Class.forName(clazz, true, this.getClass().getClassLoader()); - updateReflectionClass(event); + getCommandReflection().updateReflectionClass(event); if (!Event.class.isAssignableFrom(event)) { sender.sendMessage(Component.text("Provided class is not an event.", NamedTextColor.RED)); return true; @@ -54,9 +55,9 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab String[] offsetArgs = Arrays.copyOfRange(args, 1, args.length); sender.sendMessage(Component.text("Added event debugger!", NamedTextColor.GREEN)); - this.debuggery.getEventDebugger().addDebugger(event, (eventInstance) -> { - this.doReflectionLookups(sender, offsetArgs, eventInstance); - }); + this.plugin.getEventDebugger().addDebugger(event, (eventInstance) -> + this.getCommandReflection().doReflectionLookups(sender, offsetArgs, eventInstance) + ); } catch (Exception e) { sender.sendMessage(Component.text("Unknown class name %s!".formatted(clazz), NamedTextColor.RED)); return true; @@ -66,13 +67,13 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab } @Override - public List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args) { + public List tabCompleteLogic(Audience sender, String[] args) { if (args.length == 0) { return List.of(); } try { Class event = Class.forName(args[0], true, this.getClass().getClassLoader()); - updateReflectionClass(event); + getCommandReflection().updateReflectionClass(event); } catch (ClassNotFoundException e) { return List.of(); } @@ -82,6 +83,6 @@ public List tabCompleteLogic(CommandSender sender, Command command, Stri return List.of(); } - return super.tabCompleteLogic(sender, command, alias, trimmed); + return super.tabCompleteLogic(sender, trimmed); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java index 0efc911..721373a 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java @@ -18,26 +18,25 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandBase; +import io.zachbr.debuggery.commands.base.BukkitCommandBase; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import java.util.ArrayList; import java.util.List; -public class EventRemoveCommand extends CommandBase { +public class EventRemoveCommand extends BukkitCommandBase { private final DebuggeryBukkit debuggery; public EventRemoveCommand(DebuggeryBukkit debuggery) { - super("deventremove", "debuggery.devent.remove", true); + super("deventremove", "debuggery.devent.remove", true, true); this.debuggery = debuggery; } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { if (args.length > 0 && args[0].equals("*")) { this.debuggery.getEventDebugger().clearAll(); sender.sendMessage(Component.text("Cleared all event debuggers!", NamedTextColor.GREEN)); @@ -59,13 +58,13 @@ protected boolean commandLogic(CommandSender sender, Command command, String lab } @Override - protected boolean helpLogic(CommandSender sender, String[] args) { + protected boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(Component.text("Clears the event debugger for the provided event.")); return true; } @Override - protected List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args) { + protected List tabCompleteLogic(Audience sender, String[] args) { List names = new ArrayList<>(); this.debuggery.getEventDebugger().getAll().forEach((clazz) -> names.add(clazz.getName())); names.add("*"); diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java index fb8b8cf..677630a 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java @@ -18,23 +18,22 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; +import net.kyori.adventure.audience.Audience; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -public class ItemCommand extends CommandReflection { +public class ItemCommand extends BukkitCommandReflection { public ItemCommand(DebuggeryBukkit debuggery) { - super("ditem", "debuggery.item", true, ItemStack.class, debuggery); + super("ditem", "debuggery.item", true, true, ItemStack.class, debuggery); } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; ItemStack itemStack = player.getInventory().getItemInMainHand(); - return doReflectionLookups(sender, args, itemStack); + return getCommandReflection().doReflectionLookups(sender, args, itemStack); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java index 53f22bd..a0d46a6 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java @@ -18,21 +18,20 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; +import net.kyori.adventure.audience.Audience; import org.bukkit.entity.Player; -public class PlayerCommand extends CommandReflection { +public class PlayerCommand extends BukkitCommandReflection { public PlayerCommand(DebuggeryBukkit debuggery) { - super("dplayer", "debuggery.player", true, Player.class, debuggery); + super("dplayer", "debuggery.player", true, true, Player.class, debuggery); } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; - return doReflectionLookups(sender, args, player); + return getCommandReflection().doReflectionLookups(sender, args, player); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java index 9000d47..47181be 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java @@ -18,32 +18,28 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandBase; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.BukkitCommandBase; import io.zachbr.debuggery.util.PlatformUtil; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import java.util.List; -import static net.kyori.adventure.text.Component.text; - -public class SelectEntityCommand extends CommandBase { +public class SelectEntityCommand extends BukkitCommandBase { private final DebuggeryBukkit debuggery; public SelectEntityCommand(DebuggeryBukkit debuggery) { - super("dentityselect", "debuggery.entity.select", true); + super("dentityselect", "debuggery.entity.select", true, true); this.debuggery = debuggery; } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { if (args.length > 0 && args[0].equals("unselect")) { this.debuggery.setTargetedEntity(null); sender.sendMessage(Component.text("Unselected entity!", NamedTextColor.GREEN)); @@ -72,13 +68,13 @@ public void run() { } @Override - protected boolean helpLogic(CommandSender sender, String[] args) { + protected boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(Component.text("Look at an entity to select that entity for further /dentity actions.")); return true; } @Override - protected List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args) { + protected List tabCompleteLogic(Audience sender, String[] args) { return List.of("unselect"); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java index 91b3d3d..141aa53 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java @@ -18,20 +18,19 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; +import net.kyori.adventure.audience.Audience; import org.bukkit.Bukkit; import org.bukkit.Server; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -public class ServerCommand extends CommandReflection { +public class ServerCommand extends BukkitCommandReflection { public ServerCommand(DebuggeryBukkit debuggery) { - super("dserver", "debuggery.server", false, Server.class, debuggery); + super("dserver", "debuggery.server", false, true, Server.class, debuggery); } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { - return doReflectionLookups(sender, args, Bukkit.getServer()); + protected boolean commandLogic(Audience sender, String[] args) { + return getCommandReflection().doReflectionLookups(sender, args, Bukkit.getServer()); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java index e0b901c..85845f7 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java @@ -18,22 +18,21 @@ package io.zachbr.debuggery.commands; import io.zachbr.debuggery.DebuggeryBukkit; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.BukkitCommandReflection; +import net.kyori.adventure.audience.Audience; import org.bukkit.World; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -public class WorldCommand extends CommandReflection { +public class WorldCommand extends BukkitCommandReflection { public WorldCommand(DebuggeryBukkit debuggery) { - super("dworld", "debuggery.world", true, World.class, debuggery); + super("dworld", "debuggery.world", true, true, World.class, debuggery); } @Override - protected boolean commandLogic(CommandSender sender, Command command, String label, String[] args) { + protected boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; - return doReflectionLookups(sender, args, player.getWorld()); + return getCommandReflection().doReflectionLookups(sender, args, player.getWorld()); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java new file mode 100644 index 0000000..375efe8 --- /dev/null +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java @@ -0,0 +1,39 @@ +package io.zachbr.debuggery.commands.base; + +import io.zachbr.debuggery.DebuggeryBukkit; +import io.zachbr.debuggery.commands.CommandReflection; +import io.zachbr.debuggery.reflection.MethodMap; +import io.zachbr.debuggery.util.CommandUtil; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; + +import java.util.Arrays; +import java.util.List; + +public abstract class BukkitCommandReflection extends BukkitCommandBase { + private final CommandReflection commandReflection; + + protected BukkitCommandReflection(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp, Class clazz, DebuggeryBukkit plugin) { + super(name, permission, requiresPlayer, shouldShowInHelp); + this.commandReflection = new CommandReflection(clazz, plugin); + } + + @Override + protected boolean helpLogic(Audience sender, String[] args) { + sender.sendMessage(Component.text("Uses reflection to call API methods built into Bukkit.")); + sender.sendMessage(Component.text("Try using the tab completion to see all available subcommands.")); + return true; + } + + @Override + public List tabCompleteLogic(Audience sender, String[] args) { + List arguments = Arrays.asList(args); + MethodMap reflectionMap = this.getCommandReflection().getAvailableMethods(); + + return CommandUtil.getReflectiveCompletions(arguments, reflectionMap, this.commandReflection.getMapCache()); + } + + public CommandReflection getCommandReflection() { + return commandReflection; + } +} diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/reflection/types/handlers/bukkit/input/InventoryInputHandler.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/reflection/types/handlers/bukkit/input/InventoryInputHandler.java index 4b1b169..1365dc7 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/reflection/types/handlers/bukkit/input/InventoryInputHandler.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/reflection/types/handlers/bukkit/input/InventoryInputHandler.java @@ -29,29 +29,25 @@ public class InventoryInputHandler implements InputHandler { @Override public @NotNull Inventory instantiateInstance(String input, Class clazz, @Nullable PlatformSender sender) throws Exception { - if (sender == null || !(sender.getRawSender() instanceof Player)) { + if (sender == null || !(sender.getRawSender() instanceof Player player)) { throw new UnsupportedOperationException("Inventory input handler is only supported when used by a player!"); } - Player player = (Player) sender.getRawSender(); - switch (input.toLowerCase()) { - case "player": - return player.getInventory(); - case "ender": - return player.getEnderChest(); - case "new": - return Bukkit.createInventory(player, 27); - case "block": - Block block = player.getTargetBlock(25); + return switch (input.toLowerCase()) { + case "player" -> player.getInventory(); + case "ender" -> player.getEnderChest(); + case "new" -> Bukkit.createInventory(player, 27); + case "block" -> { + Block block = player.getTargetBlockExact(25); BlockState state = block != null ? block.getState() : null; if (state instanceof Container) { - return ((Container) block.getState(false)).getInventory(); + yield ((Container) block.getState(false)).getInventory(); } - throw new IllegalArgumentException("Block does not exist or is not a container type!"); - } - - throw new IllegalArgumentException("Unknown inventory argument, allowed: \"player\", \"ender\", \"new\", \"block\""); + } + default -> + throw new IllegalArgumentException("Unknown inventory argument, allowed: \"player\", \"ender\", \"new\", \"block\""); + }; } @Override diff --git a/debuggery-common/build.gradle.kts b/debuggery-common/build.gradle.kts index 22d8550..4e6875f 100644 --- a/debuggery-common/build.gradle.kts +++ b/debuggery-common/build.gradle.kts @@ -2,6 +2,11 @@ plugins { id("net.kyori.blossom") } +dependencies { + compileOnly("net.kyori:adventure-api:4.13.0") + compileOnly("net.kyori:adventure-text-minimessage:4.13.0") +} + configurations.register("testArchive") { extendsFrom(configurations.testCompileOnly.get()) } diff --git a/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java b/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java new file mode 100644 index 0000000..301163f --- /dev/null +++ b/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java @@ -0,0 +1,82 @@ +package io.zachbr.debuggery.commands; + +import net.kyori.adventure.audience.Audience; + +import java.util.List; + +public abstract class CommandBase { + private final String name; + private final String permission; + private final boolean requiresPlayer; + private final boolean shouldShowInHelp; + protected CommandBase(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp) { + this.name = name; + this.permission = permission; + this.requiresPlayer = requiresPlayer; + this.shouldShowInHelp = shouldShowInHelp; + } + + /** + * Gets the name of this command + * This is also used for registration + * + * @return command name + */ + public String getName() { + return name; + } + + /** + * Gets the permission required to execute this command + * + * @return permission + */ + public String getPermission() { + return permission; + } + + /** + * Gets if this command requires a player + * + * @return if command requires a player + */ + public boolean isRequiresPlayer() { + return requiresPlayer; + } + + /** + * Gets if this command should show in the plugin help directory + * + * @return if command should show in help + */ + public boolean shouldShowInHelp() { + return shouldShowInHelp; + } + + /** + * Used by classes to implement their tab completion logic + * + * @param sender {@link Audience} responsible for sending the message + * @param args arguments for the given command + * @return whether the command was successfully handled + */ + protected abstract List tabCompleteLogic(Audience sender, String [] args); + + /** + * Used by classes to implement their primary command logic + * + * @param sender {@link Audience} responsible for sending the message + * @param args arguments for the given command + * @return whether the command was successfully handled + */ + protected abstract boolean commandLogic(Audience sender, String[] args); + + /** + * Called whenever someone uses the /debuggery command with a specific command topic + * + * @param sender {@link Audience} responsible for sending the message + * @param args arguments for the given command + * @return whether the command was successfully handled + */ + protected abstract boolean helpLogic(Audience sender, String[] args); +} diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/util/FancyExceptionWrapper.java b/debuggery-common/src/main/java/io/zachbr/debuggery/util/FancyExceptionWrapper.java similarity index 93% rename from debuggery-bukkit/src/main/java/io/zachbr/debuggery/util/FancyExceptionWrapper.java rename to debuggery-common/src/main/java/io/zachbr/debuggery/util/FancyExceptionWrapper.java index a85046c..e520023 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/util/FancyExceptionWrapper.java +++ b/debuggery-common/src/main/java/io/zachbr/debuggery/util/FancyExceptionWrapper.java @@ -17,9 +17,9 @@ package io.zachbr.debuggery.util; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.io.PrintWriter; @@ -39,7 +39,7 @@ public class FancyExceptionWrapper { * @param errorMessage message displayed in chat * @param throwable throwable to format and display on hover */ - public static void sendFancyChatException(CommandSender sender, String errorMessage, Throwable throwable) { + public static void sendFancyChatException(Audience sender, String errorMessage, Throwable throwable) { Component fancyException = formatException(errorMessage, throwable); sender.sendMessage(fancyException); } diff --git a/debuggery-velocity/build.gradle.kts b/debuggery-velocity/build.gradle.kts index 85f5523..a1ffa8e 100644 --- a/debuggery-velocity/build.gradle.kts +++ b/debuggery-velocity/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("com.github.johnrengelman.shadow") + id("xyz.jpenilla.run-velocity") version "2.0.0" } tasks { @@ -15,6 +16,6 @@ tasks { dependencies { implementation(project(":debuggery-common")) - compileOnly("com.velocitypowered:velocity-api:3.1.0") - annotationProcessor("com.velocitypowered:velocity-api:3.1.0") + compileOnly("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT") + annotationProcessor("com.velocitypowered:velocity-api:3.2.0-SNAPSHOT") } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java index 4009e4d..2c4062d 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java @@ -23,7 +23,7 @@ import io.zachbr.debuggery.commands.ProxyPlayerCommand; import io.zachbr.debuggery.commands.ProxyServerCommand; import io.zachbr.debuggery.commands.ServerConnectionCommand; -import io.zachbr.debuggery.commands.base.CommandBase; +import io.zachbr.debuggery.commands.base.VelocityCommandBase; @Plugin(id = "debuggery", name = "Debuggery", @@ -63,7 +63,7 @@ public ProxyServer getProxyServer() { return this.server; } - private void registerCommand(CommandBase base) { + private void registerCommand(VelocityCommandBase base) { this.server.getCommandManager().register(base.getName(), base); } } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java index dc82c28..8b735e2 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java @@ -17,20 +17,21 @@ package io.zachbr.debuggery.commands; -import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.Player; import io.zachbr.debuggery.DebuggeryVelocity; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.VelocityCommandReflection; +import net.kyori.adventure.audience.Audience; import org.jetbrains.annotations.NotNull; -public class ProxyPlayerCommand extends CommandReflection { +public class ProxyPlayerCommand extends VelocityCommandReflection { public ProxyPlayerCommand(DebuggeryVelocity plugin) { super("vplayer", "debuggery.vplayer", true, Player.class, plugin); } @Override - protected void commandLogic(@NotNull CommandSource source, @NotNull String[] args) { - doReflectionLookups(source, args, source); + protected boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { + commandReflection().doReflectionLookups(source, args, source); + return true; } } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java index af417c6..567810c 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java @@ -17,13 +17,13 @@ package io.zachbr.debuggery.commands; -import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.ProxyServer; import io.zachbr.debuggery.DebuggeryVelocity; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.VelocityCommandReflection; +import net.kyori.adventure.audience.Audience; import org.jetbrains.annotations.NotNull; -public class ProxyServerCommand extends CommandReflection { +public class ProxyServerCommand extends VelocityCommandReflection { private final DebuggeryVelocity debuggery; public ProxyServerCommand(DebuggeryVelocity plugin) { @@ -32,7 +32,8 @@ public ProxyServerCommand(DebuggeryVelocity plugin) { } @Override - protected void commandLogic(@NotNull CommandSource source, @NotNull String[] args) { - doReflectionLookups(source, args, debuggery.getProxyServer()); + protected boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { + commandReflection().doReflectionLookups(source, args, debuggery.getProxyServer()); + return true; } } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java index f55f4af..0a21aa9 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java @@ -17,26 +17,27 @@ package io.zachbr.debuggery.commands; -import com.velocitypowered.api.command.CommandSource; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ServerConnection; import io.zachbr.debuggery.DebuggeryVelocity; -import io.zachbr.debuggery.commands.base.CommandReflection; +import io.zachbr.debuggery.commands.base.VelocityCommandReflection; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.jetbrains.annotations.NotNull; -public class ServerConnectionCommand extends CommandReflection { +public class ServerConnectionCommand extends VelocityCommandReflection { public ServerConnectionCommand(DebuggeryVelocity plugin) { super("vconnection", "debuggery.vconnection", true, ServerConnection.class, plugin); } @Override - protected void commandLogic(@NotNull CommandSource source, @NotNull String[] args) { + protected boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { Player player = (Player) source; player.getCurrentServer().ifPresentOrElse( - it -> doReflectionLookups(source, args, it), + it -> commandReflection().doReflectionLookups(source, args, it), () -> source.sendMessage(Component.text("Not connected to a server!", NamedTextColor.RED))); + return true; } } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandReflection.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandReflection.java deleted file mode 100644 index cd8ff39..0000000 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandReflection.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of Debuggery. - * - * Debuggery is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Debuggery 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Debuggery. If not, see . - */ - -package io.zachbr.debuggery.commands.base; - -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.proxy.Player; -import io.zachbr.debuggery.DebuggeryVelocity; -import io.zachbr.debuggery.reflection.MethodMap; -import io.zachbr.debuggery.reflection.MethodMapProvider; -import io.zachbr.debuggery.reflection.chain.ReflectionResult; -import io.zachbr.debuggery.reflection.types.InputException; -import io.zachbr.debuggery.reflection.types.handlers.base.platform.PlatformSender; -import io.zachbr.debuggery.util.CommandUtil; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.HoverEvent; -import net.kyori.adventure.text.format.NamedTextColor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -// todo - Really really refactor to -common, this was just a few changes - -/** - * Base class for all commands that use reflection to dig into Velocity's API - */ -public abstract class CommandReflection extends CommandBase { - private final DebuggeryVelocity debuggery; - private final MethodMapProvider mapCache; - private MethodMap availableMethods = MethodMap.EMPTY; - - protected CommandReflection(String name, String permission, boolean requiresPlayer, Class clazz, DebuggeryVelocity plugin) { - super(name, permission, requiresPlayer); - this.debuggery = plugin; - this.mapCache = plugin.getMethodMapProvider(); - updateReflectionClass(clazz); - } - - @Override - protected void helpLogic(@NotNull CommandSource sender, @NotNull String[] args) { - sender.sendMessage(Component.text("Uses reflection to call API methods built into Bukkit.")); - sender.sendMessage(Component.text("Try using the tab completion to see all available subcommands.")); - } - - @Override - public List tabCompleteLogic(@NotNull CommandSource sender, @NotNull String[] args) { - List arguments = Arrays.asList(args); - MethodMap reflectionMap = this.availableMethods; - - return CommandUtil.getReflectiveCompletions(arguments, reflectionMap, mapCache); - } - - /** - * Handles all the reflection based command logic - * - * @param sender sender to send information to - * @param args command arguments - * @param instance instance of the class type - * @return true if handled successfully - */ - protected boolean doReflectionLookups(@NotNull CommandSource sender, @NotNull String[] args, Object instance) { - // 0 args just return info on object itself - if (args.length == 0) { - String result = getOutputStringFor(instance); - if (result != null) { - sender.sendMessage(Component.text(result)); - } - return true; - } - - // more than 0 args, start chains - Class activeClass = availableMethods.getMappedClass(); - if (!activeClass.isInstance(instance)) { - throw new IllegalArgumentException("Instance is of type: " + instance.getClass().getSimpleName() + "but was expecting: " + activeClass.getSimpleName()); - } - - final String inputMethod = args[0]; - if (!availableMethods.containsId(inputMethod)) { - sender.sendMessage(Component.text("Unknown or unavailable method").color(NamedTextColor.RED)); - return true; - } - - PlatformSender platformSender = new PlatformSender<>(sender); - ReflectionResult chainResult = debuggery.runReflectionChain(args, instance, platformSender); - switch (chainResult.getType()) { - case SUCCESS -> notifySenderOfSuccess(sender, chainResult); - case INPUT_ERROR, UNHANDLED_EXCEPTION -> notifySenderOfException(sender, chainResult); - case NULL_REFERENCE, UNKNOWN_REFERENCE, ARG_MISMATCH -> notifySenderOfResultReason(sender, chainResult); - default -> throw new IllegalArgumentException("Unhandled switch case for result of type: " + chainResult.getType()); - } - - return true; - } - - private void notifySenderOfException(@NotNull CommandSource sender, @NotNull ReflectionResult chainResult) { - Throwable ex = chainResult.getException(); - Objects.requireNonNull(ex); - - String errorMessage = ex instanceof InputException ? "Exception deducing proper types from your input!" : "Exception invoking method - See console for more details!"; - Throwable cause = ex.getCause() == null ? ex : ex.getCause(); - - if (sender instanceof Player) { - sendFancyChatException(sender, errorMessage, cause); - } else { - sender.sendMessage(Component.text(errorMessage).color(NamedTextColor.RED)); - } - - cause.printStackTrace(); - } - - private void notifySenderOfResultReason(CommandSource sender, ReflectionResult chainResult) { - Objects.requireNonNull(chainResult.getReason()); - sender.sendMessage(Component.text(chainResult.getReason())); - } - - private void notifySenderOfSuccess(CommandSource sender, ReflectionResult chainResult) { - String output = getOutputStringFor(chainResult.getEndingInstance()); - if (output != null) { - sender.sendMessage(Component.text(output)); - } - } - - /** - * Updates the locally cached reflection class - * - * @param typeIn class type to cache a reflection map for - */ - protected void updateReflectionClass(Class typeIn) { - if (availableMethods.getMappedClass() != typeIn) { - availableMethods = mapCache.getMethodMapFor(typeIn); - } - } - - /** - * Convenience method to run objects past the TypeHandler - * - * @param object Object to get String output for - * @return textual description of Object - */ - protected @Nullable String getOutputStringFor(@Nullable Object object) { - return debuggery.getTypeHandler().getOutputFor(object); - } - - private void sendFancyChatException(@NotNull CommandSource source, @NotNull String msg, @NotNull Throwable throwable) { - final StringWriter writer = new StringWriter(); - throwable.printStackTrace(new PrintWriter(writer)); - - Component component = Component.text(msg) - .color(NamedTextColor.RED) - .hoverEvent(HoverEvent.showText(Component.text(writer.toString().replaceAll("\t", " ").replaceAll("\r", "")))); - - source.sendMessage(component); - } -} diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java new file mode 100644 index 0000000..3f70264 --- /dev/null +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java @@ -0,0 +1,39 @@ +package io.zachbr.debuggery.commands.base; + +import io.zachbr.debuggery.DebuggeryVelocity; +import io.zachbr.debuggery.commands.CommandReflection; +import io.zachbr.debuggery.reflection.MethodMap; +import io.zachbr.debuggery.util.CommandUtil; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class VelocityCommandReflection extends VelocityCommandBase { + private final CommandReflection commandReflection; + protected VelocityCommandReflection(String name, String permNode, boolean requiresPlayer, Class clazz, DebuggeryVelocity plugin) { + super(name, permNode, requiresPlayer); + this.commandReflection = new CommandReflection(clazz, plugin); + } + + @Override + protected boolean helpLogic(@NotNull Audience sender, @NotNull String[] args) { + super.helpLogic(sender, args); + sender.sendMessage(Component.text("Uses reflection to call API methods built into Velocity.")); + sender.sendMessage(Component.text("Try using the tab completion to see all available subcommands.")); + return true; + } + + @Override + public List tabCompleteLogic(@NotNull Audience sender, @NotNull String[] args) { + List arguments = List.of(args); + MethodMap reflectionMap = this.commandReflection().getAvailableMethods(); + + return CommandUtil.getReflectiveCompletions(arguments, reflectionMap, commandReflection().getMapCache()); + } + + protected CommandReflection commandReflection() { + return this.commandReflection; + } +} From 97148a7c804253eab1caf2ca18b908cca490fe1d Mon Sep 17 00:00:00 2001 From: Adrian Date: Fri, 17 Mar 2023 11:32:56 -0500 Subject: [PATCH 2/3] added missing changes --- .../commands/base/BukkitCommandBase.java | 97 ++++++++++ .../debuggery/commands/base/CommandBase.java | 174 ------------------ .../commands}/CommandReflection.java | 113 ++++-------- .../debuggery/commands/base/CommandBase.java | 117 ------------ .../commands/base/VelocityCommandBase.java | 58 ++++++ 5 files changed, 192 insertions(+), 367 deletions(-) create mode 100644 debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java delete mode 100644 debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java rename {debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base => debuggery-common/src/main/java/io/zachbr/debuggery/commands}/CommandReflection.java (57%) delete mode 100644 debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java create mode 100644 debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java new file mode 100644 index 0000000..8fb806f --- /dev/null +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java @@ -0,0 +1,97 @@ +/* + * This file is part of Debuggery. + * + * Debuggery is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Debuggery 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Debuggery. If not, see . + */ + +package io.zachbr.debuggery.commands.base; + +import io.zachbr.debuggery.commands.CommandBase; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.permission.PermissionChecker; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +/** + * Class to handle all the stupid minutia involved with commands + */ +public abstract class BukkitCommandBase extends CommandBase implements CommandExecutor, TabCompleter { + private static final Component NO_PERMS_MSG = Component.text("You do not have permission to do that!", NamedTextColor.RED) ; + private static final Component PLAYER_USE_ONLY_MSG = Component.text("This command can only be used by players!", NamedTextColor.RED); + + protected BukkitCommandBase(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp) { + super(name, permission, requiresPlayer, shouldShowInHelp); + } + + /** + * This is the normal Bukkit command function, intercepted here so that we don't have to deal the same + * repetitive garbage over and over. + */ + @Override + public final boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (!sender.hasPermission(this.getPermission())) { + sender.sendMessage(NO_PERMS_MSG); + return true; + } + + if (this.isRequiresPlayer() && !(sender instanceof Player)) { + sender.sendMessage(PLAYER_USE_ONLY_MSG); + return true; + } + + return this.commandLogic(sender, args); + } + + /** + * Shows help text for this command + * + * @param sender {@link CommandSender} responsible for sending the message + * @param args arguments for the given command + * @return whether the command was successfully handled + */ + public final boolean showHelpText(Audience sender, String[] args) { + if (!sender.get(PermissionChecker.POINTER).map(checker -> checker.test(this.getPermission())).orElse(false)) { + sender.sendMessage(NO_PERMS_MSG); + return true; + } + + sender.sendMessage( + Component.text("==== ") + .append(Component.text(this.getName(), NamedTextColor.GOLD)) + .append(Component.text(" ====")) + ); + return this.helpLogic(sender, args); + } + + @Override + public final List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { + if (!sender.hasPermission(this.getPermission())) { + sender.sendMessage(NO_PERMS_MSG); + return Collections.emptyList(); + } + + if (this.isRequiresPlayer() && !(sender instanceof Player)) { + sender.sendMessage(PLAYER_USE_ONLY_MSG); + return Collections.emptyList(); + } + + return this.tabCompleteLogic(sender, args); + } +} diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java deleted file mode 100644 index 6785013..0000000 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of Debuggery. - * - * Debuggery is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Debuggery 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Debuggery. If not, see . - */ - -package io.zachbr.debuggery.commands.base; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.*; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.Collections; -import java.util.List; - -/** - * Class to handle all the stupid minutia involved with commands - */ -public abstract class CommandBase implements CommandExecutor, TabCompleter { - private static final Component NO_PERMS_MSG = Component.text("You do not have permission to do that!", NamedTextColor.RED) ; - private static final Component PLAYER_USE_ONLY_MSG = Component.text("This command can only be used by players!", NamedTextColor.RED); - - private final String name; - private final String permission; - private final boolean requiresPlayer; - private final boolean shouldShowInHelp; - - protected CommandBase(String name, String permission, boolean requiresPlayer) { - this(name, permission, requiresPlayer, true); - } - - protected CommandBase(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp) { - this.name = name; - this.permission = permission; - this.requiresPlayer = requiresPlayer; - this.shouldShowInHelp = shouldShowInHelp; - } - - /** - * This is the normal Bukkit command function, intercepted here so that we don't have to deal the same - * repetitive garbage over and over. - */ - @Override - public final boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (!sender.hasPermission(this.permission)) { - sender.sendMessage(NO_PERMS_MSG); - return true; - } - - if (this.requiresPlayer && !(sender instanceof Player)) { - sender.sendMessage(PLAYER_USE_ONLY_MSG); - return true; - } - - return this.commandLogic(sender, command, label, args); - } - - /** - * Shows help text for this command - * - * @param sender {@link CommandSender} responsible for sending the message - * @param args arguments for the given command - * @return whether the command was successfully handled - */ - public final boolean showHelpText(CommandSender sender, String[] args) { - if (!sender.hasPermission(this.permission)) { - sender.sendMessage(NO_PERMS_MSG); - return true; - } - - sender.sendMessage( - Component.text("==== ") - .append(Component.text(this.getName(), NamedTextColor.GOLD)) - .append(Component.text(" ====")) - ); - return this.helpLogic(sender, args); - } - - @Override - public final List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - if (!sender.hasPermission(this.permission)) { - sender.sendMessage(NO_PERMS_MSG); - return Collections.emptyList(); - } - - if (this.requiresPlayer && !(sender instanceof Player)) { - sender.sendMessage(PLAYER_USE_ONLY_MSG); - return Collections.emptyList(); - } - - return this.tabCompleteLogic(sender, command, alias, args); - } - - /** - * Used by classes to implement their primary command logic - * - * @param sender {@link CommandSender} responsible for sending the message - * @param command Relevant {@link Command} being used - * @param label Command label in use - * @param args arguments for the given command - * @return whether the command was successfully handled - */ - protected abstract boolean commandLogic(CommandSender sender, Command command, String label, String[] args); - - /** - * Called whenever someone uses the /debuggery command with a specific command topic - * - * @param sender {@link CommandSender} responsible for sending the message - * @param args arguments for the given command - * @return whether the command was successfully handled - */ - protected abstract boolean helpLogic(CommandSender sender, String[] args); - - /** - * Used by classes to implement their tab completion logic - * - * @param sender {@link CommandSender} responsible for sending the message - * @param command Relevant {@link Command} being used - * @param alias Command alias in use - * @param args arguments for the given command - * @return whether the command was successfully handled - */ - protected abstract List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args); - - /** - * Gets the name of this command - * This is also used for registration - * - * @return command name - */ - public final String getName() { - return this.name; - } - - /** - * Gets the permission required to execute this command - * - * @return permission - */ - public final String getPermission() { - return this.permission; - } - - /** - * Gets if this command requires a player - * - * @return if command requires a player - */ - public final boolean getRequiresPlayer() { - return this.requiresPlayer; - } - - /** - * Gets if this command should show in the plugin help directory - * - * @return if command should show in help - */ - public final boolean shouldShowInHelp() { - return this.shouldShowInHelp; - } -} diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/CommandReflection.java b/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandReflection.java similarity index 57% rename from debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/CommandReflection.java rename to debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandReflection.java index ca82795..306ec2e 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/CommandReflection.java +++ b/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandReflection.java @@ -1,68 +1,33 @@ -/* - * This file is part of Debuggery. - * - * Debuggery is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Debuggery 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Debuggery. If not, see . - */ - -package io.zachbr.debuggery.commands.base; - -import io.zachbr.debuggery.DebuggeryBukkit; +package io.zachbr.debuggery.commands; + +import io.zachbr.debuggery.DebuggeryBase; import io.zachbr.debuggery.reflection.MethodMap; import io.zachbr.debuggery.reflection.MethodMapProvider; import io.zachbr.debuggery.reflection.chain.ReflectionResult; import io.zachbr.debuggery.reflection.types.InputException; import io.zachbr.debuggery.reflection.types.handlers.base.platform.PlatformSender; -import io.zachbr.debuggery.util.CommandUtil; import io.zachbr.debuggery.util.FancyExceptionWrapper; +import net.kyori.adventure.audience.Audience; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.regex.Pattern; - -/** - * Base class for all commands that use reflection to dig into Bukkit's API - */ -public abstract class CommandReflection extends CommandBase { - - // Splits by spaces unless in quotes: This[split]is[split]an[split]example ~ "This is"[split]an[split]example - private static final Pattern UNQUOTED_SPLIT = Pattern.compile(" +(?=(?:(?:[^\"]*\"){2})*[^\"]*$)"); - protected final DebuggeryBukkit debuggery; +public final class CommandReflection { + private final DebuggeryBase debuggery; private final MethodMapProvider mapCache; private MethodMap availableMethods = MethodMap.EMPTY; - protected CommandReflection(String name, String permission, boolean requiresPlayer, Class clazz, DebuggeryBukkit plugin) { - super(name, permission, requiresPlayer); + public CommandReflection(Class clazz, DebuggeryBase plugin) { this.debuggery = plugin; this.mapCache = plugin.getMethodMapProvider(); updateReflectionClass(clazz); } - @Override - protected boolean helpLogic(CommandSender sender, String[] args) { - sender.sendMessage(Component.text("Uses reflection to call API methods built into Bukkit.")); - sender.sendMessage(Component.text("Try using the tab completion to see all available subcommands.")); - return true; - } - /** * Handles all the reflection based command logic * @@ -71,31 +36,28 @@ protected boolean helpLogic(CommandSender sender, String[] args) { * @param instance instance of the class type * @return true if handled successfully */ - protected boolean doReflectionLookups(CommandSender sender, String[] args, Object instance) { + public boolean doReflectionLookups(@NotNull Audience sender, @NotNull String[] args, Object instance) { // 0 args just return info on object itself - if (args.length == 0) { - final String out = getOutputStringFor(instance); - if (out != null) { - sender.sendMessage(out); + String result = getOutputStringFor(instance); + if (result != null) { + sender.sendMessage(Component.text(result)); } - return true; } - { - // Combine quoted elements - args = parse(String.join(" ", args)); - } + // Combine quoted elements + args = parse(String.join(" ", args)); + // more than 0 args, start chains Class activeClass = availableMethods.getMappedClass(); if (!activeClass.isInstance(instance)) { throw new IllegalArgumentException("Instance is of type: " + instance.getClass().getSimpleName() + "but was expecting: " + activeClass.getSimpleName()); } - final String inputMethod = args[0]; + final String inputMethod = args[0]; if (!availableMethods.containsId(inputMethod)) { - sender.sendMessage(Component.text("Unknown or unavailable method", NamedTextColor.RED)); + sender.sendMessage(Component.text("Unknown or unavailable method").color(NamedTextColor.RED)); return true; } @@ -105,14 +67,13 @@ protected boolean doReflectionLookups(CommandSender sender, String[] args, Objec case SUCCESS -> notifySenderOfSuccess(sender, chainResult); case INPUT_ERROR, UNHANDLED_EXCEPTION -> notifySenderOfException(sender, chainResult); case NULL_REFERENCE, UNKNOWN_REFERENCE, ARG_MISMATCH -> notifySenderOfResultReason(sender, chainResult); - default -> - throw new IllegalArgumentException("Unhandled switch case for result of type: " + chainResult.getType()); + default -> throw new IllegalArgumentException("Unhandled switch case for result of type: " + chainResult.getType()); } return true; } - private void notifySenderOfException(CommandSender sender, ReflectionResult chainResult) { + private void notifySenderOfException(@NotNull Audience sender, @NotNull ReflectionResult chainResult) { Throwable ex = chainResult.getException(); Objects.requireNonNull(ex); @@ -124,15 +85,15 @@ private void notifySenderOfException(CommandSender sender, ReflectionResult chai cause.printStackTrace(); } - private void notifySenderOfResultReason(CommandSender sender, ReflectionResult chainResult) { + private void notifySenderOfResultReason(Audience sender, ReflectionResult chainResult) { Objects.requireNonNull(chainResult.getReason()); - sender.sendMessage(Component.text(chainResult.getReason(), NamedTextColor.RED)); + sender.sendMessage(Component.text(chainResult.getReason())); } - private void notifySenderOfSuccess(CommandSender sender, ReflectionResult chainResult) { + private void notifySenderOfSuccess(Audience sender, ReflectionResult chainResult) { String output = getOutputStringFor(chainResult.getEndingInstance()); if (output != null) { - sender.sendMessage(output); + sender.sendMessage(Component.text(output)); } } @@ -141,34 +102,22 @@ private void notifySenderOfSuccess(CommandSender sender, ReflectionResult chainR * * @param typeIn class type to cache a reflection map for */ - protected void updateReflectionClass(Class typeIn) { + public void updateReflectionClass(Class typeIn) { if (availableMethods.getMappedClass() != typeIn) { availableMethods = mapCache.getMethodMapFor(typeIn); } } - protected void clearReflectionClass() { - this.availableMethods = MethodMap.EMPTY; - } - /** * Convenience method to run objects past the TypeHandler * * @param object Object to get String output for * @return textual description of Object */ - protected @Nullable String getOutputStringFor(@Nullable Object object) { + public @Nullable String getOutputStringFor(@Nullable Object object) { return debuggery.getTypeHandler().getOutputFor(object); } - @Override - public List tabCompleteLogic(CommandSender sender, Command command, String alias, String[] args) { - List arguments = Arrays.asList(args); - MethodMap reflectionMap = this.availableMethods; - - return CommandUtil.getReflectiveCompletions(arguments, reflectionMap, mapCache); - } - private static String[] parse(String input) { List arguments = new ArrayList<>(); StringBuilder currentArgument = new StringBuilder(); @@ -193,4 +142,16 @@ private static String[] parse(String input) { return arguments.toArray(new String[0]); } + + public MethodMap getAvailableMethods() { + return availableMethods; + } + + public MethodMapProvider getMapCache() { + return mapCache; + } + + public void clearReflectionClass() { + this.availableMethods = MethodMap.EMPTY; + } } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java deleted file mode 100644 index e640285..0000000 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/CommandBase.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This file is part of Debuggery. - * - * Debuggery is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Debuggery 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Debuggery. If not, see . - */ - -package io.zachbr.debuggery.commands.base; - -import com.velocitypowered.api.command.CommandSource; -import com.velocitypowered.api.command.SimpleCommand; -import com.velocitypowered.api.proxy.Player; -import net.kyori.adventure.text.Component; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -// todo - this should be made more abstract at some point and merged into -common, it's mostly a copy pasta of bukkit's for now -public abstract class CommandBase implements SimpleCommand { - private final String name; - private final String permNode; - private final boolean requiresPlayer; - private final boolean shouldShowInHelp; - - protected CommandBase(String name, String permNode, boolean requiresPlayer) { - this(name, permNode, requiresPlayer, true); - } - - protected CommandBase(String name, String permNode, boolean requiresPlayer, boolean shouldShowInHelp) { - this.name = name; - this.permNode = permNode; - this.requiresPlayer = requiresPlayer; - this.shouldShowInHelp = shouldShowInHelp; - } - - @Override - public void execute(final Invocation invocation) { - commandLogic(invocation.source(), invocation.arguments()); - } - - @Override - public List suggest(final Invocation invocation) { - return tabCompleteLogic(invocation.source(), invocation.arguments()); - } - - /** - * Shows help text for this command - * - * @param source {@link CommandSource} responsible for sending the message - * @param args arguments for the given command - */ - public final void showHelpText(CommandSource source, @NotNull String[] args) { - source.sendMessage(Component.text("==== /" + this.name + " ====")); - this.helpLogic(source, args); - } - - protected abstract void commandLogic(@NotNull CommandSource source, @NotNull String[] args); - - protected abstract void helpLogic(@NotNull CommandSource source, @NotNull String[] args); - - protected abstract List tabCompleteLogic(@NotNull CommandSource source, @NotNull String[] args); - - @Override - public boolean hasPermission(final Invocation invocation) { - if (this.requiresPlayer && !(invocation.source() instanceof Player)) { - return false; - } - return invocation.source().hasPermission(this.permNode); - } - - /** - * Gets the name of this command - * This is also used for registration - * - * @return command name - */ - public final String getName() { - return this.name; - } - - /** - * Gets the permission required to execute this command - * - * @return permission - */ - public final String getPermission() { - return this.permNode; - } - - /** - * Gets if this command requires a player - * - * @return if command requires a player - */ - public final boolean getRequiresPlayer() { - return this.requiresPlayer; - } - - /** - * Gets if this command should show in the plugin help directory - * - * @return if command should show in help - */ - public final boolean shouldShowInHelp() { - return this.shouldShowInHelp; - } -} diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java new file mode 100644 index 0000000..c0c8db7 --- /dev/null +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java @@ -0,0 +1,58 @@ +/* + * This file is part of Debuggery. + * + * Debuggery is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Debuggery 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Debuggery. If not, see . + */ + +package io.zachbr.debuggery.commands.base; + +import com.velocitypowered.api.command.SimpleCommand; +import com.velocitypowered.api.proxy.Player; +import io.zachbr.debuggery.commands.CommandBase; +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public abstract class VelocityCommandBase extends CommandBase implements SimpleCommand { + + protected VelocityCommandBase(String name, String permNode, boolean requiresPlayer) { + super(name, permNode, requiresPlayer, true); + } + + @Override + public void execute(final Invocation invocation) { + commandLogic(invocation.source(), invocation.arguments()); + } + + @Override + public List suggest(final Invocation invocation) { + return tabCompleteLogic(invocation.source(), invocation.arguments()); + } + + @Override + protected boolean helpLogic(Audience source, @NotNull String[] args) { + source.sendMessage(Component.text("==== /" + this.getName() + " ====")); + return true; + } + + @Override + public boolean hasPermission(final Invocation invocation) { + if (this.isRequiresPlayer() && !(invocation.source() instanceof Player)) { + return false; + } + return invocation.source().hasPermission(this.getPermission()); + } +} From 96ac236eb79db2ef601806c148f26279c72a8c44 Mon Sep 17 00:00:00 2001 From: Adrian Date: Mon, 31 Jul 2023 19:29:43 -0500 Subject: [PATCH 3/3] Update to Paper plugins --- debuggery-bukkit/build.gradle.kts | 6 +- .../io/zachbr/debuggery/DebuggeryBukkit.java | 10 +--- .../debuggery/commands/BlockCommand.java | 2 +- .../debuggery/commands/ChunkCommand.java | 2 +- .../debuggery/commands/DebugCommand.java | 8 +-- .../debuggery/commands/DebuggeryCommand.java | 12 ++-- .../debuggery/commands/EntityCommand.java | 2 +- .../debuggery/commands/EventCommand.java | 2 +- .../commands/EventRemoveCommand.java | 8 +-- .../debuggery/commands/ItemCommand.java | 2 +- .../debuggery/commands/PlayerCommand.java | 2 +- .../commands/SelectEntityCommand.java | 8 +-- .../debuggery/commands/ServerCommand.java | 2 +- .../debuggery/commands/WorldCommand.java | 4 +- .../commands/base/BukkitCommandBase.java | 58 +++++++++++-------- .../base/BukkitCommandReflection.java | 4 +- .../src/main/resources/paper-plugin.yml | 7 +++ .../src/main/resources/plugin.yml | 44 -------------- debuggery-common/build.gradle.kts | 4 +- .../io/zachbr/debuggery/DebuggeryBase.java | 20 +++---- .../debuggery/commands/CommandBase.java | 34 +++-------- debuggery-velocity/build.gradle.kts | 2 +- .../zachbr/debuggery/DebuggeryVelocity.java | 9 ++- .../commands/ProxyPlayerCommand.java | 4 +- .../commands/ProxyServerCommand.java | 4 +- .../commands/ServerConnectionCommand.java | 4 +- .../commands/base/VelocityCommandBase.java | 31 +++++++++- .../base/VelocityCommandReflection.java | 2 +- 28 files changed, 138 insertions(+), 159 deletions(-) create mode 100644 debuggery-bukkit/src/main/resources/paper-plugin.yml delete mode 100644 debuggery-bukkit/src/main/resources/plugin.yml diff --git a/debuggery-bukkit/build.gradle.kts b/debuggery-bukkit/build.gradle.kts index fafcb20..c0ddd94 100644 --- a/debuggery-bukkit/build.gradle.kts +++ b/debuggery-bukkit/build.gradle.kts @@ -20,13 +20,13 @@ tasks { } runServer { - minecraftVersion("1.19.4") + minecraftVersion("1.20.1") } } dependencies { implementation(project(":debuggery-common")) - compileOnly("io.papermc.paper:paper-api:1.19.4-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT") testImplementation(project(path = ":debuggery-common", configuration = "testArchive")) - testImplementation("io.papermc.paper:paper-api:1.19.4-R0.1-SNAPSHOT") + testImplementation("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT") } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java index ea9b0fa..ffab33b 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/DebuggeryBukkit.java @@ -22,7 +22,6 @@ import io.zachbr.debuggery.reflection.types.handlers.bukkit.BukkitBootstrap; import io.zachbr.debuggery.util.EventDebugger; import org.bukkit.Bukkit; -import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.Nullable; @@ -68,12 +67,7 @@ private void registerCommands() { this.registerCommand(new EventRemoveCommand(this)); for (BukkitCommandBase c : commands.values()) { - PluginCommand bukkitCmd = this.getJavaPlugin().getCommand(c.getName()); - if (bukkitCmd == null) { - throw new IllegalStateException("Unable to register " + c.getName() + ". Command not registered in plugin.yml?"); - } - - bukkitCmd.setExecutor(c); + this.getJavaPlugin().getServer().getCommandMap().register(c.getName(), c); } } @@ -104,7 +98,7 @@ public EventDebugger getEventDebugger() { @Override String getPluginVersion() { - return javaPlugin.getDescription().getVersion(); + return javaPlugin.getPluginMeta().getVersion(); } @Override diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java index 4db9877..4675235 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/BlockCommand.java @@ -30,7 +30,7 @@ public BlockCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; Block block = player.getTargetBlock(null, 50); diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java index b41a4f6..55cd8af 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ChunkCommand.java @@ -30,7 +30,7 @@ public ChunkCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; return getCommandReflection().doReflectionLookups(sender, args, player.getLocation().getChunk()); diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java index a667e56..456c337 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebugCommand.java @@ -39,14 +39,14 @@ public class DebugCommand extends BukkitCommandBase { private final Set debugListeners; public DebugCommand(DebuggeryBukkit debuggery) { - super("ddebug", "debuggery.debug", false, false); + super("ddebug", "debuggery.debug", false, false, debuggery.getJavaPlugin()); this.plugin = debuggery; this.debugListeners = ((BukkitLogger) debuggery.getLogger()).getDebugListeners(); } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { // no debug mode, no debug command if (!DebuggeryBukkit.isDebugMode()) { sender.sendMessage(text("Debuggery Debug Mode is not enabled!", NamedTextColor.RED)); @@ -130,13 +130,13 @@ private void sendSystemInfo(Audience sender) { } @Override - protected boolean helpLogic(Audience sender, String[] args) { + public boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(text("Exposes the internal systems state of the Debuggery plugin")); return true; } @Override - protected List tabCompleteLogic(Audience sender, String[] args) { + public List tabCompleteLogic(Audience sender, String[] args) { return switch (args.length) { case 1 -> List.of("subscribe", "unsubscribe", "info"); case 2 -> switch (args[0].toLowerCase()) { diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java index f13a186..a227e38 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/DebuggeryCommand.java @@ -34,17 +34,17 @@ public class DebuggeryCommand extends BukkitCommandBase { private final DebuggeryBukkit debuggery; public DebuggeryCommand(DebuggeryBukkit debuggery) { - super("debuggery", "debuggery.debuggery", false, false); + super("debuggery", "debuggery.debuggery", false, false, debuggery.getJavaPlugin()); this.debuggery = debuggery; } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { if (args.length == 0) { - sender.sendMessage(text("=== Debuggery v" + debuggery.getJavaPlugin().getDescription().getVersion() + " ===", NamedTextColor.GOLD)); + sender.sendMessage(text("=== Debuggery v" + debuggery.getJavaPlugin().getPluginMeta().getVersion() + " ===", NamedTextColor.GOLD)); sender.sendMessage(text("Debuggery is designed to expose API values at runtime.")); sender.sendMessage(text("To see what commands are available and any help associated with them, use tab completion on this command.")); - sender.sendMessage(text("Source code can be found here: ").append(text(debuggery.getJavaPlugin().getDescription().getWebsite(), NamedTextColor.BLUE))); + sender.sendMessage(text("Source code can be found here: ").append(text(debuggery.getJavaPlugin().getPluginMeta().getWebsite(), NamedTextColor.BLUE))); return true; } @@ -64,7 +64,7 @@ protected boolean commandLogic(Audience sender, String[] args) { } @Override - protected boolean helpLogic(Audience sender, String[] args) { + public boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(text("Displays general information about the plugin.")); sender.sendMessage(text("Also shows more specific help for each command when entered")); sender.sendMessage(text("Try using tab completion to see all available subtopics.")); @@ -72,7 +72,7 @@ protected boolean helpLogic(Audience sender, String[] args) { } @Override - protected List tabCompleteLogic(Audience sender, String[] args) { + public List tabCompleteLogic(Audience sender, String[] args) { if (args.length > 1) { return Collections.emptyList(); } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java index 206ed83..7f3a966 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EntityCommand.java @@ -38,7 +38,7 @@ public EntityCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; Entity target = this.getTarget(player); if (target == null) { diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java index a1c169c..344de2e 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventCommand.java @@ -38,7 +38,7 @@ public EventCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { if (args.length == 0) { return true; } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java index 721373a..723238a 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/EventRemoveCommand.java @@ -31,12 +31,12 @@ public class EventRemoveCommand extends BukkitCommandBase { private final DebuggeryBukkit debuggery; public EventRemoveCommand(DebuggeryBukkit debuggery) { - super("deventremove", "debuggery.devent.remove", true, true); + super("deventremove", "debuggery.devent.remove", true, true, debuggery.getJavaPlugin()); this.debuggery = debuggery; } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { if (args.length > 0 && args[0].equals("*")) { this.debuggery.getEventDebugger().clearAll(); sender.sendMessage(Component.text("Cleared all event debuggers!", NamedTextColor.GREEN)); @@ -58,13 +58,13 @@ protected boolean commandLogic(Audience sender, String[] args) { } @Override - protected boolean helpLogic(Audience sender, String[] args) { + public boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(Component.text("Clears the event debugger for the provided event.")); return true; } @Override - protected List tabCompleteLogic(Audience sender, String[] args) { + public List tabCompleteLogic(Audience sender, String[] args) { List names = new ArrayList<>(); this.debuggery.getEventDebugger().getAll().forEach((clazz) -> names.add(clazz.getName())); names.add("*"); diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java index 677630a..c340815 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ItemCommand.java @@ -30,7 +30,7 @@ public ItemCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; ItemStack itemStack = player.getInventory().getItemInMainHand(); diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java index a0d46a6..50ef6c1 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/PlayerCommand.java @@ -29,7 +29,7 @@ public PlayerCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { Player player = (Player) sender; return getCommandReflection().doReflectionLookups(sender, args, player); diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java index 47181be..ad7b367 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/SelectEntityCommand.java @@ -34,12 +34,12 @@ public class SelectEntityCommand extends BukkitCommandBase { private final DebuggeryBukkit debuggery; public SelectEntityCommand(DebuggeryBukkit debuggery) { - super("dentityselect", "debuggery.entity.select", true, true); + super("dentityselect", "debuggery.entity.select", true, true, debuggery.getJavaPlugin()); this.debuggery = debuggery; } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { if (args.length > 0 && args[0].equals("unselect")) { this.debuggery.setTargetedEntity(null); sender.sendMessage(Component.text("Unselected entity!", NamedTextColor.GREEN)); @@ -68,13 +68,13 @@ public void run() { } @Override - protected boolean helpLogic(Audience sender, String[] args) { + public boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(Component.text("Look at an entity to select that entity for further /dentity actions.")); return true; } @Override - protected List tabCompleteLogic(Audience sender, String[] args) { + public List tabCompleteLogic(Audience sender, String[] args) { return List.of("unselect"); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java index 141aa53..00ba2ef 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/ServerCommand.java @@ -30,7 +30,7 @@ public ServerCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { + public boolean commandLogic(Audience sender, String[] args) { return getCommandReflection().doReflectionLookups(sender, args, Bukkit.getServer()); } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java index 85845f7..a7938b5 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/WorldCommand.java @@ -30,8 +30,8 @@ public WorldCommand(DebuggeryBukkit debuggery) { } @Override - protected boolean commandLogic(Audience sender, String[] args) { - Player player = (Player) sender; + public boolean commandLogic(Audience sender, String[] args) { + final Player player = (Player) sender; return getCommandReflection().doReflectionLookups(sender, args, player.getWorld()); } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java index 8fb806f..31301f9 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandBase.java @@ -19,12 +19,15 @@ import io.zachbr.debuggery.commands.CommandBase; import net.kyori.adventure.audience.Audience; -import net.kyori.adventure.permission.PermissionChecker; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Location; import org.bukkit.command.*; import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; @@ -32,12 +35,19 @@ /** * Class to handle all the stupid minutia involved with commands */ -public abstract class BukkitCommandBase extends CommandBase implements CommandExecutor, TabCompleter { - private static final Component NO_PERMS_MSG = Component.text("You do not have permission to do that!", NamedTextColor.RED) ; +public abstract class BukkitCommandBase extends Command implements CommandBase, PluginIdentifiableCommand { private static final Component PLAYER_USE_ONLY_MSG = Component.text("This command can only be used by players!", NamedTextColor.RED); - protected BukkitCommandBase(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp) { - super(name, permission, requiresPlayer, shouldShowInHelp); + private final boolean requiresPlayer; + private final boolean shouldShowInHelp; + private final JavaPlugin plugin; + + protected BukkitCommandBase(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp, JavaPlugin plugin) { + super(name); + this.setPermission(permission); + this.requiresPlayer = requiresPlayer; + this.shouldShowInHelp = shouldShowInHelp; + this.plugin = plugin; } /** @@ -45,12 +55,7 @@ protected BukkitCommandBase(String name, String permission, boolean requiresPlay * repetitive garbage over and over. */ @Override - public final boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (!sender.hasPermission(this.getPermission())) { - sender.sendMessage(NO_PERMS_MSG); - return true; - } - + public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) { if (this.isRequiresPlayer() && !(sender instanceof Player)) { sender.sendMessage(PLAYER_USE_ONLY_MSG); return true; @@ -66,12 +71,7 @@ public final boolean onCommand(@NotNull CommandSender sender, @NotNull Command c * @param args arguments for the given command * @return whether the command was successfully handled */ - public final boolean showHelpText(Audience sender, String[] args) { - if (!sender.get(PermissionChecker.POINTER).map(checker -> checker.test(this.getPermission())).orElse(false)) { - sender.sendMessage(NO_PERMS_MSG); - return true; - } - + public final boolean showHelpText(final Audience sender, final String[] args) { sender.sendMessage( Component.text("==== ") .append(Component.text(this.getName(), NamedTextColor.GOLD)) @@ -80,13 +80,10 @@ public final boolean showHelpText(Audience sender, String[] args) { return this.helpLogic(sender, args); } - @Override - public final List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - if (!sender.hasPermission(this.getPermission())) { - sender.sendMessage(NO_PERMS_MSG); - return Collections.emptyList(); - } + + @Override + public final @NotNull List tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args, @Nullable Location location) { if (this.isRequiresPlayer() && !(sender instanceof Player)) { sender.sendMessage(PLAYER_USE_ONLY_MSG); return Collections.emptyList(); @@ -94,4 +91,19 @@ public final List onTabComplete(@NotNull CommandSender sender, @NotNull return this.tabCompleteLogic(sender, args); } + + @Override + public boolean isRequiresPlayer() { + return this.requiresPlayer; + } + + @Override + public boolean shouldShowInHelp() { + return this.shouldShowInHelp; + } + + @Override + public @NotNull Plugin getPlugin() { + return this.plugin; + } } diff --git a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java index 375efe8..115f577 100644 --- a/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java +++ b/debuggery-bukkit/src/main/java/io/zachbr/debuggery/commands/base/BukkitCommandReflection.java @@ -14,12 +14,12 @@ public abstract class BukkitCommandReflection extends BukkitCommandBase { private final CommandReflection commandReflection; protected BukkitCommandReflection(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp, Class clazz, DebuggeryBukkit plugin) { - super(name, permission, requiresPlayer, shouldShowInHelp); + super(name, permission, requiresPlayer, shouldShowInHelp, plugin.getJavaPlugin()); this.commandReflection = new CommandReflection(clazz, plugin); } @Override - protected boolean helpLogic(Audience sender, String[] args) { + public boolean helpLogic(Audience sender, String[] args) { sender.sendMessage(Component.text("Uses reflection to call API methods built into Bukkit.")); sender.sendMessage(Component.text("Try using the tab completion to see all available subcommands.")); return true; diff --git a/debuggery-bukkit/src/main/resources/paper-plugin.yml b/debuggery-bukkit/src/main/resources/paper-plugin.yml new file mode 100644 index 0000000..6a51489 --- /dev/null +++ b/debuggery-bukkit/src/main/resources/paper-plugin.yml @@ -0,0 +1,7 @@ +name: Debuggery +main: io.zachbr.debuggery.DebuggeryJavaPlugin +version: ${version} +api-version: '1.19' +authors: [Z750, kennytv, Owen1212055] +website: https://github.com/PaperMC/Debuggery +description: A small plugin designed to expose API values at runtime. diff --git a/debuggery-bukkit/src/main/resources/plugin.yml b/debuggery-bukkit/src/main/resources/plugin.yml deleted file mode 100644 index a3c2d63..0000000 --- a/debuggery-bukkit/src/main/resources/plugin.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Debuggery -main: io.zachbr.debuggery.DebuggeryJavaPlugin -version: ${version} -api-version: 1.19 -authors: [Z750, kennytv, Owen1212055] -website: https://github.com/PaperMC/Debuggery -description: A small plugin designed to expose API values at runtime. -commands: - debuggery: - description: Debuggery! - usage: /debuggery - dblock: - description: Returns block info - usage: /dblock - dchunk: - description: Returns chunk info - usage: /dchunk - ddebug: - description: Returns internal system info - usage: /ddebug - dentity: - description: Returns entity info - usage: /dentity - dentityselect: - description: Selects the target entity - usage: /dentityselect - ditem: - description: Returns item info - usage: /ditem - dplayer: - description: Returns player info - usage: /dplayer - dserver: - description: Returns server info - usage: /dserver - dworld: - description: Returns world info - usage: /dworld - deventremove: - description: Removes event debugger - usage: /deventremove <*|class> - devent: - description: Adds a new event debugger - usage: /devent \ No newline at end of file diff --git a/debuggery-common/build.gradle.kts b/debuggery-common/build.gradle.kts index 4e6875f..7128291 100644 --- a/debuggery-common/build.gradle.kts +++ b/debuggery-common/build.gradle.kts @@ -3,8 +3,8 @@ plugins { } dependencies { - compileOnly("net.kyori:adventure-api:4.13.0") - compileOnly("net.kyori:adventure-text-minimessage:4.13.0") + compileOnly("net.kyori:adventure-api:4.14.0") + compileOnly("net.kyori:adventure-text-minimessage:4.14.0") } configurations.register("testArchive") { diff --git a/debuggery-common/src/main/java/io/zachbr/debuggery/DebuggeryBase.java b/debuggery-common/src/main/java/io/zachbr/debuggery/DebuggeryBase.java index c78e667..8bbc20b 100644 --- a/debuggery-common/src/main/java/io/zachbr/debuggery/DebuggeryBase.java +++ b/debuggery-common/src/main/java/io/zachbr/debuggery/DebuggeryBase.java @@ -61,17 +61,15 @@ public static boolean isDebugMode() { * @return system information */ public @NotNull String[] getSystemInfo() { - List out = new ArrayList<>(); - - out.add("Debuggery Ver: " + getPluginVersion()); - out.add("Server Impl: " + getPlatformName()); - out.add("Server Ver: " + getPlatformVersion()); - out.add("Java Runtime: " + System.getProperty("java.vendor") + " " + System.getProperty("java.runtime.version")); - out.add("Operating System: " + System.getProperty("os.name") + " " - + System.getProperty("os.version") + " " - + "(" + System.getProperty("os.arch") + ")"); - - return out.toArray(new String[0]); + return new String[] { + "Debuggery Ver: " + getPluginVersion(), + "Server Impl: " + getPlatformName(), + "Server Ver: " + getPlatformVersion(), + "Java Runtime: " + System.getProperty("java.vendor") + " " + System.getProperty("java.runtime.version"), + "Operating System: " + System.getProperty("os.name") + " " + + System.getProperty("os.version") + " " + + "(" + System.getProperty("os.arch") + ")" + }; } public final void printSystemInfo() { diff --git a/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java b/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java index 301163f..a7204fd 100644 --- a/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java +++ b/debuggery-common/src/main/java/io/zachbr/debuggery/commands/CommandBase.java @@ -4,17 +4,7 @@ import java.util.List; -public abstract class CommandBase { - private final String name; - private final String permission; - private final boolean requiresPlayer; - private final boolean shouldShowInHelp; - protected CommandBase(String name, String permission, boolean requiresPlayer, boolean shouldShowInHelp) { - this.name = name; - this.permission = permission; - this.requiresPlayer = requiresPlayer; - this.shouldShowInHelp = shouldShowInHelp; - } +public interface CommandBase { /** * Gets the name of this command @@ -22,36 +12,28 @@ protected CommandBase(String name, String permission, boolean requiresPlayer, bo * * @return command name */ - public String getName() { - return name; - } + String getName(); /** * Gets the permission required to execute this command * * @return permission */ - public String getPermission() { - return permission; - } + String getPermission(); /** * Gets if this command requires a player * * @return if command requires a player */ - public boolean isRequiresPlayer() { - return requiresPlayer; - } + boolean isRequiresPlayer(); /** * Gets if this command should show in the plugin help directory * * @return if command should show in help */ - public boolean shouldShowInHelp() { - return shouldShowInHelp; - } + boolean shouldShowInHelp(); /** * Used by classes to implement their tab completion logic @@ -60,7 +42,7 @@ public boolean shouldShowInHelp() { * @param args arguments for the given command * @return whether the command was successfully handled */ - protected abstract List tabCompleteLogic(Audience sender, String [] args); + List tabCompleteLogic(Audience sender, String [] args); /** * Used by classes to implement their primary command logic @@ -69,7 +51,7 @@ public boolean shouldShowInHelp() { * @param args arguments for the given command * @return whether the command was successfully handled */ - protected abstract boolean commandLogic(Audience sender, String[] args); + boolean commandLogic(Audience sender, String[] args); /** * Called whenever someone uses the /debuggery command with a specific command topic @@ -78,5 +60,5 @@ public boolean shouldShowInHelp() { * @param args arguments for the given command * @return whether the command was successfully handled */ - protected abstract boolean helpLogic(Audience sender, String[] args); + boolean helpLogic(Audience sender, String[] args); } diff --git a/debuggery-velocity/build.gradle.kts b/debuggery-velocity/build.gradle.kts index a1ffa8e..4bf693f 100644 --- a/debuggery-velocity/build.gradle.kts +++ b/debuggery-velocity/build.gradle.kts @@ -1,6 +1,6 @@ plugins { id("com.github.johnrengelman.shadow") - id("xyz.jpenilla.run-velocity") version "2.0.0" + id("xyz.jpenilla.run-velocity") version "2.1.0" } tasks { diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java index 2c4062d..77c923b 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/DebuggeryVelocity.java @@ -18,6 +18,7 @@ package io.zachbr.debuggery; import com.google.inject.Inject; +import com.velocitypowered.api.command.CommandMeta; import com.velocitypowered.api.plugin.Plugin; import com.velocitypowered.api.proxy.ProxyServer; import io.zachbr.debuggery.commands.ProxyPlayerCommand; @@ -31,7 +32,7 @@ description = "A small plugin designed to expose API values at runtime.", authors = {"Z750", "kennytv"}, url = "https://github.com/PaperMC/Debuggery") -public class DebuggeryVelocity extends DebuggeryBase { +public final class DebuggeryVelocity extends DebuggeryBase { private final ProxyServer server; @Inject @@ -64,6 +65,10 @@ public ProxyServer getProxyServer() { } private void registerCommand(VelocityCommandBase base) { - this.server.getCommandManager().register(base.getName(), base); + final CommandMeta commandMeta = this.server.getCommandManager() + .metaBuilder(base.getName()) + .plugin(this) + .build(); + this.server.getCommandManager().register(commandMeta, base); } } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java index 8b735e2..8a92719 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyPlayerCommand.java @@ -23,14 +23,14 @@ import net.kyori.adventure.audience.Audience; import org.jetbrains.annotations.NotNull; -public class ProxyPlayerCommand extends VelocityCommandReflection { +public final class ProxyPlayerCommand extends VelocityCommandReflection { public ProxyPlayerCommand(DebuggeryVelocity plugin) { super("vplayer", "debuggery.vplayer", true, Player.class, plugin); } @Override - protected boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { + public boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { commandReflection().doReflectionLookups(source, args, source); return true; } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java index 567810c..db2d19c 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ProxyServerCommand.java @@ -23,7 +23,7 @@ import net.kyori.adventure.audience.Audience; import org.jetbrains.annotations.NotNull; -public class ProxyServerCommand extends VelocityCommandReflection { +public final class ProxyServerCommand extends VelocityCommandReflection { private final DebuggeryVelocity debuggery; public ProxyServerCommand(DebuggeryVelocity plugin) { @@ -32,7 +32,7 @@ public ProxyServerCommand(DebuggeryVelocity plugin) { } @Override - protected boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { + public boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { commandReflection().doReflectionLookups(source, args, debuggery.getProxyServer()); return true; } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java index 0a21aa9..f086e59 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/ServerConnectionCommand.java @@ -26,14 +26,14 @@ import net.kyori.adventure.text.format.NamedTextColor; import org.jetbrains.annotations.NotNull; -public class ServerConnectionCommand extends VelocityCommandReflection { +public final class ServerConnectionCommand extends VelocityCommandReflection { public ServerConnectionCommand(DebuggeryVelocity plugin) { super("vconnection", "debuggery.vconnection", true, ServerConnection.class, plugin); } @Override - protected boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { + public boolean commandLogic(@NotNull Audience source, @NotNull String[] args) { Player player = (Player) source; player.getCurrentServer().ifPresentOrElse( it -> commandReflection().doReflectionLookups(source, args, it), diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java index c0c8db7..6b1e72d 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandBase.java @@ -26,10 +26,15 @@ import java.util.List; -public abstract class VelocityCommandBase extends CommandBase implements SimpleCommand { +public abstract class VelocityCommandBase implements CommandBase, SimpleCommand { + private final String name; + private final String permission; + private final boolean requiresPlayer; protected VelocityCommandBase(String name, String permNode, boolean requiresPlayer) { - super(name, permNode, requiresPlayer, true); + this.name = name; + this.permission = permNode; + this.requiresPlayer = requiresPlayer; } @Override @@ -43,7 +48,7 @@ public List suggest(final Invocation invocation) { } @Override - protected boolean helpLogic(Audience source, @NotNull String[] args) { + public boolean helpLogic(Audience source, @NotNull String[] args) { source.sendMessage(Component.text("==== /" + this.getName() + " ====")); return true; } @@ -55,4 +60,24 @@ public boolean hasPermission(final Invocation invocation) { } return invocation.source().hasPermission(this.getPermission()); } + + @Override + public String getName() { + return this.name; + } + + @Override + public String getPermission() { + return this.permission; + } + + @Override + public boolean isRequiresPlayer() { + return this.requiresPlayer; + } + + @Override + public boolean shouldShowInHelp() { + return true; + } } diff --git a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java index 3f70264..f41846f 100644 --- a/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java +++ b/debuggery-velocity/src/main/java/io/zachbr/debuggery/commands/base/VelocityCommandReflection.java @@ -18,7 +18,7 @@ protected VelocityCommandReflection(String name, String permNode, boolean requir } @Override - protected boolean helpLogic(@NotNull Audience sender, @NotNull String[] args) { + public boolean helpLogic(@NotNull Audience sender, @NotNull String[] args) { super.helpLogic(sender, args); sender.sendMessage(Component.text("Uses reflection to call API methods built into Velocity.")); sender.sendMessage(Component.text("Try using the tab completion to see all available subcommands."));