public void AddMessageHandlers(HalfLifeDemoParser parser) { this.parser = parser; parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_event, MessageEvent); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_sound, MessageSound); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_serverinfo, MessageServerInfo); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_updateuserinfo, MessageUpdateUserInfo); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_deltadescription, MessageDeltaDescription); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_clientdata, MessageClientData); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_pings, MessagePings); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_spawnbaseline, MessageSpawnBaseline); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_newusermsg, MessageNewUserMsg); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_packetentities, MessagePacketEntities); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_deltapacketentities, MessageDeltaPacketEntities); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_resourcelist, MessageResourceList); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_hltv, MessageHltv); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_director, MessageDirector); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_voiceinit, MessageVoiceInit); parser.AddMessageHandler((Byte)HalfLifeDemoParser.MessageId.svc_timescale, MessageTimeScale); parser.AddUserMessageHandler("ClCorpse", MessageClCorpse); parser.AddUserMessageHandler("ScreenFade", MessageScreenFade); parser.AddUserMessageHandler("SendAudio", MessageSendAudio); parser.AddUserMessageHandler("TextMsg", MessageTextMsg); Procedure <String> removeMessage = (s) => { Int32 startOffset = parser.BitBuffer.CurrentByte; Int32 messageLength = parser.FindUserMessageLength(s); Int32 endOffset = parser.BitBuffer.CurrentByte + messageLength; parser.Seek(startOffset - 1, SeekOrigin.Begin); parser.BitBuffer.RemoveBytes(endOffset - startOffset + 1); }; parser.AddUserMessageHandler("CDChallenge", () => { removeMessage("CDChallenge"); }); parser.AddUserMessageHandler("CDSalt", () => { removeMessage("CDSalt"); }); }
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(); } }