X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Firc%2FConnection.java;h=f6b791328fb9a87f8f609308f89bd82c85eda2a6;hb=b6505c4d0f4fbc2bf19cc8b6030062bca6d180dd;hp=70ac0ebed6aebc1772b47fc09e85a1a171ea31d9;hpb=bf5c410d06c7a354017ebcd321e365b9cd767081;p=xudocci.git diff --git a/src/main/java/net/pterodactylus/irc/Connection.java b/src/main/java/net/pterodactylus/irc/Connection.java index 70ac0eb..f6b7913 100644 --- a/src/main/java/net/pterodactylus/irc/Connection.java +++ b/src/main/java/net/pterodactylus/irc/Connection.java @@ -18,6 +18,7 @@ package net.pterodactylus.irc; import static com.google.common.base.Preconditions.checkState; +import static java.util.Arrays.asList; import static java.util.concurrent.TimeUnit.SECONDS; import java.io.BufferedReader; @@ -33,17 +34,21 @@ 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; + import javax.net.SocketFactory; +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; import net.pterodactylus.irc.event.ChannelNicknames; -import net.pterodactylus.irc.event.ChannelNotJoined; -import net.pterodactylus.irc.event.ChannelNotJoined.Reason; import net.pterodactylus.irc.event.ChannelNoticeReceived; import net.pterodactylus.irc.event.ChannelTopic; import net.pterodactylus.irc.event.ClientQuit; @@ -53,7 +58,6 @@ import net.pterodactylus.irc.event.ConnectionFailed; import net.pterodactylus.irc.event.DccAcceptReceived; import net.pterodactylus.irc.event.DccSendReceived; import net.pterodactylus.irc.event.KickedFromChannel; -import net.pterodactylus.irc.event.MotdReceived; import net.pterodactylus.irc.event.NicknameChanged; import net.pterodactylus.irc.event.NicknameInUseReceived; import net.pterodactylus.irc.event.NoNicknameGivenReceived; @@ -66,9 +70,9 @@ 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; import com.google.common.io.Closeables; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; @@ -123,7 +127,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic private ConnectionHandler connectionHandler; /** Whether the connection has already been established. */ - private boolean established; + private final AtomicBoolean established = new AtomicBoolean(); /** * Creates a new connection. @@ -173,7 +177,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic * false} otherwise */ public boolean established() { - return established; + return established.get(); } /** @@ -363,18 +367,20 @@ public class Connection extends AbstractExecutionThreadService implements Servic return; } + eventBus.register(this); /* now read replies and react. */ try { /* some status variables. */ - int oldConnectionStatus = 0; - int connectionStatus = 0; boolean connected = true; - StringBuilder motd = new StringBuilder(); 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), + prefixHandler + ); while (connected) { Reply reply = connectionHandler.readReply(); @@ -383,6 +389,13 @@ public class Connection extends AbstractExecutionThreadService implements Servic String command = reply.command(); List parameters = reply.parameters(); + for (Handler handler : handlers) { + if (handler.willHandle(reply)) { + handler.handleReply(reply); + break; + } + } + /* most common events. */ if (command.equalsIgnoreCase("PRIVMSG")) { String recipient = parameters.get(0); @@ -390,7 +403,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)); @@ -402,8 +415,8 @@ 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))) { - eventBus.post(new PrivateNoticeReceived(this, reply)); + } else if (!prefixHandler.isChannel(recipient)) { + eventBus.post(new PrivateNoticeReceived(this, reply.source().get(), message)); } else { eventBus.post(new ChannelNoticeReceived(this, reply.source().get(), recipient, message)); } @@ -412,7 +425,7 @@ public class Connection extends AbstractExecutionThreadService implements Servic } else if (command.equals("431")) { eventBus.post(new NoNicknameGivenReceived(this, reply)); } else if (command.equals("433")) { - if (connectionStatus == 0) { + if (!established.get()) { nickname = nicknameChooser.getNickname(); connectionHandler.sendCommand("NICK", nickname); } else { @@ -432,7 +445,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, "")); @@ -446,75 +459,17 @@ public class Connection extends AbstractExecutionThreadService implements Servic } else if (command.equalsIgnoreCase("QUIT")) { eventBus.post(new ClientQuit(this, reply.source().get(), parameters.get(0))); - /* common channel join errors. */ - } else if (command.equals("474")) { - eventBus.post(new ChannelNotJoined(this, parameters.get(1), Reason.banned)); - } else if (command.equals("473")) { - eventBus.post(new ChannelNotJoined(this, parameters.get(1), Reason.inviteOnly)); - } else if (command.equals("475")) { - eventBus.post(new ChannelNotJoined(this, parameters.get(1), Reason.badChannelKey)); - /* basic connection housekeeping. */ } else if (command.equalsIgnoreCase("PING")) { connectionHandler.sendCommand("PONG", getOptional(parameters, 0), getOptional(parameters, 1)); - /* replies 001-004 don’t hold information but they have to be sent on a successful connection. */ - } else if (command.equals("001")) { - connectionStatus |= 0x01; - } else if (command.equals("002")) { - connectionStatus |= 0x02; - } else if (command.equals("003")) { - connectionStatus |= 0x04; - } else if (command.equals("004")) { - connectionStatus |= 0x08; - - /* 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)); - } - } - - /* 375, 372, and 376 handle the server’s MOTD. */ - } else if (command.equals("375")) { - /* MOTD starts. */ - motd.append(parameters.get(1)).append('\n'); - } else if (command.equals("372")) { - motd.append(parameters.get(1)).append('\n'); - } else if (command.equals("376")) { - motd.append(parameters.get(1)).append('\n'); - eventBus.post(new MotdReceived(this, motd.toString())); - motd.setLength(0); - - } else if (command.equals("KICK")) { + } else if (command.equalsIgnoreCase("KICK")) { eventBus.post(new KickedFromChannel(this, parameters.get(0), reply.source().get(), parameters.get(1), getOptional(parameters, 2))); /* okay, everything else. */ } else { eventBus.post(new UnknownReplyReceived(this, reply)); } - - if ((connectionStatus == 0x0f) && (connectionStatus != oldConnectionStatus)) { - /* connection succeeded! */ - established = true; - eventBus.post(new ConnectionEstablished(this)); - } - oldConnectionStatus = connectionStatus; } eventBus.post(new ConnectionClosed(this)); } catch (IOException ioe1) { @@ -524,7 +479,8 @@ public class Connection extends AbstractExecutionThreadService implements Servic logger.error("Runtime error", re1); eventBus.post(new ConnectionClosed(this, re1)); } finally { - established = false; + established.set(false); + eventBus.unregister(this); logger.info("Closing Connection."); try { Closeables.close(connectionHandler, true); @@ -535,6 +491,13 @@ public class Connection extends AbstractExecutionThreadService implements Servic } + @Subscribe + public void connectionEstablished(ConnectionEstablished connectionEstablished) { + if (connectionEstablished.connection() == this) { + established.set(true); + } + } + // // PRIVATE METHODS //