public async Task UpdateGameState(Guid gameId, ContentQuery query = null) { _stateHandler.SelectedGameId = gameId; var gameContext = _locator.GetGameContext(); var game = await gameContext.FindGameOrThrowAsync(gameId).ConfigureAwait(false); if (query == null) game.CleanupContent(); await _setup.HandleGameContentsWhenNeeded(query, game.Id).ConfigureAwait(false); }
async Task ProcessGame(Game game, ContentQuery filterFunc, CancellationToken ct) { var invalidContent = game.Contents.Where(x => x.GameId == Guid.Empty).ToArray(); if (invalidContent.Any()) invalidContent.ForEach(x => x.FixGameId(game.Id)); var stats = await GetHashStats(game, ct).ConfigureAwait(false); if (!stats.ShouldSyncBecauseHashes && !stats.ShouldSyncBecauseVersion && (filterFunc == null)) return; var onlineContent = await GetContent(game, stats.Hashes).ConfigureAwait(false); ProcessContents(game, onlineContent, filterFunc); game.RefreshCollections(); var si = game.SyncInfo; var dt = Tools.Generic.GetCurrentUtcDateTime; si.ApiHashes = stats.Hashes; si.LastSync = dt; si.LastSyncVersion = Consts.SyncVersion; }
public async Task SyncContent(IReadOnlyCollection<Game> games, ContentQuery filterFunc = null) { if (Common.Flags.Verbose) MainLog.Logger.Info($"Syncing content for games: {string.Join(", ", games.Select(x => x.Id))}"); foreach (var g in games) await ProcessGame(g, filterFunc, CancellationToken.None).ConfigureAwait(false); }
private static Dictionary<Guid, ModClientApiJsonV3WithGameId> GetTheDesiredMods(Game game, ContentQuery filterFunc, IDictionary<Guid, ModClientApiJsonV3WithGameId> onlineContent) { var desired = onlineContent.Where(x => filterFunc.IsMatch(x.Value)); var dependencyChain = new Dictionary<Guid, ModClientApiJsonV3WithGameId>(); GetRelatedContent(game, desired.Select(x => x.Value), dependencyChain, onlineContent); return dependencyChain; }
private static Dictionary<Guid, ModClientApiJsonV3WithGameId> GetDesiredModList(Game game, IDictionary<Guid, ModClientApiJsonV3WithGameId> onlineContent, ContentQuery filterFunc, Dictionary<Guid, ModNetworkContent> currentContent) { if (filterFunc != null) return GetTheDesiredMods(game, filterFunc, onlineContent); var localMods = game.LocalContent.OfType<ModLocalContent>() .Select( x => onlineContent.Values.FirstOrDefault( c => c.PackageName.Equals(x.PackageName, StringComparison.CurrentCultureIgnoreCase))) .Where(x => x != null); var ids = currentContent.Keys.Concat(localMods.Select(x => x.Id)).Distinct(); return GetTheDesiredMods(game, new ContentQuery {Ids = ids.ToList()}, onlineContent); }
static void UpdateContents(Game game, IDictionary<Guid, ModClientApiJsonV3WithGameId> onlineContent, IDictionary<ModClientApiJsonV3WithGameId, ModNetworkContent> content, ContentQuery filterFunc = null) { var currentContent = game.NetworkContent.OfType<ModNetworkContent>().ToDictionary(x => x.Id, x => x); var desiredModsList = GetDesiredModList(game, onlineContent, filterFunc, currentContent); var mapping = desiredModsList.Keys .Where(onlineContent.ContainsKey) .Select( x => new { DTO = onlineContent[x], Existing = currentContent.ContainsKey(x) ? currentContent[x] : null }); foreach (var c in mapping) { var dto = c.DTO; var theGame = SetupGameStuff.GameSpecs.Select(x => x.Value).FindOrThrow(c.DTO.GameId); if (c.Existing == null) { var nc = dto.MapTo<ModNetworkContent>(); content[dto] = nc; game.Contents.Add(nc); } else { c.Existing.UpdateVersionInfo(dto.GetVersion(), dto.UpdatedVersion); dto.MapTo(c.Existing); content[dto] = c.Existing; } if (c.DTO.GameId != game.Id) content[dto].HandleOriginalGame(c.DTO.GameId, theGame.Slug, game.Id); } }
static void ProcessContents(Game game, IDictionary<Guid, ModClientApiJsonV3WithGameId> onlineContent, ContentQuery filterFunc) { // TODO: If we timestamp the DTO's, and save the timestamp also in our database, // then we can simply update data only when it has actually changed and speed things up. // The only thing to remember is when there are schema changes / new fields etc, either all timestamps need updating // or the syncer needs to take it into account.. var mapping = new Dictionary<ModClientApiJsonV3WithGameId, ModNetworkContent>(); UpdateContents(game, onlineContent, mapping, filterFunc); HandleDependencies(game, mapping); if (filterFunc == null) game.ProcessLocalContent(); }
public static Task HandleGameContentsWhenNeeded(this ISetupGameStuff This, ContentQuery query = null, params Guid[] gameIds) => This.HandleGameContentsWhenNeeded(gameIds, query);
public async Task HandleGameContentsWhenNeeded(IReadOnlyCollection<Guid> gameIds, ContentQuery query = null) { if (Common.Flags.Verbose) MainLog.Logger.Info($"Handling game contents for {string.Join(", ", gameIds)}"); var gc = _locator.GetGameContext(); await gc.Load(gameIds).ConfigureAwait(false); var games = gc.Games.Where(x => gameIds.Contains(x.Id) && x.InstalledState.IsInstalled).ToArray(); await _networkContentSyncer.SyncContent(games, query).ConfigureAwait(false); //if (shouldEmitEvents) await new StatusChanged(Status.Preparing, new ProgressInfo(progress: 50)).Raise().ConfigureAwait(false); await SynchronizeCollections(games).ConfigureAwait(false); foreach (var g in games) await g.RefreshState().ConfigureAwait(false); }