public IEnumerable <GameRule> GetRules(int modId) { DowMod mod = GetAll().Single(mod => mod.Id == modId); return(mod.Dependencies.SelectMany(dep => dep.DepMod.Rules).Concat(mod.Rules) .GroupBy(r => r.Name) .ToDictionary(g => g.Key, g => g.Last()) .Values); }
public void Add(DowMod mod) { var existing = context.Mods.SingleOrDefault(existing => existing.IsVanilla == mod.IsVanilla && existing.ModFolder.Equals(mod.ModFolder, StringComparison.OrdinalIgnoreCase)); if (existing != null) { context.Mods.Remove(existing); context.SaveChanges(); } context.ChangeTracker.TrackGraph(mod, node => node.Entry.State = !node.Entry.IsKeySet ? EntityState.Added : EntityState.Unchanged); context.SaveChanges(); }
private async Task LoadAllMods() { using var store = new ModsDataStore(); store.DropAll(); Dictionary <string, UnloadedMod> allUnloaded = BaseGameItems.Concat(ModItems) .GroupBy(item => item.Module.File.ModFolder, item => item.Module) .ToDictionary(g => g.Key, g => g.First()); foreach (var item in BaseGameItems.Concat(ModItems)) { item.IsLoaded = false; } var memo = new LoadMemo(); foreach (var item in BaseGameItems.Concat(ModItems).Where(mod => mod.Module.File.Playable)) { DowMod mod = await Observable.Start(() => dowModService.LoadMod(item.Module, allUnloaded, memo), RxApp.TaskpoolScheduler); store.Add(mod); item.IsLoaded = true; } // Yeah this is kind of weird. But essentially we want to load the playable mods first. // This is because they likely depend on the non-playable mods. Non-playable mods may be // sub-modules for playable mods. As such they might have Locales that reference the parent mod // for this reason we want to ensure that we load from the root. foreach (var item in BaseGameItems.Concat(ModItems).Where(mod => !mod.Module.File.Playable)) { DowMod mod = dowModService.LoadMod(item.Module, allUnloaded, memo); store.Add(mod); item.IsLoaded = true; } }
public DowMod LoadMod(UnloadedMod unloaded, Dictionary <string, UnloadedMod> allUnloaded, LoadMemo memo, LocaleStore?parentLocales = null) { DowMod?existing = memo.Get(unloaded.File.ModFolder, unloaded.File.IsVanilla); if (existing != null) { return(existing); } LocaleStore newLocales = new LocaleStore(); if (parentLocales != null) { newLocales.Dependencies.Add(parentLocales); } newLocales.Dependencies.Add(unloaded.Locales); var mod = new DowMod() { Name = unloaded.File.UIName, ModFolder = unloaded.File.ModFolder, Details = unloaded.File.Description, IsVanilla = unloaded.File.IsVanilla, Playable = unloaded.File.Playable }; mod.Dependencies = new List <DowModDependency>(); foreach (var dependency in unloaded.Dependencies) { mod.Dependencies.Add(new DowModDependency() { MainMod = mod, DepMod = LoadMod(allUnloaded[dependency.File.ModFolder], allUnloaded, memo, unloaded.Locales) }); } using IModuleDataExtractor extractor = this.moduleExtractorFactory.Create(unloaded.File); mod.Races = new List <DowRace>(); foreach (RaceFile race in extractor.GetRaces().Where(race => race.Playable)) { mod.Races.Add(new DowRace() { Name = newLocales.Replace(race.Name), Description = newLocales.Replace(race.Description) }); } mod.Maps = new List <DowMap>(); foreach (MapFile map in extractor.GetMaps()) { if (map.Players < 2 || map.Players > 8) { this.logger.Write($"({mod.Name}) Probably not a valid map {map.FileName} as it does not contain a valid player size: '{map.Players}'", LogLevel.Info); continue; } string?image = extractor.GetMapImage(map.FileName); if (image == null) { this.logger.Write($"({mod.Name}) Probably not valid map {map.FileName} as it does not have an image", LogLevel.Info); continue; } mod.Maps.Add(new DowMap() { Name = newLocales.Replace(map.Name), Details = newLocales.Replace(map.Description), Players = map.Players, Size = map.Size, Image = image }); } mod.Rules = new List <GameRule>(); foreach (GameRuleFile rule in extractor.GetGameRules()) { mod.Rules.Add(new GameRule() { Name = newLocales.Replace(rule.Title), Details = newLocales.Replace(rule.Description), IsWinCondition = rule.VictoryCondition }); } memo.Put(mod); return(mod); }