Skip to content

Commit

Permalink
Hot fixes and added support for paper's new command api
Browse files Browse the repository at this point in the history
  • Loading branch information
Mqzn committed Oct 2, 2024
1 parent 887ced6 commit 2896977
Show file tree
Hide file tree
Showing 29 changed files with 447 additions and 212 deletions.
63 changes: 29 additions & 34 deletions brigadier/src/main/java/dev/velix/imperat/BaseBrigadierManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ protected BaseBrigadierManager(Imperat<S> dispatcher) {

private BrigadierNode convertRoot(CommandNode<S> root) {
BrigadierNode bRoot = BrigadierNode.create(literal(root.getData().name()));

bRoot.withExecution(dispatcher, this)
.withRequirement((obj) -> {
var source = wrapCommandSource(obj);
Expand Down Expand Up @@ -79,7 +80,6 @@ private BrigadierNode convertNode(CommandNode<S> root, ParameterNode<?, ?> paren

return (hasParentPerm && hasNodePerm);
});

if (!(node instanceof CommandNode<?>)) {
child.suggest(createSuggestionProvider(root.getData(), node.getData()));
}
Expand All @@ -89,46 +89,41 @@ private BrigadierNode convertNode(CommandNode<S> root, ParameterNode<?, ?> paren
}
return child;
}


private @NotNull SuggestionProvider<Object> createSuggestionProvider(
private @NotNull SuggestionProvider<?> createSuggestionProvider(
Command<S> command,
CommandParameter<S> parameter
) {
SuggestionResolver<S> parameterResolver = dispatcher.getParameterSuggestionResolver(parameter);
SuggestionResolver<S> suggestionResolver = parameterResolver == null ? SuggestionResolver.type(parameter.wrappedType(), parameter.format()) : parameterResolver;


//ImperatDebugger.debug("suggestion resolver is null=%s for param '%s'", parameterResolver == null, parameter.format());

return (context, builder) -> {

try {

S source = this.wrapCommandSource(context.getSource());
String paramFormat = parameter.format();
String desc = parameter.description() != Description.EMPTY ? parameter.description().toString() : "";
Message tooltip = new LiteralMessage(paramFormat + (desc.isEmpty() ? "" : " - " + desc));

String input = context.getInput();

ArgumentQueue args = ArgumentQueue.parseAutoCompletion(
input.startsWith("/") ? input.substring(1) : input
);

CompletionArg arg = new CompletionArg(args.getLast(), args.size() - 1);
SuggestionContext<S> ctx = dispatcher.getContextFactory().createSuggestionContext(source, command, args, arg);
suggestionResolver
.autoComplete(ctx, parameter)
.stream()
.filter(c -> arg.isEmpty() || c.toLowerCase().startsWith(arg.value().toLowerCase()))
.distinct()
.sorted(String.CASE_INSENSITIVE_ORDER)
.forEach(suggestionResult -> builder.suggest(suggestionResult, tooltip));

} catch (Throwable e) {
e.printStackTrace();
}
return builder.buildFuture();
S source = this.wrapCommandSource(context.getSource());
String paramFormat = parameter.format();
String desc = parameter.description() != Description.EMPTY ? parameter.description().toString() : "";
Message tooltip = new LiteralMessage(paramFormat + (desc.isEmpty() ? "" : " - " + desc));

String input = context.getInput();

ArgumentQueue args = ArgumentQueue.parseAutoCompletion(
input.startsWith("/") ? input.substring(1) : input
);

CompletionArg arg = new CompletionArg(args.getLast(), args.size() - 1);
SuggestionContext<S> ctx = dispatcher.getContextFactory().createSuggestionContext(source, command, args, arg);

return parameterResolver.asyncAutoComplete(ctx, parameter)
.thenCompose((results) -> {
results
.stream()
.filter(c -> arg.isEmpty() || c.toLowerCase().startsWith(arg.value().toLowerCase()))
.distinct()
.sorted(String.CASE_INSENSITIVE_ORDER)
.forEach((res) -> builder.suggest(res, tooltip));
return builder.buildFuture();
});
};
}

Expand Down
5 changes: 5 additions & 0 deletions bukkit/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies {
compileOnly("com.mojang:brigadier:1.0.18")
compileOnly 'org.spigotmc:spigot:1.13.2-R0.1-SNAPSHOT'

compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT")
compileOnly("io.papermc.paper:paper-mojangapi:1.19.1-R0.1-SNAPSHOT")

compileOnly "${kyori(KyoriModule.API)}"
Expand All @@ -39,3 +40,7 @@ dependencies {
processTestResources {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}
9 changes: 5 additions & 4 deletions bukkit/src/main/java/dev/velix/imperat/BukkitImperat.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ private BukkitImperat(Plugin plugin, AdventureProvider<CommandSender> adventureP
registerSourceResolvers();
registerValueResolvers();
registerSuggestionResolvers();


}

private void registerSourceResolvers() {
Expand Down Expand Up @@ -110,10 +112,10 @@ public static BukkitImperat create(
@NotNull PermissionResolver<BukkitSource> permissionResolver
) {
Preconditions.notNull(plugin, "plugin");
Preconditions.notNull(permissionResolver, "permission-resolver");
return new BukkitImperat(plugin, audienceProvider, permissionResolver);
}


public static BukkitImperat create(Plugin plugin, @Nullable AdventureProvider<CommandSender> audienceProvider) {
return create(plugin, audienceProvider, DEFAULT_PERMISSION_RESOLVER);
}
Expand Down Expand Up @@ -169,18 +171,17 @@ public String commandPrefix() {
@Override
public void registerCommand(Command<BukkitSource> command) {
super.registerCommand(command);
var internalCmd = new InternalBukkitCommand(this, command);
var internalCmd = WrappedBukkitCommand.wrap(command, new InternalBukkitCommand(this, command));
if (BukkitUtil.KNOWN_COMMANDS != null) {
bukkitOGMapping.put(command.name(), internalCmd);
} else {
BukkitUtil.COMMAND_MAP.register(command.name(), internalCmd);
}
if (brigadierManager != null) {
brigadierManager.registerBukkitCommand(internalCmd, command);
brigadierManager.registerBukkitCommand(internalCmd, command, permissionResolver);
}
}

@SuppressWarnings("deprecation")
private void registerValueResolvers() {
this.registerValueResolver(Player.class, (context, parameter, cursor, raw) -> {
if (raw.equalsIgnoreCase("me")) {
Expand Down
42 changes: 20 additions & 22 deletions bukkit/src/main/java/dev/velix/imperat/InternalBukkitCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,6 @@ final class InternalBukkitCommand extends org.bukkit.command.Command implements
this.command = command;
}

@Override
public boolean execute(@NotNull CommandSender sender,
@NotNull String label,
String[] raw) {

try {
BukkitSource source = dispatcher.wrapSender(sender);
dispatcher.dispatch(source, StringUtils.stripNamespace(label), raw);
return true;
} catch (Exception ex) {
ImperatDebugger.error(InternalBukkitCommand.class, "execute", ex);
return false;
}

}

@Override
public @NotNull Plugin getPlugin() {
return dispatcher.getPlatform();
Expand All @@ -61,7 +45,7 @@ public boolean execute(@NotNull CommandSender sender,
@Nullable
@Override
public String getPermission() {
return super.getPermission();
return command.permission();
}

@NotNull
Expand All @@ -75,6 +59,22 @@ public String getDescription() {
public String getUsage() {
return super.getUsage();
}

@Override
public boolean execute(@NotNull CommandSender sender,
@NotNull String label,
String[] raw) {

try {
BukkitSource source = dispatcher.wrapSender(sender);
dispatcher.dispatch(source, StringUtils.stripNamespace(label), raw);
return true;
} catch (Exception ex) {
ImperatDebugger.error(InternalBukkitCommand.class, "execute", ex);
return false;
}

}

@Override
public @NotNull List<String> tabComplete(
Expand All @@ -83,11 +83,9 @@ public String getUsage() {
final String[] args
) throws IllegalArgumentException {
BukkitSource source = dispatcher.wrapSender(sender);
var completion = dispatcher.autoComplete(command, source, args);
if (completion instanceof List<String> list) {
return list;
}
return new ArrayList<>(completion);
var completions = dispatcher.autoComplete(command, source, args).join();
if (completions instanceof List<String> list) return list;
else return new ArrayList<>(completions);
}

}
87 changes: 87 additions & 0 deletions bukkit/src/main/java/dev/velix/imperat/WrappedBukkitCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package dev.velix.imperat;

import dev.velix.imperat.command.Description;
import dev.velix.imperat.command.DescriptionHolder;
import dev.velix.imperat.command.PermissionHolder;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@ApiStatus.Internal
public final class WrappedBukkitCommand extends Command implements PermissionHolder, DescriptionHolder {

private final dev.velix.imperat.command.Command<BukkitSource> imperatCommand;
private final Command command;
private Description description;

private WrappedBukkitCommand(dev.velix.imperat.command.Command<BukkitSource> imperatCommand, @NotNull Command command) {
super(command.getName(), command.getDescription(), command.getUsage(), command.getAliases());
this.imperatCommand = imperatCommand;
this.command = command;
this.description = Description.of(command.getDescription());
}

static WrappedBukkitCommand wrap(dev.velix.imperat.command.Command<BukkitSource> imperatCommand, Command command) {
return new WrappedBukkitCommand(imperatCommand, command);
}

public dev.velix.imperat.command.Command<BukkitSource> getImperatCommand() {
return imperatCommand;
}

/**
* Executes the command, returning its success
*
* @param sender Source object which is executing this command
* @param commandLabel The alias of the command used
* @param args All arguments passed to the command, split via ' '
* @return true if the command was successful, otherwise false
*/
@Override
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
return command.execute(sender, commandLabel, args);
}

/**
* Retrieves the current description associated with this entity.
*
* @return the current {@link Description}.
*/
@Override
public Description description() {
return description;
}

/**
* Sets the description for this entity.
*
* @param description the {@link Description} to set.
*/
@Override
public void describe(Description description) {
this.description = description;
setDescription(description.toString());
}

/**
* Retrieves the permission associated with this holder.
*
* @return the permission string, or {@code null} if no permission is set.
*/
@Override
public @Nullable String permission() {
return command.getPermission();
}

/**
* Sets the permission for this holder.
*
* @param permission the permission string to set, can be {@code null}.
*/
@Override
public void permission(String permission) {
command.setPermission(permission);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@
import dev.velix.imperat.BaseBrigadierManager;
import dev.velix.imperat.BukkitImperat;
import dev.velix.imperat.BukkitSource;
import dev.velix.imperat.WrappedBukkitCommand;
import dev.velix.imperat.command.Command;
import dev.velix.imperat.commodore.Commodore;
import dev.velix.imperat.commodore.CommodoreProvider;
import dev.velix.imperat.resolvers.PermissionResolver;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;

import static dev.velix.imperat.commodore.CommodoreProvider.isSupported;

public final class BukkitBrigadierManager extends BaseBrigadierManager<BukkitSource> {

private final Commodore commodore;
private final Commodore<WrappedBukkitCommand> commodore;

public BukkitBrigadierManager(BukkitImperat dispatcher) {
super(dispatcher);
Expand All @@ -41,9 +43,10 @@ public BukkitSource wrapCommandSource(Object commandSource) {
}

public void registerBukkitCommand(
org.bukkit.command.Command bukkitCmd,
Command<BukkitSource> imperatCommand
WrappedBukkitCommand bukkitCmd,
Command<BukkitSource> imperatCommand,
PermissionResolver<BukkitSource> resolver
) {
commodore.register(bukkitCmd, parseCommandIntoNode(imperatCommand));
commodore.register(bukkitCmd, parseCommandIntoNode(imperatCommand), (player) -> resolver.hasPermission(wrapCommandSource(player), bukkitCmd.permission()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

abstract class AbstractCommodore implements Commodore {
abstract class AbstractCommodore<C extends Command> implements Commodore<C> {

// ArgumentCommandNode#customSuggestions field
protected static final Field CUSTOM_SUGGESTIONS_FIELD;
Expand Down Expand Up @@ -91,7 +91,7 @@ abstract class AbstractCommodore implements Commodore {

// should never be called
// if ReflectionCommodore: bukkit handling should override
// if PaperCommodore: this is only sent to the client, not used for actual command handling
// if LegacyPaperCommodore: this is only sent to the client, not used for actual command handling
DUMMY_COMMAND = (ctx) -> {
throw new UnsupportedOperationException();
};
Expand Down
Loading

0 comments on commit 2896977

Please sign in to comment.