]> jfr.im git - z_archive/kelsier.git/blobdiff - Bot.cs
Adding auth
[z_archive/kelsier.git] / Bot.cs
diff --git a/Bot.cs b/Bot.cs
index 29f77e9fb3f1d2b7a3cf0a78dc46c074669e2462..3a3221720c31466342384e42b81791ec57e1c92e 100644 (file)
--- a/Bot.cs
+++ b/Bot.cs
@@ -1,4 +1,25 @@
-using System;
+// Kelsier project - Bot state and parser code (Bot.cs)
+// Written by the Jobbig codeteam. <http://jobbig.eu/code/>
+// 
+// Copyright 2013 John Runyon.
+// 
+// This file is part of the Kelsier project.
+// 
+// Kelsier is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+// 
+// You should have received a copy of the GNU Affero General Public License
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
+//
+
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -6,8 +27,8 @@
 using System.Net;
 using System.Net.Sockets;
 
-namespace Kelsier {
-    class Bot {
+namespace Kelsier.Common {
+    public class Bot {
         public int id { get; private set; }
 
         public string nick { get; private set; }
@@ -28,9 +49,9 @@ class Bot {
         public Bot(int id) {
             this.id = id;
 
-            this.log = new Logger(id.ToString("0000"), Root.log);
+            this.log = new Logger(id.ToString("0000"), Info.log);
 
-            MySqlDataReader rdr = Root.db.queryReader("SELECT nick, ident, realname, bindip, server, serverport FROM bots WHERE id = @id", new object[] { "@id", id });
+            MySqlDataReader rdr = Info.db.queryReader("SELECT nick, ident, realname, bindip, server, serverport FROM bots WHERE id = @id", new object[] { "@id", id });
             rdr.Read();
 
             this.nick = rdr.GetString("nick");
@@ -44,9 +65,17 @@ class Bot {
                 this.localip = rdr.GetString("bindip");
                 this.local = new IPEndPoint(IPAddress.Parse(this.localip), 0);
             }
-
             this.server = rdr.GetString("server");
             this.serverport = rdr.GetInt32("serverport");
+
+            rdr.Close();
+
+            // TODO move this part into a 001 hook.
+            MySqlDataReader rdr = Info.db.queryReader("SELECT authname, authpass FROM m_id_quakenet WHERE botid = @id", new object[] { "@id", id });
+            rdr.Read();
+            this.authname = rdr.GetString("authname");
+            this.authpass = rdr.GetString("authpass");
+            rdr.Close();
         }
 
         public string connect() {
@@ -55,6 +84,8 @@ class Bot {
             s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
             s.Bind(local);
             s.Connect(server, serverport);
+            
+            register();
 
             Stator rcvstate = new Stator();
             s.BeginReceive(rcvstate.buffer, 0, 1, SocketFlags.None, new AsyncCallback(dataIn), rcvstate);
@@ -67,32 +98,72 @@ class Bot {
             s.EndReceive(ar);
 
             if (rcvstate.buffer[0] == '\n') {
-                processData(rcvstate.buffersb.ToString());
+                string linein = rcvstate.buffersb.ToString();
+                processData(linein);
                 rcvstate = new Stator();
-            } else {
+            } else if (rcvstate.buffer[0] != '\r') {
                 rcvstate.buffersb.Append(Encoding.ASCII.GetString(rcvstate.buffer, 0, 1));
             }
             s.BeginReceive(rcvstate.buffer, 0, 1, SocketFlags.None, new AsyncCallback(dataIn), rcvstate);
         }
         private void send(string data, params object[] args) {
-            log.debug(">>> " + data);
+            log.info(">>> " + data);
             s.Send(Encoding.ASCII.GetBytes(data + "\n"));
         }
 
         private void processData(string data) {
-            log.debug("<<< " + data);
-
-            if (!online) { register(); return; }
-
-            short numeric;
-            if (data.StartsWith(":") && Int16.TryParse(data.Substring(data.IndexOf(' ')+1, 3), out numeric)) {
-                if (numeric == 1) {
-                    send("JOIN #mustis");
-                    send("PRIVMSG #mustis :lolol!");
-                }
-            } else if (data.Substring(0, 4) == "PING") {
-                send("PONG" + data.Substring(4));
+            log.info("<<< " + data);
+
+            string[] parts;
+            string source = null;
+            if (data.StartsWith(":")) {
+                parts = data.Split((char[])null, 2, StringSplitOptions.RemoveEmptyEntries);
+                source = parts[0].Substring(1);
+                data = parts[1];
+            }
+            
+            parts = data.Split((char[])null, 2, StringSplitOptions.RemoveEmptyEntries);
+            if (parts[0] == "PRIVMSG") {
+                processMsg(source, parts[1]);
+            } else if (parts[0] == "376") {
+                send("AUTH "+this.authname+" "+this.authpass); // TODO 001 hook
+                send("MODE "+this.nick+" +x-w");
+                send("JOIN #jobbig");
+            } else if (parts[0] == "PING") {
+                send("PONG "+parts[1]);
+            }
+        }
+        // processMsg("DimeCadmium!dime@jobbig.eu", "#mustis :hi");
+        private void processMsg(string source, string data) {
+            string[] dataparts = data.Split((char[])null, 2, StringSplitOptions.RemoveEmptyEntries);
+            
+            string nick = (source.Split(new char[] { '!' }))[0];
+            string target = dataparts[0];
+            string message = dataparts[1];
+            if (message.StartsWith(":"))
+                message = message.Substring(1);
+            string[] msgparts = message.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
+            
+            // TODO check msgparts[0] first char for trigger
+            string cmdstr = msgparts[0].Substring(1);
+            string[] args;
+            bool chanmsg;
+            Channel chan;
+            if (target.StartsWith("#")) {
+                chanmsg = true;
+                args = new string[msgparts.Length - 1];
+                Array.Copy(msgparts, 1, args, 0, msgparts.Length - 1);
+                chan = new Channel(target);
+            } else {
+                chanmsg = false;
+                args = new string[msgparts.Length - 2];
+                Array.Copy(msgparts, 2, args, 0, msgparts.Length - 2);
+                chan = new Channel(msgparts[1]);
             }
+            
+            User user = new User(nick);
+            
+            Command cmd = new Command(this, cmdstr, args, user, chan, chanmsg);
         }
 
         private void register() {
@@ -102,9 +173,9 @@ class Bot {
         }
     }
 
-    class InvalidStateException : Exception { }
+    public class InvalidStateException : Exception { }
 
-    class Stator {
+    public class Stator {
         public byte[] buffer = new byte[1];
         public StringBuilder buffersb = new StringBuilder();
     }