diff --git a/src/main/java/com/cnaude/purpleirc/IRCMessageHandler.java b/src/main/java/com/cnaude/purpleirc/IRCMessageHandler.java index d971deb..c0c8abe 100644 --- a/src/main/java/com/cnaude/purpleirc/IRCMessageHandler.java +++ b/src/main/java/com/cnaude/purpleirc/IRCMessageHandler.java @@ -16,11 +16,6 @@ */ package com.cnaude.purpleirc; -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.cnaude.purpleirc.Utilities.CaseInsensitiveMap; import com.google.common.base.Joiner; import java.text.Collator; @@ -181,7 +176,10 @@ public void processMessage(PurpleBot ircBot, User user, Channel channel, String } plugin.logDebug("GM: \"" + gameCommand.trim() + "\""); try { - plugin.commandQueue.add(new IRCCommand(new IRCCommandSender(ircBot, target, plugin, ctcpResponse, senderName), gameCommand.trim())); + plugin.commandQueue.add(new IRCCommand( + new IRCCommandSender(ircBot, target, plugin, ctcpResponse, senderName), + //new IRCConsoleCommandSender(ircBot, target, plugin, ctcpResponse, senderName), + gameCommand.trim())); } catch (Exception ex) { plugin.logError(ex.getMessage()); } diff --git a/src/main/java/com/cnaude/purpleirc/PurpleBot.java b/src/main/java/com/cnaude/purpleirc/PurpleBot.java index 4a72e0e..23f5010 100644 --- a/src/main/java/com/cnaude/purpleirc/PurpleBot.java +++ b/src/main/java/com/cnaude/purpleirc/PurpleBot.java @@ -51,6 +51,10 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import me.botsko.prism.actionlibs.QueryParameters; import me.botsko.prism.events.BlockStateChange; import org.bukkit.Achievement; @@ -139,6 +143,9 @@ public final class PurpleBot { public CaseInsensitiveMap> worldList; public CaseInsensitiveMap> muteList; public CaseInsensitiveMap> enabledMessages; + public CaseInsensitiveMap userPrefixes; + public CaseInsensitiveMap> firstOccurrenceReplacements; + public String defaultCustomPrefix; public CaseInsensitiveMap>> commandMap; public CaseInsensitiveMap>> extraCommandMap; public CaseInsensitiveMap joinNoticeCooldownMap; @@ -155,6 +162,8 @@ public final class PurpleBot { String joinNoticeMessage; String version; String finger; + private final ReadWriteLock rwl; + private final Lock wl; /** * @@ -162,6 +171,8 @@ public final class PurpleBot { * @param plugin */ public PurpleBot(File file, PurpleIRC plugin) { + this.rwl = new ReentrantReadWriteLock(); + this.wl = rwl.writeLock(); fileName = file.getName(); this.altNicks = new ArrayList<>(); this.connected = false; @@ -173,6 +184,8 @@ public PurpleBot(File file, PurpleIRC plugin) { this.extraCommandMap = new CaseInsensitiveMap<>(); this.joinNoticeCooldownMap = new CaseInsensitiveMap<>(); this.enabledMessages = new CaseInsensitiveMap<>(); + this.firstOccurrenceReplacements = new CaseInsensitiveMap<>(); + this.userPrefixes = new CaseInsensitiveMap<>(); this.muteList = new CaseInsensitiveMap<>(); this.worldList = new CaseInsensitiveMap<>(); this.opsList = new CaseInsensitiveMap<>(); @@ -669,6 +682,27 @@ private boolean loadConfig() { channelCmdNotifyMode = config.getString("command-notify.mode", "msg"); plugin.logDebug(" channelCmdNotifyMode => " + channelCmdNotifyMode); + for (String s : config.getStringList("custom-prefixes")) { + String pair[] = s.split(" ", 2); + if (pair.length > 0) { + userPrefixes.put(pair[0], ChatColor.translateAlternateColorCodes('&', pair[1])); + } + } + for (String key : userPrefixes.keySet()) { + plugin.logDebug(" CustomPrefix: " + key + " => " + userPrefixes.get(key)); + } + defaultCustomPrefix = ChatColor.translateAlternateColorCodes('&', config.getString("custom-prefix-default", "[IRC]")); + + for (String s : config.getStringList("replace-first-occurrences")) { + String pair[] = s.split(" ", 3); + if (pair.length > 2) { + CaseInsensitiveMap rfo = new CaseInsensitiveMap<>(); + rfo.put(pair[1], pair[2]); + firstOccurrenceReplacements.put(pair[0], rfo); + plugin.logDebug("ReplaceFirstOccurence: " + pair[0] + " => " + pair[1] + " => " + pair[2]); + } + } + // build command notify recipient list for (String recipient : config.getStringList("command-notify.recipients")) { if (!channelCmdNotifyRecipients.contains(recipient)) { @@ -2061,21 +2095,30 @@ public void updateNickList(Channel channel) { //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); + try { + wl.tryLock(10, TimeUnit.MILLISECONDS); + } catch (InterruptedException ex) { + plugin.logDebug("Lock Error: " + ex.getMessage()); + return; + } + try { + 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.remove(channelName); + channelNicks.put(channelName, users); + } finally { + wl.unlock(); } - channelNicks.put(channelName, users); } /** diff --git a/src/main/java/com/cnaude/purpleirc/Utilities/ChatTokenizer.java b/src/main/java/com/cnaude/purpleirc/Utilities/ChatTokenizer.java index 470ac7d..ecf178f 100644 --- a/src/main/java/com/cnaude/purpleirc/Utilities/ChatTokenizer.java +++ b/src/main/java/com/cnaude/purpleirc/Utilities/ChatTokenizer.java @@ -55,16 +55,17 @@ public ChatTokenizer(PurpleIRC plugin) { * @return */ public String chatIRCTokenizer(PurpleBot ircBot, User user, org.pircbotx.Channel channel, String template) { - return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user, ircBot) .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) .replace("%CHANNEL%", channel.getName())); } - public String ircUserTokenizer(String template, User user) { + public String ircUserTokenizer(String template, User user, PurpleBot ircBot) { String host = user.getHostmask(); String server = user.getServer(); String away = user.getAwayMessage(); String ircNick = user.getNick(); + String customPrefix = ircBot.defaultCustomPrefix; if (host == null) { host = ""; } @@ -74,13 +75,24 @@ public String ircUserTokenizer(String template, User user) { if (away == null) { away = ""; } + plugin.logDebug("customPrefix before: " + customPrefix); + if (!ircBot.userPrefixes.isEmpty()) { + for (String key : ircBot.userPrefixes.keySet()) { + if (key.equalsIgnoreCase(user.getNick()) || ircBot.checkUserMask(user, key)) { + customPrefix = ircBot.userPrefixes.get(key); + break; + } + } + } + plugin.logDebug("customPrefix after: " + customPrefix); return template.replace("%HOST%", host) + .replace("%CUSTOMPREFIX%", customPrefix) .replace("%NAME%", ircNick) .replace("%SERVER%", server) .replace("%AWAY%", away); } - public String ircUserTokenizer(String template, User recipient, User kicker) { + public String ircUserTokenizer(String template, User recipient, User kicker, PurpleBot ircBot) { String host = kicker.getHostmask(); String server = kicker.getServer(); String away = kicker.getAwayMessage(); @@ -94,7 +106,7 @@ public String ircUserTokenizer(String template, User recipient, User kicker) { if (away == null) { away = ""; } - return ircUserTokenizer(template, recipient) + return ircUserTokenizer(template, recipient, ircBot) .replace("%KICKERHOST%", host) .replace("%KICKER%", ircNick) .replace("%KICKERSERVER%", server) @@ -122,7 +134,7 @@ public String ircChatToHeroChatTokenizer(PurpleBot ircBot, User user, org.pircbo } else { tmpl = playerTokenizer(ircNick, template); } - return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user, ircBot) .replace("%HEROCHANNEL%", hChannel) .replace("%HERONICK%", channelManager.getChannel(hChannel).getNick()) .replace("%HEROCOLOR%", channelManager.getChannel(hChannel).getColor().toString()) @@ -150,7 +162,7 @@ public String ircChatToGameTokenizer(PurpleBot ircBot, User user, org.pircbotx.C plugin.logDebug("ircChatToGameTokenizer: null player: " + ircNick); tmpl = playerTokenizer(ircNick, template); } - return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user, ircBot) .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) .replace("%MESSAGE%", message) .replace("%CHANNEL%", channel.getName())); @@ -177,7 +189,7 @@ public String ircChatToHeroChatTokenizer(PurpleBot ircBot, User user, org.pircbo } else { tmpl = playerTokenizer(ircNick, template); } - return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user, ircBot) .replace("%HEROCHANNEL%", hChannel) .replace("%HERONICK%", channelManager.getChannel(hChannel).getNick()) .replace("%HEROCOLOR%", channelManager.getChannel(hChannel).getColor().toString()) @@ -206,7 +218,7 @@ public String ircChatToTownyChatTokenizer(PurpleBot ircBot, User user, org.pircb } else { tmpl = playerTokenizer(ircNick, template); } - return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(tmpl, user, ircBot) .replace("%TOWNYCHANNEL%", tChannel) .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) .replace("%MESSAGE%", message) @@ -225,7 +237,7 @@ public String ircChatToTownyChatTokenizer(PurpleBot ircBot, User user, org.pircb * @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) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, recipient, kicker, ircBot) .replace("%NICKPREFIX%", ircBot.getNickPrefix(kicker, channel)) .replace("%REASON%", reason) .replace("%CHANNEL%", channel.getName())); @@ -245,7 +257,7 @@ public String ircKickTokenizer(PurpleBot ircBot, User recipient, User kicker, St * @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) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, recipient, kicker, ircBot) .replace("%HEROCHANNEL%", hChannel) .replace("%HERONICK%", channelManager.getChannel(hChannel).getNick()) .replace("%HEROCOLOR%", channelManager.getChannel(hChannel).getColor().toString()) @@ -265,7 +277,7 @@ public String ircKickToHeroChatTokenizer(PurpleBot ircBot, User recipient, User * @return */ public String ircModeTokenizer(PurpleBot ircBot, User user, String mode, org.pircbotx.Channel channel, String template) { - return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user, ircBot) .replace("%MODE%", mode) .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) .replace("%CHANNEL%", channel.getName())); @@ -283,7 +295,7 @@ public String ircModeTokenizer(PurpleBot ircBot, User user, String mode, org.pir * @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) + return plugin.colorConverter.ircColorsToGame(ircUserTokenizer(template, user, ircBot) .replace("%NICKPREFIX%", ircBot.getNickPrefix(user, channel)) .replace("%MESSAGE%", message) .replace("%NOTICE%", notice) diff --git a/src/main/resources/SampleBot.yml b/src/main/resources/SampleBot.yml index f6a5722..55e334e 100644 --- a/src/main/resources/SampleBot.yml +++ b/src/main/resources/SampleBot.yml @@ -66,6 +66,17 @@ part-invalid-channels: false 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 +# If your irc-chat message has a %CUSTOMPREFIX% then these custom prefixes can replace them. +# Can match either nick or hostmask +custom-prefixes: + - 'AwesomeNick [AwesomePrefix]' + - '*!*sarah@example.com [Owner]' +# Default if no match is found +custom-prefix-default: '[IRC]' +# Similar to custom-prefixe above. Search and replace first occurrence of : and replace with &r: +replace-first-occurrences: + - 'AwesomeNick : &r:' + - '*!*sarah@example.com : &r:' # channels - List the channels your bot will join here channels: # Channel name must be surrounded by sing quotes to be YAML compliant.