示例#1
0
        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();
        }
示例#2
0
文件: IO.cs 项目: theDeus/ModManager
        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));
        }
示例#3
0
文件: IO.cs 项目: theDeus/ModManager
 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);
 }
示例#4
0
        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);
        }
示例#5
0
        public static void ResolveIncompatible(ModButton_Installed mod, ModButton_Installed incompatible)
        {
            var options = NewOptions;

            options.Add(DeactivateModOption(incompatible));
            options.Add(DeactivateModOption(mod));
            FloatMenu(options);
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
 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);
     }
 }
示例#11
0
        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);
        }
示例#12
0
        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();
        }
示例#13
0
        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();
            }
        }
示例#14
0
文件: IO.cs 项目: pardeike/ModManager
        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));
        }
示例#15
0
 public static List <ModList> ListsFor(ModButton_Installed button)
 {
     return(ListsFor(button?.Selected));
 }
示例#16
0
 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)));
 }
示例#17
0
 public static string DeactivateMod(ModButton_Installed mod)
 {
     return(Key("DeactivateMod").Translate(mod.Name));
 }
示例#18
0
 public static void ResolveWrongTargetVersion(ModButton_Installed mod)
 {
     ResolveFindMod(mod.Identifier);
 }
示例#19
0
 public static void ResolveWrongVersion(ModButton_Installed mod, Dependency desired)
 {
     ResolveFindMod(mod.Identifier, mod, desired.Version, desired.Operator, mod.Manifest?.Version);
 }
示例#20
0
文件: I18n.cs 项目: emahn/ModManager
 public static string MoveBefore(ModButton_Installed from, ModButton_Installed to)
 {
     return(Key("MoveBefore").Translate(TrimModName(from.Name), TrimModName(to.Name)));
 }
示例#21
0
 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)));
 }
示例#22
0
 public static string DependencyUnknownVersion(Dependency dep, ModButton_Installed tgt)
 {
     return(Key("DependencyUnknownVersion").Translate(dep, tgt.Name));
 }
示例#23
0
 public static string DependencyWrongVersion(Dependency dep, ModButton_Installed tgt)
 {
     return(Key("DependencyWrongVersion").Translate(dep, tgt.Manifest.Version));
 }
示例#24
0
        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();
        }
示例#25
0
 private static FloatMenuOption DeactivateModOption(ModButton_Installed mod)
 {
     return(new FloatMenuOption(I18n.DeactivateMod(mod), () => mod.Active = false));
 }
示例#26
0
 public static ModIssue DifferentVersion(ModButton_Installed button)
 {
     return(new ModIssue(Severity.Critical, Subject.Version, button, button.Identifier,
                         I18n.DifferentVersion(button.Selected)));
 }
示例#27
0
 public static void ResolveFindMod(Dependency dependency, ModButton_Installed requester)
 {
     ResolveFindMod(dependency.Identifier, requester, dependency.Version, dependency.Operator);
 }
示例#28
0
 public static string MoveAfter(ModButton_Installed from, ModButton_Installed to)
 {
     return(Key("MoveAfter").Translate(from.Name, to.Name));
 }
示例#29
0
 public static ModIssue InvalidVersion(ModButton_Installed button)
 {
     return(new ModIssue(Severity.Minor, Subject.Version, button, button.Identifier,
                         I18n.InvalidVersion(button.Selected.TargetVersion)));
 }
示例#30
0
 public static string DependencyMet(ModButton_Installed tgt)
 {
     return(Key("DependencyMet").Translate(tgt.Name, tgt.Manifest.Version));
 }