示例#1
0
        private void Send(string cmd)
        {
            cmd = cmd + "\r\n";
            byte[] sndBuffer = Encoding.Default.GetBytes(cmd);
            string outText   = AsciiDecoder.AsciiToUnicode(sndBuffer, sndBuffer.Length);

            _textProcessor.AllText += outText;
            List <MUDTextRun> runs = this._ansiColorParser.Translate((char)27 + "[1;33m" + cmd.Replace("\r\n", "") + (char)27 + "[0;66m");

            //fire the "received a server message" event with the runs to be displayed
            App.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                if (serverMessage != null)
                {
                    this.serverMessage(runs);
                }
            }));

            try
            {
                //send to server
                _stream.Write(sndBuffer, 0, sndBuffer.Length);
            }
            catch (Exception e)
            {
                Disconnect();
                Connect("mud.pkuxkx.net", 8080);
            }
        }
示例#2
0
        public List <byte> HandleAndRemoveTelnetBytes(byte[] buffer, int receivedCount, out List <string> telnetMessages)
        {
            //list to hold a report of any telnet control sequences received or sent
            telnetMessages = new List <string>();

            //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
                {
                    //start building a string representation of this message, to be reported to the caller
                    //caller might want to show this info to the user always, or optionally for debugging purposes
                    StringBuilder stringVersionOfMessage = new StringBuilder();

                    //also build a string version of the response (if any)
                    StringBuilder stringVersionOfResponse = new StringBuilder();

                    //DO
                    if (secondByte == (byte)Telnet.DO)
                    {
                        stringVersionOfMessage.Append("DO ");

                        //what are we being told to do?
                        currentIndex++;
                        if (currentIndex == receivedCount)
                        {
                            break;
                        }
                        byte thirdByte = buffer[currentIndex];

                        stringVersionOfMessage.Append(interpretByteAsTelnet(thirdByte));

                        //if NAWS (negotiate about window size)
                        if (thirdByte == (byte)Telnet.NAWS)
                        {
                            //on connection, we offered to negotiate about window size.  so this is a "go ahead and negotiate" response.
                            //so then, send information about client window size per the NAWS protocol
                            //we're lieing to server by telling it a ridiculously large size, so that it won't do line breaking or paging for us (annoying!)
                            stringVersionOfResponse.Append(this.sendTelnetBytes(
                                                               (byte)Telnet.SubnegotiationBegin, (byte)31,
                                                               254, 254, 254, 254,
                                                               (byte)Telnet.InterpretAsCommand, (byte)Telnet.SubnegotiationEnd));
                        }

                        //everything else the server might ask us to do is unsupported by us
                        else
                        {
                            stringVersionOfMessage.Append(interpretByteAsTelnet(thirdByte));

                            //sorry, i won't do whatever "that thing you said to do" was
                            stringVersionOfResponse.Append(this.sendTelnetBytes((byte)Telnet.InterpretAsCommand, (byte)Telnet.WONT, thirdByte));
                        }
                    }

                    //DONT
                    else if (secondByte == (byte)Telnet.DONT)
                    {
                        stringVersionOfMessage.Append("DONT ");

                        currentIndex++;
                        if (currentIndex == receivedCount)
                        {
                            break;
                        }
                        byte thirdByte = buffer[currentIndex];

                        stringVersionOfMessage.Append(interpretByteAsTelnet(thirdByte));

                        //whatever you want me to stop doing, that's no problem because i wasn't going to do it anyway
                        stringVersionOfResponse.Append(this.sendTelnetBytes((byte)Telnet.WONT, thirdByte));
                    }

                    //WILL
                    else if (secondByte == (byte)Telnet.WILL)
                    {
                        stringVersionOfMessage.Append("WILL ");

                        //find out what the server is willing to do
                        currentIndex++;
                        if (currentIndex == receivedCount)
                        {
                            break;
                        }
                        byte thirdByte = buffer[currentIndex];
                        stringVersionOfMessage.Append(interpretByteAsTelnet(thirdByte));

                        //anything the server offers to do for us, we'll tell it not to because we don't know what it is
                        stringVersionOfResponse.Append((this.sendTelnetBytes((byte)Telnet.DONT, thirdByte)));
                    }

                    //WONT
                    else if (secondByte == (byte)Telnet.WONT)
                    {
                        stringVersionOfMessage.Append("WONT ");

                        //find out what the server is NOT willing to do
                        currentIndex++;
                        if (currentIndex == receivedCount)
                        {
                            break;
                        }
                        byte thirdByte = buffer[currentIndex];

                        stringVersionOfMessage.Append(interpretByteAsTelnet(thirdByte));

                        //because we haven't asked the server to DO anything, should not expect to receive any WONT
                        //however if we do receive a WONT, respond with a DONT to confirm that the server can go ahead and NOT do that thing it doesn't want to do
                        stringVersionOfResponse.Append(this.sendTelnetBytes((byte)Telnet.DONT, thirdByte));
                    }

                    //subnegotiations
                    else if (secondByte == (byte)Telnet.SubnegotiationBegin)
                    {
                        stringVersionOfMessage.Append("SB ");
                        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
                        stringVersionOfMessage.Append(AsciiDecoder.AsciiToUnicode(subnegotiationBytesArray, subnegotiationBytes.Count));

                        //append the subnegotiation end
                        stringVersionOfMessage.Append(" SE");
                    }

                    //any other telnet message
                    else
                    {
                        //try to convert it to a known message via the enum defined above
                        stringVersionOfMessage.Append(interpretByteAsTelnet(secondByte));
                    }

                    //report the control sequence we found, if any
                    string messageToReport = stringVersionOfMessage.ToString();
                    if (!string.IsNullOrEmpty(messageToReport))
                    {
                        telnetMessages.Add("RECV: " + messageToReport.ToString());
                    }

                    //report the response message sent, if any
                    string responseToReport = stringVersionOfResponse.ToString();
                    if (!string.IsNullOrEmpty(responseToReport))
                    {
                        telnetMessages.Add("SEND: " + stringVersionOfResponse.ToString());
                    }
                }
                //move up to the next byte in the data
                currentIndex++;
            }

            return(contentBytes);
        }
示例#3
0
        //called when receiving any message
        void handleServerMessage(IAsyncResult result)
        {
            try
            {
                NetworkStream ns;
                //get length of data in buffer
                int receivedCount;
                try
                {
                    ns            = (NetworkStream)result.AsyncState;
                    receivedCount = ns.EndRead(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 <string> telnetMessages;
                List <byte>   contentBytes = this._telnetParser.HandleAndRemoveTelnetBytes(this._rcvBuffer, receivedCount, out telnetMessages);

                //report any telnet sequences seen to the caller
                App.Current.Dispatcher.BeginInvoke(new Action(delegate
                {
                    foreach (string telnetMessage in telnetMessages)
                    {
                        //fire the "received a server message" event
                        this.telnetMessage(telnetMessage);
                    }
                }));

                //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);
                _textProcessor.AllText    += message;
                _textProcessor.CurrentText = message;
                _textProcessor.ProcessText();
                //run the following on the main thread so that calling code doesn't have to think about threading

                if (this.serverMessage != null)
                {
                    App.Current.Dispatcher.BeginInvoke(new Action(delegate
                    {
                        //pass the message to the mudTranslator to parse any ANSI control sequences (colors!)
                        List <MUDTextRun> runs = this._ansiColorParser.Translate(message);

                        //fire the "received a server message" event with the runs to be displayed
                        this.serverMessage(runs);
                    }));
                }

                //now that we're done with this message, listen for the next message
                ns.BeginRead(_rcvBuffer, 0, _rcvBuffer.Length, new AsyncCallback(handleServerMessage), _stream);
            }
            catch (Exception e)
            {
                System.Windows.MessageBox.Show(e.Message + "\r\n" + e.StackTrace);
            }
        }