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

            // don't try to parse messages if the demo uses an unsupported network protocol
            if (UnsupportedNetworkProtocol)
                return;

            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();
            }
        }
Example #2
0
        private void WritingThreadWorker(String destinationFileName)
        {
            // don't know the demo format, just do a straight file copy
            if (UnsupportedDemoProtocol)
            {
                using (FileStream destStream = File.Open(destinationFileName, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    using (FileStream sourceStream = File.OpenRead(fileFullPath))
                    {
                        Byte[] buffer = new Byte[1024 * 1024];
                        Int32 percentRead = 0;

                        while (true)
                        {
                            Int32 bytesRead = sourceStream.Read(buffer, 0, buffer.Length);

                            if (bytesRead == 0)
                                break;

                            destStream.Write(buffer, 0, bytesRead);

                            // calculate what percent of the file has been read
                            Int32 oldPercentRead = percentRead;

                            percentRead = (Int32)(sourceStream.Position / (Single)sourceStream.Length * 100.0f);

                            if (percentRead != oldPercentRead)
                            {
                                writeProgressWindowInterface.UpdateProgress(percentRead);
                            }
                        }
                    }
                }

                return;
            }

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