예제 #1
0
        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();
            }
        }