public void Read_MatchOnOurServer_ReturnsCorrectStatistics() { var demo = new Demo { FilePath = Path.Combine("TestData", @"auto0-20210103-190414-139014994-de_dust2-honigbiene_vs_waldfrosch.dem") }; //Setting minimum number of rounds & players to 0 (different than during runtime) to allow reading this smaller demo file var demoReader = new DemoReader(new Match { Demo = demo }, 0, 0); demoReader.ReadHeader(); demoReader.Read(); Assert.Equal(0, demoReader.Match.CTScore); Assert.Equal(3, demoReader.Match.TScore); var expectedStatisticsAlex = demoReader.Match.PlayerResults.Single(x => x.SteamID == 76561198011775117); Assert.Equal(1, expectedStatisticsAlex.Kills); Assert.Equal(0, expectedStatisticsAlex.Deaths); Assert.Equal(3, expectedStatisticsAlex.Rounds); Assert.Equal(1, expectedStatisticsAlex.OneKill); Assert.Equal(1.096, expectedStatisticsAlex.HLTVScore); var expectedStatisticsFlo = demoReader.Match.PlayerResults.Single(x => x.SteamID == 76561197973591119); Assert.Equal(-1, expectedStatisticsFlo.Kills); Assert.Equal(2, expectedStatisticsFlo.Deaths); Assert.Equal(3, expectedStatisticsFlo.Rounds); Assert.Equal(0.091, expectedStatisticsFlo.HLTVScore); }
public MainWindow() { InitializeComponent(); m_Reader = Task.Run(() => { var stream = File.Open("demos/cp_process_final.dem", FileMode.Open, FileAccess.Read); return(DemoReader.FromStream(stream)); }); m_Reader.ContinueWith(lastTask => { lastTask.Result.Events.NewTick.Add(Events_NewTick); lastTask.Result.Events.NewTick.Add(UpdatePlayerStatuses); lastTask.Result.Events.NewTick.Add(UpdatePlayerPositions); lastTask.Result.Events.NewTick.Add(UpdateRocketPositions); lastTask.Result.Events.TempEntityCreated.Add(TempEntCreated); lastTask.Result.Events.GameEvent.Add(GameEventTriggered); progress.Dispatcher.Invoke(() => progress.Maximum = lastTask.Result.Header.m_PlaybackTicks.Value); lastTask.Result.SimulateDemo(); }); }
public void Read_GameIsRestartedAfterMatchStarted_DoesNotCountEventsBeforeRealMatchStart() { var demo = new Demo { FilePath = Path.Combine("TestData", @"auto0-20210102-204730-1247575572-de_mirage-honigbiene_vs_waldfrosch.dem") }; var demoReader = new DemoReader(new Match { Demo = demo }); demoReader.ReadHeader(); demoReader.Read(); Assert.Equal(15, demoReader.Match.CTScore); Assert.Equal(15, demoReader.Match.TScore); var expectedStatisticsForSteamId = new List <MatchStatistics> { new MatchStatistics { SteamID = 76561197984050254, Kills = 26, Deaths = 24, Rounds = 30 }, new MatchStatistics { SteamID = 76561197973591119, Kills = 24, Deaths = 27, Rounds = 30 }, new MatchStatistics { SteamID = 76561197978519504, Kills = 21, Deaths = 22, Rounds = 30 }, new MatchStatistics { SteamID = 76561198011775117, Kills = 21, Deaths = 18, Rounds = 30 }, new MatchStatistics { SteamID = 76561198011654217, Kills = 15, Deaths = 23, Rounds = 30 }, new MatchStatistics { SteamID = 76561199045573415, Kills = 37, Deaths = 19, Rounds = 30 }, new MatchStatistics { SteamID = 76561198258023370, Kills = 25, Deaths = 19, Rounds = 30 }, new MatchStatistics { SteamID = 76561197995643389, Kills = 21, Deaths = 23, Rounds = 30 }, new MatchStatistics { SteamID = 76561198031200891, Kills = 17, Deaths = 21, Rounds = 30 }, new MatchStatistics { SteamID = 76561198053826525, Kills = 14, Deaths = 25, Rounds = 30 } }; foreach (var playerResult in demoReader.Match.PlayerResults) { var expected = expectedStatisticsForSteamId.Single(x => x.SteamID == playerResult.SteamID); Assert.Equal(expected.Kills, playerResult.Kills); Assert.Equal(expected.Deaths, playerResult.Deaths); Assert.Equal(expected.Rounds, playerResult.Rounds); } }
public static void Run() { DefaultObservable <User> observable = new DefaultObservable <User>(); AbstractTaskObserver <User> observer = new DemoTaskObserver(); IReader <User> reader = new DemoReader(); var runner = new ObserverTaskRunner <User>(observable, observer, reader); // 开始运行 runner.Run(); }
private void Demo(IProgress <string> progress) { progress.Report("Start"); progress.Report($"Reading demo files from \"{Settings.DemosFolderPath}\" folder"); var demoFileRepository = new DemoFileRepository(new MongoRepositoryFactory(new ConnectionStringFactory())); var demoRepository = new BaseRepository(new MongoRepositoryFactory(new ConnectionStringFactory())); var demoReader = new DemoReader(Settings.DemosFolderPath, demoFileRepository, demoRepository, Config.CreateMapper(), progress); demoReader.Start(Settings.TimerInterval); }
public void Read_OnlyFourRounds_CorrectStatistics() { var demo = new Demo { FilePath = Path.Combine("TestData", @"auto0-20201222-213144-349508145-de_inferno-honigbiene_vs_waldfrosch.dem") }; var demoReader = new DemoReader(new Match { Demo = demo }, 0, 0); demoReader.ReadHeader(); demoReader.Read(); Assert.Equal(2, demoReader.Match.CTScore); Assert.Equal(2, demoReader.Match.TScore); Assert.Equal(4, demoReader.Match.Rounds); var expectedStatisticsForSteamId = new List <MatchStatistics> { new MatchStatistics { SteamID = 76561198011775117, Kills = 1, Deaths = 3, Rounds = 4, OneKill = 0, TwoKill = 1 }, new MatchStatistics { SteamID = 76561197984050254, Kills = 1, Deaths = 4, Rounds = 4, OneKill = 1 }, new MatchStatistics { SteamID = 76561198053826525, Kills = -1, Deaths = 4, Rounds = 4 }, new MatchStatistics { SteamID = 76561199045573415, Kills = 8, Deaths = 1, Rounds = 4, OneKill = 2, TwoKill = 0, ThreeKill = 2 }, new MatchStatistics { SteamID = 76561197973591119, Kills = 0, Deaths = 2, Rounds = 4 }, new MatchStatistics { SteamID = 76561198258023370, Kills = -1, Deaths = 2, Rounds = 4, OneKill = 1 } }; foreach (var playerResult in demoReader.Match.PlayerResults) { var expected = expectedStatisticsForSteamId.Single(x => x.SteamID == playerResult.SteamID); Assert.Equal(expected.Kills, playerResult.Kills); Assert.Equal(expected.Deaths, playerResult.Deaths); Assert.Equal(expected.Rounds, playerResult.Rounds); Assert.Equal(expected.OneKill, playerResult.OneKill); Assert.Equal(expected.TwoKill, playerResult.TwoKill); Assert.Equal(expected.ThreeKill, playerResult.ThreeKill); Assert.Equal(expected.FourKill, playerResult.FourKill); Assert.Equal(expected.FiveKill, playerResult.FiveKill); } }
public void Parse_MatchHasDifferentNumberOfRoundsPreset_ThrowsInconsistentStatistics() { var demo = new Demo { FilePath = Path.Combine("TestData", @"auto0-20210103-190414-139014994-de_dust2-honigbiene_vs_waldfrosch.dem") }; var match = new Match { Demo = demo, Rounds = 6 }; //Setting minimum number of rounds & players to 0 (different than during runtime) to allow reading this smaller demo file var demoReader = new DemoReader(match, 0, 0); Assert.Throws <InconsistentStatisticsException>(() => demoReader.Parse()); }
public void Read_GameOnOurServer_ReturnsCorrectScores(string demoFileName, int CTScore, int TScore) { var demo = new Demo { FilePath = Path.Combine("TestData", demoFileName) }; var demoReader = new DemoReader(new Match { Demo = demo }, 0, 0); var match = demoReader.Parse(); Assert.Equal(CTScore, match.CTScore); Assert.Equal(TScore, match.TScore); }
public void ProcessNewMatches(object state) { var newMatches = new List <Match>(); var blacklistedMatches = new List <Match>(); var newDemoFiles = Directory.EnumerateFiles(myDemoWatchFolder).Where(x => x.EndsWith(".dem")); myLogger.LogDebug($"Found {newDemoFiles.Count()} new demo files in the watch folder"); var demoBackuper = new DemoBackuper(myLoggerFactory.CreateLogger <DemoBackuper>()); foreach (var demoFile in newDemoFiles) { var match = new Match { Demo = new Demo { FilePath = demoFile }, Date = File.GetCreationTime(demoFile) }; try { using var demoReader = new DemoReader(match); demoReader.ReadHeader(); demoReader.Read(); match = demoReader.Match; myLogger.LogTrace($"Finished analyzing demo file {Path.GetFileName(demoFile)}"); newMatches.Add(match); } catch (DemoReaderException e) { match.Id += Guid.NewGuid().ToString(); match.Demo.Id = match.Id; myLogger.LogWarning($"Analyzing demo from watch folder ({Path.GetFileName(demoFile)}) failed: {e.Message}. Adding to repository (id: {match.Id}) without stats -> blacklisted."); match.PlayerResults.Clear(); match.CTScore = -1; match.TScore = -1; blacklistedMatches.Add(match); } BackupDemo(match.Demo, demoBackuper); } using var scope = myScopeFactory.CreateScope(); myLogger.LogTrace($"Getting match repository to add {newMatches.Count} new matches and blacklist {blacklistedMatches.Count} demos."); var matchRepository = scope.ServiceProvider.GetRequiredService <MatchRepository>(); matchRepository.AddMatchesAndSave(newMatches); matchRepository.AddMatchesAndSave(blacklistedMatches); }
public void Read_MatchMakingGame_ReturnsCorrectMatchType(string demoFileName, CompetitiveMatchType expectedMatchType) { var demo = new Demo { FilePath = Path.Combine("TestData", demoFileName) }; var demoReader = new DemoReader(new Match { Demo = demo }, 0, 0); var match = demoReader.Parse(); foreach (var matchStatistics in match.PlayerResults) { Assert.Equal(expectedMatchType, matchStatistics.MatchType); } }
public void Read_MatchMakingGame_ReturnsCorrectPlayerHighestAndLowestHLTV(string demoFileName, string highestHLTVPlayerSteamId, string lowestHLTVPlayerSteamId) { var demo = new Demo { FilePath = Path.Combine("TestData", demoFileName) }; var demoReader = new DemoReader(new Match { Demo = demo }, 0, 0); var match = demoReader.Parse(); var orderedByDescendingHLTV = match.PlayerResults.OrderByDescending(x => x.HLTVScore); Assert.Equal(long.Parse(highestHLTVPlayerSteamId), orderedByDescendingHLTV.First().SteamID); Assert.Equal(long.Parse(lowestHLTVPlayerSteamId), orderedByDescendingHLTV.Last().SteamID); }
static void Main(string[] args) { using (var stream = File.Open(@"D:\Steam\steamapps\common\Team Fortress 2\tf\demos\testdemo.dem", FileMode.Open, FileAccess.Read)) { Console.WriteLine("Parsing test demo file..."); DateTime start = DateTime.Now; DemoReader reader = DemoReader.FromStream(stream); DateTime end = DateTime.Now; Console.WriteLine("Finished parsing test demo file in {0:N1}ms.", (end - start).TotalMilliseconds); reader.SimulateDemo(); Console.WriteLine("Finished simulating demo."); Console.ReadLine(); } }
public void Read_GameIsRestartedAfterMatchStarted_DoesNotCountRoundsBeforeRealMatchStart() { var demo = new Demo { FilePath = Path.Combine("TestData", @"auto0-20210102-225615-1235223714-de_dust2-honigbiene_vs_waldfrosch.dem") }; var demoReader = new DemoReader(new Match { Demo = demo }); demoReader.ReadHeader(); demoReader.Read(); Assert.Equal(30, demoReader.Match.Rounds); foreach (var player in demoReader.Match.PlayerResults) { Assert.Equal(30, player.Rounds); } }
/// <summary> /// Initializes a new instance of the <see cref="LocalDemo" /> class. /// </summary> /// <param name="path">The path to the demo file.</param> /// <param name="version">The version of the demo.</param> public LocalDemo(string path, GameType version) { Path = path; Version = version; try { using (var stream = Open()) { var reader = new DemoReader(stream, Version); var config = reader.ReadConfiguration(); config.TryGetValue("mapname", out var map); config.TryGetValue("fs_game", out var mod); config.TryGetValue("g_gametype", out var gameType); config.TryGetValue("sv_hostname", out var server); config.TryGetValue("sv_referencedIwdNames", out var iwdNames); config.TryGetValue("sv_referencedFFNames", out var ffNames); if (!string.IsNullOrWhiteSpace(mod) && mod.ToLower().StartsWith("mods/")) { mod = mod.Substring(5); } Map = map; Mod = mod; GameType = gameType; Server = server; IWDs = iwdNames == null ? new string[0] : iwdNames.Split(' '); FFs = ffNames == null ? new string[0] : ffNames.Split(' ').Select(ff => { // Change path of usermaps files to full paths. // e.g. usermaps/mp_caen2_load -> usermaps/mp_caen2/mp_caen2_load if (!ff.StartsWith("usermaps/mp_")) { return(ff); } var mapName = ff.Split('/').Last(); if (mapName.EndsWith("_load")) { mapName = mapName.Substring(0, mapName.Length - 5); return(string.Format("usermaps/{0}/{0}_load", mapName)); } return(string.Format("usermaps/{0}/{0}", mapName)); }); } } catch (Exception) { Map = "???"; Mod = "???"; GameType = "???"; Server = "File corrupted!"; IWDs = new string[0]; FFs = new string[0]; _isCorrupted = true; } }
private void ProcessNewMatches(GameCoordinatorClient gameCoordinatorClient, ShareCodeRepository shareCodeRepository, MatchRepository matchRepository) { var newSharingCodes = shareCodeRepository.GetRetryableBatch(5); if (!newSharingCodes.Any()) { return; } myLogger.LogDebug($"Retrieved {newSharingCodes.Count} new sharing codes: {string.Join(", ", newSharingCodes.Select(x => x.Code))}"); var newMatches = new List <Match>(); var demoDownloader = new DemoDownloader(myLoggerFactory.CreateLogger <DemoDownloader>()); var demoBackuper = new DemoBackuper(myLoggerFactory.CreateLogger <DemoBackuper>()); foreach (var sharingCode in newSharingCodes) { var demo = CreateNewDemoForShareCode(sharingCode); try { var match = gameCoordinatorClient.GetMatchInfo(demo); myLogger.LogTrace($"Got match details for sharing code {sharingCode.Code}"); match.Demo.FilePath = demoDownloader.DownloadAndDecompressDemo(match.Demo.DownloadURL); myLogger.LogTrace($"Downloaded and decompressed demo file for sharing code {sharingCode.Code}"); using var demoReader = new DemoReader(match, 0, 0); match = demoReader.Parse(); myLogger.LogTrace($"Finished analyzing demo file for sharing code {sharingCode.Code}"); newMatches.Add(match); } catch (GameCoordinatorException) { myLogger.LogWarning($"Couldn't get download url for sharing code {sharingCode.Code}. See previous logs/exceptions for explanation. Continuing."); continue; } catch (DemoDownloaderException exception) { myLogger.LogWarning($"Demo downloading or decompressing failed: {exception.Message} for sharing code {sharingCode.Code}."); continue; } catch (DemoReaderException e) { myLogger.LogWarning($"Analyzing demo for share code {sharingCode.Code} failed: {e.Message}"); demo.State = DemoState.ParseFailure; continue; } finally { TryBackupDemo(demo, demoBackuper); } } myLogger.LogDebug($"Downloaded and analyzed {newMatches.Count} new matches (from {newSharingCodes.Count} new sharing codes)."); myLogger.LogTrace($"Saving {newMatches.Count} new matches to repository."); var successfullySavedMatches = matchRepository.AddMatchesAndSave(newMatches); shareCodeRepository.RemoveCodes(successfullySavedMatches.Select(x => x.Demo.ShareCode)); }
public DemoAdapter(ILogger <DemoAdapter> logger) { this.logger = logger; this.state = new DemoMachineState(); this.reader = new DemoReader(); }