Beispiel #1
0
        private void ReadHeader(BinaryReader br)
        {
            br.BaseStream.Seek(8, SeekOrigin.Begin); // skip magic, DemoFactory checks it

            demoProtocol = br.ReadUInt32();

            if (demoProtocol > 3)
            {
                throw new ApplicationException(String.Format("Unsupported demo protocol \"{0}\", should be 3.", demoProtocol));
            }

            networkProtocol = br.ReadUInt32();

            if (networkProtocol > 18)
            {
                UnsupportedNetworkProtocol = true;
            }

            serverName        = Common.ReadNullTerminatedString(br, 260);
            recorderName      = Common.ReadNullTerminatedString(br, 260);
            mapName           = Common.ReadNullTerminatedString(br, 260).ToLower();
            gameFolderName    = Common.ReadNullTerminatedString(br, 260).ToLower();
            durationInSeconds = Math.Abs(br.ReadSingle());

            if (recorderName == "SourceTV Demo")
            {
                perspective = Perspectives.SourceTv;
            }
            else
            {
                perspective = Perspectives.Pov;
            }

            Game = GameManager.Find(this);
        }
Beispiel #2
0
        public static Demo CreateDemo(String fileName)
        {
            const Int32 magicStringLength = 8;

            using (FileStream inputStream = File.OpenRead(fileName))
            {
                using (BinaryReader binaryReader = new BinaryReader(inputStream))
                {
                    String magic = Common.ReadNullTerminatedString(binaryReader, magicStringLength);
                    binaryReader.Close();

                    // create demo object
                    Demo demo = null;

                    if (magic == "HLDEMO")
                    {
                        demo = new HalfLifeDemo(fileName);
                    }
                    else if (magic == "HL2DEMO")
                    {
                        demo = new SourceDemo(fileName);
                    }
                    else
                    {
                        throw new ApplicationException("Not a valid Half-Life or Source engine demo file.");
                    }

                    return(demo);
                }
            }
        }
Beispiel #3
0
        private void ReadHeader(BinaryReader br)
        {
            br.BaseStream.Seek(8, SeekOrigin.Begin); // skip magic, DemoFactory checks it

            demoProtocol = br.ReadUInt32();

            if (demoProtocol > 3)
            {
                // the format of the rest of the header may have changed, but continue anyway since it's not critical information
                UnsupportedDemoProtocol = true;
            }

            networkProtocol = br.ReadUInt32();

            if (networkProtocol > 18)
            {
                UnsupportedNetworkProtocol = true;
            }

            serverName        = Common.ReadNullTerminatedString(br, 260);
            recorderName      = Common.ReadNullTerminatedString(br, 260);
            mapName           = Common.ReadNullTerminatedString(br, 260).ToLower();
            gameFolderName    = Common.ReadNullTerminatedString(br, 260).ToLower();
            durationInSeconds = Math.Abs(br.ReadSingle());

            if (recorderName == "SourceTV Demo")
            {
                perspective = Perspectives.SourceTv;
            }
            else
            {
                perspective = Perspectives.Pov;
            }

            Game = GameManager.Find(this);
        }
Beispiel #4
0
        private void ReadHeader(BinaryReader br)
        {
            br.BaseStream.Seek(8, SeekOrigin.Current); // skip magic, DemoFactory checks it

            demoProtocol = br.ReadUInt32();

            if (demoProtocol != 5)
            {
                throw new ApplicationException(String.Format("Unknown demo protocol \"{0}\", should be 5.", demoProtocol));
            }

            networkProtocol = br.ReadUInt32();

            if (networkProtocol < 43) // don't support demos older than HL 1.1.0.4/CS 1.0
            {
                throw new ApplicationException(String.Format("Unsupported network protcol \"{0}\", only 43 and higher are supported."));
            }

            mapName        = Common.ReadNullTerminatedString(br, 260).ToLower();
            gameFolderName = Common.ReadNullTerminatedString(br, 260).ToLower();
            mapChecksum    = br.ReadUInt32();
            Int64 directoryEntriesOffset = br.ReadUInt32();

            // check directory entries

            // check offset, should be exactly file length - no. of dir entries (int) + dir entry size * 2
            // otherwise, assume they are corrupt
            if (directoryEntriesOffset != fileLengthInBytes - 4 - (DirectoryEntrySizeInBytes * 2))
            {
                status = StatusEnum.CorruptDirEntries;
                return;
            }

            // seek to directory entries offset
            Int64 newPosition = br.BaseStream.Seek(directoryEntriesOffset, SeekOrigin.Begin); // CHECK ME: is this correct or is an exception thrown if we seek to far?

            if (newPosition != directoryEntriesOffset)
            {
                status = StatusEnum.CorruptDirEntries;
                return;
            }

            // read no. of directory entries
            Int32 nDirectoryEntries = br.ReadInt32();

            if (nDirectoryEntries != 2)
            {
                status = StatusEnum.CorruptDirEntries;
                return;
            }

            // read directory entries
            for (Int32 i = 0; i < nDirectoryEntries; i++)
            {
                br.BaseStream.Seek(4, SeekOrigin.Current);  // skip number
                String dirEntryTitle = Common.ReadNullTerminatedString(br, 64);
                br.BaseStream.Seek(8, SeekOrigin.Current);  // skip flags, cdtrack
                Single dirEntryTime = br.ReadSingle();
                br.BaseStream.Seek(12, SeekOrigin.Current); // skip frames, offset and length (we calculate these ourselves, so corrupt directory entries or not, the demo is treated the same)

                if (dirEntryTitle.ToLower() == "playback")
                {
                    // store demo duration
                    durationInSeconds = Math.Abs(dirEntryTime);
                }
            }
        }
        private Byte[] ReadFrameData(HalfLifeDemoParser.FrameHeader frameHeader, out Boolean writeFrame)
        {
            Byte[] result = null;
            writeFrame = true;

            if (frameHeader.Type == 0 || frameHeader.Type == 1)
            {
                // frame header
                Byte[] frameHeaderDemoInfo     = parser.Reader.ReadBytes(parser.GameDataDemoInfoLength);
                Byte[] frameHeaderSequenceInfo = parser.Reader.ReadBytes(parser.GameDataSequenceInfoLength);
                UInt32 gameDataLength          = parser.Reader.ReadUInt32();

                // frame data
                Byte[] frameData = null;

                if (gameDataLength != 0)
                {
                    // read frame data
                    frameData = parser.Reader.ReadBytes((Int32)gameDataLength);

                    if (frameData.Length != gameDataLength)
                    {
                        throw new ApplicationException("Gamedata frame length doesn't match header.");
                    }

                    // Give the writer interface a chance to insert any new messages into the first gamedata frame.
                    if (frameHeader.Type == 1 && !foundPlaybackOffset)
                    {
                        demoWriterInterface.ProcessFirstGameDataFrame(ref frameData);
                    }

                    // parse frame messages
                    try
                    {
                        if (demoWriterInterface.ShouldParseGameDataMessages(frameHeader.Type))
                        {
                            parser.ParseGameDataMessages(frameData, demoWriterInterface.GetNewUserMessageId);

                            // set frame data to version modified by parsing
                            frameData = parser.BitBuffer.Data;
                        }
                    }
                    catch (ThreadAbortException)
                    {
                        throw;
                    }
                    catch (Exception ex)
                    {
                        Error("Error parsing gamedata frame.\n\n" + parser.ComputeMessageLog(), ex, true);

                        if (lastErrorResult != MessageWindow.Result.Continue)
                        {
                            throw new AbortWritingException();
                        }
                        else
                        {
                            writeFrame = false;
                            return(null);
                        }
                    }
                }

                // check for end of loading segment
                if (frameHeader.Type == 1)
                {
                    if (!foundPlaybackOffset)
                    {
                        // last 5 frame (end of segment) will have stored the correct offset
                        foundPlaybackOffset = true;
                    }

                    // count playback segment gamedata frames
                    nPlaybackFrames++;
                }

                // copy contents of frame into memorystream, return result
                MemoryStream ms = new MemoryStream();
                demoWriterInterface.WriteDemoInfo(frameHeaderDemoInfo, ms);
                ms.Write(frameHeaderSequenceInfo, 0, frameHeaderSequenceInfo.Length);

                if (gameDataLength == 0)
                {
                    ms.Write(BitConverter.GetBytes(gameDataLength), 0, 4);
                }
                else
                {
                    ms.Write(BitConverter.GetBytes(frameData.Length), 0, 4);
                    ms.Write(frameData, 0, frameData.Length);
                }

                return(ms.ToArray());
            }
            else if (frameHeader.Type == 3) // client command
            {
                String command = Common.ReadNullTerminatedString(parser.Reader, 64);

                if (!demoWriterInterface.ShouldWriteClientCommand(command))
                {
                    // don't write frame
                    writeFrame = false;
                    return(null);
                }

                parser.Seek(-64);
                result = parser.Reader.ReadBytes(64);

                if (result.Length != 64)
                {
                    throw new ApplicationException("Unexpected client command frame data length.");
                }
            }
            else if (Config.Settings.PlaybackRemoveWeaponAnimations && frameHeader.Type == 7)
            {
                parser.Seek(8);
                writeFrame = false;
                return(null);
            }
            else if (frameHeader.Type != 5)
            {
                Int32 frameLength = parser.GetFrameLength(frameHeader.Type);

                if (frameLength != 0)
                {
                    result = parser.Reader.ReadBytes(frameLength);

                    if (result.Length != frameLength)
                    {
                        throw new ApplicationException("Unexpected frame data length.");
                    }
                }
            }

            return(result);
        }