private void WritingThreadWorker(String destinationFileName) { // create output file FileStream stream = File.Open(destinationFileName, FileMode.Create, FileAccess.Write, FileShare.None); BinaryWriter writer = new BinaryWriter(stream); try { // initialise parser parser = new SourceDemoParser(this); parser.AddMessageHandler((Byte)SourceDemoParser.MessageId.SVC_UserMessage, WriteMessageUserMessage); parser.Open(); Int32 percentRead = 0; // header Byte[] header = parser.Reader.ReadBytes(HeaderSizeInBytes); writer.Write(header); while (true) { // frame header SourceDemoParser.FrameHeader frameHeader = parser.ReadFrameHeader(); writer.Write((Byte)frameHeader.Type); if (frameHeader.Type != SourceDemoParser.FrameType.Stop) { writer.Write(frameHeader.Tick); } else { // write 3 bytes writer.Write((Byte)(frameHeader.Tick & 0xFF)); writer.Write((Byte)((frameHeader.Tick >> 8) & 0xFF)); writer.Write((Byte)((frameHeader.Tick >> 16) & 0xFF)); } // special cases - additional frame header info if (frameHeader.Type == SourceDemoParser.FrameType.Stop) { break; } else if (frameHeader.Type == SourceDemoParser.FrameType.Signon || frameHeader.Type == SourceDemoParser.FrameType.Packet) { // command info parser.WriteCommandInfo(parser.ReadCommandInfo(), writer); // sequence info parser.WriteSequenceInfo(parser.ReadSequenceInfo(), writer); } else if (frameHeader.Type == SourceDemoParser.FrameType.User) { Int32 outgoingSequence = parser.Reader.ReadInt32(); writer.Write(outgoingSequence); } // frame data if (frameHeader.Type != SourceDemoParser.FrameType.Synctick) { // get frame length Int32 frameLength = parser.Reader.ReadInt32(); writer.Write(frameLength); if (frameLength != 0) { Byte[] frameData = null; if (DemoProtocol == 3 && NetworkProtocol == 7 && Config.Settings.PlaybackRemoveFtb && frameHeader.Type == SourceDemoParser.FrameType.Packet) { // fade to black removal parser.ParsePacketMessages(frameLength); frameData = parser.BitBuffer.Data; } else { frameData = parser.Reader.ReadBytes(frameLength); } writer.Write(frameData); } } // calculate what percent of the file has been read Int32 oldPercentRead = percentRead; percentRead = (Int32)(parser.Position / (Single)parser.FileLength * 100.0f); if (percentRead != oldPercentRead) { writeProgressWindowInterface.UpdateProgress(percentRead); } } } finally { parser.Close(); writer.Close(); stream.Close(); } }
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(); } }