Example #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();
        }
Example #2
0
 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);
 }
Example #3
0
        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));
        }
Example #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);
        }
Example #5
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);
        }
Example #6
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);
        }
Example #7
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();
        }
Example #8
0
        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));
        }
Example #9
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();
        }