public static void Notify_DownloadCompleted(ModMetaData mod) { var downloading = AllButtons.OfType <ModButton_Downloading>() .FirstOrDefault(b => b.Identifier == mod.Identifier); var missing = AllButtons.OfType <ModButton_Missing>() .FirstOrDefault(b => b.Identifier == mod.Identifier); // add installed item to MBM var installed = ModButton_Installed.For(mod); if (missing != null && missing.Active) { Insert(installed, ActiveButtons.IndexOf(missing)); } else { TryAdd(installed); } Page_BetterModConfig.Instance.Selected = installed; TryRemove(downloading); TryRemove(missing); Page_BetterModConfig.Instance.Notify_ModsListChanged(); }
internal static void DeleteLocal(ModMetaData mod, bool force = false) { if (force) { LongEventHandler.QueueLongEvent(() => { LongEventHandler.SetCurrentEventText(I18n.RemovingLocal(mod.Name)); if (TryRemoveLocalCopy(mod)) { Messages.Message(I18n.RemoveLocalSucceeded(mod.Name), MessageTypeDefOf.NeutralEvent, false); } else { Messages.Message(I18n.RemoveLocalFailed(mod.Name), MessageTypeDefOf.RejectInput, false); } // remove this version either way, as it's likely to be borked. ModButton_Installed.For(mod).Notify_VersionRemoved(mod); }, null, true, null); return; } Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation( I18n.ConfirmRemoveLocal(mod.Name), () => DeleteLocal(mod, true), true)); }
internal static void CreateLocalCopy(ModMetaData mod, bool batch = false) { LongEventHandler.QueueLongEvent(() => { ModMetaData copy; LongEventHandler.SetCurrentEventText(I18n.CreatingLocal(mod.Name)); if (TryCreateLocalCopy(mod, out copy)) { var button = ModButton_Installed.For(copy); if (batch) { _batchCreatedCopies.Add(new Pair <ModButton_Installed, ModMetaData>(button, copy)); } else { Messages.Message(I18n.CreateLocalSucceeded(mod.Name), MessageTypeDefOf.NeutralEvent, false); LongEventHandler.QueueLongEvent(() => button.Notify_VersionAdded(copy, true), "", true, null); } } else { Messages.Message(I18n.CreateLocalFailed(mod.Name), MessageTypeDefOf.RejectInput, false); } }, null, true, null); }
public static bool TryUpdateLocalCopy(ModMetaData source, ModMetaData local) { // delete and re-copy mod. var removedResult = TryRemoveLocalCopy(local); if (!removedResult) { return(false); } var updateResult = TryCopyMod(source, out var updated, local.RootDir.FullName, false); if (!updateResult) { return(false); } // update version var button = ModButton_Installed.For(updated); button.Notify_VersionRemoved(local); button.Notify_VersionAdded(updated, true); return(true); }
public static void ResolveIncompatible(ModButton_Installed mod, ModButton_Installed incompatible) { var options = NewOptions; options.Add(DeactivateModOption(incompatible)); options.Add(DeactivateModOption(mod)); FloatMenu(options); }
public static void DoRemoveFromModListFloatMenu(ModButton_Installed mod) { var options = ListsFor(mod) .Select(l => new FloatMenuOption(I18n.RemoveFromModListX(l.Name), () => l.Remove(mod.Selected))) .ToList(); Utilities.FloatMenu(options); }
public static void ResolveShouldLoadAfter(ModButton_Installed mod, ModButton_Installed otherMod) { var options = NewOptions; options.Add(MoveAfterOption(mod, otherMod)); options.Add(MoveBeforeOption(otherMod, mod)); FloatMenu(options); }
public static void ResolveFindMod( string identifier, ModButton requester = null, Version desired = null, Dependency.EqualityOperator op = Dependency.EqualityOperator.GreaterEqual, Version current = null, bool replace = false) { // find identifier in available var mods = ModButtonManager.AvailableMods .Where(m => m.MatchesIdentifier(identifier)) .Where(m => m.VersionCompatible) .Where(m => desired == null || Dependency.MatchesVersion(m, op, desired, true)) .Where(m => current == null || Manifest.For(m)?.Version > current) .OrderByDescending(m => Manifest.For(m)?.Version); var options = NewOptions; if (mods.Any()) { var insertIndex = requester != null ? ModButtonManager.ActiveButtons.IndexOf(requester) : ModButtonManager.ActiveButtons.Count; foreach (var mod in mods) { options.Add(new FloatMenuOption(I18n.ActivateMod(mod), () => { var button = ModButton_Installed.For(mod); button.Selected = mod; ModButtonManager.Insert(button, insertIndex); if (replace && requester != null && requester != button) { requester.Active = false; } })); } } else { if (desired != null) { options.Add(new FloatMenuOption(I18n.NoMatchingModInstalled(identifier, desired, op), null)); } else { options.Add(new FloatMenuOption(I18n.NoMatchingModInstalled(identifier), null)); } } if (requester is ModButton_Missing missing && missing.Identifier.IsSteamWorkshopIdentifier()) { options.Add(SubscribeOption(missing.Name, missing.Identifier)); } options.Add(WorkshopSearchOption(requester?.TrimmedName ?? identifier)); options.Add(ForumSearchOption(requester?.TrimmedName ?? identifier)); FloatMenu(options); }
public static void DoAddToModListFloatMenu(ModButton_Installed mod) { var cur = ListsFor(mod); var options = ModLists .Where(l => !cur.Contains(l)) .Select(l => new FloatMenuOption(I18n.AddToModListX(l.Name), () => l.Add(mod.Selected))) .ToList(); Utilities.FloatMenu(options); }
public ButtonAttributes this[ModButton_Installed button] { get { if (ButtonAttributes.ContainsKey(button.Name)) { return(ButtonAttributes[button.Name]); } var attributes = new ButtonAttributes(button); ButtonAttributes.Add(button.Name, attributes); return(attributes); } }
public static bool TryUpdateLocalCopy(ModMetaData source, ModMetaData local) { // delete and re-copy mod. var updateResult = TryRemoveLocalCopy(local) && TryCopyMod(source, ref local, local.RootDir.FullName); if (!updateResult) { return(false); } // update version ModButton_Installed.For(source).Notify_VersionUpdated(local); return(true); }
public static void Reset(bool addDefaultMods = true) { foreach (var button in new List <ModButton>(ActiveButtons)) { button.Active = false; } if (addDefaultMods) { CoreMod.Active = true; if (ModManager.Settings.AddExpansionsToNewModLists) { foreach (var expansion in Expansions) { expansion.Active = true; } } if (ModManager.Settings.AddHugsLibToNewModLists) { var hugslib = ModLister.GetModWithIdentifier("unlimitedhugs.hugslib"); if (hugslib != null) { var hugslibButton = ModButton_Installed.For(hugslib); hugslibButton.Active = true; } } if (ModManager.Settings.AddModManagerToNewModLists && ModManagerMod != null) { ModManagerMod.Active = true; } if (ModManager.Settings.AddHugsLibToNewModLists || ModManager.Settings.AddModManagerToNewModLists) { // also try to activate harmony var harmony = ModLister.GetModWithIdentifier("brrainz.harmony"); if (harmony != null) { var harmonyButton = ModButton_Installed.For(harmony); harmonyButton.Active = true; Insert(harmonyButton, 0); } } } Notify_ModListChanged(); }
public static void Notify_ActiveStatusChanged(ModButton_Installed mod, bool active) { if (active) { _availableButtons.TryRemove(mod); _activeButtons.TryAdd(mod); Notify_ModListChanged(); } else { _activeButtons.TryRemove(mod); _availableButtons.TryAdd(mod); Notify_ModListChanged(); SortAvailable(); } }
internal static void DeleteLocal(ModMetaData mod) { Find.WindowStack.Add(Dialog_MessageBox.CreateConfirmation( I18n.ConfirmRemoveLocal(mod.Name), delegate { if (TryRemoveLocalCopy(mod)) { Messages.Message(I18n.RemoveLocalSucceeded(mod.Name), MessageTypeDefOf.NeutralEvent, false); } else { Messages.Message(I18n.RemoveLocalFailed(mod.Name), MessageTypeDefOf.RejectInput, false); } // remove this version either way, as it's likely to be borked. ModButton_Installed.For(mod).Notify_VersionRemoved(mod); }, true)); }
public static List <ModList> ListsFor(ModButton_Installed button) { return(ListsFor(button?.Selected)); }
private static FloatMenuOption MoveAfterOption(ModButton_Installed from, ModButton_Installed to) { return(new FloatMenuOption(I18n.MoveAfter(from, to), () => ModButtonManager.Insert(from, ModButtonManager.ActiveButtons.IndexOf(to) + 1))); }
public static string DeactivateMod(ModButton_Installed mod) { return(Key("DeactivateMod").Translate(mod.Name)); }
public static void ResolveWrongTargetVersion(ModButton_Installed mod) { ResolveFindMod(mod.Identifier); }
public static void ResolveWrongVersion(ModButton_Installed mod, Dependency desired) { ResolveFindMod(mod.Identifier, mod, desired.Version, desired.Operator, mod.Manifest?.Version); }
public static string MoveBefore(ModButton_Installed from, ModButton_Installed to) { return(Key("MoveBefore").Translate(TrimModName(from.Name), TrimModName(to.Name))); }
public static ModIssue UpdateAvailable(ModButton_Installed button) { return(new ModIssue(Severity.Update, Subject.Version, button, button.Identifier, I18n.UpdateAvailable(button.Manifest.Version, button.Manifest.Version))); }
public static string DependencyUnknownVersion(Dependency dep, ModButton_Installed tgt) { return(Key("DependencyUnknownVersion").Translate(dep, tgt.Name)); }
public static string DependencyWrongVersion(Dependency dep, ModButton_Installed tgt) { return(Key("DependencyWrongVersion").Translate(dep, tgt.Manifest.Version)); }
public static void Sort() { // ReSharper disable once InvalidXmlDocComment /** * Topological sort. * Depth first, because it's the easiest to understand. * https://en.wikipedia.org/wiki/Topological_sorting * * L ← Empty list that will contain the sorted nodes // we'll use done. * while exists nodes without a permanent mark do * select an unmarked node n * visit(n) * * function visit(node n) * if n has a permanent mark then // is in done list * return * if n has a temporary mark then // is in progress list * stop (not a DAG) * * mark n with a temporary mark // add to progress list * * for each node m with an edge from n to m do // visit each dependency * visit(m) * * remove temporary mark from n // remove from progress list * mark n with a permanent mark // add to done list * add n to head of L */ var graph = new Dictionary <ModButton, HashSet <ModButton> >(); var done = new HashSet <ModButton>(); var progress = new HashSet <ModButton>(); // create a directed acyclic graph. foreach (var activeButton in ActiveButtons) { if (!graph.ContainsKey(activeButton)) { graph[activeButton] = new HashSet <ModButton>(); } if (!(activeButton is ModButton_Installed installedActiveButton)) { continue; } foreach (var target in installedActiveButton.Manifest.LoadBefore .Select(d => d.Target) .Where(t => t != null)) { var targetButton = ModButton_Installed.For(target); if (!graph.ContainsKey(targetButton)) { graph[targetButton] = new HashSet <ModButton>(); } graph[targetButton].Add(activeButton); } foreach (var target in installedActiveButton.Manifest.LoadAfter .Concat(installedActiveButton.Manifest.Dependencies) .Select(d => d.Target) .Where(t => t != null)) { var targetButton = ModButton_Installed.For(target); graph[activeButton].Add(targetButton); if (!graph.ContainsKey(targetButton)) { graph[targetButton] = new HashSet <ModButton>(); } } } // do that sort foreach (var activeButton in ActiveButtons) { var success = Sort_Visit(activeButton, graph, ref done, ref progress); if (!success) { // we have a cyclic dependency. Messages.Message(I18n.SortFailed_Cyclic(activeButton.Name, success.Reason), MessageTypeDefOf.CautionInput, false); return; } } // reset mod list, then add mods back in order. SoundDefOf.Tick_High.PlayOneShotOnCamera(); Reset(false); foreach (var mod in done) { // try to avoid re-caching too many times. if (mod is ModButton_Installed installed) { installed.Selected.Active = true; } else { mod.Active = true; } TryAdd(mod, false); } Notify_ModListChanged(); }
private static FloatMenuOption DeactivateModOption(ModButton_Installed mod) { return(new FloatMenuOption(I18n.DeactivateMod(mod), () => mod.Active = false)); }
public static ModIssue DifferentVersion(ModButton_Installed button) { return(new ModIssue(Severity.Critical, Subject.Version, button, button.Identifier, I18n.DifferentVersion(button.Selected))); }
public static void ResolveFindMod(Dependency dependency, ModButton_Installed requester) { ResolveFindMod(dependency.Identifier, requester, dependency.Version, dependency.Operator); }
public static string MoveAfter(ModButton_Installed from, ModButton_Installed to) { return(Key("MoveAfter").Translate(from.Name, to.Name)); }
public static ModIssue InvalidVersion(ModButton_Installed button) { return(new ModIssue(Severity.Minor, Subject.Version, button, button.Identifier, I18n.InvalidVersion(button.Selected.TargetVersion))); }
public static string DependencyMet(ModButton_Installed tgt) { return(Key("DependencyMet").Translate(tgt.Name, tgt.Manifest.Version)); }