/// <summary> /// Triggers when we want to send some kind of message to the user. /// </summary> /// <param name="e">The message received, which includes the type of data.</param> protected virtual void OnReceived(ReceivedEventArgs e) { EventHandler<ReceivedEventArgs> handler = Received; handler?.Invoke(this, e); }
/// <summary> /// Triggers when we want to send some kind of message to the user. /// </summary> /// <param name="e">The message received, which includes the type of data.</param> protected virtual void OnReceived(ReceivedEventArgs e) { EventHandler <ReceivedEventArgs> handler = Received; handler?.Invoke(this, e); }
/// <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; }
/// <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; }