private void GenerateThread() { parser = new SourceDemoParser((SourceDemo)demo); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_CreateStringTable, MessageCreateStringTable); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_UpdateStringTable, MessageUpdateStringTable); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_UserMessage, MessageUserMessage); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_GameEventList, MessageGameEventList); parser.Open(); parser.Seek(SourceDemo.HeaderSizeInBytes); // so we can detect when signon frames stop and packet frames start SourceDemoParser.FrameType lastFrameType = SourceDemoParser.FrameType.Signon; Int32 percentRead = 0; try { while (true) { SourceDemoParser.FrameType frameType = parser.ReadFrameHeader().Type; if (frameType == SourceDemoParser.FrameType.Stop) { progressWindowInterface.UpdateProgress(100); break; } else if (frameType == SourceDemoParser.FrameType.Signon || frameType == SourceDemoParser.FrameType.Packet) { if (lastFrameType == SourceDemoParser.FrameType.Signon && frameType == SourceDemoParser.FrameType.Packet) { parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.NET_Tick, MessageNetTick); } lastFrameType = frameType; parser.ReadCommandInfo(); parser.ReadSequenceInfo(); Int32 frameLength = parser.Reader.ReadInt32(); try { parser.ParsePacketMessages(frameLength); } catch (ThreadAbortException) { throw; } catch (Exception ex) { throw new ApplicationException("Message parsing error.\n\n" + parser.ComputeMessageLog(), ex); } } else { parser.ParseFrame(frameType); } // calculate what percent of the file has been read Int32 oldPercentRead = percentRead; percentRead = (Int32)(parser.Position / (Single)parser.FileLength * 100.0f); if (percentRead != oldPercentRead) { progressWindowInterface.UpdateProgress(percentRead); } } } finally { parser.Close(); } }