private static tanookiStats tanookiStatsCreator(IEnumerable <TeamPlayers> tpe, IEnumerable <DisconnectedPlayer> dpe) { tanookiStats tanookiStats = new tanookiStats() { Joined = false, Left = false, RoundJoined = -1, RoundLeft = -1, RoundsLasted = -1 }; long tanookiId = 76561198123165941; if (tpe.Any(t => t.Terrorists.Any(p => p.SteamID == tanookiId)) || tpe.Any(t => t.CounterTerrorists.Any(p => p.SteamID == tanookiId))) { tanookiStats.Joined = true; tanookiStats.RoundJoined = 0; // set incase he joined in warmup but does not play any rounds IEnumerable <int> playedRoundsT = tpe.Where(t => t.Round > 0 && t.Terrorists.Any(p => p.SteamID == tanookiId)).Select(r => r.Round); IEnumerable <int> playedRoundsCT = tpe.Where(t => t.Round > 0 && t.CounterTerrorists.Any(p => p.SteamID == tanookiId)).Select(r => r.Round); tanookiStats.RoundsLasted = playedRoundsT.Count() + playedRoundsCT.Count(); bool playedTSide = (playedRoundsT.Count() > 0) ? true : false; bool playedCTSide = (playedRoundsCT.Count() > 0) ? true : false; tanookiStats.RoundJoined = playedTSide ? (playedCTSide ? ((playedRoundsT.First() < playedRoundsCT.First()) ? playedRoundsT.First() : playedRoundsCT.First()) : playedRoundsT.First()) : (playedCTSide ? playedRoundsCT.First() : tanookiStats.RoundJoined); } if (dpe.Any(d => d.PlayerDisconnectEventArgs.Player != null && d.PlayerDisconnectEventArgs.Player.SteamID == tanookiId)) { // checks if he played a round later on than his last disconnect (he left and joined back) int finalDisconnectRound = dpe.Where(d => d.PlayerDisconnectEventArgs.Player.SteamID == tanookiId).Reverse().Select(r => r.Round).First(); tanookiStats.RoundLeft = (finalDisconnectRound > tanookiStats.RoundsLasted) ? finalDisconnectRound : tanookiStats.RoundLeft; tanookiStats.Left = (tanookiStats.RoundLeft > -1) ? true : false; } return(tanookiStats); }
public void MockData() { var DemoInformation = new DemoInformation() { DemoName = "demo1", MapName = "de_testmap", TestDate = new DateTime(2020, 1, 1, 0, 0, 0).ToString(), TestType = "Defuse", }; var tanookiStats = new tanookiStats() { Joined = true, Left = true, RoundJoined = 1, RoundLeft = 2, RoundsLasted = 1, }; var MatchStartValues = new List <MatchStartedEventArgs>() { new MatchStartedEventArgs { Mapname = "de_testmap", HasBombsites = true, } }; var SwitchSidesValues = new List <SwitchSidesEventArgs>() { new SwitchSidesEventArgs { RoundBeforeSwitch = 1, } }; var MessagesValues = new List <FeedbackMessage>() { new FeedbackMessage() { Round = 1, SteamID = 12321313213, TeamName = "AlphaTeam", XCurrentPosition = 50, YCurrentPosition = 60, ZCurrentPosition = 70, XLastAlivePosition = 120, YLastAlivePosition = 130, ZLastAlivePosition = 140, XCurrentViewAngle = 45.0f, YCurrentViewAngle = 225.0f, SetPosCommandCurrentPosition = "setpos 50 60 70; setang 45 225", Message = "bad map", TimeInRound = 31.7568, } }; var TeamPlayersValues = new List <TeamPlayers>() { new TeamPlayers() { Round = 1, Terrorists = new List <Player>() { new Player { Name = "JimWood", SteamID = 32443298432, EntityID = 45, UserID = 1, LastAlivePosition = new Vector() { X = 100, Y = 100, Z = 100, }, Position = new Vector() { X = 200, Y = 200, Z = 200, }, Money = 200, RoundStartEquipmentValue = 2700, } }, CounterTerrorists = new List <Player>() { new Player { Name = "TheWhaleMan", SteamID = 12321313213, EntityID = 46, UserID = 2, LastAlivePosition = new Vector() { X = 90, Y = 900, Z = 9000, }, Position = new Vector() { X = 80, Y = 800, Z = 8000, }, Money = 200, RoundStartEquipmentValue = 200, } } }, new TeamPlayers() { Round = 2, Terrorists = new List <Player>() { new Player { Name = "TheWhaleMan", SteamID = 12321313213, EntityID = 46, UserID = 2, LastAlivePosition = new Vector() { X = 400, Y = 400, Z = 400, }, Position = new Vector() { X = 500, Y = 500, Z = 500, }, Money = 1000, RoundStartEquipmentValue = 200, } }, CounterTerrorists = new List <Player>() { new Player { Name = "JimWood", SteamID = 32443298432, EntityID = 45, UserID = 1, LastAlivePosition = new Vector() { X = 70, Y = 70, Z = 70, }, Position = new Vector() { X = 60, Y = 60, Z = 60, }, Money = 5000, RoundStartEquipmentValue = 4750, } } } }; var PlayerKilledEventsValues = new List <PlayerKilledEventArgs>() { new PlayerKilledEventArgs { Round = 1, TimeInRound = 40, Killer = TeamPlayersValues[0].Terrorists[0], Victim = TeamPlayersValues[0].CounterTerrorists[0], Assister = null, KillerBotTakeover = false, VictimBotTakeover = false, AssisterBotTakeover = false, Headshot = true, Suicide = false, TeamKill = false, PenetratedObjects = 0, AssistedFlash = false, }, new PlayerKilledEventArgs { Round = 2, TimeInRound = 90, Killer = TeamPlayersValues[1].CounterTerrorists[0], Victim = TeamPlayersValues[1].Terrorists[0], Assister = null, KillerBotTakeover = true, VictimBotTakeover = true, AssisterBotTakeover = true, Headshot = true, Suicide = false, TeamKill = false, PenetratedObjects = 1, AssistedFlash = true, } }; var PlayerValues = new Dictionary <string, IEnumerable <Player> >() { { "Kills", new List <Player>() { TeamPlayersValues[0].Terrorists[0], TeamPlayersValues[1].CounterTerrorists[0], } }, { "Deaths", new List <Player>() { TeamPlayersValues[0].CounterTerrorists[0], TeamPlayersValues[1].Terrorists[0], } }, { "Headshots", new List <Player>() { TeamPlayersValues[0].Terrorists[0], } }, { "Assists", new List <Player>() { TeamPlayersValues[0].CounterTerrorists[0], } }, { "MVPs", new List <Player>() { TeamPlayersValues[0].Terrorists[0], TeamPlayersValues[1].CounterTerrorists[0], } }, { "Shots", new List <Player>() { TeamPlayersValues[0].Terrorists[0], TeamPlayersValues[0].Terrorists[0], TeamPlayersValues[0].Terrorists[0], TeamPlayersValues[1].Terrorists[0], TeamPlayersValues[1].CounterTerrorists[0], TeamPlayersValues[1].CounterTerrorists[0], TeamPlayersValues[1].CounterTerrorists[0], } }, { "Plants", new List <Player>() { TeamPlayersValues[0].Terrorists[0], TeamPlayersValues[1].Terrorists[0], } }, { "Defuses", new List <Player>() { TeamPlayersValues[1].CounterTerrorists[0], } }, { "Rescues", new List <Player>() { TeamPlayersValues[0].CounterTerrorists[0], TeamPlayersValues[0].CounterTerrorists[0], } } }; var WeaponValues = new List <Equipment>() { new Equipment { Owner = TeamPlayersValues[0].Terrorists[0], Weapon = EquipmentElement.AK47 }, new Equipment { Owner = TeamPlayersValues[0].CounterTerrorists[0], Weapon = EquipmentElement.AWP } }; var PenetrationValues = new List <int>() { 0, 1, }; var BombsitePlantValues = new List <BombPlanted>() { new BombPlanted { Bombsite = 'A', Player = TeamPlayersValues[0].Terrorists[0], Round = 1, TimeInRound = 35, XPosition = 100, YPosition = 100, ZPosition = 100, }, new BombPlanted { Bombsite = 'B', Player = TeamPlayersValues[1].Terrorists[0], Round = 2, TimeInRound = 60, XPosition = 400, YPosition = 400, ZPosition = 400, } }; var BombsiteExplodeValues = new List <BombExploded>() { new BombExploded { Bombsite = 'A', Player = TeamPlayersValues[0].Terrorists[0], Round = 1, TimeInRound = 75, } }; var BombsiteDefuseValues = new List <BombDefused>() { new BombDefused { Bombsite = 'B', Player = TeamPlayersValues[1].CounterTerrorists[0], Round = 2, TimeInRound = 100, HasKit = true, } }; var HostageRescueValues = new List <HostageRescued>() { new HostageRescued { Hostage = 'A', HostageIndex = 250, RescueZone = 0, Player = TeamPlayersValues[0].CounterTerrorists[0], Round = 1, TimeInRound = 50, XPosition = 800, YPosition = 800, ZPosition = 800, }, new HostageRescued { Hostage = 'B', HostageIndex = 251, RescueZone = 0, Player = TeamPlayersValues[0].CounterTerrorists[0], Round = 1, TimeInRound = 51, XPosition = 700, YPosition = 700, ZPosition = 700, } }; var HostagePickedUpValues = new List <HostagePickedUp>() { new HostagePickedUp { Hostage = 'A', HostageIndex = 250, Player = TeamPlayersValues[0].CounterTerrorists[0], Round = 1, TimeInRound = 20, }, new HostagePickedUp { Hostage = 'B', HostageIndex = 251, Player = TeamPlayersValues[0].CounterTerrorists[0], Round = 1, TimeInRound = 35, }, new HostagePickedUp { Hostage = 'A', HostageIndex = 250, Player = TeamPlayersValues[1].CounterTerrorists[0], Round = 2, TimeInRound = 40, } }; var TeamValues = new List <Team>() { Team.Terrorist, Team.CounterTerrorist, }; var RoundEndReasonValues = new List <RoundEndReason>() { RoundEndReason.TargetBombed, RoundEndReason.BombDefused, }; var RoundLengthValues = new List <double>() { 80, 105, }; var TeamEquipmentValues = new List <TeamEquipmentStats>() { new TeamEquipmentStats { Round = 1, TEquipValue = 2900, TExpenditure = 200, CTEquipValue = 450, CTExpenditure = 50, }, new TeamEquipmentStats { Round = 2, TEquipValue = 800, TExpenditure = 600, CTEquipValue = 5750, CTExpenditure = 1000, } }; var GrenadeValues = new List <NadeEventArgs>() { new FlashEventArgs { NadeType = EquipmentElement.Flash, ThrownBy = TeamPlayersValues[0].Terrorists[0], Position = new Vector() { X = 500, Y = 500, Z = 500, }, FlashedPlayers = new Player[1] { TeamPlayersValues[0].CounterTerrorists[0] } } as NadeEventArgs, new NadeEventArgs { NadeType = EquipmentElement.Smoke, ThrownBy = TeamPlayersValues[0].Terrorists[0], Position = new Vector() { X = 500, Y = 500, Z = 500, }, }, new NadeEventArgs { NadeType = EquipmentElement.HE, ThrownBy = TeamPlayersValues[0].Terrorists[0], Position = new Vector() { X = 500, Y = 500, Z = 500, }, }, new NadeEventArgs { NadeType = EquipmentElement.Molotov, // all molotovs are down as incendiaries, specified why in DemoParser.cs, search for "FireNadeStarted". ThrownBy = TeamPlayersValues[0].Terrorists[0], Position = new Vector() { X = 500, Y = 500, Z = 500, }, }, new NadeEventArgs { NadeType = EquipmentElement.Incendiary, ThrownBy = TeamPlayersValues[0].Terrorists[0], Position = new Vector() { X = 500, Y = 500, Z = 500, }, }, new NadeEventArgs { NadeType = EquipmentElement.Decoy, ThrownBy = TeamPlayersValues[0].Terrorists[0], Position = new Vector() { X = 500, Y = 500, Z = 500, }, } }; var ChickenValues = new List <ChickenKilledEventArgs>() { new ChickenKilledEventArgs { } }; var ShotsFiredValues = new List <ShotFired>() { new ShotFired { Round = 1, Shooter = TeamPlayersValues[0].Terrorists[0] }, new ShotFired { Round = 1, Shooter = TeamPlayersValues[0].Terrorists[0] }, new ShotFired { Round = 1, Shooter = TeamPlayersValues[0].Terrorists[0] }, new ShotFired { Round = 2, Shooter = TeamPlayersValues[1].Terrorists[0] }, new ShotFired { Round = 2, Shooter = TeamPlayersValues[1].CounterTerrorists[0] }, new ShotFired { Round = 2, Shooter = TeamPlayersValues[1].CounterTerrorists[0] }, new ShotFired { Round = 2, Shooter = TeamPlayersValues[1].CounterTerrorists[0] } }; ProcessedData = new ProcessedData() { DemoInformation = DemoInformation, SameFilename = true, SameFolderStructure = true, ParseChickens = true, FoldersToProcess = new List <string>() { "someFolder" }, OutputRootFolder = "outputFolder", tanookiStats = tanookiStats, MatchStartValues = MatchStartValues, SwitchSidesValues = SwitchSidesValues, MessagesValues = MessagesValues, TeamPlayersValues = TeamPlayersValues, PlayerKilledEventsValues = PlayerKilledEventsValues, PlayerValues = PlayerValues, WeaponValues = WeaponValues, PenetrationValues = PenetrationValues, BombsitePlantValues = BombsitePlantValues, BombsiteExplodeValues = BombsiteExplodeValues, BombsiteDefuseValues = BombsiteDefuseValues, HostageRescueValues = HostageRescueValues, HostagePickedUpValues = HostagePickedUpValues, TeamValues = TeamValues, RoundEndReasonValues = RoundEndReasonValues, RoundLengthValues = RoundLengthValues, TeamEquipmentValues = TeamEquipmentValues, GrenadeValues = GrenadeValues, ChickenValues = ChickenValues, ShotsFiredValues = ShotsFiredValues, WriteTicks = true }; }
//Program entry point static void Main(string[] args) { string cfgPath = "config.cfg"; bool recursive = false; bool steaminfo = false; bool clear = false; bool parseChickens = true; string outputRootFolder = "parsed"; bool sameFilename = false; bool sameFolderStructure = false; bool lowOutputMode = false; List <string> foldersToProcess = new List <string>(); List <string> demosToProcess = new List <string>(); if (args.Count() == 0) { helpText(); return; } for (int i = 0; i < args.Count(); i++) { var arg = args[i].ToLower(); if (arg == "-config") { if (i < args.Count()) { cfgPath = args[i + 1]; } i++; } else if (arg == "-folders") { bool searching = true; while (i < args.Count() - 1 && searching) { i++; if (args[i][0] == '-') { searching = false; } else { foldersToProcess.Add(args[i]); } } i--; } else if (arg == "-demos") { bool searching = true; while (i < args.Count() - 1 && searching) { i++; if (args[i][0] == '-') { searching = false; } else { demosToProcess.Add(args[i]); } } i--; } else if (arg == "-output") { outputRootFolder = args[i + 1]; i++; } else if (arg == "-clear") { clear = true; } else if (arg == "-steaminfo") { steaminfo = true; } else if (arg == "-recursive") { recursive = true; } else if (arg == "-help") { helpText(); return; } else if (arg == "-nochickens") { parseChickens = false; } else if (arg == "-samefilename") { sameFilename = true; } else if (arg == "-samefolderstructure") { sameFolderStructure = true; } else if (arg == "-lowoutputmode") { lowOutputMode = true; } } if (steaminfo) { if (File.Exists(cfgPath)) { try { Config cfg = new Config(cfgPath); Steam.setAPIKey(cfg.keyVals["apikey"]); if (Steam.getSteamUserNamesLookupTable(new List <long>() { 76561198072130043 }) == null) { throw new Exception("CONFIG::STEAM_API_KEY::INVALID"); } } catch (Exception e) { Debug.Error("CONFIG ERROR... INFO:: {0}\nSteam names will not be retrieved!!!", e.Message); steaminfo = false; } } else { Debug.Error("Config unreadable... Steam names will not be retrieved!!!"); steaminfo = false; } } //Clear by recreating folder if (clear && Directory.Exists(outputRootFolder)) { Directory.Delete(outputRootFolder, true); Directory.CreateDirectory(outputRootFolder); } else if (!Directory.Exists(outputRootFolder)) { Directory.CreateDirectory(outputRootFolder); } List <DemoInformation> demosInformation = new List <DemoInformation>(); foreach (string folder in foldersToProcess) { try { string[] subDemos = Directory.GetFiles(Path.GetFullPath(folder), "*.dem", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); foreach (string demo in subDemos) { string[] pathSplit = demo.Split('\\'); string testDate, testType, mapname; Guid guid; string[] filenameSplit = pathSplit[pathSplit.Count() - 1].Split('.'); bool isFaceitDemo = Guid.TryParse(filenameSplit[0], out guid); if (isFaceitDemo) { testDate = "unknown"; testType = "unknown"; mapname = "unknown"; } else { filenameSplit = pathSplit[pathSplit.Count() - 1].Split('_', '.'); bool isSEDiscordDemo = filenameSplit.Count() > 5 ? true : false; if (isSEDiscordDemo) { testDate = $"{ filenameSplit[1] }/{ filenameSplit[0] }/{ filenameSplit[2] }"; testType = $"{ filenameSplit[filenameSplit.Count() - 2] }"; mapname = $"{ filenameSplit[3] }"; for (int i = 4; i < filenameSplit.Count() - 2; i++) { mapname += $"_{ filenameSplit[i] }"; } } else //cannot determine demo name format { testDate = "unknown"; testType = "unknown"; mapname = "unknown"; } } demosInformation.Add(new DemoInformation() { DemoName = demo, MapName = mapname, TestDate = testDate, TestType = testType }); } } catch (Exception e) { throw e; } } foreach (string demo in demosToProcess) { try { string testDate, testType, mapname; Guid guid; string[] filenameSplit = demo.Split('.'); bool isFaceitDemo = Guid.TryParse(filenameSplit[0], out guid); if (isFaceitDemo) { testDate = "unknown"; testType = "unknown"; mapname = "unknown"; } else { filenameSplit = demo.Split('_', '.'); bool isSEDiscordDemo = filenameSplit.Count() > 5 ? true : false; if (isSEDiscordDemo) { testDate = $"{ filenameSplit[1] }/{ filenameSplit[0] }/{ filenameSplit[2] }"; testType = $"{ filenameSplit[filenameSplit.Count() - 2] }"; mapname = $"{ filenameSplit[3] }"; for (int i = 4; i < filenameSplit.Count() - 2; i++) { mapname += $"_{ filenameSplit[i] }"; } } else //cannot determine demo name format { testDate = "unknown"; testType = "unknown"; mapname = "unknown"; } } demosInformation.Add(new DemoInformation() { DemoName = demo, MapName = mapname, TestDate = testDate, TestType = testType }); } catch (Exception e) { throw e; } } Debug.Info("Starting processing of {0} demos.\n", demosInformation.Count()); DateTime startTime = DateTime.Now; int passCount = 0; Console.CursorVisible = false; //Process all the found demos for (int i = 0; i < demosInformation.Count(); i++) { Console.WriteLine($"Parsing demo {demosInformation[i].DemoName}"); MatchData mdTest = MatchData.FromDemoFile(demosInformation[i].DemoName, parseChickens, lowOutputMode); IEnumerable <MatchStartedEventArgs> mse = new List <MatchStartedEventArgs>(); IEnumerable <SwitchSidesEventArgs> sse = new List <SwitchSidesEventArgs>(); IEnumerable <FeedbackMessage> fme = new List <FeedbackMessage>(); IEnumerable <TeamPlayers> tpe = new List <TeamPlayers>(); IEnumerable <PlayerKilledEventArgs> pke = new List <PlayerKilledEventArgs>(); Dictionary <string, IEnumerable <Player> > pe = new Dictionary <string, IEnumerable <Player> >(); IEnumerable <Equipment> pwe = new List <Equipment>(); IEnumerable <int> poe = new List <int>(); IEnumerable <BombPlanted> bpe = new List <BombPlanted>(); IEnumerable <BombExploded> bee = new List <BombExploded>(); IEnumerable <BombDefused> bde = new List <BombDefused>(); IEnumerable <HostageRescued> hre = new List <HostageRescued>(); IEnumerable <HostagePickedUp> hpu = new List <HostagePickedUp>(); IEnumerable <DisconnectedPlayer> dpe = new List <DisconnectedPlayer>(); IEnumerable <Team> te = new List <Team>(); IEnumerable <RoundEndReason> re = new List <RoundEndReason>(); IEnumerable <double> le = new List <double>(); IEnumerable <TeamEquipmentStats> tes = new List <TeamEquipmentStats>(); IEnumerable <NadeEventArgs> ge = new List <NadeEventArgs>(); //IEnumerable<SmokeEventArgs> gse = new List<SmokeEventArgs>(); //IEnumerable<FlashEventArgs> gfe = new List<FlashEventArgs>(); //IEnumerable<GrenadeEventArgs> gge = new List<GrenadeEventArgs>(); //IEnumerable<FireEventArgs> gie = new List<FireEventArgs>(); //IEnumerable<DecoyEventArgs> gde = new List<DecoyEventArgs>(); IEnumerable <ChickenKilledEventArgs> cke = new List <ChickenKilledEventArgs>(); IEnumerable <ShotFired> sfe = new List <ShotFired>(); mse = (from start in mdTest.GetEvents <MatchStartedEventArgs>() select(start as MatchStartedEventArgs)); sse = (from switchSide in mdTest.GetEvents <SwitchSidesEventArgs>() select(switchSide as SwitchSidesEventArgs)); fme = (from message in mdTest.GetEvents <FeedbackMessage>() select(message as FeedbackMessage)); pke = (from player in mdTest.GetEvents <PlayerKilledEventArgs>() select(player as PlayerKilledEventArgs)); pe.Add("Kills", from player in mdTest.GetEvents <PlayerKilledEventArgs>() select(player as PlayerKilledEventArgs).Killer); pe.Add("Deaths", from player in mdTest.GetEvents <PlayerKilledEventArgs>() select(player as PlayerKilledEventArgs).Victim); pe.Add("Headshots", from player in mdTest.GetEvents <PlayerKilledEventArgs>() where (player as PlayerKilledEventArgs).Headshot select(player as PlayerKilledEventArgs).Killer); pe.Add("Assists", from player in mdTest.GetEvents <PlayerKilledEventArgs>() where (player as PlayerKilledEventArgs).Assister != null select(player as PlayerKilledEventArgs).Assister); pwe = (from weapon in mdTest.GetEvents <PlayerKilledEventArgs>() select(weapon as PlayerKilledEventArgs).Weapon); poe = (from penetration in mdTest.GetEvents <PlayerKilledEventArgs>() select(penetration as PlayerKilledEventArgs).PenetratedObjects); pe.Add("MVPs", from player in mdTest.GetEvents <RoundMVPEventArgs>() select(player as RoundMVPEventArgs).Player); pe.Add("Shots", from player in mdTest.GetEvents <WeaponFiredEventArgs>() select(player as WeaponFiredEventArgs).Shooter); pe.Add("Plants", from player in mdTest.GetEvents <BombPlanted>() select(player as BombPlanted).Player); pe.Add("Defuses", from player in mdTest.GetEvents <BombDefused>() select(player as BombDefused).Player); pe.Add("Rescues", from player in mdTest.GetEvents <HostageRescued>() select(player as HostageRescued).Player); bpe = (from plant in mdTest.GetEvents <BombPlanted>() select plant as BombPlanted) .GroupBy(p => p.Round) .Select(p => p.FirstOrDefault()); bee = (from explode in mdTest.GetEvents <BombExploded>() select explode as BombExploded) .GroupBy(p => p.Round) .Select(p => p.FirstOrDefault()); bde = (from defuse in mdTest.GetEvents <BombDefused>() select defuse as BombDefused) .GroupBy(p => p.Round) .Select(p => p.FirstOrDefault()); hre = (from hostage in mdTest.GetEvents <HostageRescued>() select hostage as HostageRescued); hpu = (from hostage in mdTest.GetEvents <HostagePickedUp>() select hostage as HostagePickedUp); dpe = (from disconnection in mdTest.GetEvents <DisconnectedPlayer>() select(disconnection as DisconnectedPlayer)); te = (from team in mdTest.GetEvents <RoundEndedEventArgs>() select(team as RoundEndedEventArgs).Winner); re = (from reason in mdTest.GetEvents <RoundEndedEventArgs>() select(reason as RoundEndedEventArgs).Reason); le = (from length in mdTest.GetEvents <RoundEndedEventArgs>() select(length as RoundEndedEventArgs).Length); tpe = (from teamPlayers in mdTest.GetEvents <TeamPlayers>() where (teamPlayers as TeamPlayers).Round <= te.Count() // removes extra TeamPlayers if freezetime_end event triggers once a playtest is finished select(teamPlayers as TeamPlayers)); tes = (from round in mdTest.GetEvents <TeamEquipmentStats>() select(round as TeamEquipmentStats)); ge = (from nade in mdTest.GetEvents <NadeEventArgs>() select(nade as NadeEventArgs)); cke = (from chickenKill in mdTest.GetEvents <ChickenKilledEventArgs>() select(chickenKill as ChickenKilledEventArgs)); sfe = (from shot in mdTest.GetEvents <ShotFired>() select(shot as ShotFired)); tanookiStats tanookiStats = tanookiStatsCreator(tpe, dpe); if (mdTest.passed) { // create the json output files using the data gathered var processedData = new ProcessedData() { DemoInformation = demosInformation[i], SameFilename = sameFilename, SameFolderStructure = sameFolderStructure, ParseChickens = parseChickens, FoldersToProcess = foldersToProcess, OutputRootFolder = outputRootFolder, tanookiStats = tanookiStats, MatchStartValues = mse, SwitchSidesValues = sse, MessagesValues = fme, TeamPlayersValues = tpe, PlayerKilledEventsValues = pke, PlayerValues = pe, WeaponValues = pwe, PenetrationValues = poe, BombsitePlantValues = bpe, BombsiteExplodeValues = bee, BombsiteDefuseValues = bde, HostageRescueValues = hre, HostagePickedUpValues = hpu, TeamValues = te, RoundEndReasonValues = re, RoundLengthValues = le, TeamEquipmentValues = tes, GrenadeValues = ge, ChickenValues = cke, ShotsFiredValues = sfe, WriteTicks = true }; var allStats = mdTest.CreateFiles(processedData); passCount++; Console.WriteLine($"Finished parsing demo {demosInformation[i].DemoName}.\n"); } else { Console.WriteLine($"Failed parsing demo {demosInformation[i].DemoName}.\n"); } } Console.CursorVisible = true; Debug.Blue("========== PROCESSING COMPLETE =========\n"); DateTime end = DateTime.Now; Debug.White("Processing took {0} minutes\n", (end - startTime).TotalMinutes); Debug.White("Passed: {0}\n", passCount); Debug.White("Failed: {0}\n", demosInformation.Count() - passCount); }