All pastes #460238 Raw Edit

Untitled

public text v1 · immutable
#460238 ·published 2007-04-26 23:04 UTC
rendered paste body
/*
*   ----------------------------------------------------------------------
*   Name                parseIrcData.cs ( parseIrcData )
*
*   Description         The parseIrcData class makes use of regular
*                       expressions and basic string manipulation 
*                       methods in order to parse a raw string sent by an
*                       IRC server.
*
*   Version             1.00	[BETA]
*
*   Started             23/03/2006
*
*   Finished            29/03/2006
* 
*   Updated             11/04/2006
* 
*   Update notes        I carried out a complete rework of the code and
*                       added support for the +h halfop command
*
*   Resources           MSDN
*
*   Author              Tom Wadeson
*   ---------------------------------------------------------------------
*/

using System;
using System.Text;
using System.Text.RegularExpressions;

namespace SlimIRC {

    public class parseIrcData {
     

        // Modes Per Line (Default: 6)
        public  static  int ModesPL     = 6;

        // Trigger information
        private string      _Nick;
        private string      _Ident;
        private string      _Host;

        // Details
        private string      _CMD;
        private string      _Target;
        private string      _Modes;
        private string      _ModeLine;

        // Misc
        private string      _Limit;
        private string      _Key;
        private string      _PingID;

        // New Nick (When a Nick is changed)
        private string      _NNick;

        // Voice & De-voice Nicks
        private string[]    _VNick      = new string[ ModesPL ];
        private string[]    _DVNick     = new string[ ModesPL ];

        // Op & De-op Nicks
        private string[]    _ONick      = new string[ ModesPL ];
        private string[]    _DONick     = new string[ ModesPL ];

        // Half-Op & De-Half-Op Nicks (Note: This does not comply to the IRC RFCs)
        private string[]    _HONick     = new string[ ModesPL ];
        private string[]    _DHONick    = new string[ ModesPL ];

        // Ban Hosts & Unban Hosts
        private string[]    _BHost      = new string[ ModesPL ];
        private string[]    _UBHost     = new string[ ModesPL ];

        // Used to refer to the user kicked from a given channel
        private string      _KNick;

        // Used to refer to user messages ( PRIVMSG, Kick Message, Quit Message, Part Message, Topic )
        private string      _Message    = "";

        // Used to refer to individual 'words' of a string sent by the server
        private string[]    _Token;
       
        
        /* Regular Expressions */

        // Regex pattern to retrieve user's Nick
        private Regex       ptnNick     = new Regex( @"(?<=:)\S*(?=!)" );

        // Regex pattern to retrieve user's Ident
        private Regex       ptnIdent    = new Regex( @"(?<=!)\S*(?=@)" );

        // Regex pattern to retrieve user's Host
        private Regex       ptnHost     = new Regex( @"(?<=@)\S*" );

        // Regex pattern to retrieve variable Message
        private Regex       ptnMessage  = new Regex( @"(?<=:).*" );

        // Regex to check if an ACTION or CTCP event exists within a PRIVMSG
        private Regex       ptnSpecial   = new Regex( @"(?<=)\w*" );

        // Regex to retrieve an ACTION message
        private Regex       ptnActMsg   = new Regex( @"(?<=:ACTION).*(?=)" );

        // Regex to retrieve a PingID from a CTCP Ping request
        private Regex       ptnPingID   = new Regex( @"(?<=PING).*(?=)" );

   /* These "Event Bool"s are false by default. The parsing engine will change an "Event Bool"'s 
         * value to true if a particular event has occured.
         * 
         * For Example:
         * 
         * ":TuB!tub@TuB.users.netgamers.org PRIVMSG #test :Hello, World!"
         * 
         * The above line would be interpreted by the parsing engine and would as such be registered
         * with its relevant "Event Bool". In this case, the "Event Bool" which would be set is PrivMsg.
         * 
         * This feature is more or less the core of this class and it allows for rapid development of IRC
         * applications due to the fact that a developer is able to simply check an "Event Bool"'s status
         * and act accordingly.
         * 
         * if ( x.PrivMsg ) { Console.WriteLine( "A PrivMsg has been sent!" ); }
         */
        
        public  bool        Ping        = false;
        public  bool        PrivMsg     = false;
        public  bool        Action      = false;
        public  bool        Notice      = false;
        public  bool        CTCPPing    = false;        
        public  bool        CTCPVersion = false;
        public  bool        CTCPTime    = false;
        public  bool        Part        = false;
        public  bool        Kick        = false;
        public  bool        Quit        = false;
        public  bool        Join        = false;
        public  bool        Mode        = false;
        public  bool        Op          = false;
        public  bool        Deop        = false;
        public  bool        Voice       = false;
        public  bool        Devoice     = false;
        public  bool        Halfop      = false;
        public  bool        Dehalfop    = false;
        public  bool        Ban         = false;
        public  bool        Unban       = false;
        public  bool        Topic       = false;
        public  bool        CNick       = false;

       /* Public Gets */


        // User's Nick
        public  string      Nick
        {
            get
            {
                return this._Nick;
            }
        }

        // User's Ident
        public  string      Ident
        {
            get
            {
                return this._Ident;
            }
        }

        // User's Host
        public  string      Host
        {
            get
            {
                return this._Host;
            }
        }

        // [CMD] Command (Event - PRIVMSG, KICK, MODE, etc)
        public  string      CMD
        {
            get
            {
                return this._CMD;
            }
        }

        // Target (#Channel or direct PRIVMSG)
        public  string      Target
        {
            get
            {
                return this._Target;
            }
        }

        // Message
        public  string      Message
        {
            get
            {
                return this._Message;
            }
        }

        // Modes set/unset
        public  string      Modes
        {
            get
            {
                return this._Modes;
            }
        }

        // Mode Line
        public  string      ModeLine
        {
            get
            {
                return this._ModeLine;
            }
        }

        // Limit parameter (+l)
        public  string      Limit
        {
            get
            {
                return this._Limit;
            }
        }

        // Key parameter (+k)
        public  string      Key
        {
            get
            {
                return this._Key;
            }
        }

        // PingID
        public  string      PingID
        {
            get
            {
                return this._PingID;
            }
        }

        // New Nick
        public  string      NNick
        {
            get
            {
                return this._NNick;
            }
        }

        // Kick Nick
        public  string      KNick
        {
            get
            {
                return this._KNick;
            }
        }

        // Nicks granted +v
        public  string[]    VNick
        {
            get
            {
                return this._VNick;
            }
        }

        // Nicks dealt -v
        public  string[]    DVNick
        {
            get
            {
                return this._DVNick;
            }
        }

        // Nicks granted +o
        public  string[]    ONick
        {
            get
            {
                return this._ONick;
            }
        }

        // Nicks dealt -o
        public  string[]    DONick
        {
            get
            {
                return this._DONick;
            }
        }

        // Nicks granted +h
        public  string[]    HONick
        {
            get
            {
                return this._HONick;
            }
        }

        // Nicks dealt -h
        public  string[]    DHONick
        {
            get
            {
                return this._DHONick;
            }
        }

        // Host of Ban
        public  string[]    BHost
        {
            get
            {
                return this._BHost;
            }
        }

        // Host of Unban
        public  string[]    UBHost
        {
            get
            {
                return this._UBHost;
            }
        }

        // Token
        public  string[]    Token
        {
            get
            {
                return this._Token;
            }
        }


        /* Class Constructor */

        public parseIrcData ( string line ) {

            // Apply ptnNick to "line", assign _Nick
            if ( this.ptnNick.IsMatch( line ) ) {			
                this._Nick = this.ptnNick.Match( line ).ToString();
            }

            // Apply ptnIdent to "line", assign _Ident
            if ( this.ptnIdent.IsMatch( line ) ) {
                this._Ident = this.ptnIdent.Match( line ).ToString();
            }

            // Apply ptnHost to "line", assign _Host
            if ( this.ptnHost.IsMatch( line ) ) {
                this._Host = this.ptnHost.Match( line ).ToString();
            }

            // Split line at " "
            if ( line.IndexOf( " " ) > 0 )
            {
                this._Token = line.Split( new Char[] { ' ' } );
            }

            // Assign a value to _CMD, assuming a command exists
            if ( this._Token.Length >= 2 )
            {
                this._CMD = this.Token[1];
            }

            // Assign a value to _Target, assuming a target exists
            if ( this._Token.Length >= 3 )
            {
                this._Target = this.Token[2];
            }

            /* Mode Handling (Eeek!) */


            if ( this.CMD == "MODE" )
            {
                // Set the Mode Event Bool to true
                this.Mode = true;

                // Set the modes to the _Modes member
                this._Modes = this.Token[ 3 ];

                // Set ModeLine
                for (int a = 3; a < this.Token.Length; a++)
                {
                    this._ModeLine += this.Token[a] + " ";
                }
                this._ModeLine = this._ModeLine.TrimEnd();

                int currentParam = 3;

                bool minus  = false;
                bool plus   = false;;

                for ( int a = 0; a < this.Modes.Length; a++ )
                {
                    if ( this.Modes[a] == '-' ) {
                        minus   = true;
                        plus    = false;
                        continue;
                    }

                    if ( this.Modes[a] == '+' ) {
                        plus    = true;
                        minus   = false;
                        continue;
                    }

                    switch ( this.Modes[a] )
                    {
                        case 'o': // Handles Op and Deop Modes

                            currentParam++;

                            if ( minus )
                            {
                                this.addDeopToArray( this.Token[ currentParam ] );
                                this.Deop = true;
                            }

                            if ( plus )
                            {
                                this.addOpToArray( this.Token[ currentParam ] );
                                this.Op = true;
                            }
                            break;

                        case 'v': // Handles Voice and Devoice Modes

                            currentParam++;

                            if ( minus )
                            {
                                this.addDevoiceToArray( this.Token[ currentParam ] );
                                this.Devoice = true;
                            }

                            if ( plus )
                            {
                                this.addVoiceToArray( this.Token[ currentParam ] );
                                this.Voice = true;
                            }
                            break;

                        case 'b': // Handles Bans and Unbans

                            currentParam++;

                            if ( minus )
                            {
                                this.addUnbanhostToArray( this.Token[ currentParam ] );
                                this.Unban = true;
                            }

                            if ( plus )
                            {
                                this.addBanhostToArray( this.Token[ currentParam ] );
                                this.Ban = true;
                            }
                            break;

                        case 'h': // Handles Halfop and Dehalfop Modes

                            currentParam++;

                            if ( minus )
                            {
                                this.addHalfopToArray( this.Token[ currentParam ] );
                                this.Dehalfop = true;
                            }

                            if ( plus )
                            {
                                this.addDehalfopToArray( this.Token[ currentParam ] );
                                this.Halfop = true;
                            }
                            break;

                        case 'k': // Handles +/-k Modes

                            currentParam++;

                            this._Key = this.Token[ currentParam ];                            
                            break;

                        case 'l': // Handles +/-l (Limit) Modes

                            if (plus)
                            {
                                currentParam++;
                                this._Limit = this.Token[currentParam];
                            }                            
                            break;
                    }
                }
            }

            /* PRIVMSG  CMD */

            if ( this.CMD == "PRIVMSG" )
            {
                for ( int a = 3; a < this.Token.Length; a++ )
                {
                    this._Message += this.Token[a] + " ";
                }

                this._Message = this._Message.TrimEnd();

                if ( this.ptnMessage.IsMatch( this._Message ) )
                {
                    this._Message = this.ptnMessage.Match( this._Message ).ToString();
                }
                    
                // ACTION, CTCP: Version, Time, Ping support
                if ( this.ptnSpecial.IsMatch( this._Message ) )
                {
                    // ACTION
                    if ( this.ptnSpecial.Match( this._Message ).ToString() == "ACTION" )
                    {
                        this.Action = true;
                        this._Message = this.ptnActMsg.Match( this._Message ).ToString().Trim();
                    }

                    // CTCP VERSION
                    if ( this.ptnSpecial.Match( this._Message ).ToString() == "VERSION" )
                    {
                        this.CTCPVersion = true;
                    }

                    // CTCP TIME
                    if ( this.ptnSpecial.Match( this._Message ).ToString() == "TIME" )
                    {
                        this.CTCPTime = true;
                    }

                    // CTCP PING
                    if ( this.ptnSpecial.Match( this._Message ).ToString() == "PING" )
                    {
                        this.CTCPPing = true;

                        if ( this.ptnPingID.IsMatch( this._Message ) )
                        {
                            this._PingID = this.ptnPingID.Match( this._Message ).ToString().Trim();
                        }
                    }
                }
                // PRIVMSG
                else
                {
                    this.PrivMsg = true;
                }
            }

            /* NOTICE CMD */

            if (this.CMD == "KICK")
            {
                this.Notice = true;

                for (int a = 3; a < this.Token.Length; a++)
                {
                    this._Message += this.Token[a] + " ";
                }

                this._Message = this._Message.TrimEnd();

                if (this.ptnMessage.IsMatch(this._Message))
                {
                    this._Message = this.ptnMessage.Match(this._Message).ToString();
                }
            }
                
            /* KICK CMD */

            if ( this.CMD == "KICK" )
            {
                this.Kick = true;

                this._KNick = this.Token[ 3 ];

                for (int a = 4; a < this.Token.Length; a++)
                {
                    this._Message += this.Token[a] + " ";
                }

                this._Message = this._Message.TrimEnd();

                if (this.ptnMessage.IsMatch(this._Message))
                {
                    this._Message = this.ptnMessage.Match(this._Message).ToString();
                }
            }

            /* QUIT CMD */

            if ( this.CMD == "QUIT" )
            {
                this.Quit = true;

                for (int a = 2; a < this.Token.Length; a++)
                {
                    this._Message += this.Token[a] + " ";
                }

                this._Message = this._Message.TrimEnd();

                if (this.ptnMessage.IsMatch(this._Message))
                {
                    this._Message = this.ptnMessage.Match(this._Message).ToString();
                }
            }

            /* PART CMD */

            if ( this.CMD == "PART" )
            {
                this.Part = true;

                for (int a = 3; a < this.Token.Length; a++)
                {
                    this._Message += this.Token[a] + " ";
                }

                this._Message = this._Message.TrimEnd();

                if (this.ptnMessage.IsMatch(this._Message))
                {
                    this._Message = this.ptnMessage.Match(this._Message).ToString();
                }
            }

            /* TOPIC CMD */

            if ( this.CMD == "TOPIC" )
            {
                this.Topic = true;

                for (int a = 3; a < this.Token.Length; a++)
                {
                    this._Message += this.Token[a] + " ";
                }

                this._Message = this._Message.TrimEnd();

                if (this.ptnMessage.IsMatch(this._Message))
                {
                    this._Message = this.ptnMessage.Match(this._Message).ToString();
                }
            }

            /* JOIN CMD */

            if ( this.CMD == "JOIN" )
            {
                this.Join = true;
            }

            /* PING CMD */

            if ( this.Token[0] == "PING" )
            {
                this.Ping = true;
                this._PingID = this.Token[1];
            }

            /* CHANGE NICK CMD */

            if ( this.CMD == "NICK" )
            {
                this.CNick = true;

                if ( this.ptnMessage.IsMatch( this.Token[2] ) )
                {
                    this._NNick = this.ptnMessage.Match( this.Token[2] ).ToString();
                }
            }
        }            

        /* The members listed below allow for dynamic appending to
		* their relative arrays */

        // Add Op Nick
        private void    addOpToArray( string nick ) {

            for ( int a = 0; a < this.ONick.Length; a++ )
            {
                if ( this.ONick[a] == null ) 
                {
                    this.ONick[a] = nick;
                    break;
                }
            }
        }

        // Add Deop Nick
        private void    addDeopToArray( string nick ) {

            for ( int a = 0; a < this.DONick.Length; a++ )
            {
                if ( this.DONick[a] == null )
                {
                    this.DONick[a] = nick;
                    break;
                }
            }
        }

        // Add Voice Nick
        private void    addVoiceToArray( string nick )
        {

            for ( int a = 0; a < this.VNick.Length; a++ )
            {
                if ( this.VNick[a] == null )
                {
                    this.VNick[a] = nick;
                    break;
                }
            }
        }

        // Add Devoice Nick
        private void    addDevoiceToArray( string nick )
        {

            for ( int a = 0; a < this.DVNick.Length; a++ )
            {
                if ( this.DVNick[a] == null )
                {
                    this.DVNick[a] = nick;
                    break;
                }
            }
        }

        // Add Halfop Nick
        private void    addHalfopToArray( string nick )
        {

            for ( int a = 0; a < this.HONick.Length; a++ )
            {
                if ( this.HONick[a] == null )
                {
                    this.HONick[a] = nick;
                    break;
                }
            }
        }

        // Add Dehalfop Nick
        private void    addDehalfopToArray( string nick )
        {

            for ( int a = 0; a < this.DHONick.Length; a++ )
            {
                if ( this.DHONick[a] == null )
                {
                    this.DHONick[a] = nick;
                    break;
                }
            }
        }

        // Add Ban Host
        private void    addBanhostToArray( string host )
        {

            for ( int a = 0; a < this.BHost.Length; a++ )
            {
                if ( this.BHost[a] == null )
                {
                    this.BHost[a] = host;
                    break;
                }
            }
        }

        // Add Unban Host
        private void    addUnbanhostToArray( string host )
        {

            for ( int a = 0; a < this.UBHost.Length; a ++ )
            {
                if ( this.UBHost[a] == null )
                {
                    this.UBHost[a] = host;
                    break;
                }
            }
        }
    }
}