/// <summary> /// Parses an incoming message from the IRC server. /// This will dispatch events based on the basic content of the message. /// Handles server & channel joins, parts, quits, and classifies incoming messages. /// </summary> /// <param name="data">The complete line from the IRCd</param> private void ParseData(string data) { // split the data into parts string[] ircData = data.Split(' '); if (OnServerRawMessage != null) { OnServerRawMessage(data); } // PING messages need to be responded with PONG as quickly as possible. if (data.Length > 4) { if (data.Substring(0, 4) == "PING") { SendLine("PONG " + ircData[1]); if (OnServerPong != null) { OnServerPong(); // Notify subscribers that a keepalive happened. } return; } } // react according to the incoming IRC message switch (ircData[1]) { case "001": // server welcome message, after this we can send commands SendLine("MODE " + Nickname + " +R"); // Prevents receiving private messages from unidentified users //SendLine("MODE " + Nickname + " +i"); // Set this client 'invisible' if (OnServerConnected != null) { OnServerConnected(); // Notify any subscribers that we connected to the server successfully. } break; case "002": // ignore case "003": // ignore case "004": // ignore case "005": // ignore case "250": // ignore case "251": // ignore case "252": // ignore case "254": // ignore case "255": // ignore case "265": // ignore case "266": // ignore break; case "353": // names reply Debug.Log("Got some names."); break; case "366": // end of names reply Debug.Log("Got all names."); break; case "372": // server MOTD message, we can ignore this. case "375": // server MOTD message begins, we can ignore this. break; case "376": // server MOTD message finished, after this we can join channels. SendLine("MODE " + Nickname + " +R"); // Prevents receiving private messages from unidentified users //SendLine("MODE " + Nickname + " +i"); // Set this client 'invisible' ircConnected = true; // At this point we're ready to join channels and interact normally. if (OnConnected != null) { OnConnected(); // Notify any subscribers that we are ready. } break; case "404": // Could not send to channel, we can ignore this for now. break; case "JOIN": // someone joined if (MessageDebug) { Instance.Message("HELLO MESSAGE: |" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } if (Instance.OnUserJoined != null) { Instance.OnUserJoined(new UserJoinedEventArgs(ircData[2], ircData[0].Substring(1, ircData[0].IndexOf("!") - 1))); } break; case "NOTICE": // Server notices, ignore for now if (ircConnected) // We get some notices during early connect phase, ignore them. { if (MessageDebug) { Instance.Message("NOTICE: |" + JoinArray(ircData, 3) + "|" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } if (ircData[2].ToLower() != Nickname.ToLower()) // Doesn't match our nickname... { if (OnChannelNotice != null) { OnChannelNotice(new ChannelNoticeEventArgs(ircData[2], ircData[0].Substring(1, ircData[0].IndexOf('!') - 1), JoinArray(ircData, 3))); } } else { if (OnUserNotice != null) { OnUserNotice(new UserNoticeEventArgs(ircData[0].Substring(1, ircData[0].IndexOf('!') - 1), JoinArray(ircData, 3))); } } } break; case "PRIVMSG": // message was sent to the channel or as private if (MessageDebug) { Instance.Message("PRIVMSG: |" + JoinArray(ircData, 3) + "|" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } if (ircData[2].ToLower() != Nickname.ToLower()) // Doesn't match our nickname... { if (ircData[3].Contains("\x01")) // This is a special message. like an ACTION or VERSION { if (MessageDebug) { Instance.Message("SPECIAL: |" + JoinArray(ircData, 3) + "|" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } if (ircData[3].StartsWith(":" + "\x01")) // This is a ACTION message. { if (OnChannelAction != null) { OnChannelAction(new ChannelActionEventArgs(ircData[2], ircData[0].Substring(1, ircData[0].IndexOf('!') - 1), JoinArray(ircData, 3))); } break; } else { string[] ctcpWrapper = ircData[3].Split('\x01'); string[] ctcpData = ctcpWrapper[1].Split(' '); ParseCTCP(ctcpData); break; } } if (ircData[3] == ":" + IpcIrc.Instance.Nickname + ":") // it's a directed public message { if (OnChannelDirectedMessage != null) { OnChannelDirectedMessage(new ChannelDirectedMessageEventArgs(ircData[2], ircData[0].Substring(1, ircData[0].IndexOf('!') - 1), JoinArray(ircData, 3))); } break; } else // it's a public message { if (OnChannelMessage != null) { OnChannelMessage(new ChannelMessageEventArgs(ircData[2], ircData[0].Substring(1, ircData[0].IndexOf('!') - 1), JoinArray(ircData, 3))); } break; } } else // it's a private message { if (ircData[3].Contains("\x01")) // This is a special message. like an ACTION or VERSION { if (MessageDebug) { Instance.Message("PRIVATE SPECIAL: |" + JoinArray(ircData, 3) + "|" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } if (ircData[3].StartsWith(":" + "\x01")) // This is a ACTION message. { if (OnUserAction != null) { OnUserAction(new UserActionEventArgs(ircData[0].Substring(1, ircData[0].IndexOf('!') - 1), JoinArray(ircData, 3))); } break; } else { string[] ctcpWrapper = ircData[3].Split('\x01'); string[] ctcpData = ctcpWrapper[1].Split(' '); ParseCTCP(ctcpData); break; } } // Nothing special, just a normal user private message. if (OnUserMessage != null) { OnUserMessage(new UserMessageEventArgs(ircData[0].Substring(1, ircData[0].IndexOf('!') - 1), JoinArray(ircData, 3))); } break; } case "PART": case "QUIT": // someone left if (MessageDebug) { Instance.Message("GOODBYE MESSAGE: |" + JoinArray(ircData, 3) + "|" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } if (OnUserLeft != null) { OnUserLeft(new UserLeftEventArgs(ircData[2], ircData[0].Substring(1, data.IndexOf("!") - 1))); } break; default: // still using this while debugging String.Join("|", ircData) if (MessageDebug) { Instance.Message("UNKNOWN MESSAGE: |" + JoinArray(ircData, 3) + "|" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } if (MessageDebug) { Debug.Log("UNKNOWN MESSAGE: |" + JoinArray(ircData, 3) + "|" + ircData[2] + "|" + ircData[1] + "|" + ircData[0] + "|"); } //if (ircData.Length > 3) if (OnServerMessage != null) OnServerMessage(JoinArray(ircData, 3)); // Cut string at index 3 if we've got four or more elements. if (ircData.Length > 1) { if (OnServerMessage != null) { OnServerMessage(JoinArray(ircData, 0)); // Cut string at index 3 if we've got four or more elements. } } break; } }