From aba496a727556cc1abffb53ad4a1d7ed7944e967 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Thu, 16 Oct 2014 22:16:44 +0200 Subject: [PATCH] Add handler for parsing channel and nickname prefixes. --- .../java/net/pterodactylus/irc/Connection.java | 39 ++-------- .../irc/connection/PrefixHandler.java | 84 ++++++++++++++++++++++ 2 files changed, 91 insertions(+), 32 deletions(-) create mode 100644 src/main/java/net/pterodactylus/irc/connection/PrefixHandler.java diff --git a/src/main/java/net/pterodactylus/irc/Connection.java b/src/main/java/net/pterodactylus/irc/Connection.java index c47144b..63d12ad 100644 --- a/src/main/java/net/pterodactylus/irc/Connection.java +++ b/src/main/java/net/pterodactylus/irc/Connection.java @@ -34,7 +34,6 @@ import java.net.Socket; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -45,6 +44,7 @@ import net.pterodactylus.irc.connection.ChannelNotJoinedHandler; import net.pterodactylus.irc.connection.ConnectionEstablishHandler; import net.pterodactylus.irc.connection.Handler; import net.pterodactylus.irc.connection.MotdHandler; +import net.pterodactylus.irc.connection.PrefixHandler; import net.pterodactylus.irc.event.ChannelJoined; import net.pterodactylus.irc.event.ChannelLeft; import net.pterodactylus.irc.event.ChannelMessageReceived; @@ -73,7 +73,6 @@ import net.pterodactylus.xdcc.util.io.BandwidthCountingInputStream; import net.pterodactylus.xdcc.util.io.BandwidthCountingOutputStream; import com.google.common.base.Optional; -import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; @@ -378,14 +377,12 @@ public class Connection extends AbstractExecutionThreadService implements Servic boolean connected = true; Set nicks = Sets.newHashSet(); - /* server modes. */ - Map nickPrefixes = Maps.newHashMap(); - Set channelTypes = Sets.newHashSet(); - + PrefixHandler prefixHandler = new PrefixHandler(); List handlers = asList( new MotdHandler(eventBus, this), + new ChannelNotJoinedHandler(eventBus, this), new ConnectionEstablishHandler(eventBus, this), - new ChannelNotJoinedHandler(eventBus, this) + prefixHandler ); while (connected) { @@ -409,7 +406,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic if (message.startsWith("\u0001") && message.endsWith("\u0001")) { /* CTCP! */ handleCtcp(reply.source().get(), message); - } else if (!channelTypes.contains(recipient.charAt(0))) { + } else if (!prefixHandler.isChannel(recipient)) { eventBus.post(new PrivateMessageReceived(this, reply.source().get(), message)); } else { eventBus.post(new ChannelMessageReceived(this, recipient, reply.source().get(), message)); @@ -421,7 +418,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic if (message.startsWith("\u0001") && message.endsWith("\u0001")) { /* CTCP! */ handleCtcp(reply.source().get(), message); - } else if (!channelTypes.contains(recipient.charAt(0))) { + } else if (!prefixHandler.isChannel(recipient)) { eventBus.post(new PrivateNoticeReceived(this, reply)); } else { eventBus.post(new ChannelNoticeReceived(this, reply.source().get(), recipient, message)); @@ -451,7 +448,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic eventBus.post(new ChannelTopic(this, parameters.get(1), parameters.get(2))); } else if (command.equals("353")) { for (String nickname : parameters.get(3).split(" ")) { - if (nickPrefixes.containsKey(nickname.substring(0, 1))) { + if (prefixHandler.isNickPrefixed(nickname)) { nicks.add(new Nickname(nickname.substring(1), nickname.substring(0, 1))); } else { nicks.add(new Nickname(nickname, "")); @@ -469,28 +466,6 @@ public class Connection extends AbstractExecutionThreadService implements Servic } else if (command.equalsIgnoreCase("PING")) { connectionHandler.sendCommand("PONG", getOptional(parameters, 0), getOptional(parameters, 1)); - /* 005 originally was a bounce message, now used to transmit useful information about the server. */ - } else if (command.equals("005")) { - for (String parameter : parameters) { - if (parameter.startsWith("PREFIX=")) { - int openParen = parameter.indexOf('('); - int closeParen = parameter.indexOf(')'); - if ((openParen != -1) && (closeParen != -1)) { - for (int modeCharacterIndex = 1; modeCharacterIndex < (closeParen - openParen); ++modeCharacterIndex) { - char modeCharacter = parameter.charAt(openParen + modeCharacterIndex); - char modeSymbol = parameter.charAt(closeParen + modeCharacterIndex); - nickPrefixes.put(String.valueOf(modeSymbol), String.valueOf(modeCharacter)); - } - logger.debug(String.format("Parsed Prefixes: %s", nickPrefixes)); - } - } else if (parameter.startsWith("CHANTYPES=")) { - for (int typeIndex = 10; typeIndex < parameter.length(); ++typeIndex) { - channelTypes.add(parameter.charAt(typeIndex)); - } - logger.debug(String.format("Parsed Channel Types: %s", channelTypes)); - } - } - } else if (command.equalsIgnoreCase("KICK")) { eventBus.post(new KickedFromChannel(this, parameters.get(0), reply.source().get(), parameters.get(1), getOptional(parameters, 2))); diff --git a/src/main/java/net/pterodactylus/irc/connection/PrefixHandler.java b/src/main/java/net/pterodactylus/irc/connection/PrefixHandler.java new file mode 100644 index 0000000..51e0b86 --- /dev/null +++ b/src/main/java/net/pterodactylus/irc/connection/PrefixHandler.java @@ -0,0 +1,84 @@ +package net.pterodactylus.irc.connection; + +import static java.lang.String.format; +import static java.lang.String.valueOf; +import static org.apache.log4j.Logger.getLogger; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import net.pterodactylus.irc.Connection; +import net.pterodactylus.irc.Reply; + +import com.google.common.eventbus.EventBus; +import org.apache.log4j.Logger; + +/** + * Parses the server’s messages about which prefixes it understands for + * channels and nicknames. + * + * @author David ‘Bombe’ Roden + */ +public class PrefixHandler implements Handler { + + private static final Logger logger = + getLogger(PrefixHandler.class); + + private final Map nickPrefixes = new HashMap<>(); + private final Set channelTypes = new HashSet<>(); + + @Override + public boolean willHandle(Reply reply) { + return "005".equals(reply.command()); + } + + @Override + public void handleReply(Reply reply) { + List parameters = reply.parameters(); + + for (String parameter : parameters) { + if (parameter.startsWith("PREFIX=")) { + parseNickPrefixes(parameter); + } else if (parameter.startsWith("CHANTYPES=")) { + parseChannelTypes(parameter); + } + } + } + + public boolean isChannel(String receiver) { + return channelTypes.contains(receiver.charAt(0)); + } + + public boolean isNickPrefixed(String nick) { + return nickPrefixes.containsKey(nick.substring(0, 1)); + } + + private void parseNickPrefixes(String parameter) { + int openParen = parameter.indexOf('('); + int closeParen = parameter.indexOf(')'); + if ((openParen != -1) && (closeParen != -1)) { + for (int modeCharacterIndex = 1; + modeCharacterIndex < (closeParen - openParen); + ++modeCharacterIndex) { + char modeCharacter = parameter.charAt( + openParen + modeCharacterIndex); + char modeSymbol = parameter.charAt( + closeParen + modeCharacterIndex); + nickPrefixes.put(valueOf(modeSymbol), + valueOf(modeCharacter)); + } + logger.debug(format("Parsed Prefixes: %s", nickPrefixes)); + } + } + + private void parseChannelTypes(String parameter) { + for (char channelType : parameter.substring(10).toCharArray()) { + channelTypes.add(channelType); + } + logger.debug(format("Parsed Channel Types: %s", channelTypes)); + } + +} -- 2.7.4