Răsfoiți Sursa

[add] connect, user, pass, nick and join commands

isundil 9 ani în urmă
părinte
comite
2ed6c3a144

+ 2 - 0
build.gradle

@@ -2,6 +2,8 @@ apply plugin: 'java'
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
+    testCompile 'junit:junit:4.12'
+    compile 'org.testng:testng:6.9.6'
 }
 
 sourceCompatibility = "1.7"

+ 15 - 1
libirc.iml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.id=":libirc" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$USER_HOME$/Project/androidChatter" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+<module external.linked.project.id=":libirc" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
     <facet type="android-gradle" name="Android-Gradle">
       <configuration>
@@ -27,5 +27,19 @@
     </content>
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" exported="" name="testng-6.9.6" level="project" />
+    <orderEntry type="library" exported="" name="guice-4.0-no_aop" level="project" />
+    <orderEntry type="library" exported="" name="bsh-2.0b4" level="project" />
+    <orderEntry type="library" exported="" name="ant-1.7.0" level="project" />
+    <orderEntry type="library" exported="" name="jcommander-1.48" level="project" />
+    <orderEntry type="library" exported="" name="snakeyaml-1.15" level="project" />
+    <orderEntry type="library" exported="" name="junit-4.10" level="project" />
+    <orderEntry type="library" exported="" name="javax.inject-1" level="project" />
+    <orderEntry type="library" exported="" name="aopalliance-1.0" level="project" />
+    <orderEntry type="library" exported="" name="guava-16.0.1" level="project" />
+    <orderEntry type="library" exported="" name="ant-launcher-1.7.0" level="project" />
+    <orderEntry type="library" exported="" name="hamcrest-core-1.1" level="project" />
+    <orderEntry type="library" exported="" scope="TEST" name="junit-4.12" level="project" />
+    <orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
   </component>
 </module>

+ 28 - 6
src/main/java/com/knacki/lib/libirc/IrcConnector.java

@@ -5,6 +5,7 @@ import com.knacki.lib.libirc.api.IrcSSLSocket;
 import com.knacki.lib.libirc.api.IrcSocket;
 import com.knacki.lib.libirc.api.messages.ErrorMessage;
 import com.knacki.lib.libirc.api.messages.IrcMessage;
+import com.knacki.lib.libirc.api.messages.PingMessage;
 
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -18,18 +19,24 @@ public class IrcConnector {
     private IrcCallback cb;
     private static final Logger log = Logger.getLogger(IrcConnector.class.getName());
 
-    public IrcConnector(String addr, short port, boolean useSsl, IrcCallback cb) {
+    public IrcConnector(String addr, int port, IrcSSLSocket.SSLOptions useSsl) {
         callBackSuite = new Callbacks();
-        this.cb = cb;
 
-        if (useSsl)
-            sock = new IrcSSLSocket(addr, port);
+        if (useSsl != null)
+            sock = new IrcSSLSocket(addr, port, useSsl);
         else
           sock = new IrcSocket(addr, port);
+    }
 
+    public void connect(IrcCallback cb) {
+        this.cb = cb;
         sock.connect(callBackSuite, callBackSuite);
     }
 
+    public void joinThread() throws InterruptedException {
+        sock.joinThread();
+    }
+
     private class Callbacks implements IrcISocket.ConnectCallback, IrcISocket.MessageCallback {
         @Override
         public void onConnectError(Throwable e) {
@@ -50,6 +57,9 @@ public class IrcConnector {
                 log.warning("Ignoring unknown IRC message: " +line);
             else {
                 cb.onMessage(message);
+                if (message instanceof PingMessage) {
+                    replyPing((PingMessage) message);
+                }
                 if (message instanceof ErrorMessage) {
                     log.severe("Closing link on received error: " +((ErrorMessage) message).errorMsg);
                     sock.disconnect();
@@ -58,6 +68,11 @@ public class IrcConnector {
         }
     }
 
+    public void replyPing(PingMessage ping) {
+        sock.send("PONG " +ping.pingToken);
+        log.info("PONG: " +ping.pingToken);
+    }
+
     public void setPassword(String pass) {
         sock.send("PASS " +pass);
     }
@@ -66,9 +81,16 @@ public class IrcConnector {
         sock.send("NICK " +nick);
     }
 
-    public void setAuth(String username, String hostname, String servername, String realName, String password) {
+    public void setAuth(String nickname, String username, String servername, String realName, String password) {
         if (password != null)
             setPassword(password);
-        sock.send("USER " +username +" " +hostname +" " +servername +" :" +realName);
+        setNick(nickname);
+        sock.send("USER " +username +" androidchatter.knacki.info " +servername +" :" +realName);
+    }
+
+    public void join(String s) {
+        sock.send("JOIN " +s);
     }
+
+
 }

+ 2 - 0
src/main/java/com/knacki/lib/libirc/api/IrcISocket.java

@@ -11,6 +11,8 @@ public interface IrcISocket {
     void disconnect();
     void send(String line);
 
+    void joinThread() throws InterruptedException;
+
     interface ConnectCallback {
         void onConnectSuccess();
         void onConnectError(Throwable e);

+ 14 - 2
src/main/java/com/knacki/lib/libirc/api/IrcSSLSocket.java

@@ -3,9 +3,8 @@ package com.knacki.lib.libirc.api;
 /**
  * Created by isundil on 10/31/16.
  */
-
 public class IrcSSLSocket implements IrcISocket {
-    public IrcSSLSocket(String addr, short port) {
+    public IrcSSLSocket(String addr, int port, SSLOptions opts) {
         throw new UnsupportedOperationException("SSL not supported yet");
     }
 
@@ -14,8 +13,21 @@ public class IrcSSLSocket implements IrcISocket {
         throw new UnsupportedOperationException("SSL not supported yet");
     }
 
+    @Override
+    public void send(String line) {
+        throw new UnsupportedOperationException("SSL not supported yet");
+    }
+
+    @Override
+    public void joinThread() throws InterruptedException {
+        throw new UnsupportedOperationException("SSL not supported yet");
+    }
+
     @Override
     public void disconnect() {
         throw new UnsupportedOperationException("SSL not supported yet");
     }
+
+    public static class SSLOptions {
+    }
 }

+ 33 - 18
src/main/java/com/knacki/lib/libirc/api/IrcSocket.java

@@ -1,32 +1,39 @@
 package com.knacki.lib.libirc.api;
 
+import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.net.Socket;
 import java.net.SocketException;
+import java.net.SocketTimeoutException;
 import java.util.ArrayDeque;
 import java.util.Iterator;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.logging.Logger;
 
 /**
  * Created by isundil on 10/31/16.
  */
 public class IrcSocket implements IrcISocket {
+    private final static Logger log = Logger.getLogger(IrcSocket.class.getName());
+
     protected String addr;
     protected short port;
     protected Socket sock;
     protected Thread thread;
     private OutputStreamWriter out;
-    private ArrayDeque<String> delayMsg;
+    private ConcurrentLinkedDeque<String> delayMsg;
 
     protected MessageCallback mcb;
     protected ConnectCallback ccb;
 
-    public IrcSocket(String addr, short port) {
+    public IrcSocket(String addr, int port) {
         this.addr = addr;
-        this.port = port;
-        delayMsg = new ArrayDeque<>();
+        this.port = (short) port;
+        delayMsg = new ConcurrentLinkedDeque<>();
     }
 
     @Override
@@ -37,6 +44,7 @@ public class IrcSocket implements IrcISocket {
 
         try {
             sock = new Socket(addr, port);
+            sock.setSoTimeout(750);
             input = new InputStreamReader(sock.getInputStream());
             out = new OutputStreamWriter(sock.getOutputStream());
         }
@@ -60,8 +68,7 @@ public class IrcSocket implements IrcISocket {
             sock.close();
             thread.interrupt();
         }
-        catch (IOException e) {
-        }
+        catch (IOException e) { }
     }
 
     @Override
@@ -70,23 +77,26 @@ public class IrcSocket implements IrcISocket {
     }
 
     private void runThread(BufferedReader in) {
-        while (true) {
+        while (!Thread.interrupted()) {
             String line;
 
+            try {
+                for (Iterator<String> s = delayMsg.iterator(); s.hasNext(); ) {
+                    final String _line = s.next();
+
+                    out.write(_line + "\n");
+                    s.remove();
+                    log.info("Sent " + _line);
+                }
+                out.flush();
+            }
+            catch (IOException e) {
+                continue;
+            }
             try {
                 line = in.readLine();
             }
-            catch (InterruptedException) {
-                try {
-                    for (Iterator<String> lineIt = delayMsg.iterator(); lineIt.hasNext();) {
-                        out.write(lineIt.next() + "\n");
-                        lineIt.remove();
-                    }
-                }
-                catch (IOException e) {
-                    ccb.onConnectError(e);
-                    break;
-                }
+            catch (SocketTimeoutException e) {
                 continue;
             }
             catch (SocketException e) {
@@ -104,4 +114,9 @@ public class IrcSocket implements IrcISocket {
                 mcb.onMessage(line);
         }
     }
+
+    @Override
+    public void joinThread() throws InterruptedException {
+        thread.join();
+    }
 }

+ 4 - 3
src/main/java/com/knacki/lib/libirc/api/LineReader.java

@@ -3,13 +3,14 @@ package com.knacki.lib.libirc.api;
 /**
  * Created by isundil on 10/31/16.
  */
-
 public class LineReader {
     private String line;
-    private static String lineInit;
+    public final String src;
+    public final String lineInit;
 
     public LineReader(String s) {
         lineInit = line = s;
+        src = (!line.isEmpty() && line.charAt(0) == ':') ? nextToken().substring(1) : null;
     }
 
     public String nextToken() {
@@ -23,7 +24,7 @@ public class LineReader {
             token = line;
         else
             token = line.substring(0, tokenDelim);
-        line = line.substring(tokenDelim +1).trim();
+        line = tokenDelim == -1 ? "" : line.substring(tokenDelim +1).trim();
         return token;
     }
 

+ 7 - 0
src/main/java/com/knacki/lib/libirc/api/messages/IrcMessage.java

@@ -2,10 +2,13 @@ package com.knacki.lib.libirc.api.messages;
 
 import com.knacki.lib.libirc.api.LineReader;
 
+import java.util.logging.Logger;
+
 /**
  * Created by isundil on 10/31/16.
  */
 public abstract class IrcMessage {
+    private final static Logger log = Logger.getLogger(IrcMessage.class.getName());
 
     public static class Builder {
         private Builder() {}
@@ -14,11 +17,15 @@ public abstract class IrcMessage {
             LineReader lr = new LineReader(line);
             String token = lr.nextToken();
 
+            log.info("Received " +line);
+
             switch (token) {
                 case "NOTICE":
                     return new NoticeMessage(lr);
                 case "ERROR":
                     return new ErrorMessage(lr);
+                case "PING":
+                    return new PingMessage(lr);
             }
             return null;
         }

+ 15 - 0
src/main/java/com/knacki/lib/libirc/api/messages/PingMessage.java

@@ -0,0 +1,15 @@
+package com.knacki.lib.libirc.api.messages;
+
+import com.knacki.lib.libirc.api.LineReader;
+
+/**
+ * Created by isundil on 10/31/16.
+ */
+
+public class PingMessage extends IrcMessage {
+    public final String pingToken;
+
+    public PingMessage(LineReader lr) {
+        pingToken = lr.getRemains();
+    }
+}

+ 9 - 9
src/main/java/com/knacki/lib/libirc/test/SocketTest.java

@@ -10,14 +10,17 @@ import java.util.Timer;
 /**
  * Created by isundil on 10/31/16.
  */
-
 public class SocketTest {
     public static void main(String []av) {
-        IrcConnector con = new IrcConnector("irc.gamesurge.net", (short) 6667, false, new IrcCallback() {
+        final IrcConnector con = new IrcConnector("localhost", 6667, null);
+
+        con.connect(new IrcCallback() {
 
             @Override
             public void onConnect() {
                 System.out.println("Connected");
+                con.setAuth("nextG2", "nextG3", "nextG4", "My Real Name", null);
+                con.join("#test");
             }
 
             @Override
@@ -30,13 +33,10 @@ public class SocketTest {
                 System.out.println("read message");
             }
         });
-        while (true) {
-            try {
-                Thread.sleep(1000);
-            }
-            catch (InterruptedException e) {
-                return;
-            }
+
+        try {
+            con.joinThread();
+        } catch (InterruptedException e) {
         }
     }
 }

+ 75 - 0
src/test/java/com/knacki/lib/libirc/api/LineReaderTest.java

@@ -0,0 +1,75 @@
+package com.knacki.lib.libirc.api;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Created by isundil on 10/31/16.
+ */
+public class LineReaderTest {
+    @Test
+    public void linearReader_EmptyIsNull() {
+        LineReader lr = new LineReader("");
+
+        assertNull(lr.nextToken());
+        assertSame(lr.getRemains().length(), 0);
+        assertSame(new LineReader("").getRemains().length(), 0);
+    }
+
+    @Test
+    public void linearReader_singleToken() {
+        LineReader lr = new LineReader("test");
+
+        assertNotNull(lr.getRemains());
+        assertTrue(lr.nextToken().equals("test"));
+        assertNull(lr.nextToken());
+
+        assertSame(new LineReader("test").getRemains(), "test");
+    }
+
+    @Test
+    public void linearReader_twoToken() {
+        LineReader lr = new LineReader("testA   testB");
+        assertTrue(lr.getRemains().equals("testA   testB"));
+        assertTrue(lr.nextToken().equals("testA"));
+        assertTrue(lr.getRemains().equals("testB"));
+        assertTrue(lr.nextToken().equals("testB"));
+        assertTrue(lr.getRemains().equals(""));
+        assertNull(lr.nextToken());
+        assertNull(lr.src);
+
+        lr = new LineReader("testA testB");
+        assertTrue(lr.getRemains().equals("testA testB"));
+        assertTrue(lr.nextToken().equals("testA"));
+        assertTrue(lr.getRemains().equals("testB"));
+        assertTrue(lr.nextToken().equals("testB"));
+        assertTrue(lr.getRemains().equals(""));
+        assertNull(lr.nextToken());
+        assertNull(lr.src);
+    }
+
+    @Test
+    public void linearReader_twoTokenWithSrc() {
+        LineReader lr = new LineReader(":nick testA   testB");
+        assertTrue(lr.getRemains().equals("testA   testB"));
+        assertTrue(lr.nextToken().equals("testA"));
+        assertTrue(lr.getRemains().equals("testB"));
+        assertTrue(lr.nextToken().equals("testB"));
+        assertTrue(lr.getRemains().equals(""));
+        assertNull(lr.nextToken());
+        assertTrue(lr.src.equals("nick"));
+
+        lr = new LineReader(":nick testA testB");
+        assertTrue(lr.getRemains().equals("testA testB"));
+        assertTrue(lr.nextToken().equals("testA"));
+        assertTrue(lr.getRemains().equals("testB"));
+        assertTrue(lr.nextToken().equals("testB"));
+        assertTrue(lr.getRemains().equals(""));
+        assertNull(lr.nextToken());
+        assertTrue(lr.src.equals("nick"));
+    }
+}

+ 12 - 0
src/test/java/com/knacki/lib/libirc/api/messages/IrcMessageTest.java

@@ -0,0 +1,12 @@
+package com.knacki.lib.libirc.api.messages;
+
+import org.junit.Test;
+
+/**
+ * Created by isundil on 10/31/16.
+ */
+public class IrcMessageTest {
+    @Test
+    public void testIrcMessage_invalidToken() {
+    }
+}

+ 20 - 0
src/test/java/com/knacki/lib/libirc/api/messages/NoticeMessageTest.java

@@ -0,0 +1,20 @@
+package com.knacki.lib.libirc.api.messages;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by isundil on 10/31/16.
+ */
+
+public class NoticeMessageTest {
+    @Test
+    public void noticeMessage_std() {
+        IrcMessage msg = IrcMessage.Builder.build("NOTICE coucou coucou coucou blablabla");
+
+        assertTrue(msg instanceof NoticeMessage);
+    }
+}