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