mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-25 12:25:15 +01:00
Execute command initial
This commit is contained in:
parent
05949fe6b0
commit
c32a2ad8bd
@ -27,7 +27,7 @@ import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.channel.*;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuild;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordRole;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -139,11 +139,11 @@ public interface DiscordAPI {
|
||||
* Registers a Discord command.
|
||||
* @param command the command to register
|
||||
*/
|
||||
Command.RegistrationResult registerCommand(Command command);
|
||||
DiscordCommand.RegistrationResult registerCommand(DiscordCommand command);
|
||||
|
||||
/**
|
||||
* Unregisters a Discord command.
|
||||
* @param command the command to unregister
|
||||
*/
|
||||
void unregisterCommand(Command command);
|
||||
void unregisterCommand(DiscordCommand command);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* A Discord command.
|
||||
*/
|
||||
public class Command implements JDAEntity<CommandData> {
|
||||
public class DiscordCommand implements JDAEntity<CommandData> {
|
||||
|
||||
private static final String CHAT_INPUT_NAME_REGEX = "(?U)[\\w-]{1,32}";
|
||||
public static final Pattern CHAT_INPUT_NAME_PATTERN = Pattern.compile(CHAT_INPUT_NAME_REGEX);
|
||||
@ -100,27 +100,27 @@ public class Command implements JDAEntity<CommandData> {
|
||||
private final Map<Locale, String> nameTranslations;
|
||||
private final Map<Locale, String> descriptionTranslations;
|
||||
private final List<SubCommandGroup> subCommandGroups;
|
||||
private final List<Command> subCommands;
|
||||
private final List<DiscordCommand> subCommands;
|
||||
private final List<CommandOption> options;
|
||||
private final Long guildId;
|
||||
private final boolean guildOnly;
|
||||
private final DefaultPermission defaultPermission;
|
||||
private final Consumer<? extends AbstractCommandInteractionEvent<?>> eventHandler;
|
||||
private final Consumer<DiscordCommandAutoCompleteInteractionEvent> autoCompleteHandler;
|
||||
private final AutoCompleteHandler autoCompleteHandler;
|
||||
|
||||
private Command(
|
||||
private DiscordCommand(
|
||||
ComponentIdentifier id,
|
||||
CommandType type,
|
||||
Map<Locale, String> nameTranslations,
|
||||
Map<Locale, String> descriptionTranslations,
|
||||
List<SubCommandGroup> subCommandGroups,
|
||||
List<Command> subCommands,
|
||||
List<DiscordCommand> subCommands,
|
||||
List<CommandOption> options,
|
||||
Long guildId,
|
||||
boolean guildOnly,
|
||||
DefaultPermission defaultPermission,
|
||||
Consumer<? extends AbstractCommandInteractionEvent<?>> eventHandler,
|
||||
Consumer<DiscordCommandAutoCompleteInteractionEvent> autoCompleteHandler
|
||||
AutoCompleteHandler autoCompleteHandler
|
||||
) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
@ -181,7 +181,7 @@ public class Command implements JDAEntity<CommandData> {
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<Command> getSubCommands() {
|
||||
public List<DiscordCommand> getSubCommands() {
|
||||
return Collections.unmodifiableList(subCommands);
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ public class Command implements JDAEntity<CommandData> {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Consumer<DiscordCommandAutoCompleteInteractionEvent> getAutoCompleteHandler() {
|
||||
public AutoCompleteHandler getAutoCompleteHandler() {
|
||||
return autoCompleteHandler;
|
||||
}
|
||||
|
||||
@ -228,7 +228,8 @@ public class Command implements JDAEntity<CommandData> {
|
||||
case CHAT_INPUT:
|
||||
SlashCommandData slashCommandData = Commands.slash(getName(), Objects.requireNonNull(getDescription()));
|
||||
slashCommandData.addSubcommandGroups(subCommandGroups.stream().map(JDAEntity::asJDA).toArray(SubcommandGroupData[]::new));
|
||||
slashCommandData.addSubcommands(subCommands.stream().map(Command::asJDASubcommand).toArray(SubcommandData[]::new));
|
||||
slashCommandData.addSubcommands(subCommands.stream().map(
|
||||
DiscordCommand::asJDASubcommand).toArray(SubcommandData[]::new));
|
||||
slashCommandData.addOptions(options.stream().map(JDAEntity::asJDA).toArray(OptionData[]::new));
|
||||
commandData = slashCommandData;
|
||||
break;
|
||||
@ -252,9 +253,9 @@ public class Command implements JDAEntity<CommandData> {
|
||||
|
||||
private final Map<Locale, String> descriptionTranslations = new LinkedHashMap<>();
|
||||
private final List<SubCommandGroup> subCommandGroups = new ArrayList<>();
|
||||
private final List<Command> subCommands = new ArrayList<>();
|
||||
private final List<DiscordCommand> subCommands = new ArrayList<>();
|
||||
private final List<CommandOption> options = new ArrayList<>();
|
||||
private Consumer<DiscordCommandAutoCompleteInteractionEvent> autoCompleteHandler;
|
||||
private AutoCompleteHandler autoCompleteHandler;
|
||||
|
||||
private ChatInputBuilder(ComponentIdentifier id, String name, String description) {
|
||||
super(id, CommandType.CHAT_INPUT, name);
|
||||
@ -296,7 +297,7 @@ public class Command implements JDAEntity<CommandData> {
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public ChatInputBuilder addSubCommand(@NotNull Command command) {
|
||||
public ChatInputBuilder addSubCommand(@NotNull DiscordCommand command) {
|
||||
this.subCommands.add(command);
|
||||
return this;
|
||||
}
|
||||
@ -319,14 +320,14 @@ public class Command implements JDAEntity<CommandData> {
|
||||
* @return this builder, useful for chaining
|
||||
*/
|
||||
@NotNull
|
||||
public ChatInputBuilder setAutoCompleteHandler(Consumer<DiscordCommandAutoCompleteInteractionEvent> autoCompleteHandler) {
|
||||
public ChatInputBuilder setAutoCompleteHandler(AutoCompleteHandler autoCompleteHandler) {
|
||||
this.autoCompleteHandler = autoCompleteHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command build() {
|
||||
return new Command(
|
||||
public DiscordCommand build() {
|
||||
return new DiscordCommand(
|
||||
id,
|
||||
type,
|
||||
nameTranslations,
|
||||
@ -343,6 +344,13 @@ public class Command implements JDAEntity<CommandData> {
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AutoCompleteHandler {
|
||||
|
||||
void autoComplete(DiscordCommandAutoCompleteInteractionEvent event);
|
||||
|
||||
}
|
||||
|
||||
public static class Builder<E extends AbstractCommandInteractionEvent<?>> {
|
||||
|
||||
protected final ComponentIdentifier id;
|
||||
@ -414,8 +422,8 @@ public class Command implements JDAEntity<CommandData> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Command build() {
|
||||
return new Command(
|
||||
public DiscordCommand build() {
|
||||
return new DiscordCommand(
|
||||
id,
|
||||
type,
|
||||
nameTranslations,
|
@ -43,15 +43,15 @@ public class SubCommandGroup implements JDAEntity<SubcommandGroupData> {
|
||||
* @return a new sub command group
|
||||
*/
|
||||
@NotNull
|
||||
public static SubCommandGroup of(@NotNull String name, @NotNull String description, @NotNull Command... commands) {
|
||||
public static SubCommandGroup of(@NotNull String name, @NotNull String description, @NotNull DiscordCommand... commands) {
|
||||
return new SubCommandGroup(name, description, Arrays.asList(commands));
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final String description;
|
||||
private final List<Command> commands;
|
||||
private final List<DiscordCommand> commands;
|
||||
|
||||
private SubCommandGroup(String name, String description, List<Command> commands) {
|
||||
private SubCommandGroup(String name, String description, List<DiscordCommand> commands) {
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.commands = commands;
|
||||
@ -69,13 +69,13 @@ public class SubCommandGroup implements JDAEntity<SubcommandGroupData> {
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<Command> getCommands() {
|
||||
public List<DiscordCommand> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubcommandGroupData asJDA() {
|
||||
return new SubcommandGroupData(name, description)
|
||||
.addSubcommands(commands.stream().map(Command::asJDASubcommand).toArray(SubcommandData[]::new));
|
||||
.addSubcommands(commands.stream().map(DiscordCommand::asJDASubcommand).toArray(SubcommandData[]::new));
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
package com.discordsrv.api.discord.events.interaction.command;
|
||||
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.event.events.Event;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
@ -34,24 +34,24 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An event for registering {@link com.discordsrv.api.discord.entity.interaction.command.Command}s,
|
||||
* an alternative to {@link com.discordsrv.api.discord.DiscordAPI#registerCommand(Command)}.
|
||||
* An event for registering {@link DiscordCommand}s,
|
||||
* an alternative to {@link com.discordsrv.api.discord.DiscordAPI#registerCommand(DiscordCommand)}.
|
||||
*/
|
||||
public class CommandRegisterEvent implements Event {
|
||||
|
||||
private final List<Command> commands = new ArrayList<>();
|
||||
private final List<DiscordCommand> commands = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Add events to be registered.
|
||||
* @param commands the commands to be registered, use of the same command instances is recommended
|
||||
*/
|
||||
public void registerCommands(@NotNull Command... commands) {
|
||||
public void registerCommands(@NotNull DiscordCommand... commands) {
|
||||
this.commands.addAll(Arrays.asList(commands));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Unmodifiable
|
||||
public List<Command> getCommands() {
|
||||
public List<DiscordCommand> getCommands() {
|
||||
return Collections.unmodifiableList(commands);
|
||||
}
|
||||
}
|
||||
|
@ -47,16 +47,16 @@ public class DiscordCommandAutoCompleteInteractionEvent extends AbstractInteract
|
||||
super(jdaEvent, identifier, user, member, channel);
|
||||
}
|
||||
|
||||
public void addChoice(String key, String value) {
|
||||
this.choices.put(key, value);
|
||||
public void addChoice(String name, String value) {
|
||||
this.choices.put(name, value);
|
||||
}
|
||||
|
||||
public void addChoice(String key, double value) {
|
||||
this.choices.put(key, value);
|
||||
public void addChoice(String name, double value) {
|
||||
this.choices.put(name, value);
|
||||
}
|
||||
|
||||
public void addChoice(String key, long value) {
|
||||
this.choices.put(key, value);
|
||||
public void addChoice(String name, long value) {
|
||||
this.choices.put(name, value);
|
||||
}
|
||||
|
||||
public Map<String, Object> getChoices() {
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.discordsrv.bukkit;
|
||||
|
||||
import org.bukkit.Server;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class PaperCmdMap {
|
||||
|
||||
public static Set<String> getMap(Server server) {
|
||||
return server.getCommandMap().getKnownCommands().keySet();
|
||||
}
|
||||
}
|
@ -39,6 +39,7 @@ import com.discordsrv.bukkit.scheduler.BukkitScheduler;
|
||||
import com.discordsrv.bukkit.scheduler.FoliaScheduler;
|
||||
import com.discordsrv.bukkit.scheduler.IBukkitScheduler;
|
||||
import com.discordsrv.common.ServerDiscordSRV;
|
||||
import com.discordsrv.common.command.discord.commands.subcommand.ExecuteCommand;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.config.manager.ConnectionConfigManager;
|
||||
import com.discordsrv.common.config.manager.MainConfigManager;
|
||||
@ -47,11 +48,14 @@ import com.discordsrv.common.messageforwarding.game.minecrafttodiscord.Minecraft
|
||||
import com.discordsrv.common.plugin.PluginManager;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@ -225,4 +229,40 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<DiscordSRVBukkitBootstrap
|
||||
requiredLinkingListener.disable();
|
||||
audiences.close();
|
||||
}
|
||||
|
||||
public ExecuteCommand.AutoCompleteHelper autoCompleteHelper() {
|
||||
return parts -> {
|
||||
String commandName = !parts.isEmpty() ? parts.remove(0) : null;
|
||||
Command command = commandName != null ? server().getPluginCommand(commandName) : null;
|
||||
if (command == null) {
|
||||
if (parts.size() > 1) {
|
||||
// Command is not known but there are arguments, nothing to auto complete...
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
// List out commands
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
for (String cmd : PaperCmdMap.getMap(server())) {
|
||||
if (commandName == null || cmd.startsWith(commandName)) {
|
||||
suggestions.add(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the arguments minus the last one (if any)
|
||||
String prefix = String.join(" ", parts.subList(0, parts.size() - (!parts.isEmpty() ? 1 : 0)));
|
||||
if (!prefix.isEmpty()) {
|
||||
prefix = prefix + " ";
|
||||
}
|
||||
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
for (String suggestion : command.tabComplete(server().getConsoleSender(), commandName, parts.toArray(new String[0]))) {
|
||||
suggestions.add(commandName + " " + prefix + suggestion);
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import com.discordsrv.api.module.type.Module;
|
||||
import com.discordsrv.api.placeholder.DiscordPlaceholders;
|
||||
import com.discordsrv.common.bootstrap.IBootstrap;
|
||||
import com.discordsrv.common.channel.ChannelConfigHelper;
|
||||
import com.discordsrv.common.command.discord.commands.subcommand.ExecuteCommand;
|
||||
import com.discordsrv.common.command.game.handler.ICommandHandler;
|
||||
import com.discordsrv.common.component.ComponentFactory;
|
||||
import com.discordsrv.common.config.connection.ConnectionConfig;
|
||||
@ -34,8 +35,8 @@ import com.discordsrv.common.debug.data.OnlineMode;
|
||||
import com.discordsrv.common.debug.data.VersionInfo;
|
||||
import com.discordsrv.common.dependency.DiscordSRVDependencyManager;
|
||||
import com.discordsrv.common.discord.api.DiscordAPIImpl;
|
||||
import com.discordsrv.common.discord.connection.jda.JDAConnectionManager;
|
||||
import com.discordsrv.common.discord.connection.details.DiscordConnectionDetailsImpl;
|
||||
import com.discordsrv.common.discord.connection.jda.JDAConnectionManager;
|
||||
import com.discordsrv.common.linking.LinkProvider;
|
||||
import com.discordsrv.common.logging.Logger;
|
||||
import com.discordsrv.common.logging.impl.DiscordSRVLogger;
|
||||
@ -152,4 +153,8 @@ public interface DiscordSRV extends DiscordSRVApi {
|
||||
CompletableFuture<Void> invokeDisable();
|
||||
CompletableFuture<List<ReloadResult>> invokeReload(Set<ReloadFlag> flags, boolean silent);
|
||||
|
||||
default ExecuteCommand.AutoCompleteHelper autoCompleteHelper() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package com.discordsrv.common.command.combined.commands;
|
||||
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.CommandOption;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
@ -43,7 +43,7 @@ public class DebugCommand extends CombinedCommand {
|
||||
|
||||
private static DebugCommand INSTANCE;
|
||||
private static GameCommand GAME;
|
||||
private static Command DISCORD;
|
||||
private static DiscordCommand DISCORD;
|
||||
|
||||
private static DebugCommand getInstance(DiscordSRV discordSRV) {
|
||||
return INSTANCE != null ? INSTANCE : (INSTANCE = new DebugCommand(discordSRV));
|
||||
@ -67,10 +67,10 @@ public class DebugCommand extends CombinedCommand {
|
||||
return GAME;
|
||||
}
|
||||
|
||||
public static Command getDiscord(DiscordSRV discordSRV) {
|
||||
public static DiscordCommand getDiscord(DiscordSRV discordSRV) {
|
||||
if (DISCORD == null) {
|
||||
DebugCommand command = getInstance(discordSRV);
|
||||
DISCORD = Command.chatInput(ComponentIdentifier.of("DiscordSRV", "debug"), "debug", "Create a debug report")
|
||||
DISCORD = DiscordCommand.chatInput(ComponentIdentifier.of("DiscordSRV", "debug"), "debug", "Create a debug report")
|
||||
.addOption(
|
||||
CommandOption.builder(CommandOption.Type.STRING, "format", "The format to generate the debug report")
|
||||
.addChoice(".zip", "zip")
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.discordsrv.common.command.combined.commands;
|
||||
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
@ -24,7 +24,7 @@ public class ResyncCommand extends CombinedCommand {
|
||||
|
||||
private static ResyncCommand INSTANCE;
|
||||
private static GameCommand GAME;
|
||||
private static Command DISCORD;
|
||||
private static DiscordCommand DISCORD;
|
||||
|
||||
private static ResyncCommand getInstance(DiscordSRV discordSRV) {
|
||||
return INSTANCE != null ? INSTANCE : (INSTANCE = new ResyncCommand(discordSRV));
|
||||
@ -41,10 +41,10 @@ public class ResyncCommand extends CombinedCommand {
|
||||
return GAME;
|
||||
}
|
||||
|
||||
public static Command getDiscord(DiscordSRV discordSRV) {
|
||||
public static DiscordCommand getDiscord(DiscordSRV discordSRV) {
|
||||
if (DISCORD == null) {
|
||||
ResyncCommand command = getInstance(discordSRV);
|
||||
DISCORD = Command.chatInput(ComponentIdentifier.of("DiscordSRV", "resync"), "resync", "Perform group resync for online players")
|
||||
DISCORD = DiscordCommand.chatInput(ComponentIdentifier.of("DiscordSRV", "resync"), "resync", "Perform group resync for online players")
|
||||
.setEventHandler(command)
|
||||
.build();
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.common.command.combined.commands;
|
||||
|
||||
import com.discordsrv.api.color.Color;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.abstraction.CombinedCommand;
|
||||
@ -38,7 +38,7 @@ public class VersionCommand extends CombinedCommand {
|
||||
|
||||
private static VersionCommand INSTANCE;
|
||||
private static GameCommand GAME;
|
||||
private static Command DISCORD;
|
||||
private static DiscordCommand DISCORD;
|
||||
|
||||
private static VersionCommand getInstance(DiscordSRV discordSRV) {
|
||||
return INSTANCE != null ? INSTANCE : (INSTANCE = new VersionCommand(discordSRV));
|
||||
@ -55,10 +55,10 @@ public class VersionCommand extends CombinedCommand {
|
||||
return GAME;
|
||||
}
|
||||
|
||||
public static Command getDiscord(DiscordSRV discordSRV) {
|
||||
public static DiscordCommand getDiscord(DiscordSRV discordSRV) {
|
||||
if (DISCORD == null) {
|
||||
VersionCommand command = getInstance(discordSRV);
|
||||
DISCORD = Command.chatInput(ComponentIdentifier.of("DiscordSRV", "version"), "version", "Get the DiscordSRV version")
|
||||
DISCORD = DiscordCommand.chatInput(ComponentIdentifier.of("DiscordSRV", "version"), "version", "Get the DiscordSRV version")
|
||||
.setEventHandler(command)
|
||||
.build();
|
||||
}
|
||||
|
@ -1,26 +1,28 @@
|
||||
package com.discordsrv.common.command.discord.commands;
|
||||
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.command.combined.commands.DebugCommand;
|
||||
import com.discordsrv.common.command.combined.commands.ResyncCommand;
|
||||
import com.discordsrv.common.command.combined.commands.VersionCommand;
|
||||
import com.discordsrv.common.command.discord.commands.subcommand.ExecuteCommand;
|
||||
|
||||
public class DiscordSRVDiscordCommand {
|
||||
|
||||
private static final ComponentIdentifier IDENTIFIER = ComponentIdentifier.of("DiscordSRV", "discordsrv");
|
||||
|
||||
private static Command INSTANCE;
|
||||
private static DiscordCommand INSTANCE;
|
||||
|
||||
public static Command get(DiscordSRV discordSRV) {
|
||||
public static DiscordCommand get(DiscordSRV discordSRV) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = Command.chatInput(IDENTIFIER, "discordsrv", "DiscordSRV related commands")
|
||||
INSTANCE = DiscordCommand.chatInput(IDENTIFIER, "discordsrv", "DiscordSRV related commands")
|
||||
.addSubCommand(DebugCommand.getDiscord(discordSRV))
|
||||
.addSubCommand(VersionCommand.getDiscord(discordSRV))
|
||||
.addSubCommand(ResyncCommand.getDiscord(discordSRV))
|
||||
.addSubCommand(ExecuteCommand.get(discordSRV))
|
||||
.setGuildOnly(false)
|
||||
.setDefaultPermission(Command.DefaultPermission.ADMINISTRATOR)
|
||||
.setDefaultPermission(DiscordCommand.DefaultPermission.ADMINISTRATOR)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,88 @@
|
||||
package com.discordsrv.common.command.discord.commands.subcommand;
|
||||
|
||||
import com.discordsrv.api.discord.entity.interaction.command.CommandOption;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.api.discord.events.interaction.command.DiscordChatInputInteractionEvent;
|
||||
import com.discordsrv.api.discord.events.interaction.command.DiscordCommandAutoCompleteInteractionEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ExecuteCommand implements Consumer<DiscordChatInputInteractionEvent>, DiscordCommand.AutoCompleteHandler {
|
||||
|
||||
private static DiscordCommand INSTANCE;
|
||||
|
||||
public static DiscordCommand get(DiscordSRV discordSRV) {
|
||||
if (INSTANCE == null) {
|
||||
ExecuteCommand command = new ExecuteCommand(discordSRV);
|
||||
INSTANCE = DiscordCommand.chatInput(ComponentIdentifier.of("DiscordSRV", "execute"), "execute", "Run a Minecraft console command")
|
||||
.addOption(
|
||||
CommandOption.builder(CommandOption.Type.STRING, "command", "The command to execute")
|
||||
.setAutoComplete(true)
|
||||
.setRequired(true)
|
||||
.build()
|
||||
)
|
||||
.setAutoCompleteHandler(command)
|
||||
.setEventHandler(command)
|
||||
.build();
|
||||
}
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
|
||||
public ExecuteCommand(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(DiscordChatInputInteractionEvent event) {
|
||||
OptionMapping mapping = event.asJDA().getOption("command");
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String command = mapping.getAsString();
|
||||
discordSRV.logger().error("> " + command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void autoComplete(DiscordCommandAutoCompleteInteractionEvent event) {
|
||||
OptionMapping mapping = event.asJDA().getOption("command");
|
||||
if (mapping == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String command = mapping.getAsString();
|
||||
List<String> parts = new ArrayList<>(Arrays.asList(command.split(" ")));
|
||||
|
||||
AutoCompleteHelper helper = discordSRV.autoCompleteHelper();
|
||||
|
||||
List<String> suggestions = helper.suggestCommands(new ArrayList<>(parts));
|
||||
if (suggestions.isEmpty() || suggestions.contains(command)) {
|
||||
parts.add("");
|
||||
suggestions = new ArrayList<>(helper.suggestCommands(parts));
|
||||
|
||||
if (suggestions.isEmpty()) {
|
||||
suggestions.add(command);
|
||||
}
|
||||
}
|
||||
|
||||
for (String suggestion : suggestions) {
|
||||
if (event.getChoices().size() >= 25) break;
|
||||
|
||||
event.addChoice(suggestion, suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
public interface AutoCompleteHelper {
|
||||
|
||||
List<String> suggestCommands(List<String> parts);
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.CommandType;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.SubCommandGroup;
|
||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||
import com.discordsrv.api.discord.events.interaction.DiscordModalInteractionEvent;
|
||||
@ -130,7 +131,7 @@ public class DiscordAPIEventModule extends AbstractModule<DiscordSRV> {
|
||||
DiscordGuildMember guildMember = member != null ? api().getGuildMember(member) : null;
|
||||
DiscordMessageChannel channel = api().getMessageChannel(event.getMessageChannel());
|
||||
if (event instanceof CommandAutoCompleteInteractionEvent) {
|
||||
com.discordsrv.api.discord.entity.interaction.command.Command command = discordSRV.discordAPI().getActiveCommand(
|
||||
DiscordCommand command = discordSRV.discordAPI().getActiveCommand(
|
||||
((CommandAutoCompleteInteractionEvent) event).isGuildCommand() ? event.getGuild() : null,
|
||||
CommandType.CHAT_INPUT,
|
||||
((CommandAutoCompleteInteractionEvent) event).getName()
|
||||
@ -138,25 +139,30 @@ public class DiscordAPIEventModule extends AbstractModule<DiscordSRV> {
|
||||
if (command == null) {
|
||||
return;
|
||||
}
|
||||
command = mapCommand(
|
||||
command,
|
||||
((CommandAutoCompleteInteractionEvent) event).getSubcommandGroup(),
|
||||
((CommandAutoCompleteInteractionEvent) event).getSubcommandName()
|
||||
);
|
||||
|
||||
DiscordCommandAutoCompleteInteractionEvent autoComplete = new DiscordCommandAutoCompleteInteractionEvent(
|
||||
(CommandAutoCompleteInteractionEvent) event, command.getId(), user, guildMember, channel);
|
||||
discordSRV.eventBus().publish(autoComplete);
|
||||
Consumer<DiscordCommandAutoCompleteInteractionEvent> autoCompleteHandler = command.getAutoCompleteHandler();
|
||||
DiscordCommand.AutoCompleteHandler autoCompleteHandler = command.getAutoCompleteHandler();
|
||||
if (autoCompleteHandler != null) {
|
||||
autoCompleteHandler.accept(autoComplete);
|
||||
autoCompleteHandler.autoComplete(autoComplete);
|
||||
}
|
||||
|
||||
List<Command.Choice> choices = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : autoComplete.getChoices().entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String name = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof String) {
|
||||
choices.add(new Command.Choice(key, (String) value));
|
||||
choices.add(new Command.Choice(name, (String) value));
|
||||
} else if (value instanceof Double || value instanceof Float) {
|
||||
choices.add(new Command.Choice(key, ((Number) value).doubleValue()));
|
||||
choices.add(new Command.Choice(name, ((Number) value).doubleValue()));
|
||||
} else {
|
||||
choices.add(new Command.Choice(key, ((Number) value).longValue()));
|
||||
choices.add(new Command.Choice(name, ((Number) value).longValue()));
|
||||
}
|
||||
}
|
||||
((CommandAutoCompleteInteractionEvent) event).replyChoices(choices).queue();
|
||||
@ -169,7 +175,7 @@ public class DiscordAPIEventModule extends AbstractModule<DiscordSRV> {
|
||||
Guild guild = ((GenericCommandInteractionEvent) event).isGuildCommand() ? event.getGuild() : null;
|
||||
String name = ((GenericCommandInteractionEvent) event).getName();
|
||||
if (event instanceof MessageContextInteractionEvent) {
|
||||
com.discordsrv.api.discord.entity.interaction.command.Command command = discordSRV.discordAPI()
|
||||
DiscordCommand command = discordSRV.discordAPI()
|
||||
.getActiveCommand(guild, CommandType.MESSAGE, name).orElse(null);
|
||||
if (command == null) {
|
||||
return;
|
||||
@ -190,7 +196,7 @@ public class DiscordAPIEventModule extends AbstractModule<DiscordSRV> {
|
||||
eventHandler.accept(interactionEvent);
|
||||
}
|
||||
} else if (event instanceof UserContextInteractionEvent) {
|
||||
com.discordsrv.api.discord.entity.interaction.command.Command command = discordSRV.discordAPI()
|
||||
DiscordCommand command = discordSRV.discordAPI()
|
||||
.getActiveCommand(guild, CommandType.USER, name).orElse(null);
|
||||
if (command == null) {
|
||||
return;
|
||||
@ -211,35 +217,16 @@ public class DiscordAPIEventModule extends AbstractModule<DiscordSRV> {
|
||||
eventHandler.accept(interactionEvent);
|
||||
}
|
||||
} else if (event instanceof SlashCommandInteractionEvent) {
|
||||
com.discordsrv.api.discord.entity.interaction.command.Command command = discordSRV.discordAPI()
|
||||
DiscordCommand command = discordSRV.discordAPI()
|
||||
.getActiveCommand(guild, CommandType.CHAT_INPUT, name).orElse(null);
|
||||
if (command == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String subCommandGroupName = ((SlashCommandInteractionEvent) event).getSubcommandGroup();
|
||||
String subCommandName = ((SlashCommandInteractionEvent) event).getSubcommandName();
|
||||
|
||||
if (subCommandGroupName != null) {
|
||||
for (SubCommandGroup group : command.getSubCommandGroups()) {
|
||||
if (group.getName().equals(subCommandGroupName)) {
|
||||
for (com.discordsrv.api.discord.entity.interaction.command.Command subCommand : group.getCommands()) {
|
||||
if (subCommand.getName().equals(subCommandName)) {
|
||||
command = subCommand;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (subCommandName != null) {
|
||||
for (com.discordsrv.api.discord.entity.interaction.command.Command subCommand : command.getSubCommands()) {
|
||||
if (subCommandName.equals(subCommand.getName())) {
|
||||
command = subCommand;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
command = mapCommand(
|
||||
command,
|
||||
((SlashCommandInteractionEvent) event).getSubcommandGroup(),
|
||||
((SlashCommandInteractionEvent) event).getSubcommandName()
|
||||
);
|
||||
|
||||
DiscordChatInputInteractionEvent interactionEvent = new DiscordChatInputInteractionEvent(
|
||||
(SlashCommandInteractionEvent) event,
|
||||
@ -283,4 +270,28 @@ public class DiscordAPIEventModule extends AbstractModule<DiscordSRV> {
|
||||
discordSRV.eventBus().publish(newEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private DiscordCommand mapCommand(DiscordCommand command, String subCommandGroupName, String subCommandName) {
|
||||
if (subCommandGroupName != null) {
|
||||
for (SubCommandGroup group : command.getSubCommandGroups()) {
|
||||
if (group.getName().equals(subCommandGroupName)) {
|
||||
for (DiscordCommand subCommand : group.getCommands()) {
|
||||
if (subCommand.getName().equals(subCommandName)) {
|
||||
command = subCommand;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (subCommandName != null) {
|
||||
for (DiscordCommand subCommand : command.getSubCommands()) {
|
||||
if (subCommandName.equals(subCommand.getName())) {
|
||||
command = subCommand;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
@ -27,8 +27,8 @@ import com.discordsrv.api.discord.entity.DiscordUser;
|
||||
import com.discordsrv.api.discord.entity.channel.*;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordGuild;
|
||||
import com.discordsrv.api.discord.entity.guild.DiscordRole;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.CommandType;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.exception.NotReadyException;
|
||||
import com.discordsrv.api.discord.exception.RestErrorResponseException;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
@ -472,16 +472,16 @@ public class DiscordAPIImpl implements DiscordAPI {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Command.RegistrationResult registerCommand(Command command) {
|
||||
public DiscordCommand.RegistrationResult registerCommand(DiscordCommand command) {
|
||||
return commandRegistry.register(command, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterCommand(Command command) {
|
||||
public void unregisterCommand(DiscordCommand command) {
|
||||
commandRegistry.unregister(command);
|
||||
}
|
||||
|
||||
public Optional<Command> getActiveCommand(@Nullable Guild guild, CommandType type, String name) {
|
||||
public Optional<DiscordCommand> getActiveCommand(@Nullable Guild guild, CommandType type, String name) {
|
||||
return Optional.ofNullable(commandRegistry.getActive(guild != null ? guild.getIdLong() : null, type, name));
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.common.discord.api;
|
||||
|
||||
import com.discordsrv.api.discord.entity.JDAEntity;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.Command;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.DiscordCommand;
|
||||
import com.discordsrv.api.discord.entity.interaction.command.CommandType;
|
||||
import com.discordsrv.api.discord.events.interaction.command.CommandRegisterEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
@ -50,7 +50,7 @@ public class DiscordCommandRegistry {
|
||||
CommandRegisterEvent event = new CommandRegisterEvent();
|
||||
discordSRV.eventBus().publish(event);
|
||||
|
||||
List<Command> commands = event.getCommands();
|
||||
List<DiscordCommand> commands = event.getCommands();
|
||||
for (Map<CommandType, Registry> registryMap : registries.values()) {
|
||||
registryMap.values().forEach(registry -> registry.removeIf(reg -> reg.isTemporary() && !commands.contains(reg.getCommand())));
|
||||
}
|
||||
@ -58,27 +58,27 @@ public class DiscordCommandRegistry {
|
||||
commands.forEach(cmd -> register(cmd, true));
|
||||
}
|
||||
|
||||
public Command.RegistrationResult register(Command command, boolean temporary) {
|
||||
public DiscordCommand.RegistrationResult register(DiscordCommand command, boolean temporary) {
|
||||
CommandType type = command.getType();
|
||||
Long guildId = command.getGuildId();
|
||||
Registry registry = registries
|
||||
.computeIfAbsent(guildId != null ? guildId : GLOBAL_ID, key -> new EnumMap<>(CommandType.class))
|
||||
.computeIfAbsent(type, key -> new Registry());
|
||||
if (registry.contains(command)) {
|
||||
return Command.RegistrationResult.ALREADY_REGISTERED;
|
||||
return DiscordCommand.RegistrationResult.ALREADY_REGISTERED;
|
||||
}
|
||||
|
||||
boolean first = registry.register(command, temporary);
|
||||
if (!first) {
|
||||
return Command.RegistrationResult.NAME_ALREADY_IN_USE;
|
||||
return DiscordCommand.RegistrationResult.NAME_ALREADY_IN_USE;
|
||||
}
|
||||
if (registry.getInTimeOrder().indexOf(command) >= type.getMaximumCount()) {
|
||||
return Command.RegistrationResult.TOO_MANY_COMMANDS;
|
||||
return DiscordCommand.RegistrationResult.TOO_MANY_COMMANDS;
|
||||
}
|
||||
return Command.RegistrationResult.REGISTERED;
|
||||
return DiscordCommand.RegistrationResult.REGISTERED;
|
||||
}
|
||||
|
||||
public void unregister(Command command) {
|
||||
public void unregister(DiscordCommand command) {
|
||||
Long guildId = command.getGuildId();
|
||||
Registry registry = registries
|
||||
.computeIfAbsent(guildId != null ? guildId : GLOBAL_ID, key -> Collections.emptyMap())
|
||||
@ -90,7 +90,7 @@ public class DiscordCommandRegistry {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Command getActive(Long guildId, CommandType type, String name) {
|
||||
public DiscordCommand getActive(Long guildId, CommandType type, String name) {
|
||||
Registry registry = registries
|
||||
.computeIfAbsent(guildId != null ? guildId : GLOBAL_ID, key -> Collections.emptyMap())
|
||||
.get(type);
|
||||
@ -114,23 +114,23 @@ public class DiscordCommandRegistry {
|
||||
|
||||
for (long guildId : ids) {
|
||||
Map<CommandType, Registry> commandsByType = registries.getOrDefault(guildId, Collections.emptyMap());
|
||||
Map<CommandType, Set<Command>> commandsToRegister = new EnumMap<>(CommandType.class);
|
||||
Map<CommandType, Set<DiscordCommand>> commandsToRegister = new EnumMap<>(CommandType.class);
|
||||
|
||||
boolean updateNeeded = false;
|
||||
for (Map.Entry<CommandType, Registry> entry : commandsByType.entrySet()) {
|
||||
Registry registry = entry.getValue();
|
||||
|
||||
List<Command> commands = registry.getInTimeOrder();
|
||||
Set<Command> currentCommands = new LinkedHashSet<>();
|
||||
List<DiscordCommand> commands = registry.getInTimeOrder();
|
||||
Set<DiscordCommand> currentCommands = new LinkedHashSet<>();
|
||||
int max = Math.min(commands.size(), entry.getKey().getMaximumCount());
|
||||
for (int i = 0; i < max; i++) {
|
||||
Command command = commands.get(i);
|
||||
DiscordCommand command = commands.get(i);
|
||||
currentCommands.add(command);
|
||||
}
|
||||
|
||||
commandsToRegister.put(entry.getKey(), currentCommands);
|
||||
|
||||
Collection<Command> activeCommands = registry.activeCommands.values();
|
||||
Collection<DiscordCommand> activeCommands = registry.activeCommands.values();
|
||||
if (activeCommands.size() != currentCommands.size() || !currentCommands.containsAll(activeCommands)) {
|
||||
updateNeeded = true;
|
||||
}
|
||||
@ -148,7 +148,7 @@ public class DiscordCommandRegistry {
|
||||
action = guild.updateCommands();
|
||||
}
|
||||
|
||||
List<Command> allCommands = new ArrayList<>();
|
||||
List<DiscordCommand> allCommands = new ArrayList<>();
|
||||
commandsToRegister.values().forEach(allCommands::addAll);
|
||||
action.addCommands(allCommands.stream().map(JDAEntity::asJDA).collect(Collectors.toList()))
|
||||
.queue(v -> {
|
||||
@ -166,7 +166,7 @@ public class DiscordCommandRegistry {
|
||||
private static class Registry {
|
||||
|
||||
private final Map<String, List<Registration>> registry = new ConcurrentHashMap<>();
|
||||
private final Map<String, Command> activeCommands = new HashMap<>();
|
||||
private final Map<String, DiscordCommand> activeCommands = new HashMap<>();
|
||||
|
||||
public void removeIf(Predicate<Registration> commandPredicate) {
|
||||
List<String> removeKeys = new ArrayList<>();
|
||||
@ -180,7 +180,7 @@ public class DiscordCommandRegistry {
|
||||
removeKeys.forEach(registry::remove);
|
||||
}
|
||||
|
||||
public boolean contains(@NotNull Command command) {
|
||||
public boolean contains(@NotNull DiscordCommand command) {
|
||||
List<Registration> commands = registry.get(command.getName());
|
||||
if (commands == null) {
|
||||
return false;
|
||||
@ -189,14 +189,14 @@ public class DiscordCommandRegistry {
|
||||
return commands.stream().anyMatch(reg -> reg.getCommand() == command);
|
||||
}
|
||||
|
||||
public boolean register(@NotNull Command command, boolean temporary) {
|
||||
public boolean register(@NotNull DiscordCommand command, boolean temporary) {
|
||||
List<Registration> commands = registry.computeIfAbsent(command.getName(), key -> new CopyOnWriteArrayList<>());
|
||||
boolean empty = commands.isEmpty();
|
||||
commands.add(new Registration(command, temporary));
|
||||
return empty;
|
||||
}
|
||||
|
||||
public void unregister(@NotNull Command command) {
|
||||
public void unregister(@NotNull DiscordCommand command) {
|
||||
List<Registration> commands = registry.get(command.getName());
|
||||
if (commands == null) {
|
||||
return;
|
||||
@ -208,16 +208,16 @@ public class DiscordCommandRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
public void putActiveCommands(Set<Command> commands) {
|
||||
public void putActiveCommands(Set<DiscordCommand> commands) {
|
||||
synchronized (activeCommands) {
|
||||
activeCommands.clear();
|
||||
for (Command command : commands) {
|
||||
for (DiscordCommand command : commands) {
|
||||
activeCommands.put(command.getName(), command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Command> getInTimeOrder() {
|
||||
public List<DiscordCommand> getInTimeOrder() {
|
||||
List<Registration> registrations = registry.values().stream()
|
||||
.map(list -> list.get(0))
|
||||
.collect(Collectors.toList());
|
||||
@ -229,7 +229,7 @@ public class DiscordCommandRegistry {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Command getActive(String name) {
|
||||
public DiscordCommand getActive(String name) {
|
||||
synchronized (activeCommands) {
|
||||
return activeCommands.get(name);
|
||||
}
|
||||
@ -238,17 +238,17 @@ public class DiscordCommandRegistry {
|
||||
|
||||
private static class Registration {
|
||||
|
||||
private final Command command;
|
||||
private final DiscordCommand command;
|
||||
private final long time;
|
||||
private final boolean temporary;
|
||||
|
||||
public Registration(Command command, boolean temporary) {
|
||||
public Registration(DiscordCommand command, boolean temporary) {
|
||||
this.command = command;
|
||||
this.time = System.currentTimeMillis();
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
public Command getCommand() {
|
||||
public DiscordCommand getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user