# Source code
source: package: co.aikar.commands, class: JDACommandManager

    001package co.aikar.commands;
    002
    003import co.aikar.commands.apachecommonslang.ApacheCommonsExceptionUtil;
    004import net.dv8tion.jda.api.AccountType;
    005import net.dv8tion.jda.api.JDA;
    006import net.dv8tion.jda.api.entities.ChannelType;
    007import net.dv8tion.jda.api.entities.Message;
    008import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
    009import org.jetbrains.annotations.NotNull;
    010
    011import java.util.Arrays;
    012import java.util.Collection;
    013import java.util.Collections;
    014import java.util.HashMap;
    015import java.util.List;
    016import java.util.Locale;
    017import java.util.Map;
    018import java.util.logging.Level;
    019import java.util.logging.Logger;
    020
    021public class JDACommandManager extends CommandManager<
    022        MessageReceivedEvent,
    023        JDACommandEvent,
    024        String,
    025        MessageFormatter<String>,
    026        JDACommandExecutionContext,
    027        JDAConditionContext
    028        > {
    029
    030    private final JDA jda;
    031    protected JDACommandCompletions completions;
    032    protected JDACommandContexts contexts;
    033    protected JDALocales locales;
    034    protected Map<String, JDARootCommand> commands = new HashMap<>();
    035    private Logger logger;
    036    private CommandConfig defaultConfig;
    037    private CommandConfigProvider configProvider;
    038    private CommandPermissionResolver permissionResolver;
    039    private long botOwner = 0L;
    040
    041    public JDACommandManager(JDA jda) {
    042        this(jda, null);
    043    }
    044
    045    public JDACommandManager(JDA jda, JDAOptions options) {
    046        if (options == null) {
    047            options = new JDAOptions();
    048        }
    049        this.jda = jda;
    050        this.permissionResolver = options.permissionResolver;
    051        jda.addEventListener(new JDAListener(this));
    052        this.defaultConfig = options.defaultConfig == null ? new JDACommandConfig() : options.defaultConfig;
    053        this.configProvider = options.configProvider;
    054        this.defaultFormatter = new JDAMessageFormatter();
    055        this.completions = new JDACommandCompletions(this);
    056        this.logger = Logger.getLogger(this.getClass().getSimpleName());
    057
    058        getCommandConditions().addCondition("owneronly", context -> {
    059            if (context.getIssuer().getEvent().getAuthor().getIdLong() != getBotOwnerId()) {
    060                throw new ConditionFailedException("Only the bot owner can use this command."); // TODO: MessageKey
    061            }
    062        });
    063
    064        getCommandConditions().addCondition("guildonly", context -> {
    065            if (context.getIssuer().getEvent().getChannelType() != ChannelType.TEXT) {
    066                throw new ConditionFailedException("This command must be used in guild chat."); // TODO: MessageKey
    067            }
    068        });
    069
    070        getCommandConditions().addCondition("privateonly", context -> {
    071            if (context.getIssuer().getEvent().getChannelType() != ChannelType.PRIVATE) {
    072                throw new ConditionFailedException("This command must be used in private chat."); // TODO: MessageKey
    073            }
    074        });
    075
    076        getCommandConditions().addCondition("grouponly", context -> {
    077            if (context.getIssuer().getEvent().getChannelType() != ChannelType.GROUP) {
    078                throw new ConditionFailedException("This command must be used in group chat."); // TODO: MessageKey
    079            }
    080        });
    081    }
    082
    083    public static JDAOptions options() {
    084        return new JDAOptions();
    085    }
    086
    087    void initializeBotOwner() {
    088        if (botOwner == 0L) {
    089            if (jda.getAccountType() == AccountType.BOT) {
    090                botOwner = jda.retrieveApplicationInfo().complete().getOwner().getIdLong();
    091            } else {
    092                botOwner = jda.getSelfUser().getIdLong();
    093            }
    094        }
    095    }
    096
    097    public long getBotOwnerId() {
    098        // Just in case initialization on ReadyEvent fails.
    099        initializeBotOwner();
    100        return botOwner;
    101    }
    102
    103    public JDA getJDA() {
    104        return jda;
    105    }
    106
    107    public Logger getLogger() {
    108        return logger;
    109    }
    110
    111    public void setLogger(Logger logger) {
    112        this.logger = logger;
    113    }
    114
    115    public CommandConfig getDefaultConfig() {
    116        return defaultConfig;
    117    }
    118
    119    public void setDefaultConfig(@NotNull CommandConfig defaultConfig) {
    120        this.defaultConfig = defaultConfig;
    121    }
    122
    123    public CommandConfigProvider getConfigProvider() {
    124        return configProvider;
    125    }
    126
    127    public void setConfigProvider(CommandConfigProvider configProvider) {
    128        this.configProvider = configProvider;
    129    }
    130
    131    public CommandPermissionResolver getPermissionResolver() {
    132        return permissionResolver;
    133    }
    134
    135    public void setPermissionResolver(CommandPermissionResolver permissionResolver) {
    136        this.permissionResolver = permissionResolver;
    137    }
    138
    139    @Override
    140    public CommandContexts<?> getCommandContexts() {
    141        if (this.contexts == null) {
    142            this.contexts = new JDACommandContexts(this);
    143        }
    144        return this.contexts;
    145    }
    146
    147    @Override
    148    public CommandCompletions<?> getCommandCompletions() {
    149        return this.completions;
    150    }
    151
    152    @Override
    153    public void registerCommand(BaseCommand command) {
    154        command.onRegister(this);
    155        for (Map.Entry<String, RootCommand> entry : command.registeredCommands.entrySet()) {
    156            String commandName = entry.getKey().toLowerCase(Locale.ENGLISH);
    157            JDARootCommand cmd = (JDARootCommand) entry.getValue();
    158            if (!cmd.isRegistered) {
    159                cmd.isRegistered = true;
    160                commands.put(commandName, cmd);
    161            }
    162        }
    163    }
    164
    165    public void unregisterCommand(BaseCommand command) {
    166        for (Map.Entry<String, RootCommand> entry : command.registeredCommands.entrySet()) {
    167            String jdaCommandName = entry.getKey().toLowerCase(Locale.ENGLISH);
    168            JDARootCommand jdaCommand = (JDARootCommand) entry.getValue();
    169            jdaCommand.getSubCommands().values().removeAll(command.subCommands.values());
    170            if (jdaCommand.isRegistered && jdaCommand.getSubCommands().isEmpty()) {
    171                jdaCommand.isRegistered = false;
    172                commands.remove(jdaCommandName);
    173            }
    174        }
    175    }
    176
    177    @Override
    178    public boolean hasRegisteredCommands() {
    179        return !this.commands.isEmpty();
    180    }
    181
    182    @Override
    183    public boolean isCommandIssuer(Class<?> type) {
    184        return JDACommandEvent.class.isAssignableFrom(type);
    185    }
    186
    187    @Override
    188    public JDACommandEvent getCommandIssuer(Object issuer) {
    189        if (!(issuer instanceof MessageReceivedEvent)) {
    190            throw new IllegalArgumentException(issuer.getClass().getName() + " is not a Message Received Event.");
    191        }
    192        return new JDACommandEvent(this, (MessageReceivedEvent) issuer);
    193    }
    194
    195    @Override
    196    public RootCommand createRootCommand(String cmd) {
    197        return new JDARootCommand(this, cmd);
    198    }
    199
    200    @Override
    201    public Collection<RootCommand> getRegisteredRootCommands() {
    202        return Collections.unmodifiableCollection(commands.values());
    203    }
    204
    205    @Override
    206    public Locales getLocales() {
    207        if (this.locales == null) {
    208            this.locales = new JDALocales(this);
    209            this.locales.loadLanguages();
    210        }
    211        return this.locales;
    212    }
    213
    214    @Override
    215    public CommandExecutionContext createCommandContext(RegisteredCommand command, CommandParameter parameter, CommandIssuer sender, List<String> args, int i, Map<String, Object> passedArgs) {
    216        return new JDACommandExecutionContext(command, parameter, (JDACommandEvent) sender, args, i, passedArgs);
    217    }
    218
    219    @Override
    220    public CommandCompletionContext createCompletionContext(RegisteredCommand command, CommandIssuer sender, String input, String config, String[] args) {
    221        // Not really going to be used;
    222        //noinspection unchecked
    223        return new CommandCompletionContext(command, sender, input, config, args);
    224    }
    225
    226    @Override
    227    public void log(LogLevel level, String message, Throwable throwable) {
    228        Level logLevel = level == LogLevel.INFO ? Level.INFO : Level.SEVERE;
    229        logger.log(logLevel, LogLevel.LOG_PREFIX + message);
    230        if (throwable != null) {
    231            for (String line : ACFPatterns.NEWLINE.split(ApacheCommonsExceptionUtil.getFullStackTrace(throwable))) {
    232                logger.log(logLevel, LogLevel.LOG_PREFIX + line);
    233            }
    234        }
    235    }
    236
    237    void dispatchEvent(MessageReceivedEvent event) {
    238        Message message = event.getMessage();
    239        String msg = message.getContentRaw();
    240
    241        CommandConfig config = getCommandConfig(event);
    242
    243        String prefixFound = null;
    244        for (String prefix : config.getCommandPrefixes()) {
    245            if (msg.startsWith(prefix)) {
    246                prefixFound = prefix;
    247                break;
    248            }
    249        }
    250        if (prefixFound == null) {
    251            return;
    252        }
    253
    254        String[] args = ACFPatterns.SPACE.split(msg.substring(prefixFound.length()), -1);
    255        if (args.length == 0) {
    256            return;
    257        }
    258        String cmd = args[0].toLowerCase(Locale.ENGLISH);
    259        JDARootCommand rootCommand = this.commands.get(cmd);
    260        if (rootCommand == null) {
    261            return;
    262        }
    263        if (args.length > 1) {
    264            args = Arrays.copyOfRange(args, 1, args.length);
    265        } else {
    266            args = new String[0];
    267        }
    268        rootCommand.execute(this.getCommandIssuer(event), cmd, args);
    269    }
    270
    271    private CommandConfig getCommandConfig(MessageReceivedEvent event) {
    272        CommandConfig config = this.defaultConfig;
    273        if (this.configProvider != null) {
    274            CommandConfig provided = this.configProvider.provide(event);
    275            if (provided != null) {
    276                config = provided;
    277            }
    278        }
    279        return config;
    280    }
    281
    282
    283    @Override
    284    public String getCommandPrefix(CommandIssuer issuer) {
    285        MessageReceivedEvent event = ((JDACommandEvent) issuer).getEvent();
    286        CommandConfig commandConfig = getCommandConfig(event);
    287        List<String> prefixes = commandConfig.getCommandPrefixes();
    288        return prefixes.isEmpty() ? "" : prefixes.get(0);
    289    }
    290}