commit b3f330c3d7f4d394d50d44b216388622729f7909 Author: BuildTools Date: Thu Jan 1 12:38:43 2015 -0700 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..7fb8a51 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +PurpleIRC +========= + +PurpleIRC is a Minecraft Bukkit plugin that connects to IRC as a bot. It will relay messages between the game and IRC. +It uses the PircBotX API. https://code.google.com/p/pircbotx/ + +Latest dev build: +* http://cnaude.org/jenkins/job/PurpleIRC/lastSuccessfulBuild/ + +Live demo and chat: +* irc.esper.net - #PurpleIRC + +BukkitDev: +* http://dev.bukkit.org/bukkit-plugins/purpleirc \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100755 index 0000000..a2e2fe0 --- /dev/null +++ b/pom.xml @@ -0,0 +1,424 @@ + + + 4.0.0 + + + UTF-8 + + 1.8 + SNAPSHOT + + + com.cnaude + PurpleIRC + 1.0-${build.number} + PurpleIRC-spigot + A CraftBukkit plugin for bridging game chat with IRC. Connect to any number of IRC servers and channels simultaneously. + http://dev.bukkit.org/server-mods/purpleirc/ + + + + + cnaude-repo + http://cnaude.org/repo/ + + + + sonatype-nexus-public + SonaType public snapshots and releases repository + https://oss.sonatype.org/content/groups/public + + + false + + + false + + + + + + bukkit-repo + http://repo.bukkit.org/content/groups/public/ + + false + + + + + + regularbox-repo + http://ci.regularbox.com/plugin/repository/everything/ + + true + + + true + + + + + + + + + + + org.bukkit + spigot-api + ${bukkit.version} + jar + provided + + + + org.bukkit + spigot + ${bukkit.version} + jar + provided + + + + + com.google.guava + guava + 15.0 + jar + provided + + + + + com.cnaude.essentials + essentials + 2.14 + jar + + + + + com.nyancraft.reportrts + ReportRTS + 1.2.3 + + + com.comphenix.protocol + ProtocolLib + + + net.milkbowl.net + Vault + + + org.bukkit + bukkit + + + + + + + net.milkbowl.vault + Vault + 1.5.1 + + + + + com.cnaude.herochat + Herochat + 5.6.7 + + + + + com.cnaude.jobs + Jobs + 2.13.1 + + + + + com.cnaude.jobs + JobsOld + 2.12.0 + + + + + com.cnaude.factions + Factions + 2.7.3 + + + + + com.cnaude.orebroadcast + OreBroadcast + 1.2.3 + + + + + com.cnaude.RedditStream + RedditStream + 0.2 + + + + + com.cnaude.vanishnopacket + VanishNoPacket + 3.19.1 + + + + + com.cnaude.mcore + MassiveCore + 2.7.3 + + + + + com.cnaude.factionchat + FactionChat + 1.8.6 + + + + + com.cnaude.titanchat + TitanChat + 4.1 + + + + + com.gmail.nossr50 + mcMMO + 1.5.01-SNAPSHOT-b3682 + + + + + com.cnaude.multiverse + Multiverse-Core + 2.5 + + + + + com.cnaude.townychat + TownyChat + 0.40 + + + + + com.cnaude.towny + Towny + 0.84.0.0 + + + + + com.cnaude.protocol + ProtocolLib + 3.6.3 + + + + + org.pircbotx + pircbotx + 2.0.1 + + + + + + com.cnaude.clevernotch + CleverNotch + 1.1-RELEASE + + + + + org.slf4j + slf4j-nop + 1.7.5 + + + + + com.cnaude.deathmessages + DeathMessages + 2.9.1-SNAPSHOT + + + + + com.cnaude.shortify + Shortify + 1.8-SNAPSHOT + + + + + com.cnaude.dynmap + DynmapAPI + 1.9.4 + + + + + com.cnaude.prism + Prism + 2.0.1 + + + + + com.cnaude.adminprivatechat + AdminPrivateChat + 2.1 + + + + + com.cnaude.supervanish + SuperVanish + 5.0.1 + + + + + junit + junit + 4.10 + jar + test + + + com.carrotsearch + junit-benchmarks + 0.4.0 + test + + + + + + + + src/main/resources + true + + plugin.yml + + + + src/main/resources + false + + plugin.yml + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + + 1.7 + 1.7 + + + + + org.apache.maven.plugins + maven-shade-plugin + 2.2 + + + package + + shade + + + true + + + org.pircbotx + org.slf4j + org.apache.commons + + + + + + + org.pircbotx + org.pircbotx + + + org.slf4j + org.slf4j + + + org.slf4j.impl + org.slf4j.impl + + + org.apache.commons.lang3 + org.apache.commons.lang3 + + + + + + + + maven-antrun-plugin + + + package + + + + + + + + + + run + + + + + + + + + + stage-repo + file://${basedir}/../repo/releases + + + stage-repo-stapshots + file://${basedir}/../repo/snapshots + + + diff --git a/src/main/java/com/cnaude/purpleirc/BotWatcher.java b/src/main/java/com/cnaude/purpleirc/BotWatcher.java new file mode 100644 index 0000000..ebc38a7 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/BotWatcher.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import org.bukkit.scheduler.BukkitTask; + +/** This thread checks each bot for connectivity and reconnects when appropriate. + * + * @author Chris Naude + * + */ +public class BotWatcher { + + private final PurpleIRC plugin; + private final BukkitTask bt; + + /** + * + * @param plugin + */ + public BotWatcher(final PurpleIRC plugin) { + this.plugin = plugin; + + bt = this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, new Runnable() { + @Override + public void run() { + //plugin.logDebug("Checking connection status of IRC bots."); + for (PurpleBot ircBot : plugin.ircBots.values()) { + if (ircBot.isConnectedBlocking()) { + //plugin.logDebug("[" + ircBot.botNick + "] CONNECTED"); + ircBot.setConnected(true); + } else { + ircBot.setConnected(false); + if (ircBot.autoConnect) { + plugin.logInfo("[" + ircBot.botNick + "] NOT CONNECTED"); + ircBot.reload(); + } + } + } + } + }, plugin.ircConnCheckInterval, plugin.ircConnCheckInterval); + } + + /** + * + */ + public void cancel() { + bt.cancel(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/cnaude/purpleirc/ChannelWatcher.java b/src/main/java/com/cnaude/purpleirc/ChannelWatcher.java new file mode 100644 index 0000000..1237d0d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/ChannelWatcher.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import org.bukkit.scheduler.BukkitTask; + +/** + * + * @author Chris Naude This thread checks each for users and updates the + * internal lists. + */ +public class ChannelWatcher { + + private final PurpleIRC plugin; + private final BukkitTask bt; + + /** + * + * @param plugin + */ + public ChannelWatcher(final PurpleIRC plugin) { + this.plugin = plugin; + + bt = this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, new Runnable() { + @Override + public void run() { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.updateNickList(); + } + } + }, plugin.ircChannelCheckInterval, plugin.ircChannelCheckInterval); + } + + /** + * + */ + public void cancel() { + bt.cancel(); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/CommandHandlers.java b/src/main/java/com/cnaude/purpleirc/CommandHandlers.java new file mode 100644 index 0000000..82df625 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/CommandHandlers.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import com.cnaude.purpleirc.Commands.*; +import com.google.common.base.Joiner; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class CommandHandlers implements CommandExecutor { + + public HashMap commands = new HashMap<>(); + public ArrayList sortedCommands = new ArrayList<>(); + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public CommandHandlers(PurpleIRC plugin) { + + this.plugin = plugin; + + commands.put("addop", new AddOp(plugin)); + commands.put("addvoice", new AddVoice(plugin)); + commands.put("connect", new Connect(plugin)); + commands.put("ctcp", new CTCP(plugin)); + commands.put("deop", new DeOp(plugin)); + commands.put("devoice", new DeVoice(plugin)); + commands.put("debug", new Debug(plugin)); + commands.put("disconnect", new Disconnect(plugin)); + commands.put("join", new Join(plugin)); + commands.put("kick", new Kick(plugin)); + commands.put("leave", new Leave(plugin)); + commands.put("list", new List(plugin)); + commands.put("listbots", new ListBots(plugin)); + commands.put("listops", new ListOps(plugin)); + commands.put("listvoices", new ListVoices(plugin)); + commands.put("login", new Login(plugin)); + commands.put("load", new Load(plugin)); + commands.put("messagedelay", new MessageDelay(plugin)); + commands.put("msg", new Msg(plugin)); + commands.put("motd", new Motd(plugin)); + commands.put("mute", new Mute(plugin)); + commands.put("mutelist", new MuteList(plugin)); + commands.put("nick", new Nick(plugin)); + commands.put("notice", new Notice(plugin)); + commands.put("op", new Op(plugin)); + commands.put("reload", new Reload(plugin)); + commands.put("reloadbot", new ReloadBot(plugin)); + commands.put("reloadbotconfig", new ReloadBotConfig(plugin)); + commands.put("reloadbotconfigs", new ReloadBotConfigs(plugin)); + commands.put("reloadbots", new ReloadBots(plugin)); + commands.put("reloadconfig", new ReloadConfig(plugin)); + commands.put("removeop", new RemoveOp(plugin)); + commands.put("removevoice", new RemoveVoice(plugin)); + commands.put("save", new Save(plugin)); + commands.put("say", new Say(plugin)); + commands.put("send", new Send(plugin)); + commands.put("sendraw", new SendRaw(plugin)); + commands.put("server", new Server(plugin)); + commands.put("topic", new Topic(plugin)); + commands.put("unmute", new UnMute(plugin)); + commands.put("updatecheck", new UpdateCheck(plugin)); + commands.put("unload", new Unload(plugin)); + commands.put("voice", new Voice(plugin)); + commands.put("whois", new Whois(plugin)); + commands.put("help", new Help(plugin)); + + commands.put("test", new Test(plugin)); + + for (String s : commands.keySet()) { + sortedCommands.add(s); + } + Collections.sort(sortedCommands, Collator.getInstance()); + plugin.logDebug("Commands enabled: " + Joiner.on(", ").join(sortedCommands)); + } + + /** + * + * @param sender + * @param cmd + * @param commandLabel + * @param args + * @return + */ + @Override + public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) { + if (args.length >= 1) { + String subCmd = args[0].toLowerCase(); + if (commands.containsKey(subCmd)) { + if (!sender.hasPermission("irc." + subCmd)) { + sender.sendMessage(plugin.noPermission); + return true; + } + commands.get(subCmd).dispatch(sender, args); + return true; + } + } + commands.get("help").dispatch(sender, args); + return true; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/CommandQueueWatcher.java b/src/main/java/com/cnaude/purpleirc/CommandQueueWatcher.java new file mode 100644 index 0000000..1295552 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/CommandQueueWatcher.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import com.cnaude.purpleirc.Events.IRCCommandEvent; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import org.bukkit.command.CommandException; + +/** + * + * @author Chris Naude Poll the command queue and dispatch to Bukkit + */ +public class CommandQueueWatcher { + + private final PurpleIRC plugin; + private int bt; + private final Queue queue = new ConcurrentLinkedQueue<>(); + + /** + * + * @param plugin + */ + public CommandQueueWatcher(final PurpleIRC plugin) { + this.plugin = plugin; + startWatcher(); + } + + private void startWatcher() { + plugin.logDebug("Starting command queue"); + bt = this.plugin.getServer().getScheduler().scheduleSyncRepeatingTask(this.plugin, new Runnable() { + @Override + public void run() { + queueAndSend(); + } + }, 0, 5); + } + + private void queueAndSend() { + IRCCommand ircCommand = queue.poll(); + if (ircCommand != null) { + try { + if (plugin.getServer().getVersion().contains("MC: 1.8") + && plugin.getServer().getPluginCommand(ircCommand.getGameCommand()) == null) { + plugin.logDebug("Dispatching command as ConsoleSender: " + ircCommand.getGameCommand()); + plugin.getServer().dispatchCommand(plugin.getServer().getConsoleSender(), ircCommand.getGameCommand()); + } else { + plugin.logDebug("Dispatching command as IRCCommandSender: " + ircCommand.getGameCommand()); + plugin.getServer().dispatchCommand(ircCommand.getIRCCommandSender(), ircCommand.getGameCommand()); + } + } catch (CommandException ce) { + plugin.logError("Error running command: " + ce.getMessage()); + } + plugin.getServer().getPluginManager().callEvent(new IRCCommandEvent(ircCommand)); + } + } + + public void cancel() { + this.plugin.getServer().getScheduler().cancelTask(bt); + } + + public String clearQueue() { + int size = queue.size(); + if (!queue.isEmpty()) { + queue.clear(); + } + return "Elements removed from command queue: " + size; + } + + /** + * + * @param command + */ + public void add(IRCCommand command) { + plugin.logDebug("Adding command to queue: " + command.getGameCommand()); + queue.offer(command); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/AddOp.java b/src/main/java/com/cnaude/purpleirc/Commands/AddOp.java new file mode 100644 index 0000000..d352ea9 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/AddOp.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.pircbotx.Channel; +import org.pircbotx.User; + +/** + * + * @author cnaude + */ +public class AddOp implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [user|mask]"; + private final String desc = "Add IRC users to IRC auto op list."; + private final String name = "addop"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public AddOp(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 4) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + // #channel, user + String nick = args[3]; + String mask = nick; + Channel channel = plugin.ircBots.get(bot).getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + if (user.getNick().equalsIgnoreCase(nick)) { + mask = "*!*" + user.getLogin() + "@" + user.getHostmask(); + } + } + } + if (mask.split("[\\!\\@]", 3).length == 3) { + plugin.ircBots.get(bot).addOp(channelName, mask, sender); + plugin.ircBots.get(bot).opIrcUsers(channelName); + } else { + sender.sendMessage(ChatColor.RED + "Invalid user or mask: " + + ChatColor.WHITE + mask); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} \ No newline at end of file diff --git a/src/main/java/com/cnaude/purpleirc/Commands/AddVoice.java b/src/main/java/com/cnaude/purpleirc/Commands/AddVoice.java new file mode 100644 index 0000000..ea9443e --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/AddVoice.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.pircbotx.Channel; +import org.pircbotx.User; + +/** + * + * @author cnaude + */ +public class AddVoice implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [user|mask]"; + private final String desc = "Add IRC users to IRC auto voice list."; + private final String name = "addvoice"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public AddVoice(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 4) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + // #channel, user + String nick = args[3]; + String mask = nick; + Channel channel = plugin.ircBots.get(bot).getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + if (user.getNick().equalsIgnoreCase(nick)) { + mask = "*!*" + user.getLogin() + "@" + user.getHostmask(); + } + } + } + if (mask.split("[\\!\\@]", 3).length == 3) { + plugin.ircBots.get(bot).addVoice(channelName, mask, sender); + plugin.ircBots.get(bot).voiceIrcUsers(channelName); + } else { + sender.sendMessage(ChatColor.RED + "Invalid user or mask: " + + ChatColor.WHITE + mask); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} \ No newline at end of file diff --git a/src/main/java/com/cnaude/purpleirc/Commands/CTCP.java b/src/main/java/com/cnaude/purpleirc/Commands/CTCP.java new file mode 100644 index 0000000..7081e25 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/CTCP.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.util.ArrayList; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class CTCP implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) [target] [command]"; + private final String desc = "Send CTCP command to the user or channel."; + private final String name = "ctcp"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public CTCP(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 3) { + plugin.logDebug("Dispatching ctcp command..."); + int msgIdx = 2; + String target; + java.util.List myBots = new ArrayList(); + if (plugin.ircBots.containsKey(args[1])) { + myBots.add(plugin.ircBots.get(args[1])); + msgIdx = 3; + target = args[2]; + } else { + myBots.addAll(plugin.ircBots.values()); + target = args[1]; + } + + if (msgIdx == 3 && args.length <= 3) { + sender.sendMessage(fullUsage); + return; + } + + for (PurpleBot ircBot : myBots) { + String msg = ""; + for (int i = msgIdx; i < args.length; i++) { + msg = msg + " " + args[i]; + } + ircBot.asyncCTCPCommand(target, msg.substring(1)); + sender.sendMessage("Sent CTCP command \"" + msg.substring(1) + "\" to \"" + target + "\""); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} \ No newline at end of file diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Connect.java b/src/main/java/com/cnaude/purpleirc/Commands/Connect.java new file mode 100644 index 0000000..53bc495 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Connect.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Connect implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot])"; + private final String desc = "Connect to configured IRC server."; + private final String name = "connect"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Connect(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 1) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.asyncConnect(sender); + } + } else if (args.length == 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).asyncConnect(sender); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/DeOp.java b/src/main/java/com/cnaude/purpleirc/Commands/DeOp.java new file mode 100644 index 0000000..e2c0570 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/DeOp.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.Utilities.BotsAndChannels; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class DeOp implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel]) [user(s)]"; + private final String desc = "De-op IRC user(s)."; + private final String name = "deop"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public DeOp(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + BotsAndChannels bac; + int idx; + + if (args.length >= 4) { + bac = new BotsAndChannels(plugin, sender, args[1], args[2]); + idx = 3; + } else if (args.length == 2) { + bac = new BotsAndChannels(plugin, sender); + idx = 1; + } else { + sender.sendMessage(fullUsage); + return; + } + if (bac.bot.size() > 0 && bac.channel.size() > 0) { + for (String botName : bac.bot) { + for (String channelName : bac.channel) { + for (int i = idx; i < args.length; i++) { + plugin.ircBots.get(botName).deOp(channelName, args[i]); + sender.sendMessage("Removing operator status from " + + ChatColor.WHITE + args[i] + + ChatColor.RESET + " in " + + ChatColor.WHITE + channelName); + } + } + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/DeVoice.java b/src/main/java/com/cnaude/purpleirc/Commands/DeVoice.java new file mode 100644 index 0000000..7075b0f --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/DeVoice.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.Utilities.BotsAndChannels; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class DeVoice implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel]) [user(s)]"; + private final String desc = "De-voice IRC user(s)."; + private final String name = "devoice"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public DeVoice(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + BotsAndChannels bac; + int idx; + + if (args.length >= 4) { + bac = new BotsAndChannels(plugin, sender, args[1], args[2]); + idx = 3; + } else if (args.length == 2) { + bac = new BotsAndChannels(plugin, sender); + idx = 1; + } else { + sender.sendMessage(fullUsage); + return; + } + if (bac.bot.size() > 0 && bac.channel.size() > 0) { + for (String botName : bac.bot) { + for (String channelName : bac.channel) { + for (int i = idx; i < args.length; i++) { + plugin.ircBots.get(botName).deVoice(channelName, args[i]); + sender.sendMessage("Removing voice status from " + + ChatColor.WHITE + args[i] + + ChatColor.RESET + " in " + + ChatColor.WHITE + channelName); + } + } + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Debug.java b/src/main/java/com/cnaude/purpleirc/Commands/Debug.java new file mode 100644 index 0000000..102c0f8 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Debug.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Debug implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([t|f])"; + private final String desc = "Enable or disable debug mode."; + private final String name = "debug"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Debug(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 1) { + sender.sendMessage(ChatColor.DARK_PURPLE + "Debug mode is currently " + + ChatColor.WHITE + plugin.debugMode()); + } else if (args.length == 2) { + if (args[1].startsWith("t")) { + plugin.debugMode(true); + } else if (args[1].startsWith("f")) { + plugin.debugMode(false); + } else { + sender.sendMessage(usage); + } + sender.sendMessage(ChatColor.DARK_PURPLE + "Debug mode is now " + + ChatColor.WHITE + plugin.debugMode()); + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Disconnect.java b/src/main/java/com/cnaude/purpleirc/Commands/Disconnect.java new file mode 100644 index 0000000..75fb641 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Disconnect.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Disconnect implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot])"; + private final String desc = "Disconnect from IRC server."; + private final String name = "disconnect"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Disconnect(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 1) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.asyncQuit(sender); + } + } else if (args.length == 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).asyncQuit(sender); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Help.java b/src/main/java/com/cnaude/purpleirc/Commands/Help.java new file mode 100644 index 0000000..65f6e8a --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Help.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Help implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([command])"; + private final String desc = "Display help on a specific command or list all commands."; + private final String name = "help"; + + /** + * + * @param plugin + */ + public Help(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 2) { + String s = args[1]; + if (plugin.commandHandlers.commands.containsKey(s)) { + sender.sendMessage(helpStringBuilder( + plugin.commandHandlers.commands.get(s).name(), + plugin.commandHandlers.commands.get(s).desc(), + plugin.commandHandlers.commands.get(s).usage())); + return; + } else { + sender.sendMessage(ChatColor.RED + "Invalid sub command: " + + ChatColor.WHITE + s); + return; + } + } + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&5-----[ &fPurpleIRC&5 - &f" + plugin.getServer().getPluginManager() + .getPlugin("PurpleIRC").getDescription().getVersion() + "&5 ]-----")); + for (String s : plugin.commandHandlers.sortedCommands) { + if (plugin.commandHandlers.commands.containsKey(s)) { + sender.sendMessage(helpStringBuilder( + plugin.commandHandlers.commands.get(s).name(), + plugin.commandHandlers.commands.get(s).desc(), + plugin.commandHandlers.commands.get(s).usage())); + } + } + + } + + private String helpStringBuilder(String n, String d, String u) { + return ChatColor.translateAlternateColorCodes('&', "&5/irc " + + n + " &6" + u + " &f- " + d); + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/IRCCommandInterface.java b/src/main/java/com/cnaude/purpleirc/Commands/IRCCommandInterface.java new file mode 100644 index 0000000..075f410 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/IRCCommandInterface.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public interface IRCCommandInterface { + void dispatch(CommandSender sender, String[] args); + String name(); + String desc(); + String usage(); +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Join.java b/src/main/java/com/cnaude/purpleirc/Commands/Join.java new file mode 100644 index 0000000..a2b7049 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Join.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Join implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] ([password])"; + private final String desc = "Join IRC channel."; + private final String name = "join"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Join(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 3) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + String password = ""; + if (args.length >= 4) { + for (int i = 3; i < args.length; i++) { + password = password + " " + args[i]; + } + } + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).asyncJoinChannel(channelName, password); + sender.sendMessage(ChatColor.WHITE + "Joining " + channelName + "..."); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Kick.java b/src/main/java/com/cnaude/purpleirc/Commands/Kick.java new file mode 100644 index 0000000..1d597b1 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Kick.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Kick implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [user(s)]"; + private final String desc = "Kick user(s) from IRC channel."; + private final String name = "kick"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Kick(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 4) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + for (int i = 3; i < args.length; i++) { + // #channel, user + plugin.ircBots.get(bot).kick(channelName, args[3]); + sender.sendMessage(ChatColor.WHITE + "Kicking " + args[i] + " from " + channelName + "..."); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Leave.java b/src/main/java/com/cnaude/purpleirc/Commands/Leave.java new file mode 100644 index 0000000..5f6a3e8 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Leave.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.pircbotx.Channel; + +/** + * + * @author cnaude + */ +public class Leave implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel]"; + private final String desc = "Leave IRC channel."; + private final String name = "leave"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Leave(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 3) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + String reason = ""; + if (args.length >= 4) { + for (int i = 3; i < args.length; i++) { + reason = reason + " " + args[i]; + } + } + if (plugin.ircBots.containsKey(bot)) { + if (plugin.ircBots.get(bot).isConnected()) { + for (Channel channel : plugin.ircBots.get(bot).getChannels()) { + if (channel.getName().equalsIgnoreCase(channelName)) { + channel.send().part(reason); + sender.sendMessage(ChatColor.WHITE + "Leaving " + channelName + "..."); + return; + } + } + sender.sendMessage(ChatColor.WHITE + "Channel " + channelName + " is not valid."); + } else { + sender.sendMessage(ChatColor.RED + "Not connected."); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/List.java b/src/main/java/com/cnaude/purpleirc/Commands/List.java new file mode 100644 index 0000000..a90c992 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/List.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class List implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel])"; + private final String desc = "List users in IRC channel."; + private final String name = "list"; + //private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public List(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 1) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.sendUserList(sender); + } + } else if (args.length > 1) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + PurpleBot ircBot = plugin.ircBots.get(bot); + if (args.length > 2) { + ircBot.sendUserList(sender, args[2]); + } else { + ircBot.sendUserList(sender); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ListBots.java b/src/main/java/com/cnaude/purpleirc/Commands/ListBots.java new file mode 100644 index 0000000..4323da0 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ListBots.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.pircbotx.Channel; + +/** + * + * @author cnaude + */ +public class ListBots implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = ""; + private final String desc = "List IRC bots."; + private final String name = "listbots"; + + /** + * + * @param plugin + */ + public ListBots(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + sender.sendMessage(ChatColor.DARK_PURPLE + "-----[ " + ChatColor.WHITE + "IRC Bots" + + ChatColor.DARK_PURPLE + " ]-----"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + sender.sendMessage(ChatColor.DARK_PURPLE + "* " + ChatColor.WHITE + ircBot.getFileName() + + ChatColor.DARK_PURPLE + " [" + ChatColor.WHITE + ircBot.botNick + ChatColor.DARK_PURPLE + "]"); + if (ircBot.isConnected()) { + for (Channel channel : ircBot.getChannels()) { + sender.sendMessage(ChatColor.DARK_PURPLE + " - " + ChatColor.WHITE + channel.getName()); + } + } else { + sender.sendMessage(ChatColor.RED + "Not connected."); + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ListOps.java b/src/main/java/com/cnaude/purpleirc/Commands/ListOps.java new file mode 100644 index 0000000..48ff0c8 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ListOps.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class ListOps implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel]"; + private final String desc = "List IRC user mask in auto-op list."; + private final String name = "listops"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public ListOps(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 3) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + if (plugin.ircBots.get(bot).opsList.containsKey(channelName)) { + sender.sendMessage(ChatColor.DARK_PURPLE + "-----[ " + ChatColor.WHITE + channelName + + ChatColor.DARK_PURPLE + " - " + ChatColor.WHITE + "Auto Op Masks" + ChatColor.DARK_PURPLE + " ]-----"); + for (String userMask : plugin.ircBots.get(bot).opsList.get(channelName)) { + sender.sendMessage(" - " + userMask); + } + } else { + sender.sendMessage(plugin.invalidChannel.replace("%CHANNEL%", channelName)); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ListVoices.java b/src/main/java/com/cnaude/purpleirc/Commands/ListVoices.java new file mode 100644 index 0000000..5cfd468 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ListVoices.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class ListVoices implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel]"; + private final String desc = "List IRC user mask in auto-voice list."; + private final String name = "listvoices"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public ListVoices(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 3) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + if (plugin.ircBots.get(bot).voicesList.containsKey(channelName)) { + sender.sendMessage(ChatColor.DARK_PURPLE + "-----[ " + ChatColor.WHITE + channelName + + ChatColor.DARK_PURPLE + " - " + ChatColor.WHITE + "Auto Voice Masks" + ChatColor.DARK_PURPLE + " ]-----"); + for (String userMask : plugin.ircBots.get(bot).voicesList.get(channelName)) { + sender.sendMessage(" - " + userMask); + } + } else { + sender.sendMessage(plugin.invalidChannel.replace("%CHANNEL%", channelName)); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Load.java b/src/main/java/com/cnaude/purpleirc/Commands/Load.java new file mode 100755 index 0000000..f49f9b1 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Load.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.io.File; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Load implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot]"; + private final String desc = "Load a bot file."; + private final String name = "load"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Load(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + sender.sendMessage(ChatColor.RED + "Sorry that bot is already loaded. Try to unload it first."); + return; + } + File file = new File(plugin.botsFolder, bot); + if (file.exists()) { + sender.sendMessage(ChatColor.WHITE + "Loading " + bot + "..."); + plugin.ircBots.put(file.getName(), new PurpleBot(file, plugin)); + sender.sendMessage("Loaded bot: " + file.getName() + "[" + plugin.ircBots.get(file.getName()).botNick + "]"); + } else { + sender.sendMessage(ChatColor.RED + "No such bot file: " + ChatColor.WHITE + bot); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Login.java b/src/main/java/com/cnaude/purpleirc/Commands/Login.java new file mode 100644 index 0000000..25c0ea3 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Login.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Login implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [login]"; + private final String desc = "Change bot's IRC login name."; + private final String name = "login"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Login(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 3) { + String bot = plugin.botify(args[1]); + String login = args[2]; + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).changeLogin(sender, login); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/MessageDelay.java b/src/main/java/com/cnaude/purpleirc/Commands/MessageDelay.java new file mode 100644 index 0000000..ecc39fd --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/MessageDelay.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class MessageDelay implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [milliseconds]"; + private final String desc = "Change IRC message delay."; + private final String name = "messagedelay"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public MessageDelay(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 3) { + if (args[2].matches("\\d+")) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + long delay = Long.parseLong(args[2]); + plugin.ircBots.get(bot).setIRCDelay(sender, delay); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } else if (args.length == 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + sender.sendMessage(ChatColor.WHITE + "IRC message delay is currently " + + plugin.ircBots.get(bot).getMessageDelay() + " ms."); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Motd.java b/src/main/java/com/cnaude/purpleirc/Commands/Motd.java new file mode 100644 index 0000000..b264b26 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Motd.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.util.ArrayList; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Motd implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot])"; + private final String desc = "Get server motd."; + private final String name = "motd"; + + /** + * + * @param plugin + */ + public Motd(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + java.util.List myBots = new ArrayList(); + if (args.length >= 2) { + if (plugin.ircBots.containsKey(args[1])) { + myBots.add(plugin.ircBots.get(args[1])); + + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", args[1])); + } + } else { + myBots.addAll(plugin.ircBots.values()); + } + + for (PurpleBot ircBot : myBots) { + String motd = ircBot.getMotd(); + if (motd != null) { + sender.sendMessage(motd); + } else { + sender.sendMessage("No MOTD found."); + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Msg.java b/src/main/java/com/cnaude/purpleirc/Commands/Msg.java new file mode 100644 index 0000000..2d08d1b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Msg.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.util.ArrayList; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * + * @author cnaude + */ +public class Msg implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) [user] [message]"; + private final String desc = "Send a private message to an IRC user."; + private final String name = "msg"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Msg(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 3) { + plugin.logDebug("Dispatching msg command..."); + int msgIdx = 2; + String nick; + java.util.List myBots = new ArrayList<>(); + if (plugin.ircBots.containsKey(args[1])) { + myBots.add(plugin.ircBots.get(args[1])); + msgIdx = 3; + nick = args[2]; + } else { + myBots.addAll(plugin.ircBots.values()); + nick = args[1]; + } + + if (msgIdx == 3 && args.length <= 3) { + sender.sendMessage(fullUsage); + return; + } + + for (PurpleBot ircBot : myBots) { + String msg = ""; + final String template = plugin.getMsgTemplate(ircBot.botNick, "game-pchat-response"); + for (int i = msgIdx; i < args.length; i++) { + msg = msg + " " + args[i]; + } + if (sender instanceof Player) { + ircBot.msgPlayer((Player) sender, nick, msg.substring(1)); + } else { + ircBot.consoleMsgPlayer(nick, msg.substring(1)); + } + if (!template.isEmpty()) { + sender.sendMessage(plugin.tokenizer.msgChatResponseTokenizer(nick, msg.substring(1), template)); + } + } + } + else { + sender.sendMessage(fullUsage); + } +} + +@Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Mute.java b/src/main/java/com/cnaude/purpleirc/Commands/Mute.java new file mode 100644 index 0000000..702a918 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Mute.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.Utilities.BotsAndChannels; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Mute implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel]) [user(s)]"; + private final String desc = "Mute IRC user(s) in a channel."; + private final String name = "mute"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Mute(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + BotsAndChannels bac; + int idx; + + if (args.length >= 4) { + bac = new BotsAndChannels(plugin, sender, args[1], args[2]); + idx = 3; + } else if (args.length == 2) { + bac = new BotsAndChannels(plugin, sender); + idx = 1; + } else { + sender.sendMessage(fullUsage); + return; + } + if (bac.bot.size() > 0 && bac.channel.size() > 0) { + for (String botName : bac.bot) { + for (String channelName : bac.channel) { + for (int i = idx; i < args.length; i++) { + plugin.ircBots.get(botName).mute(channelName, sender, args[i]); + } + } + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/MuteList.java b/src/main/java/com/cnaude/purpleirc/Commands/MuteList.java new file mode 100644 index 0000000..6a6f32d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/MuteList.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.Utilities.BotsAndChannels; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class MuteList implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel])"; + private final String desc = "List muted IRC user(s) for a channel."; + private final String name = "mutelist"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public MuteList(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + BotsAndChannels bac; + + if (args.length >= 3) { + bac = new BotsAndChannels(plugin, sender, args[1], args[2]); + } else if (args.length == 1) { + bac = new BotsAndChannels(plugin, sender); + } else { + sender.sendMessage(fullUsage); + return; + } + if (bac.bot.size() > 0 && bac.channel.size() > 0) { + for (String botName : bac.bot) { + for (String channelName : bac.channel) { + plugin.ircBots.get(botName).muteList(channelName, sender); + } + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Nick.java b/src/main/java/com/cnaude/purpleirc/Commands/Nick.java new file mode 100644 index 0000000..81f44f0 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Nick.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Nick implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [nick]"; + private final String desc = "Change bot's IRC nick."; + private final String name = "nick"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Nick(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 3) { + String bot = plugin.botify(args[1]); + String nick = args[2]; + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).asyncChangeNick(sender, nick); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Notice.java b/src/main/java/com/cnaude/purpleirc/Commands/Notice.java new file mode 100644 index 0000000..39d64af --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Notice.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.util.ArrayList; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Notice implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) [target] [message]"; + private final String desc = "Send notice message to the user or channel."; + private final String name = "notice"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Notice(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 3) { + plugin.logDebug("Dispatching notice command..."); + int msgIdx = 2; + String target; + java.util.List myBots = new ArrayList(); + if (plugin.ircBots.containsKey(args[1])) { + myBots.add(plugin.ircBots.get(args[1])); + msgIdx = 3; + target = args[2]; + } else { + myBots.addAll(plugin.ircBots.values()); + target = args[1]; + } + + if (msgIdx == 3 && args.length <= 3) { + sender.sendMessage(fullUsage); + return; + } + + for (PurpleBot ircBot : myBots) { + String msg = ""; + for (int i = msgIdx; i < args.length; i++) { + msg = msg + " " + args[i]; + } + ircBot.asyncNotice(target, msg.substring(1)); + sender.sendMessage("Sent notice message \"" + msg.substring(1) + "\" to \"" + target + "\""); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Op.java b/src/main/java/com/cnaude/purpleirc/Commands/Op.java new file mode 100644 index 0000000..6d0625d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Op.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Op implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [user(s)]"; + private final String desc = "Op an IRC user in a channel."; + private final String name = "op"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Op(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 4) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + for (int i = 3; i < args.length; i++) { + // #channel, user + plugin.ircBots.get(bot).op(channelName, args[i]); + sender.sendMessage("Giving operator status to " + + ChatColor.WHITE + args[i] + + ChatColor.RESET + " on " + + ChatColor.WHITE + channelName); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Reload.java b/src/main/java/com/cnaude/purpleirc/Commands/Reload.java new file mode 100644 index 0000000..0a3a60a --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Reload.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Reload implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = ""; + private final String desc = "Reload the plugin."; + private final String name = "reload"; + + /** + * + * @param plugin + */ + public Reload(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + sender.sendMessage("Disabling PurpleIRC..."); + plugin.getServer().getPluginManager().disablePlugin(plugin); + sender.sendMessage("Enabling PurpleIRC..."); + plugin.getServer().getPluginManager().enablePlugin(plugin); + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ReloadBot.java b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBot.java new file mode 100644 index 0000000..f633583 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBot.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class ReloadBot implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot]"; + private final String desc = "Reload a bot."; + private final String name = "reloadbot"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public ReloadBot(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).reload(sender); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ReloadBotConfig.java b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBotConfig.java new file mode 100644 index 0000000..b086728 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBotConfig.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class ReloadBotConfig implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot]"; + private final String desc = "Reload a bot's configuration."; + private final String name = "reloadbotconfig"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public ReloadBotConfig(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).reloadConfig(sender); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ReloadBotConfigs.java b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBotConfigs.java new file mode 100644 index 0000000..f66a8f6 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBotConfigs.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class ReloadBotConfigs implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = ""; + private final String desc = "Reload all bot configurations."; + private final String name = "reloadbotconfigs"; + + /** + * + * @param plugin + */ + public ReloadBotConfigs(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reloadConfig(sender); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ReloadBots.java b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBots.java new file mode 100644 index 0000000..00f831d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ReloadBots.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class ReloadBots implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = ""; + private final String desc = "Reload all bots."; + private final String name = "reloadbots"; + + /** + * + * @param plugin + */ + public ReloadBots(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reload(sender); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/ReloadConfig.java b/src/main/java/com/cnaude/purpleirc/Commands/ReloadConfig.java new file mode 100644 index 0000000..f997c79 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/ReloadConfig.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class ReloadConfig implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = ""; + private final String desc = "Reload PurpleIRC/config.yml."; + private final String name = "reloadconfig"; + + /** + * + * @param plugin + */ + public ReloadConfig(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + plugin.reloadMainConfig(sender); + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/RemoveOp.java b/src/main/java/com/cnaude/purpleirc/Commands/RemoveOp.java new file mode 100644 index 0000000..32d6d00 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/RemoveOp.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class RemoveOp implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [user mask]"; + private final String desc = "Remove a user mask from the auto-op list."; + private final String name = "removeop"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public RemoveOp(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 4) { + String bot = plugin.botify(args[1]); + String channel = args[2]; + if (plugin.ircBots.containsKey(bot)) { + // #channel, user + plugin.ircBots.get(bot).removeOp(channel, args[3], sender); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/RemoveVoice.java b/src/main/java/com/cnaude/purpleirc/Commands/RemoveVoice.java new file mode 100644 index 0000000..3c0e28f --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/RemoveVoice.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class RemoveVoice implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [user mask]"; + private final String desc = "Remove a user mask from the auto-voice list."; + private final String name = "removevoice"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public RemoveVoice(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 4) { + String bot = plugin.botify(args[1]); + String channel = args[2]; + if (plugin.ircBots.containsKey(bot)) { + // #channel, user + plugin.ircBots.get(bot).removeVoice(channel, args[3], sender); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Save.java b/src/main/java/com/cnaude/purpleirc/Commands/Save.java new file mode 100644 index 0000000..b4a1cd1 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Save.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Save implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot])"; + private final String desc = "Save bot configuration."; + private final String name = "save"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Save(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 1) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.saveConfig(sender); + } + } else if (args.length >= 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + plugin.ircBots.get(bot).saveConfig(sender); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Say.java b/src/main/java/com/cnaude/purpleirc/Commands/Say.java new file mode 100644 index 0000000..7c7cba1 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Say.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Say implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [message]"; + private final String desc = "Make the bot speak."; + private final String name = "say"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Say(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 4) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + String msg = ""; + for (int i = 3; i < args.length; i++) { + msg = msg + " " + args[i]; + } + plugin.ircBots.get(bot).asyncIRCMessage(channelName, msg.substring(1)); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Send.java b/src/main/java/com/cnaude/purpleirc/Commands/Send.java new file mode 100644 index 0000000..e03d29b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Send.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * + * @author cnaude + */ +public class Send implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel]) [message]"; + private final String desc = "Send a message to an IRC channel."; + private final String name = "send"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Send(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 2) { + int msgIdx = 1; + String channelName = null; + List myBots = new ArrayList(); + if (plugin.ircBots.containsKey(args[1])) { + myBots.add(plugin.ircBots.get(args[1])); + msgIdx = 2; + if (args.length >= 3) { + if (plugin.ircBots.get(args[1]).isValidChannel(args[2])) { + channelName = args[2]; + } + } + } else { + myBots.addAll(plugin.ircBots.values()); + } + for (PurpleBot ircBot : myBots) { + String msg = ""; + for (int i = msgIdx; i < args.length; i++) { + msg = msg + " " + args[i]; + } + if (channelName == null) { + for (String c : ircBot.botChannels) { + if (sender instanceof Player) { + ircBot.gameChat((Player) sender, c, msg.substring(1)); + } else { + ircBot.consoleChat(c, msg.substring(1)); + } + } + } else { + if (sender instanceof Player) { + ircBot.gameChat((Player) sender, channelName, msg.substring(1)); + } else { + ircBot.consoleChat(channelName, msg.substring(1)); + } + } + + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/SendRaw.java b/src/main/java/com/cnaude/purpleirc/Commands/SendRaw.java new file mode 100644 index 0000000..08da63a --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/SendRaw.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class SendRaw implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) [message]"; + private final String desc = "Send raw message to the IRC server."; + private final String name = "sendraw"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public SendRaw(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 2) { + int msgIdx = 1; + List myBots = new ArrayList(); + if (plugin.ircBots.containsKey(args[1])) { + myBots.add(plugin.ircBots.get(args[1])); + msgIdx = 2; + } else { + myBots.addAll(plugin.ircBots.values()); + } + for (PurpleBot ircBot : myBots) { + String msg = ""; + for (int i = msgIdx; i < args.length; i++) { + msg = msg + " " + args[i]; + } + plugin.logDebug("Sending raw message to the server: " + msg.substring(1)); + ircBot.asyncRawlineNow(msg.substring(1)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Server.java b/src/main/java/com/cnaude/purpleirc/Commands/Server.java new file mode 100644 index 0000000..fb348f3 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Server.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Server implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [server] ([true|false])"; + private final String desc = "Set IRC server hostname. Optionally set autoconnect."; + private final String name = "server"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Server(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 3) { + String bot = plugin.botify(args[1]); + String server = args[2]; + if (plugin.ircBots.containsKey(bot)) { + if (args.length == 3) { + plugin.ircBots.get(bot).setServer(sender, server); + } else if (args.length == 4) { + plugin.ircBots.get(bot).setServer(sender, server, Boolean.parseBoolean(args[3])); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Test.java b/src/main/java/com/cnaude/purpleirc/Commands/Test.java new file mode 100755 index 0000000..33b6fa5 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Test.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Test implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[player name]"; + private final String desc = "Testing various Vault methods."; + private final String name = "test"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Test(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + //irc test + if (plugin.vaultHelpers == null) { + sender.sendMessage(ChatColor.RED + "Vault is no enabled!"); + return; + } + if (plugin.debugMode()) { + if (args.length >= 2) { + String playername = args[1]; + sender.sendMessage(ChatColor.LIGHT_PURPLE + "Testing " + playername); + sender.sendMessage("getGroupPrefix : " + plugin.getGroupPrefix(plugin.defaultPlayerWorld, playername)); + sender.sendMessage("getGroupSuffix : " + plugin.getGroupSuffix(plugin.defaultPlayerWorld, playername)); + sender.sendMessage("getPlayerPrefix : " + plugin.getPlayerPrefix(plugin.defaultPlayerWorld, playername)); + sender.sendMessage("getPlayerSuffix : " + plugin.getPlayerSuffix(plugin.defaultPlayerWorld, playername)); + sender.sendMessage("getPlayerGroup : " + plugin.getPlayerGroup(plugin.defaultPlayerWorld, playername)); + } else { + sender.sendMessage(fullUsage); + } + } else { + sender.sendMessage(ChatColor.RED + "Debug mode must enabled to use this feature."); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Topic.java b/src/main/java/com/cnaude/purpleirc/Commands/Topic.java new file mode 100644 index 0000000..b02f712 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Topic.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.Utilities.BotsAndChannels; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Topic implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel]) ([topic])"; + private final String desc = "Set, or get, IRC channel top"; + private final String name = "topic"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Topic(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + BotsAndChannels bac; + int idx; + + if (args.length >= 4) { + bac = new BotsAndChannels(plugin, sender, args[1], args[2]); + idx = 3; + } else if (args.length == 2) { + bac = new BotsAndChannels(plugin, sender); + idx = 1; + } else { + bac = new BotsAndChannels(plugin, sender); + for (String botName : bac.bot) { + for (String channelName : bac.channel) { + sender.sendMessage(ChatColor.WHITE + "[" + ChatColor.DARK_PURPLE + + botName + ChatColor.WHITE + + "/" + ChatColor.DARK_PURPLE + channelName + + ChatColor.WHITE + "]" + + " Topic: " + plugin.ircBots.get(botName) + .channelTopic.get(channelName)); + } + } + sender.sendMessage(fullUsage); + return; + } + if (bac.bot.size() > 0 && bac.channel.size() > 0) { + for (String botName : bac.bot) { + for (String channelName : bac.channel) { + String topic = ""; + for (int i = idx; i < args.length; i++) { + topic = topic + " " + args[i]; + } + plugin.ircBots.get(botName).changeTopic(channelName, + topic.substring(1), sender); + } + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/UnMute.java b/src/main/java/com/cnaude/purpleirc/Commands/UnMute.java new file mode 100644 index 0000000..4ede5b3 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/UnMute.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.Utilities.BotsAndChannels; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class UnMute implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) ([channel]) [user(s)]"; + private final String desc = "Unmute IRC user(s) in a channel."; + private final String name = "unmute"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public UnMute(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + BotsAndChannels bac; + int idx; + + if (args.length >= 4) { + bac = new BotsAndChannels(plugin, sender, args[1], args[2]); + idx = 3; + } else if (args.length == 2) { + bac = new BotsAndChannels(plugin, sender); + idx = 1; + } else { + sender.sendMessage(fullUsage); + return; + } + if (bac.bot.size() > 0 && bac.channel.size() > 0) { + for (String botName : bac.bot) { + for (String channelName : bac.channel) { + for (int i = idx; i < args.length; i++) { + plugin.ircBots.get(botName).unMute(channelName, sender, args[i]); + } + } + } + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Unload.java b/src/main/java/com/cnaude/purpleirc/Commands/Unload.java new file mode 100755 index 0000000..d030382 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Unload.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import java.io.File; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Unload implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] (disable)"; + private final String desc = "Unload the bot and optionally disable it."; + private final String name = "unload"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Unload(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 2) { + String bot = plugin.botify(args[1]); + if (plugin.ircBots.containsKey(bot)) { + sender.sendMessage(ChatColor.WHITE + "Unloading " + bot + "..."); + plugin.ircBots.get(bot).quit(); + plugin.ircBots.get(bot).saveConfig(plugin.getServer().getConsoleSender()); + plugin.ircBots.remove(bot); + if (args.length >= 3) { + if (args[2].equalsIgnoreCase("disable")) { + sender.sendMessage(ChatColor.WHITE + "Renaming " + bot + " to " + bot + ".disabled"); + File file = new File(plugin.botsFolder, bot); + file.renameTo(new File(plugin.botsFolder, bot + ".disabled")); + } + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/UpdateCheck.java b/src/main/java/com/cnaude/purpleirc/Commands/UpdateCheck.java new file mode 100755 index 0000000..6900fde --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/UpdateCheck.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class UpdateCheck implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[stable|dev]"; + private final String desc = "Ceck for latest updates."; + private final String name = "updatecheck"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public UpdateCheck(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 2) { + String mode = args[1]; + plugin.updateChecker.asyncUpdateCheck(sender, mode); + } else { + plugin.updateChecker.asyncUpdateCheck(sender, plugin.updateCheckerMode()); + } + + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Voice.java b/src/main/java/com/cnaude/purpleirc/Commands/Voice.java new file mode 100644 index 0000000..552f761 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Voice.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Voice implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "[bot] [channel] [user(s)]"; + private final String desc = "Voice an IRC user in a channel."; + private final String name = "voice"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Voice(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length >= 4) { + String bot = plugin.botify(args[1]); + String channelName = args[2]; + if (plugin.ircBots.containsKey(bot)) { + for (int i = 3; i < args.length; i++) { + // #channel, user + plugin.ircBots.get(bot).voice(channelName, args[i]); + sender.sendMessage("Giving voice status to " + + ChatColor.WHITE + args[i] + + ChatColor.RESET + " on " + + ChatColor.WHITE + channelName); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Commands/Whois.java b/src/main/java/com/cnaude/purpleirc/Commands/Whois.java new file mode 100644 index 0000000..51de6ed --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Commands/Whois.java @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Commands; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class Whois implements IRCCommandInterface { + + private final PurpleIRC plugin; + private final String usage = "([bot]) [nick]"; + private final String desc = "Get whois info for IRC user."; + private final String name = "whois"; + private final String fullUsage = ChatColor.WHITE + "Usage: " + ChatColor.GOLD + "/irc " + name + " " + usage; + + /** + * + * @param plugin + */ + public Whois(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param sender + * @param args + */ + @Override + public void dispatch(CommandSender sender, String[] args) { + if (args.length == 2) { + String nick = args[1]; + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.sendUserWhois(sender, nick); + } + } else if (args.length == 3) { + String bot = plugin.botify(args[1]); + String nick = args[2]; + if (plugin.ircBots.containsKey(bot)) { + PurpleBot ircBot = plugin.ircBots.get(bot); + ircBot.sendUserWhois(sender, nick); + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", bot)); + } + } else { + sender.sendMessage(fullUsage); + } + } + + @Override + public String name() { + return name; + } + + @Override + public String desc() { + return desc; + } + + @Override + public String usage() { + return usage; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Events/IRCCommandEvent.java b/src/main/java/com/cnaude/purpleirc/Events/IRCCommandEvent.java new file mode 100644 index 0000000..6390003 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Events/IRCCommandEvent.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Events; + +import com.cnaude.purpleirc.IRCCommand; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * + * @author cnaude + * Event listener for plugins that want to catch command events from PurpleIRC + */ +public class IRCCommandEvent extends Event { + + private static final HandlerList handlers = new HandlerList(); + private final IRCCommand ircCommand; + + /** + * + * @param ircCommand + */ + public IRCCommandEvent(IRCCommand ircCommand) { + this.ircCommand = ircCommand; + } + + /** + * + * @return + */ + public IRCCommand getIRCCommand() { + return this.ircCommand; + } + + /** + * + * @return + */ + @Override + public HandlerList getHandlers() { + return handlers; + } + + /** + * + * @return + */ + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/AdminChatListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/AdminChatListener.java new file mode 100755 index 0000000..39c2107 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/AdminChatListener.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.ammaraskar.adminonly.AdminChatEvent; +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class AdminChatListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public AdminChatListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onAdminChatEvent(AdminChatEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.adminChat(event.getName(), event.getMessage(), event.getWorld()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/CleverNotchListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/CleverNotchListener.java new file mode 100644 index 0000000..baed711 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/CleverNotchListener.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.dotGaming.Endain.CleverNotch.CleverEvent; + +/** + * + * @author cnaude + */ +public class CleverNotchListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public CleverNotchListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onCleverEvent(CleverEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.cleverChat(event.getName(), event.getMessage()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/DeathMessagesListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/DeathMessagesListener.java new file mode 100644 index 0000000..23f772d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/DeathMessagesListener.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.TemplateName; +import com.gmail.josemanuelgassin.DeathMessages.DeathMessageEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class DeathMessagesListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public DeathMessagesListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onDeathMessageEvent(DeathMessageEvent event) { + plugin.logDebug("onDeathMessageEvent caught"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameDeath(event.getPlayer(), event.getDeathMessage(), TemplateName.DEATH_MESSAGES); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/DynmapListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/DynmapListener.java new file mode 100644 index 0000000..dc9a7d3 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/DynmapListener.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.dynmap.DynmapWebChatEvent; + +/** + * + * @author cnaude + */ +public class DynmapListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public DynmapListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onDynmapWebChatEvent(DynmapWebChatEvent event) { + String message = event.getMessage(); + String name = event.getName(); + String source = event.getSource(); + plugin.logDebug("DynmapWebChat: " + source + " : " + name + ":" + message); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.dynmapWebChat(source, name, message); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/EssentialsListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/EssentialsListener.java new file mode 100644 index 0000000..16ec37a --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/EssentialsListener.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import net.ess3.api.IUser; +import net.ess3.api.events.AfkStatusChangeEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class EssentialsListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public EssentialsListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onAfkStatusChangeEvent(AfkStatusChangeEvent event) { + IUser user = event.getAffected(); + plugin.logDebug("AFK: " + user.getName() + ":" + user.isAfk()); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.essentialsAFK(user.getBase(), !user.isAfk()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerChatListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerChatListener.java new file mode 100644 index 0000000..2b738c5 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerChatListener.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerChatListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerChatListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.MONITOR) + public void onAsyncPlayerChat(AsyncPlayerChatEvent event) { + String message = event.getMessage(); + plugin.logDebug("ChatFormat [" + event.isCancelled() + "]: " + event.getFormat()); + if (message.startsWith("[[townytag]]")) { + event.setMessage(message.replace("[[townytag]]", "")); + plugin.logDebug("Ignoring due to townytag"); + return; + } + event.setMessage(message.replace("[[townytag]]", "")); + if (event.isCancelled() && !plugin.isPluginEnabled("FactionChat") && !plugin.ignoreChatCancel) { + plugin.logDebug("Ignore chat message due to event cancellation: " + event.getMessage()); + return; + } + if (event.getPlayer().hasPermission("irc.message.gamechat")) { + plugin.logDebug("Player " + event.getPlayer().getName() + " has permission irc.message.gamechat"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameChat(event.getPlayer(), event.getMessage()); + } + } else { + plugin.logDebug("Player " + event.getPlayer().getName() + " does not have irc.message.gamechat permission."); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerCommandPreprocessingListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerCommandPreprocessingListener.java new file mode 100644 index 0000000..0344cb9 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerCommandPreprocessingListener.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerCommandPreprocessingListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerCommandPreprocessingListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerCommandPreprocessEvent(PlayerCommandPreprocessEvent event) { + if (event.isCancelled()) { + return; + } + String msg = event.getMessage(); + if (event.getPlayer().hasPermission("irc.message.gamechat")) { + if (msg.startsWith("/me ")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameAction(event.getPlayer(), msg.replace("/me", "")); + } + } else if (msg.startsWith("/broadcast ")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameBroadcast(event.getPlayer(), msg.replace("/broadcast", "")); + } + } + } + if (plugin.isPluginEnabled("Essentials")) { + if (msg.startsWith("/helpop ") || msg.startsWith("/amsg ") || msg.startsWith("/ac ")) { + if (msg.contains(" ")) { + String message = msg.split(" ", 2)[1]; + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.essHelpOp(event.getPlayer(), message); + } + } + } + } + for (PurpleBot ircBot : plugin.ircBots.values()) { + if (msg.startsWith("/")) { + String cmd; + String params = ""; + if (msg.contains(" ")) { + cmd = msg.split(" ", 2)[0]; + params = msg.split(" ", 2)[1]; + } else { + cmd = msg; + } + cmd = cmd.substring(0); + if (ircBot.channelCmdNotifyEnabled && !ircBot.channelCmdNotifyIgnore.contains(cmd)) { + ircBot.commandNotify(event.getPlayer(), cmd, params); + } + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerDeathListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerDeathListener.java new file mode 100644 index 0000000..9b1e64b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerDeathListener.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.TemplateName; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerDeathListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerDeathListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerDeathEvent(PlayerDeathEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameDeath((Player) event.getEntity(), + event.getDeathMessage(), TemplateName.GAME_DEATH); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerGameModeChangeListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerGameModeChangeListener.java new file mode 100644 index 0000000..532f13b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerGameModeChangeListener.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerGameModeChangeEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerGameModeChangeListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerGameModeChangeListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerGameModeChangeEvent(PlayerGameModeChangeEvent event) { + plugin.logDebug("GAMEMODE: " + event.getPlayer().getName() + " => " + event.getNewGameMode()); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameModeChange(event.getPlayer(), event.getNewGameMode()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerJoinListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerJoinListener.java new file mode 100644 index 0000000..47c8a01 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerJoinListener.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerJoinListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerJoinListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoinEvent(final PlayerJoinEvent event) { + plugin.logDebug("PlayerJoinEvent: " + event.getPlayer().getDisplayName() + + ": " + event.getPlayer().getCustomName()); + if (plugin.kickedPlayers.contains(event.getPlayer().getName())) { + plugin.kickedPlayers.remove(event.getPlayer().getName()); + plugin.logDebug("Removing player " + event.getPlayer().getName() + " from the recently kicked list."); + } + plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() { + @Override + public void run() { + plugin.clearHostCache(event.getPlayer()); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameJoin(event.getPlayer(), event.getJoinMessage()); + if (plugin.netPackets != null) { + plugin.netPackets.updateTabList(event.getPlayer()); + } + } + plugin.updateDisplayNameCache(event.getPlayer()); + plugin.updateUuidCache(event.getPlayer()); + } + }, 20); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerKickListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerKickListener.java new file mode 100644 index 0000000..a121a03 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerKickListener.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerKickEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerKickListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerKickListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerKickEvent(PlayerKickEvent event) { + plugin.logDebug("KICK: " + event.getPlayer().getName()); + if (!plugin.kickedPlayers.contains(event.getPlayer().getName())) { + plugin.kickedPlayers.add(event.getPlayer().getName()); + } + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameKick(event.getPlayer(), event.getLeaveMessage(), event.getReason()); + } + } + +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerPlayerAchievementAwardedListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerPlayerAchievementAwardedListener.java new file mode 100644 index 0000000..a683051 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerPlayerAchievementAwardedListener.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerAchievementAwardedEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerPlayerAchievementAwardedListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerPlayerAchievementAwardedListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerAchievementAwardedEvent(PlayerAchievementAwardedEvent event) { + plugin.logDebug("ACHIEVEMENT: " + event.getPlayer().getName() + " => " + event.getAchievement()); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameAchievement(event.getPlayer(), event.getAchievement()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerQuitListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerQuitListener.java new file mode 100644 index 0000000..3724fed --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GamePlayerQuitListener.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerQuitEvent; + +/** + * + * @author cnaude + */ +public class GamePlayerQuitListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GamePlayerQuitListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerQuitEvent(PlayerQuitEvent event) { + plugin.logDebug("QUIT: " + event.getPlayer().getName()); + if (plugin.kickedPlayers.contains(event.getPlayer().getName())) { + plugin.kickedPlayers.remove(event.getPlayer().getName()); + plugin.logDebug("Player " + + event.getPlayer().getName() + + " was in the recently kicked list. Not sending quit message."); + return; + } + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameQuit(event.getPlayer(), event.getQuitMessage()); + if (plugin.netPackets != null) { + plugin.netPackets.updateTabList(event.getPlayer()); + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/GameServerCommandListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/GameServerCommandListener.java new file mode 100644 index 0000000..f39a80a --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/GameServerCommandListener.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.server.ServerCommandEvent; + +/** + * + * @author cnaude + */ +public class GameServerCommandListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public GameServerCommandListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(priority = EventPriority.NORMAL) + public void onServerCommandEvent(ServerCommandEvent event) { + String cmd = event.getCommand(); + if (cmd.startsWith("say ")) { + String msg = cmd.split(" ", 2)[1]; + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.consoleChat(msg); + } + } else if (cmd.startsWith("broadcast ")) { + String msg = cmd.split(" ", 2)[1]; + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.consoleBroadcast(msg); + } + } else { + //plugin.logDebug("Invalid CE: " + cmd); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/HeroChatListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/HeroChatListener.java new file mode 100644 index 0000000..7729e4f --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/HeroChatListener.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.dthielke.herochat.ChannelChatEvent; +import com.dthielke.herochat.Chatter; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class HeroChatListener implements Listener { + + final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public HeroChatListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) + public void onChannelChatEvent(ChannelChatEvent event) { + Chatter chatter = event.getSender(); + plugin.logDebug("HC Format: " + event.getFormat()); + + ChatColor chatColor = event.getChannel().getColor(); + Player player = chatter.getPlayer(); + if (player.hasPermission("irc.message.gamechat") + && chatter.getChannels().contains(event.getChannel())) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + if (plugin.heroChatEmoteFormat.equals(event.getFormat())) { + plugin.logDebug("HC Emote: TRUE"); + ircBot.heroAction(chatter, chatColor, event.getMessage()); + } else { + plugin.logDebug("HC Emote: FALSE"); + ircBot.heroChat(chatter, chatColor, event.getMessage()); + } + } + } + } + +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/McMMOChatListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/McMMOChatListener.java new file mode 100644 index 0000000..c2b26d8 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/McMMOChatListener.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.gmail.nossr50.events.chat.McMMOAdminChatEvent; +import com.gmail.nossr50.events.chat.McMMOChatEvent; +import com.gmail.nossr50.events.chat.McMMOPartyChatEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class McMMOChatListener implements Listener { + + final PurpleIRC plugin; + + public McMMOChatListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onMcMMOChatEvent(McMMOChatEvent event) { + event.setMessage(event.getMessage().replace("[[townytag]]", "")); + String sender = event.getSender(); + Player player = plugin.getServer().getPlayer(sender); + plugin.logDebug("McMMOChatEvent caught: " + sender); + if (player != null && !sender.isEmpty()) { + if (player.hasPermission("irc.message.gamechat")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.mcMMOChat(player, event.getMessage()); + } + } + } + } + + @EventHandler + public void onMcMMOAdminChatEvent(McMMOAdminChatEvent event) { + event.setMessage(event.getMessage().replace("[[townytag]]", "")); + String sender = event.getSender(); + Player player = plugin.getServer().getPlayer(sender); + plugin.logDebug("McMMOAdminChatEvent caught: " + sender); + if (player != null && !sender.isEmpty()) { + if (player.hasPermission("irc.message.gamechat")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.mcMMOAdminChat(player, event.getMessage()); + } + } + } + } + + @EventHandler + public void onMcMMOPartyChatEvent(McMMOPartyChatEvent event) { + event.setMessage(event.getMessage().replace("[[townytag]]", "")); + String sender = event.getSender(); + Player player = plugin.getServer().getPlayer(sender); + String party = event.getParty(); + plugin.logDebug("onMcMMOPartyChatEvent caught: " + sender); + if (player != null && !sender.isEmpty()) { + if (player.hasPermission("irc.message.gamechat")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.mcMMOPartyChat(player, party, event.getMessage()); + } + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/OreBroadcastListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/OreBroadcastListener.java new file mode 100644 index 0000000..658c8e2 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/OreBroadcastListener.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import be.bendem.orebroadcast.OreBroadcastEvent; +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class OreBroadcastListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public OreBroadcastListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onOreBroadcastEvent(OreBroadcastEvent event) { + plugin.logDebug("onOreBroadcastEvent caught"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gameOreBroadcast(event.getPlayer(), event.getMessage()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/PrismListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/PrismListener.java new file mode 100644 index 0000000..f748ea0 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/PrismListener.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.TemplateName; +import me.botsko.prism.events.PrismBlocksDrainEvent; +import me.botsko.prism.events.PrismBlocksExtinguishEvent; +import me.botsko.prism.events.PrismBlocksRollbackEvent; +import me.botsko.prism.events.PrismCustomPlayerActionEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class PrismListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public PrismListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onPrismBlocksRollbackEvent(PrismBlocksRollbackEvent event) { + plugin.logDebug("onPrismBlocksRollbackEvent caught"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gamePrismRollback(event.onBehalfOf(), event.getQueryParameters(), event.getResult().getBlockStateChanges()); + } + } + + /** + * + * @param event + */ + @EventHandler + public void onPrismBlocksDrainEvent(PrismBlocksDrainEvent event) { + plugin.logDebug("onPrismBlocksDrainEvent caught"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gamePrismDrainOrExtinguish(TemplateName.PRISM_DRAIN, event.onBehalfOf(), event.getRadius(), event.getBlockStateChanges()); + } + } + + /** + * + * @param event + */ + @EventHandler + public void onPrismBlocksExtinguishEvent(PrismBlocksExtinguishEvent event) { + plugin.logDebug("onPrismBlocksExtinguishEvent caught"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gamePrismDrainOrExtinguish(TemplateName.PRISM_EXTINGUISH, event.onBehalfOf(), event.getRadius(), event.getBlockStateChanges()); + } + } + + /** + * + * @param event + */ + @EventHandler + public void onPrismCustomPlayerActionEvent(PrismCustomPlayerActionEvent event) { + plugin.logDebug("onPrismCustomPlayerActionEvent caught"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.gamePrismCustom(event.getPlayer(), event.getActionTypeName(), + event.getMessage(), event.getPluginName()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/RedditStreamListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/RedditStreamListener.java new file mode 100644 index 0000000..f4ae79b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/RedditStreamListener.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import io.github.wolf_359.RedditBroadcastEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class RedditStreamListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public RedditStreamListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onRedditBroadcastEvent(RedditBroadcastEvent event) { + plugin.logDebug("onRedditBroadcastEvent caught"); + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.redditStreamBroadcast(event.getMessage()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/ReportRTSListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/ReportRTSListener.java new file mode 100644 index 0000000..23de09e --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/ReportRTSListener.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.nyancraft.reportrts.event.TicketAssignEvent; +import com.nyancraft.reportrts.event.TicketClaimEvent; +import com.nyancraft.reportrts.event.TicketCompleteEvent; +import com.nyancraft.reportrts.event.TicketCreateEvent; +import com.nyancraft.reportrts.event.TicketHoldEvent; +import com.nyancraft.reportrts.event.TicketBroadcastEvent; +import com.nyancraft.reportrts.event.TicketReopenEvent; +import com.nyancraft.reportrts.event.TicketUnclaimEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class ReportRTSListener implements Listener { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public ReportRTSListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler + public void onTicketCreateEvent(TicketCreateEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getTicket().getName(), + event.getTicket(), ircBot.botNick, "rts-notify"); + } + } + + @EventHandler + public void onTicketCompleteEvent(TicketCompleteEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getTicket().getName(), + event.getTicket(), ircBot.botNick, "rts-complete"); + } + } + + @EventHandler + public void onTicketClaimEvent(TicketClaimEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getTicket().getName(), + event.getTicket(), ircBot.botNick, "rts-claim"); + } + } + + @EventHandler + public void onTicketUnclaimEvent(TicketUnclaimEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getTicket().getName(), + event.getTicket(), ircBot.botNick, "rts-unclaim"); + } + } + + @EventHandler + public void onTicketHoldEvent(TicketHoldEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getTicket().getName(), + event.getTicket(), ircBot.botNick, "rts-held"); + } + } + + @EventHandler + public void onTicketAssignEvent(TicketAssignEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getTicket().getName(), + event.getTicket(), ircBot.botNick, "rts-assign"); + } + } + + @EventHandler + public void onTicketReopenEvent(TicketReopenEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getTicket().getName(), + event.getTicket(), ircBot.botNick, "rts-reopen"); + } + } + + @EventHandler + public void onTicketBroadcastEvent(TicketBroadcastEvent event) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.reportRTSNotify(event.getSender(), + event.getMessage(), ircBot.botNick, "rts-modbroadcast"); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/TitanChatListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/TitanChatListener.java new file mode 100644 index 0000000..2470224 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/TitanChatListener.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.titankingdoms.dev.titanchat.core.participant.Participant; +import com.titankingdoms.dev.titanchat.event.ChannelChatEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class TitanChatListener implements Listener { + + final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public TitanChatListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param event + */ + @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) + public void onChannelChatEvent(ChannelChatEvent event) { + Participant participant = event.getSender(); + Player player = plugin.getServer().getPlayer(participant.getName()); + String tChannel = event.getChannel().getName(); + String tColor = event.getChannel().getDisplayColour(); + if (player.hasPermission("irc.message.gamechat")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.titanChat(participant, tChannel, tColor, event.getMessage()); + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/GameListeners/TownyChatListener.java b/src/main/java/com/cnaude/purpleirc/GameListeners/TownyChatListener.java new file mode 100644 index 0000000..8c1135d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/GameListeners/TownyChatListener.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.GameListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.palmergames.bukkit.TownyChat.channels.Channel; +import com.palmergames.bukkit.TownyChat.events.AsyncChatHookEvent; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +/** + * + * @author cnaude + */ +public class TownyChatListener implements Listener { + + final PurpleIRC plugin; + + public TownyChatListener(PurpleIRC plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onAsyncChatHookEvent(AsyncChatHookEvent event) { + if (event.getAsyncPlayerChatEvent().isCancelled()) { + plugin.logDebug("Ignore TC chat due to event is cancelled."); + return; + } + Channel townyChannel = event.getChannel(); + + plugin.logDebug("TC Format[1]: " + event.getFormat()); + + Player player = event.getPlayer(); + if (player.hasPermission("irc.message.gamechat")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + ircBot.townyChat(player, townyChannel, event.getMessage()); + } + } + event.getAsyncPlayerChatEvent().setMessage("[[townytag]]" + event.getMessage()); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/AdminPrivateChatHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/AdminPrivateChatHook.java new file mode 100755 index 0000000..ff3b124 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/AdminPrivateChatHook.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.ammaraskar.adminonly.AdminChat; +import com.cnaude.purpleirc.PurpleIRC; + + +/** + * + * @author cnaude + */ +public class AdminPrivateChatHook { + + private final PurpleIRC plugin; + private final AdminChat ac; + + /** + * + * @param plugin + */ + public AdminPrivateChatHook(PurpleIRC plugin) { + this.plugin = plugin; + this.ac = (AdminChat) plugin.getServer().getPluginManager().getPlugin("AdminPrivateChat"); + } + + public void sendMessage(String message, String playername) { + plugin.logDebug("AdminPrivateChatHook: " + message); + ac.methods.MessageBuild(message, playername, ""); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/DynmapHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/DynmapHook.java new file mode 100644 index 0000000..f622e3c --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/DynmapHook.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import org.dynmap.DynmapCommonAPI; + +/** + * + * @author cnaude + */ +public class DynmapHook { + + private final PurpleIRC plugin; + private final DynmapCommonAPI dynmapAPI; + + /** + * + * @param plugin + */ + public DynmapHook(PurpleIRC plugin) { + this.plugin = plugin; + this.dynmapAPI = (DynmapCommonAPI)plugin.getServer().getPluginManager().getPlugin("dynmap"); + } + + /** + * + * @param nick + * @param message + */ + public void sendMessage(String nick, String message) { + dynmapAPI.sendBroadcastToWeb(nick, message); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/FactionChatHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/FactionChatHook.java new file mode 100644 index 0000000..4f1c08b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/FactionChatHook.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import nz.co.lolnet.james137137.FactionChat.FactionChatAPI; +import org.bukkit.entity.Player; + +/** + * + * @author cnaude + */ +public class FactionChatHook { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public FactionChatHook(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param player + * @return + */ + public String getChatMode(Player player) { + String playerChatMode = null; + + try { + playerChatMode = FactionChatAPI.getChatMode(player); + plugin.logDebug("fcHook => [CM: " + playerChatMode + "] [" + player.getName() + "]"); + } catch (Exception ex) { + plugin.logError("fcHook ERROR: " + ex.getMessage()); + } + if (playerChatMode == null) { + playerChatMode = "unknown"; + } + return playerChatMode.toLowerCase(); + } + + /** + * + * @param player + * @return + */ + public String getFactionName(Player player) { + String factionName = null; + try { + factionName = FactionChatAPI.getFactionName(player); + plugin.logDebug("fcHook => [FN: " + factionName + "] [" + player.getName() + "]"); + } catch (Exception ex) { + plugin.logError("fcHook ERROR: " + ex.getMessage()); + } + if (factionName == null) { + factionName = "unknown"; + } + return factionName; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/JobsHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/JobsHook.java new file mode 100644 index 0000000..ba7d347 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/JobsHook.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.TemplateName; +import com.cnaude.purpleirc.PurpleIRC; +import com.gamingmesh.jobs.Jobs; +import com.gamingmesh.jobs.PlayerManager; +import com.gamingmesh.jobs.container.Job; +import com.google.common.base.Joiner; +import java.util.ArrayList; +import org.bukkit.entity.Player; + +/** + * + * @author cnaude + */ +public class JobsHook { + + private final PurpleIRC plugin; + private PlayerManager playerManager = null; + + /** + * + * @param plugin + */ + public JobsHook(PurpleIRC plugin) { + this.plugin = plugin; + try { + this.playerManager = Jobs.getPlayerManager(); + } catch (Exception ex) { + plugin.logError("Jobs: " + ex.getMessage()); + } + } + + public String getPlayerJob(Player player, boolean shortName) { + if (playerManager == null) { + return ""; + } + if (player != null) { + ArrayList j = new ArrayList<>(); + if (plugin.isPluginEnabled("Jobs")) { + for (Job job : Jobs.getJobs()) { + if (playerManager.getJobsPlayer(player).isInJob(job)) { + if (shortName) { + j.add(job.getShortName()); + } else { + j.add(job.getName()); + } + } + } + if (!j.isEmpty()) { + return Joiner.on(plugin.getMsgTemplate(TemplateName.JOBS_SEPARATOR)).join(j); + } + } + } + return ""; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/JobsHookOld.java b/src/main/java/com/cnaude/purpleirc/Hooks/JobsHookOld.java new file mode 100755 index 0000000..3dc6bb8 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/JobsHookOld.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.TemplateName; +import com.cnaude.purpleirc.PurpleIRC; +import com.google.common.base.Joiner; +import java.util.ArrayList; +import me.zford.jobs.Jobs; +import me.zford.jobs.PlayerManager; +import me.zford.jobs.container.Job; +import org.bukkit.entity.Player; + +/** + * + * @author cnaude + */ +public class JobsHookOld { + + private final PurpleIRC plugin; + private PlayerManager playerManager = null; + + /** + * + * @param plugin + */ + public JobsHookOld(PurpleIRC plugin) { + this.plugin = plugin; + try { + this.playerManager = Jobs.getPlayerManager(); + } catch (Exception ex) { + plugin.logError("Jobs: " + ex.getMessage()); + } + } + + public String getPlayerJob(Player player, boolean shortName) { + if (playerManager == null) { + return ""; + } + if (player != null) { + ArrayList j = new ArrayList<>(); + if (plugin.isPluginEnabled("Jobs")) { + for (Job job : Jobs.getJobs()) { + if (playerManager.getJobsPlayer(player).isInJob(job)) { + if (shortName) { + j.add(job.getShortName()); + } else { + j.add(job.getName()); + } + } + } + if (!j.isEmpty()) { + return Joiner.on(plugin.getMsgTemplate(TemplateName.JOBS_SEPARATOR)).join(j); + } + } + } + return ""; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/ReportRTSHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/ReportRTSHook.java new file mode 100755 index 0000000..e3a8423 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/ReportRTSHook.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import com.nyancraft.reportrts.RTSFunctions; +import com.nyancraft.reportrts.util.Message; + +/** + * + * @author cnaude + */ +public class ReportRTSHook { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public ReportRTSHook(PurpleIRC plugin) { + this.plugin = plugin; + } + + public void modBroadcast(String name, String message) { + RTSFunctions.messageMods(Message.parse("broadcastMessage", name, message), false); + plugin.logDebug("RTSMB: " + message); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/ShortifyHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/ShortifyHook.java new file mode 100644 index 0000000..0d7b656 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/ShortifyHook.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import com.nullblock.vemacs.Shortify.common.CommonConfiguration; +import com.nullblock.vemacs.Shortify.common.Shortener; +import com.nullblock.vemacs.Shortify.common.ShortifyException; +import com.nullblock.vemacs.Shortify.util.ShortifyUtility; +import java.io.File; + +/** + * + * @author cnaude + */ +public class ShortifyHook { + + private final PurpleIRC plugin; + private final CommonConfiguration configuration; + private final Shortener shortener; + + /** + * + * @param plugin + */ + public ShortifyHook(PurpleIRC plugin) { + this.plugin = plugin; + this.configuration = ShortifyUtility.loadCfg(new File("plugins/Shortify/config.yml")); + this.shortener = ShortifyUtility.getShortener(configuration); + } + + public String shorten(String message) { + String m = message; + int minLength = 20; + plugin.logDebug("ShortifyBefore: " + m); + if (configuration != null) { + try { + minLength = Integer.valueOf(configuration.getString("minlength", "20")); + } catch (Exception ex) { + plugin.logError(ex.getMessage()); + return message; + } + } + + if (shortener != null) { + try { + m = ShortifyUtility.shortenAll(message, minLength, shortener, ""); + } catch (ShortifyException ex) { + plugin.logError(ex.getMessage()); + return message; + } + } + plugin.logDebug("ShortifyAfter: " + m); + return m; + } + +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/SuperVanishHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/SuperVanishHook.java new file mode 100755 index 0000000..11d8e2f --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/SuperVanishHook.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import java.util.List; +import me.MyzelYam.SuperVanish.api.SVAPI; +import org.bukkit.entity.Player; + +/** + * + * @author cnaude + */ +public class SuperVanishHook { + + final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public SuperVanishHook(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param player + * @return + */ + public boolean isVanished(Player player) { + List invisiblePlayers = SVAPI.getInvisiblePlayers(); + for (String uuid : invisiblePlayers) { + if (uuid.equalsIgnoreCase(player.getUniqueId().toString())) { + plugin.logDebug("Player " + player.getName() + " is vanished."); + return true; + } + } + return false; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/TownyChatHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/TownyChatHook.java new file mode 100644 index 0000000..627d203 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/TownyChatHook.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import com.palmergames.bukkit.TownyChat.Chat; +import com.palmergames.bukkit.TownyChat.channels.channelTypes; +import com.palmergames.bukkit.towny.exceptions.NotRegisteredException; +import com.palmergames.bukkit.towny.object.Resident; +import com.palmergames.bukkit.towny.object.TownyUniverse; +import java.util.ArrayList; +import org.bukkit.entity.Player; + +/** + * + * @author cnaude + */ +public class TownyChatHook { + + private final PurpleIRC plugin; + private final Chat chat; + private final ArrayList townyChannelTypes; + + /** + * + * @param plugin + */ + public TownyChatHook(PurpleIRC plugin) { + this.plugin = plugin; + chat = (Chat) plugin.getServer().getPluginManager().getPlugin("TownyChat"); + townyChannelTypes = new ArrayList(); + townyChannelTypes.add(channelTypes.TOWN); + townyChannelTypes.add(channelTypes.GLOBAL); + townyChannelTypes.add(channelTypes.NATION); + townyChannelTypes.add(channelTypes.DEFAULT); + } + + public String getTown(Player player) { + String town = ""; + Resident resident; + try { + resident = TownyUniverse.getDataSource().getResident(player.getName()); + } catch (NotRegisteredException ex) { + resident = null; + } + + if (resident != null) { + try { + town = resident.getTown().getName(); + } catch (NotRegisteredException ex) { + town = ""; + } + } + return town; + } + + public String getNation(Player player) { + String nation = ""; + Resident resident; + try { + resident = TownyUniverse.getDataSource().getResident(player.getName()); + } catch (NotRegisteredException ex) { + resident = null; + } + if (resident != null) { + try { + nation = resident.getTown().getNation().getName(); + } catch (NotRegisteredException ex) { + nation = ""; + } + } + return nation; + } + + public String getTitle(Player player) { + Resident resident; + try { + resident = TownyUniverse.getDataSource().getResident(player.getName()); + } catch (NotRegisteredException ex) { + resident = null; + } + String title = ""; + if (resident != null) { + title = resident.getTitle(); + } + return title; + } + + public void sendMessage(String townyChannel, String message) { + plugin.logDebug("TownyChatHook called..."); + for (Player player : plugin.getServer().getOnlinePlayers()) { + plugin.logDebug("P: " + player.getName()); + for (channelTypes ct : townyChannelTypes) { + plugin.logDebug("CT: " + ct.name()); + String townyChannelName = chat.getChannelsHandler().getActiveChannel(player, ct).getName(); + if (townyChannel.equalsIgnoreCase(townyChannelName)) { + plugin.logDebug("TC ["+townyChannelName+"]: Sending message to " + player + ": " + message); + player.sendMessage(message); + break; + } else { + plugin.logDebug("TC "+townyChannelName+"]: invalid TC channel name for " + player); + } + + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/VanishHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/VanishHook.java new file mode 100644 index 0000000..d2ca813 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/VanishHook.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import org.bukkit.entity.Player; +import org.bukkit.metadata.MetadataValue; + +/** + * + * @author cnaude + */ +public class VanishHook { + + final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public VanishHook(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param player + * @return + */ + public boolean isVanished(Player player) { + // Try SuperVanish first + if (plugin.superVanishHook != null) { + return plugin.superVanishHook.isVanished(player); + } else { + // Fallback to other Vanish + if (player.hasMetadata("vanished")) { + plugin.logDebug("Player " + player.getName() + " has vanished metadata."); + MetadataValue md = player.getMetadata("vanished").get(0); + if (md.asBoolean()) { + plugin.logDebug("Player " + player.getName() + " is vanished."); + return true; + } else { + plugin.logDebug("Player " + player.getName() + " is NOT vanished."); + } + } else { + plugin.logDebug("Player " + player.getName() + " has NO vanished metadata."); + } + } + return false; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Hooks/VaultHook.java b/src/main/java/com/cnaude/purpleirc/Hooks/VaultHook.java new file mode 100644 index 0000000..e2cf477 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Hooks/VaultHook.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Hooks; + +import com.cnaude.purpleirc.PurpleIRC; +import net.milkbowl.vault.chat.Chat; +import net.milkbowl.vault.permission.Permission; +import org.bukkit.plugin.RegisteredServiceProvider; + +/** + * + * @author cnaude + */ +public class VaultHook { + + final PurpleIRC plugin; + + /** + * + */ + public Permission permission; + + /** + * + */ + public Chat chat; + + /** + * + * @param plugin + */ + public VaultHook(PurpleIRC plugin) { + this.plugin = plugin; + + setupPermissions(); + setupChat(); + } + + private void setupPermissions() { + RegisteredServiceProvider permissionProvider = plugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class); + if (permissionProvider != null) { + permission = permissionProvider.getProvider(); + } + } + + private void setupChat() { + RegisteredServiceProvider chatProvider = plugin.getServer().getServicesManager().getRegistration(net.milkbowl.vault.chat.Chat.class); + if (chatProvider != null) { + chat = chatProvider.getProvider(); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCCommand.java b/src/main/java/com/cnaude/purpleirc/IRCCommand.java new file mode 100644 index 0000000..f063093 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCCommand.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +/** + * + * @author cnaude + */ +public class IRCCommand { + final private IRCCommandSender sender; + final private String command; + + /** + * + * @param sender + * @param command + */ + public IRCCommand(IRCCommandSender sender, String command) { + this.sender = sender; + this.command = command; + } + + /** + * + * @return + */ + public IRCCommandSender getIRCCommandSender() { + return sender; + } + + /** + * + * @return + */ + public String getGameCommand() { + return command; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCCommandSender.java b/src/main/java/com/cnaude/purpleirc/IRCCommandSender.java new file mode 100644 index 0000000..144534b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCCommandSender.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import java.util.Set; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.command.CommandSender; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.plugin.Plugin; + +/** + * + * @author Chris Naude We have to implement our own CommandSender so that we can + * receive output from the command dispatcher. + */ +public class IRCCommandSender implements CommandSender { + + private final PurpleBot ircBot; + private final String target; + private final PurpleIRC plugin; + private final boolean ctcpResponse; + + /** + * + * @param message + */ + @Override + public void sendMessage(String message) { + plugin.logDebug("sendMessage: " + message); + addMessageToQueue(message); + } + + /** + * + * @param messages + */ + @Override + public void sendMessage(String[] messages) { + for (String message : messages) { + plugin.logDebug("sendMessage[]: " + message); + addMessageToQueue(message); + } + } + + private void addMessageToQueue(String message) { + ircBot.messageQueue.add(new IRCMessage(target, + plugin.colorConverter.gameColorsToIrc(message), ctcpResponse)); + } + + /** + * + * @param ircBot + * @param target + * @param plugin + * @param ctcpResponse + */ + public IRCCommandSender(PurpleBot ircBot, String target, PurpleIRC plugin, boolean ctcpResponse) { + super(); + this.target = target; + this.ircBot = ircBot; + this.plugin = plugin; + this.ctcpResponse = ctcpResponse; + + } + + /** + * + * @return + */ + @Override + public Server getServer() { + return Bukkit.getServer(); + } + + /** + * + * @return + */ + @Override + public String getName() { + return "CONSOLE"; + } + + /** + * + * @return + */ + @Override + public Set getEffectivePermissions() { + return null; + } + + /** + * + * @param perm + * @return + */ + @Override + public boolean hasPermission(final String perm) { + return true; + } + + /** + * + * @param arg0 + * @return + */ + @Override + public boolean hasPermission(final Permission arg0) { + return true; + } + + /** + * + * @param arg0 + * @return + */ + @Override + public boolean isPermissionSet(final String arg0) { + return true; + } + + /** + * + * @param arg0 + * @return + */ + @Override + public boolean isPermissionSet(final Permission arg0) { + return true; + } + + /** + * + */ + @Override + public void recalculatePermissions() { + } + + /** + * + * @param arg0 + */ + @Override + public void removeAttachment(final PermissionAttachment arg0) { + } + + /** + * + * @return + */ + @Override + public boolean isOp() { + return true; + } + + /** + * + * @param op + */ + @Override + public void setOp(final boolean op) { + } + + /** + * + * @param arg0 + * @return + */ + @Override + public PermissionAttachment addAttachment(final Plugin arg0) { + return null; + } + + /** + * + * @param arg0 + * @param arg1 + * @return + */ + @Override + public PermissionAttachment addAttachment(final Plugin arg0, final int arg1) { + return null; + } + + /** + * + * @param arg0 + * @param arg1 + * @param arg2 + * @return + */ + @Override + public PermissionAttachment addAttachment(final Plugin arg0, final String arg1, final boolean arg2) { + return null; + } + + /** + * + * @param arg0 + * @param arg1 + * @param arg2 + * @param arg3 + * @return + */ + @Override + public PermissionAttachment addAttachment(final Plugin arg0, final String arg1, final boolean arg2, final int arg3) { + return null; + } + +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/ActionListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/ActionListener.java new file mode 100644 index 0000000..68b0a9b --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/ActionListener.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.ActionEvent; + +/** + * + * @author cnaude + */ +public class ActionListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public ActionListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onAction(ActionEvent event) { + Channel channel = event.getChannel(); + if (ircBot.isValidChannel(channel.getName())) { + ircBot.broadcastAction(event.getUser(), channel, event.getAction()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/ConnectListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/ConnectListener.java new file mode 100644 index 0000000..84193c9 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/ConnectListener.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.PircBotX; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.ConnectEvent; + +/** + * + * @author cnaude + */ +public class ConnectListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public ConnectListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onConnect(ConnectEvent event) { + PircBotX bot = event.getBot(); + if (bot.getUserBot().getNick().isEmpty()) { + plugin.logError("Connected but bot nick is blank!"); + } else { + ircBot.broadcastIRCConnect(ircBot.botNick); + if (ircBot.sendRawMessageOnConnect) { + plugin.logInfo("Sending raw message to server"); + ircBot.asyncRawlineNow(ircBot.rawMessage); + } + } + ircBot.setConnected(true); + ircBot.autoJoinChannels(); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/DisconnectListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/DisconnectListener.java new file mode 100644 index 0000000..77db392 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/DisconnectListener.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.DisconnectEvent; + +/** + * + * @author cnaude + */ +public class DisconnectListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public DisconnectListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onDisconnect(DisconnectEvent event) { + ircBot.asyncQuit(false); + ircBot.broadcastIRCDisconnect(ircBot.botNick); + ircBot.setConnected(false); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/JoinListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/JoinListener.java new file mode 100644 index 0000000..5fb7ac1 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/JoinListener.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.JoinEvent; + +/** + * + * @author cnaude + */ +public class JoinListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public JoinListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onJoin(JoinEvent event) { + Channel channel = event.getChannel(); + String channelName = channel.getName(); + User user = event.getUser(); + + if (!ircBot.isValidChannel(channel.getName())) { + plugin.logDebug("Invalid channel: " + channelName); + plugin.logDebug("Part if invalid: " + ircBot.partInvalidChannels); + plugin.logDebug("Nick: " + user.getNick()); + if (user.getNick().equals(ircBot.botNick) && ircBot.partInvalidChannels) { + plugin.logInfo("Leaving invalid channel: " + channel.getName()); + channel.send().part(ircBot.partInvalidChannelsMsg); + } + return; + } + ircBot.broadcastIRCJoin(user, channel); + ircBot.opIrcUser(channel, user); + ircBot.voiceIrcUser(channel, user); + ircBot.joinNotice(channel, user); + if (user.getNick().equals(ircBot.botNick)) { + plugin.logInfo("Joining channel: " + channelName); + plugin.logDebug("Setting channel modes: " + channelName + " => " + ircBot.channelModes.get(channel.getName())); + channel.send().setMode(ircBot.channelModes.get(channelName)); + ircBot.fixTopic(channel, channel.getTopic(), channel.getTopicSetter()); + ircBot.updateNickList(channel); + if (ircBot.msgOnJoin.containsKey(channelName) && ircBot.joinMsg.containsKey(channelName)) { + if (ircBot.msgOnJoin.get(channelName) && !ircBot.joinMsg.get(channelName).isEmpty()) { + plugin.logDebug("Sending on join message to IRC server: " + ircBot.joinMsg.get(channelName)); + ircBot.asyncRawlineNow(ircBot.joinMsg.get(channelName)); + } + } + } + if (plugin.netPackets != null) { + plugin.netPackets.addToTabList(user.getNick(), ircBot, channel); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/KickListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/KickListener.java new file mode 100644 index 0000000..bf24bc6 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/KickListener.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.KickEvent; + +/** + * + * @author cnaude + */ +public class KickListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public KickListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onKick(KickEvent event) { + Channel channel = event.getChannel(); + User recipient = event.getRecipient(); + User user = event.getUser(); + + if (ircBot.isValidChannel(channel.getName())) { + ircBot.broadcastIRCKick(recipient, user, event.getReason(), channel); + if (plugin.netPackets != null) { + plugin.netPackets.remFromTabList(recipient.getNick()); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/MessageListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/MessageListener.java new file mode 100644 index 0000000..19c82f9 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/MessageListener.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.MessageEvent; + +/** + * + * @author cnaude + */ +public class MessageListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public MessageListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onMessage(MessageEvent event) { + + String message = event.getMessage(); + Channel channel = event.getChannel(); + User user = event.getUser(); + + plugin.logDebug("Message caught <" + user.getNick() + ">: " + message); + + if (plugin.shortifyHook != null && ircBot.isShortifyEnabled(channel.getName())) { + plugin.logDebug("Shortifying message (before): " + message); + message = plugin.shortifyHook.shorten(message); + plugin.logDebug("Shortifying message (after): " + message); + } else { + plugin.logDebug("Shortify: false"); + } + + if (ircBot.isValidChannel(channel.getName())) { + plugin.ircMessageHandler.processMessage(ircBot, user, channel, message, false); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/ModeListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/ModeListener.java new file mode 100644 index 0000000..87fcebe --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/ModeListener.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.ModeEvent; + +/** + * + * @author cnaude + */ +public class ModeListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public ModeListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onMode(ModeEvent event) { + Channel channel = event.getChannel(); + String mode = event.getMode(); + User user = event.getUser(); + + if (!ircBot.isValidChannel(channel.getName())) { + ircBot.broadcastIRCMode(user, mode, channel); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/MotdListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/MotdListener.java new file mode 100644 index 0000000..3ea0aa7 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/MotdListener.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.MotdEvent; + +/** + * + * @author cnaude + */ +public class MotdListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public MotdListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onMotd(MotdEvent event) { + if (ircBot.showMOTD) { + plugin.logInfo(event.getMotd()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/NickChangeListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/NickChangeListener.java new file mode 100644 index 0000000..67747f2 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/NickChangeListener.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.TemplateName; +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.NickChangeEvent; + +/** + * + * @author cnaude + */ +public class NickChangeListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public NickChangeListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onNickChange(NickChangeEvent event) { + String newNick = event.getNewNick(); + String oldNick = event.getOldNick(); + plugin.logDebug("OLD: " + oldNick); + plugin.logDebug("NEW: " + newNick); + + for (String channelName : ircBot.channelNicks.keySet()) { + Channel channel = ircBot.getChannel(channelName); + if (channel != null) { + if (ircBot.enabledMessages.get(channelName).contains(TemplateName.IRC_NICK_CHANGE)) { + plugin.getServer().broadcast(plugin.colorConverter.ircColorsToGame( + plugin.getMsgTemplate(ircBot.botNick, TemplateName.IRC_NICK_CHANGE) + .replace("%NEWNICK%", newNick) + .replace("%OLDNICK%", oldNick) + .replace("%CHANNEL%", channelName)), "irc.message.nickchange"); + } + if (plugin.netPackets != null) { + plugin.netPackets.remFromTabList(oldNick); + plugin.netPackets.addToTabList(newNick, ircBot, channel); + } + if (ircBot.channelNicks.get(channelName).contains(oldNick)) { + ircBot.channelNicks.get(channelName).remove(oldNick); + plugin.logDebug("Removing " + oldNick); + } + ircBot.channelNicks.get(channelName).add(newNick); + plugin.logDebug("Adding " + newNick); + } + } + + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/NoticeListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/NoticeListener.java new file mode 100644 index 0000000..1519b23 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/NoticeListener.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.NoticeEvent; + +/** + * + * @author cnaude + */ +public class NoticeListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public NoticeListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onNotice(NoticeEvent event) { + Channel channel = event.getChannel(); + String message = event.getMessage(); + String notice = event.getNotice(); + User user = event.getUser(); + + plugin.logInfo("-" + user.getNick() + "-" + message); + if (channel != null) { + if (ircBot.isValidChannel(channel.getName())) { + ircBot.broadcastIRCNotice(user, message, notice, channel); + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/PartListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/PartListener.java new file mode 100644 index 0000000..2b07041 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/PartListener.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.PartEvent; + +/** + * + * @author cnaude + */ +public class PartListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public PartListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onPart(PartEvent event) { + Channel channel = event.getChannel(); + User user = event.getUser(); + + if (ircBot.isValidChannel(channel.getName())) { + ircBot.broadcastIRCPart(user, channel); + if (plugin.netPackets != null) { + plugin.netPackets.remFromTabList(user.getNick()); + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/PrivateMessageListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/PrivateMessageListener.java new file mode 100644 index 0000000..fc5ffed --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/PrivateMessageListener.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.PrivateMessageEvent; + +/** + * + * @author cnaude + */ +public class PrivateMessageListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public PrivateMessageListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onPrivateMessage(PrivateMessageEvent event) { + + String message = event.getMessage(); + User user = event.getUser(); + Channel channel; + + plugin.logDebug("Private message caught <" + user.getNick() + ">: " + message); + + for (String myChannel : ircBot.botChannels) { + channel = ircBot.getChannel(myChannel); + if (channel != null) { + if (user.getChannels().contains(channel)) { + plugin.ircMessageHandler.processMessage(ircBot, user, channel, message, true); + return; + } + plugin.logDebug("Private message from " + user.getNick() + " ignored because not in valid channel."); + } + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/QuitListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/QuitListener.java new file mode 100644 index 0000000..a28dbe4 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/QuitListener.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.QuitEvent; + +/** + * + * @author cnaude + */ +public class QuitListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public QuitListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onQuit(QuitEvent event) { + String nick = event.getUser().getNick(); + for (String channelName : ircBot.channelNicks.keySet()) { + if (ircBot.channelNicks.get(channelName).contains(nick)) { + ircBot.broadcastIRCQuit(event.getUser(), ircBot.getChannel(channelName), event.getReason()); + if (plugin.netPackets != null) { + plugin.netPackets.remFromTabList(nick); + } + } + ircBot.channelNicks.get(channelName).remove(nick); + } + } +} + diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/ServerResponseListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/ServerResponseListener.java new file mode 100644 index 0000000..bb54a93 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/ServerResponseListener.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.ReplyConstants; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.ServerResponseEvent; + +/** + * + * @author cnaude + */ +public class ServerResponseListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public ServerResponseListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onServerResponse(ServerResponseEvent event) { + int serverReply = event.getCode(); + + if (serverReply == ReplyConstants.ERR_BADCHANNELKEY) { + plugin.logInfo("Bad channel password."); + } + + if (serverReply == ReplyConstants.ERR_BANNEDFROMCHAN) { + plugin.logInfo("Banned from the channel."); + } + + if (serverReply == ReplyConstants.ERR_NICKNAMEINUSE) { + plugin.logInfo("Nickname already in use."); + ircBot.altNickChange(); + } + + //plugin.logDebug("Server response: " + event.getRawLine()); + + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/TopicListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/TopicListener.java new file mode 100644 index 0000000..96ec01f --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/TopicListener.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.TemplateName; +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import org.pircbotx.Channel; +import org.pircbotx.User; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.TopicEvent; + +/** + * + * @author cnaude + */ +public class TopicListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public TopicListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onTopic(TopicEvent event) { + Channel channel = event.getChannel(); + User user = event.getUser(); + + if (ircBot.isValidChannel(channel.getName())) { + ircBot.fixTopic(channel, event.getTopic(), event.getUser().getNick()); + if (event.isChanged()) { + if (ircBot.enabledMessages.get(channel.getName()).contains(TemplateName.IRC_TOPIC)) { + String message = plugin.colorConverter.ircColorsToGame( + plugin.getMsgTemplate(ircBot.botNick, TemplateName.IRC_TOPIC) + .replace("%NAME%", user.getNick()) + .replace("%TOPIC%", event.getTopic()) + .replace("%CHANNEL%", channel.getName())); + plugin.logDebug("Sending topic notification due to " + + TemplateName.IRC_TOPIC + " being true: " + message); + plugin.getServer().broadcast(message, "irc.message.topic"); + } + } + ircBot.activeTopic.put(channel.getName(), event.getTopic()); + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCListeners/WhoisListener.java b/src/main/java/com/cnaude/purpleirc/IRCListeners/WhoisListener.java new file mode 100644 index 0000000..bf73d5a --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCListeners/WhoisListener.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.IRCListeners; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import java.text.SimpleDateFormat; +import java.util.List; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.pircbotx.hooks.ListenerAdapter; +import org.pircbotx.hooks.events.WhoisEvent; + +/** + * + * @author cnaude + */ +public class WhoisListener extends ListenerAdapter { + + PurpleIRC plugin; + PurpleBot ircBot; + + /** + * + * @param plugin + * @param ircBot + */ + public WhoisListener(PurpleIRC plugin, PurpleBot ircBot) { + this.plugin = plugin; + this.ircBot = ircBot; + } + + /** + * + * @param event + */ + @Override + public void onWhois(WhoisEvent event) { + if (ircBot.whoisSenders.isEmpty()) { + return; + } + CommandSender sender = ircBot.whoisSenders.remove(0); + + sender.sendMessage(ChatColor.DARK_PURPLE + "----[ " + ChatColor.WHITE + "Whois" + ChatColor.DARK_PURPLE + " ]----"); + sender.sendMessage(ChatColor.DARK_PURPLE + "Nick: " + ChatColor.WHITE + event.getNick()); + sender.sendMessage(ChatColor.DARK_PURPLE + "Username: " + ChatColor.WHITE + event.getLogin() + "@" + event.getHostname()); + sender.sendMessage(ChatColor.DARK_PURPLE + "Real name: " + ChatColor.WHITE + event.getRealname()); + sender.sendMessage(ChatColor.DARK_PURPLE + "Server: " + ChatColor.WHITE + event.getServer()); + if (!event.getChannels().isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (Object channel : (List)event.getChannels()) { + sb.append(" "); + sb.append(channel); + } + sender.sendMessage(ChatColor.DARK_PURPLE + "Currently on:" + ChatColor.WHITE + sb.toString()); + } + sender.sendMessage(ChatColor.DARK_PURPLE + "Idle: " + ChatColor.WHITE + secondsToTime(event.getIdleSeconds())); + sender.sendMessage(ChatColor.DARK_PURPLE + "Online since: " + ChatColor.WHITE + secondsToDate(event.getSignOnTime())); + sender.sendMessage(ChatColor.DARK_PURPLE + "----[ " + ChatColor.WHITE + "End Whois" + ChatColor.DARK_PURPLE + " ]----"); + } + + private String secondsToDate(long sec) { + return new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new java.util.Date (sec * 1000)); + } + + private String secondsToTime(long sec) { + int idleDays = (int) (sec / 86400L); + int idleHours = (int) (sec / 3600L % 24L); + int idleMinutes = (int) (sec / 60L % 60L); + int idleSeconds = (int) (sec % 60L); + String msg = ""; + if (idleDays > 0) { + msg = idleDays + " day"; + if (idleDays > 1) { + msg = msg + "s"; + } + msg = msg + " "; + } + if (idleHours > 0) { + msg = idleHours + " hour"; + if (idleHours > 1) { + msg = msg + "s"; + } + msg = msg + " "; + } + if (idleMinutes > 0 ) { + msg = msg + idleMinutes + " minute"; + if (idleMinutes > 1) { + msg = msg + "s"; + } + msg = msg + " "; + } + if (idleSeconds > 0 ) { + msg = msg + idleSeconds + " second"; + if (idleSeconds > 1) { + msg = msg + "s"; + } + msg = msg + " "; + } + return msg; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCMessage.java b/src/main/java/com/cnaude/purpleirc/IRCMessage.java new file mode 100644 index 0000000..de4b78d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCMessage.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +/** + * + * @author cnaude + */ +public class IRCMessage { + + public String target; + public String message; + public boolean ctcpResponse; + + public IRCMessage(String target, String message, boolean ctcpResponse) { + this.target = target; + this.message = message; + this.ctcpResponse = ctcpResponse; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/IRCMessageQueueWatcher.java b/src/main/java/com/cnaude/purpleirc/IRCMessageQueueWatcher.java new file mode 100644 index 0000000..199af37 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/IRCMessageQueueWatcher.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * + * @author Chris Naude Poll the command queue and dispatch to Bukkit + */ +public class IRCMessageQueueWatcher { + + private final PurpleIRC plugin; + private final PurpleBot ircBot; + private final Timer timer; + private final BlockingQueue queue = new LinkedBlockingQueue<>(); + + /** + * + * @param plugin + * @param ircBot + */ + public IRCMessageQueueWatcher(final PurpleBot ircBot, final PurpleIRC plugin) { + this.plugin = plugin; + this.ircBot = ircBot; + this.timer = new Timer(); + startWatcher(); + } + + private void startWatcher() { + timer.schedule(new TimerTask() { + @Override + public void run() { + queueAndSend(); + } + + }, 0, 5); + } + + private void queueAndSend() { + IRCMessage ircMessage = queue.poll(); + if (ircMessage != null) { + plugin.logDebug("[" + queue.size() + "]: queueAndSend message detected"); + if (ircMessage.ctcpResponse) { + ircBot.blockingCTCPMessage(ircMessage.target, ircMessage.message); + } else { + ircBot.blockingIRCMessage(ircMessage.target, ircMessage.message); + } + } + } + + public void cancel() { + timer.cancel(); + } + + public String clearQueue() { + int size = queue.size(); + if (!queue.isEmpty()) { + queue.clear(); + } + return "Elements removed from message queue: " + size; + } + + /** + * + * @param ircMessage + */ + public void add(IRCMessage ircMessage) { + queue.offer(ircMessage); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/PurpleBot.java b/src/main/java/com/cnaude/purpleirc/PurpleBot.java new file mode 100644 index 0000000..e2198ca --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/PurpleBot.java @@ -0,0 +1,2959 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import com.cnaude.purpleirc.IRCListeners.ActionListener; +import com.cnaude.purpleirc.IRCListeners.ConnectListener; +import com.cnaude.purpleirc.IRCListeners.DisconnectListener; +import com.cnaude.purpleirc.IRCListeners.JoinListener; +import com.cnaude.purpleirc.IRCListeners.KickListener; +import com.cnaude.purpleirc.IRCListeners.MessageListener; +import com.cnaude.purpleirc.IRCListeners.ModeListener; +import com.cnaude.purpleirc.IRCListeners.MotdListener; +import com.cnaude.purpleirc.IRCListeners.NickChangeListener; +import com.cnaude.purpleirc.IRCListeners.NoticeListener; +import com.cnaude.purpleirc.IRCListeners.PartListener; +import com.cnaude.purpleirc.IRCListeners.PrivateMessageListener; +import com.cnaude.purpleirc.IRCListeners.QuitListener; +import com.cnaude.purpleirc.IRCListeners.ServerResponseListener; +import com.cnaude.purpleirc.IRCListeners.TopicListener; +import com.cnaude.purpleirc.IRCListeners.WhoisListener; +import com.cnaude.purpleirc.Utilities.CaseInsensitiveMap; +import com.dthielke.herochat.Chatter; +import com.dthielke.herochat.Herochat; +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableSortedSet; +import com.massivecraft.factions.entity.Faction; +import com.massivecraft.factions.entity.MPlayer; +import com.nyancraft.reportrts.data.Ticket; +import com.titankingdoms.dev.titanchat.core.participant.Participant; +import java.io.File; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.charset.Charset; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import me.botsko.prism.actionlibs.QueryParameters; +import me.botsko.prism.events.BlockStateChange; +import org.bukkit.Achievement; +import org.bukkit.ChatColor; +import org.bukkit.GameMode; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.pircbotx.Channel; +import org.pircbotx.Configuration; +import org.pircbotx.PircBotX; +import org.pircbotx.User; +import org.pircbotx.UtilSSLSocketFactory; +import org.pircbotx.exception.IrcException; +import org.pircbotx.hooks.ListenerAdapter; + +/** + * + * @author Chris Naude + */ +public final class PurpleBot { + + private PircBotX bot; + + public final PurpleIRC plugin; + private final File file; + private YamlConfiguration config; + private boolean connected; + public boolean autoConnect; + public boolean ssl; + public boolean trustAllCerts; + public boolean sendRawMessageOnConnect; + public boolean showMOTD; + public boolean channelCmdNotifyEnabled; + public boolean relayPrivateChat; + public boolean partInvalidChannels; + public int botServerPort; + public long chatDelay; + public String botServer; + public String bindAddress; + public String nick; + public String botNick; + public List altNicks; + int nickIndex = 0; + public String botLogin; + public String botRealName; + public int ircMaxLineLength; + public String botServerPass; + public String charSet; + public String commandPrefix; + public String quitMessage; + public String botIdentPassword; + public String rawMessage; + public String channelCmdNotifyMode; + public String partInvalidChannelsMsg; + private String connectMessage; + public ArrayList botChannels; + public CaseInsensitiveMap> channelNicks; + public CaseInsensitiveMap> tabIgnoreNicks; + public CaseInsensitiveMap> filters; + public CaseInsensitiveMap channelPassword; + public CaseInsensitiveMap channelTopic; + public CaseInsensitiveMap channelTopicChanserv; + public CaseInsensitiveMap activeTopic; + public CaseInsensitiveMap channelModes; + public CaseInsensitiveMap joinMsg; + public CaseInsensitiveMap msgOnJoin; + public CaseInsensitiveMap channelTopicProtected; + public CaseInsensitiveMap channelAutoJoin; + public long channelAutoJoinDelay; + public CaseInsensitiveMap ignoreIRCChat; + public CaseInsensitiveMap hideJoinWhenVanished; + public CaseInsensitiveMap hideListWhenVanished; + public CaseInsensitiveMap hideQuitWhenVanished; + public CaseInsensitiveMap invalidCommandPrivate; + public CaseInsensitiveMap invalidCommandCTCP; + public CaseInsensitiveMap logIrcToHeroChat; + public CaseInsensitiveMap enableMessageFiltering; + private final CaseInsensitiveMap shortify; + public CaseInsensitiveMap heroChannel; + public CaseInsensitiveMap townyChannel; + public CaseInsensitiveMap> opsList; + public CaseInsensitiveMap> voicesList; + public CaseInsensitiveMap> worldList; + public CaseInsensitiveMap> muteList; + public CaseInsensitiveMap> enabledMessages; + public CaseInsensitiveMap>> commandMap; + public CaseInsensitiveMap>> extraCommandMap; + public CaseInsensitiveMap joinNoticeCooldownMap; + public ArrayList whoisSenders; + public List channelCmdNotifyRecipients; + public List channelCmdNotifyIgnore; + private final ArrayList ircListeners; + public IRCMessageQueueWatcher messageQueue; + private final String fileName; + int joinNoticeCoolDown; + boolean joinNoticeEnabled; + boolean joinNoticePrivate; + boolean joinNoticeCtcp; + String joinNoticeMessage; + String version; + String finger; + + /** + * + * @param file + * @param plugin + */ + public PurpleBot(File file, PurpleIRC plugin) { + fileName = file.getName(); + this.altNicks = new ArrayList<>(); + this.connected = false; + this.botChannels = new ArrayList<>(); + this.ircListeners = new ArrayList<>(); + this.channelCmdNotifyRecipients = new ArrayList<>(); + this.channelCmdNotifyIgnore = new ArrayList<>(); + this.commandMap = new CaseInsensitiveMap<>(); + this.extraCommandMap = new CaseInsensitiveMap<>(); + this.joinNoticeCooldownMap = new CaseInsensitiveMap<>(); + this.enabledMessages = new CaseInsensitiveMap<>(); + this.muteList = new CaseInsensitiveMap<>(); + this.worldList = new CaseInsensitiveMap<>(); + this.opsList = new CaseInsensitiveMap<>(); + this.voicesList = new CaseInsensitiveMap<>(); + this.heroChannel = new CaseInsensitiveMap<>(); + this.townyChannel = new CaseInsensitiveMap<>(); + this.invalidCommandCTCP = new CaseInsensitiveMap<>(); + this.logIrcToHeroChat = new CaseInsensitiveMap<>(); + this.shortify = new CaseInsensitiveMap<>(); + this.invalidCommandPrivate = new CaseInsensitiveMap<>(); + this.hideQuitWhenVanished = new CaseInsensitiveMap<>(); + this.hideListWhenVanished = new CaseInsensitiveMap<>(); + this.hideJoinWhenVanished = new CaseInsensitiveMap<>(); + this.ignoreIRCChat = new CaseInsensitiveMap<>(); + this.channelAutoJoin = new CaseInsensitiveMap<>(); + this.channelTopicProtected = new CaseInsensitiveMap<>(); + this.channelModes = new CaseInsensitiveMap<>(); + this.activeTopic = new CaseInsensitiveMap<>(); + this.channelTopic = new CaseInsensitiveMap<>(); + this.channelPassword = new CaseInsensitiveMap<>(); + this.tabIgnoreNicks = new CaseInsensitiveMap<>(); + this.filters = new CaseInsensitiveMap<>(); + this.channelNicks = new CaseInsensitiveMap<>(); + this.channelTopicChanserv = new CaseInsensitiveMap<>(); + this.joinMsg = new CaseInsensitiveMap<>(); + this.msgOnJoin = new CaseInsensitiveMap<>(); + this.enableMessageFiltering = new CaseInsensitiveMap<>(); + this.plugin = plugin; + this.file = file; + whoisSenders = new ArrayList<>(); + config = new YamlConfiguration(); + loadConfig(); + addListeners(); + version = plugin.getDescription().getFullName() + ", " + + plugin.getDescription().getDescription() + " - " + + plugin.getDescription().getWebsite(); + buildBot(); + messageQueue = new IRCMessageQueueWatcher(this, plugin); + + } + + public void buildBot() { + Configuration.Builder configBuilder = new Configuration.Builder() + .setName(botNick) + .setLogin(botLogin) + .setAutoNickChange(true) + .setVersion(version) + .setFinger(finger) + .setCapEnabled(true) + .setMessageDelay(chatDelay) + .setRealName(botRealName) + .setMaxLineLength(ircMaxLineLength) + //.setAutoReconnect(autoConnect) // Why doesn't this work? + .setServer(botServer, botServerPort, botServerPass); + //addAutoJoinChannels(configBuilder); + for (ListenerAdapter ll : ircListeners) { + configBuilder.addListener(ll); + } + if (!botIdentPassword.isEmpty()) { + plugin.logInfo("Setting IdentPassword ..."); + configBuilder.setNickservPassword(botIdentPassword); + } + if (ssl) { + UtilSSLSocketFactory socketFactory = new UtilSSLSocketFactory(); + socketFactory.disableDiffieHellman(); + if (trustAllCerts) { + plugin.logInfo("Enabling SSL and trusting all certificates ..."); + socketFactory.trustAllCertificates(); + } else { + plugin.logInfo("Enabling SSL ..."); + } + configBuilder.setSocketFactory(socketFactory); + } + if (charSet.isEmpty()) { + plugin.logInfo("Using default character set: " + Charset.defaultCharset()); + } else { + if (Charset.isSupported(charSet)) { + plugin.logInfo("Using character set: " + charSet); + configBuilder.setEncoding(Charset.forName(charSet)); + } else { + plugin.logError("Invalid character set: " + charSet); + plugin.logInfo("Available character sets: " + Joiner.on(", ").join(Charset.availableCharsets().keySet())); + plugin.logInfo("Using default character set: " + Charset.defaultCharset()); + } + } + if (!bindAddress.isEmpty()) { + plugin.logInfo("Binding to " + bindAddress); + try { + configBuilder.setLocalAddress(InetAddress.getByName(bindAddress)); + } catch (UnknownHostException ex) { + plugin.logError(ex.getMessage()); + } + } + Configuration configuration = configBuilder.buildConfiguration(); + bot = new PircBotX(configuration); + if (autoConnect) { + asyncConnect(); + } else { + plugin.logInfo("Auto-connect is disabled. To connect: /irc connect " + bot.getNick()); + } + plugin.logInfo("Max line length: " + configBuilder.getMaxLineLength()); + } + + private void addListeners() { + ircListeners.add(new ActionListener(plugin, this)); + ircListeners.add(new ConnectListener(plugin, this)); + ircListeners.add(new DisconnectListener(plugin, this)); + ircListeners.add(new JoinListener(plugin, this)); + ircListeners.add(new KickListener(plugin, this)); + ircListeners.add(new MessageListener(plugin, this)); + ircListeners.add(new ModeListener(plugin, this)); + ircListeners.add(new NickChangeListener(plugin, this)); + ircListeners.add(new NoticeListener(plugin, this)); + ircListeners.add(new PartListener(plugin, this)); + ircListeners.add(new PrivateMessageListener(plugin, this)); + ircListeners.add(new QuitListener(plugin, this)); + ircListeners.add(new TopicListener(plugin, this)); + ircListeners.add(new WhoisListener(plugin, this)); + ircListeners.add(new MotdListener(plugin, this)); + ircListeners.add(new ServerResponseListener(plugin, this)); + } + + /* + private void addAutoJoinChannels(Configuration.Builder configBuilder) { + for (String channelName : botChannels) { + if (channelAutoJoin.containsKey(channelName)) { + if (channelAutoJoin.get(channelName)) { + if (channelPassword.get(channelName).isEmpty()) { + configBuilder.addAutoJoinChannel(channelName); + } else { + configBuilder.addAutoJoinChannel(channelName, channelPassword.get(channelName)); + } + } + } + } + } + */ + public void autoJoinChannels() { + plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() { + @Override + public void run() { + for (String channelName : botChannels) { + if (channelAutoJoin.containsKey(channelName)) { + if (channelAutoJoin.get(channelName)) { + if (bot.isConnected()) { + if (channelPassword.get(channelName).isEmpty()) { + bot.sendIRC().joinChannel(channelName); + } else { + bot.sendIRC().joinChannel(channelName, channelPassword.get(channelName)); + } + } + } + } + } + + } + }, channelAutoJoinDelay); + + } + + public void reload(CommandSender sender) { + sender.sendMessage("Reloading bot: " + botNick); + reload(); + } + + public void reload() { + asyncQuit(true); + } + + /** + * + * @param sender + */ + public void reloadConfig(CommandSender sender) { + config = new YamlConfiguration(); + loadConfig(); + sender.sendMessage("[PurpleIRC] [" + botNick + "] IRC bot configuration reloaded."); + } + + /** + * + * @param channelName + * @param sender + * @param user + */ + public void mute(String channelName, CommandSender sender, String user) { + if (muteList.get(channelName).contains(user)) { + sender.sendMessage("User '" + user + "' is already muted."); + } else { + sender.sendMessage("User '" + user + "' is now muted."); + muteList.get(channelName).add(user); + saveConfig(); + } + } + + /** + * + * @param channelName + * @param sender + */ + public void muteList(String channelName, CommandSender sender) { + if (muteList.get(channelName).isEmpty()) { + sender.sendMessage("There are no users muted for " + channelName); + } else { + sender.sendMessage("Muted users for " + channelName + + ": " + Joiner.on(", ").join(muteList.get(channelName))); + saveConfig(); + } + } + + /** + * + * @param channelName + * @param sender + * @param user + */ + public void unMute(String channelName, CommandSender sender, String user) { + if (muteList.get(channelName).contains(user)) { + sender.sendMessage("User '" + user + "' is no longer muted."); + muteList.get(channelName).remove(user); + saveConfig(); + } else { + sender.sendMessage("User '" + user + "' is not muted."); + } + } + + public void asyncConnect(CommandSender sender) { + sender.sendMessage(connectMessage); + asyncConnect(); + } + + public boolean isShortifyEnabled(String channelName) { + if (shortify.containsKey(channelName)) { + return shortify.get(channelName); + } + return false; + } + + /** + * + */ + public void asyncConnect() { + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + try { + plugin.logInfo(connectMessage); + bot.startBot(); + } catch (IOException | IrcException ex) { + plugin.logError("Problem connecting to " + botServer + " => " + + " as " + botNick + " [Error: " + ex.getMessage() + "]"); + } + } + }); + } + + public void asyncIRCMessage(final String target, final String message) { + plugin.logDebug("Entering aysncIRCMessage"); + messageQueue.add(new IRCMessage(target, plugin.colorConverter. + gameColorsToIrc(message), false)); + } + + public void asyncCTCPMessage(final String target, final String message) { + plugin.logDebug("Entering asyncCTCPMessage"); + messageQueue.add(new IRCMessage(target, plugin.colorConverter + .gameColorsToIrc(message), true)); + } + + public void blockingIRCMessage(final String target, final String message) { + if (!this.isConnected()) { + return; + } + plugin.logDebug("[blockingIRCMessage] About to send IRC message to " + target); + bot.sendIRC().message(target, plugin.colorConverter + .gameColorsToIrc(message)); + plugin.logDebug("[blockingIRCMessage] Message sent to " + target); + } + + public void blockingCTCPMessage(final String target, final String message) { + if (!this.isConnected()) { + return; + } + plugin.logDebug("[blockingCTCPMessage] About to send IRC message to " + target); + bot.sendIRC().ctcpResponse(target, plugin.colorConverter + .gameColorsToIrc(message)); + plugin.logDebug("[blockingCTCPMessage] Message sent to " + target); + } + + public void asyncCTCPCommand(final String target, final String command) { + if (!this.isConnected()) { + return; + } + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + bot.sendIRC().ctcpCommand(target, command); + } + }); + } + + /** + * + * @param sender + */ + public void saveConfig(CommandSender sender) { + try { + config.save(file); + sender.sendMessage(plugin.LOG_HEADER_F + + " Saving bot \"" + botNick + "\" to " + file.getName()); + } catch (IOException ex) { + plugin.logError(ex.getMessage()); + sender.sendMessage(ex.getMessage()); + } + } + + /** + * + */ + public void saveConfig() { + try { + config.save(file); + } catch (IOException ex) { + plugin.logError(ex.getMessage()); + } + } + + /** + * + * @param sender + * @param newNick + */ + public void asyncChangeNick(final CommandSender sender, final String newNick) { + if (!this.isConnected()) { + return; + } + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + bot.sendIRC().changeNick(newNick); + + } + }); + sender.sendMessage("Setting nickname to " + newNick); + config.set("nick", newNick); + saveConfig(); + } + + public void asyncJoinChannel(final String channelName, final String password) { + if (!this.isConnected()) { + return; + } + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + bot.sendIRC().joinChannel(channelName, password); + } + }); + } + + public void asyncNotice(final String target, final String message) { + if (!this.isConnected()) { + return; + } + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + bot.sendIRC().notice(target, message); + } + }); + } + + public void asyncRawlineNow(final String message) { + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + bot.sendRaw().rawLineNow(message); + } + }); + } + + public void asyncIdentify(final String password) { + if (!this.isConnected()) { + return; + } + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + bot.sendIRC().identify(password); + } + }); + } + + /** + * + * @param sender + * @param newLogin + */ + public void changeLogin(CommandSender sender, String newLogin) { + sender.sendMessage(ChatColor.DARK_PURPLE + + "Login set to " + ChatColor.WHITE + + newLogin + ChatColor.DARK_PURPLE + + ". Reload the bot for the change to take effect."); + config.set("login", newLogin); + saveConfig(); + } + + private void sanitizeServerName() { + botServer = botServer.replace("^.*\\/\\/", ""); + botServer = botServer.replace(":\\d+$", ""); + config.set("server", botServer); + saveConfig(); + } + + private void loadConfig() { + try { + config.load(file); + autoConnect = config.getBoolean("autoconnect", true); + ssl = config.getBoolean("ssl", false); + trustAllCerts = config.getBoolean("trust-all-certs", false); + sendRawMessageOnConnect = config.getBoolean("raw-message-on-connect", false); + rawMessage = config.getString("raw-message", ""); + relayPrivateChat = config.getBoolean("relay-private-chat", false); + partInvalidChannels = config.getBoolean("part-invalid-channels", false); + partInvalidChannelsMsg = config.getString("part-invalid-channels-message", ""); + nick = config.getString("nick", ""); + botNick = nick; + altNicks = config.getStringList("alt-nicks"); + plugin.loadTemplates(config, botNick); + botLogin = config.getString("login", "PircBot"); + botRealName = config.getString("realname", ""); + ircMaxLineLength = config.getInt("max-line-length", 512); + if (botRealName.isEmpty()) { + botRealName = plugin.getServer() + .getPluginManager().getPlugin("PurpleIRC") + .getDescription().getWebsite(); + } + botServer = config.getString("server", ""); + bindAddress = config.getString("bind", ""); + channelAutoJoinDelay = config.getLong("channel-auto-join-delay", 20); + charSet = config.getString("charset", ""); + sanitizeServerName(); + showMOTD = config.getBoolean("show-motd", false); + botServerPort = config.getInt("port"); + botServerPass = config.getString("password", ""); + botIdentPassword = config.getString("ident-password", ""); + commandPrefix = config.getString("command-prefix", "."); + chatDelay = config.getLong("message-delay", 1000); + finger = config.getString("finger-reply", "PurpleIRC"); + plugin.logDebug("Message Delay => " + chatDelay); + quitMessage = ChatColor.translateAlternateColorCodes('&', config.getString("quit-message", "")); + plugin.logDebug("Nick => " + botNick); + plugin.logDebug("Login => " + botLogin); + plugin.logDebug("Server => " + botServer); + plugin.logDebug("Channel Auto Join Delay => " + channelAutoJoinDelay); + plugin.logDebug(("Bind => ") + bindAddress); + plugin.logDebug("SSL => " + ssl); + plugin.logDebug("Trust All Certs => " + trustAllCerts); + plugin.logDebug("Port => " + botServerPort); + plugin.logDebug("Command Prefix => " + commandPrefix); + //plugin.logDebug("Server Password => " + botServerPass); + plugin.logDebug("Quit Message => " + quitMessage); + botChannels.clear(); + opsList.clear(); + voicesList.clear(); + muteList.clear(); + enabledMessages.clear(); + worldList.clear(); + commandMap.clear(); + extraCommandMap.clear(); + + channelCmdNotifyEnabled = config.getBoolean("command-notify.enabled", false); + plugin.logDebug(" CommandNotifyEnabled => " + channelCmdNotifyEnabled); + + channelCmdNotifyMode = config.getString("command-notify.mode", "msg"); + plugin.logDebug(" channelCmdNotifyMode => " + channelCmdNotifyMode); + + // build command notify recipient list + for (String recipient : config.getStringList("command-notify.recipients")) { + if (!channelCmdNotifyRecipients.contains(recipient)) { + channelCmdNotifyRecipients.add(recipient); + } + plugin.logDebug(" Command Notify Recipient => " + recipient); + } + if (channelCmdNotifyRecipients.isEmpty()) { + plugin.logInfo(" No command recipients defined."); + } + + // build command notify ignore list + for (String command : config.getStringList("command-notify.ignore")) { + if (!channelCmdNotifyIgnore.contains(command)) { + channelCmdNotifyIgnore.add(command); + } + plugin.logDebug(" Command Notify Ignore => " + command); + } + if (channelCmdNotifyIgnore.isEmpty()) { + plugin.logInfo(" No command-notify ignores defined."); + } + + for (String enChannelName : config.getConfigurationSection("channels").getKeys(false)) { + String channelName = decodeChannel(enChannelName); + if (isValidChannel(channelName)) { + plugin.logError("Ignoring duplicate channel: " + channelName); + continue; + } + plugin.logDebug("Channel => " + channelName); + botChannels.add(channelName); + + channelAutoJoin.put(channelName, config.getBoolean("channels." + enChannelName + ".autojoin", true)); + plugin.logDebug(" Autojoin => " + channelAutoJoin.get(channelName)); + + channelPassword.put(channelName, config.getString("channels." + enChannelName + ".password", "")); + + channelTopic.put(channelName, config.getString("channels." + enChannelName + ".topic", "")); + plugin.logDebug(" Topic => " + channelTopic.get(channelName)); + + channelModes.put(channelName, config.getString("channels." + enChannelName + ".modes", "")); + plugin.logDebug(" Channel Modes => " + channelModes.get(channelName)); + + channelTopicProtected.put(channelName, config.getBoolean("channels." + enChannelName + ".topic-protect", false)); + plugin.logDebug(" Topic Protected => " + channelTopicProtected.get(channelName).toString()); + + channelTopicChanserv.put(channelName, config.getBoolean("channels." + enChannelName + ".topic-chanserv", false)); + plugin.logDebug(" Topic Chanserv Mode => " + channelTopicChanserv.get(channelName).toString()); + + heroChannel.put(channelName, config.getString("channels." + enChannelName + ".hero-channel", "")); + plugin.logDebug(" HeroChannel => " + heroChannel.get(channelName)); + + townyChannel.put(channelName, config.getString("channels." + enChannelName + ".towny-channel", "")); + plugin.logDebug(" TownyChannel => " + townyChannel.get(channelName)); + + logIrcToHeroChat.put(channelName, config.getBoolean("channels." + enChannelName + ".log-irc-to-hero-chat", false)); + plugin.logDebug(" LogIrcToHeroChat => " + logIrcToHeroChat.get(channelName)); + + ignoreIRCChat.put(channelName, config.getBoolean("channels." + enChannelName + ".ignore-irc-chat", false)); + plugin.logDebug(" IgnoreIRCChat => " + ignoreIRCChat.get(channelName)); + + hideJoinWhenVanished.put(channelName, config.getBoolean("channels." + enChannelName + ".hide-join-when-vanished", true)); + plugin.logDebug(" HideJoinWhenVanished => " + hideJoinWhenVanished.get(channelName)); + + hideListWhenVanished.put(channelName, config.getBoolean("channels." + enChannelName + ".hide-list-when-vanished", true)); + plugin.logDebug(" HideListWhenVanished => " + hideListWhenVanished.get(channelName)); + + hideQuitWhenVanished.put(channelName, config.getBoolean("channels." + enChannelName + ".hide-quit-when-vanished", true)); + plugin.logDebug(" HideQuitWhenVanished => " + hideQuitWhenVanished.get(channelName)); + + invalidCommandPrivate.put(channelName, config.getBoolean("channels." + enChannelName + ".invalid-command.private", false)); + plugin.logDebug(" InvalidCommandPrivate => " + invalidCommandPrivate.get(channelName)); + + invalidCommandCTCP.put(channelName, config.getBoolean("channels." + enChannelName + ".invalid-command.ctcp", false)); + plugin.logDebug(" InvalidCommandCTCP => " + invalidCommandCTCP.get(channelName)); + + shortify.put(channelName, config.getBoolean("channels." + enChannelName + ".shortify", true)); + plugin.logDebug(" Shortify => " + shortify.get(channelName)); + + joinMsg.put(channelName, config.getString("channels." + enChannelName + ".raw-message", "")); + plugin.logDebug(" JoinMessage => " + joinMsg.get(channelName)); + + msgOnJoin.put(channelName, config.getBoolean("channels." + enChannelName + ".raw-message-on-join", false)); + plugin.logDebug(" SendMessageOnJoin => " + msgOnJoin.get(channelName)); + + enableMessageFiltering.put(channelName, config.getBoolean("channels." + enChannelName + ".enable-filtering", false)); + plugin.logDebug(" EnableMessageFiltering => " + enableMessageFiltering.get(channelName)); + + // build channel op list + Collection cOps = new ArrayList<>(); + for (String channelOper : config.getStringList("channels." + enChannelName + ".ops")) { + if (!cOps.contains(channelOper)) { + cOps.add(channelOper); + } + plugin.logDebug(" Channel Op => " + channelOper); + } + opsList.put(channelName, cOps); + if (opsList.isEmpty()) { + plugin.logInfo("No channel ops defined."); + } + + // build channel voice list + Collection cVoices = new ArrayList<>(); + for (String channelVoice : config.getStringList("channels." + enChannelName + ".voices")) { + if (!cVoices.contains(channelVoice)) { + cVoices.add(channelVoice); + } + plugin.logDebug(" Channel Voice => " + channelVoice); + } + voicesList.put(channelName, cVoices); + if (voicesList.isEmpty()) { + plugin.logInfo("No channel voices defined."); + } + + // build mute list + Collection m = new ArrayList<>(); + for (String mutedUser : config.getStringList("channels." + enChannelName + ".muted")) { + if (!m.contains(mutedUser)) { + m.add(mutedUser); + } + plugin.logDebug(" Channel Mute => " + mutedUser); + } + muteList.put(channelName, m); + if (muteList.isEmpty()) { + plugin.logInfo("IRC mute list is empty."); + } + + // build valid chat list + Collection c = new ArrayList<>(); + for (String validChat : config.getStringList("channels." + enChannelName + ".enabled-messages")) { + if (!c.contains(validChat)) { + c.add(validChat); + } + plugin.logDebug(" Enabled Message => " + validChat); + } + enabledMessages.put(channelName, c); + if (enabledMessages.isEmpty()) { + plugin.logInfo("There are no enabled messages!"); + } + + // build valid world list + Collection w = new ArrayList<>(); + for (String validWorld : config.getStringList("channels." + enChannelName + ".worlds")) { + if (!w.contains(validWorld)) { + w.add(validWorld); + } + plugin.logDebug(" Enabled World => " + validWorld); + } + worldList.put(channelName, w); + if (worldList.isEmpty()) { + plugin.logInfo("World list is empty!"); + } + + // build valid world list + Collection t = new ArrayList<>(); + for (String name : config.getStringList("channels." + enChannelName + ".custom-tab-ignore-list")) { + if (!t.contains(name)) { + t.add(name); + } + plugin.logDebug(" Tab Ignore => " + name); + } + tabIgnoreNicks.put(channelName, t); + if (tabIgnoreNicks.isEmpty()) { + plugin.logInfo("World list is empty!"); + } + + // build valid world list + Collection f = new ArrayList<>(); + for (String word : config.getStringList("channels." + enChannelName + ".filter-list")) { + if (!f.contains(word)) { + f.add(word); + } + plugin.logDebug(" Filtered From IRC => " + word); + } + filters.put(channelName, f); + if (filters.isEmpty()) { + plugin.logInfo("World list is empty!"); + } + + // build join notice + joinNoticeCoolDown = config.getInt("channels." + enChannelName + ".join-notice.cooldown", 60); + joinNoticeEnabled = config.getBoolean("channels." + enChannelName + ".join-notice.enabled", false); + joinNoticePrivate = config.getBoolean("channels." + enChannelName + ".join-notice.private", true); + joinNoticeCtcp = config.getBoolean("channels." + enChannelName + ".join-notice.ctcp", true); + joinNoticeMessage = config.getString("channels." + enChannelName + ".join-notice.message", ""); + plugin.logDebug("join-notice.cooldown: " + joinNoticeCoolDown); + plugin.logDebug("join-notice.enabled: " + joinNoticeEnabled); + plugin.logDebug("join-notice.private: " + joinNoticePrivate); + plugin.logDebug("join-notice.ctcp: " + joinNoticeCtcp); + plugin.logDebug("join-notice.message: " + joinNoticeMessage); + + // build command map + CaseInsensitiveMap> map = new CaseInsensitiveMap<>(); + CaseInsensitiveMap> extraMap = new CaseInsensitiveMap<>(); + try { + for (String command : config.getConfigurationSection("channels." + enChannelName + ".commands").getKeys(false)) { + plugin.logDebug(" Command => " + command); + CaseInsensitiveMap optionPair = new CaseInsensitiveMap<>(); + List extraCommands = new ArrayList<>(); + String commandKey = "channels." + enChannelName + ".commands." + command + "."; + optionPair.put("modes", config.getString(commandKey + "modes", "*")); + optionPair.put("private", config.getString(commandKey + "private", "false")); + optionPair.put("ctcp", config.getString(commandKey + "ctcp", "false")); + optionPair.put("game_command", config.getString(commandKey + "game_command", "")); + extraCommands.addAll(config.getStringList(commandKey + "extra_commands")); + plugin.logDebug("extra_commands: " + extraCommands.toString()); + optionPair.put("private_listen", config.getString(commandKey + "private_listen", "true")); + optionPair.put("channel_listen", config.getString(commandKey + "channel_listen", "true")); + optionPair.put("perm", config.getString(commandKey + "perm", "")); + for (String s : optionPair.keySet()) { + config.set(commandKey + s, optionPair.get(s)); + } + map.put(command, optionPair); + extraMap.put(command, extraCommands); + } + } catch (Exception ex) { + plugin.logError("No commands found for channel " + enChannelName); + } + commandMap.put(channelName, map); + extraCommandMap.put(channelName, extraMap); + if (map.isEmpty()) { + plugin.logInfo("No commands specified!"); + } + connectMessage = "Connecting to \"" + botServer + ":" + + botServerPort + "\" as \"" + botNick + + "\" [SSL: " + ssl + "]" + " [TrustAllCerts: " + + trustAllCerts + "]"; + } + } catch (IOException | InvalidConfigurationException ex) { + plugin.logError(ex.getMessage()); + } + } + + /** + * + * @param sender + * @param delay + */ + public void setIRCDelay(CommandSender sender, long delay) { + config.set("message-delay", delay); + saveConfig(); + sender.sendMessage(ChatColor.DARK_PURPLE + + "IRC message delay changed to " + + ChatColor.WHITE + delay + ChatColor.DARK_PURPLE + " ms. " + + "Reload for the change to take effect."); + } + + private boolean isPlayerInValidWorld(Player player, String channelName) { + if (worldList.containsKey(channelName)) { + if (worldList.get(channelName).contains("*")) { + return true; + } + if (worldList.get(channelName).contains(player.getWorld().getName())) { + return true; + } + } + return false; + } + + /** + * Called from normal game chat listener + * + * @param player + * @param message + */ + public void gameChat(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + if (plugin.fcHook != null) { + String playerChatMode; + String playerFactionName; + try { + playerChatMode = plugin.fcHook.getChatMode(player); + } catch (IllegalAccessError ex) { + plugin.logDebug("FC Error: " + ex.getMessage()); + playerChatMode = "public"; + } + try { + playerFactionName = plugin.fcHook.getFactionName(player); + } catch (IllegalAccessError ex) { + plugin.logDebug("FC Error: " + ex.getMessage()); + playerFactionName = "unknown"; + } + + String chatName = "faction-" + playerChatMode.toLowerCase() + "-chat"; + plugin.logDebug("Faction [Player: " + player.getName() + + "] [Tag: " + playerFactionName + "] [Mode: " + + playerChatMode + "]"); + if (enabledMessages.get(channelName) + .contains(chatName)) { + asyncIRCMessage(channelName, plugin.tokenizer + .chatFactionTokenizer(player, botNick, message, + playerFactionName, playerChatMode)); + } else { + plugin.logDebug("Player " + player.getName() + " is in chat mode \"" + + playerChatMode + "\" but \"" + chatName + "\" is disabled."); + } + } else { + plugin.logDebug("No Factions"); + } + if (isMessageEnabled(channelName, TemplateName.GAME_CHAT)) { + plugin.logDebug("[" + TemplateName.GAME_CHAT + "] => " + + channelName + " => " + message); + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate(botNick, TemplateName.GAME_CHAT), message)); + } else { + plugin.logDebug("Ignoring message due to " + + TemplateName.GAME_CHAT + " not being listed."); + } + } + } + + // Called from HeroChat listener + /** + * + * @param chatter + * @param chatColor + * @param message + */ + public void heroChat(Chatter chatter, ChatColor chatColor, String message) { + if (!this.isConnected()) { + return; + } + Player player = chatter.getPlayer(); + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + String hChannel = chatter.getActiveChannel().getName(); + String hNick = chatter.getActiveChannel().getNick(); + String hColor = chatColor.toString(); + plugin.logDebug("HC Channel: " + hChannel); + if (isMessageEnabled(channelName, "hero-" + hChannel + "-chat") + || isMessageEnabled(channelName, TemplateName.HERO_CHAT)) { + asyncIRCMessage(channelName, plugin.tokenizer + .chatHeroTokenizer(player, message, hColor, hChannel, + hNick, plugin.getHeroChatChannelTemplate(botNick, hChannel))); + } else { + plugin.logDebug("Player " + player.getName() + " is in \"" + + hChannel + "\" but hero-" + hChannel + "-chat is disabled."); + } + } + } + + public void mcMMOAdminChat(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + if (isMessageEnabled(channelName, TemplateName.MCMMO_ADMIN_CHAT)) { + plugin.logDebug("Sending message because " + TemplateName.MCMMO_ADMIN_CHAT + " is enabled."); + asyncIRCMessage(channelName, plugin.tokenizer + .mcMMOChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.MCMMO_ADMIN_CHAT), message)); + } else { + plugin.logDebug("Player " + player.getName() + + " is in mcMMO AdminChat but " + TemplateName.MCMMO_ADMIN_CHAT + " is disabled."); + } + } + } + + public void mcMMOPartyChat(Player player, String partyName, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + if (isMessageEnabled(channelName, TemplateName.MCMMO_PARTY_CHAT)) { + plugin.logDebug("Sending message because " + TemplateName.MCMMO_PARTY_CHAT + " is enabled."); + asyncIRCMessage(channelName, plugin.tokenizer + .mcMMOPartyChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.MCMMO_PARTY_CHAT), message, partyName)); + } else { + plugin.logDebug("Player " + player.getName() + + " is in mcMMO PartyChat but " + TemplateName.MCMMO_PARTY_CHAT + " is disabled."); + } + } + } + + public void mcMMOChat(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + if (isMessageEnabled(channelName, TemplateName.MCMMO_CHAT)) { + plugin.logDebug("Sending message because " + TemplateName.MCMMO_CHAT + " is enabled."); + asyncIRCMessage(channelName, plugin.tokenizer + .mcMMOChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.MCMMO_CHAT), message)); + } else { + plugin.logDebug("Player " + player.getName() + + " is in mcMMO Chat but " + TemplateName.MCMMO_CHAT + " is disabled."); + } + } + } + + public void townyChat(Player player, com.palmergames.bukkit.TownyChat.channels.Channel townyChannel, String message) { + if (!this.isConnected()) { + return; + } + if (plugin.tcHook != null) { + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + plugin.logDebug("townyChat: Checking for towny-" + + townyChannel.getName() + "-chat" + + " or " + "towny-" + townyChannel.getChannelTag() + "-chat" + + " or towny-chat"); + if (isMessageEnabled(channelName, "towny-" + townyChannel.getName() + "-chat") + || isMessageEnabled(channelName, "towny-" + townyChannel.getChannelTag() + "-chat") + || isMessageEnabled(channelName, "towny-chat") + || isMessageEnabled(channelName, "towny-channel-chat")) { + asyncIRCMessage(channelName, plugin.tokenizer + .chatTownyChannelTokenizer(player, townyChannel, message, + plugin.getMsgTemplate(botNick, "towny-channel-chat"))); + } + } + } + } + + public void heroAction(Chatter chatter, ChatColor chatColor, String message) { + if (!this.isConnected()) { + return; + } + Player player = chatter.getPlayer(); + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + String hChannel = chatter.getActiveChannel().getName(); + String hNick = chatter.getActiveChannel().getNick(); + String hColor = chatColor.toString(); + plugin.logDebug("HC Channel: " + hChannel); + if (isMessageEnabled(channelName, "hero-" + hChannel + "-action") + || isMessageEnabled(channelName, "hero-action")) { + asyncIRCMessage(channelName, plugin.tokenizer + .chatHeroTokenizer(player, message, hColor, hChannel, + hNick, plugin.getHeroActionChannelTemplate(botNick, hChannel))); + } else { + plugin.logDebug("Player " + player.getName() + " is in \"" + + hChannel + "\" but hero-" + hChannel + "-action is disabled."); + } + } + } + + // Called from TitanChat listener + /** + * + * @param participant + * @param tChannel + * @param tColor + * @param message + */ + public void titanChat(Participant participant, String tChannel, String tColor, String message) { + if (!this.isConnected()) { + return; + } + Player player = plugin.getServer().getPlayer(participant.getName()); + for (String channelName : botChannels) { + if (!isPlayerInValidWorld(player, channelName)) { + continue; + } + plugin.logDebug("TC Channel: " + tChannel); + if (isMessageEnabled(channelName, "titan-" + tChannel + "-chat") + || isMessageEnabled(channelName, "titan-chat")) { + asyncIRCMessage(channelName, plugin.tokenizer + .titanChatTokenizer(player, tChannel, tColor, message, + plugin.getMsgTemplate(botNick, "titan-chat"))); + } else { + plugin.logDebug("Player " + player.getName() + " is in \"" + + tChannel + "\" but titan-" + tChannel + "-chat is disabled."); + } + } + } + + // Called from /irc send + /** + * + * @param player + * @param channelName + * @param message + */ + public void gameChat(Player player, String channelName, String message) { + if (!this.isConnected()) { + return; + } + if (isValidChannel(channelName)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.GAME_SEND), message)); + } + } + + // Called from CleverEvent + /** + * + * @param cleverBotName + * @param message + */ + public void cleverChat(String cleverBotName, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, "clever-chat")) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(cleverBotName, plugin.getMsgTemplate(botNick, "clever-send"), message)); + } + } + } + + // Called from AdminChatEvent + /** + * + * @param name + * @param message + * @param world + */ + public void adminChat(String name, String message, String world) { + if (!this.isConnected() || world.isEmpty()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_A_CHAT)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(name, plugin.getMsgTemplate(botNick, TemplateName.GAME_A_CHAT), message) + .replace("%WORLD%", world) + ); + } + } + } + + // Called from ReportRTS event + /** + * + * @param pName + * @param ticket + * @param botNick + * @param messageType + */ + public void reportRTSNotify(String pName, Ticket ticket, + String botNick, String messageType) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, messageType)) { + asyncIRCMessage(channelName, plugin.tokenizer + .reportRTSTokenizer(pName, plugin.getMsgTemplate(botNick, messageType), ticket)); + } + } + } + + public void reportRTSNotify(CommandSender sender, String message, String botNick, String messageType) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, messageType)) { + asyncIRCMessage(channelName, plugin.tokenizer + .reportRTSTokenizer(sender, message, plugin.getMsgTemplate(botNick, messageType))); + } + } + } + + /** + * + * @param channelName + * @param message + */ + public void consoleChat(String channelName, String message) { + if (!this.isConnected()) { + return; + } + if (isValidChannel(channelName)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer("CONSOLE", message, plugin.getMsgTemplate( + botNick, TemplateName.GAME_SEND))); + } + } + + /** + * + * @param message + */ + public void consoleChat(String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.CONSOLE_CHAT)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(plugin.getMsgTemplate(botNick, + TemplateName.CONSOLE_CHAT), ChatColor.translateAlternateColorCodes('&', message))); + } + } + } + + /** + * + * @param player + * @param message + */ + public void gameBroadcast(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.BROADCAST_MESSAGE)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin + .getMsgTemplate(botNick, TemplateName.BROADCAST_MESSAGE), + ChatColor.translateAlternateColorCodes('&', message))); + } + } + } + + /** + * + * @param player + * @param message + */ + public void essHelpOp(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.ESS_HELPOP)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin + .getMsgTemplate(botNick, TemplateName.ESS_HELPOP), + ChatColor.translateAlternateColorCodes('&', message))); + } + } + } + + /** + * + * @param player + * @param message + */ + public void gameOreBroadcast(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.ORE_BROADCAST)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate(botNick, TemplateName.ORE_BROADCAST), ChatColor.translateAlternateColorCodes('&', message))); + } + } + } + + /** + * + * @param name + * @param message + * @param source + */ + public void dynmapWebChat(String source, String name, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.DYNMAP_WEB_CHAT)) { + asyncIRCMessage(channelName, plugin.tokenizer + .dynmapWebChatToIRCTokenizer(source, name, plugin.getMsgTemplate( + botNick, TemplateName.DYNMAP_WEB_CHAT), + ChatColor.translateAlternateColorCodes('&', message))); + } + } + } + + /** + * + * @param message + */ + public void consoleBroadcast(String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.BROADCAST_CONSOLE_MESSAGE)) { + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(plugin.getMsgTemplate(botNick, + TemplateName.BROADCAST_CONSOLE_MESSAGE), ChatColor.translateAlternateColorCodes('&', message))); + } + } + } + + /** + * + * @param message + */ + public void redditStreamBroadcast(String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.REDDIT_MESSAGES)) { + plugin.logDebug("Checking if " + TemplateName.REDDIT_MESSAGES + " is enabled... YES"); + asyncIRCMessage(channelName, plugin.tokenizer.gameChatToIRCTokenizer(plugin.getMsgTemplate(botNick, TemplateName.REDDIT_MESSAGES), message)); + } else { + plugin.logDebug("Checking if " + TemplateName.REDDIT_MESSAGES + " is enabled... NOPE"); + } + + } + } + + /** + * + * @param player + * @param message + */ + public void gameJoin(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_JOIN)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + if (hideJoinWhenVanished.get(channelName)) { + plugin.logDebug("Checking if player " + player.getName() + " is vanished."); + if (plugin.vanishHook.isVanished(player)) { + plugin.logDebug("Not sending join message to IRC for player " + + player.getName() + " due to being vanished."); + continue; + } + } + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.GAME_JOIN), message)); + } else { + plugin.logDebug("Not sending join message due to " + TemplateName.GAME_JOIN + " being disabled"); + } + } + } + + /** + * + * @param player + * @param message + */ + public void gameQuit(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_QUIT)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + if (hideQuitWhenVanished.get(channelName)) { + plugin.logDebug("Checking if player " + player.getName() + + " is vanished."); + if (plugin.vanishHook.isVanished(player)) { + plugin.logDebug("Not sending quit message to IRC for player " + + player.getName() + " due to being vanished."); + continue; + } + } + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.GAME_QUIT), message)); + } + } + } + + /** + * + * @param player + * @param achievement + */ + public void gameAchievement(Player player, Achievement achievement) { + if (!this.isConnected()) { + return; + } + String message = achievement.toString(); + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_ACHIEVEMENT)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.GAME_ACHIEVEMENT), message)); + } + } + } + + /** + * + * @param player + * @param gameMode + */ + public void gameModeChange(Player player, GameMode gameMode) { + if (!this.isConnected()) { + return; + } + String message = gameMode.toString(); + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_MODE)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.GAME_MODE), message)); + } + } + } + + /** + * + * @param player + * @param message + * @param reason + */ + public void gameKick(Player player, String message, String reason) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_KICK)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + asyncIRCMessage(channelName, plugin.tokenizer + .gameKickTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.GAME_KICK), message, reason)); + } + } + } + + /** + * + * @param player + * @param message + */ + public void gameAction(Player player, String message) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_ACTION)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, TemplateName.GAME_ACTION), message)); + } + } + } + + /** + * + * @param player + * @param message + * @param templateName + */ + public void gameDeath(Player player, String message, String templateName) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, templateName)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + asyncIRCMessage(channelName, plugin.tokenizer + .gameChatToIRCTokenizer(player, plugin.getMsgTemplate( + botNick, templateName), message)); + } + } + } + + /** + * + * @param channelName + * @param topic + * @param sender + */ + public void changeTopic(String channelName, String topic, CommandSender sender) { + Channel channel = this.getChannel(channelName); + String tTopic = tokenizedTopic(topic); + if (channel != null) { + setTheTopic(channel, tTopic); + config.set("channels." + encodeChannel(getConfigChannelName(channelName)) + ".topic", topic); + channelTopic.put(channelName, topic); + saveConfig(); + sender.sendMessage("IRC topic for " + channelName + " changed to \"" + topic + "\""); + } else { + sender.sendMessage("Invalid channel: " + channelName); + } + } + + public String getConfigChannelName(String channelName) { + for (String s : botChannels) { + if (channelName.equalsIgnoreCase(s)) { + return s; + } + } + return channelName; + } + + public Channel getChannel(String channelName) { + Channel channel = null; + for (Channel c : getChannels()) { + if (c.getName().equalsIgnoreCase(channelName)) { + return c; + } + } + return channel; + } + + /** + * + * @param sender + * @param botServer + */ + public void setServer(CommandSender sender, String botServer) { + setServer(sender, botServer, autoConnect); + } + + /** + * + * @param sender + * @param server + * @param auto + */ + public void setServer(CommandSender sender, String server, Boolean auto) { + + if (server.contains(":")) { + botServerPort = Integer.parseInt(server.split(":")[1]); + botServer = server.split(":")[0]; + } else { + botServer = server; + } + sanitizeServerName(); + autoConnect = auto; + config.set("server", botServer); + config.set("port", botServerPort); + config.set("autoconnect", autoConnect); + + sender.sendMessage("IRC server changed to \"" + botServer + ":" + + botServerPort + "\". (AutoConnect: " + + autoConnect + ")"); + } + + /** + * + * @param channelName + * @param userMask + * @param sender + */ + public void addOp(String channelName, String userMask, CommandSender sender) { + if (opsList.get(channelName).contains(userMask)) { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " is already in the ops list."); + } else { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " has been added to the ops list."); + opsList.get(channelName).add(userMask); + } + config.set("channels." + encodeChannel(getConfigChannelName(channelName)) + ".ops", opsList.get(channelName)); + saveConfig(); + } + + /** + * + * @param channelName + * @param userMask + * @param sender + */ + public void addVoice(String channelName, String userMask, CommandSender sender) { + if (voicesList.get(channelName).contains(userMask)) { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " is already in the voices list."); + } else { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " has been added to the voices list."); + voicesList.get(channelName).add(userMask); + } + config.set("channels." + encodeChannel(getConfigChannelName(channelName)) + ".voices", voicesList.get(channelName)); + saveConfig(); + } + + /** + * + * @param channelName + * @param userMask + * @param sender + */ + public void removeOp(String channelName, String userMask, CommandSender sender) { + if (opsList.get(channelName).contains(userMask)) { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " has been removed to the ops list."); + opsList.get(channelName).remove(userMask); + } else { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " is not in the ops list."); + } + config.set("channels." + encodeChannel(getConfigChannelName(channelName)) + ".ops", opsList.get(channelName)); + saveConfig(); + } + + /** + * + * @param channelName + * @param userMask + * @param sender + */ + public void removeVoice(String channelName, String userMask, CommandSender sender) { + if (voicesList.get(channelName).contains(userMask)) { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " has been removed to the voices list."); + voicesList.get(channelName).remove(userMask); + } else { + sender.sendMessage("User mask " + ChatColor.WHITE + userMask + + ChatColor.RESET + " is not in the voices list."); + } + config.set("channels." + encodeChannel(getConfigChannelName(channelName)) + ".voices", voicesList.get(channelName)); + saveConfig(); + } + + /** + * + * @param channelName + * @param nick + */ + public void op(String channelName, String nick) { + Channel channel; + channel = getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + if (user.getNick().equals(nick)) { + channel.send().op(user); + return; + } + } + } + } + + /** + * + * @param channelName + * @param nick + */ + public void voice(String channelName, String nick) { + Channel channel; + channel = getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + if (user.getNick().equals(nick)) { + channel.send().voice(user); + return; + } + } + } + } + + /** + * + * @param channelName + * @param nick + */ + public void deOp(String channelName, String nick) { + Channel channel; + channel = getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + if (user.getNick().equals(nick)) { + channel.send().deOp(user); + return; + } + } + } + } + + /** + * + * @param channelName + * @param nick + */ + public void deVoice(String channelName, String nick) { + Channel channel; + channel = getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + if (user.getNick().equals(nick)) { + channel.send().deVoice(user); + return; + } + } + } + } + + /** + * + * @param channelName + * @param nick + */ + public void kick(String channelName, String nick) { + Channel channel; + channel = getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + if (user.getNick().equals(nick)) { + channel.send().kick(user); + return; + } + } + } + } + + private String encodeChannel(String s) { + return s.replace(".", "%2E"); + } + + private String decodeChannel(String s) { + return s.replace("%2E", "."); + } + + /** + * + * @param channel + * @param topic + * @param setBy + */ + public void fixTopic(Channel channel, String topic, String setBy) { + String channelName = channel.getName(); + String tTopic = tokenizedTopic(topic); + if (setBy.equals(botNick)) { + //config.set("channels." + encodeChannel(channelName) + ".topic", topic); + //saveConfig(); + return; + } + + if (channelTopic.containsKey(channelName)) { + if (channelTopicProtected.containsKey(channelName)) { + if (channelTopicProtected.get(channelName)) { + plugin.logDebug("[" + channel.getName() + "] Topic protected."); + String myTopic = tokenizedTopic(channelTopic.get(channelName)); + plugin.logDebug("rTopic: " + channelTopic.get(channelName)); + plugin.logDebug("tTopic: " + tTopic); + plugin.logDebug("myTopic: " + myTopic); + if (!tTopic.equals(myTopic)) { + plugin.logDebug("Topic is not correct. Fixing it."); + setTheTopic(channel, myTopic); + } else { + plugin.logDebug("Topic is correct."); + } + } + } + } + } + + private void setTheTopic(Channel channel, String topic) { + String myChannel = channel.getName(); + if (channelTopicChanserv.containsKey(myChannel)) { + if (channelTopicChanserv.get(myChannel)) { + String msg = String.format("TOPIC %s %s", myChannel, topic); + plugin.logDebug("Sending chanserv rmessage: " + msg); + asyncIRCMessage("chanserv", msg); + return; + } + } + channel.send().setTopic(topic); + } + + private String tokenizedTopic(String topic) { + return plugin.colorConverter + .gameColorsToIrc(topic.replace("%MOTD%", plugin.getServer().getMotd())); + } + + /** + * + * @param sender + */ + public void asyncQuit(CommandSender sender) { + sender.sendMessage("Disconnecting " + bot.getNick() + " from IRC server " + botServer); + asyncQuit(false); + } + + /** + * + * @param reload + */ + public void asyncQuit(final Boolean reload) { + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + @Override + public void run() { + quit(); + if (reload) { + buildBot(); + } + } + }); + + } + + public void quit() { + if (this.isConnected()) { + plugin.logDebug("Q: " + quitMessage); + if (quitMessage.isEmpty()) { + bot.sendIRC().quitServer(); + } else { + bot.sendIRC().quitServer(plugin.colorConverter.gameColorsToIrc(quitMessage)); + } + } + } + + /** + * + * @param sender + */ + public void sendTopic(CommandSender sender) { + for (String channelName : botChannels) { + if (commandMap.containsKey(channelName)) { + sender.sendMessage(ChatColor.WHITE + "[" + ChatColor.DARK_PURPLE + + botNick + ChatColor.WHITE + "]" + ChatColor.RESET + + " IRC topic for " + ChatColor.WHITE + channelName + + ChatColor.RESET + ": \"" + + ChatColor.WHITE + plugin.colorConverter + .ircColorsToGame(activeTopic.get(channelName)) + + ChatColor.RESET + "\""); + } + } + } + + /** + * + * @param sender + * @param nick + */ + public void sendUserWhois(CommandSender sender, String nick) { + User user = null; + for (Channel channel : getChannels()) { + for (User u : channel.getUsers()) { + if (u.getNick().equals(nick)) { + user = u; + } + } + } + + if (user == null) { + sender.sendMessage(ChatColor.RED + "Invalid user: " + ChatColor.WHITE + nick); + } else { + bot.sendRaw().rawLineNow(String.format("WHOIS %s %s", nick, nick)); + whoisSenders.add(sender); + } + } + + /** + * + * @param sender + * @param channelName + */ + public void sendUserList(CommandSender sender, String channelName) { + String invalidChannel = ChatColor.RED + "Invalid channel: " + + ChatColor.WHITE + channelName; + if (!isValidChannel(channelName)) { + sender.sendMessage(invalidChannel); + return; + } + Channel channel = getChannel(channelName); + if (channel != null) { + sendUserList(sender, channel); + } else { + sender.sendMessage(invalidChannel); + } + } + + /** + * + * @param sender + * @param channel + */ + public void sendUserList(CommandSender sender, Channel channel) { + String channelName = channel.getName(); + if (!isValidChannel(channelName)) { + sender.sendMessage(ChatColor.RED + "Invalid channel: " + + ChatColor.WHITE + channelName); + return; + } + sender.sendMessage(ChatColor.DARK_PURPLE + "-----[ " + ChatColor.WHITE + channelName + + ChatColor.DARK_PURPLE + " - " + ChatColor.WHITE + bot.getNick() + ChatColor.DARK_PURPLE + " ]-----"); + if (!this.isConnected()) { + sender.sendMessage(ChatColor.RED + " Not connected!"); + return; + } + List channelUsers = new ArrayList<>(); + for (User user : channel.getUsers()) { + String nick = user.getNick(); + nick = getNickPrefix(user, channel) + nick; + if (user.isAway()) { + nick = nick + ChatColor.GRAY + " | Away"; + } + if (nick.equals(bot.getNick())) { + nick = ChatColor.DARK_PURPLE + nick; + } + channelUsers.add(nick); + } + Collections.sort(channelUsers, Collator.getInstance()); + for (String userName : channelUsers) { + sender.sendMessage(" " + ChatColor.WHITE + userName); + } + } + + public String getNickPrefix(User user, Channel channel) { + try { + if (user.getChannels() != null) { + if (user.isIrcop()) { + return plugin.ircNickPrefixIrcOp; + } else if (user.getChannelsSuperOpIn().contains(channel)) { + return plugin.ircNickPrefixSuperOp; + } else if (user.getChannelsOpIn().contains(channel)) { + return plugin.ircNickPrefixOp; + } else if (user.getChannelsHalfOpIn().contains(channel)) { + return plugin.ircNickPrefixHalfOp; + } else if (user.getChannelsVoiceIn().contains(channel)) { + return plugin.ircNickPrefixVoice; + } + } + } catch (Exception ex) { + plugin.logDebug(ex.getMessage()); + } + return ""; + } + + /** + * + * @param sender + */ + public void sendUserList(CommandSender sender) { + for (Channel channel : getChannels()) { + if (isValidChannel(channel.getName())) { + sendUserList(sender, channel); + } + } + } + + /** + * + */ + public void updateNickList() { + if (!this.isConnected()) { + return; + } + for (Channel channel : this.getChannels()) { + this.updateNickList(channel); + } + } + + /** + * + * @param channel + */ + public void updateNickList(Channel channel) { + if (!this.isConnected()) { + return; + } + // Build current list of names in channel + ArrayList users = new ArrayList<>(); + for (User user : channel.getUsers()) { + //plugin.logDebug("N: " + user.getNick()); + users.add(user.getNick()); + } + // Iterate over previous list and remove from tab list + String channelName = channel.getName(); + if (channelNicks.containsKey(channelName)) { + for (String name : channelNicks.get(channelName)) { + //plugin.logDebug("O: " + name); + if (!users.contains(name)) { + plugin.logDebug("Removing " + name + " from list."); + if (plugin.netPackets != null) { + plugin.netPackets.remFromTabList(name); + } + } + } + channelNicks.remove(channelName); + } + channelNicks.put(channelName, users); + } + + /** + * + * @param channel + */ + public void opIrcUsers(Channel channel) { + for (User user : channel.getUsers()) { + opIrcUser(channel, user); + } + } + + /** + * + * @param channelName + */ + public void opIrcUsers(String channelName) { + Channel channel = getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + opIrcUser(channel, user); + } + } + } + + /** + * + * @param channel + */ + public void voiceIrcUsers(Channel channel) { + for (User user : channel.getUsers()) { + voiceIrcUser(channel, user); + } + } + + /** + * + * @param channelName + */ + public void voiceIrcUsers(String channelName) { + Channel channel = getChannel(channelName); + if (channel != null) { + for (User user : channel.getUsers()) { + voiceIrcUser(channel, user); + } + } + } + + /** + * + * @param user + * @param userMask + * @return + */ + public boolean checkUserMask(User user, String userMask) { + String mask[] = userMask.split("[\\!\\@]", 3); + if (mask.length == 3) { + String gUser = plugin.regexGlobber.createRegexFromGlob(mask[0]); + String gLogin = plugin.regexGlobber.createRegexFromGlob(mask[1]); + String gHost = plugin.regexGlobber.createRegexFromGlob(mask[2]); + return (user.getNick().matches(gUser) + && user.getLogin().matches(gLogin) + && user.getHostmask().matches(gHost)); + } + return false; + } + + /** + * + * @param channel + * @param user + */ + public void opIrcUser(Channel channel, User user) { + String channelName = channel.getName(); + if (user.getNick().equals(botNick)) { + return; + } + if (channel.getOps().contains(user)) { + plugin.logInfo("User " + user.getNick() + " is already an operator on " + channelName); + return; + } + for (String userMask : opsList.get(channelName)) { + if (checkUserMask(user, userMask)) { + plugin.logInfo("Giving operator status to " + user.getNick() + " on " + channelName); + channel.send().op(user); + break; + } + } + } + + /** + * + * @param channel + * @param user + */ + public void voiceIrcUser(Channel channel, User user) { + String channelName = channel.getName(); + if (user.getNick().equals(botNick)) { + return; + } + if (channel.getVoices().contains(user)) { + plugin.logInfo("User " + user.getNick() + " is already a voice on " + channelName); + return; + } + for (String userMask : voicesList.get(channelName)) { + if (checkUserMask(user, userMask)) { + plugin.logInfo("Giving voice status to " + user.getNick() + " on " + channelName); + channel.send().voice(user); + break; + } + } + } + + public String filterMessage(String message, String myChannel) { + if (filters.containsKey(myChannel)) { + if (!filters.get(myChannel).isEmpty()) { + for (String filter : filters.get(myChannel)) { + if (filter.startsWith("/") && filter.endsWith("/")) { + filter = filter.substring(1, filter.length() - 1); + plugin.logDebug("Regex filtering " + filter + " from " + message); + message = message.replaceAll(filter, ""); + } else { + plugin.logDebug("Filtering " + filter + " from " + message); + message = message.replace(filter, ""); + } + } + } + } + return message; + } + + // Broadcast chat messages from IRC + /** + * + * @param user + * @param channel + * @param target + * @param message + * @param override + * @param ctcpResponse + */ + public void broadcastChat(User user, org.pircbotx.Channel channel, String target, String message, boolean override, boolean ctcpResponse) { + boolean messageSent = false; + String myChannel = channel.getName(); + if (plugin.dynmapHook != null) { + plugin.logDebug("Checking if " + TemplateName.IRC_DYNMAP_WEB_CHAT + " is enabled ..."); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_DYNMAP_WEB_CHAT)) { + plugin.logDebug("Yes, " + TemplateName.IRC_DYNMAP_WEB_CHAT + " is enabled..."); + plugin.logDebug("broadcastChat [DW]: " + message); + String template = plugin.getMsgTemplate(botNick, TemplateName.IRC_DYNMAP_WEB_CHAT); + String rawDWMessage = filterMessage( + plugin.tokenizer.ircChatToGameTokenizer(this, user, channel, template, message), myChannel); + plugin.dynmapHook.sendMessage(user.getNick(), rawDWMessage); + messageSent = true; + } else { + plugin.logDebug("Nope, " + TemplateName.IRC_DYNMAP_WEB_CHAT + " is NOT enabled..."); + } + } + if (plugin.tcHook != null) { + plugin.logDebug("Checking if " + TemplateName.IRC_TOWNY_CHAT + " is enabled ..."); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_TOWNY_CHAT)) { + plugin.logDebug("Yes, " + TemplateName.IRC_TOWNY_CHAT + " is enabled..."); + if (townyChannel.containsKey(myChannel)) { + String tChannel = townyChannel.get(myChannel); + if (!tChannel.isEmpty()) { + String tmpl = plugin.getIRCTownyChatChannelTemplate(botNick, tChannel); + plugin.logDebug("broadcastChat [TC]: " + tChannel + ": " + tmpl); + String rawTCMessage = filterMessage( + plugin.tokenizer.ircChatToTownyChatTokenizer(this, user, channel, tmpl, message, tChannel), myChannel); + plugin.tcHook.sendMessage(tChannel, rawTCMessage); + messageSent = true; + } + } + } else { + plugin.logDebug("Nope, " + TemplateName.IRC_TOWNY_CHAT + " is NOT enabled..."); + } + } + + plugin.logDebug("Checking if " + TemplateName.IRC_CHAT + " is enabled before broadcasting chat from IRC"); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_CHAT) || override) { + plugin.logDebug("Yup we can broadcast due to " + TemplateName.IRC_CHAT + " enabled"); + String newMessage = filterMessage( + plugin.tokenizer.ircChatToGameTokenizer(this, user, channel, plugin.getMsgTemplate( + botNick, TemplateName.IRC_CHAT), message), myChannel); + if (!newMessage.isEmpty()) { + plugin.getServer().broadcast(newMessage, "irc.message.chat"); + messageSent = true; + } + } else { + plugin.logDebug("NOPE we can't broadcast due to " + TemplateName.IRC_CHAT + " disabled"); + } + + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_CONSOLE_CHAT)) { + String tmpl = plugin.getMsgTemplate(botNick, TemplateName.IRC_CONSOLE_CHAT); + plugin.logDebug("broadcastChat [Console]: " + tmpl); + plugin.getServer().getConsoleSender().sendMessage(plugin.tokenizer.ircChatToGameTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, TemplateName.IRC_CONSOLE_CHAT), message)); + messageSent = true; + } + + plugin.logDebug("Checking if " + TemplateName.IRC_HERO_CHAT + " is enabled before broadcasting chat from IRC to HeroChat"); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_HERO_CHAT)) { + String hChannel = heroChannel.get(myChannel); + String tmpl = plugin.getIRCHeroChatChannelTemplate(botNick, hChannel); + plugin.logDebug("broadcastChat [HC]: " + hChannel + ": " + tmpl); + String rawHCMessage = filterMessage( + plugin.tokenizer.ircChatToHeroChatTokenizer(this, user, channel, tmpl, message, Herochat.getChannelManager(), hChannel), myChannel); + if (!rawHCMessage.isEmpty()) { + Herochat.getChannelManager().getChannel(hChannel).sendRawMessage(rawHCMessage); + messageSent = true; + if (logIrcToHeroChat.containsKey(myChannel)) { + if (logIrcToHeroChat.get(myChannel)) { + plugin.getServer().getConsoleSender().sendMessage(rawHCMessage); + } + } + } + } else { + plugin.logDebug("NOPE we can't broadcast to HeroChat due to " + TemplateName.IRC_HERO_CHAT + " disabled"); + } + if (plugin.isPluginEnabled("Essentials")) { + plugin.logDebug("Checking if " + TemplateName.IRC_ESS_HELPOP + " is enabled before broadcasting chat from IRC"); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_ESS_HELPOP) || override) { + plugin.logDebug("Yup we can broadcast due to " + TemplateName.IRC_ESS_HELPOP + " enabled"); + String newMessage = filterMessage( + plugin.tokenizer.ircChatToGameTokenizer(this, user, channel, plugin.getMsgTemplate( + botNick, TemplateName.IRC_ESS_HELPOP), message), myChannel); + if (!newMessage.isEmpty()) { + plugin.getServer().broadcast(newMessage, "essentials.helpop.receive"); + messageSent = true; + } + } else { + plugin.logDebug("NOPE we can't broadcast due to " + TemplateName.IRC_ESS_HELPOP + + " disabled"); + } + } + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_CHAT_RESPONSE) && messageSent && target != null) { + // Let the sender know the message was sent + String responseTemplate = plugin.getMsgTemplate(botNick, TemplateName.IRC_CHAT_RESPONSE); + if (!responseTemplate.isEmpty()) { + if (ctcpResponse) { + asyncCTCPMessage(target, plugin.tokenizer.targetChatResponseTokenizer(target, message, responseTemplate)); + } else { + asyncIRCMessage(target, plugin.tokenizer.targetChatResponseTokenizer(target, message, responseTemplate)); + } + } + } + } + +// Broadcast chat messages from IRC to specific hero channel + /** + * + * @param user + * @param channel + * @param target + * @param message + */ + public void broadcastHeroChat(User user, org.pircbotx.Channel channel, String target, String message) { + String ircChannel = channel.getName(); + if (message == null) { + plugin.logDebug("H: NULL MESSAGE"); + asyncIRCMessage(target, "No channel specified!"); + return; + } + if (message.contains(" ")) { + String hChannel; + String msg; + hChannel = message.split(" ", 2)[0]; + msg = message.split(" ", 2)[1]; + plugin.logDebug("Check if " + TemplateName.IRC_HERO_CHAT + " is enabled before broadcasting chat from IRC"); + if (enabledMessages.get(ircChannel).contains(TemplateName.IRC_HERO_CHAT)) { + plugin.logDebug("Checking if " + hChannel + " is a valid hero channel..."); + if (Herochat.getChannelManager().hasChannel(hChannel)) { + hChannel = Herochat.getChannelManager().getChannel(hChannel).getName(); + String template = plugin.getIRCHeroChatChannelTemplate(botNick, hChannel); + plugin.logDebug("T: " + template); + String t = plugin.tokenizer.ircChatToHeroChatTokenizer(this, user, + channel, template, msg, + Herochat.getChannelManager(), hChannel); + plugin.logDebug("Sending message to" + hChannel + ":" + t); + Herochat.getChannelManager().getChannel(hChannel) + .sendRawMessage(t); + plugin.logDebug("Channel format: " + Herochat.getChannelManager().getChannel(hChannel).getFormat()); + // Let the sender know the message was sent + String responseTemplate = plugin.getMsgTemplate(botNick, TemplateName.IRC_HCHAT_RESPONSE); + if (!responseTemplate.isEmpty()) { + asyncIRCMessage(target, plugin.tokenizer + .targetChatResponseTokenizer(hChannel, msg, responseTemplate)); + } + } else { + asyncIRCMessage(target, "Hero channel \"" + hChannel + "\" does not exist!"); + } + } else { + plugin.logDebug("NOPE we can't broadcast due to " + + TemplateName.IRC_HERO_CHAT + " disabled"); + } + } else { + asyncIRCMessage(target, "No message specified."); + } + } + + // Send chat messages from IRC to player + /** + * + * @param user + * @param channel + * @param target + * @param message + */ + public void playerChat(User user, org.pircbotx.Channel channel, String target, String message) { + String myChannel = channel.getName(); + if (message == null) { + plugin.logDebug("H: NULL MESSAGE"); + asyncIRCMessage(target, "No player specified!"); + return; + } + if (message.contains(" ")) { + String pName; + String msg; + pName = message.split(" ", 2)[0]; + msg = message.split(" ", 2)[1]; + plugin.logDebug("Check if " + TemplateName.IRC_PCHAT + " is enabled before broadcasting chat from IRC"); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_PCHAT)) { + plugin.logDebug("Yup we can broadcast due to " + TemplateName.IRC_PCHAT + + " enabled... Checking if " + pName + " is a valid player..."); + Player player = plugin.getServer().getPlayer(pName); + if (player != null) { + if (player.isOnline()) { + plugin.logDebug("Yup, " + pName + " is a valid player..."); + String template = plugin.getMsgTemplate(botNick, TemplateName.IRC_PCHAT); + String t = plugin.tokenizer.ircChatToGameTokenizer(this, user, + channel, template, msg); + String responseTemplate = plugin.getMsgTemplate(botNick, + TemplateName.IRC_PCHAT_RESPONSE); + if (!responseTemplate.isEmpty()) { + asyncIRCMessage(target, plugin.tokenizer + .targetChatResponseTokenizer(pName, msg, responseTemplate)); + } + plugin.logDebug("Tokenized message: " + t); + player.sendMessage(t); + } else { + asyncIRCMessage(target, "Player is offline: " + pName); + } + } else { + asyncIRCMessage(target, "Player not found (possibly offline): " + pName); + } + } else { + plugin.logDebug("NOPE we can't broadcast due to irc-pchat disabled"); + } + } else { + asyncIRCMessage(target, "No message specified."); + } + } + +// Broadcast action messages from IRC + /** + * + * @param user + * @param channel + * @param message + */ + public void broadcastAction(User user, org.pircbotx.Channel channel, String message) { + String myChannel = channel.getName(); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_ACTION)) { + plugin.getServer().broadcast(plugin.tokenizer.ircChatToGameTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, + TemplateName.IRC_ACTION), message), "irc.message.action"); + } else { + plugin.logDebug("Ignoring action due to " + + TemplateName.IRC_ACTION + " is false"); + } + + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_HERO_ACTION)) { + String hChannel = heroChannel.get(myChannel); + String tmpl = plugin.getIRCHeroActionChannelTemplate(botNick, hChannel); + plugin.logDebug("broadcastChat [HA]: " + hChannel + ": " + tmpl); + String rawHCMessage = filterMessage( + plugin.tokenizer.ircChatToHeroChatTokenizer(this, user, channel, tmpl, message, Herochat.getChannelManager(), hChannel), myChannel); + if (!rawHCMessage.isEmpty()) { + Herochat.getChannelManager().getChannel(hChannel).sendRawMessage(rawHCMessage); + if (logIrcToHeroChat.containsKey(myChannel)) { + if (logIrcToHeroChat.get(myChannel)) { + plugin.getServer().getConsoleSender().sendMessage(rawHCMessage); + } + } + } + } + + if (plugin.dynmapHook != null) { + plugin.logDebug("xChecking if " + TemplateName.IRC_ACTION_DYNMAP_WEB_CHAT + " is enabled ..."); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_ACTION_DYNMAP_WEB_CHAT)) { + plugin.logDebug("Yes, " + TemplateName.IRC_ACTION_DYNMAP_WEB_CHAT + " is enabled..."); + String template = plugin.getMsgTemplate(botNick, TemplateName.IRC_ACTION_DYNMAP_WEB_CHAT); + String rawDWMessage = filterMessage( + plugin.tokenizer.ircChatToGameTokenizer(this, user, channel, template, message), myChannel); + plugin.dynmapHook.sendMessage(user.getNick(), rawDWMessage); + } else { + plugin.logDebug("Nope, " + TemplateName.IRC_ACTION_DYNMAP_WEB_CHAT + " is NOT enabled..."); + } + } + } + + /** + * + * @param recipient + * @param kicker + * @param reason + * @param channel + */ + public void broadcastIRCKick(User recipient, User kicker, String reason, org.pircbotx.Channel channel) { + String myChannel = channel.getName(); + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_KICK)) { + plugin.getServer().broadcast(plugin.tokenizer.ircKickTokenizer( + this, recipient, kicker, reason, channel, plugin.getMsgTemplate( + botNick, TemplateName.IRC_KICK)), + "irc.message.kick"); + } + + if (enabledMessages.get(myChannel).contains(TemplateName.IRC_HERO_KICK)) { + Herochat.getChannelManager().getChannel(heroChannel.get(myChannel)) + .sendRawMessage(plugin.tokenizer + .ircKickToHeroChatTokenizer(this, + recipient, kicker, + reason, channel, + plugin.getMsgTemplate(botNick, TemplateName.IRC_HERO_KICK), + Herochat.getChannelManager(), + heroChannel.get(myChannel) + ) + ); + } + } + + /** + * + * @return + */ + public boolean isConnectedBlocking() { + return bot.isConnected(); + } + + /** + * + * @param user + * @param mode + * @param channel + */ + public void broadcastIRCMode(User user, String mode, org.pircbotx.Channel channel) { + if (isMessageEnabled(channel, TemplateName.IRC_MODE)) { + plugin.getServer().broadcast(plugin.tokenizer.ircModeTokenizer(this, user, mode, + channel, plugin.getMsgTemplate(botNick, + TemplateName.IRC_MODE)), "irc.message.mode"); + } + } + + /** + * + * @param user + * @param message + * @param notice + * @param channel + */ + public void broadcastIRCNotice(User user, String message, String notice, org.pircbotx.Channel channel) { + if (isMessageEnabled(channel, TemplateName.IRC_NOTICE)) { + plugin.getServer().broadcast(plugin.tokenizer.ircNoticeTokenizer(this, user, + message, notice, channel, plugin.getMsgTemplate(botNick, + TemplateName.IRC_NOTICE)), "irc.message.notice"); + } + } + + /** + * + * @param user + * @param channel + */ + public void broadcastIRCJoin(User user, org.pircbotx.Channel channel) { + if (isMessageEnabled(channel, TemplateName.IRC_JOIN)) { + plugin.logDebug("[broadcastIRCJoin] Broadcasting join message because " + TemplateName.IRC_JOIN + " is true."); + plugin.getServer().broadcast(plugin.tokenizer.chatIRCTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, TemplateName.IRC_JOIN)), "irc.message.join"); + } else { + plugin.logDebug("[broadcastIRCJoin] NOT broadcasting join message because irc-join is false."); + } + + if (isMessageEnabled(channel, TemplateName.IRC_HERO_JOIN)) { + Herochat.getChannelManager().getChannel(heroChannel.get(channel.getName())) + .sendRawMessage(plugin.tokenizer.ircChatToHeroChatTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, + TemplateName.IRC_HERO_JOIN), + Herochat.getChannelManager(), + heroChannel.get(channel.getName()))); + } + } + + public void broadcastIRCPart(User user, org.pircbotx.Channel channel) { + if (isMessageEnabled(channel, TemplateName.IRC_PART)) { + String message = plugin.tokenizer.chatIRCTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, TemplateName.IRC_PART)); + plugin.logDebug("[broadcastIRCPart] Broadcasting part message because " + + TemplateName.IRC_PART + " is true: " + message); + plugin.getServer().broadcast(message, "irc.message.part"); + } else { + plugin.logDebug("[broadcastIRCPart] NOT broadcasting part message because " + + TemplateName.IRC_PART + " is false."); + } + + if (isMessageEnabled(channel, TemplateName.IRC_HERO_PART)) { + Herochat.getChannelManager().getChannel(heroChannel.get(channel.getName())) + .sendRawMessage(plugin.tokenizer.ircChatToHeroChatTokenizer( + this, user, channel, plugin.getMsgTemplate( + botNick, TemplateName.IRC_HERO_PART), + Herochat.getChannelManager(), + heroChannel.get(channel.getName()))); + } + } + + public void broadcastIRCQuit(User user, org.pircbotx.Channel channel, String reason) { + if (isMessageEnabled(channel, TemplateName.IRC_QUIT)) { + plugin.logDebug("[broadcastIRCQuit] Broadcasting quit message because " + + TemplateName.IRC_QUIT + " is true."); + plugin.getServer().broadcast(plugin.tokenizer.chatIRCTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, TemplateName.IRC_QUIT)) + .replace("%REASON%", reason), "irc.message.quit"); + } else { + plugin.logDebug("[broadcastIRCQuit] NOT broadcasting quit message because " + + TemplateName.IRC_QUIT + " is false."); + } + + if (isMessageEnabled(channel, TemplateName.IRC_HERO_QUIT)) { + Herochat.getChannelManager().getChannel(heroChannel.get(channel.getName())) + .sendRawMessage(plugin.tokenizer.ircChatToHeroChatTokenizer( + this, user, channel, plugin.getMsgTemplate( + botNick, TemplateName.IRC_HERO_QUIT), + Herochat.getChannelManager(), + heroChannel.get(channel.getName()))); + } + + } + + /** + * Broadcast topic changes from IRC + * + * @param user + * @param channel + * @param message + */ + public void broadcastIRCTopic(User user, org.pircbotx.Channel channel, String message) { + if (isMessageEnabled(channel, TemplateName.IRC_TOPIC)) { + plugin.getServer().broadcast(plugin.tokenizer.chatIRCTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, TemplateName.IRC_TOPIC)), "irc.message.topic"); + } + + if (isMessageEnabled(channel, TemplateName.IRC_HERO_TOPIC)) { + Herochat.getChannelManager().getChannel(heroChannel.get(channel.getName())) + .sendRawMessage(plugin.tokenizer.ircChatToHeroChatTokenizer( + this, user, channel, plugin.getMsgTemplate(botNick, TemplateName.IRC_HERO_TOPIC), message, + Herochat.getChannelManager(), + heroChannel.get(channel.getName()))); + } + } + + /** + * + * @param channelName + * @param templateName + * @return + */ + public boolean isMessageEnabled(String channelName, String templateName) { + return enabledMessages.get(channelName).contains(templateName); + } + + /** + * + * @param channel + * @param templateName + * @return + */ + public boolean isMessageEnabled(Channel channel, String templateName) { + return isMessageEnabled(channel.getName(), templateName); + } + + /** + * Broadcast disconnect messages from IRC + * + * @param nick + */ + public void broadcastIRCDisconnect(String nick) { + plugin.getServer().broadcast("[" + nick + "] Disconnected from IRC server.", "irc.message.disconnect"); + } + + /** + * Broadcast connect messages from IRC + * + * @param nick + */ + public void broadcastIRCConnect(String nick) { + plugin.getServer().broadcast("[" + nick + "] Connected to IRC server.", "irc.message.connect"); + } + + /** + * Notify when players use commands + * + * @param player + * @param cmd + * @param params + */ + public void commandNotify(Player player, String cmd, String params) { + if (!this.isConnected()) { + return; + } + String msg = plugin.tokenizer.gameCommandToIRCTokenizer(player, + plugin.getMsgTemplate(botNick, TemplateName.GAME_COMMAND), cmd, params); + if (channelCmdNotifyMode.equalsIgnoreCase("msg")) { + for (String recipient : channelCmdNotifyRecipients) { + asyncIRCMessage(recipient, msg); + } + } else if (channelCmdNotifyMode.equalsIgnoreCase("ctcp")) { + for (String recipient : channelCmdNotifyRecipients) { + asyncCTCPMessage(recipient, msg); + } + } + } + + // Notify when player goes AFK + /** + * + * @param player + * @param afk + */ + public void essentialsAFK(Player player, boolean afk) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.GAME_AFK)) { + if (!isPlayerInValidWorld(player, channelName)) { + return; + } + String template; + if (afk) { + template = plugin.getMsgTemplate(botNick, TemplateName.ESS_PLAYER_AFK); + } else { + template = plugin.getMsgTemplate(botNick, TemplateName.ESS_PLAYER_NOT_AFK); + } + plugin.logDebug("Sending AFK message to " + channelName); + asyncIRCMessage(channelName, plugin.tokenizer.gamePlayerAFKTokenizer(player, template)); + } + } + } + + /** + * + * @param sender + * @param nick + * @param message + */ + public void msgPlayer(Player sender, String nick, String message) { + String msg = plugin.tokenizer.gameChatToIRCTokenizer(sender, + plugin.getMsgTemplate(botNick, TemplateName.GAME_PCHAT), message); + asyncIRCMessage(nick, msg); + } + + /** + * + * @param nick + * @param message + */ + public void consoleMsgPlayer(String nick, String message) { + String msg = plugin.tokenizer.gameChatToIRCTokenizer("console", + plugin.getMsgTemplate(botNick, TemplateName.CONSOLE_CHAT), message); + asyncIRCMessage(nick, msg); + } + + /** + * + * @param player + * @return + */ + protected String getFactionName(Player player) { + MPlayer mPlayer = MPlayer.get(player); + Faction faction = mPlayer.getFaction(); + return faction.getName(); + } + + public boolean isConnected() { + return connected; + } + + public ImmutableSortedSet getChannels() { + if (bot.getNick().isEmpty()) { + return ImmutableSortedSet.naturalOrder().build(); + } + return bot.getUserBot().getChannels(); + } + + public long getMessageDelay() { + return bot.getConfiguration().getMessageDelay(); + } + + public String getMotd() { + return bot.getServerInfo().getMotd(); + } + + public boolean isValidChannel(String channelName) { + for (String s : botChannels) { + if (channelName.equalsIgnoreCase(s)) { + return true; + } + } + plugin.logDebug("Channel " + channelName + " is not valid."); + return false; + } + + public PircBotX getBot() { + return bot; + } + + /** + * + * @param connected + */ + public void setConnected(boolean connected) { + this.connected = connected; + } + + public String getFileName() { + return fileName; + } + + public String prismBlockStateChangeTokens(String message, ArrayList blockStateChange) { + String X; + String Y; + String Z; + String origBlock; + String newBlock; + String blockWorld; + try { + blockWorld = String.valueOf(blockStateChange.get(0).getNewBlock().getWorld().getName()); + } catch (Exception ex) { + plugin.logDebug(ex.getMessage()); + blockWorld = ""; + } + try { + origBlock = String.valueOf(blockStateChange.get(0).getOriginalBlock().getType().name()); + } catch (Exception ex) { + plugin.logDebug(ex.getMessage()); + origBlock = ""; + } + try { + newBlock = String.valueOf(blockStateChange.get(0).getNewBlock().getType().name()); + } catch (Exception ex) { + plugin.logDebug(ex.getMessage()); + newBlock = ""; + } + try { + X = String.valueOf(blockStateChange.get(0).getNewBlock().getX()); + Y = String.valueOf(blockStateChange.get(0).getNewBlock().getY()); + Z = String.valueOf(blockStateChange.get(0).getNewBlock().getZ()); + } catch (Exception ex) { + plugin.logDebug(ex.getMessage()); + X = ""; + Y = ""; + Z = ""; + } + if (X == null) { + X = ""; + } + if (Y == null) { + Y = ""; + } + if (Z == null) { + Z = ""; + } + if (blockWorld == null) { + blockWorld = null; + } + if (origBlock == null) { + origBlock = ""; + } + if (newBlock == null) { + newBlock = ""; + } + return message + .replace("%ORIGINALBLOCK%", origBlock) + .replace("%NEWBLOCK%", newBlock) + .replace("%X%", X) + .replace("%Y%", Y) + .replace("%Z%", Z) + .replace("%BLOCKWORLD%", blockWorld); + } + + public void gamePrismRollback(Player player, QueryParameters queryParams, ArrayList blockStateChange) { + if (!this.isConnected()) { + return; + } + String keyword = queryParams.getKeyword(); + String sortDirection = queryParams.getSortDirection(); + String worldName = queryParams.getWorld(); + String id = String.valueOf(queryParams.getId()); + String radius = String.valueOf(queryParams.getRadius()); + if (keyword == null) { + keyword = ""; + } + if (sortDirection == null) { + sortDirection = ""; + } + if (worldName == null) { + worldName = ""; + } + if (id == null) { + id = ""; + } + if (radius == null) { + radius = ""; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.PRISM_ROLLBACK)) { + asyncIRCMessage(channelName, prismBlockStateChangeTokens(plugin.tokenizer + .playerTokenizer(player, plugin.getMsgTemplate(botNick, TemplateName.PRISM_ROLLBACK)) + .replace("%COMMAND%", queryParams.getOriginalCommand()) + .replace("%KEYWORD%", keyword) + .replace("%SORTDIRECTION%", sortDirection) + .replace("%PARAMWORLD%", worldName) + .replace("%ID%", id) + .replace("%RADIUS%", radius), blockStateChange + )); + } + } + } + + public void gamePrismDrainOrExtinguish(String template, Player player, int radius, ArrayList blockStateChange) { + if (!this.isConnected()) { + return; + } + String radiusStr = String.valueOf(radius); + + if (radiusStr == null) { + radiusStr = ""; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, template)) { + asyncIRCMessage(channelName, prismBlockStateChangeTokens(plugin.tokenizer + .playerTokenizer(player, plugin.getMsgTemplate(botNick, template)) + .replace("%RADIUS%", radiusStr), blockStateChange + )); + } + } + } + + public void gamePrismCustom(Player player, String actionName, String message, String pluginName) { + if (!this.isConnected()) { + return; + } + for (String channelName : botChannels) { + if (isMessageEnabled(channelName, TemplateName.PRISM_CUSTOM)) { + asyncIRCMessage(channelName, plugin.tokenizer + .playerTokenizer(player, plugin.getMsgTemplate(botNick, TemplateName.PRISM_CUSTOM)) + .replace("%ACTION%", actionName) + .replace("%MESSAGE%", message) + .replace("%PLUGIN%", pluginName) + ); + } + } + } + + public void joinNotice(Channel channel, User user) { + if (user.getNick().equalsIgnoreCase(botNick)) { + return; + } + if (joinNoticeEnabled) { + if (joinNoticeCooldownMap.containsKey(user.getHostmask())) { + long prevTime = joinNoticeCooldownMap.get(user.getHostmask()); + long currentTime = System.currentTimeMillis(); + long diff = currentTime - prevTime; + if (diff < (joinNoticeCoolDown * 1000)) { + plugin.logDebug("joinNotice: " + diff); + return; + } + } else { + joinNoticeCooldownMap.put(user.getHostmask(), System.currentTimeMillis()); + } + String target = channel.getName(); + if (joinNoticePrivate) { + target = user.getNick(); + } + String myMessage = ChatColor.translateAlternateColorCodes('&', plugin.colorConverter.gameColorsToIrc(joinNoticeMessage.replace("%NAME%", user.getNick()))); + if (joinNoticeMessage.startsWith("/")) { + plugin.commandQueue.add(new IRCCommand(new IRCCommandSender(this, target, plugin, joinNoticeCtcp), myMessage.trim().substring(1))); + } else { + if (joinNoticeCtcp) { + asyncCTCPMessage(target, myMessage); + } else { + asyncIRCMessage(target, myMessage); + } + } + } + } + + public void altNickChange() { + if (altNicks.isEmpty()) { + return; + } + if (nickIndex >= 0 && nickIndex < altNicks.size()) { + botNick = altNicks.get(nickIndex).replace("%NICK%", nick); + nickIndex++; + } else { + nickIndex = 0; + } + plugin.logInfo("Trying alternate nick " + botNick); + bot.sendIRC().changeNick(botNick); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/PurpleIRC.java b/src/main/java/com/cnaude/purpleirc/PurpleIRC.java new file mode 100755 index 0000000..8b46032 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/PurpleIRC.java @@ -0,0 +1,1436 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import com.cnaude.purpleirc.GameListeners.AdminChatListener; +import com.cnaude.purpleirc.GameListeners.CleverNotchListener; +import com.cnaude.purpleirc.GameListeners.DeathMessagesListener; +import com.cnaude.purpleirc.GameListeners.DynmapListener; +import com.cnaude.purpleirc.GameListeners.EssentialsListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerChatListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerCommandPreprocessingListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerDeathListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerGameModeChangeListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerJoinListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerKickListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerPlayerAchievementAwardedListener; +import com.cnaude.purpleirc.GameListeners.GamePlayerQuitListener; +import com.cnaude.purpleirc.GameListeners.GameServerCommandListener; +import com.cnaude.purpleirc.GameListeners.HeroChatListener; +import com.cnaude.purpleirc.GameListeners.McMMOChatListener; +import com.cnaude.purpleirc.GameListeners.OreBroadcastListener; +import com.cnaude.purpleirc.GameListeners.PrismListener; +import com.cnaude.purpleirc.GameListeners.RedditStreamListener; +import com.cnaude.purpleirc.GameListeners.ReportRTSListener; +import com.cnaude.purpleirc.GameListeners.TitanChatListener; +import com.cnaude.purpleirc.GameListeners.TownyChatListener; +import com.cnaude.purpleirc.Hooks.AdminPrivateChatHook; +import com.cnaude.purpleirc.Hooks.DynmapHook; +import com.cnaude.purpleirc.Hooks.FactionChatHook; +import com.cnaude.purpleirc.Hooks.JobsHook; +import com.cnaude.purpleirc.Hooks.JobsHookOld; +import com.cnaude.purpleirc.Hooks.ReportRTSHook; +import com.cnaude.purpleirc.Hooks.ShortifyHook; +import com.cnaude.purpleirc.Hooks.SuperVanishHook; +import com.cnaude.purpleirc.Hooks.TownyChatHook; +import com.cnaude.purpleirc.Hooks.VanishHook; +import com.cnaude.purpleirc.Hooks.VaultHook; +import com.cnaude.purpleirc.Utilities.CaseInsensitiveMap; +import com.cnaude.purpleirc.Utilities.ChatTokenizer; +import com.cnaude.purpleirc.Utilities.ColorConverter; +import com.cnaude.purpleirc.Utilities.IRCMessageHandler; +import com.cnaude.purpleirc.Utilities.NetPackets; +import com.cnaude.purpleirc.Utilities.Query; +import com.cnaude.purpleirc.Utilities.RegexGlobber; +import com.cnaude.purpleirc.Utilities.UpdateChecker; +import com.google.common.base.Joiner; +import com.onarandombox.MultiverseCore.api.MVPlugin; +import com.onarandombox.MultiverseCore.api.MultiverseWorld; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; +import org.pircbotx.IdentServer; + +/** + * + * @author Chris Naudé + */ +public class PurpleIRC extends JavaPlugin { + + public String LOG_HEADER; + public String LOG_HEADER_F; + static final Logger log = Logger.getLogger("Minecraft"); + private final String sampleFileName; + private final String MAINCONFIG; + private File pluginFolder; + public File botsFolder; + private File configFile; + public static long startTime; + public boolean identServerEnabled; + private final CaseInsensitiveMap> messageTmpl; + private final CaseInsensitiveMap> ircHeroChannelMessages; + private final CaseInsensitiveMap> ircHeroActionChannelMessages; + private final CaseInsensitiveMap> ircTownyChannelMessages; + private final CaseInsensitiveMap> heroChannelMessages; + private final CaseInsensitiveMap> heroActionChannelMessages; + private final Map hostCache; + public String defaultPlayerSuffix, + defaultPlayerPrefix, + defaultPlayerGroup, + defaultGroupPrefix, + defaultPlayerWorld, + defaultGroupSuffix, + customTabPrefix, + heroChatEmoteFormat, + listFormat, + listSeparator, + listPlayer, + ircNickPrefixIrcOp, + ircNickPrefixSuperOp, + ircNickPrefixOp, + ircNickPrefixHalfOp, + ircNickPrefixVoice; + private final CaseInsensitiveMap displayNameCache; + public CaseInsensitiveMap uuidCache; + + public ArrayList kickedPlayers = new ArrayList<>(); + + public final String invalidBotName = ChatColor.RED + "Invalid bot name: " + + ChatColor.WHITE + "%BOT%" + + ChatColor.RED + ". Type '" + ChatColor.WHITE + "/irc listbots" + + ChatColor.RED + "' to see valid bots."; + + public final String invalidChannelName = ChatColor.RED + "Invalid channel name: " + + ChatColor.WHITE + "%CHANNEL%"; + + public final String invalidChannel = ChatColor.RED + "Invalid channel: " + + ChatColor.WHITE + "%CHANNEL%"; + public final String noPermission = ChatColor.RED + "You do not have permission to use this command."; + + private boolean updateCheckerEnabled; + private String updateCheckerMode; + private boolean debugEnabled; + private boolean stripGameColors; + private boolean stripIRCColors; + private boolean stripIRCBackgroundColors; + public boolean customTabList; + public String customTabGamemode; + private boolean listSortByName; + public boolean exactNickMatch; + public boolean ignoreChatCancel; + public Long ircConnCheckInterval; + public Long ircChannelCheckInterval; + public ChannelWatcher channelWatcher; + public ColorConverter colorConverter; + public RegexGlobber regexGlobber; + public CaseInsensitiveMap ircBots; + public FactionChatHook fcHook; + public TownyChatHook tcHook; + public DynmapHook dynmapHook; + public JobsHook jobsHook; + public JobsHookOld jobsHookOld; + public AdminPrivateChatHook adminPrivateChatHook; + public ShortifyHook shortifyHook; + public ReportRTSHook reportRTSHook; + public NetPackets netPackets; + public CommandHandlers commandHandlers; + public PurpleTabCompleter ircTabCompleter; + private BotWatcher botWatcher; + public IRCMessageHandler ircMessageHandler; + + public CommandQueueWatcher commandQueue; + public UpdateChecker updateChecker; + public ChatTokenizer tokenizer; + private File heroConfigFile; + public VaultHook vaultHelpers; + public VanishHook vanishHook; + public SuperVanishHook superVanishHook; + private YamlConfiguration heroConfig; + private final File cacheFile; + private final File uuidCacheFile; + + public PurpleIRC() { + this.MAINCONFIG = "MAIN-CONFIG"; + this.sampleFileName = "SampleBot.yml"; + this.netPackets = null; + this.ircBots = new CaseInsensitiveMap<>(); + this.messageTmpl = new CaseInsensitiveMap<>(); + this.ircHeroChannelMessages = new CaseInsensitiveMap<>(); + this.ircHeroActionChannelMessages = new CaseInsensitiveMap<>(); + this.ircTownyChannelMessages = new CaseInsensitiveMap<>(); + this.heroChannelMessages = new CaseInsensitiveMap<>(); + this.heroActionChannelMessages = new CaseInsensitiveMap<>(); + this.displayNameCache = new CaseInsensitiveMap<>(); + this.uuidCache = new CaseInsensitiveMap<>(); + this.hostCache = new HashMap<>(); + this.cacheFile = new File("plugins/PurpleIRC/displayName.cache"); + this.uuidCacheFile = new File("plugins/PurpleIRC/uuid.cache"); + } + + /** + * + */ + @Override + public void onEnable() { + LOG_HEADER = "[" + this.getName() + "]"; + LOG_HEADER_F = ChatColor.DARK_PURPLE + "[" + this.getName() + "]" + ChatColor.RESET; + if (!getServer().getVersion().contains("Spigot")) { + logError("This plugin is only compatible with Spigot. Please download the CraftBukkit version from the BukkitDev site."); + this.getPluginLoader().disablePlugin(this); + return; + } + pluginFolder = getDataFolder(); + botsFolder = new File(pluginFolder + "/bots"); + configFile = new File(pluginFolder, "config.yml"); + createConfigDirs(); + createConfig(); + getConfig().options().copyDefaults(true); + saveConfig(); + loadConfig(); + loadDisplayNameCache(); + loadUuidCache(); + if (identServerEnabled) { + logInfo("Starting Ident Server ..."); + try { + IdentServer.startServer(); + } catch (Exception ex) { + logError(ex.getMessage()); + } + } + getServer().getPluginManager().registerEvents(new GamePlayerPlayerAchievementAwardedListener(this), this); + getServer().getPluginManager().registerEvents(new GamePlayerGameModeChangeListener(this), this); + getServer().getPluginManager().registerEvents(new GamePlayerChatListener(this), this); + getServer().getPluginManager().registerEvents(new GamePlayerCommandPreprocessingListener(this), this); + getServer().getPluginManager().registerEvents(new GamePlayerDeathListener(this), this); + getServer().getPluginManager().registerEvents(new GamePlayerJoinListener(this), this); + getServer().getPluginManager().registerEvents(new GamePlayerKickListener(this), this); + getServer().getPluginManager().registerEvents(new GamePlayerQuitListener(this), this); + getServer().getPluginManager().registerEvents(new GameServerCommandListener(this), this); + if (isPluginEnabled("Herochat")) { + logInfo("Enabling HeroChat support."); + getServer().getPluginManager().registerEvents(new HeroChatListener(this), this); + heroConfig = new YamlConfiguration(); + heroConfigFile = new File(getServer().getPluginManager() + .getPlugin("Herochat").getDataFolder(), "config.yml"); + try { + heroConfig.load(heroConfigFile); + } catch (IOException | InvalidConfigurationException ex) { + logError(ex.getMessage()); + } + heroChatEmoteFormat = heroConfig.getString("format.emote", ""); + } else { + logInfo("HeroChat not detected."); + } + if (isPluginEnabled("TitanChat")) { + logInfo("Enabling TitanChat support."); + getServer().getPluginManager().registerEvents(new TitanChatListener(this), this); + } else { + logInfo("TitanChat not detected."); + } + if (isPluginEnabled("Prism")) { + logInfo("Enabling Prism support."); + getServer().getPluginManager().registerEvents(new PrismListener(this), this); + } else { + logInfo("Prism not detected."); + } + if (isPluginEnabled("RedditStream")) { + logInfo("Enabling RedditStream support."); + getServer().getPluginManager().registerEvents(new RedditStreamListener(this), this); + } else { + logInfo("RedditStream not detected."); + } + if (isPluginEnabled("TownyChat")) { + logInfo("Enabling TownyChat support."); + getServer().getPluginManager().registerEvents(new TownyChatListener(this), this); + tcHook = new TownyChatHook(this); + } else { + logInfo("TownyChat not detected."); + } + if (isPluginEnabled("CleverNotch")) { + logInfo("Enabling CleverNotch support."); + getServer().getPluginManager().registerEvents(new CleverNotchListener(this), this); + } else { + logInfo("CleverNotch not detected."); + } + if (isPluginEnabled("mcMMO")) { + logInfo("Enabling mcMMO support."); + getServer().getPluginManager().registerEvents(new McMMOChatListener(this), this); + } else { + logInfo("mcMMO not detected."); + } + if (isFactionsEnabled()) { + if (isPluginEnabled("FactionChat")) { + String factionChatVersion = getServer().getPluginManager().getPlugin("FactionChat").getDescription().getVersion(); + if (factionChatVersion.startsWith("1.7")) { + logError("FactionChat v" + factionChatVersion + " not supported. Please install 1.8 or newer."); + } else { + logInfo("Enabling FactionChat support."); + fcHook = new FactionChatHook(this); + } + } else { + logInfo("FactionChat not detected."); + } + } + if (isPluginEnabled("AdminPrivateChat")) { + logInfo("Enabling AdminPrivateChat support."); + adminPrivateChatHook = new AdminPrivateChatHook(this); + getServer().getPluginManager().registerEvents(new AdminChatListener(this), this); + } else { + logInfo("AdminPrivateChat not detected."); + } + if (isPluginEnabled("Jobs")) { + String m = getServer().getPluginManager().getPlugin("Jobs").getDescription().getMain(); + String jobsVersion = getServer().getPluginManager().getPlugin("Jobs").getDescription().getVersion(); + if (m.contains("me.zford")) { + logInfo("Enabling legacy Jobs support: " + jobsVersion); + jobsHookOld = new JobsHookOld(this); + } else if (m.contains("com.gamingmesh")) { + logInfo("Enabling new Jobs support: " + jobsVersion); + jobsHook = new JobsHook(this); + } else { + logError("Unable to hook into Jobs: " + m); + } + } else { + logInfo("Jobs not detected."); + } + if (isPluginEnabled("DeathMessages")) { + logInfo("Enabling DeathMessages support."); + getServer().getPluginManager().registerEvents(new DeathMessagesListener(this), this); + } else { + logInfo("DeathMessages not detected."); + } + if (isPluginEnabled("Shortify")) { + String shortifyVersion = getServer().getPluginManager().getPlugin("Shortify").getDescription().getVersion(); + if (shortifyVersion.startsWith("1.8")) { + logInfo("Enabling Shortify v" + shortifyVersion + " support."); + shortifyHook = new ShortifyHook(this); + } else { + logError("Shortify v" + shortifyVersion + " not supported. Please use the latest version from http://jenkins.cnaude.org/job/Shortify/"); + } + } else { + logInfo("Shortify not detected."); + } + if (isPluginEnabled("dynmap")) { + logInfo("Enabling Dynmap support."); + getServer().getPluginManager().registerEvents(new DynmapListener(this), this); + dynmapHook = new DynmapHook(this); + } else { + logInfo("Dynmap not detected."); + } + if (isPluginEnabled("OreBroadcast")) { + logInfo("Enabling OreBroadcast support."); + getServer().getPluginManager().registerEvents(new OreBroadcastListener(this), this); + } else { + logInfo("OreBroadcast not detected."); + } + vanishHook = new VanishHook(this); + if (isPluginEnabled("SuperVanish")) { + logInfo("Enabling SuperVanish support."); + superVanishHook = new SuperVanishHook(this); + } else { + logInfo("SuperVanish not detected."); + } + if (isPluginEnabled("ReportRTS")) { + logInfo("Enabling ReportRTS support."); + getServer().getPluginManager().registerEvents(new ReportRTSListener(this), this); + reportRTSHook = new ReportRTSHook(this); + } else { + logInfo("ReportRTS not detected."); + } + if (isPluginEnabled("Essentials")) { + logInfo("Enabling Essentials support."); + getServer().getPluginManager().registerEvents(new EssentialsListener(this), this); + } else { + logInfo("Essentials not detected."); + } + commandHandlers = new CommandHandlers(this); + ircTabCompleter = new PurpleTabCompleter(this); + getCommand("irc").setExecutor(commandHandlers); + getCommand("irc").setTabCompleter(ircTabCompleter); + regexGlobber = new RegexGlobber(); + tokenizer = new ChatTokenizer(this); + loadBots(); + createSampleBot(); + channelWatcher = new ChannelWatcher(this); + setupVault(); + if (customTabList) { + if (checkForProtocolLib()) { + logInfo("Hooked into ProtocolLib! Custom tab list is enabled."); + netPackets = new NetPackets(this); + } else { + logError("ProtocolLib not found! The custom tab list is disabled."); + netPackets = null; + } + } else { + netPackets = null; + } + botWatcher = new BotWatcher(this); + ircMessageHandler = new IRCMessageHandler(this); + commandQueue = new CommandQueueWatcher(this); + updateChecker = new UpdateChecker(this); + } + + /** + * + */ + @Override + public void onDisable() { + if (channelWatcher != null) { + logDebug("Disabling channelWatcher ..."); + channelWatcher.cancel(); + } + if (botWatcher != null) { + logDebug("Disabling botWatcher ..."); + botWatcher.cancel(); + } + if (updateChecker != null) { + logDebug("Disabling updateChecker ..."); + updateChecker.cancel(); + } + if (ircBots.isEmpty()) { + logInfo("No IRC bots to disconnect."); + } else { + logInfo("Disconnecting IRC bots."); + for (PurpleBot ircBot : ircBots.values()) { + commandQueue.cancel(); + ircBot.saveConfig(getServer().getConsoleSender()); + ircBot.quit(); + } + ircBots.clear(); + } + if (identServerEnabled) { + logInfo("Stopping Ident Server"); + try { + IdentServer.stopServer(); + } catch (IOException ex) { + logError(ex.getMessage()); + } + } + saveDisplayNameCache(); + saveUuidCache(); + } + + /** + * + * @param debug + */ + public void debugMode(boolean debug) { + debugEnabled = debug; + getConfig().set("Debug", debug); + try { + getConfig().save(configFile); + } catch (IOException ex) { + logError("Problem saving to " + configFile.getName() + ": " + ex.getMessage()); + } + } + + /** + * + * @return + */ + public boolean debugMode() { + return debugEnabled; + } + + public String getHeroMsgTemplate(String botName, String tmpl) { + if (messageTmpl.containsKey(botName)) { + if (messageTmpl.get(botName).containsKey(tmpl)) { + return messageTmpl.get(botName).get(tmpl); + } + } + if (messageTmpl.get(MAINCONFIG).containsKey(tmpl)) { + return messageTmpl.get(MAINCONFIG).get(tmpl); + } + return ""; + } + + public String getMsgTemplate(String botName, String tmpl) { + if (messageTmpl.containsKey(botName)) { + if (messageTmpl.get(botName).containsKey(tmpl)) { + return messageTmpl.get(botName).get(tmpl); + } + } + if (messageTmpl.get(MAINCONFIG).containsKey(tmpl)) { + return messageTmpl.get(MAINCONFIG).get(tmpl); + } + return "INVALID TEMPLATE"; + } + + public String getMsgTemplate(String tmpl) { + return getMsgTemplate(MAINCONFIG, tmpl); + } + + public String getHeroTemplate(CaseInsensitiveMap> hc, + String botName, String hChannel) { + if (hc.containsKey(botName)) { + logDebug("HC1 => " + hChannel); + for (String s : hc.get(botName).keySet()) { + logDebug("HT => " + s); + } + if (hc.get(botName).containsKey(hChannel)) { + logDebug("HC2 => " + hChannel); + return hc.get(botName).get(hChannel); + } + } + if (hc.containsKey(MAINCONFIG)) { + logDebug("HC3 => " + hChannel); + for (String s : hc.get(MAINCONFIG).keySet()) { + logDebug("HT => " + s); + } + if (hc.get(MAINCONFIG).containsKey(hChannel)) { + logDebug("HC4 => " + hChannel); + return hc.get(MAINCONFIG).get(hChannel); + } + } + return ""; + } + + public String getHeroChatChannelTemplate(String botName, String hChannel) { + String tmpl = getHeroTemplate(heroChannelMessages, botName, hChannel); + if (tmpl.isEmpty()) { + return getMsgTemplate(MAINCONFIG, TemplateName.HERO_CHAT); + } + return getHeroTemplate(heroChannelMessages, botName, hChannel); + } + + public String getHeroActionChannelTemplate(String botName, String hChannel) { + String tmpl = getHeroTemplate(heroActionChannelMessages, botName, hChannel); + if (tmpl.isEmpty()) { + return getMsgTemplate(MAINCONFIG, TemplateName.HERO_ACTION); + } + return getHeroTemplate(heroActionChannelMessages, botName, hChannel); + } + + public String getIRCHeroChatChannelTemplate(String botName, String hChannel) { + String tmpl = getHeroTemplate(ircHeroChannelMessages, botName, hChannel); + if (tmpl.isEmpty()) { + return getMsgTemplate(MAINCONFIG, TemplateName.IRC_HERO_CHAT); + } + return getHeroTemplate(ircHeroChannelMessages, botName, hChannel); + } + + public String getIRCHeroActionChannelTemplate(String botName, String hChannel) { + String tmpl = getHeroTemplate(ircHeroActionChannelMessages, botName, hChannel); + if (tmpl.isEmpty()) { + return getMsgTemplate(MAINCONFIG, TemplateName.IRC_HERO_ACTION); + } + return getHeroTemplate(ircHeroActionChannelMessages, botName, hChannel); + } + + public String getIRCTownyChatChannelTemplate(String botName, String tChannel) { + String tmpl = getHeroTemplate(ircTownyChannelMessages, botName, tChannel); + if (tmpl.isEmpty()) { + return getMsgTemplate(MAINCONFIG, TemplateName.IRC_TOWNY_CHAT); + } + return getHeroTemplate(ircTownyChannelMessages, botName, tChannel); + } + + public void loadCustomColors(YamlConfiguration config) { + for (String t : config.getConfigurationSection("irc-color-map").getKeys(false)) { + colorConverter.addIrcColorMap(t, config.getString("irc-color-map." + t)); + } + for (String t : config.getConfigurationSection("game-color-map").getKeys(false)) { + colorConverter.addGameColorMap(t, config.getString("game-color-map." + t)); + } + } + + public void loadTemplates(YamlConfiguration config, String configName) { + messageTmpl.put(configName, new HashMap()); + ircHeroChannelMessages.put(configName, new CaseInsensitiveMap()); + ircHeroActionChannelMessages.put(configName, new CaseInsensitiveMap()); + ircTownyChannelMessages.put(configName, new CaseInsensitiveMap()); + heroChannelMessages.put(configName, new CaseInsensitiveMap()); + heroActionChannelMessages.put(configName, new CaseInsensitiveMap()); + + if (config.contains("message-format")) { + for (String t : config.getConfigurationSection("message-format").getKeys(false)) { + if (!t.startsWith("MemorySection")) { + messageTmpl.get(configName).put(t, ChatColor.translateAlternateColorCodes('&', + config.getString("message-format." + t, ""))); + logDebug("message-format: " + t + " => " + messageTmpl.get(configName).get(t)); + } + } + + if (config.contains("message-format.irc-hero-channels")) { + for (String hChannelName : config.getConfigurationSection("message-format.irc-hero-channels").getKeys(false)) { + ircHeroChannelMessages.get(configName).put(hChannelName, + ChatColor.translateAlternateColorCodes('&', + config.getString("message-format.irc-hero-channels." + + hChannelName))); + logDebug("message-format.irc-hero-channels: " + hChannelName + + " => " + ircHeroChannelMessages.get(configName).get(hChannelName)); + } + } + + if (config.contains("message-format.irc-hero-action-channels")) { + for (String hChannelName : config.getConfigurationSection("message-format.irc-hero-action-channels").getKeys(false)) { + ircHeroActionChannelMessages.get(configName).put(hChannelName, + ChatColor.translateAlternateColorCodes('&', + config.getString("message-format.irc-hero-action-channels." + + hChannelName))); + logDebug("message-format.irc-hero-action-channels: " + hChannelName + + " => " + ircHeroActionChannelMessages.get(configName).get(hChannelName)); + } + } + + if (config.contains("message-format.irc-towny-channels")) { + for (String tChannelName : config.getConfigurationSection("message-format.irc-towny-channels").getKeys(false)) { + ircTownyChannelMessages.get(configName).put(tChannelName, + ChatColor.translateAlternateColorCodes('&', + config.getString("message-format.irc-towny-channels." + + tChannelName))); + logDebug("message-format.irc-towny-channels: " + tChannelName + + " => " + ircTownyChannelMessages.get(configName).get(tChannelName)); + } + } + + if (config.contains("message-format.hero-channels")) { + for (String hChannelName : config.getConfigurationSection("message-format.hero-channels").getKeys(false)) { + heroChannelMessages.get(configName).put(hChannelName, + ChatColor.translateAlternateColorCodes('&', + config.getString("message-format.hero-channels." + + hChannelName))); + logDebug("message-format.hero-channels: " + hChannelName + + " => " + heroChannelMessages.get(configName).get(hChannelName)); + } + } + if (config.contains("message-format.hero-action-channels")) { + for (String hChannelName : config.getConfigurationSection("message-format.hero-action-channels").getKeys(false)) { + heroActionChannelMessages.get(configName).put(hChannelName, + ChatColor.translateAlternateColorCodes('&', + config.getString("message-format.hero-action-channels." + + hChannelName))); + logDebug("message-format.hero-action-channels: " + hChannelName + + " => " + heroActionChannelMessages.get(configName).get(hChannelName)); + } + } + } else { + logDebug("No message-format section found for " + configName); + } + } + + private void loadConfig() { + try { + getConfig().load(configFile); + } catch (IOException | InvalidConfigurationException ex) { + logError(ex.getMessage()); + } + updateCheckerEnabled = getConfig().getBoolean("update-checker", true); + updateCheckerMode = getConfig().getString("update-checker-mode", "stable"); + debugEnabled = getConfig().getBoolean("Debug"); + identServerEnabled = getConfig().getBoolean("enable-ident-server"); + logDebug("Debug enabled"); + stripGameColors = getConfig().getBoolean("strip-game-colors", false); + stripIRCColors = getConfig().getBoolean("strip-irc-colors", false); + stripIRCBackgroundColors = getConfig().getBoolean("strip-irc-bg-colors", true); + exactNickMatch = getConfig().getBoolean("nick-exact-match", true); + ignoreChatCancel = getConfig().getBoolean("ignore-chat-cancel", false); + colorConverter = new ColorConverter(this, stripGameColors, stripIRCColors, stripIRCBackgroundColors); + logDebug("strip-game-colors: " + stripGameColors); + logDebug("strip-irc-colors: " + stripIRCColors); + + loadTemplates((YamlConfiguration) this.getConfig(), MAINCONFIG); + loadCustomColors((YamlConfiguration) this.getConfig()); + + defaultPlayerSuffix = ChatColor.translateAlternateColorCodes('&', getConfig().getString("message-format.default-player-suffix", "")); + defaultPlayerPrefix = ChatColor.translateAlternateColorCodes('&', getConfig().getString("message-format.default-player-prefix", "")); + defaultPlayerGroup = ChatColor.translateAlternateColorCodes('&', getConfig().getString("message-format.default-player-group", "")); + defaultGroupSuffix = ChatColor.translateAlternateColorCodes('&', getConfig().getString("message-format.default-group-suffix", "")); + defaultGroupPrefix = ChatColor.translateAlternateColorCodes('&', getConfig().getString("message-format.default-group-prefix", "")); + defaultPlayerWorld = ChatColor.translateAlternateColorCodes('&', getConfig().getString("message-format.default-player-world", "")); + + ircNickPrefixIrcOp = ChatColor.translateAlternateColorCodes('&', getConfig().getString("nick-prefixes.ircop", "~")); + ircNickPrefixSuperOp = ChatColor.translateAlternateColorCodes('&', getConfig().getString("nick-prefixes.ircsuperop", "&&")); + ircNickPrefixOp = ChatColor.translateAlternateColorCodes('&', getConfig().getString("nick-prefixes.op", "@")); + ircNickPrefixHalfOp = ChatColor.translateAlternateColorCodes('&', getConfig().getString("nick-prefixes.halfop", "%")); + ircNickPrefixVoice = ChatColor.translateAlternateColorCodes('&', getConfig().getString("nick-prefixes.voice", "+")); + + listFormat = ChatColor.translateAlternateColorCodes('&', getConfig().getString("list-format", "")); + listSeparator = ChatColor.translateAlternateColorCodes('&', getConfig().getString("list-separator", "")); + listPlayer = ChatColor.translateAlternateColorCodes('&', getConfig().getString("list-player", "")); + listSortByName = getConfig().getBoolean("list-sort-by-name", true); + + ircConnCheckInterval = getConfig().getLong("conn-check-interval"); + ircChannelCheckInterval = getConfig().getLong("channel-check-interval"); + + customTabGamemode = getConfig().getString("custom-tab-gamemode", "SPECTATOR"); + customTabList = getConfig().getBoolean("custom-tab-list", false); + customTabPrefix = ChatColor.translateAlternateColorCodes('&', getConfig().getString("custom-tab-prefix", "[IRC] ")); + logDebug("custom-tab-list: " + customTabList); + logDebug("custom-tab-prefix: " + customTabPrefix); + logDebug("custom-tab-gamemode: " + customTabGamemode); + } + + private void loadBots() { + if (botsFolder.exists()) { + logInfo("Checking for bot files in " + botsFolder); + for (final File file : botsFolder.listFiles()) { + if (file.getName().toLowerCase().endsWith(".yml")) { + logInfo("Loading bot file: " + file.getName()); + ircBots.put(file.getName(), new PurpleBot(file, this)); + logInfo("Loaded bot: " + file.getName() + "[" + ircBots.get(file.getName()).botNick + "]"); + } + } + } + } + + /** + * + * @return + */ + public boolean isFactionsEnabled() { + if (getServer().getPluginManager().getPlugin("Factions") != null) { + String v = getServer().getPluginManager().getPlugin("Factions").getDescription().getVersion(); + logDebug("Factions version => " + v); + if (v.startsWith("2.")) { + return true; + } else { + logInfo("Invalid Factions version! Only version 2.0.0 and higher is supported."); + } + } + return false; + } + + public boolean isPluginEnabled(String pluginName) { + return getServer().getPluginManager().getPlugin(pluginName) != null; + } + + private void createSampleBot() { + File file = new File(pluginFolder + "/" + sampleFileName); + try { + try (InputStream in = PurpleIRC.class.getResourceAsStream("/" + sampleFileName)) { + byte[] buf = new byte[1024]; + int len; + try (OutputStream out = new FileOutputStream(file)) { + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + } + } + } catch (IOException ex) { + logError("Problem creating sample bot: " + ex.getMessage()); + } + } + + /** + * + * @param worldName + * @return + */ + public String getWorldAlias(String worldName) { + String alias = worldName; + Plugin plugin = getServer().getPluginManager().getPlugin("Multiverse-Core"); + if (plugin != null) { + MVPlugin mvPlugin = (MVPlugin) plugin; + MultiverseWorld world = mvPlugin.getCore().getMVWorldManager().getMVWorld(worldName); + if (world != null) { + alias = world.getAlias(); + } + } + if (alias == null) { + alias = worldName; + } + logDebug("getWorldAlias: worldName => " + worldName); + logDebug("getWorldAlias: alias => " + alias); + return alias; + } + + /** + * + * @param sender + */ + public void reloadMainConfig(CommandSender sender) { + sender.sendMessage(LOG_HEADER_F + " Reloading config.yml ..."); + reloadConfig(); + getConfig().options().copyDefaults(false); + loadConfig(); + sender.sendMessage(LOG_HEADER_F + " Done."); + } + + private void createConfigDirs() { + if (!pluginFolder.exists()) { + try { + logInfo("Creating " + pluginFolder.getAbsolutePath()); + pluginFolder.mkdir(); + } catch (Exception e) { + logError(e.getMessage()); + } + } + + if (!botsFolder.exists()) { + try { + logInfo("Creating " + botsFolder.getAbsolutePath()); + botsFolder.mkdir(); + } catch (Exception e) { + logError(e.getMessage()); + } + } + } + + private void createConfig() { + if (!configFile.exists()) { + try { + logInfo("Creating config.yml"); + configFile.createNewFile(); + } catch (IOException e) { + logError(e.getMessage()); + } + } + + } + + /** + * + * @param message + */ + public void logInfo(String message) { + log.log(Level.INFO, String.format("%s %s", LOG_HEADER, message)); + } + + /** + * + * @param message + */ + public void logError(String message) { + log.log(Level.SEVERE, String.format("%s %s", LOG_HEADER, message)); + } + + /** + * + * @param message + */ + public void logDebug(String message) { + if (debugEnabled) { + log.log(Level.INFO, String.format("%s [DEBUG] %s", LOG_HEADER, message)); + } + } + + /** + * + * @return + */ + public String getMCUptime() { + long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime(); + String msg = "Server uptime: " + (int) (jvmUptime / 86400000L) + " days" + + " " + (int) (jvmUptime / 3600000L % 24L) + " hours" + + " " + (int) (jvmUptime / 60000L % 60L) + " minutes" + + " " + (int) (jvmUptime / 1000L % 60L) + " seconds."; + return msg; + } + + public String getServerMotd() { + return "MOTD: " + getServer().getMotd(); + } + + /** + * + * @param ircBot + * @param channelName + * @return + */ + public String getMCPlayers(PurpleBot ircBot, String channelName) { + Map playerList = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + for (Player player : getServer().getOnlinePlayers()) { + if (ircBot.hideListWhenVanished.get(channelName)) { + logDebug("List: Checking if player " + player.getName() + " is vanished."); + if (vanishHook.isVanished(player)) { + logDebug("Not adding player to list command" + player.getName() + " due to being vanished."); + continue; + } + } + String pName = tokenizer.playerTokenizer(player, listPlayer); + playerList.put(player.getName(), pName); + } + + String pList; + if (!listSortByName) { + // sort as before + ArrayList tmp = new ArrayList<>(playerList.values()); + Collections.sort(tmp, Collator.getInstance()); + pList = Joiner.on(listSeparator).join(tmp); + } else { + // sort without nick prefixes + pList = Joiner.on(listSeparator).join(playerList.values()); + } + + String msg = listFormat + .replace("%COUNT%", Integer.toString(playerList.size())) + .replace("%MAX%", Integer.toString(getServer().getMaxPlayers())) + .replace("%PLAYERS%", pList); + logDebug("L: " + msg); + return colorConverter.gameColorsToIrc(msg); + } + + public String getRemotePlayers(String commandArgs) { + if (commandArgs != null) { + String host; + int port = 25565; + if (commandArgs.contains(":")) { + host = commandArgs.split(":")[0]; + port = Integer.parseInt(commandArgs.split(":")[1]); + } else { + host = commandArgs; + } + Query query = new Query(host, port); + try { + query.sendQuery(); + } catch (IOException ex) { + return ex.getMessage(); + } + String players[] = query.getOnlineUsernames(); + String m; + if (players.length == 0) { + m = "There are no players on " + host + + ":" + port; + } else { + m = "Players on " + host + "(" + + players.length + + "): " + Joiner.on(", ") + .join(players); + } + return m; + } else { + return "Invalid host."; + } + } + + /** + * + */ + public void setupVault() { + if (getServer().getPluginManager().getPlugin("Vault") != null) { + vaultHelpers = new VaultHook(this); + String vv = getServer().getPluginManager().getPlugin("Vault").getDescription().getVersion(); + logInfo("Hooked into Vault v" + vv); + } else { + logInfo("Not hooked into Vault!"); + } + } + + /** + * + * @param player + * @return + */ + public String getPlayerGroup(Player player) { + String groupName = ""; + if (vaultHelpers != null) { + if (vaultHelpers.permission != null) { + try { + groupName = vaultHelpers.permission.getPrimaryGroup(player); + } catch (Exception ex) { + logDebug("Problem with primary group (" + player.getName() + "): " + ex.getMessage()); + } + } + } + if (groupName == null) { + groupName = ""; + } + return ChatColor.translateAlternateColorCodes('&', groupName); + } + + /** + * + * @param player + * @return + */ + public UUID getPlayerUuid(String player) { + if (uuidCache.containsKey(player)) { + return uuidCache.get(player); + } + return null; + } + + /** + * + * @param worldName + * @param player + * @return + */ + public String getPlayerGroup(String worldName, String player) { + String groupName = ""; + UUID uuid = getPlayerUuid(player); + if (vaultHelpers != null && uuid != null) { + if (vaultHelpers.permission != null) { + OfflinePlayer offlinePlayer = getServer().getOfflinePlayer(uuid); + if (offlinePlayer != null) { + try { + groupName = vaultHelpers.permission.getPrimaryGroup(worldName, offlinePlayer); + } catch (Exception ex) { + logDebug("getPlayerGroup (" + player + "): " + ex.getMessage()); + } + } + } + } + if (groupName == null) { + groupName = ""; + } + return ChatColor.translateAlternateColorCodes('&', groupName); + } + + /** + * + * @param player + * @return + */ + public String getPlayerPrefix(Player player) { + String prefix = ""; + if (vaultHelpers != null) { + if (vaultHelpers.chat != null) { + prefix = vaultHelpers.chat.getPlayerPrefix(player); + } + } + if (prefix == null) { + prefix = ""; + } + return ChatColor.translateAlternateColorCodes('&', prefix); + } + + /** + * + * @param worldName + * @param player + * @return + */ + public String getPlayerPrefix(String worldName, String player) { + String prefix = ""; + UUID uuid = getPlayerUuid(player); + if (vaultHelpers != null && uuid != null) { + if (vaultHelpers.chat != null) { + OfflinePlayer offlinePlayer = getServer().getOfflinePlayer(uuid); + if (offlinePlayer != null) { + try { + prefix = vaultHelpers.chat.getPlayerPrefix(worldName, offlinePlayer); + } catch (Exception ex) { + logDebug("getPlayerPrefix (" + player + "): " + ex.getMessage()); + } + } + } + } + if (prefix == null) { + prefix = ""; + } + return ChatColor.translateAlternateColorCodes('&', prefix); + } + + /** + * + * @param player + * @return + */ + public String getPlayerSuffix(Player player) { + String suffix = ""; + if (vaultHelpers != null) { + if (vaultHelpers.chat != null) { + suffix = vaultHelpers.chat.getPlayerSuffix(player); + } + } + if (suffix == null) { + suffix = ""; + } + return ChatColor.translateAlternateColorCodes('&', suffix); + } + + /** + * + * @param worldName + * @param player + * @return + */ + public String getPlayerSuffix(String worldName, String player) { + String suffix = ""; + UUID uuid = getPlayerUuid(player); + if (vaultHelpers != null && uuid != null) { + if (vaultHelpers.chat != null) { + OfflinePlayer offlinePlayer = getServer().getOfflinePlayer(uuid); + if (offlinePlayer != null) { + try { + suffix = vaultHelpers.chat.getPlayerSuffix(worldName, offlinePlayer); + } catch (Exception ex) { + logDebug("getPlayerSuffix (" + player + "): " + ex.getMessage()); + } + } + } + } + if (suffix == null) { + suffix = ""; + } + return ChatColor.translateAlternateColorCodes('&', suffix); + } + + /** + * + * @param pName + * @return + */ + public String getDisplayName(String pName) { + String displayName = null; + Player player = this.getServer().getPlayer(pName); + logDebug("player: " + player); + if (player != null) { + displayName = player.getDisplayName(); + } + if (displayName != null) { + logDebug("Caching displayName for " + pName + " = " + displayName); + displayNameCache.put(pName, displayName); + } else if (displayNameCache.containsKey(pName)) { + displayName = displayNameCache.get(pName); + } else { + displayName = pName; + } + return displayName; + } + + /** + * + * @param player + */ + public void updateDisplayNameCache(Player player) { + logDebug("Caching displayName for " + player.getName() + " = " + player.getDisplayName()); + displayNameCache.put(player.getName(), player.getDisplayName()); + } + + /** + * + * @param player + * @param displayName + */ + public void updateDisplayNameCache(String player, String displayName) { + logDebug("Caching displayName for " + player + " = " + displayName); + displayNameCache.put(player, displayName); + } + + /** + * + * @param player + */ + public void updateUuidCache(Player player) { + logDebug("Caching UUID for " + player.getName() + " = " + player.getUniqueId().toString()); + uuidCache.put(player.getName(), player.getUniqueId()); + } + + /** + * + * @param player + * @param uuid + */ + public void updateUuidCache(String player, UUID uuid) { + logDebug("Caching UUID for " + player + " = " + uuid.toString()); + uuidCache.put(player, uuid); + } + + /** + * + * @param player + * @return + */ + public String getGroupPrefix(Player player) { + String prefix = ""; + if (vaultHelpers != null) { + if (vaultHelpers.chat != null) { + String group = ""; + try { + group = vaultHelpers.permission.getPrimaryGroup(player); + } catch (Exception ex) { + logDebug("getGroupPrefix (" + player.getName() + "): " + ex.getMessage()); + } + if (group == null) { + group = ""; + } + prefix = vaultHelpers.chat.getGroupPrefix(player.getLocation().getWorld(), group); + } + } + if (prefix == null) { + prefix = ""; + } + return ChatColor.translateAlternateColorCodes('&', prefix); + } + + /** + * + * @param worldName + * @param player + * @return + */ + public String getGroupPrefix(String worldName, String player) { + String prefix = ""; + if (vaultHelpers != null) { + if (vaultHelpers.chat != null) { + String group = ""; + OfflinePlayer offlinePlayer = getServer().getOfflinePlayer(player); + if (offlinePlayer != null) { + try { + group = vaultHelpers.permission.getPrimaryGroup(worldName, offlinePlayer); + } catch (Exception ex) { + logDebug("getGroupPrefix (" + player + "): " + ex.getMessage()); + } + } + if (group == null) { + group = ""; + } + prefix = vaultHelpers.chat.getGroupPrefix(worldName, group); + } + } + if (prefix == null) { + prefix = ""; + } + return ChatColor.translateAlternateColorCodes('&', prefix); + } + + /** + * + * @param worldName + * @return + */ + public String getWorldColor(String worldName) { + String color = worldName; + Plugin plugin = getServer().getPluginManager().getPlugin("Multiverse-Core"); + if (plugin != null) { + MVPlugin mvPlugin = (MVPlugin) plugin; + MultiverseWorld world = mvPlugin.getCore().getMVWorldManager().getMVWorld(worldName); + if (world != null) { + color = world.getColor().toString(); + } + } + if (color == null) { + color = worldName; + } + logDebug("getWorldColor: worldName => " + worldName); + logDebug("getWorldColor: color => " + color); + return color; + } + + /** + * + * @param player + * @return + */ + public String getGroupSuffix(Player player) { + String suffix = ""; + if (vaultHelpers != null) { + if (vaultHelpers.chat != null) { + String group = ""; + try { + group = vaultHelpers.permission.getPrimaryGroup(player); + } catch (Exception ex) { + logDebug("Problem with primary group (" + player.getName() + "): " + ex.getMessage()); + } + if (group == null) { + group = ""; + } + suffix = vaultHelpers.chat.getGroupSuffix(player.getLocation().getWorld(), group); + } + } + if (suffix == null) { + suffix = ""; + } + return ChatColor.translateAlternateColorCodes('&', suffix); + } + + /** + * + * @param worldName + * @param player + * @return + */ + public String getGroupSuffix(String worldName, String player) { + String suffix = ""; + if (vaultHelpers != null) { + if (vaultHelpers.chat != null) { + String group = ""; + try { + group = vaultHelpers.permission.getPrimaryGroup(worldName, player); + } catch (Exception ex) { + logDebug("Problem with primary group (" + player + "): " + ex.getMessage()); + } + if (group == null) { + group = ""; + } + suffix = vaultHelpers.chat.getGroupSuffix(worldName, group); + } + } + if (suffix == null) { + suffix = ""; + } + return ChatColor.translateAlternateColorCodes('&', suffix); + } + + /** + * + * @return + */ + public boolean checkForProtocolLib() { + return (getServer().getPluginManager().getPlugin("ProtocolLib") != null); + } + + public boolean isPrismEnabled() { + return (getServer().getPluginManager().getPlugin("Prism") != null); + } + + public void saveDisplayNameCache() { + BufferedWriter writer; + try { + writer = new BufferedWriter(new FileWriter(cacheFile)); + } catch (IOException ex) { + logError(ex.getMessage()); + return; + } + + try { + for (String s : displayNameCache.keySet()) { + logDebug("Saving to displayName.cache: " + s + "\t" + displayNameCache.get(s)); + writer.write(s + "\t" + displayNameCache.get(s) + "\n"); + } + writer.close(); + } catch (IOException ex) { + logError(ex.getMessage()); + } + } + + public void loadDisplayNameCache() { + try { + try (BufferedReader in = new BufferedReader(new FileReader(cacheFile))) { + String line; + while ((line = in.readLine()) != null) { + if (line.equals("\n")) { + continue; + } + String[] parts = line.split("\t", 2); + updateDisplayNameCache(parts[0], parts[1]); + } + } + } catch (IOException | NumberFormatException e) { + logError(e.getMessage()); + } + } + + public void saveUuidCache() { + BufferedWriter writer; + try { + writer = new BufferedWriter(new FileWriter(uuidCacheFile)); + } catch (IOException ex) { + logError(ex.getMessage()); + return; + } + + try { + for (String s : uuidCache.keySet()) { + logDebug("Saving to uuid.cache: " + s + "\t" + uuidCache.get(s).toString()); + writer.write(s + "\t" + uuidCache.get(s).toString() + "\n"); + } + writer.close(); + } catch (IOException ex) { + logError(ex.getMessage()); + } + } + + public void loadUuidCache() { + try { + try (BufferedReader in = new BufferedReader(new FileReader(uuidCacheFile))) { + String line; + while ((line = in.readLine()) != null) { + if (line.equals("\n")) { + continue; + } + String[] parts = line.split("\t", 2); + updateUuidCache(parts[0], UUID.fromString(parts[1])); + } + } + } catch (IOException | NumberFormatException e) { + logError(e.getMessage()); + } + } + + public String getPlayerHost(Player player) { + final String playerIP = player.getAddress().getAddress().getHostAddress(); + if (hostCache.containsKey(playerIP)) { + return hostCache.get(playerIP); + } else { + getServer().getScheduler().runTaskLaterAsynchronously(this, new Runnable() { + @Override + public void run() { + long a = System.currentTimeMillis(); + InetAddress addr = null; + try { + addr = InetAddress.getByName(playerIP); + } catch (UnknownHostException ex) { + logError(ex.getMessage()); + } + String host; + if (addr != null) { + host = addr.getHostName(); + } else { + host = playerIP; + } + hostCache.put(playerIP, host); + logDebug("getPlayerHost[" + (System.currentTimeMillis() - a) + "ms] " + playerIP + " = " + host); + } + }, 0); + return playerIP; + } + } + + public void clearHostCache(final Player player) { + String playerIP = player.getAddress().getAddress().getHostAddress(); + if (hostCache.containsKey(playerIP)) { + hostCache.remove(playerIP); + } + } + + public String botify(String bot) { + if (bot.toLowerCase().endsWith("yml")) { + return bot; + } else { + return bot + ".yml"; + } + } + + public boolean isUpdateCheckerEnabled() { + return updateCheckerEnabled; + } + + public String updateCheckerMode() { + return updateCheckerMode; + } + +} diff --git a/src/main/java/com/cnaude/purpleirc/PurpleTabCompleter.java b/src/main/java/com/cnaude/purpleirc/PurpleTabCompleter.java new file mode 100755 index 0000000..cc0c188 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/PurpleTabCompleter.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +import java.util.ArrayList; +import java.util.List; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.pircbotx.Channel; +import org.pircbotx.User; + +/** + * + * @author cnaude + */ +public class PurpleTabCompleter implements TabCompleter { + + private final PurpleIRC plugin; + + /** + * + * @param plugin + */ + public PurpleTabCompleter(final PurpleIRC plugin) { + this.plugin = plugin; + } + + @Override + public List onTabComplete(CommandSender cs, Command cmnd, String string, String[] strings) { + + List list = new ArrayList<>(); + + plugin.logDebug("S: " + string); + for (String s : strings) { + plugin.logDebug("S1: " + s); + } + if (strings.length == 1) { + for (String c : plugin.commandHandlers.sortedCommands) { + if (cs.hasPermission("irc." + c)) { + if (c.startsWith(strings[0])) { + list.add(c); + } + } + } + } + + if (strings.length == 2) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + for (Channel channel : ircBot.getChannels()) { + for (User user : channel.getUsers()) { + if (user.getNick().startsWith(strings[1])) { + list.add(user.getNick()); + } + } + } + } + for (Player player : plugin.getServer().getOnlinePlayers()) { + if (plugin.vanishHook != null) { + if (plugin.vanishHook.isVanished(player)) { + continue; + } + } + if (player.getDisplayName().startsWith(strings[1])) { + list.add(player.getDisplayName()); + } + } + } + + return list; + } + +} diff --git a/src/main/java/com/cnaude/purpleirc/TemplateName.java b/src/main/java/com/cnaude/purpleirc/TemplateName.java new file mode 100644 index 0000000..a70d991 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/TemplateName.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc; + +/** + * + * @author cnaude + */ +public class TemplateName { + public final static String GAME_ACHIEVEMENT = "game-achievement"; + public final static String GAME_ACTION = "game-action"; + public final static String GAME_AFK = "game-afk"; + public final static String GAME_CHAT = "game-chat"; + public final static String GAME_PCHAT = "game-pchat"; + public final static String GAME_PCHAT_RESPONSE = "game-pchat-response"; + public final static String GAME_SEND = "game-send"; + public final static String GAME_DEATH = "game-death"; + public final static String GAME_JOIN = "game-join"; + public final static String GAME_QUIT = "game-quit"; + public final static String GAME_KICK = "game-kick"; + public final static String GAME_COMMAND = "game-command"; + public final static String GAME_MODE = "game-mode"; + + public final static String DYNMAP_WEB_CHAT = "dynmap-web-chat"; + public final static String IRC_DYNMAP_WEB_CHAT = "irc-dynmap-web-chat"; + public final static String IRC_ACTION_DYNMAP_WEB_CHAT = "irc-action-dynmap-web-chat"; + + public final static String CLEVER_SEND = "clever-send"; + + public final static String MCMMO_ADMIN_CHAT = "mcmmo-admin-chat"; + public final static String MCMMO_PARTY_CHAT = "mcmmo-party-chat"; + public final static String MCMMO_CHAT = "mcmmo-chat"; + + public final static String HERO_ACTION = "hero-action"; + public final static String HERO_CHAT = "hero-chat"; + + public final static String IRC_HERO_ACTION = "irc-hero-action"; + public final static String IRC_HERO_CHAT = "irc-hero-chat"; + public final static String IRC_HERO_KICK = "irc-hero-kick"; + public final static String IRC_HERO_JOIN = "irc-hero-join"; + public final static String IRC_HERO_PART = "irc-hero-part"; + public final static String IRC_HERO_QUIT = "irc-hero-quit"; + public final static String IRC_HERO_TOPIC = "irc-hero-topic"; + public final static String IRC_ESS_HELPOP = "irc-ess-helpop"; + + public final static String IRC_HERO_CHANNELS = "irc-hero-channels"; + public final static String HERO_CHANNELS = "hero-channels"; + public final static String IRC_ACTION_CHANNELS = "irc-action-channels"; + + public final static String TITAN_CHAT = "titan-chat"; + public final static String IRC_TITAN_CHAT = "irc-titan-chat"; + + public final static String TOWNY_CHAT = "towny-chat"; + public final static String IRC_TOWNY_CHAT = "irc-towny-chat"; + + public final static String FACTION_PUBLIC_CHAT = "faction-public-chat"; + public final static String FACTION_ALLY_CHAT = "faction-ally-chat"; + public final static String FACTION_ENEMY_CHAT = "faction-enemy-chat"; + + public final static String CONSOLE_CHAT = "console-chat"; + + public final static String IRC_ACTION = "irc-action"; + public final static String IRC_CHAT = "irc-chat"; + public final static String IRC_HCHAT_RESPONSE = "irc-hchat-response"; + public final static String IRC_PCHAT = "irc-pchat"; + public final static String IRC_PCHAT_RESPONSE = "irc-pchat-response"; + public final static String IRC_CHAT_RESPONSE = "irc-chat-response"; + public final static String IRC_KICK = "irc-kick"; + public final static String IRC_JOIN = "irc-join"; + public final static String IRC_PART = "irc-part"; + public final static String IRC_QUIT = "irc-quit"; + public final static String IRC_TOPIC = "irc-topic"; + public final static String IRC_NICK_CHANGE = "irc-nickchange"; + public final static String IRC_MODE = "irc-mode"; + public final static String IRC_NOTICE = "irc-notice"; + public final static String IRC_CONSOLE_CHAT = "irc-console-chat"; + + public final static String ESS_PLAYER_AFK = "ess-player-afk"; + public final static String ESS_PLAYER_NOT_AFK = "ess-player-not-afk"; + public final static String ESS_HELPOP = "ess-helpop"; + + public final static String VALID_IRC_COMMANDS = "valid-irc-commands"; + public final static String INVALID_IRC_COMMAND = "invalid-irc-command"; + public final static String NO_PERM_FOR_IRC_COMMAND = "no-perm-for-irc-command"; + + public final static String BROADCAST_MESSAGE = "broadcast-message"; + public final static String BROADCAST_CONSOLE_MESSAGE = "broadcast-console-message"; + + public final static String RTS_SEND = "rts-notify"; + public final static String RTS_COMPLETE = "rts-complete"; + public final static String RTS_CLAIM = "rts-claim"; + public final static String RTS_UNCLAIM = "rts-unclaim"; + public final static String RTS_HELD = "rts-held"; + public final static String RTS_ASSIGN = "rts-assign"; + public final static String RTS_REOPEN = "rts-reopen"; + public final static String RTS_MOD_BROADCAST = "rts-modbroadcast"; + + public final static String JOBS_SEPARATOR = "jobs-separator"; + + /* http://dev.bukkit.org/bukkit-plugins/death-messages */ + public final static String DEATH_MESSAGES = "death-messages"; + + public final static String ORE_BROADCAST = "ore-broadcast"; + + public final static String PRISM_ROLLBACK = "prism-rollback"; + public final static String PRISM_DRAIN = "prism-drain"; + public final static String PRISM_EXTINGUISH = "prism-extinguish"; + public final static String PRISM_CUSTOM = "prism-custom"; + + public final static String REDDIT_MESSAGES = "reddit-messages"; + + public final static String IRC_A_RESPONSE = "irc-a-response"; + public final static String GAME_A_CHAT = "game-a-chat"; + +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/BotsAndChannels.java b/src/main/java/com/cnaude/purpleirc/Utilities/BotsAndChannels.java new file mode 100644 index 0000000..3c7e91a --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/BotsAndChannels.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Utilities; + +import com.cnaude.purpleirc.PurpleIRC; +import java.util.ArrayList; +import org.bukkit.command.CommandSender; + +/** + * + * @author cnaude + */ +public class BotsAndChannels { + + public ArrayList bot = new ArrayList<>(); + public ArrayList channel = new ArrayList<>(); + + public BotsAndChannels(PurpleIRC plugin, CommandSender sender, String botName, String channelName) { + if (plugin.ircBots.containsKey(botName)) { + bot.add(botName); + if (plugin.ircBots.get(botName).isValidChannel(channelName)) { + channel.add(channelName); + } else { + sender.sendMessage(plugin.invalidChannelName.replace("%CHANNEL%", channelName)); + } + } else { + sender.sendMessage(plugin.invalidBotName.replace("%BOT%", botName)); + } + } + + public BotsAndChannels(PurpleIRC plugin, CommandSender sender) { + for (String botName : plugin.ircBots.keySet()) { + bot.add(botName); + for (String channelName : plugin.ircBots.get(botName).botChannels) { + channel.add(channelName); + } + } + } + +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/CaseInsensitiveMap.java b/src/main/java/com/cnaude/purpleirc/Utilities/CaseInsensitiveMap.java new file mode 100644 index 0000000..0e79e00 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/CaseInsensitiveMap.java @@ -0,0 +1,464 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 VMware Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VMware Inc. - initial contribution + *******************************************************************************/ + +// http://underlap.blogspot.com/2009/04/caseinsensitivemapv.html + +package com.cnaude.purpleirc.Utilities; + +import java.util.AbstractMap; +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * {@link CaseInsensitiveMap} is a {@link Map} from String keys to values which is case-insensitive and + * case-preserving with respect to the keys in the map. + *

+ * + * Concurrent Semantics
+ * + * This class is not necessarily thread safe. + * + * @param range type parameter + */ +public class CaseInsensitiveMap extends AbstractMap { + + private final Map map = new ConcurrentHashMap(); + + private static final class KeySet extends AbstractSet { + + private static final class KeySetIterator implements Iterator { + + private final Iterator iterator; + + public KeySetIterator(Iterator iterator) { + this.iterator = iterator; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean hasNext() { + return this.iterator.hasNext(); + } + + /** + * {@inheritDoc} + */ + @Override + public String next() { + return this.iterator.next().toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public void remove() { + this.iterator.remove(); + } + } + + private final Set keySet; + + public KeySet(Set keySet) { + this.keySet = keySet; + } + + /** + * Not supported for sets returned by Map.keySet. + */ + @Override + public boolean add(String o) { + throw new UnsupportedOperationException("Map.keySet must return a Set which does not support add"); + } + + /** + * Not supported for sets returned by Map.keySet. + */ + @Override + public boolean addAll(Collection c) { + throw new UnsupportedOperationException("Map.keySet must return a Set which does not support addAll"); + } + + /** + * {@inheritDoc} + */ + @Override + public void clear() { + this.keySet.clear(); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean contains(Object o) { + return o instanceof String ? this.keySet.contains(CaseInsensitiveKey.objectToKey(o)) : false; + } + + /** + * {@inheritDoc} + */ + @Override + public Iterator iterator() { + return new KeySetIterator(this.keySet.iterator()); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean remove(Object o) { + // The following can throw ClassCastException which conforms to the method specification. + return this.keySet.remove(CaseInsensitiveKey.objectToKey(o)); + } + + /** + * {@inheritDoc} + */ + @Override + public int size() { + return this.keySet.size(); + } + + } + + private static final class EntrySet extends AbstractSet> { + + private static final class MapEntry implements Entry { + + private final Entry entry; + + public MapEntry(Entry entry) { + this.entry = entry; + } + + /** + * {@inheritDoc} + */ + @Override + public String getKey() { + return this.entry.getKey().toString(); + } + + /** + * {@inheritDoc} + */ + @Override + public V getValue() { + return this.entry.getValue(); + } + + /** + * {@inheritDoc} + */ + @Override + public V setValue(V value) { + return this.entry.setValue(value); + } + + /** + * Get the underlying {@link Map.Entry}. + * + * @return the underlying Entry + */ + public Entry getEntry() { + return this.entry; + } + } + + private static final class EntrySetIterator implements Iterator> { + + private final Iterator> iterator; + + public EntrySetIterator(Iterator> iterator) { + this.iterator = iterator; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean hasNext() { + return this.iterator.hasNext(); + } + + /** + * {@inheritDoc} + */ + @Override + public Entry next() { + return new MapEntry(this.iterator.next()); + } + + /** + * {@inheritDoc} + */ + @Override + public void remove() { + this.iterator.remove(); + } + } + + private final Set> entrySet; + + private final CaseInsensitiveMap map; + + public EntrySet(Set> entrySet, CaseInsensitiveMap map) { + this.entrySet = entrySet; + this.map = map; + } + + /** + * Not supported for sets returned by Map.entrySet. + */ + @Override + public boolean add(Entry o) { + throw new UnsupportedOperationException("Map.entrySet must return a Set which does not support add"); + } + + /** + * Not supported for sets returned by Map.entrySet. + */ + @Override + public boolean addAll(Collection> c) { + throw new UnsupportedOperationException("Map.entrySet must return a Set which does not support addAll"); + } + + /** + * {@inheritDoc} + */ + @Override + public void clear() { + this.entrySet.clear(); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + @Override + public boolean contains(Object o) { + if (o instanceof Entry) { + Entry e = (Entry) o; + V value = this.map.get(e.getKey()); + return value.equals(e.getValue()); + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public Iterator> iterator() { + return new EntrySetIterator(this.entrySet.iterator()); + } + + /** + * {@inheritDoc} + */ + @SuppressWarnings("unchecked") + @Override + public boolean remove(Object o) { + try { + return this.entrySet.remove(((MapEntry) o).getEntry()); + } catch (ClassCastException e) { + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public int size() { + return this.entrySet.size(); + } + + } + + static final class CaseInsensitiveKey { + + private final String key; + + private CaseInsensitiveKey(String key) { + this.key = key; + } + + /** + * {@inheritDoc} + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + key.toLowerCase().hashCode(); + return result; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + CaseInsensitiveKey other = (CaseInsensitiveKey) obj; + if (key == null) { + if (other.key != null) { + return false; + } + } else if (!key.equalsIgnoreCase(other.key)) { + return false; + } + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return key; + } + + /** + * Convert the given key Object to a {@link CaseInsensitiveKey}. + *

+ * Pre-condition: key instanceof String + * + * @param key the key to be converted + * @return the CaseInsensitiveKey corresponding to the given key + */ + public static CaseInsensitiveKey objectToKey(Object key) { + return new CaseInsensitiveKey((String) key); + } + + } + + public CaseInsensitiveMap() { + } + + public CaseInsensitiveMap(CaseInsensitiveMap map) { + this.map.putAll(map.map); + } + /** + * {@inheritDoc} + */ + @Override + public void clear() { + this.map.clear(); + } + + /** + * {@inheritDoc} + * @param key + * @return + */ + @Override + public boolean containsKey(Object key) { + return key instanceof String ? this.map.containsKey(CaseInsensitiveKey.objectToKey(key)) : false; + } + + /** + * {@inheritDoc} + * @param value + * @return + */ + @Override + public boolean containsValue(Object value) { + return this.map.containsValue(value); + } + + /** + * {@inheritDoc} + * @return + */ + @Override + public Set> entrySet() { + return new EntrySet(this.map.entrySet(), this); + } + + /** + * {@inheritDoc} + * @param key + * @return + */ + @Override + public V get(Object key) { + return key instanceof String ? this.map.get(CaseInsensitiveKey.objectToKey(key)) : null; + } + + /** + * {@inheritDoc} + * @return + */ + @Override + public Set keySet() { + return new KeySet(this.map.keySet()); + } + + /** + * {@inheritDoc} + * @param key + * @param value + * @return + */ + @Override + public V put(String key, V value) { + if (key == null) { + throw new NullPointerException("CaseInsensitiveMap does not permit null keys"); + } + return this.map.put(CaseInsensitiveKey.objectToKey(key), value); + } + + /** + * {@inheritDoc} + * @param key + * @return + */ + @Override + public V remove(Object key) { + return key instanceof String ? this.map.remove(CaseInsensitiveKey.objectToKey(key)) : null; + } + + /** + * {@inheritDoc} + * @return + */ + @Override + public int size() { + return this.map.size(); + } + + /** + * {@inheritDoc} + * @return + */ + @Override + public Collection values() { + return this.map.values(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/ChatTokenizer.java b/src/main/java/com/cnaude/purpleirc/Utilities/ChatTokenizer.java new file mode 100644 index 0000000..7a7ebf2 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/ChatTokenizer.java @@ -0,0 +1,722 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Utilities; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.dthielke.herochat.ChannelManager; +import com.gmail.nossr50.util.player.UserManager; +import com.nyancraft.reportrts.data.Ticket; +import com.palmergames.bukkit.TownyChat.channels.Channel; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.pircbotx.User; + +/** + * Main class containing all message template token expanding methods + * + * @author cnaude + */ +public class ChatTokenizer { + + PurpleIRC plugin; + + /** + * Class initializer + * + * @param plugin + */ + public ChatTokenizer(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * IRC to game chat tokenizer without a message + * + * @param ircBot + * @param user + * @param channel + * @param template + * @return + */ + public String chatIRCTokenizer(PurpleBot ircBot, User user, org.pircbotx.Channel channel, String template) { + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) + .replace("%CHANNEL%", channel.getName())); + } + + public String ircUserTokenizer(String template, User user) { + String host = user.getHostmask(); + String server = user.getServer(); + String away = user.getAwayMessage(); + String ircNick = user.getNick(); + if (host == null) { + host = ""; + } + if (server == null) { + server = ""; + } + if (away == null) { + away = ""; + } + return template.replace("%HOST%", host) + .replace("%NAME%", ircNick) + .replace("%SERVER%", server) + .replace("%AWAY%", away); + } + + public String ircUserTokenizer(String template, User recipient, User kicker) { + String host = kicker.getHostmask(); + String server = kicker.getServer(); + String away = kicker.getAwayMessage(); + String ircNick = kicker.getNick(); + if (host == null) { + host = ""; + } + if (server == null) { + server = ""; + } + if (away == null) { + away = ""; + } + return ircUserTokenizer(template, recipient) + .replace("%KICKERHOST%", host) + .replace("%KICKER%", ircNick) + .replace("%KICKERSERVER%", server) + .replace("%KICKERAWAY%", away); + } + + /** + * IRC to Hero chat tokenizer without a message + * + * @param ircBot + * @param user + * @param channel + * @param template + * @param channelManager + * @param hChannel + * @return + */ + public String ircChatToHeroChatTokenizer(PurpleBot ircBot, User user, org.pircbotx.Channel channel, String template, ChannelManager channelManager, String hChannel) { + String ircNick = user.getNick(); + String tmpl; + Player player = this.getPlayer(ircNick); + if (player != null) { + plugin.logDebug("ircChatToHeroChatTokenizer: player not null "); + tmpl = playerTokenizer(player, template); + } else { + tmpl = playerTokenizer(ircNick, template); + } + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + .replace("%HEROCHANNEL%", hChannel) + .replace("%HERONICK%", channelManager.getChannel(hChannel).getNick()) + .replace("%HEROCOLOR%", channelManager.getChannel(hChannel).getColor().toString()) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * Normal IRC to game chat tokenizer + * + * @param ircBot + * @param user + * @param channel + * @param template + * @param message + * @return + */ + public String ircChatToGameTokenizer(PurpleBot ircBot, User user, org.pircbotx.Channel channel, String template, String message) { + String ircNick = user.getNick(); + String tmpl; + Player player = this.getPlayer(ircNick); + if (player != null) { + tmpl = playerTokenizer(player, template); + } else { + plugin.logDebug("ircChatToGameTokenizer: null player: " + ircNick); + tmpl = playerTokenizer(ircNick, template); + } + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) + .replace("%MESSAGE%", message) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * IRC to Hero chat channel tokenizer + * + * @param ircBot + * @param user + * @param channel + * @param template + * @param message + * @param channelManager + * @param hChannel + * @return + */ + public String ircChatToHeroChatTokenizer(PurpleBot ircBot, User user, org.pircbotx.Channel channel, String template, String message, ChannelManager channelManager, String hChannel) { + String ircNick = user.getNick(); + String tmpl; + Player player = this.getPlayer(ircNick); + if (player != null) { + tmpl = playerTokenizer(player, template); + } else { + tmpl = playerTokenizer(ircNick, template); + } + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + .replace("%HEROCHANNEL%", hChannel) + .replace("%HERONICK%", channelManager.getChannel(hChannel).getNick()) + .replace("%HEROCOLOR%", channelManager.getChannel(hChannel).getColor().toString()) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) + .replace("%MESSAGE%", message) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * IRC to Hero chat channel tokenizer + * + * @param ircBot + * @param user + * @param channel + * @param template + * @param message + * @param tChannel + * @return + */ + public String ircChatToTownyChatTokenizer(PurpleBot ircBot, User user, org.pircbotx.Channel channel, String template, String message, String tChannel) { + String ircNick = user.getNick(); + String tmpl; + Player player = this.getPlayer(ircNick); + if (player != null) { + tmpl = playerTokenizer(player, template); + } else { + tmpl = playerTokenizer(ircNick, template); + } + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + .replace("%TOWNYCHANNEL%", tChannel) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) + .replace("%MESSAGE%", message) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * IRC kick message to game + * + * @param ircBot + * @param recipient + * @param kicker + * @param reason + * @param channel + * @param template + * @return + */ + public String ircKickTokenizer(PurpleBot ircBot, User recipient, User kicker, String reason, org.pircbotx.Channel channel, String template) { + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, recipient, kicker) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(kicker, channel)) + .replace("%REASON%", reason) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * IRC to hero kick message + * + * @param ircBot + * @param recipient + * @param kicker + * @param reason + * @param channel + * @param template + * @param channelManager + * @param hChannel + * @return + */ + public String ircKickToHeroChatTokenizer(PurpleBot ircBot, User recipient, User kicker, String reason, org.pircbotx.Channel channel, String template, ChannelManager channelManager, String hChannel) { + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, recipient, kicker) + .replace("%HEROCHANNEL%", hChannel) + .replace("%HERONICK%", channelManager.getChannel(hChannel).getNick()) + .replace("%HEROCOLOR%", channelManager.getChannel(hChannel).getColor().toString()) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(kicker, channel)) + .replace("%REASON%", reason) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * IRC mode change messages + * + * @param ircBot + * @param user + * @param mode + * @param channel + * @param template + * @return + */ + public String ircModeTokenizer(PurpleBot ircBot, User user, String mode, org.pircbotx.Channel channel, String template) { + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user) + .replace("%MODE%", mode) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * IRC notice change messages + * + * @param ircBot + * @param user + * @param message + * @param notice + * @param channel + * @param template + * @return + */ + public String ircNoticeTokenizer(PurpleBot ircBot, User user, String message, String notice, org.pircbotx.Channel channel, String template) { + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user) + .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) + .replace("%MESSAGE%", message) + .replace("%NOTICE%", notice) + .replace("%CHANNEL%", channel.getName())); + } + + /** + * Game chat to IRC + * + * @param pName + * @param template + * + * @param message + * @return + */ + public String gameChatToIRCTokenizer(String pName, String template, String message) { + return plugin.colorConverter.gameColorsToIrc(template + .replace("%NAME%", pName) + .replace("%MESSAGE%", plugin.colorConverter.gameColorsToIrc(message))); + } + + /** + * Game chat to IRC + * + * @param player + * @param template + * + * @param message + * @return + */ + public String gameChatToIRCTokenizer(Player player, String template, String message) { + if (message == null) { + message = ""; + } + return plugin.colorConverter.gameColorsToIrc(playerTokenizer(player, template).replace("%MESSAGE%", message)); + } + + /** + * Game chat to IRC + * + * @param source + * @param name + * @param template + * @param message + * @return + */ + public String dynmapWebChatToIRCTokenizer(String source, String name, + String template, String message) { + if (message == null) { + message = ""; + } + + return plugin.colorConverter.gameColorsToIrc( + playerTokenizer(name, template) + .replace("%SOURCE%", source) + .replace("%MESSAGE%", message)); + } + + /** + * Game player AFK to IRC + * + * @param player + * @param template + * + * @return + */ + public String gamePlayerAFKTokenizer(Player player, String template) { + return plugin.colorConverter.gameColorsToIrc(playerTokenizer(player, template)); + } + + /** + * mcMMO chat to IRC + * + * @param player + * @param template + * + * @param message + * @param partyName + * @return + */ + public String mcMMOPartyChatToIRCTokenizer(Player player, String template, String message, String partyName) { + return mcMMOChatToIRCTokenizer(player, template, message) + .replace("%PARTY%", partyName); + } + + /** + * mcMMO chat to IRC + * + * @param player + * @param template + * @param message + * @return + */ + public String mcMMOChatToIRCTokenizer(Player player, String template, String message) { + int powerLevel = UserManager.getPlayer(player).getPowerLevel(); + return gameChatToIRCTokenizer(player, template, message) + .replace("%POWERLEVEL%", Integer.toString(powerLevel)); + } + + /** + * FactionChat to IRC + * + * @param player + * @param botNick + * @param message + * @param chatTag + * @param chatMode + * @return + */ + public String chatFactionTokenizer(Player player, String botNick, String message, String chatTag, String chatMode) { + String template; + switch (chatMode) { + case "public": + template = plugin.getMsgTemplate(botNick, "faction-public-chat"); + break; + case "ally": + template = plugin.getMsgTemplate(botNick, "faction-ally-chat"); + break; + case "enemy": + template = plugin.getMsgTemplate(botNick, "faction-enemy-chat"); + break; + default: + return ""; + } + return plugin.colorConverter.gameColorsToIrc( + gameChatToIRCTokenizer(player, template, message) + .replace("%FACTIONTAG%", chatTag) + .replace("%FACTIONMODE%", chatMode)); + } + + /** + * Herochat to IRC + * + * @param player + * @param message + * @param hColor + * @param hChannel + * @param hNick + * @param template + * @return + */ + public String chatHeroTokenizer(Player player, String message, String hColor, String hChannel, String hNick, String template) { + return gameChatToIRCTokenizer(player, template, message) + .replace("%HEROCHANNEL%", hChannel) + .replace("%HERONICK%", hNick) + .replace("%HEROCOLOR%", plugin.colorConverter.gameColorsToIrc(hColor)) + .replace("%CHANNEL%", hChannel); + } + + public String chatTownyChannelTokenizer(Player player, Channel townyChannel, String message, String template) { + + return gameChatToIRCTokenizer(player, template, message) + .replace("%TOWNYCHANNEL%", ChatColor.translateAlternateColorCodes('&', townyChannel.getName())) + .replace("%TOWNYCHANNELTAG%", ChatColor.translateAlternateColorCodes('&', townyChannel.getChannelTag())) + .replace("%TOWNYMSGCOLOR%", ChatColor.translateAlternateColorCodes('&', townyChannel.getMessageColour())); + } + + /** + * TitanChat to IRC + * + * @param player + * @param tChannel + * @param tColor + * @param message + * @param template + * @return + */ + public String titanChatTokenizer(Player player, String tChannel, String tColor, String message, String template) { + return gameChatToIRCTokenizer(player, template, message) + .replace("%TITANCHANNEL%", tChannel) + .replace("%TITANCOLOR%", plugin.colorConverter.gameColorsToIrc(tColor)) + .replace("%CHANNEL%", tChannel); + } + + /** + * Game chat to IRC + * + * @param template + * @param message + * @return + */ + public String gameChatToIRCTokenizer(String template, String message) { + return plugin.colorConverter.gameColorsToIrc(template + .replace("%MESSAGE%", message)); + } + + /** + * Game kick message to IRC + * + * @param player + * @param template + * @param reason + * @param message + * @return + */ + public String gameKickTokenizer(Player player, String template, String message, String reason) { + return plugin.colorConverter.gameColorsToIrc( + gameChatToIRCTokenizer(player, template, message) + .replace("%MESSAGE%", message) + .replace("%REASON%", reason)); + } + + /** + * ReportRTS notifications to IRC + * + * @param pName + * @param template + * @param ticket + * @return + */ + public String reportRTSTokenizer(String pName, String template, Ticket ticket) { + String message = ticket.getMessage(); + String modName = ticket.getModName(); + String displayModName = ""; + String name = ticket.getName(); + String world = ticket.getWorld(); + String modComment = ticket.getModComment(); + int id = ticket.getId(); + if (message == null) { + message = ""; + } + if (modName == null) { + modName = ""; + } else { + Player player = this.getPlayer(modName); + if (player != null) { + displayModName = player.getDisplayName(); + } else { + displayModName = modName; + } + } + if (name == null) { + name = ""; + } + if (world == null) { + world = ""; + } + if (modComment == null) { + modComment = ""; + } + return plugin.colorConverter.gameColorsToIrc(playerTokenizer(pName, template) + .replace("%MESSAGE%", message) + .replace("%MODNAME%", modName) + .replace("%DISPLAYMODNAME%", displayModName) + .replace("%MODCOMMENT%", modComment) + .replace("%TICKETNUMBER%", String.valueOf(id)) + .replace("%RTSNAME%", name) + .replace("%RTSWORLD%", world)); + } + + public String reportRTSTokenizer(CommandSender sender, String message, String template) { + return gameChatToIRCTokenizer(sender.getName(), template, message); + } + + public String playerTokenizer(Player player, String message) { + String pName = player.getName(); + plugin.logDebug("Tokenizing " + pName + "(O: " + player.isOnline() + ")"); + String pSuffix = plugin.getPlayerSuffix(player); + String pPrefix = plugin.getPlayerPrefix(player); + String gPrefix = plugin.getGroupPrefix(player); + String gSuffix = plugin.getGroupSuffix(player); + String group = plugin.getPlayerGroup(player); + String displayName = player.getDisplayName(); + String playerIP = player.getAddress().getAddress().getHostAddress(); + String host = plugin.getPlayerHost(player); + String worldName = ""; + String worldAlias = ""; + String worldColor = ""; + String jobShort = ""; + String job = ""; + if (pSuffix == null) { + pSuffix = ""; + } + if (pPrefix == null) { + pPrefix = ""; + } + if (gSuffix == null) { + gSuffix = ""; + } + if (gPrefix == null) { + gPrefix = ""; + } + if (group == null) { + group = ""; + } + if (playerIP == null) { + playerIP = ""; + } + if (displayName == null) { + displayName = ""; + } + if (player.getWorld() != null) { + worldName = player.getWorld().getName(); + worldAlias = plugin.getWorldAlias(worldName); + worldColor = plugin.getWorldColor(worldName); + } + if (plugin.jobsHook != null) { + job = plugin.jobsHook.getPlayerJob(player, false); + jobShort = plugin.jobsHook.getPlayerJob(player, true); + } + if (plugin.jobsHookOld != null) { + job = plugin.jobsHookOld.getPlayerJob(player, false); + jobShort = plugin.jobsHookOld.getPlayerJob(player, true); + } + plugin.logDebug("[P]Raw message: " + message); + return message.replace("%DISPLAYNAME%", displayName) + .replace("%JOBS%", job) + .replace("%JOBSSHORT%", jobShort) + .replace("%NAME%", pName) + .replace("%PLAYERIP%", playerIP) + .replace("%HOST%", host) + .replace("%GROUP%", group) + .replace("%PLAYERPREFIX%", pPrefix) + .replace("%PLAYERSUFFIX%", pSuffix) + .replace("%GROUPPREFIX%", gPrefix) + .replace("%GROUPSUFFIX%", gSuffix) + .replace("%WORLDALIAS%", worldAlias) + .replace("%WORLDCOLOR%", worldColor) + .replace("%WORLD%", worldName); + } + + private String playerTokenizer(String playerName, String message) { + plugin.logDebug("Tokenizing " + playerName); + String worldName = plugin.defaultPlayerWorld; + plugin.logDebug("playerTokenizer: 1 "); + String pSuffix = plugin.getPlayerSuffix(worldName, playerName); + plugin.logDebug("playerTokenizer: 2 "); + String pPrefix = plugin.getPlayerPrefix(worldName, playerName); + plugin.logDebug("playerTokenizer: 3 "); + String gPrefix = plugin.getGroupPrefix(worldName, playerName); + plugin.logDebug("playerTokenizer: 4 "); + String gSuffix = plugin.getGroupSuffix(worldName, playerName); + plugin.logDebug("playerTokenizer: 5 "); + String group = plugin.getPlayerGroup(worldName, playerName); + plugin.logDebug("playerTokenizer: 6 "); + String displayName = plugin.getDisplayName(playerName); + plugin.logDebug("playerTokenizer: 7 "); + String worldAlias = ""; + String worldColor = ""; + String jobShort = ""; + String job = ""; + plugin.logDebug("playerTokenizer: 8 "); + if (!worldName.isEmpty()) { + worldAlias = plugin.getWorldAlias(worldName); + worldColor = plugin.getWorldColor(worldName); + } + plugin.logDebug("playerTokenizer: 9 "); + if (pSuffix == null) { + pSuffix = plugin.defaultPlayerSuffix; + } + plugin.logDebug("playerTokenizer: 10 "); + if (pPrefix == null) { + pPrefix = plugin.defaultPlayerPrefix; + } + plugin.logDebug("playerTokenizer: 11 "); + if (gSuffix == null) { + gSuffix = plugin.defaultGroupSuffix; + } + plugin.logDebug("playerTokenizer: 12 "); + if (gPrefix == null) { + gPrefix = plugin.defaultGroupPrefix; + } + plugin.logDebug("playerTokenizer: 13 "); + if (group == null) { + group = plugin.defaultPlayerGroup; + } + plugin.logDebug("playerTokenizer: 14 "); + Player player = getPlayer(playerName); + if (player != null) { + if (plugin.jobsHook != null) { + job = plugin.jobsHook.getPlayerJob(player, false); + jobShort = plugin.jobsHook.getPlayerJob(player, true); + } + } + plugin.logDebug("playerTokenizer: 15 "); + if (player != null) { + if (plugin.jobsHookOld != null) { + job = plugin.jobsHookOld.getPlayerJob(player, false); + jobShort = plugin.jobsHookOld.getPlayerJob(player, true); + } + } + plugin.logDebug("[S]Raw message: " + message); + return message.replace("%DISPLAYNAME%", displayName) + .replace("%JOBS%", job) + .replace("%JOBSSHORT%", jobShort) + .replace("%NAME%", playerName) + .replace("%GROUP%", group) + .replace("%PLAYERPREFIX%", pPrefix) + .replace("%PLAYERSUFFIX%", pSuffix) + .replace("%GROUPSUFFIX%", gSuffix) + .replace("%GROUPPREFIX%", gPrefix) + .replace("%WORLDALIAS%", worldAlias) + .replace("%WORLDCOLOR%", worldColor) + .replace("%WORLD%", worldName); + } + + private Player getPlayer(String name) { + Player player; + if (plugin.exactNickMatch) { + plugin.logDebug("Checking for exact player matching " + name); + player = plugin.getServer().getPlayerExact(name); + } else { + plugin.logDebug("Checking for player matching " + name); + player = plugin.getServer().getPlayer(name); + } + return player; + } + + /** + * + * @param player + * @param template + * @param cmd + * @param params + * @return + */ + public String gameCommandToIRCTokenizer(Player player, String template, String cmd, String params) { + return plugin.colorConverter.gameColorsToIrc(playerTokenizer(player, template) + .replace("%COMMAND%", cmd) + .replace("%PARAMS%", params)); + } + + public String targetChatResponseTokenizer(String target, String message, String template) { + return plugin.colorConverter.gameColorsToIrc(template + .replace("%TARGET%", target) + .replace("%MESSAGE%", message) + ); + } + + public String msgChatResponseTokenizer(String target, String message, String template) { + return plugin.colorConverter.ircColorsToGame(template + .replace("%TARGET%", target) + .replace("%MESSAGE%", message) + ); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/ColorConverter.java b/src/main/java/com/cnaude/purpleirc/Utilities/ColorConverter.java new file mode 100644 index 0000000..f848dfe --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/ColorConverter.java @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Utilities; + +import com.cnaude.purpleirc.PurpleIRC; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.bukkit.ChatColor; +import org.pircbotx.Colors; + +/** + * + * @author cnaude + */ +public class ColorConverter { + + PurpleIRC plugin; + private final boolean stripGameColors; + private final boolean stripIRCColors; + private final boolean stripIRCBackgroundColors; + private final EnumMap ircColorMap = new EnumMap<>(ChatColor.class); + private final HashMap gameColorMap = new HashMap<>(); + private final Pattern bgColorPattern; + private final Pattern singleDigitColorPattern; + private final Pattern colorHack; + + /** + * + * @param plugin + * @param stripGameColors + * @param stripIRCColors + * @param stripIRCBackgroundColors + */ + public ColorConverter(PurpleIRC plugin, boolean stripGameColors, boolean stripIRCColors, boolean stripIRCBackgroundColors) { + this.stripGameColors = stripGameColors; + this.stripIRCColors = stripIRCColors; + this.stripIRCBackgroundColors = stripIRCBackgroundColors; + this.plugin = plugin; + buildDefaultColorMaps(); + this.bgColorPattern = Pattern.compile("((\\u0003\\d+),\\d+)"); + this.singleDigitColorPattern = Pattern.compile("((\\u0003)(\\d))\\D+"); + this.colorHack = Pattern.compile("((\\u0003\\d+)(,\\d+))\\D"); + } + + /** + * + * @param message + * @return + */ + public String gameColorsToIrc(String message) { + if (stripGameColors) { + return ChatColor.stripColor(message); + } else { + String newMessage = message; + for (ChatColor gameColor : ircColorMap.keySet()) { + newMessage = newMessage.replace(gameColor.toString(), ircColorMap.get(gameColor)); + } + // We return the message with the remaining MC color codes stripped out + return ChatColor.stripColor(newMessage); + } + } + + /** + * + * @param message + * @return + */ + public String ircColorsToGame(String message) { + Matcher matcher; + if (stripIRCBackgroundColors) { + matcher = bgColorPattern.matcher(message); + while (matcher.find()) { + plugin.logDebug("Strip bg color: " + matcher.group(1) + " => " + matcher.group(2)); + message = message.replace(matcher.group(1), matcher.group(2)); + } + } + matcher = singleDigitColorPattern.matcher(message); + while (matcher.find()) { + plugin.logDebug("Single to double: " + matcher.group(3) + " => " + + matcher.group(2) + "0" + matcher.group(3)); + // replace \u0003N with \u00030N + message = message.replace(matcher.group(1), matcher.group(2) + "0" + matcher.group(3)); + } + matcher = colorHack.matcher(message); + while (matcher.find()) { + plugin.logDebug("Silly IRC colors: " + matcher.group(1) + " => " + + matcher.group(2)); + // replace \u0003N,N with \u00030N + message = message.replace(matcher.group(1), matcher.group(2)); + } + + if (stripIRCColors) { + return Colors.removeFormattingAndColors(message); + } else { + String newMessage = message; + for (String ircColor : gameColorMap.keySet()) { + newMessage = newMessage.replace(ircColor, gameColorMap.get(ircColor).toString()); + } + // We return the message with the remaining IRC color codes stripped out + return Colors.removeFormattingAndColors(newMessage); + } + } + + public void addIrcColorMap(String gameColor, String ircColor) { + ChatColor chatColor; + try { + chatColor = ChatColor.valueOf(gameColor.toUpperCase()); + if (ircColor.equalsIgnoreCase("strip") && ircColorMap.containsKey(chatColor)) { + plugin.logDebug("addIrcColorMap: " + ircColor + " => " + gameColor); + ircColorMap.remove(chatColor); + return; + } + } catch (Exception ex) { + plugin.logError("Invalid game color: " + gameColor); + return; + } + if (chatColor != null) { + plugin.logDebug("addIrcColorMap: " + gameColor + " => " + ircColor); + ircColorMap.put(chatColor, getIrcColor(ircColor)); + } + } + + public void addGameColorMap(String ircColor, String gameColor) { + if (gameColor.equalsIgnoreCase("strip") && gameColorMap.containsKey(getIrcColor(ircColor))) { + plugin.logDebug("addGameColorMap: " + ircColor + " => " + gameColor); + gameColorMap.remove(getIrcColor(ircColor)); + return; + } + ChatColor chatColor; + try { + chatColor = ChatColor.valueOf(gameColor.toUpperCase()); + } catch (Exception ex) { + plugin.logError("Invalid game color: " + gameColor); + return; + } + plugin.logDebug("addGameColorMap: " + ircColor + " => " + gameColor); + gameColorMap.put(getIrcColor(ircColor), chatColor); + } + + private String getIrcColor(String ircColor) { + String s = ""; + try { + s = (String) Colors.class.getField(ircColor.toUpperCase()).get(null); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { + plugin.logError(ex.getMessage()); + } + if (s.isEmpty()) { + plugin.logError("Invalid IRC color: " + ircColor); + } + return s; + } + + private void buildDefaultColorMaps() { + ircColorMap.put(ChatColor.AQUA, Colors.CYAN); + ircColorMap.put(ChatColor.BLACK, Colors.BLACK); + ircColorMap.put(ChatColor.BLUE, Colors.BLUE); + ircColorMap.put(ChatColor.BOLD, Colors.BOLD); + ircColorMap.put(ChatColor.DARK_AQUA, Colors.TEAL); + ircColorMap.put(ChatColor.DARK_BLUE, Colors.DARK_BLUE); + ircColorMap.put(ChatColor.DARK_GRAY, Colors.DARK_GRAY); + ircColorMap.put(ChatColor.DARK_GREEN, Colors.DARK_GREEN); + ircColorMap.put(ChatColor.DARK_PURPLE, Colors.PURPLE); + ircColorMap.put(ChatColor.DARK_RED, Colors.RED); + ircColorMap.put(ChatColor.GOLD, Colors.OLIVE); + ircColorMap.put(ChatColor.GRAY, Colors.LIGHT_GRAY); + ircColorMap.put(ChatColor.GREEN, Colors.GREEN); + ircColorMap.put(ChatColor.LIGHT_PURPLE, Colors.MAGENTA); + ircColorMap.put(ChatColor.RED, Colors.RED); + ircColorMap.put(ChatColor.UNDERLINE, Colors.UNDERLINE); + ircColorMap.put(ChatColor.YELLOW, Colors.YELLOW); + ircColorMap.put(ChatColor.WHITE, Colors.WHITE); + ircColorMap.put(ChatColor.RESET, Colors.NORMAL); + + gameColorMap.put(Colors.BLACK, ChatColor.BLACK); + gameColorMap.put(Colors.BLUE, ChatColor.BLUE); + gameColorMap.put(Colors.BOLD, ChatColor.BOLD); + gameColorMap.put(Colors.BROWN, ChatColor.GRAY); + gameColorMap.put(Colors.CYAN, ChatColor.AQUA); + gameColorMap.put(Colors.DARK_BLUE, ChatColor.DARK_BLUE); + gameColorMap.put(Colors.DARK_GRAY, ChatColor.DARK_GRAY); + gameColorMap.put(Colors.DARK_GREEN, ChatColor.DARK_GREEN); + gameColorMap.put(Colors.GREEN, ChatColor.GREEN); + gameColorMap.put(Colors.LIGHT_GRAY, ChatColor.GRAY); + gameColorMap.put(Colors.MAGENTA, ChatColor.LIGHT_PURPLE); + gameColorMap.put(Colors.NORMAL, ChatColor.RESET); + gameColorMap.put(Colors.OLIVE, ChatColor.GOLD); + gameColorMap.put(Colors.PURPLE, ChatColor.DARK_PURPLE); + gameColorMap.put(Colors.RED, ChatColor.RED); + gameColorMap.put(Colors.TEAL, ChatColor.DARK_AQUA); + gameColorMap.put(Colors.UNDERLINE, ChatColor.UNDERLINE); + gameColorMap.put(Colors.WHITE, ChatColor.WHITE); + gameColorMap.put(Colors.YELLOW, ChatColor.YELLOW); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/IRCMessageHandler.java b/src/main/java/com/cnaude/purpleirc/Utilities/IRCMessageHandler.java new file mode 100644 index 0000000..8c9a3bf --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/IRCMessageHandler.java @@ -0,0 +1,295 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Utilities; + +import com.cnaude.purpleirc.IRCCommand; +import com.cnaude.purpleirc.IRCCommandSender; +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.cnaude.purpleirc.TemplateName; +import com.google.common.base.Joiner; +import java.text.Collator; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.bukkit.entity.Player; +import org.pircbotx.Channel; +import org.pircbotx.User; + +/** + * + * @author cnaude + */ +public class IRCMessageHandler { + + PurpleIRC plugin; + + /** + * + * @param plugin + */ + public IRCMessageHandler(PurpleIRC plugin) { + this.plugin = plugin; + } + + /** + * + * @param ircBot + * @param user + * @param channel + * @param message + * @param privateMessage + */ + public void processMessage(PurpleBot ircBot, User user, Channel channel, String message, boolean privateMessage) { + plugin.logDebug("processMessage: " + message); + String myChannel = channel.getName(); + if (ircBot.muteList.get(myChannel).contains(user.getNick())) { + plugin.logDebug("User is muted. Ignoring message from " + user.getNick() + ": " + message); + return; + } + if (message.startsWith(ircBot.commandPrefix) && (!message.startsWith(ircBot.commandPrefix + ircBot.commandPrefix))) { + String command = message.split(" ")[0].substring(ircBot.commandPrefix.length()); + + String commandArgs = null; + if (message.contains(" ")) { + commandArgs = message.split(" ", 2)[1]; + } + plugin.logDebug("IRC command detected: " + command); + + plugin.logDebug(message); + String target = channel.getName(); + if (ircBot.commandMap.get(myChannel).containsKey(command)) { + boolean privateListen = Boolean.parseBoolean(ircBot.commandMap + .get(myChannel).get(command).get("private_listen")); + boolean channelListen = Boolean.parseBoolean(ircBot.commandMap + .get(myChannel).get(command).get("channel_listen")); + plugin.logDebug("privateListen: " + privateListen); + plugin.logDebug("channelListen: " + channelListen); + if (privateMessage && !privateListen) { + plugin.logDebug("This is a private message but privateListen is false. Ignoring..."); + return; + } + if (!privateMessage && !channelListen) { + plugin.logDebug("This is a channel message but channelListen is false. Ignoring..."); + return; + } + + String gc = (String) ircBot.commandMap.get(myChannel).get(command).get("game_command"); + List extraCommands = ircBot.extraCommandMap.get(myChannel).get(command); + List gameCommands = new ArrayList<>(); + gameCommands.add(gc); + gameCommands.addAll(extraCommands); + String modes = (String) ircBot.commandMap.get(myChannel).get(command).get("modes"); + String perm = (String) ircBot.commandMap.get(myChannel).get(command).get("perm"); + boolean privateCommand = Boolean.parseBoolean(ircBot.commandMap.get(myChannel).get(command).get("private")); + boolean ctcpResponse = Boolean.parseBoolean(ircBot.commandMap.get(myChannel).get(command).get("ctcp")); + + if (privateCommand || privateMessage) { + target = user.getNick(); + } + + plugin.logDebug("Target: " + target); + + if (isValidMode(modes, user, channel) && checkPerm(perm, user.getNick())) { + for (String gameCommand : gameCommands) { + switch (gameCommand) { + case "@list": + sendMessage(ircBot, target, plugin.getMCPlayers(ircBot, myChannel), ctcpResponse); + break; + case "@uptime": + sendMessage(ircBot, target, plugin.getMCUptime(), ctcpResponse); + break; + case "@help": + sendMessage(ircBot, target, getCommands(ircBot.commandMap, myChannel), ctcpResponse); + break; + case "@chat": + ircBot.broadcastChat(user, channel, target, commandArgs, false, ctcpResponse); + break; + case "@ochat": + ircBot.broadcastChat(user, channel, target, commandArgs, true, ctcpResponse); + break; + case "@hchat": + ircBot.broadcastHeroChat(user, channel, target, commandArgs); + break; + case "@motd": + sendMessage(ircBot, target, plugin.getServerMotd(), ctcpResponse); + break; + case "@version": + sendMessage(ircBot, target, plugin.getServer().getVersion(), ctcpResponse); + break; + case "@versionfull": + String v = "This server is running " + + plugin.getServer().getName() + + " version " + + plugin.getServer().getVersion() + + " (Implementing API version " + + plugin.getServer().getBukkitVersion() + ")"; + sendMessage(ircBot, target, v, ctcpResponse); + break; + case "@bukkit": + sendMessage(ircBot, target, plugin.getServer().getBukkitVersion(), ctcpResponse); + break; + case "@rtsmb": + if (plugin.reportRTSHook != null) { + plugin.reportRTSHook.modBroadcast(user.getNick(), commandArgs); + } + break; + case "@msg": + ircBot.playerChat(user, channel, target, commandArgs); + break; + case "@clearqueue": + sendMessage(ircBot, target, plugin.commandQueue.clearQueue(), ctcpResponse); + sendMessage(ircBot, target, ircBot.messageQueue.clearQueue(), ctcpResponse); + break; + case "@query": + sendMessage(ircBot, target, plugin.getRemotePlayers(commandArgs), ctcpResponse); + break; + case "@a": + if (plugin.adminPrivateChatHook != null) { + plugin.adminPrivateChatHook.sendMessage(commandArgs, user.getNick()); + String acResponse = plugin.tokenizer.msgChatResponseTokenizer(target, commandArgs, plugin.getMsgTemplate(TemplateName.IRC_A_RESPONSE)); + if (!acResponse.isEmpty()) { + sendMessage(ircBot, target, acResponse, ctcpResponse); + } + } + break; + default: + if (commandArgs == null) { + commandArgs = ""; + } + if (gameCommand.contains("%ARGS%")) { + gameCommand = gameCommand.replace("%ARGS%", commandArgs); + } + if (gameCommand.contains("%NAME%")) { + gameCommand = gameCommand.replace("%NAME%", user.getNick()); + } + plugin.logDebug("GM: \"" + gameCommand.trim() + "\""); + try { + plugin.commandQueue.add(new IRCCommand(new IRCCommandSender(ircBot, target, plugin, ctcpResponse), gameCommand.trim())); + } catch (Exception ex) { + plugin.logError(ex.getMessage()); + } + break; + } + } + } else { + plugin.logDebug("User '" + user.getNick() + "' mode not okay."); + ircBot.asyncIRCMessage(target, plugin.getMsgTemplate( + ircBot.botNick, TemplateName.NO_PERM_FOR_IRC_COMMAND) + .replace("%NICK%", user.getNick()) + .replace("%CMDPREFIX%", ircBot.commandPrefix)); + } + } else { + if (privateMessage || ircBot.invalidCommandPrivate.get(myChannel)) { + target = user.getNick(); + } + plugin.logDebug("Invalid command: " + command); + String invalidIrcCommand = plugin.getMsgTemplate( + ircBot.botNick, TemplateName.INVALID_IRC_COMMAND) + .replace("%NICK%", user.getNick()) + .replace("%CMDPREFIX%", ircBot.commandPrefix); + if (!invalidIrcCommand.isEmpty()) { + if (ircBot.invalidCommandCTCP.get(myChannel)) { + ircBot.blockingCTCPMessage(target, invalidIrcCommand); + } else { + ircBot.asyncIRCMessage(target, invalidIrcCommand); + } + } + if (ircBot.enabledMessages.get(myChannel).contains(TemplateName.INVALID_IRC_COMMAND)) { + plugin.logDebug("Invalid IRC command dispatched for broadcast..."); + ircBot.broadcastChat(user, channel, null, message, false, false); + } + } + } else { + if (ircBot.ignoreIRCChat.get(myChannel)) { + plugin.logDebug("Message NOT dispatched for broadcast due to \"ignore-irc-chat\" being true ..."); + return; + } + if (privateMessage && !ircBot.relayPrivateChat) { + plugin.logDebug("Message NOT dispatched for broadcast due to \"relay-private-chat\" being false and this is a private message ..."); + return; + } + plugin.logDebug("Message dispatched for broadcast..."); + ircBot.broadcastChat(user, channel, null, message, false, false); + } + } + + private boolean isValidMode(String modes, User user, Channel channel) { + boolean modeOkay = false; + if (modes.equals("*")) { + return true; + } + if (modes.contains("i") && !modeOkay) { + modeOkay = user.isIrcop(); + } + if (modes.contains("o") && !modeOkay) { + modeOkay = user.getChannelsOpIn().contains(channel); + } + if (modes.contains("v") && !modeOkay) { + modeOkay = user.getChannelsVoiceIn().contains(channel); + } + if (modes.contains("h") && !modeOkay) { + modeOkay = user.getChannelsHalfOpIn().contains(channel); + } + if (modes.contains("q") && !modeOkay) { + modeOkay = user.getChannelsOwnerIn().contains(channel); + } + if (modes.contains("s") && !modeOkay) { + modeOkay = user.getChannelsSuperOpIn().contains(channel); + } + return modeOkay; + } + + private void sendMessage(PurpleBot ircBot, String target, String message, boolean ctcpResponse) { + if (ctcpResponse) { + plugin.logDebug("Sending message to target: " + target + " => " + message); + ircBot.asyncCTCPMessage(target, message); + } else { + plugin.logDebug("Sending message to target: " + target + " => " + message); + ircBot.asyncIRCMessage(target, message); + } + } + + private String getCommands(CaseInsensitiveMap>> commandMap, String myChannel) { + if (commandMap.containsKey(myChannel)) { + List sortedCommands = new ArrayList<>(); + for (String command : commandMap.get(myChannel).keySet()) { + sortedCommands.add(command); + } + Collections.sort(sortedCommands, Collator.getInstance()); + String cmds = Joiner.on(", ").join(sortedCommands); + String msg = plugin.getMsgTemplate(TemplateName.VALID_IRC_COMMANDS).replace("%COMMANDS%", cmds); + return msg; + } + return ""; + } + + private boolean checkPerm(String perm, String playerName) { + if (perm.isEmpty()) { + return true; + } + Player player = plugin.getServer().getPlayer(playerName); + + if (player != null) { + plugin.logDebug("[checkPerm] Player " + playerName + " permission node " + perm + "=" + player.hasPermission(perm)); + return player.hasPermission(perm); + } else { + plugin.logDebug("[checkPerm] Player not online: " + playerName); + return false; + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/NetPackets.java b/src/main/java/com/cnaude/purpleirc/Utilities/NetPackets.java new file mode 100644 index 0000000..c36ec2d --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/NetPackets.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Utilities; + +import com.cnaude.purpleirc.PurpleBot; +import com.cnaude.purpleirc.PurpleIRC; +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.Packets; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.injector.PacketConstructor; +import com.comphenix.protocol.reflect.FieldAccessException; +import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; +import com.comphenix.protocol.wrappers.PlayerInfoData; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.google.common.base.Charsets; +import com.mojang.authlib.GameProfile; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.UUID; +import org.bukkit.entity.Player; +import org.pircbotx.Channel; +import org.pircbotx.User; + +/** + * + * @author cnaude + */ +public class NetPackets { + + PurpleIRC plugin; + private final ProtocolManager protocolManager; + private PacketConstructor playerListConstructor; + + /** + * + * @param plugin + */ + public NetPackets(PurpleIRC plugin) { + this.plugin = plugin; + protocolManager = ProtocolLibrary.getProtocolManager(); + } + + /** + * + * @param name + * @param ircBot + * @param channel + */ + public void addToTabList(String name, PurpleBot ircBot, Channel channel) { + if (!plugin.customTabList) { + return; + } + String channelName = channel.getName(); + if (ircBot.tabIgnoreNicks.containsKey(channelName)) { + if (ircBot.tabIgnoreNicks.get(channelName).contains(name)) { + plugin.logDebug("Not adding " + name + " to tab list."); + return; + } + } + try { + PacketContainer packet = tabPacket(name, true); + if (packet != null) { + for (Player reciever : plugin.getServer().getOnlinePlayers()) { + if (reciever.hasPermission("irc.tablist")) { + protocolManager.sendServerPacket(reciever, packet); + } + } + } + } catch (FieldAccessException | InvocationTargetException e) { + plugin.logError(e.getMessage()); + } + } + + /** + * + * @param name + */ + public void remFromTabList(String name) { + if (!plugin.customTabList) { + return; + } + try { + PacketContainer packet = tabPacket(name, false); + if (packet != null) { + for (Player reciever : plugin.getServer().getOnlinePlayers()) { + if (reciever.hasPermission("irc.tablist")) { + protocolManager.sendServerPacket(reciever, packet); + } + } + } + } catch (FieldAccessException | InvocationTargetException e) { + plugin.logError(e.getMessage()); + } + } + + private PacketContainer tabPacket(String name, boolean add) { + String displayName = truncateName(plugin.customTabPrefix + name); + PacketContainer packet = null; + String version = plugin.getServer().getVersion(); + if (version.contains("MC: 1.7.10")) { + try { + packet = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO); + packet.getIntegers().write(0, (add ? 0 : 4)); + packet.getGameProfiles().write(0, new WrappedGameProfile(java.util.UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), displayName)); + packet.getIntegers().write(1, 0); + packet.getIntegers().write(2, 0); + packet.getStrings().write(0, displayName); + } catch (Exception ex) { + plugin.logError("tabPacket: " + ex.getMessage()); + } + } else if (version.contains("MC: 1.8")) { + try { + UUID uuid = null; // = plugin.getPlayerUuid(name); + if (uuid == null) { + uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + displayName).getBytes(Charsets.UTF_8)); + } + if (add) { + packet = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO); + + PlayerInfoData pid = new PlayerInfoData( + new WrappedGameProfile(uuid, displayName), + 0, + NativeGameMode.valueOf(plugin.customTabGamemode.toUpperCase()), + WrappedChatComponent.fromJson("{\"text\": \"" + displayName + "\"}")); + packet.getPlayerInfoDataLists().write(0, Arrays.asList(pid)); + } else { + plugin.logDebug("T: Removing: " + name); + net.minecraft.server.v1_8_R1.EntityPlayer pl = new net.minecraft.server.v1_8_R1.EntityPlayer( + net.minecraft.server.v1_8_R1.MinecraftServer.getServer(), + net.minecraft.server.v1_8_R1.MinecraftServer.getServer().getWorldServer(0), + (GameProfile) (new WrappedGameProfile(uuid, displayName)).getHandle(), + new net.minecraft.server.v1_8_R1.PlayerInteractManager(net.minecraft.server.v1_8_R1.MinecraftServer.getServer().getWorldServer(0)) + ); + net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo pi = new net.minecraft.server.v1_8_R1.PacketPlayOutPlayerInfo(net.minecraft.server.v1_8_R1.EnumPlayerInfoAction.REMOVE_PLAYER, pl); + return PacketContainer.fromPacket(pi); + + } + return packet; + } catch (Exception ex) { + plugin.logError("tabPacket: " + ex.getMessage()); + } + } else { + plugin.logDebug("tabPacket: deprecated "); + playerListConstructor = protocolManager.createPacketConstructor(Packets.Server.PLAYER_INFO, "", false, (int) 0); + packet = playerListConstructor.createPacket(displayName, add, 0); + } + return packet; + } + + /** + * + * @param player + * @param ircBot + * @param channel + */ + public void updateTabList(Player player, final PurpleBot ircBot, final Channel channel) { + plugin.getServer().getScheduler().runTaskLater(plugin, new Runnable() { + @Override + public void run() { + for (User user : channel.getUsers()) { + String nick = user.getNick(); + addToTabList(nick, ircBot, channel); + } + } + }, 5); + + } + + /** + * + * @param player + */ + public void updateTabList(Player player) { + if (player.hasPermission("irc.tablist")) { + for (PurpleBot ircBot : plugin.ircBots.values()) { + if (ircBot.isConnected()) { + for (Channel channel : ircBot.getChannels()) { + if (ircBot.isValidChannel(channel.getName())) { + updateTabList(player, ircBot, channel); + } + } + } + } + } + } + + private String truncateName(String name) { + if (name.length() > 16) { + return name.substring(0, 15); + } else { + return name; + } + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/Query.java b/src/main/java/com/cnaude/purpleirc/Utilities/Query.java new file mode 100644 index 0000000..ab5a075 --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/Query.java @@ -0,0 +1,231 @@ +/* + * https://github.com/ryanshawty/MCJQuery + * + */ +package com.cnaude.purpleirc.Utilities; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Send a query to a given minecraft server and store any metadata and the + * player list. + * + * @author Ryan Shaw, Jonas Konrad + */ +public class Query { + + /** + * The target address and port + */ + private InetSocketAddress address; + /** + * null if no successful request has been sent, otherwise a Map + * containing any metadata received except the player list + */ + private Map values; + /** + * null if no successful request has been sent, otherwise an + * array containing all online player usernames + */ + private String[] onlineUsernames; + + /** + * Convenience constructor + * + * @see Query#Query(InetSocketAddress) + * @param host The target host + * @param port The target port + */ + public Query(String host, int port) { + this(new InetSocketAddress(host, port)); + } + + /** + * Create a new instance of this class + * + * @param address The servers IP-address + */ + public Query(InetSocketAddress address) { + this.address = address; + } + + /** + * Try pinging the server and then sending the query + * + * @see Query#pingServer() + * @see Query#sendQueryRequest() + * @throws IOException If the server cannot be pinged + */ + public void sendQuery() throws IOException { + sendQueryRequest(); + } + + /** + * Try pinging the server + * + * @return true if the server can be reached within 1.5 second + */ + public boolean pingServer() { + // try pinging the given server + try { + final Socket socket = new Socket(); + socket.connect(address, 1500); + socket.close(); + return true; + } catch (IOException e) { + } + return false; + } + + /** + * Get the additional values if the Query has been sent + * + * @return The data + * @throws IllegalStateException if the query has not been sent yet or there + * has been an error + */ + public Map getValues() { + if (values == null) { + throw new IllegalStateException("Query has not been sent yet!"); + } else { + return values; + } + } + + /** + * Get the online usernames if the Query has been sent + * + * @return The username array + * @throws IllegalStateException if the query has not been sent yet or there + * has been an error + */ + public String[] getOnlineUsernames() { + if (onlineUsernames == null) { + throw new IllegalStateException("Query has not been sent yet!"); + } else { + return onlineUsernames; + } + } + + /** + * Request the UDP query + * + * @throws IOException if anything goes wrong during the request + */ + private void sendQueryRequest() throws IOException { + final DatagramSocket socket = new DatagramSocket(); + try { + final byte[] receiveData = new byte[10240]; + socket.setSoTimeout(2000); + sendPacket(socket, address, 0xFE, 0xFD, 0x09, 0x01, 0x01, 0x01, 0x01); + final int challengeInteger; + { + receivePacket(socket, receiveData); + byte byte1; + int i = 0; + byte[] buffer = new byte[8]; + for (int count = 5; (byte1 = receiveData[count++]) != 0;) { + buffer[i++] = byte1; + } + challengeInteger = Integer.parseInt(new String(buffer).trim()); + } + sendPacket(socket, address, 0xFE, 0xFD, 0x00, 0x01, 0x01, 0x01, 0x01, + challengeInteger >> 24, challengeInteger >> 16, + challengeInteger >> 8, challengeInteger, 0x00, 0x00, 0x00, 0x00); + + final int length = receivePacket(socket, receiveData).getLength(); + values = new HashMap(); + final AtomicInteger cursor = new AtomicInteger(5); + while (cursor.get() < length) { + final String s = readString(receiveData, cursor); + if (s.isEmpty()) { + break; + } else { + final String v = readString(receiveData, cursor); + values.put(s, v); + } + } + readString(receiveData, cursor); + final Set players = new HashSet(); + while (cursor.get() < length) { + final String name = readString(receiveData, cursor); + if (name.length() > 0) { + players.add(name); + } + } + onlineUsernames = players.toArray(new String[players.size()]); + } finally { + socket.close(); + } + } + + /** + * Helper method to send a datagram packet + * + * @param socket The connection the packet should be sent through + * @param targetAddress The target IP + * @param data The byte data to be sent + * @throws IOException + */ + private static void sendPacket(DatagramSocket socket, InetSocketAddress targetAddress, byte... data) throws IOException { + DatagramPacket sendPacket = new DatagramPacket(data, data.length, targetAddress.getAddress(), targetAddress.getPort()); + socket.send(sendPacket); + } + + /** + * Helper method to send a datagram packet + * + * @see Query#sendPacket(DatagramSocket, InetSocketAddress, byte...) + * @param socket The connection the packet should be sent through + * @param targetAddress The target IP + * @param data The byte data to be sent, will be cast to bytes + * @throws IOException + */ + private static void sendPacket(DatagramSocket socket, InetSocketAddress targetAddress, int... data) throws IOException { + final byte[] d = new byte[data.length]; + int i = 0; + for (int j : data) { + d[i++] = (byte) (j & 0xff); + } + sendPacket(socket, targetAddress, d); + } + + /** + * Receive a packet from the given socket + * + * @param socket the socket + * @param buffer the buffer for the information to be written into + * @return the entire packet + * @throws IOException + */ + private static DatagramPacket receivePacket(DatagramSocket socket, byte[] buffer) throws IOException { + final DatagramPacket dp = new DatagramPacket(buffer, buffer.length); + socket.receive(dp); + return dp; + } + + /** + * Read a String until 0x00 + * + * @param array The byte array + * @param cursor The mutable cursor (will be increased) + * @return The string + */ + private static String readString(byte[] array, AtomicInteger cursor) { + final int startPosition = cursor.incrementAndGet(); + while (cursor.get() < array.length && array[cursor.get()] != 0) { + cursor.incrementAndGet(); + } + return new String(Arrays.copyOfRange(array, startPosition, cursor.get())); + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/RegexGlobber.java b/src/main/java/com/cnaude/purpleirc/Utilities/RegexGlobber.java new file mode 100644 index 0000000..1ecb15f --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/RegexGlobber.java @@ -0,0 +1,38 @@ +package com.cnaude.purpleirc.Utilities; + +/** http://stackoverflow.com/questions/1247772/is-there-an-equivalent-of-java-util-regex-for-glob-type-patterns + * + * @author cnaude + */ +public class RegexGlobber { + + /** + * + * @param glob + * @return + */ + public String createRegexFromGlob(String glob) { + String out = "^"; + for (int i = 0; i < glob.length(); ++i) { + final char c = glob.charAt(i); + switch (c) { + case '*': + out += ".*"; + break; + case '?': + out += '.'; + break; + case '.': + out += "\\."; + break; + case '\\': + out += "\\\\"; + break; + default: + out += c; + } + } + out += '$'; + return out; + } +} diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/UpdateChecker.java b/src/main/java/com/cnaude/purpleirc/Utilities/UpdateChecker.java new file mode 100755 index 0000000..b74418c --- /dev/null +++ b/src/main/java/com/cnaude/purpleirc/Utilities/UpdateChecker.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2014 cnaude + * + * 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 . + */ +package com.cnaude.purpleirc.Utilities; + +import com.cnaude.purpleirc.PurpleIRC; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import org.bukkit.command.CommandSender; +import org.bukkit.scheduler.BukkitTask; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +/** + * + * @author cnaude + */ +public class UpdateChecker { + + PurpleIRC plugin; + + private BukkitTask bt; + private int newBuild = 0; + private int currentBuild = 0; + private String currentVersion = ""; + private String newVersion = ""; + + /** + * + * @param plugin + */ + public UpdateChecker(PurpleIRC plugin) { + this.plugin = plugin; + currentVersion = plugin.getDescription().getVersion(); + try { + currentBuild = Integer.valueOf(currentVersion.split("-")[1]); + } catch (NumberFormatException e) { + currentBuild = 0; + } + startUpdateChecker(); + } + + private void startUpdateChecker() { + bt = this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() { + @Override + public void run() { + if (plugin.isUpdateCheckerEnabled()) { + plugin.logInfo("Checking for " + plugin.updateCheckerMode() + " updates ... "); + updateCheck(plugin.getServer().getConsoleSender(), plugin.updateCheckerMode()); + } + } + }, 0, 432000); + } + + public void asyncUpdateCheck(final CommandSender sender, final String mode) { + plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() { + @Override + public void run() { + if (plugin.isUpdateCheckerEnabled()) { + updateCheck(sender, mode); + } + } + }, 0); + } + + private void updateCheck(CommandSender sender, String mode) { + if (mode.equalsIgnoreCase("stable")) { + try { + URL url = new URL("https://api.curseforge.com/servermods/files?projectids=56773"); + URLConnection conn = url.openConnection(); + conn.setReadTimeout(5000); + conn.addRequestProperty("User-Agent", "PurpleIRC Update Checker"); + conn.setDoOutput(true); + final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + final String response = reader.readLine(); + final JSONArray array = (JSONArray) JSONValue.parse(response); + if (array.size() == 0) { + plugin.logInfo("No files found, or Feed URL is bad."); + return; + } + newVersion = ((String) ((JSONObject) array.get(array.size() - 1)).get("name")).trim(); + plugin.logDebug("newVersionTitle: " + newVersion); + newBuild = Integer.valueOf(newVersion.split("-")[1]); + if (newBuild > currentBuild) { + sender.sendMessage(plugin.LOG_HEADER_F + " Stable version: " + newVersion + " is out!" + " You are still running version: " + currentVersion); + sender.sendMessage(plugin.LOG_HEADER_F + " Update at: http://dev.bukkit.org/server-mods/purpleirc"); + } else if (currentBuild > newBuild) { + sender.sendMessage(plugin.LOG_HEADER_F + " Stable version: " + newVersion + " | Current Version: " + currentVersion); + } else { + sender.sendMessage(plugin.LOG_HEADER_F + " No new version available"); + } + } catch (IOException | NumberFormatException e) { + sender.sendMessage(plugin.LOG_HEADER_F + " Error checking for latest version: " + e.getMessage()); + } + } else { + try { + URL url = new URL("http://h.cnaude.org:8081/job/PurpleIRC/lastStableBuild/api/json"); + URLConnection conn = url.openConnection(); + conn.setReadTimeout(5000); + conn.addRequestProperty("User-Agent", "PurpleIRC Update Checker"); + conn.setDoOutput(true); + final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + final String response = reader.readLine(); + final JSONObject obj = (JSONObject) JSONValue.parse(response); + if (obj.isEmpty()) { + sender.sendMessage(plugin.LOG_HEADER_F + " No files found, or Feed URL is bad."); + return; + } + + newVersion = obj.get("number").toString(); + String downloadUrl = obj.get("url").toString(); + plugin.logDebug("newVersionTitle: " + newVersion); + newBuild = Integer.valueOf(newVersion); + if (newBuild > currentBuild) { + sender.sendMessage(plugin.LOG_HEADER_F + " Latest dev build: " + newVersion + " is out!" + " You are still running build: " + currentVersion); + sender.sendMessage(plugin.LOG_HEADER_F + " Update at: " + downloadUrl); + } else if (currentBuild > newBuild) { + sender.sendMessage(plugin.LOG_HEADER_F + " Dev build: " + newVersion + " | Current build: " + currentVersion); + } else { + sender.sendMessage(plugin.LOG_HEADER_F + " No new version available"); + } + } catch (IOException | NumberFormatException e) { + sender.sendMessage(plugin.LOG_HEADER_F + " Error checking for latest dev build: " + e.getMessage()); + } + } + } + + public void cancel() { + bt.cancel(); + } +} diff --git a/src/main/resources/SampleBot.yml b/src/main/resources/SampleBot.yml new file mode 100644 index 0000000..4edaf62 --- /dev/null +++ b/src/main/resources/SampleBot.yml @@ -0,0 +1,341 @@ +# Sample PurpleIRC bot configuration. +# Most of these options should be self explanatory. +# Place your bot file in the PurpleIRC/bots/ folder. +# NOTE: If you make changes to this file while the server is running use "/irc reloadbotconfigs" to load the changes into memory. +# +# nick - Your bot's unique nickname +nick: AwesomeBot +# If your bot's nick is in use try these alternates. Leave blank for none. +alt-nicks: + - %NICK%_ + - %NICK%__ +# login - Your bot's login name +login: AwesomeName +# realname +realname: '' +# server - IRC server to join +server: irc.excample.com +# port - IRC server port +port: 6667 +# Attempt ssl connection to IRC server +ssl: false +# Trust all SSL certs +trust-all-certs: false +# Bind address +bind: '' +# Auto split length for long messages +max-line-length: 440 +# Character encoding. Leave blank for Java default. +charset: '' +# show irc server motd on connect +show-motd: false +# autoconnect - Connect automatically on startup +autoconnect: 'false' +# password - Server password if needed +password: '' +# identify password (sent to NickServ) +ident-password: '' +# command-prefix - The bot will listen for commands that start with this. +command-prefix: '.' +# quit-message - Message the bot will send when it quits the server +quit-message: '&r[&5PurpleIRC&r] &rGood bye!' +# Message delay in milliseconds (be careful when changing this) +message-delay: 1000 +# CTCP finger reply +finger-reply: '' +# send a raw message on connect +raw-message-on-connect: false +# the raw message +raw-message: auth name pass +# relay-private-chat - Allow private chat to the bot to relay to the game +relay-private-chat: false +# notify channels or users when a player uses commands +command-notify: + enabled: false + # valid modes: msg, ctcp + mode: msg + # recipients can be channels or users + recipients: + - '#minecraft-test' + - example + ignore: + - /example +# Automatically part invalid channels +part-invalid-channels: false +# Message when leaving invalid channel +part-invalid-channels-message: 'I should not be here! Bye!' +# Channel auto join delay in server ticks (20 ticks = 1 second) +channel-auto-join-delay: 20 +# channels - List the channels your bot will join here +channels: + # Channel name must be surrounded by sing quotes to be YAML compliant. + # Use %2E instead of dots in the channel names. + # Example: minecraft%2Etest == minecraft.test + '#minecraft-test': + # worlds we listen to for this channel + worlds: + - '*' + # autojoin - Join the channel automatically on connect + autojoin: true + # modes - Channel modes to set + modes: '' + # password - Channel password + password: '' + # topic - Channel topic + topic: New topic + # topic-protect - Prevent others from changing the topic + topic-protect: false + # Enable chanserve mode for topic set command (/msg chanserv topic #channel + topic-chanserv: false + # If the Shortify plugin is installed then shoten URLs sent from IRC + shortify: true + # Enable or disable message filtering + enable-filtering: false + # Filters. These wll be removed from IRC to game messages. + filter-list: + - AwesomeBot + # enabled-messages - These are the message types that are either sent to the game or IRC + # config.yml. Remove or comment the messages you don't want. + enabled-messages: + # These messages are sent from game to IRC (see permissions) + - console-chat + - game-action + - game-chat + - game-death + - game-kick + - game-join + - game-quit + - game-mode + # Essentials helpop messages (/helpop /amsg /ac) + - ess-helpop + # Prism + #- prism-rollback + #- prism-drain + #- prism-extinguish + #- prism-custom + # The game-afk message type is not functional yet. + #- game-afk + # These messages are sent from IRC to game (see permissions) + - irc-action + - irc-chat + - irc-pchat + - irc-join + - irc-kick + - irc-part + - irc-topic + - irc-quit + - irc-nickchange + - irc-mode + - irc-notice + #- invalid-irc-commmand + #- irc-console-chat + # Dynmap Web Chat to IRC + - dynmap-web-chat + # IRC to Dynmap Web Chat + - irc-dynmap-web-chat + # IRC acion to Dynmap Chat (/me) + - irc-action-dynmap-web-chat + # mcMMO messages sent to IRC + - mcmmo-admin-chat + - mcmmo-party-chat + - mcmmo-chat + # FactionChat messages sent to IRC + - faction-public-chat + - faction-ally-chat + - faction-enemy-chat + # Hero chat message types that are sent from game to IRC + # Game messages from Global HC channel + - hero-Global-chat + - hero-Global-action + # Game messages from any HC channel + - hero-chat + - hero-action + # Specific HC channel + #- hero-[CHANNEL]-chat + #- hero-[CHANNEL]-action + # Various IRC messages that are sent to Herochat channel. Receiving HC + # channel name is configured per hero-channel: 'CHANNEL NAME' + #- irc-hero-action + #- irc-hero-chat + #- irc-hero-kick + #- irc-hero-join + #- irc-hero-part + #- irc-hero-topic + # CleverNotch bot messages will be sent to the IRC channel + - clever-chat + # OreBroadcast messages + #- ore-broadcast + - titan-chat + - towny-chat + # Specific TownyChat channel or tag + #- towny-[CHANNEL]-chat + #- towny-[CHANNELTAG]-chat + # Specific TitanChat channel + #- titan-[CHANNEL]-chat + # ReportRTS ticket notifications to irc + - rts-notify + # Catch /broadcast messages + #- broadcast-console-message + #- broadcast-message + # RedditStream + #- reddit-messages + # AdminPrivateChat messages + #- game-a-chat + # Hero channel destination for IRC messages + hero-channel: admin + # Towny channel destination for IRC messages + towny-channel: irc + # Log all messages from IRC to HeroChat + log-irc-to-hero-chat: false + # ops - IRC hostname mask styled ops list + ops: + - '*!*sarah@example.com' + # muted - IRC users that should not be heard in game + muted: + - KuShy + # Set ignore-irc-chat to true if you are using @chat and don't want regular IRC chat in your game + ignore-irc-chat: false + # ignore list for custom tab list + custom-tab-ignore-list: + - AwesomeBot + # Hide join message when player is invisible (VanishNoPacket) + hide-join-when-vanished: true + # Hide quit message when player is invisible (VanishNoPacket) + hide-quit-when-vanished: true + # How to respond to an invalid command + invalid-command: + private: false + ctcp: false + # Raw message to send if raw-message-on-join is true + raw-message: '' + raw-message-on-join: false + # join-notice + join-notice: + # Enable or disable this feature. + enabled: false + # Cool down in seconds per user. + cooldown: 60 + # If true then message will be sent in private + private: true + # If true then message will be sent via ctcp. if false then normal msg + ctcp: true + # The actual message sent to the user when joining the channel. + # If the message starts with a / then a command will be run and the output sent as the message. + message: '/list' + # commands - A list of commands that the bot will act on + # There are several builtin game_command options. + # @list - list the players in the game + # @help - print out of all of the commands + # @uptime - print the uptime of the game server + # @chat - send message to game + # @hchat - send message to specific hero channel + # @ochat - send message to game (overrides irc-chat) + # @motd - display minecraft server motd + # @msg - send private message to player + # @query - query remote minecraft server + # @rtsmb - Send ReportRTS broadcast message to mods + # @a - Send message to AdminPrivateChat + # @version - display version + # @bukkit - display API version + # @versionfull - display full version info (same as /version) + # The modes can be *, o , v , h, q, s, or i. Mix and match as needed. + # If game_command can optionally accept arguments via %ARGS% and %NAME% + # If a command is private then the result is sent to the player privately. + commands: + chat: + modes: '*' + private: false + ctcp: false + game_command: '@chat' + private_listen: true + channel_listen: true + ochat: + modes: '*' + private: false + ctcp: false + game_command: '@ochat' + private_listen: true + channel_listen: true + h: + modes: '*' + private: false + ctcp: false + game_command: '@hchat' + private_listen: true + channel_listen: true + msg: + modes: '*' + private: true + ctcp: false + game_command: '@msg' + private_listen: true + channel_listen: true + list: + modes: '*' + private: false + ctcp: false + game_command: '@list' + private_listen: true + channel_listen: true + help: + modes: '*' + private: false + ctcp: false + game_command: '@help' + private_listen: true + channel_listen: true + uptime: + modes: '*' + private: false + ctcp: false + game_command: '@uptime' + private_listen: true + channel_listen: true + version: + modes: '*' + private: false + ctcp: false + game_command: '@versionfull' + private_listen: true + channel_listen: true + lag: + modes: '*' + private: false + ctcp: false + game_command: lag + private_listen: true + channel_listen: true + mb: + modes: 'o' + private: 'false' + ctcp: 'false' + game_command: '@rtsmb' + private_listen: 'true' + channel_listen: 'true' + perm: '' + lv: + modes: 'o' + private: 'false' + ctcp: 'false' + game_command: '@list' + extra_commands: + - '@version' + private_listen: 'true' + channel_listen: 'true' + perm: '' +## Uncomment this if you want to hook into AdminPrivateChat +# a: +# modes: '*' +# private: false +# ctcp: false +# game_command: '@a' +# private_listen: true +# channel_listen: true +## Uncomment this to allow gamemode changes via IRC +# gamemode: +# modes: 'o' +# private: false +# ctcp: false +# game_command: 'gamemode %ARGS%' +# private_listen: true +# channel_listen: true \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100755 index 0000000..9fbcbe0 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,279 @@ +# Global configuration for PurpleIRC +# NOTE: If you make changes to this file while the server is running use "/irc reloadconfig" to load the changes into memory. +# Check for updates +update-checker: true +# Update checker mode: stable or dev +update-checker-mode: stable +# How often we check to see if a bot is connected to the IRC server. This is in server ticks (There 20 ticks in one sec). +conn-check-interval: 1000 +# Startup an ident server +enable-ident-server: false +# How often we check the channel user list +channel-check-interval: 100 +# Chat messages support standard Bukkit color codes using '&#'. See http://minecraft.gamepedia.com/Formatting_codes +# The following macro tokens are also supported. +# %WORLD% +# %NAME% +# %HOST% - Host of player or IRC user +# %SERVER% - Server of IRC user +# %AWAY% - IRC user away message +# %KICKERHOST% - Host of IRC kicker +# %KICKERSERVER% - Server of IRC kicker +# %KICKERAWAY% - IRC kicker away message +# %NICKPREFIX% - IRC user's status (see nick-prefixes below) +# %DISPLAYNAME% - Player's custom name +# %PLAYERIP% - IP address of a player +# %CHANNEL% +# %MESSAGE% +# %KICKER% - IRC kicker name +# %TOPIC% +# %REASON% +# %GROUP% - Requires Vault if you want to use this. +# %PLAYERPREFIX% - Requires Vault if you want to use this. +# %PLAYERSUFFIX% - Requires Vault if you want to use this. +# %GROUPSUFFIX% - Requires Vault if you want to use this. +# %GROUPPREFIX% - Requires Vault if you want to use this. +# %WORLDCOLOR% - Requires Multiverse. +# %PARTY% - mcMMO party channel name +# %FACTIONMODE% - Faction chat mode (all, ally, enemy) +# %FACTIONTAG% - Faction tag name +# %HEROCHANNEL% - HeroChat channel name +# %HERONICK% - HeroChat channel nick +# %HEROCOLOR% - HeroChat channel color +# %TITANCHANNEL% - TitanChat channel name +# %TITANCOLOR% - TitanChat channel color +# %WORLDALIAS% - World alias name +# ReportRTS ticket: %MESSAGE%, %MODNAME% %DISPLAYMODNAME% %RTSNAME% %RTSWORLD% %TICKETNUMBER% %MODCOMMENT% +# %TOWNYCHANNEL% - Towny channel name +# %TOWNYCHANNELTAG% - Towny channel tag name +# %TOWNYMSGCOLOR% - Towny message color +# %JOBS% - Player jobs +# %JOBSSHORT% - Player jobs shortened +# Prism custom tokens: +# prism-rollback: +# %COMMAND% +# %KEYWORD% +# %SORTDIRECTION% +# %PARAMWORLD% +# %ID% +# %ORIGINALBLOCK% +# %NEWBLOCK% +# %X% +# %Y% +# %Z% +# %BLOCKWORLD% +# prism-drain and prism-extinguish: +# %RADIUS% +# %ORIGINALBLOCK% +# %NEWBLOCK% +# %X% +# %Y% +# %Z% +# %BLOCKWORLD% +# prism-custom: +# %ACTION% +# %MESSAGE% +# %PLUGIN% +message-format: + # Message templates for game to IRC messages + console-chat: '[&dServer&r] %MESSAGE%' + game-achievement: '[&2%WORLD%&r] %NAME% has just earned the achievement [%MESSAGE%]' + game-mode: '[&2%WORLD%&r] %NAME% has changed game mode: [%MESSAGE%]' + game-action: '[&2%WORLD%&r]***%NAME% %MESSAGE%' + game-pchat: '[&2%WORLD%] <%NAME%> %MESSAGE%' + # death-messages - http://dev.bukkit.org/bukkit-plugins/death-messages + death-messages: '[&2%WORLD%&r]%MESSAGE%' + # Notification to player when sending a private message to an IRC user + game-pchat-response: ' &6-> &7%TARGET%: %MESSAGE%' + game-chat: '[&2%WORLD%&r] <%NAME%> %MESSAGE%' + game-death: '[&2%WORLD%&r] %MESSAGE%' + game-kick: '[&2%WORLD%&r] %MESSAGE%: %REASON%' + game-join: '[&2%WORLD%&r] %NAME% joined the game.' + game-quit: '[&2%WORLD%&r] %NAME% left the game.' + game-command: '[&2%WORLD%&r] Command detected by %NAME%: %COMMAND% %PARAMS%' + # Message template for "/irc send" to IRC message + game-send: '[&2%WORLD%&r]<%NAME%> %MESSAGE%' + # Essentials messages + ess-player-afk: '[&2%WORLD%&r] %NAME% is now AFK' + ess-player-not-afk: '[&2%WORLD%&r] %NAME% is no longer AFK' + ess-helpop: '&4[HelpOp] %DISPLAYNAME%&r: %MESSAGE%' + irc-ess-helpop: '&4[HelpOp] %DISPLAYNAME%&r: %MESSAGE%' + # Message templates for IRC to game messages + irc-action: '[&4IRC&r] ***%NAME% %MESSAGE%' + irc-chat: '[&4IRC&r]<%NAME%> %MESSAGE%' + # Response message when using @chat or @ochat + irc-chat-response: ' &6-> &7Minecraft: %MESSAGE%' + irc-pchat: '&dPrivate message: [&4IRC&r]<%NAME%> %MESSAGE%' + # Notification to user when sending a private message to a player + irc-pchat-response: ' &6-> &7%TARGET%: %MESSAGE%' + # Notification to user when sending a message to a specific hero channel + irc-hchat-response: ' &6-> &7%TARGET%: %MESSAGE%' + irc-join: '[&4IRC&r] %NAME% has joined %CHANNEL%.' + irc-kick: '[&4IRC&r] %NAME% was kicked from %CHANNEL% by %KICKER%. (Reason- %REASON%)' + irc-part: '[&4IRC&r] %NAME% has left %CHANNEL%.' + irc-quit: '[&4IRC&r] %NAME% has left %CHANNEL%. (Reason: %REASON%)' + irc-topic: '[&4IRC&r] Topic changed by %NAME%: %TOPIC%.' + irc-nickchange: '[&4IRC&r] %OLDNICK% is now known as %NEWNICK%.' + irc-mode: '[&4IRC&r] %NAME% %MODE% on %CHANNEL%' + irc-console-chat: '&f[&5IRC&f]&r<%NAME%> %MESSAGE%' + irc-notice: '[&4IRC&r] [notice(%CHANNEL%)] %NOTICE% ' + # AdminPrivateChat response message in IRC. Set to '' to disable. + irc-a-response: ' &6-> &7[AdminChat]: %MESSAGE%' + # AdinPrivateChat message from game to IRC + game-a-chat: '[%WORLD%] <%NAME%> -> [AdminChat]: %MESSAGE%' + # Message template for Clevernotch bot to IRC messages + clever-send: '[&4BOT]<%NAME%> %MESSAGE%' + # Message templates for mcMMO to IRC messages + mcmmo-admin-chat: '[admin:%WORLD%]<%NAME%> %MESSAGE%' + mcmmo-party-chat: '[party:%PARTY%]<%NAME%> %MESSAGE%' + mcmmo-chat: '[mcMMO]<%NAME%> %MESSAGE%' + # Message templates for FactionChat to IRC messages + faction-public-chat: '[%FACTIONMODE%&r][%FACTIONTAG%]<%NAME%> %MESSAGE%' + faction-ally-chat: '[%FACTIONMODE%&r][%FACTIONTAG%]<%NAME%> %MESSAGE%' + faction-enemy-chat: '[%FACTIONMODE%&r][%FACTIONTAG%]<%NAME%> %MESSAGE%' + # Message template for Herochat to IRC messages + hero-chat: '[%CHANNEL%]<%NAME%> %MESSAGE%' + hero-action: '[&2%CHANNEL%&r]***%NAME% %MESSAGE%' + # Message templates for IRC to Herochat messages + irc-hero-action: '[&3IRC&r] ***%NAME% %MESSAGE%' + irc-hero-chat: '[&3IRC&r]<%NAME%> %MESSAGE%' + irc-hero-join: '[&3IRC&r] %NAME% has joined %CHANNEL%.' + irc-hero-kick: '[&3IRC&r] %NAME% was kicked from %CHANNEL% by %KICKER%. (Reason- %REASON%)' + irc-hero-part: '[&3IRC&r] %NAME% has left %CHANNEL%.' + irc-hero-quit: '[&3IRC&r] %NAME% has left %CHANNEL%.' + irc-hero-topic: '[&3IRC&r] Topic changed by %NAME%: %TOPIC%.' + # Message template for TitanChat to IRC messages + titan-chat: '[%CHANNEL%]<%NAME%> %MESSAGE%' + # Message templates for IRC to TitanChat messages + irc-titan-chat: '[&3IRC&r]<%NAME%> %MESSAGE%' + # Help reply message + valid-irc-commands: 'Valid commands: %COMMANDS%' + # Invalid IRC command message + invalid-irc-command: "I'm sorry '%NICK%' I can't do that. Type '%CMDPREFIX%help' for a list of commands I might respond to." + no-perm-for-irc-command: "I'm sorry '%NICK%' you are not authorized to do that. Type '%CMDPREFIX%help' for a list of commands I might respond to." + rts-notify: '[RTS:New] #%TICKETNUMBER% <%NAME%> %MESSAGE%' + rts-complete: '[RTS:Complete] #%TICKETNUMBER% <%NAME%> %MESSAGE%' + rts-claim: '[RTS:Claim] #%TICKETNUMBER% <%NAME%> %MESSAGE%' + rts-unclaim: '[RTS:Unclaim] #%TICKETNUMBER% <%NAME%> %MESSAGE%' + rts-held: '[RTS:Held] #%TICKETNUMBER% <%NAME%> %MESSAGE%' + rts-assign: '[RTS:Assign] #%TICKETNUMBER% <%NAME%> %MESSAGE%' + rts-reopen: '[RTS:Reopen] #%TICKETNUMBER% <%NAME%> %MESSAGE%' + # Dynmap Web Chat to IRC + dynmap-web-chat: '[Dynmap] <%NAME%> %MESSAGE%' + # IRC to Dynmap Chat + irc-dynmap-web-chat: '[IRC] %MESSAGE%' + # IRC acion to Dynmap Chat (/me) + irc-action-dynmap-web-chat: '[IRC] ***%NAME% %MESSAGE%' + # OreBroadcast message + ore-broadcast: '[OreBroadcast] %MESSAGE%' + # Jobs seperator + jobs-separator: ', ' + # Message format per hero channel. From IRC to game. + irc-hero-channels: + Global: '[G][IRC]%PLAYERPREFIX%%NAME% %MESSAGE%' + # Message format per hero channel. From IRC actions to game. + irc-hero-action-channels: + Global: '[G][IRC]***%PLAYERPREFIX%%NAME% %MESSAGE%' + # Message format per hero channel. From game to IRC. Overrides hero-chat template. + hero-channels: + Global: '[%CHANNEL%]<%NAME%> %MESSAGE%' + # Emote message format per hero channel. From game to IRC. Overrides hero-action template. + hero-action-channels: + Global: '[&2%CHANNEL%&r]***%NAME% %MESSAGE%' + # Message templates for Towny to IRC messages + towny-channel-chat: '%TOWNYCHANNELTAG%[%TOWNYCHANNEL%]<%NAME%> %MESSAGE%' + # Message templates for IRC to Towny messages + irc-towny-chat: '[&3IRC&r]<%NAME%> %MESSAGE%' + # Message format per towny channel. From IRC to game. + irc-towny-channels: + irc: '[IRC]%PLAYERPREFIX%%NAME% %MESSAGE%' + broadcast-message: '[Broadcast] <%NAME%> %MESSAGE%' + broadcast-console-message: '[Broadcast] %MESSAGE%' + # Prism templates. See above for token names. + prism-rollback: '[PrismRollback] [Player: %NAME%] [Radius: %RADIUS%] [Command: %COMMAND%] [Keyword: %KEYWORD%] [X,Y,Z: %X%,%Y%,%Z%] [World: %PARAMWORLD%]' + prism-drain: '[PrismDrain] [Player: %NAME%] [Radius: %RADIUS%] [OrigBlock: %ORIGINALBLOCK%] [NewBlock: %NEWBLOCK%] [X,Y,Z: %X%,%Y%,%Z%] [World: %BLOCKWORLD%]' + prism-extinguish: '[PrismExtinguish] [Player: %NAME%] [Radius%: %RADIUS] [OrigBlock: %ORIGINALBLOCK%] [NewBlock: %NEWBLOCK%] [X,Y,Z: %X%,%Y%,%Z%] [World: %BLOCKWORLD%]' + prism-custom: '[PrismCustom] [Player: %NAME%] [Action: %ACTION%] [Message: %MESSAGE%] [Plugin: %PLUGIN%]' + # RedditStream + reddit-messages: '[R] %MESSAGE%' + # Defaults below take effect when user joins IRC and matching player is offline + default-player-suffix: '' + default-player-prefix: '' + default-group-suffix: '' + default-group-prefix: '' + default-player-world: 'world' + default-player-group: '' +# Format for the @list command in IRC +list-format: '[&9Minecraft&r] &2Online &r(%COUNT%/%MAX%): %PLAYERS%' +list-separator: ', ' +list-player: '%GROUPPREFIX%%NAME%' +# Sort playerlist by %NAME% and not by list-player format +list-sort-by-name: true +# Prevent game colors from appearing in IRC +strip-game-colors: false +# Prevent IRC colors from appearing in game +strip-irc-colors: false +# Strip IRC background colors (recommend leaving this as true) +strip-irc-bg-colors: true +# Add IRC names to in-game tab list +custom-tab-list: false +# Nothing to see here +custom-tab-prefix: '[I] ' +# IRC user gamemode in the tab list: ADVENTURE, CREATIVE, NOT_SET, SPECTATOR, SURVIVAL +custom-tab-gamemode: SPECTATOR +# IRC nick must be an exact match to a player name for token expanding +nick-exact-match: true +# IRC nick prefixes (can include & color codes) +nick-prefixes: + ircop: '&4~' + ircsuperop: '&6&&' + op: '&c@' + halfop: '&3%' + voice: '&2+' +# See http://site.pircbotx.googlecode.com/hg/apidocs/org/pircbotx/Colors.html for IRC color names +# See http://jd.bukkit.org/rb/doxygen/d7/dc0/enumorg_1_1bukkit_1_1ChatColor.html for game color names +# Game to IRC color map: Game Color Code => IRC Color Code +irc-color-map: + AQUA: CYAN + BLACK: BLACK + BLUE: BLUE + BOLD: BOLD + DARK_AQUA: TEAL + DARK_BLUE: DARK_BLUE + DARK_GRAY: DARK_GRAY + DARK_GREEN: DARK_GREEN + DARK_PURPLE: PURPLE + DARK_RED: RED + GOLD: OLIVE + GRAY: LIGHT_GRAY + GREEN: GREEN + LIGHT_PURPLE: MAGENTA + RED: RED + UNDERLINE: UNDERLINE + YELLOW: YELLOW + WHITE: WHITE + RESET: NORMAL +# IRC to game color map: IRC Color Code => Game Color Code +game-color-map: + BLACK: BLACK + BLUE: BLUE + BOLD: BOLD + BROWN: GRAY + CYAN: AQUA + DARK_BLUE: DARK_BLUE + DARK_GRAY: DARK_GRAY + DARK_GREEN: DARK_GREEN + GREEN: GREEN + LIGHT_GRAY: GRAY + MAGENTA: LIGHT_PURPLE + NORMAL: RESET + OLIVE: GOLD + PURPLE: DARK_PURPLE + RED: RED + TEAL: DARK_AQUA + UNDERLINE: UNDERLINE + WHITE: WHITE + YELLOW: YELLOW +Debug: false +# Ignore chat cancellation. +ignore-chat-cancel: false \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..02af985 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,109 @@ +name: ${project.name} +version: ${project.version} +description: ${project.description} +author: cnaude +website: http://dev.bukkit.org/server-mods/purpleirc/ +main: com.cnaude.purpleirc.PurpleIRC +softdepend: +- Vault +- Factions +- FactionChat +- HeroChat +- mcMMO +- CleverNotch +- TitanChat +- ReportRTS +- Essentials +- TownyChat +- dynmap +- Shortify +- OreBroadcast +- RedditStream +- AdminPrivateChat +- SuperVanish +commands: + irc: + description: Various irc commands + usage: / help - List all irc commands available. +permissions: + 'irc.reloadconfig': + description: Gives player access to the /irc reloadconfig. + default: op + 'irc.reloadbot': + description: Gives player access to the /irc reloadbot. + default: op + 'irc.reloadbotconfig': + description: Gives player access to the /irc reloadconfig. + default: op + 'irc.reconnect': + description: Gives player access to the /irc reconnect. + default: op + 'irc.message.chat': + description: Receive IRC chat messages. + default: true + 'irc.message.gamechat': + description: Send game chat to IRC + default: true + 'irc.message.action': + description: Receive IRC chat actions (/me). + default: true + 'irc.message.nickchange': + description: Receive IRC nick change messages + default: true + 'irc.message.join': + description: Receive IRC join messages. + default: false + 'irc.message.quit': + description: Receive IRC quit messages. + default: false + 'irc.message.disconnect': + description: Receive IRC disconnect messages. + default: op + 'irc.message.connect': + description: Receive IRC connect messages. + default: op + 'irc.message.topic': + description: Receive IRC topic messages. + default: false + 'irc.message.kick': + description: Receive IRC kick messages. + default: false + 'irc.message.part': + description: Receive IRC part messages. + default: false + 'irc.listbots': + description: Gives player access to the /irc listbots command. + default: op + 'irc.list': + description: Gives player access to the /irc list command. + default: op + 'irc.tablist': + description: Allow player to see IRC nick list in the tab list + default: op + 'irc.msg': + description: Gives player access to the /irc msg command. + default: op + 'irc.sendraw': + description: Gives player access to the /irc sendraw command. + default: op + 'irc.ctcp': + description: Gives player access to the /irc ctcp command. + default: op + 'irc.notice': + description: Gives player access to the /irc notice command. + default: op + 'irc.message.mode': + description: Player receives IRC mode change messages. + default: op + 'irc.message.notice': + description: Player receives IRC notice messages. + default: op + 'irc.motd': + description: Gives player access to the /irc motd command. + default: op + 'irc.load': + description: Gives player access to the /irc load command. + default: op + 'irc.unload': + description: Gives player access to the /irc unload command. + default: op \ No newline at end of file diff --git a/src/test/java/com/cnaude/purpleirc/AppTest.java b/src/test/java/com/cnaude/purpleirc/AppTest.java new file mode 100644 index 0000000..b1d3467 --- /dev/null +++ b/src/test/java/com/cnaude/purpleirc/AppTest.java @@ -0,0 +1,38 @@ +package com.cnaude.purpleirc; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +}