Example #1
0
        void handleServerMessage(IAsyncResult result)
        {
            int receivedCount;

            try
            {
                receivedCount = connection.Client.EndReceive(result);
            }
            catch
            {
                //if there was any issue reading the server text, ignore the message (what else can we do?)
                return;
            }

            //0 bytes received means the server disconnected
            if (receivedCount == 0)
            {
                this.Disconnect();
                return;
            }

            //list of bytes which aren't telnet sequences
            //ultimately, this will be the original buffer minus any telnet messages from the server
            List <byte> contentBytes = this.telnetParser.HandleAndRemoveTelnetBytes(this.buffer, receivedCount);

            //now we've filtered-out and responded accordingly to any telnet data.
            //next, convert the actual MUD content of the message from ASCII to Unicode
            string message = AsciiDecoder.AsciiToUnicode(contentBytes.ToArray(), contentBytes.Count);

            //run the following on the main thread so that calling code doesn't have to think about threading
            if (this.serverMessage != null)
            {
                List <MUDToken> runs = this.ansiParser.Translate(message, this, telnetParser, TextGrouping);
                this.serverMessage(runs);
            }

            //now that we're done with this message, listen for the next message
            connection.Client.BeginReceive(this.buffer, 0, this.buffer.Length, SocketFlags.None, new AsyncCallback(this.handleServerMessage), null);
        }
Example #2
0
        public List <byte> HandleAndRemoveTelnetBytes(byte[] buffer, int receivedCount)
        {
            //list to hold any bytes which aren't telnet bytes (which will be most of the bytes)
            List <byte> contentBytes = new List <byte>();

            //we'll scan for telnet control sequences.  anything NOT a telnet control sequence will be added to the contentBytes list for later processing.
            int currentIndex = 0;

            while (currentIndex < receivedCount)
            {
                //search for an IAC, which may signal the beginning of a telnet message
                while (currentIndex < receivedCount && buffer[currentIndex] != (byte)Telnet.InterpretAsCommand)
                {
                    contentBytes.Add(buffer[currentIndex]);
                    currentIndex++;
                }

                //if at the end of the data, stop.  otherwise we've encountered an IAC and there should be at least one more byte here
                if (++currentIndex == receivedCount)
                {
                    break;
                }

                //read the next byte
                byte secondByte = buffer[currentIndex];

                //if another IAC, then this was just sequence IAC IAC, which is the escape sequence to represent byte value 255 (=IAC) in the content stream
                if (secondByte == (byte)Telnet.InterpretAsCommand)
                {
                    //write byte value 255 to the content stream and move on
                    contentBytes.Add(secondByte);
                }

                //otherwise we have a "real" telnet sequence, where the second byte is a command or negotiation
                else
                {
                    //DO
                    if (secondByte == (byte)Telnet.DO ||
                        secondByte == (byte)Telnet.DONT ||
                        secondByte == (byte)Telnet.WILL ||
                        secondByte == (byte)Telnet.WONT)
                    {
                        //what are we being told to do?
                        currentIndex++;
                        if (currentIndex == receivedCount)
                        {
                            break;
                        }
                        byte thirdByte = buffer[currentIndex];

                        if (secondByte == (byte)Telnet.WILL && thirdByte == (byte)Telnet.SuppressGoAhead)
                        {
                            this.sendTelnetBytes((byte)Telnet.DO, thirdByte);
                        }
                    }

                    //subnegotiations
                    else if (secondByte == (byte)Telnet.SubnegotiationBegin)
                    {
                        List <byte> subnegotiationBytes = new List <byte>();

                        //read until an IAC followed by an SE
                        while (currentIndex < receivedCount - 1 &&
                               !(buffer[currentIndex] == (byte)Telnet.InterpretAsCommand && buffer[currentIndex] == (byte)Telnet.SubnegotiationEnd))
                        {
                            subnegotiationBytes.Add(buffer[currentIndex]);
                            currentIndex++;
                        }

                        byte[] subnegotiationBytesArray = subnegotiationBytes.ToArray();

                        //append the content of the subnegotiation to the incoming message report string
                        AsciiDecoder.AsciiToUnicode(subnegotiationBytesArray, subnegotiationBytes.Count);
                    }
                }
                //move up to the next byte in the data
                currentIndex++;
            }

            return(contentBytes);
        }