feat: very ass discord slash commands

This commit is contained in:
ChomeNS
2025-05-25 09:21:05 +07:00
parent 040be16246
commit 95a1f58fe1
5 changed files with 129 additions and 26 deletions

View File

@@ -8,8 +8,8 @@ import me.chayapak1.chomens_bot.util.ComponentUtilities;
import me.chayapak1.chomens_bot.util.I18nUtilities;
import me.chayapak1.chomens_bot.util.UUIDUtilities;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.utils.FileUpload;
import net.kyori.adventure.text.Component;
import org.geysermc.mcprotocollib.auth.GameProfile;
@@ -17,24 +17,35 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
import java.awt.*;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
public class DiscordCommandContext extends CommandContext {
public final MessageReceivedEvent event;
public final Member member;
public final String name;
public final Consumer<FileUpload> replyFiles;
public final Consumer<MessageEmbed> replyEmbed;
private final Bot bot;
public DiscordCommandContext (final Bot bot, final String prefix, final MessageReceivedEvent event) {
public DiscordCommandContext (
final Bot bot,
final String prefix,
final Member member,
final String name,
final Consumer<FileUpload> replyFiles,
final Consumer<MessageEmbed> replyEmbed
) {
super(
bot,
prefix,
new PlayerEntry(
new GameProfile(
UUIDUtilities.getOfflineUUID(event.getAuthor().getName()),
event.getAuthor().getName()
UUIDUtilities.getOfflineUUID(name),
name
),
GameMode.SURVIVAL,
-69420,
Component.text(event.getAuthor().getName()),
Component.text(name),
0L,
null,
new byte[0],
@@ -43,7 +54,10 @@ public class DiscordCommandContext extends CommandContext {
false
);
this.bot = bot;
this.event = event;
this.member = member;
this.name = name;
this.replyFiles = replyFiles;
this.replyEmbed = replyEmbed;
}
@Override
@@ -55,12 +69,12 @@ public class DiscordCommandContext extends CommandContext {
if (output.length() > 2048) {
output = ComponentUtilities.stringify(rendered);
event.getMessage().replyFiles(
replyFiles.accept(
FileUpload.fromData(
output.getBytes(StandardCharsets.UTF_8),
String.format("output-%d.txt", System.currentTimeMillis())
)
).queue();
);
} else {
final EmbedBuilder builder = new EmbedBuilder();
builder.setTitle("Output");
@@ -69,12 +83,12 @@ public class DiscordCommandContext extends CommandContext {
final MessageEmbed embed = builder.build();
event.getMessage().replyEmbeds(embed).queue();
replyEmbed.accept(embed);
}
}
@Override
public Component displayName () {
return Component.text(event.getAuthor().getName());
return Component.text(name);
}
}

View File

@@ -59,7 +59,14 @@ public class GuildMessageEventHandler extends ListenerAdapter {
final String messageString = messageObject.getContentDisplay();
if (messageString.startsWith(prefix)) {
final DiscordCommandContext context = new DiscordCommandContext(bot, prefix, event);
final DiscordCommandContext context = new DiscordCommandContext(
bot,
prefix,
event.getMember(),
event.getAuthor().getName(),
fileUpload -> messageObject.replyFiles(fileUpload).queue(),
embed -> messageObject.replyEmbeds(embed).queue()
);
bot.commandHandler.executeCommand(messageString.substring(prefix.length()), context);

View File

@@ -0,0 +1,92 @@
package me.chayapak1.chomens_bot.discord;
import me.chayapak1.chomens_bot.Bot;
import me.chayapak1.chomens_bot.Main;
import me.chayapak1.chomens_bot.command.Command;
import me.chayapak1.chomens_bot.command.contexts.DiscordCommandContext;
import me.chayapak1.chomens_bot.plugins.CommandHandlerPlugin;
import me.chayapak1.chomens_bot.util.I18nUtilities;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.InteractionContextType;
import net.dv8tion.jda.api.interactions.commands.DefaultMemberPermissions;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData;
import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
import org.jetbrains.annotations.NotNull;
public class SlashCommandHandler extends ListenerAdapter {
private final JDA jda;
public SlashCommandHandler (final JDA jda) {
this.jda = jda;
addCommands();
jda.addEventListener(this);
}
private void addCommands () {
CommandListUpdateAction commandListAction = jda.updateCommands();
for (final Command command : CommandHandlerPlugin.COMMANDS) {
if (command.consoleOnly) continue;
final SlashCommandData commandData = Commands.slash(
command.name,
I18nUtilities.get(
String.format(
"commands.%s.description",
command.name
)
)
);
commandData
.setContexts(InteractionContextType.GUILD)
.setDefaultPermissions(DefaultMemberPermissions.ENABLED)
.addOption(OptionType.STRING, "args", "Arguments for the command");
commandListAction = commandListAction.addCommands(commandData);
}
commandListAction.queue();
}
@Override
public void onSlashCommandInteraction (@NotNull final SlashCommandInteractionEvent event) {
boolean found = false;
for (final Bot bot : Main.bots) {
final String channelId = Main.discord.findChannelId(bot.options.discordChannel);
if (channelId == null || !event.getChannel().getId().equals(channelId)) continue;
if (!found) found = true;
final DiscordCommandContext context = new DiscordCommandContext(
bot,
"/",
event.getMember(),
event.getUser().getName(),
fileUpload -> event.getInteraction().replyFiles(fileUpload).queue(),
embed -> event.getInteraction().replyEmbeds(embed).queue()
);
final OptionMapping args = event.getOption("args");
// seems very ass
final String input = event.getName() +
(args != null
? " " + args.getAsString()
: ""
);
bot.commandHandler.executeCommand(input, context);
}
if (!found) event.reply("You are not in one of the bot's log channels!").queue();
}
}

View File

@@ -13,7 +13,6 @@ import me.chayapak1.chomens_bot.data.listener.Listener;
import me.chayapak1.chomens_bot.util.ExceptionUtilities;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -110,17 +109,6 @@ public class CommandHandlerPlugin implements Listener {
) {
final boolean inGame = context instanceof PlayerCommandContext;
final boolean discord;
final MessageReceivedEvent event;
if (context instanceof final DiscordCommandContext discordContext) {
discord = true;
event = discordContext.event;
} else {
discord = false;
event = null;
}
final boolean bypass = context instanceof ConsoleCommandContext || context instanceof ChomeNSModCommandContext;
if (commandsPerSecond.get() > 100) return;
@@ -195,8 +183,8 @@ public class CommandHandlerPlugin implements Listener {
}
context.trustLevel = remote.source.trustLevel;
} else if (discord) {
final Member member = event.getMember();
} else if (context instanceof final DiscordCommandContext discordCommandContext) {
final Member member = discordCommandContext.member;
if (member == null) return;

View File

@@ -7,6 +7,7 @@ import me.chayapak1.chomens_bot.data.listener.Listener;
import me.chayapak1.chomens_bot.discord.DirectMessageEventHandler;
import me.chayapak1.chomens_bot.discord.GuildMessageEventHandler;
import me.chayapak1.chomens_bot.discord.MessageLogger;
import me.chayapak1.chomens_bot.discord.SlashCommandHandler;
import me.chayapak1.chomens_bot.util.CodeBlockUtilities;
import me.chayapak1.chomens_bot.util.ComponentUtilities;
import me.chayapak1.chomens_bot.util.I18nUtilities;
@@ -88,6 +89,7 @@ public class DiscordPlugin {
new MessageLogger(jda);
new GuildMessageEventHandler(jda, prefix, messagePrefix);
new DirectMessageEventHandler(jda, options);
new SlashCommandHandler(jda);
Main.EXECUTOR.scheduleAtFixedRate(this::onDiscordTick, 0, 50, TimeUnit.MILLISECONDS);