Chew / JDA-Chewtils

Chew's fork of JDA-Applications/JDA-Utilities, with support for modern features such as Slash Commands, Context Menus, and more.

Home Page:https://chew.pro/JDA-Chewtils

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add a way to provide/use own interfaces/classes/... for SlashCommands

Andre601 opened this issue · comments

Issue Checklist

  • I have checked for similar issues on the Issue tracker
  • I have updated to the latest version of JDA-Chewtils.
  • I have checked the branches or the maintainer's PRs for upcoming features and updates.

Affected Modules

Command

Description

It would be useful, if there was a sort of SlashCommandPreProcess method or alike that would allow me (and probably many others) to do the most common checks on a slash command such as if it was from a guild.

What could be somewhat problematic is to decide how stuff is returned... Should it stay a SlashCommandEvent, or should it already be handled (deferReply()?) and then the InteractionHook returned?

I personally would find it cool, if we could "override" the default execute method to have our own instead.

To explain what I mean with that, I want to quickly show an example of what I'm currently using in my bot with message-based commands.
I'm using a different library for those commands called JDA-Command, which provides and uses an interface called AbstractCommand<T>. Since my commands are always with JDA Message objects and only work in Guilds did I "override" it by extending a Command interface I made with it to then override the method with my own:
https://github.com/purrbot-site/PurrBot/blob/2f44f14757bbbd6d82ca29bffa41bb53d42da232/src/main/java/site/purrbot/bot/commands/Command.java

This basically allowed me to reduce commonly made checks and actions and have a bit more safety about things (i.e. that Guild and Member are always present)

Having a similar way in Chewtils would help a lot, because then I could check if the command is from a Guild, obtain user/member and the textchannel instance and if they are null return an error before processing it further...

I hope you get what I mean... I'm not the best at explaining stuff...

Would you like a ISlashCommand interface that you can implement, as long as it has whatever the library requires?

Could be a solution.

My personal goal is just a way to have Chewtils handle the SlashCommandEvent in one central place and then execute a method for the respective command class that would have stuff...

If I understand interfaces correctly do I currently have a setup like this:

  • Command
    public class CmdSomething extends SlashCommand implements CommandConverter {
    
        private final Bot bot;
    
        public CmdSomething(Bot bot) {
            this.bot = bot;
            
            this.name = "something";
            this.help = "Does something";
        }
        
        @Override
        protected void execute(SlashCommandEvent event) {
            this.convertCommand(event, bot);
        }
        
        @Override
        public void handle(SlashCommandEvent event, InteractionHook hook, Guild guild, TextChannel tc, Member member) {
            // Do stuff here
        }
    }
  • CommandConverter interface
    public interface CommandConverter {
    
        default void convertCommand(SlashCommandEvent event, Bot bot) {
            Guild guild = event.getGuild();
            if (guild == null) {
                CommandUtil.replyError(event, "Command can only be executed within a Guild");
                return;
            }
            
            Member member = event.getMember();
            if (member == null) {
                CommandUtil.replyErrorTranslated(event, bot, guild, "errors.no_member");
                return;
            }
            
            event.deferReply().queue(hook -> handle(event, hook, guild, event.getTextChannel(), member);
        }
        
        void handle(SlashCommandEvent event, InteractionHook hook, Guild guild, TextChannel tc, Member member);
    }

It'd be something like this:

Chewtils has a ISlashCommand

Then you have your own Impl, (SlashCommand will be an impl as well)

Maybe like this:

public class MyCustomSlashCommand implements ISlashCommand {
    public void handle(SlashCommandEvent event) {
        // the cool stuff

        run(); // method in interface
    }
}

Then in your own bot:

public class SuperCommand extends MyCustomSlashCommand {
    // code like normal
}

This is merely a theory, I'm sure something like it is possible.