|
|
- using IPA.Loader;
- using IPA.Utilities;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using UnityEngine;
- using UnityEngine.SceneManagement;
-
- namespace BSIPA_ModList.UI
- {
- internal struct WarningEntry
- {
- public string ModName;
- public string[] MissingDependencies;
- public string[] IgnoredDependencies;
- public string[] DisabledDependencies;
-
- public WarningEntry(string modName, string[] missingDependencies, string[] ignoredDependencies, string[] disabledDependencies)
- {
- ModName = modName;
- MissingDependencies = missingDependencies;
- IgnoredDependencies = ignoredDependencies;
- DisabledDependencies = disabledDependencies;
- }
- }
-
- internal class WarningUI : MonoBehaviour
- { // TODO: rework this to just use disable/ignore reason
- internal static WarningUI Instance;
- internal static bool firstShow = true;
-
- public void Awake()
- {
- DontDestroyOnLoad(gameObject);
- SceneManager.activeSceneChanged += this.SceneManager_activeSceneChanged;
- }
-
- private void SceneManager_activeSceneChanged(Scene from, Scene to)
- {
- if (to.name == "EmptyTransition")
- {
- if (Instance != null)
- {
- Instance.StopAllCoroutines();
- Destroy(Instance.gameObject);
- _mainFlow = null;
- }
- Instance = null;
- }
- }
-
- public void Init()
- {
- Instance = this;
-
- Logger.log.Debug("Warning UI Awake");
- if (firstShow)
- {
- firstShow = false;
- StartCoroutine(LookForUnmetDependencies());
- }
- }
-
- private static MainFlowCoordinator _mainFlow;
- private static SimpleDialogPromptViewController _warningDialog;
- private static Queue<WarningEntry> _warningsQueue = new Queue<WarningEntry>();
-
- private static IEnumerator LookForUnmetDependencies()
- {
- Logger.log.Debug("Waiting for MainFlowCoordinator to appear...");
-
- yield return new WaitWhile(() => FindObjectOfType<MainFlowCoordinator>() == null);
-
- Logger.log.Debug("Looking for unmet dependencies...");
-
- lock (Instance)
- {
- if (_mainFlow == null)
- {
- _mainFlow = FindObjectOfType<MainFlowCoordinator>();
- _warningDialog = _mainFlow.GetPrivateField<SimpleDialogPromptViewController>("_simpleDialogPromptViewController");
- }
-
- _warningsQueue.Clear();
-
- var enabledPlugins = PluginManager.AllPlugins.Select(p => p.Metadata).Where(x => x.Id != null).ToDictionary(x => x.Id, y => y.Version);
- var ignoredPlugins = PluginLoader.ignoredPlugins.Where(x => x.Id != null).ToDictionary(x => x.Id, y => y.Version);
- var disabledPlugins = PluginManager.DisabledPlugins.Where(x => x.Id != null).ToDictionary(x => x.Id, y => y.Version);
-
- // iterate only disabled and ignored, as thats where missing deps can end up
- foreach (var meta in PluginManager.DisabledPlugins.Concat(PluginLoader.ignoredPlugins))
- {
- List<string> disabledDependencies = new List<string>();
- List<string> ignoredDependencies = new List<string>();
- List<string> missingDependencies = new List<string>();
- foreach (var dep in meta.Manifest.Dependencies)
- {
- #if DEBUG
- Logger.log.Debug($"Looking for dependency {dep.Key} with version range {dep.Value.Intersect(new SemVer.Range("*.*.*"))}");
- #endif
-
- if (disabledPlugins.TryGetValue(dep.Key, out var version) && dep.Value.IsSatisfied(version))
- {
- Logger.log.Debug($"Dependency {dep.Key} was found, but disabled.");
- disabledDependencies.Add($"{dep.Key} {dep.Value.ToString()}");
- }
- else if (ignoredPlugins.TryGetValue(dep.Key, out version) && dep.Value.IsSatisfied(version))
- {
- Logger.log.Debug($"Dependency {dep.Key} was found, but was ignored, likely due to a missing dependency.");
- ignoredDependencies.Add($"{dep.Key} {dep.Value.ToString()}");
- }
- else if (enabledPlugins.TryGetValue(dep.Key, out version) && dep.Value.IsSatisfied(version))
- {
- // do nothing, this was probably user disabled
- }
- else
- {
- Logger.log.Debug($"{meta.Name} is missing dependency {dep.Key} {dep.Value}");
- missingDependencies.Add($"{dep.Key} {dep.Value.ToString()}");
- }
-
- }
-
- if(disabledDependencies.Count > 0 || ignoredDependencies.Count > 0 || missingDependencies.Count > 0)
- _warningsQueue.Enqueue(new WarningEntry(meta.Name, missingDependencies.ToArray(), ignoredDependencies.ToArray(), disabledDependencies.ToArray()));
- }
-
- if (_warningsQueue.Count > 0)
- {
- yield return new WaitWhile(() => !_mainFlow.isActivated);
-
- ShowWarningDialog();
- }
-
- yield break;
- }
- }
-
- private static void ShowWarningDialog()
- {
- WarningEntry warning = _warningsQueue.Dequeue();
- _warningDialog.Init("Unmet Dependencies", $"Mod <b>{warning.ModName}</b> has unmet dependencies!" +
- (warning.MissingDependencies.Length > 0 ? $"\nMissing:\n<color=red>{string.Join("\n", warning.MissingDependencies)}</color>" : "") +
- (warning.IgnoredDependencies.Length > 0 ? $"\nIgnored:\n<color=#C2B2B2>{string.Join("\n", warning.IgnoredDependencies)}</color>" : "") +
- (warning.DisabledDependencies.Length > 0 ? $"\nDisabled:\n<color=#C2C2C2>{string.Join("\n", warning.DisabledDependencies)}</color>" : "")
- , "Okay", WarningDialogDidFinish);
- _mainFlow.InvokePrivateMethod("PresentViewController", _warningDialog, null, true);
- }
-
- private static void WarningDialogDidFinish(int button)
- {
- _mainFlow.InvokePrivateMethod("DismissViewController", _warningDialog, null, (_warningsQueue.Count > 0));
-
- if (_warningsQueue.Count > 0)
- {
- ShowWarningDialog();
- }
- }
- }
- }
|