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(); } }
private void ReadingThreadWorker() { FileStream fs = null; BinaryReader br = null; try { fs = File.OpenRead(FileFullPath); br = new BinaryReader(fs); // read header if (fs.Length < HeaderSizeInBytes) { throw new ApplicationException("File length is too short to parse the header."); } ReadHeader(br); } finally { if (br != null) { br.Close(); } if (fs != null) { fs.Close(); } } try { // initialise parser parser = new SourceDemoParser(this); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_Print, ReadMessagePrint); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_ServerInfo, ReadMessageServerInfo); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_CreateStringTable, ReadMessageCreateStringTable); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_UpdateStringTable, ReadMessageUpdateStringTable); parser.Open(); parser.Seek(HeaderSizeInBytes); Boolean firstSignonFrameParsed = false; while (true) { // frame header SourceDemoParser.FrameHeader frameHeader = parser.ReadFrameHeader(); // special cases - additional frame header info if (frameHeader.Type == SourceDemoParser.FrameType.Stop || frameHeader.Type == SourceDemoParser.FrameType.Packet) { break; } else if (frameHeader.Type == SourceDemoParser.FrameType.Signon) { // command info parser.ReadCommandInfo(); // sequence info parser.ReadSequenceInfo(); } else if (frameHeader.Type == SourceDemoParser.FrameType.User) { parser.Seek(4); // outgoing sequence number } // frame data if (frameHeader.Type != SourceDemoParser.FrameType.Synctick) { // get frame length Int32 frameLength = parser.Reader.ReadInt32(); if (frameLength != 0) { if (frameHeader.Type == SourceDemoParser.FrameType.Signon) { try { if (!firstSignonFrameParsed) { firstSignonFrameParsed = true; if (networkProtocol == 15) { Int64 start = parser.Position; try { CalculateProtocol15Hack(frameLength); } catch (Exception) { Protocol15Hack = true; } parser.Seek(start, SeekOrigin.Begin); } } parser.ParsePacketMessages(frameLength); } catch (ThreadAbortException) { throw; } catch (Exception ex) { throw new ApplicationException("Message parsing error.\n\n" + parser.ComputeMessageLog(), ex); } } else { parser.Seek(frameLength); } } } } } finally { parser.Close(); } }