diff --git a/src/main/java/me/youhavetrouble/inviter/Main.java b/src/main/java/me/youhavetrouble/inviter/Main.java index e872332..2e347a5 100644 --- a/src/main/java/me/youhavetrouble/inviter/Main.java +++ b/src/main/java/me/youhavetrouble/inviter/Main.java @@ -1,6 +1,9 @@ package me.youhavetrouble.inviter; +import me.youhavetrouble.inviter.discord.command.ApiStatusChangeCommand; +import me.youhavetrouble.inviter.discord.command.Command; import me.youhavetrouble.inviter.discord.listener.GuildJoinAndLeaveListener; +import me.youhavetrouble.inviter.discord.listener.SlashCommandInteractionListener; import me.youhavetrouble.inviter.http.ApiServer; import me.youhavetrouble.inviter.discord.DiscordInviteManager; import me.youhavetrouble.inviter.storage.SqliteStorage; @@ -76,11 +79,16 @@ public class Main { jda = JDABuilder.createLight(token, Set.of(GatewayIntent.GUILD_INVITES)) .setCallbackPool(Executors.newVirtualThreadPerTaskExecutor()) - .addEventListeners(new GuildJoinAndLeaveListener()) + .addEventListeners( + new GuildJoinAndLeaveListener(), + new SlashCommandInteractionListener() + ) .build(); jda.awaitReady(); + Command.registerCommand(new ApiStatusChangeCommand()); + jda.getGuilds().parallelStream().forEach(guild -> storage.saveDefaultGuildSettings(guild.getIdLong())); discordInviteManager = new DiscordInviteManager(jda); @@ -92,7 +100,7 @@ public class Main { System.exit(1); } - LOGGER.info("Welcome to the Inviter Application!"); + LOGGER.info("Inviter is up and running!"); } public static JDA getJda() { diff --git a/src/main/java/me/youhavetrouble/inviter/discord/command/ApiStatusChangeCommand.java b/src/main/java/me/youhavetrouble/inviter/discord/command/ApiStatusChangeCommand.java new file mode 100644 index 0000000..87c2b83 --- /dev/null +++ b/src/main/java/me/youhavetrouble/inviter/discord/command/ApiStatusChangeCommand.java @@ -0,0 +1,67 @@ +package me.youhavetrouble.inviter.discord.command; + +import me.youhavetrouble.inviter.Main; +import me.youhavetrouble.inviter.discord.GuildSettings; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.IntegrationType; +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.OptionData; +import org.jetbrains.annotations.Nullable; + +public class ApiStatusChangeCommand extends Command { + + @Nullable + public String getName() { + return "api"; + } + + public void register(JDA jda, String name) { + jda.upsertCommand(Commands.slash("api", "Change if Inviter API should allow to retrieve this server's invites.") + .setIntegrationTypes(IntegrationType.GUILD_INSTALL) + .addOptions( + new OptionData(OptionType.BOOLEAN, "status", "Status of the api availability for this guild", false) + ) + .setContexts(InteractionContextType.GUILD) + .setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MANAGE_SERVER)) + ).queue(); + } + + @Override + public void execute(SlashCommandInteractionEvent event) { + OptionMapping statusMapping = event.getOption("status"); + + Guild guild = event.getGuild(); + if (guild == null) { + event.reply("This command can only be used in a guild.").setEphemeral(true).queue(); + return; + } + + event.deferReply(true).queue(); + + if (statusMapping == null) { + GuildSettings setings = Main.getStorage().getGuildSettings(guild.getIdLong()); + + String message = setings.apiEnabled() ? + "Inviter API is currently __**enabled**__ for this server." : + "Inviter API is currently __**disabled**__ for this server."; + + event.getHook().editOriginal(message).queue(); + return; + } + + boolean status = statusMapping.getAsBoolean(); + long guildId = guild.getIdLong(); + + Main.getStorage().updateDiscordApiEnabled(guildId, status); + String message = status ? "Inviter API is now __**enabled**__ for this server." : "Inviter API is now __**disabled**__ for this server."; + event.getHook().editOriginal(message).queue(); + } + +} diff --git a/src/main/java/me/youhavetrouble/inviter/discord/command/Command.java b/src/main/java/me/youhavetrouble/inviter/discord/command/Command.java new file mode 100644 index 0000000..aa19bd8 --- /dev/null +++ b/src/main/java/me/youhavetrouble/inviter/discord/command/Command.java @@ -0,0 +1,56 @@ +package me.youhavetrouble.inviter.discord.command; + +import me.youhavetrouble.inviter.Main; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +public abstract class Command extends ListenerAdapter { + + private static final Map commands = new HashMap<>(); + + public abstract void register(JDA jda, String name); + + public abstract void execute(SlashCommandInteractionEvent event); + + public abstract String getName(); + + boolean canUse(User user) { + return true; + } + + public static void registerCommand(Command command) { + String name = command.getName(); + if (commands.containsKey(name)) { + Main.LOGGER.warn("Command {} is already registered.", name); + return; + } + command.register(Main.getJda(), name); + commands.put(name, command); + } + + public static void executeCommand(SlashCommandInteractionEvent event, String name) { + Command command = commands.get(name.toLowerCase(Locale.ENGLISH)); + if (command == null) { + event.reply("Unknown command.") + .setEphemeral(true) + .queue(); + return; + } + + if (!command.canUse(event.getUser())) { + event.reply("You do not have permission to use this command.") + .setEphemeral(true) + .queue(); + return; + } + + command.execute(event); + } + +} diff --git a/src/main/java/me/youhavetrouble/inviter/discord/listener/SlashCommandInteractionListener.java b/src/main/java/me/youhavetrouble/inviter/discord/listener/SlashCommandInteractionListener.java new file mode 100644 index 0000000..1435096 --- /dev/null +++ b/src/main/java/me/youhavetrouble/inviter/discord/listener/SlashCommandInteractionListener.java @@ -0,0 +1,15 @@ +package me.youhavetrouble.inviter.discord.listener; + +import me.youhavetrouble.inviter.discord.command.Command; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +public class SlashCommandInteractionListener extends ListenerAdapter { + + @Override + public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { + String command = event.getName(); + Command.executeCommand(event, command); + } + +}