public static SourceDemoParseResult ParseDemo(string file, DEMO_TYPE DemoType) { #region Source Demo Parser var result = new SourceDemoParseResult(); try { using (var fs = new FileStream(file, FileMode.Open, FileAccess.Read)) using (var br = new BinaryReader(fs)) { #region Original HL2 Demo Parser ASCII.GetString(br.ReadBytes(8)).TrimEnd('\0'); result.Protocol = (ToInt32(br.ReadBytes(4), 0)).ToString(InvariantCulture); result.NProtocol = (ToInt32(br.ReadBytes(4), 0)).ToString(InvariantCulture); result.ServerName = ASCII.GetString(br.ReadBytes(260)).TrimEnd('\0'); result.PlayerName = ASCII.GetString(br.ReadBytes(260)).TrimEnd('\0'); result.MapName = ASCII.GetString(br.ReadBytes(260)).TrimEnd('\0'); result.GameName = ASCII.GetString(br.ReadBytes(260)).TrimEnd('\0'); // gamedir=gamename result.PTime = (Abs(ToInt32(br.ReadBytes(4), 0))).ToString(InvariantCulture); result.Pticks = (Abs(ToInt32(br.ReadBytes(4), 0))).ToString(InvariantCulture); result.Pframes = (Abs(ToInt32(br.ReadBytes(4), 0))).ToString(InvariantCulture); var signOnLen = br.ReadInt32(); result.Flags = new List <Flag>(); result.Cheetz = new List <string>(); result.CoordsList = new List <Point3D>(); byte command; do { command = br.ReadByte(); if (command == 0x07) // dem_stop { break; } var tick = br.ReadInt32(); if (tick >= 0) { result.TotalTicks = tick; } switch (command) { case 0x01: br.BaseStream.Seek(signOnLen, SeekOrigin.Current); break; case 0x02: { br.BaseStream.Seek(4, SeekOrigin.Current); // skip flags var x = br.ReadSingle(); var y = br.ReadSingle(); var z = br.ReadSingle(); result.CoordsList.Add(new Point3D((int)x, (int)y, (int)z)); br.BaseStream.Seek(0x44, SeekOrigin.Current); var packetLen = br.ReadInt32(); br.BaseStream.Seek(packetLen, SeekOrigin.Current); } break; case 0x04: { var concmdLen = br.ReadInt32(); var concmd = ASCII.GetString(br.ReadBytes(concmdLen - 1)); result.CMDs.Add(concmd); if (concmd.Contains("#SAVE#")) { if (tick >= 0) { result.Flags.Add(new Flag(tick, tick * 0.015f, "#SAVE#")); } } foreach (var s in cheats.Where(concmd.Contains)) { result.Cheated = true; result.Cheetz.Add(concmd); } if (concmd == "autosave") { //Autosave happened. if (tick >= 0) { result.Flags.Add(new Flag(tick, tick * 0.015f, "autosave")); } } if (concmd.StartsWith("+jump")) { result.TotalJumps++; } br.BaseStream.Seek(1, SeekOrigin.Current); // skip null terminator } break; case 0x05: { br.BaseStream.Seek(4, SeekOrigin.Current); // skip sequence//int test = br.ReadInt32(); var userCmdLen = br.ReadInt32(); br.BaseStream.Seek(userCmdLen, SeekOrigin.Current); } break; case 0x08: { var stringTableLen = br.ReadInt32(); br.BaseStream.Seek(stringTableLen, SeekOrigin.Current); } break; } } while (command != 0x07); // dem_stop result.Suceeded = true; #endregion } } catch (Exception e) { result.Suceeded = false; } result.TotalTime = result.TotalTicks * 0.015f; // 1 tick = 0.015s return(result); #endregion }
public static GoldSourceDemoParseResult ParseGoldSourceDemo(string file, DEMO_TYPE type) { #region Goldsource demo parser var result = new GoldSourceDemoParseResult(); result.Flags = new List <Flag>(); result.Cheetz = new List <string>(); if (HLDEMO_IsValidDemo(file)) { if (HLDEMO_Open(file, 1) == IntPtr.Zero) { if (HLSDEMO_IsValidDemo(file)) { if (HLSDEMO_Open(file, 1) == IntPtr.Zero) { result.Suceeded = true; var demoFile = HLSDEMO_Open(file, 1); var demoFileDemoHeader = HLSDEMO_DemoFileGetDemoHeader(demoFile); result.MapName = Marshal.PtrToStringAnsi(demoFileDemoHeader.mapName); result.Protocol = demoFileDemoHeader.demoProtocol.ToString(); result.MapCrc = demoFileDemoHeader.ToString(); result.DOffset = demoFileDemoHeader.directoryOffset.ToString(); result.NProtocol = demoFileDemoHeader.netProtocol.ToString(); result.Gamedir = Marshal.PtrToStringAnsi(demoFileDemoHeader.gameDir); var size = HLDEMO_GetDirectoryEntryCount(demoFile); for (var i = 0; i < size; i++) { var currentDemoDirectoryEntry = HLDEMO_GetDirectoryEntry(demoFile, i); var frameCount = HLDEMO_GetFrameCount(currentDemoDirectoryEntry.frame_data); for (var j = 0; j < frameCount; j++) { var currFrame = HLDEMO_GetFrame( currentDemoDirectoryEntry.frame_data, j); if (currFrame.type == (int)demo_frame_type.CONSOLE_COMMAND) { var command = Marshal.PtrToStringAnsi( HLDEMO_TreatAsConsoleCommandFrame(currFrame.frame_pointer).command); result.TotalTime = currFrame.time; result.CMDs.Add(command); result.Pframes = currFrame.frame; if (command != null) { foreach (var s in cheats.Where(command.Contains)) { result.Cheated = true; result.Cheetz.Add(command); } } } } } } else { result.Suceeded = false; } } else { result.Suceeded = false; } } else { var demoFile = HLDEMO_Open(file, 1); var demoFileDemoHeader = HLDEMO_DemoFileGetDemoHeader(demoFile); result.MapName = Marshal.PtrToStringAnsi(demoFileDemoHeader.mapName); result.Protocol = demoFileDemoHeader.demoProtocol.ToString(); result.MapCrc = demoFileDemoHeader.mapCRC.ToString(); result.DOffset = demoFileDemoHeader.directoryOffset.ToString(); result.NProtocol = demoFileDemoHeader.netProtocol.ToString(); result.Gamedir = Marshal.PtrToStringAnsi(demoFileDemoHeader.gameDir); var size = HLDEMO_GetDirectoryEntryCount(demoFile); for (var i = 0; i < size; i++) { var currentDemoDirectoryEntry = HLDEMO_GetDirectoryEntry(demoFile, i); var frameCount = HLDEMO_GetFrameCount(currentDemoDirectoryEntry.frame_data); for (var j = 0; j < frameCount; j++) { var currFrame = HLDEMO_GetFrame( currentDemoDirectoryEntry.frame_data, j); if (currFrame.type == (int)demo_frame_type.CONSOLE_COMMAND) { var command = Marshal.PtrToStringAnsi( HLDEMO_TreatAsConsoleCommandFrame(currFrame.frame_pointer).command); result.TotalTime = currFrame.time; result.CMDs.Add(command); result.Pframes = currFrame.frame; if (command != null) { foreach (var s in cheats.Where(command.Contains)) { result.Cheated = true; result.Cheetz.Add(command); } } } } } result.Suceeded = true; } } else { result.Suceeded = false; } return(result); #endregion }