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; } }