mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-25 12:25:15 +01:00
Add console command execution and user/role limiting to custom commands
This commit is contained in:
parent
227138fc94
commit
791abc7888
@ -33,8 +33,7 @@ import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public abstract class AbstractInteractionEvent<T extends GenericInteractionCreateEvent> extends
|
public abstract class AbstractInteractionEvent<T extends GenericInteractionCreateEvent> extends AbstractDiscordEvent<T> {
|
||||||
AbstractDiscordEvent<T> {
|
|
||||||
|
|
||||||
protected final ComponentIdentifier identifier;
|
protected final ComponentIdentifier identifier;
|
||||||
protected final DiscordUser user;
|
protected final DiscordUser user;
|
||||||
|
@ -31,11 +31,11 @@ import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifi
|
|||||||
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
|
import net.dv8tion.jda.api.events.interaction.GenericInteractionCreateEvent;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public abstract class AbstractDeferrableInteractionEvent<T extends GenericInteractionCreateEvent> extends AbstractInteractionEvent<T> {
|
public class AbstractInteractionWithHookEvent<T extends GenericInteractionCreateEvent> extends AbstractInteractionEvent<T> {
|
||||||
|
|
||||||
protected final DiscordInteractionHook hook;
|
protected final DiscordInteractionHook hook;
|
||||||
|
|
||||||
public AbstractDeferrableInteractionEvent(
|
public AbstractInteractionWithHookEvent(
|
||||||
T jdaEvent,
|
T jdaEvent,
|
||||||
ComponentIdentifier identifier,
|
ComponentIdentifier identifier,
|
||||||
DiscordUser user,
|
DiscordUser user,
|
@ -30,7 +30,7 @@ import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
|||||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||||
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent;
|
||||||
|
|
||||||
public class DiscordModalInteractionEvent extends AbstractDeferrableInteractionEvent<ModalInteractionEvent> {
|
public class DiscordModalInteractionEvent extends AbstractInteractionWithHookEvent<ModalInteractionEvent> {
|
||||||
|
|
||||||
public DiscordModalInteractionEvent(
|
public DiscordModalInteractionEvent(
|
||||||
ModalInteractionEvent jdaEvent,
|
ModalInteractionEvent jdaEvent,
|
||||||
|
@ -32,7 +32,7 @@ import com.discordsrv.api.discord.entity.guild.DiscordRole;
|
|||||||
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
||||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||||
import com.discordsrv.api.events.discord.interaction.AbstractDeferrableInteractionEvent;
|
import com.discordsrv.api.events.discord.interaction.AbstractInteractionWithHookEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.command.GenericCommandInteractionEvent;
|
||||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -40,7 +40,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public abstract class AbstractCommandInteractionEvent<E extends GenericCommandInteractionEvent>
|
public abstract class AbstractCommandInteractionEvent<E extends GenericCommandInteractionEvent>
|
||||||
extends AbstractDeferrableInteractionEvent<E> {
|
extends AbstractInteractionWithHookEvent<E> {
|
||||||
|
|
||||||
private final DiscordSRVApi discordSRV;
|
private final DiscordSRVApi discordSRV;
|
||||||
|
|
||||||
@ -63,6 +63,8 @@ public abstract class AbstractCommandInteractionEvent<E extends GenericCommandIn
|
|||||||
return reply(message, false);
|
return reply(message, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract CompletableFuture<DiscordInteractionHook> deferReply(boolean ephemeral);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getOptionAsString(String name) {
|
public String getOptionAsString(String name) {
|
||||||
OptionMapping mapping = jdaEvent.getOption(name);
|
OptionMapping mapping = jdaEvent.getOption(name);
|
||||||
|
@ -28,10 +28,10 @@ import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
|||||||
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||||
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
||||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||||
import com.discordsrv.api.events.discord.interaction.AbstractDeferrableInteractionEvent;
|
import com.discordsrv.api.events.discord.interaction.AbstractInteractionWithHookEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
|
||||||
|
|
||||||
public class DiscordButtonInteractionEvent extends AbstractDeferrableInteractionEvent<ButtonInteractionEvent> {
|
public class DiscordButtonInteractionEvent extends AbstractInteractionWithHookEvent<ButtonInteractionEvent> {
|
||||||
|
|
||||||
public DiscordButtonInteractionEvent(
|
public DiscordButtonInteractionEvent(
|
||||||
ButtonInteractionEvent jdaEvent,
|
ButtonInteractionEvent jdaEvent,
|
||||||
@ -39,8 +39,8 @@ public class DiscordButtonInteractionEvent extends AbstractDeferrableInteraction
|
|||||||
DiscordUser user,
|
DiscordUser user,
|
||||||
DiscordGuildMember member,
|
DiscordGuildMember member,
|
||||||
DiscordMessageChannel channel,
|
DiscordMessageChannel channel,
|
||||||
DiscordInteractionHook interaction
|
DiscordInteractionHook hook
|
||||||
) {
|
) {
|
||||||
super(jdaEvent, identifier, user, member, channel, interaction);
|
super(jdaEvent, identifier, user, member, channel, hook);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,10 @@ import com.discordsrv.api.discord.entity.channel.DiscordMessageChannel;
|
|||||||
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||||
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
import com.discordsrv.api.discord.entity.interaction.DiscordInteractionHook;
|
||||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||||
import com.discordsrv.api.events.discord.interaction.AbstractDeferrableInteractionEvent;
|
import com.discordsrv.api.events.discord.interaction.AbstractInteractionWithHookEvent;
|
||||||
import net.dv8tion.jda.api.events.interaction.component.GenericSelectMenuInteractionEvent;
|
import net.dv8tion.jda.api.events.interaction.component.GenericSelectMenuInteractionEvent;
|
||||||
|
|
||||||
public class DiscordSelectMenuInteractionEvent extends AbstractDeferrableInteractionEvent<GenericSelectMenuInteractionEvent<?, ?>> {
|
public class DiscordSelectMenuInteractionEvent extends AbstractInteractionWithHookEvent<GenericSelectMenuInteractionEvent<?, ?>> {
|
||||||
|
|
||||||
public DiscordSelectMenuInteractionEvent(
|
public DiscordSelectMenuInteractionEvent(
|
||||||
GenericSelectMenuInteractionEvent<?, ?> jdaEvent,
|
GenericSelectMenuInteractionEvent<?, ?> jdaEvent,
|
||||||
|
@ -91,7 +91,7 @@ public class ExecuteCommand implements Consumer<DiscordChatInputInteractionEvent
|
|||||||
DiscordCommandConfig.ExecuteConfig config = discordSRV.config().discordCommand.execute;
|
DiscordCommandConfig.ExecuteConfig config = discordSRV.config().discordCommand.execute;
|
||||||
boolean ephemeral = config.ephemeral;
|
boolean ephemeral = config.ephemeral;
|
||||||
if (!config.enabled) {
|
if (!config.enabled) {
|
||||||
event.reply(SendableDiscordMessage.builder().setContent("The execute command is disabled").build(), ephemeral);
|
event.reply(SendableDiscordMessage.builder().setContent("The execute command is disabled").build(), true); // TODO: translation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ public class ExecuteCommand implements Consumer<DiscordChatInputInteractionEvent
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isNotAcceptableCommand(event.getMember(), event.getUser(), command, false)) {
|
if (isNotAcceptableCommand(event.getMember(), event.getUser(), command, false)) {
|
||||||
event.reply(SendableDiscordMessage.builder().setContent("You do not have permission to run that command").build(), ephemeral);
|
event.reply(SendableDiscordMessage.builder().setContent("You do not have permission to run that command").build(), true); // TODO: translation
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,9 +21,12 @@ package com.discordsrv.common.config.main;
|
|||||||
import com.discordsrv.api.discord.entity.interaction.command.CommandOption;
|
import com.discordsrv.api.discord.entity.interaction.command.CommandOption;
|
||||||
import com.discordsrv.api.discord.entity.message.DiscordMessageEmbed;
|
import com.discordsrv.api.discord.entity.message.DiscordMessageEmbed;
|
||||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.common.config.configurate.annotation.Constants;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
@ -48,21 +51,52 @@ public class CustomCommandConfig {
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Comment("The command in Discord, this can be in up-to 3 parts (seperated by spaces).\n"
|
||||||
|
+ "You cannot specify commands on the 2nd and 3rd layer for the same main command at once.\n"
|
||||||
|
+ "You cannot specify a action for the main command if you specify something for the same main command on the 2nd or 3rd layer")
|
||||||
public String command = "";
|
public String command = "";
|
||||||
|
|
||||||
|
@Comment("The description of the command, will be shown to the user")
|
||||||
public String description = "";
|
public String description = "";
|
||||||
|
|
||||||
|
@Comment("If the command output should only be visible to the user who ran the command")
|
||||||
public boolean ephemeral = false;
|
public boolean ephemeral = false;
|
||||||
|
|
||||||
public List<OptionConfig> options = new ArrayList<>();
|
public List<OptionConfig> options = new ArrayList<>();
|
||||||
|
|
||||||
|
@Comment("Only one of the constraints has to be true to allow execution")
|
||||||
|
public List<ConstraintConfig> constraints = new ArrayList<>(Collections.singletonList(new ConstraintConfig()));
|
||||||
|
|
||||||
|
@Comment("A list of console commands to run upon this commands execution")
|
||||||
|
public List<String> consoleCommandsToRun = new ArrayList<>();
|
||||||
|
|
||||||
public SendableDiscordMessage.Builder response = SendableDiscordMessage.builder().setContent("test");
|
public SendableDiscordMessage.Builder response = SendableDiscordMessage.builder().setContent("test");
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public static class OptionConfig {
|
public static class OptionConfig {
|
||||||
|
|
||||||
|
@Comment("Acceptable options are: %1")
|
||||||
|
@Constants.Comment("STRING, LONG, DOUBLE, BOOLEAN, USER, CHANNEL, ROLE, MENTIONABLE, ATTACHMENT")
|
||||||
public CommandOption.Type type = CommandOption.Type.USER;
|
public CommandOption.Type type = CommandOption.Type.USER;
|
||||||
|
|
||||||
|
@Comment("The name of this option, will be shown to the user")
|
||||||
public String name = "target_user";
|
public String name = "target_user";
|
||||||
|
|
||||||
|
@Comment("The description of this option, will be shown to the user")
|
||||||
public String description = "The user to greet";
|
public String description = "The user to greet";
|
||||||
|
|
||||||
|
@Comment("If this option is required to run the command")
|
||||||
public boolean required = true;
|
public boolean required = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public static class ConstraintConfig {
|
||||||
|
|
||||||
|
@Comment("The role and user ids that should/should not be allowed to run this custom command")
|
||||||
|
public List<Long> roleAndUserIds = new ArrayList<>();
|
||||||
|
|
||||||
|
@Comment("true for blacklisting the specified roles and users, false for whitelisting")
|
||||||
|
public boolean blacklist = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,4 +54,12 @@ public class DiscordChatInputInteractionEventImpl extends DiscordChatInputIntera
|
|||||||
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<DiscordInteractionHook> deferReply(boolean ephemeral) {
|
||||||
|
return discordSRV.discordAPI().mapExceptions(
|
||||||
|
() -> jdaEvent.deferReply(ephemeral).submit()
|
||||||
|
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,9 @@ public class DiscordMessageContextInteractionEventImpl extends DiscordMessageCon
|
|||||||
ComponentIdentifier identifier,
|
ComponentIdentifier identifier,
|
||||||
DiscordUser user,
|
DiscordUser user,
|
||||||
DiscordGuildMember member,
|
DiscordGuildMember member,
|
||||||
DiscordMessageChannel channel, DiscordInteractionHook interaction) {
|
DiscordMessageChannel channel,
|
||||||
|
DiscordInteractionHook interaction
|
||||||
|
) {
|
||||||
super(discordSRV, jdaEvent, identifier, user, member, channel, interaction);
|
super(discordSRV, jdaEvent, identifier, user, member, channel, interaction);
|
||||||
this.discordSRV = discordSRV;
|
this.discordSRV = discordSRV;
|
||||||
}
|
}
|
||||||
@ -54,4 +56,12 @@ public class DiscordMessageContextInteractionEventImpl extends DiscordMessageCon
|
|||||||
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<DiscordInteractionHook> deferReply(boolean ephemeral) {
|
||||||
|
return discordSRV.discordAPI().mapExceptions(
|
||||||
|
() -> jdaEvent.deferReply(ephemeral).submit()
|
||||||
|
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,4 +54,12 @@ public class DiscordUserContextInteractionEventImpl extends DiscordUserContextIn
|
|||||||
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<DiscordInteractionHook> deferReply(boolean ephemeral) {
|
||||||
|
return discordSRV.discordAPI().mapExceptions(
|
||||||
|
() -> jdaEvent.deferReply(ephemeral).submit()
|
||||||
|
.thenApply(ih -> new DiscordInteractionHookImpl(discordSRV, ih))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,11 +21,13 @@ package com.discordsrv.common.feature.customcommands;
|
|||||||
import com.discordsrv.api.DiscordSRVApi;
|
import com.discordsrv.api.DiscordSRVApi;
|
||||||
import com.discordsrv.api.discord.entity.DiscordUser;
|
import com.discordsrv.api.discord.entity.DiscordUser;
|
||||||
import com.discordsrv.api.discord.entity.channel.DiscordChannel;
|
import com.discordsrv.api.discord.entity.channel.DiscordChannel;
|
||||||
|
import com.discordsrv.api.discord.entity.guild.DiscordGuildMember;
|
||||||
import com.discordsrv.api.discord.entity.guild.DiscordRole;
|
import com.discordsrv.api.discord.entity.guild.DiscordRole;
|
||||||
import com.discordsrv.api.discord.entity.interaction.command.CommandOption;
|
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.command.DiscordCommand;
|
||||||
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
import com.discordsrv.api.discord.entity.interaction.component.ComponentIdentifier;
|
||||||
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
import com.discordsrv.api.discord.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.api.events.discord.interaction.command.AbstractCommandInteractionEvent;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.main.CustomCommandConfig;
|
import com.discordsrv.common.config.main.CustomCommandConfig;
|
||||||
import com.discordsrv.common.core.logging.NamedLogger;
|
import com.discordsrv.common.core.logging.NamedLogger;
|
||||||
@ -99,73 +101,8 @@ public class CustomCommandModule extends AbstractModule<DiscordSRV> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
commandBuilder.setEventHandler(event -> {
|
ExecutionHandler handler = new ExecutionHandler(config);
|
||||||
SendableDiscordMessage.Formatter formatter = config.response.toFormatter();
|
commandBuilder.setEventHandler(handler::accept);
|
||||||
|
|
||||||
for (CustomCommandConfig.OptionConfig option : config.options) {
|
|
||||||
String optionName = option.name;
|
|
||||||
|
|
||||||
Object context;
|
|
||||||
String reLookup = null;
|
|
||||||
switch (option.type) {
|
|
||||||
case CHANNEL:
|
|
||||||
context = event.getOptionAsChannel(optionName);
|
|
||||||
reLookup = "channel";
|
|
||||||
break;
|
|
||||||
case USER:
|
|
||||||
context = event.getOptionAsUser(optionName);
|
|
||||||
reLookup = "user";
|
|
||||||
break;
|
|
||||||
case ROLE:
|
|
||||||
context = event.getOptionAsRole(optionName);
|
|
||||||
reLookup = "role";
|
|
||||||
break;
|
|
||||||
case MENTIONABLE:
|
|
||||||
Long id = event.getOptionAsLong(optionName);
|
|
||||||
if (id == null) {
|
|
||||||
context = event.getOptionAsString(optionName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DiscordUser user = discordSRV.discordAPI().getUserById(id);
|
|
||||||
if (user != null) {
|
|
||||||
context = user;
|
|
||||||
reLookup = "user";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DiscordRole role = discordSRV.discordAPI().getRoleById(id);
|
|
||||||
if (role != null) {
|
|
||||||
context = role;
|
|
||||||
reLookup = "role";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DiscordChannel channel = discordSRV.discordAPI().getChannelById(id);
|
|
||||||
if (channel != null) {
|
|
||||||
context = channel;
|
|
||||||
reLookup = "channel";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
context = event.getOptionAsString(optionName);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
context = event.getOptionAsString(optionName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
formatter = formatter.addPlaceholder("option_" + optionName, context, reLookup);
|
|
||||||
}
|
|
||||||
|
|
||||||
SendableDiscordMessage message = formatter.applyPlaceholderService().build();
|
|
||||||
event.reply(message, config.ephemeral).whenComplete((ih, t) -> {
|
|
||||||
if (t != null) {
|
|
||||||
logger().debug("Failed to reply to custom command: " + config.command, t);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
DiscordCommand command = commandBuilder.build();
|
DiscordCommand command = commandBuilder.build();
|
||||||
|
|
||||||
LayerCommand foundLayer = layeredCommands.stream()
|
LayerCommand foundLayer = layeredCommands.stream()
|
||||||
@ -230,4 +167,115 @@ public class CustomCommandModule extends AbstractModule<DiscordSRV> {
|
|||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ExecutionHandler implements Consumer<AbstractCommandInteractionEvent<?>> {
|
||||||
|
|
||||||
|
private final CustomCommandConfig config;
|
||||||
|
|
||||||
|
public ExecutionHandler(CustomCommandConfig config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(AbstractCommandInteractionEvent<?> event) {
|
||||||
|
DiscordGuildMember member = event.getMember();
|
||||||
|
if (member == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean anyAllowingConstraint = config.constraints.isEmpty();
|
||||||
|
for (CustomCommandConfig.ConstraintConfig constraint : config.constraints) {
|
||||||
|
boolean included = constraint.roleAndUserIds.contains(member.getUser().getId());
|
||||||
|
if (!included) {
|
||||||
|
for (DiscordRole role : member.getRoles()) {
|
||||||
|
if (constraint.roleAndUserIds.contains(role.getId())) {
|
||||||
|
included = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (included != constraint.blacklist) {
|
||||||
|
anyAllowingConstraint = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!anyAllowingConstraint) {
|
||||||
|
event.reply(SendableDiscordMessage.builder().setContent("You do not have permission to run that command").build(), true); // TODO: translation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> commandsToRun = config.consoleCommandsToRun;
|
||||||
|
for (String command : commandsToRun) {
|
||||||
|
discordSRV.console().runCommandWithLogging(discordSRV, event.getUser(), command);
|
||||||
|
}
|
||||||
|
|
||||||
|
SendableDiscordMessage.Formatter formatter = config.response.toFormatter();
|
||||||
|
optionsToFormatter(event, formatter);
|
||||||
|
|
||||||
|
SendableDiscordMessage message = formatter.applyPlaceholderService().build();
|
||||||
|
event.reply(message, config.ephemeral).whenComplete((__, t) -> {
|
||||||
|
if (t != null) {
|
||||||
|
logger().debug("Failed to reply to custom command: " + config.command, t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void optionsToFormatter(AbstractCommandInteractionEvent<?> event, SendableDiscordMessage.Formatter formatter) {
|
||||||
|
for (CustomCommandConfig.OptionConfig option : config.options) {
|
||||||
|
String optionName = option.name;
|
||||||
|
|
||||||
|
Object context;
|
||||||
|
String reLookup = null;
|
||||||
|
switch (option.type) {
|
||||||
|
case CHANNEL:
|
||||||
|
context = event.getOptionAsChannel(optionName);
|
||||||
|
reLookup = "channel";
|
||||||
|
break;
|
||||||
|
case USER:
|
||||||
|
context = event.getOptionAsUser(optionName);
|
||||||
|
reLookup = "user";
|
||||||
|
break;
|
||||||
|
case ROLE:
|
||||||
|
context = event.getOptionAsRole(optionName);
|
||||||
|
reLookup = "role";
|
||||||
|
break;
|
||||||
|
case MENTIONABLE:
|
||||||
|
Long id = event.getOptionAsLong(optionName);
|
||||||
|
if (id == null) {
|
||||||
|
context = event.getOptionAsString(optionName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscordUser user = discordSRV.discordAPI().getUserById(id);
|
||||||
|
if (user != null) {
|
||||||
|
context = user;
|
||||||
|
reLookup = "user";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscordRole role = discordSRV.discordAPI().getRoleById(id);
|
||||||
|
if (role != null) {
|
||||||
|
context = role;
|
||||||
|
reLookup = "role";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscordChannel channel = discordSRV.discordAPI().getChannelById(id);
|
||||||
|
if (channel != null) {
|
||||||
|
context = channel;
|
||||||
|
reLookup = "channel";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
context = event.getOptionAsString(optionName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
context = event.getOptionAsString(optionName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
formatter = formatter.addPlaceholder("option_" + optionName, context, reLookup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user