Example #1
0
    /// <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;
        }
    }