Exemple #1
0
 /// <summary>
 /// Triggers when the users list is received, continued, or ends
 /// </summary>
 /// <param name="e">The arguments with the list of users</param>
 protected virtual void OnUserList(UserListEventArgs e)
 {
     EventHandler<UserListEventArgs> handler = UserList;
     handler?.Invoke(this, e);
 }
Exemple #2
0
        /// <summary>
        /// Triggers when the users list is received, continued, or ends
        /// </summary>
        /// <param name="e">The arguments with the list of users</param>
        protected virtual void OnUserList(UserListEventArgs e)
        {
            EventHandler <UserListEventArgs> handler = UserList;

            handler?.Invoke(this, e);
        }
Exemple #3
0
        /// <summary>
        /// IRC protocol implementation per IRC RFC 2812 https://tools.ietf.org/html/rfc2812
        /// </summary>
        public void ReadProtocol()
        {
            var command = _sr.ReadLine();
            Console.WriteLine(command);

            IRCCommand cmd = IRCCommand.Parse(command);
            if (command == null || cmd == null) return;

            switch (cmd.Command)
            {
                case "001": //RPL_WELCOME
                case "002": //RPL_YOURHOST
                case "003": //RPL_CREATED
                case "004": //RPL_MYINFO
                case "NOTICE": //NOTICE
                    OnServerMessage(command);
                    SendCommand("JOIN " + Channel);
                    break;
                case "332":
                    OnServerMessage(command);
                    break;
                case "353": //RPL_NAMREPLY
                    //make sure if for this channel,
                    //i think i might get lists for all
                    //channels in the server.
                    if (cmd.Arguments[2] == Channel)
                    {
                        //lists of users for the channel we are connected
                        //lets ignore the type of channels for now (@, =, *)
                        var ulea = new UserListEventArgs
                        {
                            Users = new List<string>(cmd.Arguments[3].Split(' '))
                        };

                        //checks if the command before this one was a 353,
                        //if it is, that means the list of users was not completely
                        //received, so this packet is a continuation of the list.
                        //otherwise, this is the beginning of the list.
                        if (_previousCommand != "353")
                        {
                            ulea.Type = UserListMessageType.ListStart;
                        }
                        else if (_previousCommand == "353")
                        {
                            ulea.Type = UserListMessageType.ListContinue;
                        }

                        OnUserList(ulea);
                    }
                    break;
                case "366": //RPL_ENDOFNAMES
                    //this is the end of the list of users.
                    OnUserList(new UserListEventArgs() { Type = UserListMessageType.ListEnd });
                    break;
                case "433": //ERR_NICKNAMEINUSE
                    //tries to log in with a different nickname
                    SendCommand("NICK " + Nickname + "_" + new Random().Next(100));
                    break;
                case "PRIVMSG": //new message to the channel, or private
                    ReceivedEventArgs rec = new ReceivedEventArgs
                    {
                        MessageFrom = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal))
                    };

                    //TODO: handle messages that are for specific users, and show them in a unique way
                    //maybe something like FromUser > ToUser: Hello, World!

                    //let us worry about
                    //public and private messages only
                    if (cmd.Arguments[0] == Nickname)
                    {
                        rec.Type = MessageType.MessageToMe;
                    }
                    else
                    {
                        rec.Type = MessageType.MessageToChannel;
                    }

                    rec.Message = cmd.Arguments[1];
                    OnReceived(rec);
                    break;
                case "PING": //reply with pong :p
                    SendCommand("PONG " + command.Substring(5));
                    break;
                case "JOIN": //someone joined the channel
                    //two options: We could either re-ask for the entire list
                    //or simply add the specific user
                    string userJoined = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal));
                    if (userJoined != Nickname)
                    {
                        OnUserJoined(userJoined);
                    }
                    else
                    {
                        //this is when I joined the channel.
                        OnConnected();
                        IsConnected = true;
                    }
                    break;
                case "PART": //someone has left/quit the channel
                case "QUIT":
                    string userLeft = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal));
                    if (userLeft != Nickname)
                    {
                        OnUserQuit(userLeft);
                    }
                    else
                    {
                        //leave chatroom gracefully
                        OnQuit();
                        IsConnected = false;
                    }
                    break;
                case "NICK": //change in nick

                    if (cmd.Arguments != null && cmd.Arguments.Count > 0)
                    {
                        var newNickname = cmd.Arguments[0];
                        var oldNickname = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal));

                        //raise this event to update the nickname in the lists
                        OnNicknameChanged(oldNickname, newNickname, NicknameChangedType.NickChanged);
                    }

                    break;
                case "ERROR":
                    OnQuit();
                    IsConnected = false;
                    break;
            }

            _previousCommand = cmd.Command;
        }
Exemple #4
0
        /// <summary>
        /// IRC protocol implementation per IRC RFC 2812 https://tools.ietf.org/html/rfc2812
        /// </summary>
        public void ReadProtocol()
        {
            var command = _sr.ReadLine();

            Console.WriteLine(command);

            IRCCommand cmd = IRCCommand.Parse(command);

            if (command == null || cmd == null)
            {
                return;
            }

            switch (cmd.Command)
            {
            case "001":     //RPL_WELCOME
            case "002":     //RPL_YOURHOST
            case "003":     //RPL_CREATED
            case "004":     //RPL_MYINFO
            case "NOTICE":  //NOTICE
                OnServerMessage(command);
                SendCommand("JOIN " + Channel);
                break;

            case "332":
                OnServerMessage(command);
                break;

            case "353":     //RPL_NAMREPLY
                //make sure if for this channel,
                //i think i might get lists for all
                //channels in the server.
                if (cmd.Arguments[2] == Channel)
                {
                    //lists of users for the channel we are connected
                    //lets ignore the type of channels for now (@, =, *)
                    var ulea = new UserListEventArgs
                    {
                        Users = new List <string>(cmd.Arguments[3].Split(' '))
                    };


                    //checks if the command before this one was a 353,
                    //if it is, that means the list of users was not completely
                    //received, so this packet is a continuation of the list.
                    //otherwise, this is the beginning of the list.
                    if (_previousCommand != "353")
                    {
                        ulea.Type = UserListMessageType.ListStart;
                    }
                    else if (_previousCommand == "353")
                    {
                        ulea.Type = UserListMessageType.ListContinue;
                    }

                    OnUserList(ulea);
                }
                break;

            case "366":     //RPL_ENDOFNAMES
                //this is the end of the list of users.
                OnUserList(new UserListEventArgs()
                {
                    Type = UserListMessageType.ListEnd
                });
                break;

            case "433":     //ERR_NICKNAMEINUSE
                //tries to log in with a different nickname
                SendCommand("NICK " + Nickname + "_" + new Random().Next(100));
                break;

            case "PRIVMSG":     //new message to the channel, or private
                ReceivedEventArgs rec = new ReceivedEventArgs
                {
                    MessageFrom = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal))
                };

                //TODO: handle messages that are for specific users, and show them in a unique way
                //maybe something like FromUser > ToUser: Hello, World!

                //let us worry about
                //public and private messages only
                if (cmd.Arguments[0] == Nickname)
                {
                    rec.Type = MessageType.MessageToMe;
                }
                else
                {
                    rec.Type = MessageType.MessageToChannel;
                }

                rec.Message = cmd.Arguments[1];
                OnReceived(rec);
                break;

            case "PING":     //reply with pong :p
                SendCommand("PONG " + command.Substring(5));
                break;

            case "JOIN":     //someone joined the channel
                //two options: We could either re-ask for the entire list
                //or simply add the specific user
                string userJoined = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal));
                if (userJoined != Nickname)
                {
                    OnUserJoined(userJoined);
                }
                else
                {
                    //this is when I joined the channel.
                    OnConnected();
                    IsConnected = true;
                }
                break;

            case "PART":     //someone has left/quit the channel
            case "QUIT":
                string userLeft = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal));
                if (userLeft != Nickname)
                {
                    OnUserQuit(userLeft);
                }
                else
                {
                    //leave chatroom gracefully
                    OnQuit();
                    IsConnected = false;
                }
                break;

            case "NICK":     //change in nick

                if (cmd.Arguments != null && cmd.Arguments.Count > 0)
                {
                    var newNickname = cmd.Arguments[0];
                    var oldNickname = cmd.Prefix.Substring(0, cmd.Prefix.IndexOf("!", StringComparison.Ordinal));

                    //raise this event to update the nickname in the lists
                    OnNicknameChanged(oldNickname, newNickname, NicknameChangedType.NickChanged);
                }

                break;

            case "ERROR":
                OnQuit();
                IsConnected = false;
                break;
            }

            _previousCommand = cmd.Command;
        }