public void Seek(Int64 offset, SeekOrigin origin)
 {
     if (readingGameData)
     {
         Debug.Assert(offset <= Int32.MaxValue);
         bitBuffer.SeekBytes((Int32)offset, origin);
     }
     else
     {
         fileStream.Seek(offset, origin);
     }
 }
示例#2
0
        /// <summary>
        /// Parses S2C_PLAYER.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="si"></param>
        private void ParsePlayerQueryReply(BitBuffer bitBuffer)
        {
            Int32 nPlayers = bitBuffer.ReadByte();

            for (Int32 i = 0; i < nPlayers; i++)
            {
                bitBuffer.SeekBytes(1); // skip index

                Player player = new Player();
                player.Name = bitBuffer.ReadString();
                player.Score = bitBuffer.ReadInt32();
                Single time = bitBuffer.ReadSingle();
                player.Time = (time == -1 ? "BOT" : Common.DurationString(time));

                mainWindowInterface.AddPlayerToServer(this, player);
            }
        }
示例#3
0
        /// <summary>
        /// Parses S2C_INFO.
        /// </summary>
        /// <param name="data"></param>
        /// <param name="si"></param>
        private void ParseInfoQueryReply(Byte[] data)
        {
            BitBuffer bitBuffer = new BitBuffer(data);

            if (bitBuffer.ReadInt32() != -1)
            {
                throw new ApplicationException("Bad A2S_INFO reply");
            }

            // read reply type
            Byte type = bitBuffer.ReadByte();
            Boolean sourceEngine;

            if (type == S2C_INFO_SOURCE)
            {
                sourceEngine = true;
            }
            else if (type == S2C_INFO_GOLDSRC)
            {
                sourceEngine = false;
            }
            else
            {
                throw new ApplicationException(String.Format("Bad A2S_INFO type: {0}", type));
            }

            mainWindowInterface.SetServerProperty(this, "SourceEngine", sourceEngine);

            // read the rest
            if (!sourceEngine)
            {
                bitBuffer.ReadString();
                //si.Address = bitBuffer.ReadString(); // resolved hostname
            }
            else
            {
                bitBuffer.SeekBytes(1); // network version
            }

            mainWindowInterface.SetServerProperty(this, "Title", bitBuffer.ReadString()); // server name
            mainWindowInterface.SetServerProperty(this, "Map", bitBuffer.ReadString()); // map
            String gameFolder = bitBuffer.ReadString();
            mainWindowInterface.SetServerProperty(this, "GameFolder", gameFolder); // game folder
            String gameName = bitBuffer.ReadString(); // game name

            if (sourceEngine)
            {
                bitBuffer.SeekBytes(2); // app id
            }

            mainWindowInterface.SetServerProperty(this, "NumSpectators", bitBuffer.ReadByte()); // num spectators
            mainWindowInterface.SetServerProperty(this, "MaxSpectators", bitBuffer.ReadByte()); // max spectators
            bitBuffer.SeekBytes(1); // goldsrc: network version, source: num bots
            bitBuffer.SeekBytes(1); // dedicated
            bitBuffer.SeekBytes(1); // os
            mainWindowInterface.SetServerProperty(this, "PasswordProtected", (bitBuffer.ReadByte() == 1));

            // determine game name
            Game game = GameManager.Find((sourceEngine ? Game.Engines.Source : Game.Engines.HalfLife), gameFolder);

            if (game == null)
            {
                mainWindowInterface.SetServerProperty(this, "GameName", gameName);
            }
            else
            {
                mainWindowInterface.SetServerProperty(this, "GameName", game.Name);
            }
        }
        public void ParseGameDataMessages(Byte[] frameData, Function <Byte, Byte> userMessageCallback)
        {
            Int64 gameDataStartOffset = fileStream.Position - frameData.Length;

            // read game data frame into memory
            bitBuffer       = new BitBuffer(frameData);
            readingGameData = true;

            try
            {
                BeginMessageLog(gameDataStartOffset, frameData);

                // start parsing messages
                while (true)
                {
                    Int32  messageFrameOffset = bitBuffer.CurrentByte;
                    Byte   messageId          = bitBuffer.ReadByte();
                    String messageName        = Enum.GetName(typeof(MessageId), messageId);

                    if (messageName == null) // a user message, presumably
                    {
                        messageName = FindMessageIdString(messageId);
                    }

                    LogMessage(messageId, messageName, messageFrameOffset);

                    MessageHandler messageHandler = FindMessageHandler(messageId);

                    // Handle the conversion of user message id's.
                    // Used by demo writing to convert to the current network protocol.
                    if (messageId > 64 && userMessageCallback != null)
                    {
                        Byte newMessageId = userMessageCallback(messageId);

                        if (newMessageId != messageId)
                        {
                            // write the new id to the bitbuffer
                            bitBuffer.SeekBytes(-1);
                            bitBuffer.RemoveBytes(1);
                            bitBuffer.InsertBytes(new Byte[] { newMessageId });
                        }
                    }

                    // unknown message
                    if (messageHandler == null)
                    {
                        throw new ApplicationException(String.Format("Cannot find message handler for message id \"[{0}] {1}\"", messageId, messageName));
                    }

                    // callback takes priority over length
                    if (messageHandler.Callback != null)
                    {
                        messageHandler.Callback();
                    }
                    else if (messageHandler.Length != -1)
                    {
                        Seek(messageHandler.Length);
                    }
                    else
                    {
                        // user messages
                        if (messageId >= 64)
                        {
                            // All non-engine user messages start with a byte that is the number of bytes in the message remaining.
                            Byte length = bitBuffer.ReadByte();
                            Seek(length);
                        }
                        else
                        {
                            throw new ApplicationException(String.Format("Unknown message id \"{0}\"", messageId));
                        }
                    }

                    // Check if we've reached the end of the frame, or if any of the messages have called SkipGameDataFrame (readingGameData will be false).
                    if (bitBuffer.CurrentByte == bitBuffer.Length || !readingGameData)
                    {
                        break;
                    }
                }
            }
            finally
            {
                readingGameData = false;
            }
        }