+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();
+ }
+}