/* * This file is part of Foxbot. * * Foxbot 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. * * Foxbot 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 Foxbot. If not, see <http://www.gnu.org/licenses/>. */ package co.foxdev.foxbot; import co.foxdev.foxbot.commands.Command; import co.foxdev.foxbot.config.Config; import co.foxdev.foxbot.permissions.PermissionManager; import co.foxdev.foxbot.utils.CommandManager; import com.google.common.base.Charsets; import com.maxmind.geoip.LookupService; import lombok.Getter; import org.pircbotx.Configuration; import org.pircbotx.PircBotX; import org.pircbotx.UtilSSLSocketFactory; import org.pircbotx.exception.IrcException; import org.pircbotx.hooks.ListenerAdapter; import org.reflections.Reflections; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.SSLSocketFactory; import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * FoxBot - A highly configurable IRC bot * * @author TheReverend403 (Lee Watson) - https://revthefox.co.uk * @website http://foxbot.foxdev.co * @repo https://github.com/FoxDev/FoxBot */ public class FoxBot { private PircBotX bot; private Configuration.Builder configBuilder; @Getter private static FoxBot instance; @Getter private Config config; @Getter private Logger logger; @Getter private PermissionManager permissionManager; @Getter private CommandManager commandManager; @Getter private LookupService lookupService; @Getter private Reflections reflections = new Reflections("co.foxdev.foxbot"); public static void main(String[] args) { FoxBot me = new FoxBot(); me.start(args); } private void start(String[] args) { instance = this; logger = LoggerFactory.getLogger(getClass().getName()); File path = new File("data/custcmds"); if (!path.exists() && !path.mkdirs()) { logger.info("Could not create required folders (data/custcmds/). Shutting down."); shutdown(); return; } config = new Config(this); permissionManager = new PermissionManager(this); commandManager = new CommandManager(this); try { lookupService = new LookupService(new File("data/GeoLiteCity.dat"), LookupService.GEOIP_STANDARD); } catch (IOException ex) { logger.warn("GeoIP database not found, GeoIP feature will be unavailable."); logger.warn("Download a database from http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz and extract it to data/GeoLiteCity.dat"); } setBotInfo(); registerListeners(); registerCommands(); connectToServer(); } private void setBotInfo() { configBuilder = new Configuration.Builder(); configBuilder.setEncoding(Charsets.UTF_8); logger.info("Setting bot info"); configBuilder.setAutoNickChange(config.getAutoNickChange()); logger.info(String.format("Set auto nick change to %s", config.getAutoNickChange())); configBuilder.setAutoReconnect(config.getAutoReconnect()); logger.info(String.format("Set auto-reconnect to %s", config.getAutoReconnect())); configBuilder.setMessageDelay(config.getMessageDelay()); logger.info(String.format("Set message delay to %s", config.getMessageDelay())); configBuilder.setCapEnabled(true); configBuilder.setRealName(config.getBotRealName()); configBuilder.setVersion(String.format("FoxBot - A Java IRC bot written by FoxDev and owned by %s - http://foxbot.foxdev.co - Use %shelp for more info", config.getBotOwner(), config.getCommandPrefix())); logger.info(String.format("Set version to 'FoxBot - A Java IRC bot written by FoxDev and owned by %s - https://github.com/FoxDev/FoxBot - Use %shelp for more info'", config.getBotOwner(), config.getCommandPrefix())); configBuilder.setAutoSplitMessage(true); configBuilder.setName(config.getBotNick()); logger.info(String.format("Set nick to '%s'", config.getBotNick())); configBuilder.setLogin(config.getBotIdent()); logger.info(String.format("Set ident to '%s'", config.getBotIdent())); } private void connectToServer() { configBuilder.setServer(config.getServerAddress(), config.getServerPort(), config.getServerPassword()); if (config.getServerSsl()) { configBuilder.setSocketFactory(config.getAcceptInvalidSsl() ? new UtilSSLSocketFactory().trustAllCertificates().disableDiffieHellman() : SSLSocketFactory.getDefault()); } if (config.useNickserv()) { configBuilder.setNickservPassword(config.getNickservPassword()); } logger.info(String.format("Connecting to %s on port %s%s...", config.getServerAddress(), config.getServerPort(), config.getServerSsl() ? " with SSL" : " without SSL")); logger.info("Adding channels..."); for (String channel : config.getChannels()) { if (channel.contains(":")) { String[] parts = channel.split(":"); configBuilder.addAutoJoinChannel(parts[0], parts[1]); continue; } configBuilder.addAutoJoinChannel(channel); } try { bot = new PircBotX(configBuilder.buildConfiguration()); bot.startBot(); } catch (IOException | IrcException ex) { logger.error("Error occurred while connecting", ex); shutdown(); } } // Automatically loads and registers all classes extending ListenerAdapter.class private void registerListeners() { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); try { for (Class clazz : reflections.getSubTypesOf(ListenerAdapter.class)) { classLoader.loadClass(clazz.getName()); Constructor clazzConstructor = clazz.getConstructor(getClass()); ListenerAdapter listener = (ListenerAdapter) clazzConstructor.newInstance(this); configBuilder.getListenerManager().addListener(listener); logger.info(String.format("Registered listener '%s'", listener.getClass().getSimpleName())); } } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException ex) { logger.error("Error registering listener", ex); } } // Automatically loads and registers all classes extending Command.class private void registerCommands() { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); try { for (Class clazz : reflections.getSubTypesOf(Command.class)) { classLoader.loadClass(clazz.getName()); Constructor clazzConstructor = clazz.getConstructor(getClass()); Command command = (Command) clazzConstructor.newInstance(this); commandManager.registerCommand(command); logger.info(String.format("Registered command '%s'", command.getName())); } } catch (ClassNotFoundException | InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException ex) { logger.error("Error registering command", ex); } } public void shutdown() { bot.sendIRC().quitServer(); bot.stopBotReconnect(); } public PircBotX bot() { return bot; } }