Adjusted Command Processing

Completion annotations have been moved to top level, from per method, for a much clearer understanding of how the annotation should be used.
This commit is contained in:
Paul Reilly 2023-07-23 02:15:12 -05:00
parent 2b12f4eebb
commit 6842cb2792
16 changed files with 71 additions and 66 deletions

View File

@ -37,6 +37,9 @@ import org.jetbrains.annotations.NotNull;
@Info(name = "cage", description = "Cage a player.", @Info(name = "cage", description = "Cage a player.",
usage = "/cage <player> <on|off> [material]") usage = "/cage <player> <on|off> [material]")
@Permissive(perm = "datura.cage") @Permissive(perm = "datura.cage")
@Completion(args = {"%player%"}, index = 0)
@Completion(args = {"on", "off"}, index = 1)
@Completion(args = {"[material]"}, index = 2)
public class CageCommand extends Commander public class CageCommand extends Commander
{ {
protected CageCommand(final @NotNull JavaPlugin plugin) protected CageCommand(final @NotNull JavaPlugin plugin)
@ -44,8 +47,6 @@ public class CageCommand extends Commander
super(plugin); super(plugin);
} }
@Completion(args = {"%player%"}, index = 0)
@Completion(args = {"on", "off"}, index = 1)
@Subcommand(permission = "datura.cage", args = {Player.class, String.class}) @Subcommand(permission = "datura.cage", args = {Player.class, String.class})
public void cagePlayer(final CommandSender sender, final Player player, final String string) public void cagePlayer(final CommandSender sender, final Player player, final String string)
{ {
@ -62,7 +63,6 @@ public class CageCommand extends Commander
} }
} }
@Completion(args = {"[material]"}, index = 2)
@Subcommand(permission = "datura.cage.custom", args = {Player.class, String.class, Material.class}) @Subcommand(permission = "datura.cage.custom", args = {Player.class, String.class, Material.class})
public void cagePlayer(final CommandSender sender, final Player player, final String string, public void cagePlayer(final CommandSender sender, final Player player, final String string,
final Material material) final Material material)

View File

@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
@Info(name = "cleardrops", description = "Clears all item drops in the world" + ".", usage = "/<command>", aliases = @Info(name = "cleardrops", description = "Clears all item drops in the world" + ".", usage = "/<command>", aliases =
{"cd", "clearitems", "ci", "wipeitems", "wi", "removedrops", "rd"}) {"cd", "clearitems", "ci", "wipeitems", "wi", "removedrops", "rd"})
@Permissive(perm = "datura.cleardrops") @Permissive(perm = "datura.cleardrops")
@Completion(index = 0, args = {"%world%"})
public class ClearDropsCommand extends Commander public class ClearDropsCommand extends Commander
{ {
/** /**
@ -70,7 +71,6 @@ public class ClearDropsCommand extends Commander
} }
@Subcommand(permission = "datura.cleardrops", args = {World.class}) @Subcommand(permission = "datura.cleardrops", args = {World.class})
@Completion(index = 0, args = {"%world%"})
public void clearDrops(final CommandSender sender, final World world) public void clearDrops(final CommandSender sender, final World world)
{ {
Patchwork.getInstance() Patchwork.getInstance()

View File

@ -17,6 +17,7 @@ import org.jetbrains.annotations.NotNull;
@Info(name = "clearentities", description = "Clears all entities in the world.", usage = "/<command> [world]", @Info(name = "clearentities", description = "Clears all entities in the world.", usage = "/<command> [world]",
aliases = {"ew", "ce", "entitywipe", "entityclear", "ec"}) aliases = {"ew", "ce", "entitywipe", "entityclear", "ec"})
@Permissive(perm = "datura.clearentities") @Permissive(perm = "datura.clearentities")
@Completion(index = 0, args = {"%world%"})
public class ClearEntitiesCommand extends Commander public class ClearEntitiesCommand extends Commander
{ {
/** /**
@ -57,7 +58,6 @@ public class ClearEntitiesCommand extends Commander
} }
@Subcommand(permission = "datura.clearentities", args = {World.class}) @Subcommand(permission = "datura.clearentities", args = {World.class})
@Completion(index = 0, args = {"%world%"})
public void clearEntities(final CommandSender sender, final World world) public void clearEntities(final CommandSender sender, final World world)
{ {
int i = 0; int i = 0;

View File

@ -17,6 +17,8 @@ import org.jetbrains.annotations.NotNull;
@Info(name = "halt", description = "Halt a single player, or every player.", usage = "/<command> <player | all> <on, off>") @Info(name = "halt", description = "Halt a single player, or every player.", usage = "/<command> <player | all> <on, off>")
@Permissive(perm = "datura.halt") @Permissive(perm = "datura.halt")
@Completion(index = 0, args = {"%player%", "all"})
@Completion(index = 1, args = {"on", "off"})
public class HaltCommand extends Commander public class HaltCommand extends Commander
{ {
private final Datura plugin = Shortcuts.provideModule(Datura.class); private final Datura plugin = Shortcuts.provideModule(Datura.class);
@ -35,9 +37,6 @@ public class HaltCommand extends Commander
super(plugin); super(plugin);
} }
@Completion(index = 0, args = {"%player%", "all"})
@Completion(index = 1, args = {"on", "off"})
@Subcommand(permission = "datura.halt", args = {Player.class, String.class}) @Subcommand(permission = "datura.halt", args = {Player.class, String.class})
public void haltPlayer(final CommandSender sender, final Player target, final String toggle) public void haltPlayer(final CommandSender sender, final Player target, final String toggle)
{ {
@ -58,7 +57,6 @@ public class HaltCommand extends Commander
} }
} }
// No completion needed here since it's already registered.
@Subcommand(permission = "datura.halt.all", args = {String.class, String.class}) @Subcommand(permission = "datura.halt.all", args = {String.class, String.class})
public void haltAll(final CommandSender sender, final String all, final String toggle) public void haltAll(final CommandSender sender, final String all, final String toggle)
{ {

View File

@ -13,6 +13,8 @@ import org.jetbrains.annotations.NotNull;
@Info(name = "locker", description = "Lock a player, preventing them from interacting with their game client.", @Info(name = "locker", description = "Lock a player, preventing them from interacting with their game client.",
usage = "/locker <player> <on|off>", aliases = {"lock", "lockup"}) usage = "/locker <player> <on|off>", aliases = {"lock", "lockup"})
@Permissive(perm = "datura.locker") @Permissive(perm = "datura.locker")
@Completion(args = {"%player%"}, index = 0)
@Completion(args = {"on", "off"}, index = 1)
public final class LockerCommand extends Commander public final class LockerCommand extends Commander
{ {
public LockerCommand(final @NotNull Datura plugin) public LockerCommand(final @NotNull Datura plugin)
@ -20,8 +22,6 @@ public final class LockerCommand extends Commander
super(plugin); super(plugin);
} }
@Completion(args = {"%player%"}, index = 0)
@Completion(args = {"on", "off"}, index = 1)
@Subcommand(permission = "datura.locker", args = {Player.class, String.class}) @Subcommand(permission = "datura.locker", args = {Player.class, String.class})
public void lockPlayer(final CommandSender sender, final Player player, final String string) public void lockPlayer(final CommandSender sender, final Player player, final String string)
{ {

View File

@ -20,6 +20,9 @@ import org.jetbrains.annotations.NotNull;
@Info(name = "manageuser", description = "Manage a user's permissions", usage = "/manageuser <username> <info | (add " @Info(name = "manageuser", description = "Manage a user's permissions", usage = "/manageuser <username> <info | (add "
+ "| remove <permission>)>", aliases = {"mu", "userdata", "ud", "usermanager", "um"}) + "| remove <permission>)>", aliases = {"mu", "userdata", "ud", "usermanager", "um"})
@Permissive(perm = "datura.manageuser") @Permissive(perm = "datura.manageuser")
@Completion(index = 0, args = {"%player%"})
@Completion(index = 1, args = {"info", "add", "remove"})
@Completion(index = 2, args = {"<permission>"})
public class ManageUserCommand extends Commander public class ManageUserCommand extends Commander
{ {
@ -38,9 +41,6 @@ public class ManageUserCommand extends Commander
} }
@Subcommand(permission = "datura.manageuser", args = {Player.class, String.class, String.class, Long.class}) @Subcommand(permission = "datura.manageuser", args = {Player.class, String.class, String.class, Long.class})
@Completion(index = 0, args = {"%player%"})
@Completion(index = 1, args = {"info", "add", "remove"})
@Completion(index = 2, args = {"<permission>"})
public void manageUser(final CommandSender sender, final Player player, final String addOrRemove, public void manageUser(final CommandSender sender, final Player player, final String addOrRemove,
final String permission, final long duration) final String permission, final long duration)
{ {

View File

@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
@Info(name = "smite", description = "Smite a player.", usage = "/smite <player>", aliases = {"sm"}) @Info(name = "smite", description = "Smite a player.", usage = "/smite <player>", aliases = {"sm"})
@Permissive(perm = "datura.smite") @Permissive(perm = "datura.smite")
@Completion(index = 0, args = {"%player%"})
public class SmiteCommand extends Commander public class SmiteCommand extends Commander
{ {
/** /**
@ -30,7 +31,6 @@ public class SmiteCommand extends Commander
} }
@Subcommand(permission = "datura.smite", args = {Player.class}) @Subcommand(permission = "datura.smite", args = {Player.class})
@Completion(index = 0, args = {"%player%"})
public void smite(final CommandSender sender, final Player player) public void smite(final CommandSender sender, final Player player)
{ {
final double size = 5D; final double size = 5D;

View File

@ -1,5 +1,9 @@
package me.totalfreedom.audience; package me.totalfreedom.audience;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.chat.ChatType; import net.kyori.adventure.chat.ChatType;
@ -13,13 +17,8 @@ import net.kyori.adventure.title.Title;
import net.kyori.adventure.title.TitlePart; import net.kyori.adventure.title.TitlePart;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
/** /**
* A replacement for {@link net.kyori.adventure.audience.ForwardingAudience} that allows for audiences to be removed & * A replacement for {@link net.kyori.adventure.audience.ForwardingAudience} that allows for audiences to be removed and
* added at will. Not thread safe. * added at will. Not thread safe.
* <p> * <p>
* This is intended for use in toggleable logging systems, for example, potion spy. * This is intended for use in toggleable logging systems, for example, potion spy.

View File

@ -1,5 +1,9 @@
package me.totalfreedom.command; package me.totalfreedom.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import me.totalfreedom.command.annotation.Completion; import me.totalfreedom.command.annotation.Completion;
import me.totalfreedom.command.annotation.Subcommand; import me.totalfreedom.command.annotation.Subcommand;
import me.totalfreedom.provider.ContextProvider; import me.totalfreedom.provider.ContextProvider;
@ -10,24 +14,18 @@ import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginIdentifiableCommand; import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/** /**
* This class is acts as a delegate between our custom command implementation and the Bukkit API. * This class is acts as a delegate between our custom command implementation and the Bukkit API.
* <br> * <br>
* This class is not meant to be used directly, and is only public to allow for the Bukkit API to access it. As a * This class is not meant to be used directly, and is only public to allow for the Bukkit API to access it. As a
* result, this file will remain undocumented. * result, this file will remain undocumented.
* <span color=#ff0000> * <br>
* <br> * <br>
* This class is not thread-safe. * This class is not thread-safe.
* <br> * <br>
@ -36,7 +34,6 @@ import java.util.Set;
* This class is not meant to be instantiated. * This class is not meant to be instantiated.
* <br> * <br>
* This class is not meant to be used outside Patchwork. * This class is not meant to be used outside Patchwork.
* </span>
*/ */
public final class BukkitDelegate extends Command implements PluginIdentifiableCommand public final class BukkitDelegate extends Command implements PluginIdentifiableCommand
{ {
@ -101,14 +98,18 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
{ {
try try
{ {
if (noConsole) { if (noConsole)
{
command.getBaseMethod() command.getBaseMethod()
.invoke(command, (Player)sender); .invoke(command, (Player) sender);
} else { }
else
{
command.getBaseMethod() command.getBaseMethod()
.invoke(command, sender); .invoke(command, sender);
} }
} catch (Exception ex) }
catch (Exception ex)
{ {
FreedomLogger.getLogger("Patchwork") FreedomLogger.getLogger("Patchwork")
.error(ex); .error(ex);
@ -142,37 +143,45 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
final String[] reasonArgs = Arrays.copyOfRange(args, i, args.length - 1); final String[] reasonArgs = Arrays.copyOfRange(args, i, args.length - 1);
final String reason = String.join(" ", reasonArgs); final String reason = String.join(" ", reasonArgs);
objects[i] = reason; objects[i] = reason;
} else }
else
{ {
continue; continue;
} }
} }
if (argType.equals(Location.class)) { if (argType.equals(Location.class))
{
final String[] locationArgs = Arrays.copyOfRange(args, i, i + 3); final String[] locationArgs = Arrays.copyOfRange(args, i, i + 3);
final String location = String.join(" ", locationArgs); final String location = String.join(" ", locationArgs);
objects[i] = location; objects[i] = location;
} }
final Object obj = provider.fromString(arg, argType); final Object obj = provider.fromString(arg, argType);
if (obj == null) { if (obj == null)
FreedomLogger.getLogger("Datura").error("Failed to parse argument " + arg + " for type " + argType.getName()); {
FreedomLogger.getLogger("Datura")
.error("Failed to parse argument " + arg + " for type " + argType.getName());
return; return;
} }
objects[i] = obj; objects[i] = obj;
} }
try try
{ {
if (noConsole) { if (noConsole)
{
command.getSubcommands() command.getSubcommands()
.get(node) .get(node)
.invoke(command, (Player)sender, objects); .invoke(command, (Player) sender, objects);
} else { }
else
{
command.getSubcommands() command.getSubcommands()
.get(node) .get(node)
.invoke(command, sender, objects); .invoke(command, sender, objects);
} }
} catch (Exception ex) }
catch (Exception ex)
{ {
FreedomLogger.getLogger("Patchwork") FreedomLogger.getLogger("Patchwork")
.error(ex); .error(ex);
@ -204,16 +213,16 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
.map(World::getName) .map(World::getName)
.toList()); .toList());
case "%number%" -> results.addAll(List.of( case "%number%" -> results.addAll(List.of(
"0", "0",
"1", "1",
"2", "2",
"3", "3",
"4", "4",
"5", "5",
"6", "6",
"7", "7",
"8", "8",
"9")); "9"));
case "%location%" -> results.add("world x y z"); case "%location%" -> results.add("world x y z");
default -> results.add(p); default -> results.add(p);
} }

View File

@ -12,7 +12,7 @@ import java.lang.annotation.Target;
* This will register at class level, and does not retain method information. As a result, you only need to register the * This will register at class level, and does not retain method information. As a result, you only need to register the
* arguments a single time, and it will always be used in tab completions. * arguments a single time, and it will always be used in tab completions.
*/ */
@Target(ElementType.METHOD) @Target(ElementType.TYPE)
@Repeatable(Completions.class) @Repeatable(Completions.class)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Completion public @interface Completion

View File

@ -8,10 +8,10 @@ import java.lang.annotation.Target;
/** /**
* A marker interface which represents a holder for multiple {@link Completion} annotations. * A marker interface which represents a holder for multiple {@link Completion} annotations.
* <br> * <br>
* <u>This interface is <span color=#ff0000><b>NOT</b></span> intended for implementation and should * <u>This interface is <b>NOT</b> intended for implementation and should
* <span color=#ff0000><b>NOT</b></span> be used.</u> * <b>NOT</b> be used.</u>
*/ */
@Target(ElementType.METHOD) @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Completions public @interface Completions
{ {

View File

@ -284,7 +284,7 @@ public class ServiceTaskRegistry
* <br> * <br>
* <i>The service should have been registered previously as a <b>ServiceSubscription</b></i>. * <i>The service should have been registered previously as a <b>ServiceSubscription</b></i>.
* *
* @param service The service you are trying to unregister. * @param clazz The service you are trying to unregister.
* @see #registerService(ServiceSubscription) * @see #registerService(ServiceSubscription)
* @see ServiceSubscription * @see ServiceSubscription
*/ */

View File

@ -78,6 +78,7 @@ public class DisplayableView extends InventoryView
} }
@Override @Override
@Deprecated(forRemoval = true, since = "1.16")
public @NotNull String getTitle() public @NotNull String getTitle()
{ {
return title; return title;

View File

@ -56,7 +56,7 @@ public interface Trail
* *
* @return The color of the trail, or null if the trail is a gradient or non-colorable. * @return The color of the trail, or null if the trail is a gradient or non-colorable.
* @see Particle * @see Particle
* @see #getColors(); * @see #getColors()
*/ */
@Nullable @Nullable
Color getColor(); Color getColor();

View File

@ -1,9 +1,7 @@
package me.totalfreedom.shop; package me.totalfreedom.shop;
import me.totalfreedom.display.BossBarDisplay;
import net.kyori.adventure.text.Component;
import java.time.Duration; import java.time.Duration;
import net.kyori.adventure.text.Component;
/** /**
* Represents a chat reaction that can be performed by a player. * Represents a chat reaction that can be performed by a player.
@ -59,10 +57,4 @@ public abstract class Reaction implements Reactable
{ {
return reactionType; return reactionType;
} }
@Override
public BossBarDisplay getBossBarDisplay()
{
}
} }

View File

@ -59,6 +59,12 @@ subprojects {
weight = 0 weight = 0
} }
} }
javadoc {
options {
encoding = 'UTF-8'
}
}
} }
tasks.register('buildChain') { tasks.register('buildChain') {