public void Start() { MatchData = new Match(); using (var compressedStream = _matchInformation != null ? Helpers.GetStreamFromUrl(_matchInformation.roundstats.map) : replayStream) using (var outputStream = new MemoryStream()) { if (replayCompressed) { BZip2.Decompress(compressedStream, outputStream, false); outputStream.Seek(0L, SeekOrigin.Begin); parser = new DemoParser(outputStream); } else { parser = new DemoParser(compressedStream); } parser.MatchStarted += MatchStarted_Event; parser.ParseHeader(); parser.ParseToEnd(); MatchEnded_Event(); } }
private static void InitDemo() { demoParser = new DemoParser(File.OpenRead("pov_qwerty.dem")); demoParser.TickDone += parser_TickDone; demoParser.ParseHeader(); demoParser.ParseToEnd(); }
public void parseToSQLite() { setSqlSubscription(); parser.ParseHeader(); parser.ParseToEnd(); }
private void StartParseThread(string filePath) { using (var filestream = File.OpenRead(filePath)) { using (var parser = new DemoParser(filestream)) { parser.HeaderParsed += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnHeaderParsed, s, e, "header PArsed")); parser.RoundOfficiallyEnd += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnRoundEnd, s, e, "rounf official end")); parser.RoundStart += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnRoundStart, s, e, "round start")); parser.PlayerTeam += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnPlayerTeam, s, e, "Player team")); parser.SmokeNadeStarted += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnSmokeNadeStarted, s, e)); parser.MatchStarted += (s, e) => MatchStarted = true; parser.WeaponFired += _eventsHandler.OnWeaponFired; parser.PlayerHurt += _eventsHandler.OnPlayerHurt; parser.TickDone += _eventsHandler.OnTickDone; parser.ParseHeader(); parser.ParseToEnd(); OnParsingComplete(); Thread.CurrentThread.Abort(); } } }
public void Read() { myDemoParser.MatchStarted += HandleMatchStarted; myDemoParser.RoundAnnounceMatchStarted += HandleRoundAnnounceMatchStarted; myDemoParser.RoundStart += HandleRoundStarted; myDemoParser.PlayerKilled += HandlePlayerKilled; myDemoParser.RoundOfficiallyEnd += HandleRoundOfficiallyEnd; myDemoParser.LastRoundHalf += HandleLastRoundHalf; try { myDemoParser.ParseToEnd(); } catch (Exception e) { throw new DemoReaderException($"Unexpected exception thrown during demo analysis: {e.Message}"); } ProcessMissingLastRound(); ParseFinalTeamScores(); AssertMinimumRoundsAndPlayers(); CheckResultConsistency(); SetMatchRoundsAndScore(); SetMatchType(); }
/// <summary> /// Parses the replay till the matchHasStarted event occurs /// Initializes game-specific info /// </summary> /// <returns>true if it successully ran through</returns> public bool ParseToMatchStart() { using (var fileStream = File.OpenRead(_filePath)) { using (DemoParser parser = new DemoParser(fileStream)) { parser.ParseHeader(); Map = parser.Header.MapName; _matchTime = parser.Header.PlaybackTime; CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; parser.MatchStarted += (sender, e) => { Counterterrorists = parser.PlayingParticipants.Where(a => a.Team == Team.CounterTerrorist).ToArray(); Terrorists = parser.PlayingParticipants.Where(a => a.Team == Team.Terrorist).ToArray(); Terrorists.CopyTo(Players, 0); Counterterrorists.CopyTo(Players, 5); tokenSource.Cancel(); }; parser.ParseToEnd(token); } return(true); } }
private void ParseDemo(FileStream file) { _parser = new DemoParser(file); _parser.ParseHeader(); _parser.MatchStarted += Parser_MatchStarted; _parser.RoundStart += Parser_RoundStart; _parser.PlayerKilled += Parser_PlayerKilled; _parser.RoundEnd += Parser_RoundEnd; _parser.TickDone += Parser_TickDone; _parser.BombPlanted += Parser_BombPlanted; _parser.BombDefused += Parser_BombDefused; _parser.BombExploded += Parser_BombExploded; _parser.PlayerBind += Parser_PlayerBind; _parser.FreezetimeEnded += Parser_FreezetimeEnded; _parser.PlayerHurt += Parser_PlayerHurt; _progress.Report($"Parse file: \"{_demoFileName}\" Size: {new FileInfo(file.Name).Length.ToSize(LongExtension.SizeUnits.MB)}Mb"); var sw = new Stopwatch(); sw.Start(); _parser.ParseToEnd(); sw.Stop(); MatchFinish(); _progress.Report($"It took: {sw.Elapsed:mm':'ss':'fff}"); }
public static DemoParser CsgoDemoParser(string file) { var csgodemo = new DemoParser(File.OpenRead(file)); csgodemo.ParseHeader(); csgodemo.ParseToEnd(); return(csgodemo); }
private static void DemoTest1() { parser = new DemoParser(File.OpenRead("commu.dem")); parser.TickDone += parser_TickDone; parser.ParseHeader(); parser.ParseToEnd(); }
private static void DemoTest() { parser = new DemoParser(File.OpenRead("match730_003317647861457354858_2030613425_135.dem")); parser.TickDone += parser_TickDone; parser.ParseHeader(); parser.ParseToEnd(); }
public void ParseHeader(DemoParser parser) { parser.ParseHeader(); parser.MatchStarted += (sender, e) => { Team1 = parser.CTClanName; Team2 = parser.TClanName; mapName = parser.Map; }; parser.ParseToEnd(); }
static void Main(string[] args) { DemoParser dp = new DemoParser(File.OpenRead("1.dem")); int mollies = 0; dp.ParseHeader(); dp.FireNadeStarted += (sender, e) => { mollies++; }; dp.ParseToEnd(); Console.WriteLine("{0}", mollies); }
public static void Main(string[] args) { foreach (var file in Directory.GetFiles(@"D:\Users\Moritz\Desktop\playtest2", "*.dem")) { Console.WriteLine("Parsing " + file); using (var input = File.OpenRead(args[0])) { using (DemoParser p = new DemoParser(input)) { p.ParseHeader(); p.ParseToEnd(); } } } }
public static void GenerateFrags(DemoParser parser) { parser.ParseHeader(); // Make a print on round-start so you can see the actual frags per round. parser.RoundStart += (sender, e) => Console.WriteLine("New Round, Current Score: T {0} : {1} CT", parser.TScore, parser.CTScore); parser.PlayerKilled += (sender, e) => { if (e.Killer == null) { // The player has murdered himself (falling / own nade / ...) Console.WriteLine("<World><0><None>"); } else { Console.Write("<{0}><{1}><{2}>", e.Killer.Name, e.Killer.SteamID, ShortTeam(e.Killer.Team)); } if (e.Assister == null) { // nothing } else { Console.Write(" + <{0}><{1}><{2}>", e.Assister.Name, e.Assister.SteamID, ShortTeam(e.Assister.Team)); } Console.Write(" [{0}]", e.Weapon.Weapon); if (e.Headshot) { Console.Write("[HS]"); } if (e.PenetratedObjects > 0) { Console.Write("[Wall]"); } Console.Write(" "); Console.Write("<{0}><{1}><{2}>", e.DeathPerson.Name, e.DeathPerson.SteamID, ShortTeam(e.DeathPerson.Team)); Console.WriteLine(); }; parser.ParseToEnd(); }
private static void PrintSteamIdList(string fileName) { using (var fileStream = File.OpenRead(fileName)) { Console.WriteLine("==== List of the steamids of the players ===="); using (var parser = new DemoParser(fileStream)) { parser.ParseHeader(); parser.ParseToEnd(); foreach (var player in parser.PlayingParticipants) { Console.WriteLine(" - {0} {1}", player.SteamID, player.Name); } } } }
static void Main(string[] args) { var watch = new System.Diagnostics.Stopwatch(); Dictionary <Player, int> killsPerPlayer = new Dictionary <Player, int>(); watch.Start(); using (var file = File.OpenRead("demo3.dem")) { using (var demo = new DemoParser(file)) { demo.ParseHeader(); string map = demo.Map; demo.MatchStarted += (sender, e) => { foreach (var player in demo.PlayingParticipants) { killsPerPlayer[player] = 0; } }; demo.PlayerKilled += (object sender, PlayerKilledEventArgs e) => { if (e.Killer != null) { if (killsPerPlayer.ContainsKey(e.Killer)) { killsPerPlayer[e.Killer]++; } } }; demo.ParseToEnd(); } } watch.Stop(); Console.WriteLine("Base Run time: " + watch.Elapsed); foreach (KeyValuePair <Player, int> x in killsPerPlayer) { Console.WriteLine("{0} : {1}", x.Key.Name, x.Value); } Console.ReadKey(); }
public ReplayViewer() { InitializeComponent(); drawingBitmap = new Bitmap(1024, 1024); g = Graphics.FromImage(drawingBitmap); OpenFileDialog diag = new OpenFileDialog(); diag.DefaultExt = "*.dem"; diag.Filter = "CS:GO Demo (*.dem)|*.dem"; diag.FileName = "~/.steam/steam/SteamApps/common/Counter-Strike Global Offensive/csgo/replays/"; diag.ShowDialog(); if (!File.Exists(diag.FileName)) { MessageBox.Show("No valid file specified. "); this.Close(); Environment.Exit(0); } var reader = File.OpenRead(diag.FileName); parser = new DemoParser(reader); parser.ParseHeader(); parser.ParseToEnd(); LoadBackgroundInfo(); timer1.Enabled = true; parser.TickDone += parser_TickDone; parser.MatchStarted += parser_MatchStarted; parser.PlayerKilled += HandlePlayerKilled; parser.WeaponFired += HandleWeaponFired; }
public Results ParseDemo(string demoPath) { this.matchStarted = false; // Verify hash of demo SHA256Managed sha = new SHA256Managed(); byte[] bhash = sha.ComputeHash(File.OpenRead(demoPath)); string hash = BitConverter.ToString(bhash).Replace("-", String.Empty); Debug.WriteLine(String.Format("Demo hash: {0}", hash)); this.results = new Results(hash); parser = new DemoParser(File.OpenRead(demoPath)); parser.ParseHeader(); // Record the map this.results.Map = parser.Map; this.currentRound = new Round(); Debug.WriteLine(String.Format("Map: {0}", this.results.Map)); parser.MatchStarted += Parser_MatchStarted; parser.RoundStart += Parser_RoundStart; parser.PlayerKilled += Parser_PlayerKilled; parser.RoundEnd += Parser_RoundEnd; parser.TickDone += Parser_TickDone; parser.BombPlanted += Parser_BombPlanted; parser.BombDefused += Parser_BombDefused; parser.ParseToEnd(); // Record the final score and MVPs foreach (DemoInfo.Player p in parser.PlayingParticipants) { this.results.Players[p.SteamID].Score = p.AdditionaInformations.Score; this.results.Players[p.SteamID].MVPs = p.AdditionaInformations.MVPs; } return(this.results); }
public IActionResult Index(string name = "") { ViewBag.FilterName = name; DemoParser demoParser = new DemoParser(LDemo); demoParser.ParseHeader(); List <Vector2> shootingPositions = new List <Vector2>(); List <Vector2> deathPositions = new List <Vector2>(); bool hasMatchStarted = false; demoParser.MatchStarted += (sender, e) => { hasMatchStarted = true; }; demoParser.PlayerKilled += (sender, e) => { if (e.Victim.Name.Contains(name) && hasMatchStarted) { Vector2 vet = TrasnlateScale(e.Victim.LastAlivePosition.X, e.Victim.LastAlivePosition.Y); deathPositions.Add(vet); } }; demoParser.WeaponFired += (sender, e) => { if (e.Shooter.Name.Contains(name) && hasMatchStarted && e.Weapon.Weapon != EquipmentElement.Knife && e.Weapon.Weapon != EquipmentElement.Molotov && e.Weapon.Weapon != EquipmentElement.Smoke && e.Weapon.Weapon != EquipmentElement.Flash && e.Weapon.Weapon != EquipmentElement.Decoy && e.Weapon.Weapon != EquipmentElement.HE) { Vector2 vet = TrasnlateScale(e.Shooter.Position.X, e.Shooter.Position.Y); shootingPositions.Add(vet); } }; demoParser.ParseToEnd(); DrawingPoints(shootingPositions, deathPositions); return(View(demoParser.ReadPlayersName())); }
private static void WebClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e) { progressBar.Dispose(); Console.WriteLine("finished."); Console.Write("Uncompressing... "); using (var fStream = File.Create(_FileName)) { BZip2.Decompress(File.OpenRead(_ArchiveFileName), fStream, true); } Console.WriteLine("finished."); Console.Write("Parsing demo... "); using (var demoStream = File.OpenRead(_FileName)) { _dp = new DemoParser(demoStream); _dp.RoundStart += _dp_RoundStart; _dp.ParseHeader(); _dp.ParseToEnd(); _dp.Dispose(); } Console.WriteLine("finished."); Finished = true; }
public async Task <MinifiedDemo> MinifyDemoAsync(string path, CancellationToken token, Action <string, float> progressCallback = null) { FileStream stream = File.OpenRead(path); Parser = new DemoParser(stream); Demo = new MinifiedDemo(); CurrentTick = new Tick(); MostRecentPlayerStates = new Dictionary <byte, FullPlayerState>(); MostRecentEntityStates = new Dictionary <int, FullEntityState>(); ProgressCallback = progressCallback; RegisterEvents(); ParseHeader(); bool completed = await Task.Run(() => { try { Parser.ParseToEnd(token); return(true); } catch (Exception e) { return(false); } }, token); stream.Dispose(); if (!completed) { return(null); } return(Demo); }
private static void Main(string[] args) { var file = File.OpenRead( @"d:\MSExam\SALo\Latest\Utils\ReadFile.ReadDemo\bin\Debug\Demos\auto0-20191009-125008-1572099890-de_mirage-fuse8delete.dem"); _parser = new DemoParser(file); _parser.ParseHeader(); _parser.MatchStarted += Parser_MatchStarted; _parser.RoundStart += Parser_RoundStart; _parser.PlayerKilled += Parser_PlayerKilled; _parser.RoundEnd += Parser_RoundEnd; _parser.TickDone += Parser_TickDone; _parser.BombPlanted += Parser_BombPlanted; _parser.BombDefused += Parser_BombDefused; _parser.ParseToEnd(); Console.WriteLine($"{nameof(_results.HighestFragDeathRatio)}: {_results.HighestFragDeathRatio.Name}"); Console.WriteLine($"{nameof(_results.LeastDeaths)}: {_results.LeastDeaths.Name}"); Console.WriteLine($"{nameof(_results.LeastKills)}: {_results.LeastKills.Name}"); Console.ReadKey(); }
public static void Main(string[] args) { using (var input = File.OpenRead(args[0])) { var parser = new DemoParser(input); parser.ParseHeader(); parser.WeaponFired += (sender, e) => { Console.WriteLine("Weapon_fire"); Console.WriteLine("{"); Console.WriteLine("velx=" + e.Shooter.Velocity.X); Console.WriteLine("vely=" + e.Shooter.Velocity.Y); Console.WriteLine("weapon=" + e.Weapon.Weapon); Console.WriteLine("playername=" + e.Shooter.Name); Console.WriteLine("playersteamid=" + e.Shooter.SteamID); Console.WriteLine("}"); }; parser.ParseToEnd(); Console.WriteLine("End"); } }
public static void Main(string[] args) { using (var input = File.OpenRead(args[0])) { var parser = new DemoParser(input); parser.ParseHeader(); #if DEBUG Dictionary <Player, int> failures = new Dictionary <Player, int>(); parser.TickDone += (sender, e) => { //Problem: The HP coming from CCSPlayerEvent are sent 1-4 ticks later //I guess this is because the think()-method of the CCSPlayerResource isn't called //that often. Haven't checked though. foreach (var p in parser.PlayingParticipants) { //Make sure the array is never empty ;) failures[p] = failures.ContainsKey(p) ? failures[p] : 0; if (p.HP == p.AdditionaInformations.ScoreboardHP) { failures[p] = 0; } else { failures[p]++; //omg this is hacky. } //Okay, if it's wrong 2 seconds in a row, something's off //Since there should be a tick where it's right, right? //And if there's something off (e.g. two players are swapped) //there will be 2 seconds of ticks where it's wrong //So no problem here :) Debug.Assert( failures[p] < parser.TickRate * 2, string.Format( "The player-HP({0}) of {2} (Clan: {3}) and it's Scoreboard HP ({1}) didn't match for {4} ticks. ", p.HP, p.AdditionaInformations.ScoreboardHP, p.Name, p.AdditionaInformations.Clantag, parser.TickRate * 2 ) ); } }; if (args.Length >= 2) { // progress reporting requested using (var progressFile = File.OpenWrite(args[1])) using (var progressWriter = new StreamWriter(progressFile) { AutoFlush = false }) { int lastPercentage = -1; while (parser.ParseNextTick()) { var newProgress = (int)(parser.ParsingProgess * 100); if (newProgress != lastPercentage) { progressWriter.Write(lastPercentage = newProgress); progressWriter.Flush(); } } } return; } #endif parser.ParseToEnd(); } }
private void btnParser_Click(object sender, EventArgs e) { try { txtResult.Clear(); folderName = txtInputFolder.Text; outputFolderName = txtOutputFolder.Text; if (Directory.Exists(folderName) && Directory.Exists(outputFolderName)) { string[] files = Directory.GetFiles(folderName, "*.dem", SearchOption.TopDirectoryOnly); string fileNameWithoutExtension = ""; string fileName = ""; foreach (string file in files) { fileName = Path.GetFileName(file); fileNameWithoutExtension = fileName.Substring(0, fileName.Length - 4); outputFolderName = txtOutputFolder.Text + fileNameWithoutExtension + "\\"; //If an folder with the same name as the currently processed file exists, //then the current file is not processed. if (Directory.Exists(outputFolderName)) { txtResult.AppendText(fileName + " was parsered"); txtResult.AppendText(Environment.NewLine); txtResult.AppendText(Environment.NewLine); } else { parser = new DemoParser(File.OpenRead(file)); RegisterEvents(); isMatchStarted = true; isFreezetime = true; showDetailInfo = cbShowDetailInfo.Checked; stopRoundNumber = int.Parse(txtParserRoundNumber.Text); currentRoundNumber = 1; sbWeapon = new StringBuilder(); sbHurt = new StringBuilder(); sbNade = new StringBuilder(); Directory.CreateDirectory(outputFolderName); txtResult.AppendText("======Strat Parser " + fileName + " at " + DateTime.Now + "======"); txtResult.AppendText(Environment.NewLine); //As the movement data is hugh, we need to immediately write each record to the file to prevent this procedure run out the memory using (swMovement = new StreamWriter(Path.Combine(outputFolderName, fileNameWithoutExtension + ".csv"))) { parser.ParseHeader(); txtResult.AppendText("ClientName: " + parser.Header.ClientName + "; Map: " + parser.Header.MapName + "; ServerName: " + parser.Header.ServerName); txtResult.AppendText(Environment.NewLine); txtResult.AppendText("PlaybackTicks: " + parser.Header.PlaybackTicks + "; PlaybackTime: " + parser.Header.PlaybackTime + "; TickRate: " + parser.TickRate + "; TickTime: " + parser.TickTime); txtResult.AppendText(Environment.NewLine); parser.ParseToEnd(); parser.Dispose(); } File.WriteAllText(Path.Combine(outputFolderName, fileNameWithoutExtension + "-Weapon.csv"), sbWeapon.ToString()); File.WriteAllText(Path.Combine(outputFolderName, fileNameWithoutExtension + "-Hurt.csv"), sbHurt.ToString()); File.WriteAllText(Path.Combine(outputFolderName, fileNameWithoutExtension + "-Nade.csv"), sbNade.ToString()); txtResult.AppendText(Environment.NewLine); txtResult.AppendText("==============Parser Completed=============="); txtResult.AppendText(Environment.NewLine); txtResult.AppendText(Environment.NewLine); } } } else { txtResult.AppendText("Folder is not exist."); txtResult.AppendText(Environment.NewLine); } } catch (Exception ex) { txtResult.AppendText(ex.ToString()); } }
public static void GenerateScoreboards(DemoParser parser) { int i = 0; parser.ParseHeader(); Console.WriteLine("map: " + parser.Map); int roundEndedCount = 0; parser.RoundEnd += (object sender, RoundEndedEventArgs e) => { // The reason I'm doing this after tick_done is that // entity-updates only come in the same tick as round_end // comes, meaning the score-update might not be transmitted yet // which would be sad - we always want the current score! // so we wait 1 second. roundEndedCount = 1; }; parser.TickDone += (object sender, TickDoneEventArgs e) => { if (roundEndedCount == 0) { return; } roundEndedCount++; // Wait twice the tickrate of the demo (~2 seconds) to make sure the // screen has been updated. I *LOVE* demo files :) if (roundEndedCount < parser.TickRate * 2) { return; } roundEndedCount = 0; Console.WriteLine("------------------------------------------------------------"); Console.WriteLine("Round {0}, CT: {1}, T: {2}", ++i, parser.CTScore, parser.TScore); Console.WriteLine("Ts\t" + parser.TClanName); Console.WriteLine("Tag\tName\tSteamID\tKills\tDeaths\tAssists\tScore\t"); foreach (var player in parser.PlayingParticipants.Where(a => a.Team == Team.Terrorist)) { Console.WriteLine( "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", player.AdditionaInformations.Clantag, player.Name, player.SteamID, player.AdditionaInformations.Kills, player.AdditionaInformations.Deaths, player.AdditionaInformations.Assists, player.AdditionaInformations.Score ); } Console.WriteLine("CTs\t" + parser.CTClanName); Console.WriteLine("Tag\tName\tSteamID\tKills\tDeaths\tAssists\tScore\t"); foreach (var player in parser.PlayingParticipants.Where(a => a.Team == Team.CounterTerrorist)) { Console.WriteLine( "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", player.AdditionaInformations.Clantag, player.Name, player.SteamID, player.AdditionaInformations.Kills, player.AdditionaInformations.Deaths, player.AdditionaInformations.Assists, player.AdditionaInformations.Score ); } Console.WriteLine(); }; parser.ParseToEnd(); }
private static void Main(string[] args) { if (args.Length < 1) { PrintHelp(); Console.ReadKey(); // TODO: remove return; } var fileArgument = -1; if (args.Length > 1) { for (var i = 0; i < args.Length; i++) { var arg = args[i]; if (arg.StartsWith("-") || arg.StartsWith("/")) { if (arg.Substring(1).ToLower().Equals("liststeamids")) { _liststeamids = true; } else if (arg.Substring(1).ToLower().Equals("steamid")) { _steamid = args[++i]; // get the next argv (make the loop jump to the next arg) } } else if (fileArgument == -1) // not set yet { fileArgument = i; } } } var fileName = args[fileArgument]; if (_liststeamids) { PrintSteamIdList(fileName); Console.ReadKey(); // TODO: remove return; } if (string.IsNullOrEmpty(_steamid)) { Console.WriteLine("[ERROR] steamid parameter is empty !\n"); PrintHelp(); Console.ReadKey(); // TODO: remove return; } if (!Regex.IsMatch(_steamid, @"^\d{17}$")) { Console.WriteLine("[ERROR] The SteamId provided is invalid (should be a number of 17 digits) !\n"); PrintHelp(); Console.ReadKey(); // TODO: remove return; } using (var fileStream = File.OpenRead(fileName)) { Console.WriteLine("Parsing demo {0}", fileName); using (var parser = new DemoParser(fileStream)) { parser.ParseHeader(); parser.BotTakeOver += (sender, e) => { if (_steamid.Equals(e.Taker.SteamID.ToString())) { var tick = ((DemoParser)sender).IngameTick; var botName = "a bot"; // The lib does not send the Bot along with the event. Console.WriteLine("[{0}] {1} took over {2}.", tick, e.Taker.Name, botName); VdmGenerator.Add(new PlayCommandsAction { StartTick = tick, Name = "Normal speed", Commands = "demo_timescale " + DEMO_SPEED_NORMAL }); } }; parser.PlayerKilled += (sender, e) => { var theParser = (DemoParser)sender; var tick = theParser.IngameTick; var killerName = e?.Killer?.Name ?? "[Someone]"; var victimName = e?.Victim?.Name; if (victimName != null) { Console.WriteLine("[{0}] {1} killed {2}.", tick, killerName, victimName); } else { Console.WriteLine("[{0}] {1} killed himself.", tick, killerName); } var victimSteamId = e?.Victim?.SteamID.ToString(); if (victimSteamId != null && victimSteamId.Equals(_steamid)) // if The Suspect died { // Fast forward VdmGenerator.Add(new PlayCommandsAction { StartTick = tick, Name = "Fast Forward", Commands = "demo_timescale " + DEMO_SPEED_FASTFORWARD }); } var killerSteamId = e?.Killer?.SteamID.ToString(); if (killerSteamId != null && killerSteamId.Equals(_steamid)) // if The Suspect killed someone { // Play "beep beep" :) VdmGenerator.Add(new PlayCommandsAction { StartTick = tick + 1, Name = "Beep Beep", Commands = "play ui/deathnotice" }); } }; parser.RoundStart += (sender, e) => { var tick = ((DemoParser)sender).IngameTick; _round++; Console.WriteLine("[{0}] The round #{1} has started.", tick, _round); VdmGenerator.Add(new PlayCommandsAction { StartTick = tick, Name = "Spec player", Commands = "spec_player_by_accountid " + _steamid }); }; parser.FreezetimeEnded += (sender, e) => { var tick = ((DemoParser)sender).IngameTick; Console.WriteLine("[{0}] Freeztime ended", tick); VdmGenerator.Add(new PlayCommandsAction { StartTick = tick, Name = "Normal speed", Commands = "demo_timescale " + DEMO_SPEED_NORMAL }); }; parser.RoundEnd += (sender, e) => { var tick = ((DemoParser)sender).IngameTick; Console.WriteLine("[{0}] The round #{1} is over.", tick, _round); VdmGenerator.Add(new PlayCommandsAction { StartTick = tick, Name = "Fast Forward", Commands = "demo_timescale " + DEMO_SPEED_FASTFORWARD }); }; parser.ParseToEnd(); } } var vdmFile = fileName.Replace(".dem", ".vdm"); VdmGenerator.Generate(vdmFile); Console.ReadKey(); // TODO: remove }
//private void OpenDemo(object file) => _demo = new DemoParser((Stream)file); public void GenerateData(string urlDemo) { List <Models.Player> players = new List <Models.Player>(); List <Models.Player> alivePlayers = new List <Models.Player>(); List <Weapon> weapons = new List <Weapon>(); bool firstKillFlag = true; bool lastAliveTR = false; bool lastAliveCT = false; bool roundStarted = false; int roundCount = 0; GetFile(urlDemo); OpenDemo(@"C:\Users\vitor\source\repos\DemoCSGO_API\DemoCSGO\demos\myDemo.dem"); _demo.ParseHeader(); bool hasMatchStarted = false; _demo.MatchStarted += (sender, e) => { hasMatchStarted = true; }; _demo.RoundAnnounceMatchStarted += (sender, e) => { roundCount = 0; }; #region BombPlanted Event _demo.BombPlanted += (sender, e) => { if (hasMatchStarted && e.Player != null) { var jogadores = _demo.Participants; var player = players.Where(p => p.Name == e.Player.Name).FirstOrDefault(); if (player != null) { player.BombsPlanted++; } } }; #endregion #region RoundMVP Event _demo.RoundMVP += (sender, e) => { if (hasMatchStarted) { if (e.Reason == RoundMVPReason.MostEliminations && e.Player != null) { var player = players.Where(p => p.Name == e.Player.Name).FirstOrDefault(); if (player != null) { player.RoundMVPs++; } } } }; #endregion #region SetDistanceTraveled and WalkQuantityAsTR _demo.TickDone += (sender, e) => { if (hasMatchStarted && IsAllPlayersRegistered(players) && roundStarted && _demo.Participants != null) { foreach (var player in players) { var jogador = _demo.Participants.Where(p => p.Name == player.Name).FirstOrDefault(); if (jogador != null) { if (player.TeamSide == Team.Terrorist) { player.DistanceTraveledAsTR += (jogador.Velocity.Absolute * _demo.TickTime); player.DistanceTraveledAsTR = Math.Round(player.DistanceTraveledAsTR, 2); } else { player.DistanceTraveledAsCT += (jogador.Velocity.Absolute * _demo.TickTime); player.DistanceTraveledAsCT = Math.Round(player.DistanceTraveledAsCT, 2); } if (IsPlayerWalking(jogador)) { if (player.TeamSide == Team.Terrorist) { player.WalkQuantityAsTR++; } else { player.WalkQuantityAsCT++; } } } } } }; #endregion #region RoundStart Event _demo.RoundStart += (sender, e) => { if (hasMatchStarted) { firstKillFlag = true; roundStarted = true; roundCount++; if (IsAllPlayersRegistered(players)) { lastAliveTR = false; lastAliveCT = false; UpdateTeamSide(players, _demo.Participants); foreach (var player in players) { player.IsAlive = true; player.IsLastAliveThisRound = false; } } } }; #endregion #region RoundEnd Event _demo.RoundEnd += (sender, e) => { roundStarted = false; SetADR(players, roundCount); SetClutches(players, e); //foreach (var player in players) //{ // if (player.TeamSide == Team.CounterTerrorist) // player.TeamName = _demo.TClanName; // else // player.TeamName = _demo.CTClanName; //} }; #endregion #region GetBlindedEnemies _demo.FlashNadeExploded += (sender, e) => { if (hasMatchStarted) { if (players.Any(p => p.Name == e.ThrownBy.Name)) { int blindedEnemies = BlindedEnemies(e.FlashedPlayers, e.ThrownBy); var player = players.Where(p => p.Name == e.ThrownBy.Name).FirstOrDefault(); player.FlashedEnemies += blindedEnemies; } else { players.Add(new Models.Player(e.ThrownBy.Name, 0, 0, BlindedEnemies(e.FlashedPlayers, e.ThrownBy), new List <Weapon>())); } } }; #endregion #region GetPlayersKilledAndVictim _demo.PlayerKilled += (sender, e) => { if (hasMatchStarted) { string nameWeaponFired = GetNameWeapon(e.Weapon.Weapon); //Vitima if (e.Victim != null) { if (e.Victim.FlashDuration >= 1 && e.Assister != null) { var assister = players.Where(p => p.Name == e.Assister.Name).FirstOrDefault(); if (assister != null) { assister.FlashAssists++; } } if (players.Any(p => p.Name == e.Victim.Name)) { bool foundWeapon = false; var victim = players.Where(p => p.Name == e.Victim.Name).FirstOrDefault(); if (victim != null) { victim.IsAlive = false; victim.Death++; } foreach (Weapon weapon in victim.Weapons) { if (weapon.NameWeapon.Equals(nameWeaponFired)) { weapon.DeathQuantity++; foundWeapon = true; } } if (!foundWeapon) { victim.Weapons.Add(new Weapon(nameWeaponFired, 0, 1, Enum.GetName(typeof(EquipmentClass), e.Weapon.Class))); } SetPlayerTeamName(e.Victim, victim); } else { players.Add(new Models.Player(e.Victim.Name, 0, 1, 0, new List <Weapon>())); var victim = players.Where(p => p.Name == e.Victim.Name).FirstOrDefault(); if (victim != null) { victim.Weapons.Add(new Weapon(nameWeaponFired, 0, 1, Enum.GetName(typeof(EquipmentClass), e.Weapon.Class))); victim.TeamSide = e.Victim.Team; SetPlayerTeamName(e.Victim, victim); } } } //Assasino if (e.Killer != null) { if (players.Any(p => p.Name == e.Killer.Name)) { bool foundWeapon = false; var killer = players.Where(p => p.Name == e.Killer.Name).FirstOrDefault(); if (killer != null) { killer.Killed++; } if (IsAllPlayersRegistered(players)) { (lastAliveCT, lastAliveTR) = SetLastAliveQuantity(players, lastAliveCT, lastAliveTR); } if (firstKillFlag) { Models.Player victim = null; killer.FirstKills++; if (e.Victim != null) { victim = players.Where(p => p.Name == e.Victim.Name).FirstOrDefault(); } if (victim != null) { victim.FirstDeaths++; } firstKillFlag = false; } foreach (Weapon weapon in killer.Weapons) { if (weapon.NameWeapon.Equals(nameWeaponFired)) { weapon.KillQuantity++; foundWeapon = true; } } if (!foundWeapon) { killer.Weapons.Add(new Weapon(nameWeaponFired, 1, 0, Enum.GetName(typeof(EquipmentClass), e.Weapon.Class))); } SetPlayerTeamName(e.Killer, killer); } else { players.Add(new Models.Player(e.Killer.Name, 1, 0, 0, new List <Weapon>())); var killer = players.Where(p => p.Name == e.Killer.Name).FirstOrDefault(); if (killer != null) { killer.Weapons.Add(new Weapon(nameWeaponFired, 1, 0, Enum.GetName(typeof(EquipmentClass), e.Weapon.Class))); killer.TeamSide = e.Killer.Team; SetPlayerTeamName(e.Killer, killer); } } } } }; #endregion #region PlayerHurt Event _demo.PlayerHurt += (sender, e) => { if (hasMatchStarted && e.Attacker != null) { var player = players.Where(p => p.Name == e.Attacker.Name).FirstOrDefault(); if (player != null) { var damage = e.HealthDamage; if (damage > 100) { damage = 100; } player.TotalDamageDealt += damage; } } }; #endregion #region GetHeatMap string nomeJogador = "dupreeh"; mapDust2 = MakeMap("de_dust2", -2476, 3239, 4.4f); List <Vector2> shootingPositions = new List <Vector2>(); List <Vector2> deathPositions = new List <Vector2>(); _demo.PlayerKilled += (sender, e) => { if (e.Victim != null) { if (e.Victim.Name.Contains(nomeJogador) && hasMatchStarted) { Vector2 vet = TrasnlateScale(e.Victim.LastAlivePosition.X, e.Victim.LastAlivePosition.Y); deathPositions.Add(vet); } } }; _demo.WeaponFired += (sender, e) => { if (e.Shooter != null) { if (e.Shooter.Name.Contains(nomeJogador) && hasMatchStarted && e.Weapon.Weapon != EquipmentElement.Knife && e.Weapon.Weapon != EquipmentElement.Molotov && e.Weapon.Weapon != EquipmentElement.Smoke && e.Weapon.Weapon != EquipmentElement.Flash && e.Weapon.Weapon != EquipmentElement.Decoy && e.Weapon.Weapon != EquipmentElement.HE) { Vector2 vet = TrasnlateScale(e.Shooter.Position.X, e.Shooter.Position.Y); shootingPositions.Add(vet); } } }; #endregion _demo.ParseToEnd(); WriteJsonFile(@"..\..\PythonScript\json\PlayersStats", JsonConvert.SerializeObject(players)); SetWeaponsKills(players); players = SetMetrics(players); WriteJsonPlayers(players); DrawingPoints(shootingPositions, deathPositions); RunLogisticRegression(); players.Clear(); }
public void Process() { #region detect demos string[] demos; demos = System.IO.Directory.GetFiles(System.Environment.CurrentDirectory + "/" + TARGET_FOLDER + "/", "*.dem", System.IO.SearchOption.AllDirectories); Debug.Success("Found {0} demo files", demos.Count()); for (int i = 0; i < demos.Count();) { // KB MB Debug.Blue("{0} - {1}mb\t", Path.GetFileName(demos[i]), new FileInfo(demos[i]).Length / 1024 / 1024); i++; if (i % 3 == 0) { Console.Write("\n"); } } Console.Write("\n\n"); Debug.Info("Press enter to start processing"); Console.ReadLine(); #endregion #region collect match structure //Doing the processing Dictionary <int, string> matches = new Dictionary <int, string>(); int mId = 0; foreach (string mPath in demos) { matches.Add(mId, demos[mId]); mId++; } #endregion #region process all demos //Now for each demo foreach (int matchID in matches.Keys) { //Debug.Log("Starting processing match id {0}, demo: {1}", matchID, Path.GetFileName(demos[matchID])); Debug.progressBar(matchID + "/" + demos.Count() + " | " + Path.GetFileName(demos[matchID]), 0); Dictionary <int, long> playerLookups = new Dictionary <int, long>(); //Set up recorder settings RecorderSettings rs = new RecorderSettings(); rs.matchID = matchID; rs.playerLookups = playerLookups; currentRS = rs; //Create the parser DemoParser dp = new DemoParser(File.OpenRead(matches[matchID])); dp.ParseHeader(); //Trigger subscription event EventSubscription?.Invoke(new EventSubscriptionEventArgs(dp)); //Hard coded necessary event handlers --------------------------------------------------- dp.PlayerBind += (object sender, PlayerBindEventArgs e) => { if (!playerLookups.ContainsKey(e.Player.EntityID)) { if (e.Player.SteamID != 0) { playerLookups.Add(e.Player.EntityID, e.Player.SteamID); } } }; int tickCounter = 0; dp.TickDone += (object sender, TickDoneEventArgs e) => { tickCounter++; if (tickCounter > 1000) { tickCounter = 0; Debug.updateProgressBar((int)(dp.ParsingProgess * 100)); } }; // ------------------------------------------------------------------------------------- //End of event handlers try { dp.ParseToEnd(); } catch { Debug.exitProgressBar(); Debug.Error("Attempted to read past end of stream..."); } dp.Dispose(); Debug.exitProgressBar(); } #endregion Debug.Success("Complete!!!"); }
public static void Main(string[] args) { // First, check wether the user needs assistance: if (args.Length == 0 || args [0] == "--help") { PrintHelp(); return; } if (args[0] == "--paths") { bool generatePNGs = false; bool generateCSV = false; bool writePathsToDB = true; switch (args[1]) { case "--png": generatePNGs = true; break; case "--nopng": generatePNGs = false; break; default: generatePNGs = false; break; } switch (args[2]) { case "--csv": generateCSV = true; break; case "--nocsv": generateCSV = false; break; default: generateCSV = false; break; } for (int i = 3; i < args.Length; i++) { using (var fileStream = File.OpenRead(args[i])) { using (var parser = new DemoParser(fileStream)) { PathGenerator.GeneratePath(parser, generatePNGs, generateCSV, writePathsToDB, Path.GetFileName(fileStream.Name)); } } } return; } if (args[0] == "--analyze") { using (var fileStream = File.OpenRead(args[1])) { PathAnalyzer.AnalyzePaths(Path.GetFileName(fileStream.Name), fileStream); } return; } if (args[0] == "--stratmeta") { StratMetaGenerator.GenerateStratMeta(int.Parse(args[1])); return; } if (args [0] == "--scoreboard") { using (var fileStream = File.OpenRead(args[1])) { using (var parser = new DemoParser(fileStream)) { ScoreboardGenerator.GenerateScoreboards(parser); } } return; } if (args [0] == "--frags") { using (var fileStream = File.OpenRead(args[1])) { using (var parser = new DemoParser(fileStream)) { FragGenerator.GenerateFrags(parser); } } return; } // Every argument is a file, so let's iterate over all the arguments // So you can call this program like // > StatisticsGenerator.exe hello.dem bye.dem // It'll generate the statistics. foreach (var fileName in args) { // Okay, first we need to initalize a demo-parser // It takes a stream, so we simply open with a filestream using (var fileStream = File.OpenRead(fileName)) { // By using "using" we make sure that the fileStream is properly disposed // the same goes for the DemoParser which NEEDS to be disposed (else it'll // leak memory and kittens will die. Console.WriteLine("Parsing demo " + fileName); using (var parser = new DemoParser(fileStream)) { // So now we've initialized a demo-parser. // let's parse the head of the demo-file to get which map the match is on! // this is always the first step you need to do. parser.ParseHeader(); // and now, do some magic: grab the match! string map = parser.Map; // And now, generate the filename of the resulting file string outputFileName = fileName + "." + map + ".csv"; // and open it. var outputStream = new StreamWriter(outputFileName); //And write a header so you know what is what in the resulting file outputStream.WriteLine(GenerateCSVHeader()); // Cool! Now let's get started generating the analysis-data. //Let's just declare some stuff we need to remember // Here we'll save how far a player has travelled each round. // Here we remember wheter the match has started yet. bool hasMatchStarted = false; int ctStartroundMoney = 0, tStartroundMoney = 0, ctEquipValue = 0, tEquipValue = 0, ctSaveAmount = 0, tSaveAmount = 0; float ctWay = 0, tWay = 0; int defuses = 0; int plants = 0; Dictionary <Player, int> killsThisRound = new Dictionary <Player, int> (); List <Player> ingame = new List <Player> (); // Since most of the parsing is done via "Events" in CS:GO, we need to use them. // So you bind to events in C# as well. // AFTER we have bound the events, we start the parser! parser.MatchStarted += (sender, e) => { hasMatchStarted = true; //Okay let's output who's really in this game! Console.WriteLine("Participants: "); Console.WriteLine(" Terrorits \"{0}\": ", parser.CTClanName); foreach (var player in parser.PlayingParticipants.Where(a => a.Team == Team.Terrorist)) { Console.WriteLine(" {0} {1} (Steamid: {2})", player.AdditionaInformations.Clantag, player.Name, player.SteamID); } Console.WriteLine(" Counter-Terrorits \"{0}\": ", parser.TClanName); foreach (var player in parser.PlayingParticipants.Where(a => a.Team == Team.CounterTerrorist)) { Console.WriteLine(" {0} {1} (Steamid: {2})", player.AdditionaInformations.Clantag, player.Name, player.SteamID); } // Okay, problem: At the end of the demo // a player might have already left the game, // so we need to store some information // about the players before they left :) ingame.AddRange(parser.PlayingParticipants); }; parser.PlayerKilled += (object sender, PlayerKilledEventArgs e) => { //the killer is null if you're killed by the world - eg. by falling if (e.Killer != null) { if (!killsThisRound.ContainsKey(e.Killer)) { killsThisRound[e.Killer] = 0; } //Remember how many kills each player made this rounds killsThisRound[e.Killer]++; } }; parser.RoundStart += (sender, e) => { if (!hasMatchStarted) { return; } //How much money had each team at the start of the round? ctStartroundMoney = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.Money); tStartroundMoney = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.Money); //And how much they did they save from the last round? ctSaveAmount = parser.Participants.Where(a => a.Team == Team.CounterTerrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue); tSaveAmount = parser.Participants.Where(a => a.Team == Team.Terrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue); //And let's reset those statistics ctWay = 0; tWay = 0; plants = 0; defuses = 0; killsThisRound.Clear(); }; parser.FreezetimeEnded += (sender, e) => { if (!hasMatchStarted) { return; } // At the end of the freezetime (when players can start walking) // calculate the equipment value of each team! ctEquipValue = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.CurrentEquipmentValue); tEquipValue = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.CurrentEquipmentValue); }; parser.BombPlanted += (sender, e) => { if (!hasMatchStarted) { return; } plants++; }; parser.BombDefused += (sender, e) => { if (!hasMatchStarted) { return; } defuses++; }; parser.TickDone += (sender, e) => { if (!hasMatchStarted) { return; } // Okay, let's measure how far each team travelled. // As you might know from school the amount walked // by a player is the sum of it's velocities foreach (var player in parser.PlayingParticipants) { // We multiply it by the time of one tick // Since the velocity is given in // ingame-units per second float currentWay = (float)(player.Velocity.Absolute * parser.TickTime); // This is just an example of what kind of stuff you can do // with this parser. // Of course you could find out who makes the most footsteps, and find out // which player ninjas the most - just to give you an example if (player.Team == Team.CounterTerrorist) { ctWay += currentWay; } else if (player.Team == Team.Terrorist) { tWay += currentWay; } } }; //So now lets do some fancy output parser.RoundEnd += (sender, e) => { if (!hasMatchStarted) { return; } // We do this in a method-call since we'd else need to duplicate code // The much parameters are there because I simply extracted a method // Sorry for this - you should be able to read it anywys :) PrintRoundResults(parser, outputStream, ctStartroundMoney, tStartroundMoney, ctEquipValue, tEquipValue, ctSaveAmount, tSaveAmount, ctWay, tWay, defuses, plants, killsThisRound); }; //Now let's parse the demo! parser.ParseToEnd(); //And output the result of the last round again. PrintRoundResults(parser, outputStream, ctStartroundMoney, tStartroundMoney, ctEquipValue, tEquipValue, ctSaveAmount, tSaveAmount, ctWay, tWay, defuses, plants, killsThisRound); //Lets just display an end-game-scoreboard! Console.WriteLine("Finished! Results: "); Console.WriteLine(" Terrorits \"{0}\": ", parser.CTClanName); foreach (var player in ingame.Where(a => a.Team == Team.Terrorist)) { Console.WriteLine( " {0} {1} (Steamid: {2}): K: {3}, D: {4}, A: {5}", player.AdditionaInformations.Clantag, player.Name, player.SteamID, player.AdditionaInformations.Kills, player.AdditionaInformations.Deaths, player.AdditionaInformations.Assists ); } Console.WriteLine(" Counter-Terrorits \"{0}\": ", parser.TClanName); foreach (var player in ingame.Where(a => a.Team == Team.CounterTerrorist)) { Console.WriteLine( " {0} {1} (Steamid: {2}): K: {3}, D: {4}, A: {5}", player.AdditionaInformations.Clantag, player.Name, player.SteamID, player.AdditionaInformations.Kills, player.AdditionaInformations.Deaths, player.AdditionaInformations.Assists ); } outputStream.Close(); } } } }