fCraft.IRC.MessageParser C# (CSharp) Method

MessageParser() private static method

private static MessageParser ( [ rawline, [ actualBotNick ) : IRCMessage
rawline [
actualBotNick [
return IRCMessage
        private static IRCMessage MessageParser( [NotNull] string rawline, [NotNull] string actualBotNick ) {
            if ( rawline == null )
                throw new ArgumentNullException( "rawline" );
            if ( actualBotNick == null )
                throw new ArgumentNullException( "actualBotNick" );

            string line;
            string nick = null;
            string ident = null;
            string host = null;
            string channel = null;
            string message = null;
            IRCReplyCode replycode;

            if ( rawline[0] == ':' ) {
                line = rawline.Substring( 1 );
            } else {
                line = rawline;
            }

            string[] linear = line.Split( new[] { ' ' } );

            // conform to RFC 2812
            string from = linear[0];
            string messagecode = linear[1];
            int exclamationpos = from.IndexOf( '!' );
            int atpos = from.IndexOf( '@' );
            int colonpos = line.IndexOfOrdinal( " :" );
            if ( colonpos != -1 ) {
                // we want the exact position of ":" not beginning from the space
                colonpos += 1;
            }
            if ( exclamationpos != -1 ) {
                nick = from.Substring( 0, exclamationpos );
            }
            if ( ( atpos != -1 ) &&
                ( exclamationpos != -1 ) ) {
                ident = from.Substring( exclamationpos + 1, ( atpos - exclamationpos ) - 1 );
            }
            if ( atpos != -1 ) {
                host = from.Substring( atpos + 1 );
            }

            try {
                replycode = ( IRCReplyCode )int.Parse( messagecode );
            } catch ( FormatException ) {
                replycode = IRCReplyCode.Null;
            }
            IRCMessageType type = GetMessageType( rawline, actualBotNick );
            if ( colonpos != -1 ) {
                message = line.Substring( colonpos + 1 );
            }

            switch ( type ) {
                case IRCMessageType.Join:
                case IRCMessageType.Kick:
                case IRCMessageType.Part:
                case IRCMessageType.TopicChange:
                case IRCMessageType.ChannelModeChange:
                case IRCMessageType.ChannelMessage:
                case IRCMessageType.ChannelAction:
                case IRCMessageType.ChannelNotice:
                    channel = linear[2];
                    break;

                case IRCMessageType.Who:
                case IRCMessageType.Topic:
                case IRCMessageType.Invite:
                case IRCMessageType.BanList:
                case IRCMessageType.ChannelMode:
                    channel = linear[3];
                    break;

                case IRCMessageType.Name:
                    channel = linear[4];
                    break;
            }

            if ( ( channel != null ) &&
                ( channel[0] == ':' ) ) {
                channel = channel.Substring( 1 );
            }

            return new IRCMessage( from, nick, ident, host, channel, message, rawline, type, replycode );
        }

Usage Example

Example #1
0
            void HandleMessage([NotNull] string message)
            {
                if (message == null)
                {
                    throw new ArgumentNullException("message");
                }

                IRCMessage msg      = IRC.MessageParser(message, ActualBotNick);
                var        SendList = Server.Players.Where(p => !p.IsDeaf && !p.GlobalChatIgnore);

#if DEBUG_IRC
                Logger.Log(LogType.IRC,
                           "[{0}]: {1}",
                           msg.Type, msg.RawMessage);
#endif

                switch (msg.Type)
                {
                case IRCMessageType.Login:
                    foreach (string channel in channelNames)
                    {
                        Send(IRCCommands.Join(channel));
                    }
                    IsReady = true;
                    AssignBotForInputParsing();     // bot should be ready to receive input after joining
                    return;


                case IRCMessageType.Ping:
                    // ping-pong
                    Send(IRCCommands.Pong(msg.RawMessageArray[1].Substring(1)));
                    return;


                case IRCMessageType.ChannelAction:
                case IRCMessageType.ChannelMessage:
                    // channel chat
                    if (!ResponsibleForInputParsing)
                    {
                        return;
                    }
                    string processedMessage = msg.Message;
                    if (msg.Type == IRCMessageType.ChannelAction)
                    {
                        if (processedMessage.StartsWith("\u0001ACTION"))
                        {
                            processedMessage = processedMessage.Substring(8);
                        }
                        else
                        {
                            return;
                        }
                    }

                    processedMessage = IRC.NonPrintableChars.Replace(processedMessage, "");
                    if (processedMessage.Length > 0)
                    {
                        if (msg.Type == IRCMessageType.ChannelAction)
                        {
                            SendList.Message("&g[Global] * {1} {2}", ActualBotNick, msg.Nick, processedMessage);
                            Logger.Log(LogType.GlobalChat, "[Global] * {1} {2}", ActualBotNick, msg.Nick, processedMessage);
                        }
                        else
                        {
                            SendList.Message("&g[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage);
                            Logger.Log(LogType.GlobalChat, "[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage);
                        }
                    }

                    else if (msg.Message.StartsWith("#"))
                    {
                        SendList.Message("&g[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage.Substring(1));
                        Logger.Log(LogType.GlobalChat, "[Global] {1}: {2}", ActualBotNick, msg.Nick, processedMessage.Substring(1));
                    }
                    return;


                case IRCMessageType.Join:
                    if (!ResponsibleForInputParsing)
                    {
                        return;
                    }
                    if (msg.Nick.StartsWith("("))
                    {
                        SendList.Message("&g[Global] Server {0} joined the LegendCraft Global Chat", msg.Nick);
                        Logger.Log(LogType.GlobalChat, "[Global] Server {0} joined the LegendCraft Global Chat", msg.Nick);
                    }
                    else
                    {
                        SendList.Message("&g[Global] {0} joined the LegendCraft Global Chat", msg.Nick);
                        Logger.Log(LogType.GlobalChat, "[Global] {0} joined the LegendCraft Global Chat", msg.Nick);
                    }
                    return;


                case IRCMessageType.Kick:
                    string kicked = msg.RawMessageArray[3];
                    if (kicked == ActualBotNick)
                    {
                        Logger.Log(LogType.SystemActivity, "Bot was kicked from {0} by {1} ({2}), rejoining.", msg.Channel, msg.Nick, msg.Message);
                        Thread.Sleep(ReconnectDelay);
                        Send(IRCCommands.Join(msg.Channel));
                    }
                    else
                    {
                        if (!ResponsibleForInputParsing)
                        {
                            return;
                        }
                        SendList.Message("&g[Global] {0} kicked {1} ({2})", msg.Nick, kicked, msg.Message);
                        Logger.Log(LogType.GlobalChat, "[Global] {0} kicked {1} ({2})", msg.Nick, kicked, msg.Message);
                    }
                    return;


                case IRCMessageType.Part:
                case IRCMessageType.Quit:
                    if (!ResponsibleForInputParsing)
                    {
                        return;
                    }
                    SendList.Message("&g[Global] Server {0} left the LegendCraft Global Chat", msg.Nick);
                    Logger.Log(LogType.GlobalChat, "[Global] Server {0} left the LegendCraft Global Chat", msg.Nick);
                    return;


                case IRCMessageType.NickChange:
                    if (!ResponsibleForInputParsing)
                    {
                        return;
                    }
                    SendList.Message("&g[Global] {0} is now known as {1}", msg.Nick, msg.Message);
                    Logger.Log(LogType.GlobalChat, "[Global] {0} is now known as {1}", msg.Nick, msg.Message);
                    return;


                case IRCMessageType.ErrorMessage:
                case IRCMessageType.Error:
                    bool die = false;
                    switch (msg.ReplyCode)
                    {
                    case IRCReplyCode.ErrorNicknameInUse:
                    case IRCReplyCode.ErrorNicknameCollision:
                        ActualBotNick = ActualBotNick.Remove(ActualBotNick.Length - 4) + "_";
                        Logger.Log(LogType.SystemActivity,
                                   "Error: Global Chat Nickname is already in use. Trying \"{0}\"",
                                   ActualBotNick);
                        Send(IRCCommands.Nick(ActualBotNick));
                        break;

                    case IRCReplyCode.ErrorBannedFromChannel:
                    case IRCReplyCode.ErrorNoSuchChannel:
                        Logger.Log(LogType.SystemActivity,
                                   "Error: {0} ({1})",
                                   msg.ReplyCode, msg.Channel);
                        GCReady = false;
                        die     = true;
                        break;

                    //wont happen
                    case IRCReplyCode.ErrorBadChannelKey:
                        Logger.Log(LogType.SystemActivity,
                                   "Error: Channel password required for {0}. LegendCraft does not currently support passworded channels.",
                                   msg.Channel);
                        die     = true;
                        GCReady = false;
                        break;

                    default:
                        Logger.Log(LogType.SystemActivity,
                                   "Error ({0}): {1}",
                                   msg.ReplyCode, msg.RawMessage);
                        GCReady = false;
                        break;
                    }

                    if (die)
                    {
                        Logger.Log(LogType.SystemActivity, "Error: Disconnecting from Global Chat.");
                        reconnect = false;
                        DisconnectThread();
                    }

                    return;


                case IRCMessageType.QueryAction:
                    // TODO: PMs
                    Logger.Log(LogType.SystemActivity,
                               "Query: {0}", msg.RawMessage);
                    break;


                case IRCMessageType.Kill:
                    Logger.Log(LogType.SystemActivity,
                               "Bot was killed from {0} by {1} ({2}), reconnecting.",
                               hostName, msg.Nick, msg.Message);
                    reconnect   = true;
                    isConnected = false;
                    return;
                }
            }