/// <summary> /// Font setting /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void fontToolStripMenuItem1_Click(object sender, EventArgs e) { try { using (var fd = new FontDialog()) { if (fd.ShowDialog() == DialogResult.OK) { richTextBox1.Font = fd.Font; var parser = new FileIniDataParser(); var cvt = new FontConverter(); var iniD = parser.ReadFile(SettingsPath); iniD["SETTINGS"]["main_font"] = cvt.ConvertToString(fd.Font); parser.WriteFile(SettingsPath, iniD); } } if (CurrentFile == null || (!File.Exists(CurrentFile) || Path.GetExtension(CurrentFile) != ".dem")) { return; } richTextBox1.Text = @"Analyzing file..."; CurrentDemoFile = CrossDemoParser.Parse(CurrentFile); PrintDemoDetails(CurrentDemoFile); Log(Path.GetFileName(CurrentFile + " rescanned for font change.")); Log("Font changed"); } catch (Exception ex) { Log(ex.Message); } }
/// <summary> /// The main constructor with a string param for openwith file thingy /// </summary> /// <param name="file"></param> public Main(string file) { InitializeComponent(); SettingsManager(false); richTextBox1.Font = MainFont; AllowDrop = true; netdecodeToolStripMenuItem.Enabled = false; heatmapGeneratorToolStripMenuItem1.Enabled = false; statisticsToolStripMenuItem.Enabled = false; HotkeyTimer.Start(); if (File.Exists(LogPath)) { File.Delete(LogPath); } Log("Application loaded!"); CurrentFile = file; if ((File.Exists(CurrentFile) && Path.GetExtension(CurrentFile) == ".dem")) { richTextBox1.Text = @"Analyzing file..."; UpdateForm(); CurrentDemoFile = CrossDemoParser.Parse(CurrentFile); PrintDemoDetails(CurrentDemoFile); Log(Path.GetFileName(CurrentFile + " opened")); } else { SourceToolsToolStripMenuItem.Enabled = false; goldSourceToolsToolStripMenuItem.Enabled = false; richTextBox1.Text = @"^ Use File->Open to open a correct .dem file or drop the file here!"; UpdateForm(); } }
/// <summary> /// Rescan the demo file. /// </summary> public void RescanFile() { if (CurrentFile != null && (File.Exists(CurrentFile) && Path.GetExtension(CurrentFile) == ".dem")) { richTextBox1.Text = @"Analyzing file..."; UpdateForm(); CurrentDemoFile = CrossDemoParser.Parse(CurrentFile); } PrintDemoDetails(CurrentDemoFile); Log(Path.GetFileName(CurrentFile) + " rescanned."); }
/// <summary> /// Print the details of the demo to the Main richtextbox /// </summary> /// <param name="demo"></param> public void PrintDemoDetails(CrossParseResult demo) { Log("Demo details printed!"); if (demo != null) { Text = @"VolvoWrench - " + Path.GetFileName(CurrentFile); PrintDetails(richTextBox1, demo.DisplayData); StripEnabler(demo); } else { richTextBox1.Text = @"Not a demo! "; } }
/// <summary> /// Normal constructor /// </summary> public Main() { InitializeComponent(); SettingsManager(false); richTextBox1.Font = MainFont; AllowDrop = true; netdecodeToolStripMenuItem.Enabled = false; heatmapGeneratorToolStripMenuItem1.Enabled = false; statisticsToolStripMenuItem.Enabled = false; HotkeyTimer.Start(); if (File.Exists(LogPath)) { File.Delete(LogPath); } #region OpenedWithFile check var dropFile = (Environment.GetCommandLineArgs().Any(x => Path.GetExtension(x) == ".dem")) ? Environment.GetCommandLineArgs().First(x => Path.GetExtension(x) == ".dem") : null; if (dropFile == null) { richTextBox1.Text = @"^ Use demo_file->Open to open a correct .dem file or drop the file here!"; UpdateForm(); } else { if ((File.Exists(dropFile) && Path.GetExtension(dropFile) == ".dem")) { CurrentFile = dropFile; richTextBox1.Text = @"Analyzing file..."; UpdateForm(); CurrentDemoFile = CrossDemoParser.Parse(CurrentFile); PrintDemoDetails(CurrentDemoFile); Log(Path.GetFileName(CurrentFile + " opened")); } else { SourceToolsToolStripMenuItem.Enabled = false; goldSourceToolsToolStripMenuItem.Enabled = false; richTextBox1.Text = @"^ Use demo_file->Open to open a correct .dem file or drop the file here!"; UpdateForm(); } } #endregion Log("Application loaded!"); }
/// <summary> /// This method is responsible for enabling the correct MenuStrips after demoparsing /// </summary> /// <param name="cpr"></param> public void StripEnabler(CrossParseResult cpr) { Log("Strips changed!"); switch (cpr.Type) { case Parseresult.UnsupportedFile: SourceToolsToolStripMenuItem.Enabled = false; goldSourceToolsToolStripMenuItem.Enabled = false; netdecodeToolStripMenuItem.Enabled = false; statisticsToolStripMenuItem.Enabled = false; heatmapGeneratorToolStripMenuItem1.Enabled = false; break; case Parseresult.Hlsooe: case Parseresult.GoldSource: SourceToolsToolStripMenuItem.Enabled = false; goldSourceToolsToolStripMenuItem.Enabled = true; netdecodeToolStripMenuItem.Enabled = false; statisticsToolStripMenuItem.Enabled = false; heatmapGeneratorToolStripMenuItem1.Enabled = false; break; case Parseresult.Portal: case Parseresult.Source: SourceToolsToolStripMenuItem.Enabled = true; netdecodeToolStripMenuItem.Enabled = true; goldSourceToolsToolStripMenuItem.Enabled = false; statisticsToolStripMenuItem.Enabled = true; heatmapGeneratorToolStripMenuItem1.Enabled = true; break; case Parseresult.L4D2Branch: SourceToolsToolStripMenuItem.Enabled = false; netdecodeToolStripMenuItem.Enabled = true; goldSourceToolsToolStripMenuItem.Enabled = false; statisticsToolStripMenuItem.Enabled = false; heatmapGeneratorToolStripMenuItem1.Enabled = false; break; } }
/// <summary> /// This happens when we drop the file on the form /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Main_DragDrop(object sender, DragEventArgs e) { var dropfiles = (string[])e.Data.GetData(DataFormats.FileDrop); var dropfile = (dropfiles.Any(x => Path.GetExtension(x) == ".dem")) ? dropfiles.First(x => Path.GetExtension(x) == ".dem") : null; if (dropfile != null) { CurrentFile = dropfile; } if (CurrentFile != null && (File.Exists(CurrentFile) && Path.GetExtension(CurrentFile) == ".dem")) { richTextBox1.Text = @"Analyzing file..."; UpdateForm(); CurrentDemoFile = CrossDemoParser.Parse(CurrentFile); PrintDemoDetails(CurrentDemoFile); Log(Path.GetFileName(CurrentFile) + " opened!"); } else { richTextBox1.Text = @"Bad file!"; } }
/// <summary> /// This is where we check the settings and add the data to the string that will be printed /// </summary> /// <param name="demo"></param> public static void PrintOverlayData(CrossParseResult demo) { Demodata = "Parsed file!"; #region Print switch (demo.Type) { case Parseresult.UnsupportedFile: Demodata = @"Unsupported file!"; break; case Parseresult.GoldSource: if (demo.GsDemoInfo.ParsingErrors.ToArray().Length > 0) { Demodata = "Error while parsing goldsource demo: \n"; foreach (var err in demo.GsDemoInfo.ParsingErrors) { Demodata += ("\n" + err); } } else { float frametimeMin = 0f, frametimeMax = 0f; var frametimeSum = 0.0; var count = 0; int msecMin = 0, msecMax = 0; long msecSum = 0; var first = true; foreach (var f in from entry in demo.GsDemoInfo.DirectoryEntries from frame in entry.Frames where (int)frame.Key.Type < 2 || (int)frame.Key.Type > 9 select(GoldSource.NetMsgFrame) frame.Value) { frametimeSum += f.RParms.Frametime; msecSum += f.UCmd.Msec; count++; if (first) { first = false; frametimeMin = f.RParms.Frametime; frametimeMax = f.RParms.Frametime; msecMin = f.UCmd.Msec; msecMax = f.UCmd.Msec; } else { frametimeMin = Math.Min(frametimeMin, f.RParms.Frametime); frametimeMax = Math.Max(frametimeMax, f.RParms.Frametime); msecMin = Math.Min(msecMin, f.UCmd.Msec); msecMax = Math.Max(msecMax, f.UCmd.Msec); } } if (Gos.DemoProtocol) { Demodata += $"\nDemo protocol: {demo.GsDemoInfo.Header.DemoProtocol}"; } if (Gos.NetProtocol) { Demodata += $"\nNet protocol: {demo.GsDemoInfo.Header.NetProtocol}"; } if (Gos.MapName) { Demodata += $"\nMap name: {demo.GsDemoInfo.Header.MapName}"; } if (Gos.GameDirectory) { Demodata += $"\nGame directory: {demo.GsDemoInfo.Header.GameDir}"; } if (Gos.MeasuredTime) { Demodata += $"\nLength in seconds: {demo.GsDemoInfo.DirectoryEntries.Sum(x => x.TrackTime).ToString("n3")}s"; } if (Gos.MeasuredTicks) { Demodata += $"\nFrame count: {demo.GsDemoInfo.DirectoryEntries.Sum(x => x.FrameCount)}"; } if (Gos.HighestFps) { Demodata += $"\nHigest FPS: {(1/frametimeMin).ToString("N2")}"; } if (Gos.LowestFps) { Demodata += $"\nLowest FPS: {(1/frametimeMax).ToString("N2")}"; } if (Gos.AverageFps) { Demodata += $"\nAverage FPS: {(count/frametimeSum).ToString("N2")}"; } if (Gos.LowestMsec) { Demodata += $"\nLowest msec: {(1000.0/msecMax).ToString("N2")} FPS"; } if (Gos.HighestMsec) { Demodata += $"\nHighest msec: {(1000.0/msecMin).ToString("N2")} FPS"; } if (Gos.AverageMsec) { Demodata += $"\nAverage msec: {(1000.0/(msecSum/(double) count)).ToString("N2")} FPS"; } } break; case Parseresult.Hlsooe: if (demo.HlsooeDemoInfo.ParsingErrors.ToArray().Length > 0) { Demodata = @"Error while parsing HLSOOE demo: "; foreach (var err in demo.HlsooeDemoInfo.ParsingErrors) { Demodata += ("\n" + err); } } else { if (Hos.DemoProtocol) { Demodata += $"\nDemo protocol: {demo.HlsooeDemoInfo.Header.DemoProtocol}"; } if (Hos.NetProtocol) { Demodata += $"\nNet protocol: {demo.HlsooeDemoInfo.Header.NetProtocol}"; } if (Hos.MapName) { Demodata += $"\nMap name: {demo.HlsooeDemoInfo.Header.MapName}"; } if (Hos.GameDirectory) { Demodata += $"\nGame directory: {demo.HlsooeDemoInfo.Header.GameDir}"; } if (Hos.MeasuredTime) { Demodata += $"\nLength in seconds: {(demo.HlsooeDemoInfo.DirectoryEntries.Last().Frames.LastOrDefault().Key.Frame)*0.015}s"; } if (Hos.MeasuredTicks) { Demodata += $"\nTick count: {(demo.HlsooeDemoInfo.DirectoryEntries.Last().Frames.LastOrDefault().Key.Frame)}"; } foreach ( var flag in demo.HlsooeDemoInfo.DirectoryEntries.SelectMany( demoDirectoryEntry => demoDirectoryEntry.Flags)) { Demodata += (flag.Value.Command + " at " + flag.Key.Frame + " -> " + (flag.Key.Frame * 0.015).ToString("n3") + "s"); } } break; case Parseresult.Source: if (demo.Sdi.ParsingErrors.ToArray().Length > 0) { Demodata = @"Error while parsing Source engine demo: "; foreach (var err in demo.Sdi.ParsingErrors) { Demodata += ("\n" + err); } } else { if (Sos.DemoProtocol) { Demodata += $"\nDemo protocol: {demo.Sdi.DemoProtocol}"; } if (Sos.ServerName) { Demodata += $"\nServer name: {demo.Sdi.ServerName}"; } if (Sos.ClientName) { Demodata += $"\nClient name: {demo.Sdi.ClientName}"; } if (Sos.MapName) { Demodata += $"\nMap name: {demo.Sdi.MapName}"; } if (Sos.MeasuredTime) { Demodata += $"\nMeasured time: {(demo.Sdi.Messages.Max(x => x.Tick)*0.015).ToString("n3")}s"; } if (Sos.MeasuredTicks) { Demodata += $"\nMeasured ticks: {demo.Sdi.Messages.Max(x => x.Tick)}"; } foreach (var f in demo.Sdi.Flags) { switch (f.Name) { case "#SAVE#": if (Sos.SaveFlag) { Demodata += ($"\n#SAVE# flag at Tick: {f.Tick} -> {f.Time}s"); } break; case "autosave": if (Sos.AutosaveFlag) { Demodata += ($"\nAutosave at Tick: {f.Tick} -> {f.Time}s"); } break; } } } break; case Parseresult.Portal: case Parseresult.L4D2Branch: if (demo.L4D2BranchInfo.Parsingerrors.ToArray().Length > 0) { Demodata = @"Error while parsing L4D2Branch demo: "; foreach (var err in demo.L4D2BranchInfo.Parsingerrors) { Demodata += ("\n" + err); } } else { if (Los.DemoProtocol) { Demodata += $"\nProtocol: {demo.L4D2BranchInfo.Header.Protocol}"; } if (Los.NetProtocol) { Demodata += $"\nNetwork protocol: {demo.L4D2BranchInfo.Header.NetworkProtocol}"; } if (Los.ServerName) { Demodata += $"\nServer name: {demo.L4D2BranchInfo.Header.ServerName}"; } if (Los.ClientName) { Demodata += $"\nClient name: {demo.L4D2BranchInfo.Header.ClientName}"; } if (Los.MapName) { Demodata += $"\nMapname: {demo.L4D2BranchInfo.Header.MapName}"; } if (Los.GameDirectory) { Demodata += $"\nGameDir: {demo.L4D2BranchInfo.Header.GameDirectory}"; } if (Los.MeasuredTime) { Demodata += $"\nPlaybacktime: {(demo.L4D2BranchInfo.Header.PlaybackTicks*0.015).ToString("n3")}s"; } if (Los.MeasuredTicks) { Demodata += $"\nPlaybackticks: {demo.L4D2BranchInfo.Header.PlaybackTicks}"; } if (Los.AdjustedTicks) { Demodata += $"\nAdjusted ticks: {demo.L4D2BranchInfo.PortalDemoInfo?.AdjustedTicks}"; } if (Los.AdjustedTime) { Demodata += $"\nAdjusted time: {demo.L4D2BranchInfo.PortalDemoInfo?.AdjustedTicks*0.015 + "s"}"; } if (Los.DemoProtocol) { Demodata += $"\nProtocol: {demo.L4D2BranchInfo.Header.Protocol}"; } if (Los.DemoProtocol) { Demodata += $"\nProtocol: {demo.L4D2BranchInfo.Header.Protocol}"; } } break; } #endregion }
/// <summary> /// Rename the demo /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void renameDemoToolStripMenuItem_Click(object sender, EventArgs e) { try { if (CurrentFile != null && File.Exists(CurrentFile) && Path.GetExtension(CurrentFile) == ".dem") { if (CurrentDemoFile == null) { richTextBox1.Text = @"Analyzing file..."; UpdateForm(); CurrentDemoFile = CrossDemoParser.Parse(CurrentFile); } switch (CurrentDemoFile.Type) { case Parseresult.UnsupportedFile: MessageBox.Show(@"Couldn't rename! There is no file loaded/non-supported file!"); Log("Tried to rename file but failed " + CurrentFile); break; case Parseresult.GoldSource: File.Move(CurrentFile, Path.GetDirectoryName(CurrentFile) + "\\" + CurrentDemoFile.GsDemoInfo.Header.MapName + "-" + $"{CurrentDemoFile.GsDemoInfo.DirectoryEntries.Last().TrackTime.ToString("#,0.000")}" + "-" + Environment.UserName + ".dem"); break; case Parseresult.Hlsooe: File.Move(CurrentFile, Path.GetDirectoryName(CurrentFile) + "\\" + CurrentDemoFile.HlsooeDemoInfo.Header.MapName + "-" + $"{CurrentDemoFile.HlsooeDemoInfo.DirectoryEntries.Last().PlaybackTime.ToString("#,0.000")}" + "-" + Environment.UserName + ".dem"); break; case Parseresult.Source: var stime = (CurrentDemoFile.Sdi.Flags.Count(x => x.Name == "#SAVE#") == 0) ? CurrentDemoFile.Sdi.Seconds.ToString("#,0.000") : CurrentDemoFile.Sdi.Flags.Last(x => x.Name == "#SAVE#").Time.ToString("#,0.000"); File.Move(CurrentFile, Path.GetDirectoryName(CurrentFile) + "\\" + CurrentDemoFile.Sdi.MapName + "-" + $"{stime}" + "-" + CurrentDemoFile.Sdi.ClientName + ".dem"); break; case Parseresult.Portal: File.Move(CurrentFile, Path.GetDirectoryName(CurrentFile) + "\\" + CurrentDemoFile.L4D2BranchInfo.PortalDemoInfo.MapName + "-" + (CurrentDemoFile.L4D2BranchInfo.PortalDemoInfo?.AdjustedTicks * (1f / (CurrentDemoFile.L4D2BranchInfo.Header.PlaybackTicks / CurrentDemoFile.L4D2BranchInfo.Header.PlaybackTime))) + "-" + CurrentDemoFile.L4D2BranchInfo.PortalDemoInfo.PlayerName + ".dem"); break; case Parseresult.L4D2Branch: File.Move(CurrentFile, Path.GetDirectoryName(CurrentFile) + "\\" + CurrentDemoFile.L4D2BranchInfo.Header.MapName + "-" + (CurrentDemoFile.L4D2BranchInfo.Header.PlaybackTime) + "-" + CurrentDemoFile.L4D2BranchInfo.Header.ClientName + ".dem"); break; } Log("Renamed demo"); } else { richTextBox1.Text = @"Please select a file first!"; } } catch (Exception ex) { Log(ex); } }
static void Main(string[] args) { Base[] checks = { new Base() { Enabled = false }, new BunnyHop() { Enabled = true }, new AimBot() { Enabled = false }, // new StrafeChecker() }; if (!File.Exists(CurrentFile) || Path.GetExtension(CurrentFile) != ".dem") { Console.WriteLine($"Can't open {CurrentFile} / wrong format."); return; } CurrentDemoFile = CrossDemoParser.Parse(CurrentFile); /* * Console.WriteLine("Demo data:"); * foreach (var data in CurrentDemoFile.DisplayData) * { * Console.WriteLine($"\t{data}"); * * * } */ if (CurrentDemoFile.Type != Parseresult.GoldSource) { Console.WriteLine($"Not GoldSrc demo type ({CurrentDemoFile.Type})."); return; } #region My code foreach (var entry in CurrentDemoFile.GsDemoInfo.DirectoryEntries) { if (entry.Type != 1) // Only PLAYBACK state { continue; } foreach (var frame in entry.Frames) { //Console.WriteLine($"-> .Index:{frame.Key.Index} .FrameIndex:{frame.Key.FrameIndex} .Time:{frame.Key.Time}"); foreach (var check in checks) { if (!check.Enabled) { continue; } check.Frame(frame); } if (enableDataLogging) { continue; } var type = frame.Key.Type; //Console.WriteLine($"Type: {type}"); switch (type) { case GoldSource.DemoFrameType.ConsoleCommand: { var Command = ((GoldSource.ConsoleCommandFrame)frame.Value).Command; Console.WriteLine($" Command: {Command}"); break; } /* * case GoldSource.DemoFrameType.ClientData: * { * var CData = ((GoldSource.ClientDataFrame)frame.Value); * var CData_string = "ClientData: {\n" + $"\t Origin: [ {CData.Origin.X}, {CData.Origin.Y}, {CData.Origin.Z} ] \n" + $"\t Viewangles: [ {CData.Viewangles.X}, {CData.Viewangles.Y}, {CData.Viewangles.Z} ] \n" + $"\t WeaponBits: {CData.WeaponBits} \n" + $"\t Fov: {CData.Fov}" + "\n}"; + + Console.WriteLine(CData_string); + + break; + } + + case GoldSource.DemoFrameType.Event: + { + var EventData = ((GoldSource.EventFrame)frame.Value); + var EventData_string = "EventData: {\n" + $"\t Delay: [ {EventData.Delay} ] \n" + $"\t Index: {EventData.Index} \n" + "\t EventArguments: { \n" + $"\t\t EntityIndex: {EventData.EventArguments.EntityIndex} \n" + $"\t\t Velocity:[ {EventData.EventArguments.Velocity.X}, {EventData.EventArguments.Velocity.Y}, {EventData.EventArguments.Velocity.Z}] \n" + $"\t\t Angles: [ {EventData.EventArguments.Angles.X}, {EventData.EventArguments.Angles.Y}, {EventData.EventArguments.Angles.Z}] \n" + $"\t\t Flags: {EventData.EventArguments.Flags} \n" + $"\t\t Ducking: {EventData.EventArguments.Ducking} \n" + "\t }" + "\n}"; + + Console.WriteLine(EventData_string); + + break; + } */ case GoldSource.DemoFrameType.NetMsg: { var NetMsgData = ((GoldSource.NetMsgFrame)frame.Value); var NetMsgData_string = "NetMsgData: {\n" + $"\t RParms.Onground: {NetMsgData.RParms.Onground}\n" + $"\t RParms.ClViewangles: [{NetMsgData.RParms.ClViewangles.X},{NetMsgData.RParms.ClViewangles.Y},{NetMsgData.RParms.ClViewangles.Z}]\n" + $"\t RParms.Viewangles: [{NetMsgData.RParms.Viewangles.X},{NetMsgData.RParms.Viewangles.Y},{NetMsgData.RParms.Viewangles.Z}]\n" + $"\t UCmd.Buttons: {NetMsgData.UCmd.Buttons}\n" + $"\t UCmd.Msec: {NetMsgData.UCmd.Msec}\n" + "\n}"; Console.WriteLine(NetMsgData_string); break; } case GoldSource.DemoFrameType.WeaponAnim: { var WeaponAnim = ((GoldSource.WeaponAnimFrame)frame.Value); break; } } } } #endregion Console.WriteLine($"Analyze finished!"); Console.ReadKey(); }