コード例 #1
0
        public void Parse()
        {
            parser = new HalfLifeDemoParser(demo);

            // add svc message handlers
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_print, MessagePrint);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_stufftext, MessageStuffText);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_serverinfo, MessageServerInfo);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_updateuserinfo, MessageUpdateUserInfo);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_pings, MessagePings);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_event_reliable, MessageEventReliable);

            // add user message handlers
            parser.AddUserMessageHandler("SayText", MessageSayText);
            parser.AddUserMessageHandler("TextMsg", MessageTextMsg);
            parser.AddUserMessageHandler("ResetHUD", MessageResetHUD);
            parser.AddUserMessageHandler("DeathMsg", MessageDeathMsg);
            parser.AddUserMessageHandler("ScoreInfo", MessageScoreInfo);
            parser.AddUserMessageHandler("TeamInfo", MessageTeamInfo);
            parser.AddUserMessageHandler("TeamScore", MessageTeamScore);

            parser.Open();
            parser.Seek(HalfLifeDemo.HeaderSizeInBytes); // seek past header

            Int32   percentRead          = 0;
            Boolean foundPlaybackSegment = false;

            try
            {
                while (true)
                {
                    HalfLifeDemoParser.FrameHeader frameHeader = parser.ReadFrameHeader();

                    if (frameHeader.Type == 0 || frameHeader.Type == 1)
                    {
                        if (!foundPlaybackSegment && frameHeader.Type == 1)
                        {
                            foundPlaybackSegment = true;
                        }

                        HalfLifeDemoParser.GameDataFrameHeader gameDataFrameHeader = parser.ReadGameDataFrameHeader();
                        currentTimestamp = frameHeader.Timestamp;

                        // length can be 0
                        // e.g. GotFrag Demo 15111 (volcano vs 4k).zip
                        if (gameDataFrameHeader.Length > 0)
                        {
                            Byte[] frameData = parser.Reader.ReadBytes((Int32)gameDataFrameHeader.Length);

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

                            try
                            {
                                parser.ParseGameDataMessages(frameData);
                            }
                            catch (ThreadAbortException)
                            {
                                throw;
                            }
                            catch (Exception ex)
                            {
                                throw new ApplicationException("Message parsing error.\n\n" + parser.ComputeMessageLog(), ex);
                            }
                        }
                    }
                    else if (frameHeader.Type == 5) // end of segment
                    {
                        if (foundPlaybackSegment)
                        {
                            progressWindowInterface.UpdateProgress(100);
                            break;
                        }
                    }
                    else
                    {
                        parser.SkipFrame(frameHeader.Type);
                    }

                    // 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();
            }
        }
コード例 #2
0
ファイル: HalfLifeDemo.cs プロジェクト: Hengle/coldemoplayer
        private void ReadingThreadWorker()
        {
            FileStream   fs = null;
            BinaryReader br = null;

            // read header
            try
            {
                fs = File.OpenRead(FileFullPath);
                br = new BinaryReader(fs);

                fileLengthInBytes = fs.Length;

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

            // create parser
            parser = new HalfLifeDemoParser(this);

            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_setview, ReadMessageSetView);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_print, ReadMessagePrint);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_serverinfo, ReadMessageServerInfo);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_updateuserinfo, ReadMessageUpdateUserInfo);
            parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_hltv, ReadMessageHltv);

            parser.Open();
            parser.Seek(HeaderSizeInBytes); // seek past header

            try
            {
                // read and parse frames until the end of the loading segment
                while (true)
                {
                    HalfLifeDemoParser.FrameHeader frameHeader = parser.ReadFrameHeader();

                    // "no loading segment" bug
                    if (frameHeader.Type == 1)
                    {
                        if (serverInfoParsed)
                        {
                            break;
                        }
                    }

                    if (frameHeader.Type == 0 || frameHeader.Type == 1)
                    {
                        HalfLifeDemoParser.GameDataFrameHeader gameDataFrameHeader = parser.ReadGameDataFrameHeader();

                        if (gameDataFrameHeader.Length > 0)
                        {
                            Byte[] frameData = parser.Reader.ReadBytes((Int32)gameDataFrameHeader.Length);

                            try
                            {
                                parser.ParseGameDataMessages(frameData);
                            }
                            catch (ThreadAbortException)
                            {
                                throw;
                            }
                            catch (Exception ex)
                            {
                                throw new ApplicationException("Error parsing gamedata frame.\n\n" + parser.ComputeMessageLog(), ex);
                            }
                        }
                    }
                    else
                    {
                        parser.SkipFrame(frameHeader.Type);
                    }
                }
            }
            finally
            {
                parser.Close();
            }

            // get demo recorder's name
            if (perspective == Perspectives.Pov)
            {
                foreach (Player p in playerList)
                {
                    if (p.Slot == recorderSlot)
                    {
                        recorderName = p.InfoKeys["name"];
                    }
                }
            }
        }
コード例 #3
0
        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);
        }