/* Signal the other instances which have lost mainMod status */ internal void NotifyStandbys(bool mainEnabled) { var selfAware = m_self.userModInstance as IAmAware; Assert.IsTrue(m_self == m_mainMod, "Only the main mod should notify others"); Assert.IsNotNull(helperMod, "Others should only be notified if a helper exists"); Assert.IsNotNull(selfAware, $"Self should be an {typeof(IAmAware).Name} instance"); foreach (var mod in Singleton <PluginManager> .instance.GetPluginsInfo()) { if (mod != m_mainMod && mod != m_self && mod.isEnabledNoOverride) { try { IAmAware awareInst = mod.userModInstance as IAmAware; if (awareInst != null) { awareInst.OnMainModChanged(selfAware, mainEnabled); } } catch (ReflectionTypeLoadException ex) { ex.LoaderExceptions.Do((e) => (m_self.userModInstance as Mod).report.ReportPlugin(mod, ModReport.ProblemType.ExceptionThrown, $"LoaderException: {e}")); } catch (Exception ex) { (m_self.userModInstance as Mod).report.ReportPlugin(mod, ModReport.ProblemType.ExceptionThrown, ex.Message); UnityEngine.Debug.LogWarning($"[{Versioning.FULL_PACKAGE_NAME}] While notifying standys, {mod.name} caused exception {ex.GetType().Name}: {ex.Message}"); } } } }
internal Patcher(IAmAware selfMod, string name, bool onAwarenessCallback = false) { id = HARMONY_ID + (name != null ? "+" + name : string.Empty); compat_id = id + "+Compat"; #if DEBUG Harmony.DEBUG = true; #endif self = selfMod; harmony1SelfPatcher = new Harmony1SelfPatcher(); EnableHarmony(); harmony = new Harmony(id); compatHarmony = new Harmony(compat_id); if (!Harmony.Harmony1Patched) { Harmony.Harmony1Patched = true; try { ImplementAdditionalVersionSupport(true); } catch (HarmonyModSupportException ex) { foundUnsupportedHarmonyLib = true; DisableHarmony(); (self as Mod).report.ReportUnsupportedHarmony(ex); } } }
internal Handover(IAmAware selfMod) { m_self = Singleton <PluginManager> .instance.GetPluginsInfo().First((x) => { try { return(x.isEnabledNoOverride && x.userModInstance == selfMod); } catch (ReflectionTypeLoadException ex) { ex.LoaderExceptions.Do((e) => (selfMod as Mod).report.ReportPlugin(x, ModReport.ProblemType.ExceptionThrown, $"LoaderException: {e}")); } catch (Exception ex) { (selfMod as Mod).report.ReportPlugin(x, ModReport.ProblemType.ExceptionThrown, ex.Message); UnityEngine.Debug.LogWarning($"[{Versioning.FULL_PACKAGE_NAME}] While Scanning plugins, {x.name} caused exception {ex.GetType().Name}: {ex.Message}"); } return(false); }); DisableHarmonyFromBoformer(); }
/* FIXME: If the app is shutting down, I have to be last to disable, * to catch exceptions from other mods disabling, and to turn off HarmonyLib(s) last. */ // void IAwareness.IAmAware.OnMainModChanged(IAwareness0::IAwareness.IAmAware main, bool enabled) void IAmAware.OnMainModChanged(IAmAware main, bool enabled) { try { if (handover != null) { #if TRACE UnityEngine.Debug.LogError($"[{Versioning.FULL_PACKAGE_NAME}] In Mod.OnMainModChanged() enabled={enabled} I am={handover.self.name}"); #endif /* TODO: Implement */ if (handover.BootStrapMainMod(enabled)) { var mainModName = $"{(handover.mainMod().userModInstance as IUserMod).Name} {handover.mainModVersion}"; if (handover.isHelper) { helperMod = handover.helperMod; mainMod = handover.mainMod(); mainModInstance = mainMod.userModInstance as Mod; UnityEngine.Debug.Log($"[{Versioning.FULL_PACKAGE_NAME}] INFO: I switched to Helper role to Mod '{mainModName}'"); } else { UnityEngine.Debug.Log($"[{Versioning.FULL_PACKAGE_NAME}] INFO: I switched to Standby role to Mod '{mainModName}'"); } if (enabled) { #if HEAVY_TRACE resolver.Uninstall(); #endif patcher.Uninstall(); main.PutModReports(report.modReports); report.OnDisabled(handover.self, true); report = null; } } else { #if DEBUG var oldMain = Singleton <PluginManager> .instance.GetPluginsInfo().First((x) => x.isEnabledNoOverride && x.userModInstance == main); UnityEngine.Debug.Log($"[{Versioning.FULL_PACKAGE_NAME}] INFO: I switched to Main role from {oldMain.name}"); #endif OnActive(); } Assert.IsTrue(mainMod.userModInstance is IAmAware, "Only IAmAware instances can be main mods"); Assert.IsFalse(enabled && handover.isMainMod, "Notified instance should concur that it is no longer the main Mod"); Assert.IsTrue(main == handover.mainMod(), "Notification of another Harmony mod being main should be accurate"); } #if HEAVY_TRACE else { UnityEngine.Debug.LogError($"[{Versioning.FULL_PACKAGE_NAME}] In Mod.OnMainModChanged() enabled={enabled}"); } #endif } catch (Exception ex) { SelfReport(SelfProblemType.FailedToYieldToMain, ex); } }