]> jfr.im git - z_archive/kelsier.git/blobdiff - Bot.cs
Added bot class, misc other changes
[z_archive/kelsier.git] / Bot.cs
diff --git a/Bot.cs b/Bot.cs
new file mode 100644 (file)
index 0000000..29f77e9
--- /dev/null
+++ b/Bot.cs
@@ -0,0 +1,111 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MySql.Data.MySqlClient;
+using System.Net;
+using System.Net.Sockets;
+
+namespace Kelsier {
+    class Bot {
+        public int id { get; private set; }
+
+        public string nick { get; private set; }
+        public string ident { get; private set; }
+        public string realname { get; private set; }
+        public string localip { get; private set; }
+        public string server { get; private set; }
+        public int serverport { get; private set; }
+
+        private IPEndPoint local;
+
+        private Socket s;
+        public bool online { get; private set; }
+
+        private Logger log;
+
+
+        public Bot(int id) {
+            this.id = id;
+
+            this.log = new Logger(id.ToString("0000"), Root.log);
+
+            MySqlDataReader rdr = Root.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");
+            this.ident = rdr.GetString("ident");
+            this.realname = rdr.GetString("realname");
+
+            if (rdr.IsDBNull(rdr.GetOrdinal("bindip"))) {
+                this.localip = null;
+                this.local = new IPEndPoint(IPAddress.Any, 0);
+            } else {
+                this.localip = rdr.GetString("bindip");
+                this.local = new IPEndPoint(IPAddress.Parse(this.localip), 0);
+            }
+
+            this.server = rdr.GetString("server");
+            this.serverport = rdr.GetInt32("serverport");
+        }
+
+        public string connect() {
+            if (online) throw new InvalidStateException();
+
+            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+            s.Bind(local);
+            s.Connect(server, serverport);
+
+            Stator rcvstate = new Stator();
+            s.BeginReceive(rcvstate.buffer, 0, 1, SocketFlags.None, new AsyncCallback(dataIn), rcvstate);
+
+            return "TODO";
+        }
+
+        public void dataIn(IAsyncResult ar) {
+            Stator rcvstate = (Stator)ar.AsyncState;
+            s.EndReceive(ar);
+
+            if (rcvstate.buffer[0] == '\n') {
+                processData(rcvstate.buffersb.ToString());
+                rcvstate = new Stator();
+            } else {
+                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);
+            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));
+            }
+        }
+
+        private void register() {
+            send(String.Format("NICK {0}", nick));
+            send(String.Format("USER {0} * * :{1}", ident, realname));
+            online = true;
+        }
+    }
+
+    class InvalidStateException : Exception { }
+
+    class Stator {
+        public byte[] buffer = new byte[1];
+        public StringBuilder buffersb = new StringBuilder();
+    }
+}