Skip to content
This repository was archived by the owner on Aug 3, 2018. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
313bee5
sbt build
pfn Oct 2, 2014
f6cc5a9
sbt build update
pfn Nov 5, 2014
d8214ac
Add more durability from server lines
pfn Oct 7, 2014
bb379f8
capability negotiation and server-time implementation
pfn Nov 5, 2014
17ebbf1
Initial hookup of new event listeners
pfn Nov 6, 2014
c8699d8
add listener registration, uncomment date format
pfn Nov 6, 2014
7e1dd88
android workaround
pfn Nov 6, 2014
7217cec
synchronize date format
pfn Nov 7, 2014
e1ef299
Add remove event listeners
pfn Dec 10, 2014
a6b5a31
Fixes for capability negotiation
pfn Dec 10, 2014
149075d
Merge pull request #1 from sorcix/master
pfn Oct 20, 2015
ccf93d1
1.1.6-pfn
pfn Oct 20, 2015
ff89b2a
Merge branch 'master' of github.com:pfn/sIRC
pfn Oct 20, 2015
704beb0
Some small performance and thread safety improvements
jentfoo Oct 27, 2014
0ec3392
Fix for condition where user is not in the map
jentfoo Oct 27, 2014
0d4bf9e
Spacing fix (Not used to working in tabs)
jentfoo Oct 27, 2014
8e330cb
Fix: putIfAbsent is not available when using the Map interface
sorcix Oct 29, 2014
a3eafeb
Specify the github project as project homepage.
sorcix Nov 6, 2014
a6ffa19
1.1.6-pfn
pfn Oct 20, 2015
71617bf
Merge branch 'master' of github.com:pfn/sIRC
pfn Oct 20, 2015
ae74a1a
1.1.6-pfn
pfn Oct 20, 2015
914e543
Add onMotd, onConnect and onDisconnect to ServerEventListener
pfn Oct 20, 2015
db8e7ef
1.1.6-pfn.1
pfn Oct 20, 2015
fb9691e
Update IrcDebug calls with connection info
pfn Jan 29, 2016
ed7ecb3
Handle malformed PRIVMSG
pfn Jul 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
*~
.project
.classpath
/project/target/
52 changes: 52 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name := "sirc"

autoScalaLibrary := false

javacOptions in Compile ++= Seq("-target", "1.6", "-source", "1.6")

javacOptions in (Compile,doc) ~= {
_.foldRight(List.empty[String]) { case (o,r) =>
if (o != "-target") o :: r else r.drop(1)
}
}

crossPaths := false

organization := "com.hanhuy"

version := "1.1.6-pfn.3"

// sonatype publishing options follow
publishMavenStyle := true

publishTo := {
val nexus = "https://oss.sonatype.org/"
if (isSnapshot.value)
Some("snapshots" at nexus + "content/repositories/snapshots")
else
Some("releases" at nexus + "service/local/staging/deploy/maven2")
}

pomIncludeRepository := { _ => false }

pomExtra :=
<scm>
<url>git@github.com:pfn/sIRC.git</url>
<connection>scm:git:git@github.com:pfn/sIRC.git</connection>
</scm>
<developers>
<developer>
<id>pfnguyen</id>
<name>Perry Nguyen</name>
<url>https://github.com/pfn</url>
</developer>
</developers>

licenses := Seq("BSD-style" -> url("http://www.opensource.org/licenses/bsd-license.php"))

homepage := Some(url("https://github.com/pfn/sIRC"))

libraryDependencies ++= Seq(
"com.novocode" % "junit-interface" % "0.11" % "test",
"org.mockito" % "mockito-core" % "1.8.5" % "test"
)
1 change: 1 addition & 0 deletions project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=0.13.6
10 changes: 5 additions & 5 deletions src/main/java/com/sorcix/sirc/Channel.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public final class Channel {
/** The user list. */
private ConcurrentHashMap<String, User> users;
/** Possible channel prefixes. */
protected static final String CHANNEL_PREFIX = "#&+!";
public static final String CHANNEL_PREFIX = "#&+!";

/**
* Creates a new {@code Channel} object with given name.
Expand All @@ -56,7 +56,7 @@ public final class Channel {
* channel.
* @param global Whether this object is going to be shared.
*/
protected Channel(final String name, final IrcConnection irc, final boolean global) {
public Channel(final String name, final IrcConnection irc, final boolean global) {
this.name = name;
this.irc = irc;
if (global) {
Expand All @@ -71,7 +71,7 @@ protected Channel(final String name, final IrcConnection irc, final boolean glob
*
* @param user The user to add.
*/
protected void addUser(final User user) {
public void addUser(final User user) {
if (this.users != null) {
this.users.putIfAbsent(user.getNickLower(), user);
}
Expand Down Expand Up @@ -357,7 +357,7 @@ public void removeOperator(final User user) {
*
* @param user The user to remove.
*/
protected void removeUser(final User user) {
public void removeUser(final User user) {
if (this.users != null) {
this.users.remove(user.getNickLower());
}
Expand Down Expand Up @@ -501,7 +501,7 @@ public String toString() {
* didn't exist.
* @return The updated shared User object.
*/
protected User updateUser(final User user, final boolean createNew) {
public User updateUser(final User user, final boolean createNew) {
if (this.hasUser(user.getNickLower())) {
// update user if it exists
final User shared = this.getUser(user.getNickLower());
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/sorcix/sirc/ClientState.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ protected ClientState() {
* @param channel
* The channel to add.
*/
protected void addChannel(final Channel channel) {
public void addChannel(final Channel channel) {
if (!this.channels.containsKey(channel.getName().toLowerCase())) {
this.channels.put(channel.getName().toLowerCase(), channel);
}
Expand Down Expand Up @@ -100,7 +100,7 @@ protected Channel getChannel(final Channel channel) {
* @return The channel, or null if this channel doesn't exist. (The local
* user is not in that channel)
*/
protected Channel getChannel(final String channel) {
public Channel getChannel(final String channel) {
if (channel != null && this.channels.containsKey(channel.toLowerCase())) {
return this.channels.get(channel.toLowerCase());
}
Expand Down Expand Up @@ -165,7 +165,7 @@ protected void removeAll() {
* @param channel
* The channel name.
*/
protected void removeChannel(final String channel) {
public void removeChannel(final String channel) {
if (channel != null && this.channels.containsKey(channel.toLowerCase())) {
this.channels.remove(channel.toLowerCase());
}
Expand Down
86 changes: 81 additions & 5 deletions src/main/java/com/sorcix/sirc/IrcConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
*/
package com.sorcix.sirc;

import com.sorcix.sirc.cap.CapNegotiator;
import com.sorcix.sirc.event.MessageEventListener;
import com.sorcix.sirc.event.ServerEventListener;

import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import java.io.IOException;
Expand Down Expand Up @@ -60,12 +64,18 @@ public class IrcConnection {
public static final String VERSION = "1.1.6-SNAPSHOT";
/** Advanced listener. */
private AdvancedListener advancedListener = null;

private CapNegotiator.Listener capNegotiatorListener = null;
/** Connection InputStream thread. */
private IrcInput in = null;
/** Outgoing message delay. (Flood control) */
private int messageDelay = 100;
/** Message listeners. */
private final List<MessageListener> messageListeners;

private final List<MessageEventListener> messageEventListeners;
private final List<ServerEventListener> serverEventListeners;

/** Mode listeners. */
private final List<ModeListener> modeListeners;
/** Connection OutputStream thread. */
Expand Down Expand Up @@ -133,6 +143,8 @@ public IrcConnection(final String server, final int port) {
public IrcConnection(final String server, final int port,
final String password) {
this.server = new IrcServer(server, port, password, false);
this.serverEventListeners = new Vector<ServerEventListener>(4);
this.messageEventListeners = new Vector<MessageEventListener>(4);
this.serverListeners = new Vector<ServerListener>(4);
this.messageListeners = new Vector<MessageListener>(4);
this.modeListeners = new Vector<ModeListener>(2);
Expand Down Expand Up @@ -164,6 +176,18 @@ public void addMessageListener(final MessageListener listener) {
}
}

/**
* Adds a message listener to this IrcConnection.
*
* @param listener
* The message listener to add.
*/
public void addMessageEventListener(final MessageEventListener listener) {
if ((listener != null) && !this.messageEventListeners.contains(listener)) {
this.messageEventListeners.add(listener);
}
}

/**
* Adds a mode listener to this IrcConnection. Note that adding mode
* listeners will cause sIRC to check every incoming mode change for
Expand Down Expand Up @@ -192,7 +216,19 @@ public void addServerListener(final ServerListener listener) {
}
}

/**
/**
* Adds a server listener to this IrcConnection.
*
* @param listener
* The server listener to add.
*/
public void addServerEventListener(final ServerEventListener listener) {
if ((listener != null) && !this.serverEventListeners.contains(listener)) {
this.serverEventListeners.add(listener);
}
}

/**
* Add and load a service. {@code IrcConnection} will call the
* {@link SIRCService#load(IrcConnection)} method of this
* {@code SIRCService} after adding it to the service list.
Expand Down Expand Up @@ -234,7 +270,7 @@ public void sendRaw(final String line) {
* @param channel
* The channel to request the userlist for.
*/
protected void askNames(final Channel channel) {
public void askNames(final Channel channel) {
this.out.send(IrcPacketFactory.createNAMES(channel.getName()));
}

Expand Down Expand Up @@ -369,10 +405,17 @@ public void connect(Socket sock) throws UnknownHostException, IOException, NickN
this.socket = sock;
reconnecting = false;
}
// open streams
// open streams
this.out = new IrcOutput(this, new OutputStreamWriter(this.socket.getOutputStream(), this.charset));
this.in = new IrcInput(this, new InputStreamReader(this.socket.getInputStream(), this.charset));
CapNegotiator capNegotiator = new CapNegotiator(out);
if (capNegotiatorListener != null)
capNegotiator.addListener(capNegotiatorListener);
if (!reconnecting) {
// start capability negotiation
if (capNegotiatorListener != null) {
this.out.sendNowEx(IrcPacketFactory.createCAPLS());
}
// send password if given
if (this.server.getPassword() != null) {
this.out.sendNowEx(IrcPacketFactory.createPASS(this.server
Expand All @@ -388,10 +431,14 @@ public void connect(Socket sock) throws UnknownHostException, IOException, NickN
loop: while ((line = this.in.getReader().readLine()) != null) {
IrcDebug.log(line);
final IrcPacket decoder = new IrcPacket(line, this);
if (decoder.isNumeric()) {
if (capNegotiator.isNegotiating()) {
capNegotiator.process(decoder);
}
if (decoder.isNumeric()) {
final int command = decoder.getNumericCommand();
switch (command) {
case 1:
capNegotiator.cancel();
case 2:
case 3: {
final String nick = decoder.getArgumentsArray()[0];
Expand All @@ -411,7 +458,9 @@ public void connect(Socket sock) throws UnknownHostException, IOException, NickN
throw new PasswordException("Invalid password");
} // break; unnecessary due to throw
}
}
} else if ("CAP".equals(decoder.getCommand()) && !capNegotiator.isNegotiating()) {
capNegotiator.process(decoder);
}
if (line.startsWith("PING ")) {
this.out.pong(line.substring(5));
}
Expand All @@ -426,6 +475,9 @@ public void connect(Socket sock) throws UnknownHostException, IOException, NickN
.hasNext();) {
it.next().onConnect(this);
}
for (ServerEventListener l : serverEventListeners) {
l.onConnect(this);
}
}

/**
Expand Down Expand Up @@ -625,6 +677,14 @@ protected Iterator<ServerListener> getServerListeners() {
return this.serverListeners.iterator();
}

protected List<ServerEventListener> getServerEventListeners() {
return this.serverEventListeners;
}

protected List<MessageEventListener> getMessageEventListeners() {
return this.messageEventListeners;
}

/**
* Gives the port number this {@code IrcConnection} is using to connect.
*
Expand Down Expand Up @@ -755,6 +815,18 @@ public void removeServerListener(final ServerListener listener) {
}
}

public void removeServerEventListener(final ServerEventListener listener) {
if ((listener != null) && this.serverEventListeners.contains(listener)) {
this.serverEventListeners.remove(listener);
}
}

public void removeMessageEventListener(final MessageEventListener listener) {
if ((listener != null) && this.messageEventListeners.contains(listener)) {
this.messageEventListeners.remove(listener);
}
}

/**
* Remove a service. {@code IrcConnection} will call the
* {@link SIRCService#unload(IrcConnection)} method of this
Expand All @@ -780,6 +852,10 @@ public void setAdvancedListener(final AdvancedListener listener) {
this.advancedListener = listener;
}

public void setCapNegotiatorListener(final CapNegotiator.Listener listener) {
this.capNegotiatorListener = listener;
}

/**
* Marks you as away on the server. If any user sends a message to you while
* marked as away, the the server will send them a message back.
Expand Down
14 changes: 10 additions & 4 deletions src/main/java/com/sorcix/sirc/IrcInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
*/
package com.sorcix.sirc;

import com.sorcix.sirc.event.ServerEventListener;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
Expand Down Expand Up @@ -106,20 +108,22 @@ public void run() {
try {
// wait for lines to come in
while ((line = this.in.readLine()) != null) {
IrcDebug.log("<<< " + line);
IrcDebug.log(irc + " <<< " + line);
// always respond to PING
if (line.startsWith("PING ")) {
this.irc.out.pong(line.substring(5));
} else {
} else if (!line.trim().isEmpty()){
this.handleLine(line);
}
} else {
IrcDebug.log(irc + ": *** Invalid line from server, ignoring");
}
}
} catch (final SocketException ex) {
this.irc.setConnected(false);
} catch (final IOException ex) {
this.irc.setConnected(false);
} catch (final Exception ex) {
IrcDebug.log("Exception " + ex + " on: " + line);
IrcDebug.log(irc + ": Exception " + ex + " on: " + line);
ex.printStackTrace();
}
// when reaching this, we are disconnected
Expand All @@ -130,5 +134,7 @@ public void run() {
for (final Iterator<ServerListener> it = this.irc.getServerListeners(); it.hasNext();) {
it.next().onDisconnect(this.irc);
}
for (ServerEventListener l : irc.getServerEventListeners())
l.onDisconnect(irc);
}
}
8 changes: 4 additions & 4 deletions src/main/java/com/sorcix/sirc/IrcOutput.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
*
* @author Sorcix
*/
class IrcOutput extends Thread {
public class IrcOutput extends Thread {

/** The IrcConnection. */
private final IrcConnection irc;
Expand Down Expand Up @@ -171,7 +171,7 @@ protected synchronized void sendNow(final String line) {
* @throws IOException If anything goes wrong while sending this
* message.
*/
protected synchronized void sendNowEx(final IrcPacket packet) throws IOException {
public synchronized void sendNowEx(final IrcPacket packet) throws IOException {
this.sendNowEx(packet.getRaw());
}

Expand All @@ -183,11 +183,11 @@ protected synchronized void sendNowEx(final IrcPacket packet) throws IOException
* @throws IOException If anything goes wrong while sending this
* message.
*/
private synchronized void sendNowEx(String line) throws IOException {
public synchronized void sendNowEx(String line) throws IOException {
if (line.length() > (IrcOutput.MAX_LINE_LENGTH - 2)) {
line = line.substring(0, IrcOutput.MAX_LINE_LENGTH - 2);
}
IrcDebug.log(">>> " + line);
IrcDebug.log(irc + " >>> " + line);
this.out.write(line + IrcConnection.ENDLINE);
this.out.flush();
}
Expand Down
Loading