package handiebot.command; import handiebot.utils.DisappearingMessage; import handiebot.utils.FileUtil; import handiebot.view.BotLog; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IGuild; import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IUser; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static handiebot.HandieBot.client; import static handiebot.HandieBot.log; /** * @author Andrew Lalis * Class to process commands. */ public class CommandHandler { public static final String DEFAULT_PREFIX = "!"; public static Map PREFIXES = loadGuildPrefixes(); /** * Main method to handle user messages. * @param event The event generated by the message. */ public static void handleCommand(MessageReceivedEvent event){ IMessage message = event.getMessage(); IUser user = event.getAuthor(); //Exit immediately if the user is a bot; avoids bot spam chat. if (user.isBot()){ return; } IChannel channel = event.getChannel(); IGuild guild = event.getGuild(); //Check if the guild already has a prefix assigned, and if not, give it the default. if (!PREFIXES.containsKey(guild)){ PREFIXES.put(guild, DEFAULT_PREFIX); } String command = extractCommand(message); String[] args = extractArgs(message); //Create a context to give to each command's execution, so it knows what channel to reply on, etc. CommandContext context = new CommandContext(user, channel, guild, args); if (guild != null && command != null){ DisappearingMessage.deleteMessageAfter(1000, message); Commands.executeCommand(command, context); } } /** * Returns a command word, if one exists, from a given message. * @param message The message to get a command from. * @return The command word, minus the prefix, or null. */ private static String extractCommand(IMessage message){ String[] words = message.getContent().split(" "); if (words[0].startsWith(PREFIXES.get(message.getGuild()))){ return words[0].replaceFirst(PREFIXES.get(message.getGuild()), "").toLowerCase(); } return null; } /** * Extracts a list of arguments from a message, assuming a command exists. * @param message The message to parse. * @return A list of strings representing args. */ private static String[] extractArgs(IMessage message){ String[] words = message.getContent().split(" "); if (words[0].startsWith(PREFIXES.get(message.getGuild()))){ String[] args = new String[words.length-1]; for (int i = 0; i < words.length-1; i++){ args[i] = words[i+1]; } return args; } return new String[0]; } /** * Loads a persistent list of prefixes for guilds from a file called guildPrefixes.txt * @return The mapping of guild to prefix. */ private static Map loadGuildPrefixes(){ File prefixFile = new File(FileUtil.getDataDirectory()+"guildPrefixes.txt"); Map prefixes = new HashMap<>(); if (prefixFile.exists()){ List lines = FileUtil.getLinesFromFile(prefixFile); for (String line : lines){ String[] words = line.split(" / "); prefixes.put(client.getGuildByID(Long.parseLong(words[0])), words[1]); } } log.log(BotLog.TYPE.INFO, "Loaded prefixes."); return prefixes; } /** * Saves the list of prefixes to a file. */ public static void saveGuildPrefixes(){ File prefixFile = new File(FileUtil.getDataDirectory()+"guildPrefixes.txt"); List lines = new ArrayList<>(); for (Map.Entry entry : PREFIXES.entrySet()){ lines.add(Long.toString(entry.getKey().getLongID())+" / "+entry.getValue()); } FileUtil.writeLinesToFile(lines, prefixFile); log.log(BotLog.TYPE.INFO, "Saved prefixes."); } }