RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Help modifying Knives' Chat 3.0 beta 9 slightly

Dbagjones

Sorceror
Help modifying Knives' Chat 3.0 beta 9 slightly

I'm trying (so far quite unsuccessfully) to use a registered nick for the IRC channel. Reason being, I want to be able to AutoOp the shard nick. I need a way to be able to specify the password for the nickserv IDENTIFY command. I'm able to use an unregistered nick and everything works fine. Any ideas on how to add this ability to the script?

I can tinker some with the scripts, but I'm by no means an expert. Any and all help is appreciated.
 

Lokai

Knight
Dbagjones;774953 said:
I'm trying (so far quite unsuccessfully) to use a registered nick for the IRC channel. Reason being, I want to be able to AutoOp the shard nick. I need a way to be able to specify the password for the nickserv IDENTIFY command. I'm able to use an unregistered nick and everything works fine. Any ideas on how to add this ability to the script?

I can tinker some with the scripts, but I'm by no means an expert. Any and all help is appreciated.

I'm pretty handy with C#, but I guess I am a complete IRC noob.

First, what's a 'nick'?
Second, if you can post your code for the unregistered nick, perhaps someone could make suggestions on how to modify it to specify the password, and register it. This is a 'Script Support' forum after all.

Thanks.
 

Dbagjones

Sorceror
Ok, here's the code for the IRC connection from Knives' Chat:

Code:
using System;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
using Server;
using Server.Guilds;
using Server.Network;

namespace Knives.Chat3
{
	public enum IrcColor
	{
		White = 0,
		Black = 1,
		Blue = 2,
		Green = 3,
		LightRed = 4,
		Brown = 5,
		Purple = 6,
		Orange = 7,
		Yellow = 8,
		LightGreen = 9,
		Cyan = 10,
		LightCyan = 11,
		LightBlue = 12,
		Pink = 13,
		Grey = 14,
		LightGrey = 15,
	};

	public class IrcConnection
	{
		private static IrcConnection s_Connection = new IrcConnection();

		public static IrcConnection Connection{ get{ return s_Connection; } }

		private TcpClient c_Tcp;
		private Thread c_Thread;
		private StreamReader c_Reader;
		private StreamWriter c_Writer;
		private bool c_Connecting, c_Connected;
		private int c_Attempts;
		private DateTime c_LastPong;
        private DateTime c_NextStatus = DateTime.Now;
        private Server.Timer c_ConnectTimer;

		public bool Connecting{ get{ return c_Connecting; } }
		public bool Connected{ get{ return c_Connected; } }
		public bool HasMoreAttempts{ get{ return c_Attempts <= Data.IrcMaxAttempts; } }

        public string Status
        {
            get
            {
                return "Server: RunUO 2.0   Creatures: " + World.Mobiles.Count + "   Items: " + World.Items.Count + "   Guilds: " + BaseGuild.List.Count + "   Players: " + NetState.Instances.Count;
            }
        }

		public IrcConnection()
		{
		}

		public void Connect( Mobile m )
		{
			Data data = Data.GetData( m );

			if ( c_Connecting )
			{
				m.SendMessage( data.SystemC, General.Local(102) );
				return;
			}

			if ( c_Connected )
			{
				m.SendMessage( data.SystemC, General.Local(103) );
				return;
			}

			Connect();
		}

		public void Connect()
		{
			new Thread( new ThreadStart( ConnectTcp ) ).Start();
		}

		public void CancelConnect()
		{
			c_Attempts = Data.IrcMaxAttempts;
		}

		private void Reconnect()
		{
			c_Attempts++;

			if ( !HasMoreAttempts )
			{
				c_Attempts = 1;
				BroadcastSystem( General.Local(104) );
				return;
			}

			BroadcastSystem( General.Local(105) + c_Attempts );

			Connect();
		}

		private void ConnectTcp()
		{
			try{ c_Tcp = new TcpClient( Data.IrcServer, Data.IrcPort ); }
			catch
			{
				BroadcastSystem( General.Local(106) );

				Reconnect();

				return;
			}

			ConnectStream();
		}

		private void ConnectStream()
		{
            try
            {
                c_Connecting = true;
                c_ConnectTimer = Server.Timer.DelayCall(TimeSpan.FromSeconds(90), new Server.TimerCallback(TimerFail));
                c_LastPong = DateTime.Now;

                c_Reader = new StreamReader(c_Tcp.GetStream(), System.Text.Encoding.Default);
                c_Writer = new StreamWriter(c_Tcp.GetStream(), System.Text.Encoding.Default);

                BroadcastSystem(General.Local(107));

                SendMessage(String.Format("USER {0} 1 * :Hello!", Data.IrcNick));
                [COLOR="Red"]SendMessage(String.Format("NICK {0}", Data.IrcNick));[/COLOR]

                c_Thread = new Thread(new ThreadStart(ReadStream));
                c_Thread.Start();

                Server.Timer.DelayCall(TimeSpan.FromSeconds(15.0), new Server.TimerCallback(Names));

                foreach (Data data in Data.Datas.Values)
                    if (data.Mobile.HasGump(typeof(IrcGump)))
                        GumpPlus.RefreshGump(data.Mobile, typeof(IrcGump));

            }
            catch(Exception e)
            { 
                Errors.Report(General.Local(266), e);
                Console.WriteLine(e.Message);
                Console.WriteLine(e.Source);
                Console.WriteLine(e.StackTrace);
            }
        }

        private void TimerFail()
        {
            if (!c_Connecting || c_Connected)
                return;

            c_Connecting = false;
            BroadcastSystem("IRC connection attempt timed out.");

            try
            {
                if (c_Thread != null)
                    c_Thread.Abort();
            }
            catch
            {
            }

            c_Thread = null;

            foreach (Data data in Data.Datas.Values)
                if (data.Mobile.HasGump(typeof(IrcGump)))
                    GumpPlus.RefreshGump(data.Mobile, typeof(IrcGump));
        }

        private void Names()
        {
            if (c_Connected)
                SendMessage("NAMES " + Data.IrcRoom);
            else
                return;

            Server.Timer.DelayCall( TimeSpan.FromSeconds( 15.0 ), new Server.TimerCallback( Names ) );
        }

		private void PingPong(string str)
		{
            if (!c_Connecting && !c_Connected)
                return;

            if (str.IndexOf("PING") != -1)
                str = str.Replace("PING", "PONG");
            else
                str = str.Replace("PONG", "PING");
            
			SendMessage( str );
		}

		public void SendMessage( string msg )
		{
			try{

			BroadcastRaw( msg );

			c_Writer.WriteLine( msg );
			c_Writer.Flush();

			}catch{ Disconnect(); }
		}

		public void SendUserMessage( Mobile m, string msg )
		{
			if ( !Connected )
				return;

            msg = OutParse(m, m.RawName + ": " + msg);
			s_Connection.SendMessage( String.Format( "PRIVMSG {0} : {1}", Data.IrcRoom, msg  ));

            if (msg.ToLower().IndexOf("!status") != -1 && c_NextStatus < DateTime.Now)
            {
                c_NextStatus = DateTime.Now + TimeSpan.FromSeconds(15);
                s_Connection.SendMessage(String.Format("PRIVMSG {0} : {1}", Data.IrcRoom, Status));
                BroadcastSystem(Status);
            }

            BroadcastRaw(String.Format("PRIVMSG {0} : {1}", Data.IrcRoom, msg));
		}

		private string OutParse( Mobile m, string str )
		{
			if ( m.AccessLevel != AccessLevel.Player )
				return str = '\x0003' + ((int)Data.IrcStaffColor).ToString() + str;

			return str;
		}

		private void BroadcastSystem( string msg )
		{
            if (Channel.GetByType(typeof(Irc)) == null)
                return;

            Channel.GetByType(typeof(Irc)).BroadcastSystem(msg);
		}

		private void Broadcast( string name, string msg )
		{
            if (Channel.GetByType(typeof(Irc)) == null)
                return;

            ((Irc)Channel.GetByType(typeof(Irc))).Broadcast(name, msg);
		}

		private void Broadcast( Mobile m, string msg )
		{
		}

		private void BroadcastRaw( string msg )
		{
			foreach( Data data in Data.Datas.Values )
				if ( data.IrcRaw )
					data.Mobile.SendMessage( data.SystemC, "RAW: " + msg );
		}

		private void ReadStream()
		{
            try
            {

                string input = "";

                while (c_Thread.IsAlive)
                {
                    input = c_Reader.ReadLine();

                    if (input == null)
                        break;

                    HandleInput(input);
                }

                if (c_Connected)
                    Disconnect();

            }
            catch { if (c_Connected) Disconnect(); }
        }

        private void HandleInput(string str)
        {
            try
            {
                if (str == null)
                    return;

                BroadcastRaw(str);

                if (str.IndexOf("PONG") != -1 || str.IndexOf("PING") != -1)
                {
                    PingPong(str);
                    return;
                }

                if (str.IndexOf("353") != -1)
                {
                    BroadcastRaw(General.Local(109));

                    int index = str.ToLower().IndexOf(Data.IrcRoom.ToLower()) + Data.IrcRoom.Length + 2;

                    if (index == 1)
                        return;

                    string strList = str.Substring(index, str.Length - index);

                    string[] strs = strList.Trim().Split(' ');

                    Data.IrcList.Clear();
                    Data.IrcList.AddRange(strs);
                    Data.IrcList.Remove(Data.IrcNick);
                }

                if (str.IndexOf("001") != -1 && c_Connecting)
                {
                    c_Connected = true;
                    c_Connecting = false;

                    if (c_ConnectTimer != null)
                        c_ConnectTimer.Stop();

                    BroadcastSystem(General.Local(108));
                    c_Attempts = 1;

                    SendMessage(String.Format("JOIN {0}", Data.IrcRoom));

                    foreach (Data data in Data.Datas.Values)
                        if (data.Mobile.HasGump(typeof(IrcGump)))
                            GumpPlus.RefreshGump(data.Mobile, typeof(IrcGump));
                }

                if (str.Length > 300)
                    return;

                if (str.IndexOf("PRIVMSG") != -1)
                {
                    string parOne = str.Substring(1, str.IndexOf("!") - 1);

                    string parThree = str.Substring(str.IndexOf("!") + 1, str.Length - str.IndexOf("!") - (str.Length - str.IndexOf("PRIVMSG")) - 1);

                    int index = 0;

                    index = str.ToLower().IndexOf(Data.IrcRoom.ToLower()) + Data.IrcRoom.Length + 2;

                    if (index == 1)
                        return;

                    string parTwo = str.Substring(index, str.Length - index);

                    if (parTwo.IndexOf("ACTION") != -1)
                    {
                        index = parTwo.IndexOf("ACTION") + 7;
                        parTwo = parTwo.Substring(index, parTwo.Length - index);
                        str = String.Format("<{0}> {1} {2}", Data.IrcRoom, parOne, parTwo);
                    }
                    else
                        str = String.Format("<{0}> {1}: {2}", Data.IrcRoom, parOne, parTwo);

                    Broadcast(parOne, str);

                    if (str.ToLower().IndexOf("!status") != -1 && c_NextStatus < DateTime.Now)
                    {
                        c_NextStatus = DateTime.Now + TimeSpan.FromSeconds(15);
                        s_Connection.SendMessage(String.Format("PRIVMSG {0} : {1}", Data.IrcRoom, Status));
                        BroadcastSystem(Status);
                    }
                }
            }
            catch (Exception e)
            { 
                Errors.Report(General.Local(267), e);
                Console.WriteLine(e.Message);
                Console.WriteLine(e.Message);
                Console.WriteLine(e.Message);
            }
        }

		public void Disconnect()
		{
			Disconnect( true );
		}

        public void Disconnect(bool reconn)
        {
            try
            {
                if (c_Connected)
                    BroadcastSystem(General.Local(110));

                c_Connected = false;
                c_Connecting = false;

                if (c_Thread != null)
                {
                    try { c_Thread.Abort(); }
                    catch { }
                    c_Thread = null;
                }
                if (c_Reader != null)
                    c_Reader.Close();
                if (c_Writer != null)
                    c_Writer.Close();
                if (c_Tcp != null)
                    c_Tcp.Close();

                if (reconn)
                    Reconnect();

                foreach (Data data in Data.Datas.Values)
                    if (data.Mobile.HasGump(typeof(IrcGump)))
                        GumpPlus.RefreshGump(data.Mobile, typeof(IrcGump));
            }
            catch (Exception e)
            {
                Errors.Report(General.Local(268), e);
                Console.WriteLine(e.Message);
                Console.WriteLine(e.Source);
                Console.WriteLine(e.StackTrace);
            }
        }
    }
}

Right now what it does is connect to the specified (in the in-game gump) IRC server. It then sets the nick (nickname/handle) to what was specified in the in-game gump. Finally, it joins the channel that you specify. All this works great, but... I need for it to send a message to the IRC server to identify the owner of the nick. For example, I log onto the IRC server and my client prog specifies my nick to be Dbagjones (which is registered with NickServ on DALnet). Then my IRC client sends my password to nickserv to prove that I'm the owner of that registered nick.

If I were to do this manually, which is fine for me but not the server, I would log onto the IRC server, I would type: /nick Dbagjones, then the server responds saying that the nick I chose belongs to someone and I have a certain amount of time (3 mins, I believe) to send the command to identify myself. That command looks like this: /msg [email protected] IDENTIFY <password>

I highlighted in red the part of the code I believe sets the nick, so I imagine the identify part would go just after that.

I just need to add the nickserv identify command with the password to the script. I don't really care if the script has the password hard coded into it or if a modification to the IRC connection gump asks for the password. Hope this helps to explain a little better what I'm trying to do. If you need more info, let me know. Thanks again.

P.S.

Here's the code for the IRC Gump that shows up in the settings for Knives' Chat:

Code:
using System;
using Server;

namespace Knives.Chat3
{
    public class IrcGump : GumpPlus
    {
        public IrcGump(Mobile m)
            : base(m, 100, 100)
        {
            m.CloseGump(typeof(IrcGump));
        }

        protected override void BuildGump()
        {
            int width = 300;
            int y = 10;

            AddHtml(0, y, width, "<CENTER>" + General.Local(100));
            AddImage(width / 2 - 100, y + 2, 0x39);
            AddImage(width / 2 + 70, y + 2, 0x3B);

            AddHtml(0, y += 25, width, "<CENTER>" + General.Local(177));
            AddButton(width / 2 - 80, y, 0x2716, "Channel Options", new GumpCallback(ChannelOptions));
            AddButton(width / 2 + 60, y, 0x2716, "Channel Options", new GumpCallback(ChannelOptions));

            AddHtml(0, y += 20, width, "<CENTER>" + General.Local(98));
            AddButton(width/2-80, y+3, Data.IrcEnabled ? 0x2343 : 0x2342, "IRC Enabled", new GumpCallback(IrcEnabled));
            AddButton(width/2+60, y+3, Data.IrcEnabled ? 0x2343 : 0x2342, "IRC Enabled", new GumpCallback(IrcEnabled));

            if (!Data.IrcEnabled)
            {
                AddBackgroundZero(0, 0, width, y + 100, Data.GetData(Owner).DefaultBack);
                return;
            }

            AddHtml(0, y += 25, width, "<CENTER>" + General.Local(115));
            AddButton(width/2-80, y, Data.IrcAutoConnect ? 0x2343 : 0x2342, "IRC Auto Connect", new GumpCallback(IrcAutoConnect));
            AddButton(width/2+60, y, Data.IrcAutoConnect ? 0x2343 : 0x2342, "IRC Auto Connect", new GumpCallback(IrcAutoConnect));

            AddHtml(0, y+=20, width, "<CENTER>" + General.Local(116));
            AddButton(width / 2 - 80, y, Data.IrcAutoReconnect ? 0x2343 : 0x2342, "IRC Auto Reconnect", new GumpCallback(IrcAutoReconnect));
            AddButton(width / 2 + 60, y, Data.IrcAutoReconnect ? 0x2343 : 0x2342, "IRC Auto Reconnect", new GumpCallback(IrcAutoReconnect));

            AddHtml(0, y += 25, width, "<CENTER>" + General.Local(138) + ": " + General.Local(121 + (int)Data.IrcStaffColor));
            AddButton(width / 2 - 80, y + 4, 0x2716, "Irc Staff Color", new GumpCallback(IrcStaffColor));
            AddButton(width / 2 + 70, y + 4, 0x2716, "Irc Staff Color", new GumpCallback(IrcStaffColor));

            AddHtml(0, y += 25, width / 2 - 10, "<DIV ALIGN=RIGHT>" + General.Local(117));
            AddTextField(width / 2 + 10, y, 100, 21, 0x480, 0xBBA, "Nick", Data.IrcNick);
            AddButton(width / 2 - 5, y + 4, 0x2716, "Submit", new GumpCallback(Submit));

            AddHtml(0, y += 20, width / 2 - 10, "<DIV ALIGN=RIGHT>" + General.Local(118));
            AddTextField(width / 2 + 10, y, 100, 21, 0x480, 0xBBA, "Server", Data.IrcServer);
            AddButton(width / 2 - 5, y + 4, 0x2716, "Submit", new GumpCallback(Submit));

            AddHtml(0, y += 20, width / 2 - 10, "<DIV ALIGN=RIGHT>" + General.Local(119));
            AddTextField(width / 2 + 10, y, 100, 21, 0x480, 0xBBA, "Room", Data.IrcRoom);
            AddButton(width / 2 - 5, y + 4, 0x2716, "Submit", new GumpCallback(Submit));

            AddHtml(0, y += 20, width / 2 - 10, "<DIV ALIGN=RIGHT>" + General.Local(120));
            AddTextField(width / 2 + 10, y, 70, 21, 0x480, 0xBBA, "Port", "" + Data.IrcPort);
            AddButton(width / 2 - 5, y + 4, 0x2716, "Submit", new GumpCallback(Submit));

            int num = 139;

            if (IrcConnection.Connection.Connected)
                num = 141;
            if (IrcConnection.Connection.Connecting)
                num = 140;

            AddHtml(0, y += 40, width, "<CENTER>" + General.Local(num));
            AddButton(width / 2 - 60, y + 4, 0x2716, "Connect or Cancel or Close", new GumpCallback(ConnectCancelClose));
            AddButton(width / 2 + 50, y + 4, 0x2716, "Connect or Cancel or Close", new GumpCallback(ConnectCancelClose));

            AddBackgroundZero(0, 0, width, y+40, Data.GetData(Owner).DefaultBack);
        }

        private void ChannelOptions()
        {
            NewGump();
            new ChannelGump(Owner, Channel.GetByType(typeof(Irc)));
        }

        private void IrcEnabled()
        {
            Data.IrcEnabled = !Data.IrcEnabled;
            NewGump();
        }

        private void IrcAutoConnect()
        {
            Data.IrcAutoConnect = !Data.IrcAutoConnect;
            NewGump();
        }

        private void IrcAutoReconnect()
        {
            Data.IrcAutoReconnect = !Data.IrcAutoReconnect;
            NewGump();
        }

        private void Submit()
        {
            Data.IrcNick = GetTextField("Nick");
            Data.IrcServer = GetTextField("Server");
            Data.IrcRoom = GetTextField("Room");
            Data.IrcPort = GetTextFieldInt("Port");
            NewGump();
        }

        private void IrcStaffColor()
        {
            new IrcStaffColorGump(Owner, this);
        }

        private void ConnectCancelClose()
        {
            Data.IrcNick = GetTextField("Nick");
            Data.IrcServer = GetTextField("Server");
            Data.IrcRoom = GetTextField("Room");
            Data.IrcPort = GetTextFieldInt("Port");

            if (IrcConnection.Connection.Connected)
                IrcConnection.Connection.Disconnect(false);
            else if (IrcConnection.Connection.Connecting)
                IrcConnection.Connection.CancelConnect();
            else if (!IrcConnection.Connection.Connected)
                IrcConnection.Connection.Connect(Owner);

            NewGump();
        }


        private class IrcStaffColorGump : GumpPlus
        {
            private GumpPlus c_Gump;

            public IrcStaffColorGump(Mobile m, GumpPlus g)
                : base(m, 100, 100)
            {
                c_Gump = g;
            }

            protected override void BuildGump()
            {
                int width = 200;
                int y = 10;

                AddHtml(0, y, width, "<CENTER>" + General.Local(137));
                AddImage(width / 2 - 70, y + 2, 0x39);
                AddImage(width / 2 + 40, y + 2, 0x3B);

                y += 5;

                for (int i = 0; i < 16; ++i)
                {
                    AddHtml(0, y += 20, width, "<CENTER>" + General.Local(121 + i));
                    AddButton(width / 2 - 60, y + 3, 0x2716, "Select", new GumpStateCallback(Select), i);
                    AddButton(width / 2 + 50, y + 3, 0x2716, "Select", new GumpStateCallback(Select), i);
                }

                AddBackgroundZero(0, 0, 150, y + 40, Data.GetData(Owner).DefaultBack);
            }

            protected override void OnClose()
            {
                c_Gump.NewGump();
            }

            private void Select(object o)
            {
                if (!(o is int))
                    return;

                Data.IrcStaffColor = (IrcColor)(int)o;
                c_Gump.NewGump();
            }
        }
    }
}
 

Pyro-Tech

Knight
Couldn't you just log onto the server once with an IRC client with your Shard nick, register it yourself? that would cut the coding portion in half if you just did that part manually.

the hard part is sending the password over...you'll have to script that into the connect portion of the script.

Are you running your own IRC server or joining someone elses?

I run my own server, so this isn't a problem for me...i just set it where only users with the IP mask of localhost (127.0.0.1) can log on with the chat bot's nick. and it works great.

EDIT: sorry...didn't catch the last post explaining that you already thought of this lol
 

Mayla

Sorceror
I would actually love to get an answer to this as well. I'm trying to connect to IRC via my shard, however, my host server -requires- you to have a registered nickname in order to connect at all. So it keeps bouncing my shard into "Not Registered" every time I try to connect. As for simply registering the name via mIRC or another client, that won't work. Simply because it requires the password at the time of connection, and if another client is already using that nickname, it indicates it as "In Use". So! If there was a way to simply make this script give the line that inputs the code line /msg NickServ IDENTIFY <password> that would be great :D
 

Arvoreen

Sorceror
I would actually love to get an answer to this as well. I'm trying to connect to IRC via my shard, however, my host server -requires- you to have a registered nickname in order to connect at all. So it keeps bouncing my shard into "Not Registered" every time I try to connect. As for simply registering the name via mIRC or another client, that won't work. Simply because it requires the password at the time of connection, and if another client is already using that nickname, it indicates it as "In Use". So! If there was a way to simply make this script give the line that inputs the code line /msg NickServ IDENTIFY <password> that would be great :D

Sometime after connecting, you'd have to do
Code:
BroadcastRaw(String.Format("PRIVMSG NickServ :IDENTIFY {0}", pwString));
where pwString would be your password, as far as I can tell from looking at the code.

Details on how IRC messages are constructed can be found in the RFC http://www.ietf.org/rfc/rfc1459.txt
 

Mortis

Knight
I have a really old IRC script that does what your asking. I forget who made it.

You may find an answer in it's code for what you need.
Code:
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
using Server.Misc;
 
namespace Server
{
  class IRCNet
  {
      private Thread botThread;
 
      public static string Server = "irc.gamesurge.net";
      public static string Channel = "#IRONMAIDENUO";
      public static int Port = 6666;
 
      public static string nick = "IRONMAIDENUO";
      public static string username = "IRONMAIDENUO";
      public static string realname = "IRONMAIDENUO";
      public static string info = "IRONMAIDENUO";
 
      public static bool confirmed = false;
 
      private bool Connected;
     
      private string data;
      private IPHostEntry ServerHost;
      private IPEndPoint ipend;
      private IPAddress ServerIP;
      private Socket sock;
      private NetworkStream ns;
      private StreamReader sr;
      private StreamWriter sw;
 
 
 
      public IRCNet(  )
      {
            botThread = new Thread( new ThreadStart( this.Run ) );
      }
   
      public void Start(  )
      {
            botThread.Start(  );
      }
   
      public static void Initialize(  )
      {
        IRCNet b = new IRCNet(  );
        b.Start(  );
      }
 
 
   
      public void IRCConnect(  )
      {
        Cons_Send( "Looking up "+Server+".." );
        try
        {
            ServerHost = Dns.GetHostByName( Server );
        }
        catch ( SocketException )
        {
            Cons_Send( "Unknown host. Maybe you mispelled it?" );
            return;
        }
     
        ServerIP = ServerHost.AddressList[0];
        ipend = new IPEndPoint( ServerIP, Port );
        sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
         
        Cons_Send( "Connecting to "+Server+" ( "+ServerIP.ToString(  )+" ) port "+Port+".." );
        try
        {
            sock.Connect( ipend );
        }
        catch ( SocketException )
        {
            Cons_Send( "Connection failed." );
            return;
        }
         
        ns = new NetworkStream( sock );  // so we can use streams on the socket
        sr = new StreamReader( ns );      // used to read data off the socket
        sw = new StreamWriter( ns );      // used to write data to the socket
         
        Cons_Send( "Connected. Now logging in.." );
        sw.WriteLine( "nick "+nick );
        sw.Flush(  );
        sw.WriteLine( "USER "+username+" 0 * :"+realname );
        sw.Flush(  );
         
        Connected = true;
         
        while( Connected )
        {
            try
            {
              data = sr.ReadLine(  );  // get a line off the socket
            }
            catch ( IOException )
            {      // we'll catch this if the connection closes
              if( !Connected ) // just in case we disconnected since loop started
                  return;
              Cons_Send( "Connection lost." );
              sr.Close(  );      // close streams
              sw.Close(  );
              ns.Close(  );
              sock.Shutdown( SocketShutdown.Both );
              sock.Close(  );  // close socket               
              Cons_Send( "Disconnected." );
              Connected = false;
              sr = null;
              sw = null;
              ns = null;
              sock = null;
              return;
            }
            catch ( OutOfMemoryException e )
            {
              Cons_Send( e.ToString(  ) );
              continue;
            }
           
            lock( data )
            {
              if( data.Length > 1 )
                  Parse( data );
            }
        }
     
        IRCDisconnect( "Closing connection." );
      }
 
      public void IRCDisconnect( string msg )
      {
        if( sw == null )
        {
            Cons_Send( "Not connected." );
            return;
        }
 
//        IRCForm.QuitMessage( page.parent.PageOne.next, nick, ( info == null )?username+"@localhost":info, msg );         
        sw.WriteLine( "QUIT :"+msg );
        sw.Flush(  );
 
        Connected = false;
//        page.parent.PartAll( page.parent.PageOne.next );
        sr.Close(  );      // close streams
        sw.Close(  );
        ns.Close(  );
        sock.Shutdown( SocketShutdown.Both );
        sock.Close(  );  // close socket
        Cons_Send( "Disconnected." );         
        sr = null;
        sw = null;
        ns = null;
        sock = null;
      }
 
      public void Cons_Send( string msg )
      {
        Console.WriteLine( nick + " : " + msg );         
      }
 
      public void IRCSend( string msg )
      {
        if( !Connected )
            return;
        Cons_Send( msg );
        sw.WriteLine( msg );
        sw.Flush(  );
      }
 
      public void Run(  )
      {
        System.Console.WriteLine( nick+": Connecting to "+Server+" on "+Port );     
        try
        {
            this.IRCConnect(  );
        }
        catch( Exception )
        {
            // Show the exception, sleep for a while and try to establish a new connection to irc server
            Cons_Send( "catch( Exception )" );
            Cons_Send( "Connection lost..." );
            Thread.Sleep( 5000 );
            Run(  );
        }
      }
 
      public void Parse( string data )
      {
        string[] parts = data.Split( new char[] {' '}, 4 ); // split incoming data on space
        string prefix, command, target, paraone;
        int numeric;
 
        Cons_Send( data );
 
        if( data[0] == ':' )
        { // if line has prefix           
            prefix = parts[0];
            command = parts[1];
 
            if( command.Length == 3 )
            { // if numeric reply from server
              target = parts[2];
              numeric = System.Int32.Parse( command ); // make the numeric reply a number
              paraone = data.Substring( prefix.Length + target.Length + 6 ); // 6 is 3 chars and 3 spaces
              if( numeric == 001 ) { // do this here so we don't have to pass the nick
              //  page.server.nick = target; // setting the nick we settled on while connecting
              //  page.parent.nick = target; // in case it changed, since no NICK reply is sent
              }
              Reply( prefix, numeric, paraone ); // parse the reply
            }
            else
            { // otherwise normal command
              Command( prefix, command, data.Substring( prefix.Length + command.Length + 2 ) );
            }
        }
        else
        {
            command = parts[0];
           
            // parse the command, null prefix ( server assumed )
            Command( null, command, data.Substring( command.Length + 1 ) );
        }
      }
 
      public void Reply( string prefix, int command, string parameters )
      {
        //string[] parts = null;
        //string tail;
 
        // A lot of this is commented out because the "default" handling is appropriate.
        // As something needs to be handled differently, it can simply be uncommented and
        // modified.
        if( parameters[0] == ':' )
            Cons_Send( parameters.Substring( 1 ) );
        else
            Cons_Send( parameters );
      }
 
      public void Command( string prefix, string command, string parameters )
      {
        string[] parts = null;
 
        if( command.Equals( "PING" ) )
        {
            // Command: PING  Parameters: <server>
            IRCSend( "PONG "+parameters );
        }
        else if( command.Equals("MODE") )
        {
            // Command: MODE    Parameters: <channel> *( ( "-" / "+" ) *<modes> *<modeparams> )
            IRCSend( "JOIN " + Channel + "" );
        }
        else
        {
            // unsupported command
            Cons_Send( "UNKNOWN: ["+prefix+" "+command+" "+parameters+"]" );
        }
      }
  }
}
 
Top