コード例 #1
0
        public void ProcessFirstGameDataFrame(ref Byte[] frameData)
        {
            // A svc_director message preceeds svc_spawnbaseline in newer HLTV demos. The director message is used to initialise and reset the HUD. Since old HLTV demos omit this message, it can be added here (and set the perspective to first-person too).
            if (demo.Perspective != Demo.Perspectives.Hltv || haveParsedDirectorMessage)
            {
                return;
            }

            const Byte DRC_CMD_START = 1;
            const Byte DRC_CMD_MODE  = 3;
            const Byte OBS_IN_EYE    = 4;

            // Create a svc_director message to initialise the HUD.
            BitWriter directorMessage = new BitWriter();

            directorMessage.WriteByte((Byte)HalfLifeDemoParser.MessageId.svc_director);
            directorMessage.WriteByte(1); // length
            directorMessage.WriteByte(DRC_CMD_START);

            // Create a svc_director message to set the perspective to first-person.
            directorMessage.WriteByte((Byte)HalfLifeDemoParser.MessageId.svc_director);
            directorMessage.WriteByte(2); // length
            directorMessage.WriteByte(DRC_CMD_MODE);
            directorMessage.WriteByte(OBS_IN_EYE);

            // Insert the new messages.
            BitBuffer bitBuffer = new BitBuffer(frameData);

            bitBuffer.InsertBytes(directorMessage.Data);

            frameData = bitBuffer.Data;
        }
コード例 #2
0
        public void ProcessFirstGameDataFrame(ref Byte[] frameData)
        {
            // A svc_director message preceeds svc_spawnbaseline in newer HLTV demos. The director message is used to initialise and reset the HUD. Since old HLTV demos omit this message, it can be added here (and set the perspective to first-person too).
            if (demo.Perspective != Demo.Perspectives.Hltv || haveParsedDirectorMessage)
            {
                return;
            }

            const Byte DRC_CMD_START = 1;
            const Byte DRC_CMD_MODE = 3;
            const Byte OBS_IN_EYE = 4;

            // Create a svc_director message to initialise the HUD.
            BitWriter directorMessage = new BitWriter();
            directorMessage.WriteByte((Byte)HalfLifeDemoParser.MessageId.svc_director);
            directorMessage.WriteByte(1); // length
            directorMessage.WriteByte(DRC_CMD_START);

            // Create a svc_director message to set the perspective to first-person.
            directorMessage.WriteByte((Byte)HalfLifeDemoParser.MessageId.svc_director);
            directorMessage.WriteByte(2); // length
            directorMessage.WriteByte(DRC_CMD_MODE);
            directorMessage.WriteByte(OBS_IN_EYE);

            // Insert the new messages.
            BitBuffer bitBuffer = new BitBuffer(frameData);
            bitBuffer.InsertBytes(directorMessage.Data);

            frameData = bitBuffer.Data;
        }
コード例 #3
0
        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;
            }
        }