dev.maisentito.suca.commands.BotCommands.java Source code

Java tutorial

Introduction

Here is the source code for dev.maisentito.suca.commands.BotCommands.java

Source

/*
 * BotCommands.java
 *
 * Copyright (c) 2015  forsenonlhaimaisentito
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package dev.maisentito.suca.commands;

import dev.maisentito.suca.Main;
import dev.maisentito.suca.listeners.ChannelMessagesPipeline;
import dev.maisentito.suca.util.BotCommand;
import dev.maisentito.suca.util.Bundle;
import dev.maisentito.suca.util.GlobalsUser;
import org.apache.commons.lang3.StringUtils;
import org.pircbotx.hooks.events.MessageEvent;

import java.util.*;

public class BotCommands extends ChannelMessagesPipeline.MessageMiddleware {
    public static final String COMMAND_PREFIX = "!";

    /**
     * Abstract base class for command listeners.
     */
    public static abstract class CommandHandler extends GlobalsUser {
        public CommandHandler(Bundle globals) {
            super(globals);
        }

        /**
         * This method is called when the command associated with this listener is issued.
         *
         * @param event the original {@link org.pircbotx.hooks.events.MessageEvent}
         * @param args  the text following the command name, split by <code>"\\s+"</code>
         * @throws Throwable
         */
        public abstract void handleCommand(MessageEvent event, String[] args) throws Throwable;

        /**
         * This method is called when the help message for this command is requested, it should return a String without
         * newlines or <code>null</code> if not help is available for this command.
         * The default implementation returns <code>null</code>.
         *
         * @param event the original {@link org.pircbotx.hooks.events.MessageEvent}
         * @param args  the text following the !help command, split by <code>"\\s+"</code>
         * @return the one-line help message or <code>null</code>
         */
        public String getHelp(MessageEvent event, String[] args) {
            BotCommand attrs;
            if ((attrs = getClass().getAnnotation(BotCommand.class)) != null) {
                return attrs.help();
            }

            return null;
        }
    }

    private final List<String> mAvailableCommands = new ArrayList<>();
    private final Map<String, CommandHandler> mCommandHandlers = new HashMap<>();

    public BotCommands(Bundle globals) {
        super(globals);
        // Built-in commands
        addCommandHandler("quit", new CommandHandler(getGlobals()) {
            @Override
            public void handleCommand(MessageEvent event, String[] args) throws Throwable {
                if ((!Main.config.verifyOwner || event.getUser().isVerified())
                        && event.getUser().getNick().equals(getStringGlobal(Main.GLOBAL_OWNER, ""))) {
                    event.getBot().stopBotReconnect();
                    event.getBot().sendIRC()
                            .quitServer("I'm quitting, master " + getStringGlobal(Main.GLOBAL_OWNER, ""));
                } else {
                    event.respond("nope");
                }
            }
        });

        addCommandHandler("help", new CommandHandler(getGlobals()) {
            @Override
            public void handleCommand(MessageEvent event, String[] args) throws Throwable {
                if (args.length == 0) {
                    event.respond("Available commands: " + StringUtils.join(mAvailableCommands, ", "));
                    return;
                }

                String command = args[0].replace(COMMAND_PREFIX, "");
                String help;

                if (!mCommandHandlers.containsKey(command)) {
                    event.respond("command not found: " + args[0]);
                } else if ((help = mCommandHandlers.get(command).getHelp(event, args)) != null) {
                    event.respond("help for command " + args[0] + ": " + help);
                } else {
                    event.respond("no help available for command " + args[0]);
                }
            }
        });
    }

    public void addCommandHandler(CommandHandler handler) {
        BotCommand attrs;
        if ((handler != null) && ((attrs = handler.getClass().getAnnotation(BotCommand.class)) != null)) {
            addCommandHandler(attrs.name(), handler);
        }
    }

    public void addCommandHandler(String command, CommandHandler handler) {
        if ((command != null) && (handler != null)) {
            mCommandHandlers.put(command, handler);
            mAvailableCommands.add(COMMAND_PREFIX + command);
        }
    }

    public void removeCommandHandler(String command) {
        if (command != null) {
            mCommandHandlers.remove(command);
            mAvailableCommands.remove(COMMAND_PREFIX + command);
        }
    }

    public static String[] parseCommandArgs(String message) {
        String[] parts = message.trim().substring(1).split("\\s+");
        if (parts.length > 1) {
            return Arrays.copyOfRange(parts, 1, parts.length);
        } else {
            return new String[0];
        }
    }

    @Override
    public boolean onMessage(MessageEvent event) throws Throwable {
        if (event.getMessage().startsWith(COMMAND_PREFIX) && !event.getUser().equals(event.getBot().getUserBot())) {
            String[] parts = event.getMessage().substring(1).split("\\s+");
            if ((parts.length > 0) && (mCommandHandlers.containsKey(parts[0]))) {
                CommandHandler handler = mCommandHandlers.get(parts[0]);

                BotCommand attrs = handler.getClass().getAnnotation(BotCommand.class);
                if ((attrs != null) && (parts.length <= attrs.minArgc())) {
                    event.respond(COMMAND_PREFIX + parts[0] + ": not enough arguments");
                    return true;
                }

                if (parts.length > 1) {
                    handler.handleCommand(event, Arrays.copyOfRange(parts, 1, parts.length));
                } else {
                    handler.handleCommand(event, new String[] {});
                }
                return true;
            }
        }
        return false;
    }
}