Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SkipIntroCinematic v1.0.2
SkipIntroCinematic.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("SkipIntroCinematic")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyInformationalVersion("1.0.2")] [assembly: AssemblyProduct("SkipIntroCinematic")] [assembly: AssemblyTitle("SkipIntroCinematic")] [assembly: AssemblyVersion("1.0.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Moopfam.SkipIntroCinematic { [BepInPlugin("Moopfam.SkipIntroCinematic", "SkipIntroCinematic", "1.0.2")] [BepInProcess("valheim.exe")] public sealed class SkipIntroCinematicPlugin : BaseUnityPlugin { public const string PluginGuid = "Moopfam.SkipIntroCinematic"; public const string PluginName = "SkipIntroCinematic"; public const string PluginVersion = "1.0.2"; internal const string AccessibilityToggleName = "Moopfam.SkipIntroCinematic.AccessibilityToggle"; internal const string ToggleLabel = "Skip intro cinematic"; internal const string ToggleTooltip = "Skip Valheim's startup cinematic and go directly to the main menu. Enabled by default."; private Harmony _harmony; private static bool _cinematicsReflectionResolved; private static Type _cinematicsManagerType; private static FieldInfo _cinematicsInstanceField; private static FieldInfo _introOnStartupField; private static bool _fejdReflectionResolved; private static Type _fejdStartupType; private static FieldInfo _fejdInstanceField; private static FieldInfo _fejdMainMenuField; private static bool _gameReflectionResolved; private static FieldInfo _gameHasStartedOnceField; internal static SkipIntroCinematicPlugin Instance { get; private set; } internal static ConfigEntry<bool> Enabled { get; private set; } internal static ManualLogSource Log { get; private set; } private static void ResolveCinematicsReflection() { if (!_cinematicsReflectionResolved) { _cinematicsReflectionResolved = true; _cinematicsManagerType = AccessTools.TypeByName("CinematicsManager"); if (!(_cinematicsManagerType == null)) { _cinematicsInstanceField = AccessTools.Field(_cinematicsManagerType, "s_instance"); _introOnStartupField = AccessTools.Field(_cinematicsManagerType, "m_introOnStartup"); } } } private static void ResolveFejdReflection() { if (!_fejdReflectionResolved) { _fejdReflectionResolved = true; _fejdStartupType = AccessTools.TypeByName("FejdStartup"); if (!(_fejdStartupType == null)) { _fejdInstanceField = AccessTools.Field(_fejdStartupType, "instance"); _fejdMainMenuField = AccessTools.Field(_fejdStartupType, "m_mainMenu"); } } } private static void ResolveGameReflection() { if (!_gameReflectionResolved) { _gameReflectionResolved = true; Type type = AccessTools.TypeByName("Game"); if (type != null) { _gameHasStartedOnceField = AccessTools.Field(type, "m_hasStartedOnce"); } } } private void Awake() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown if (!Application.isBatchMode) { Instance = this; Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Moopfam", "Enabled", true, "When true, skips Valheim's startup cinematic. The in-game Accessibility toggle controls this setting."); Enabled.SettingChanged += OnEnabledChanged; _harmony = new Harmony("Moopfam.SkipIntroCinematic"); _harmony.PatchAll(typeof(SkipIntroCinematicPlugin).Assembly); ApplyStartupCinematicSetting(); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Skip intro: {2}", "SkipIntroCinematic", "1.0.2", Enabled.Value)); } } private void OnDestroy() { if (Enabled != null) { Enabled.SettingChanged -= OnEnabledChanged; } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if (Instance == this) { Instance = null; } } private static void OnEnabledChanged(object sender, EventArgs e) { ApplyStartupCinematicSetting(); RefreshAccessibilityToggles(); } internal static bool ShouldSkipIntro() { return Enabled == null || Enabled.Value; } internal static void SetSkipIntro(bool value) { if (Enabled == null) { return; } if (Enabled.Value != value) { Enabled.Value = value; SkipIntroCinematicPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Config.Save(); } } ApplyStartupCinematicSetting(); } internal static void ApplyStartupCinematicSetting() { try { ResolveCinematicsReflection(); if (!(_cinematicsInstanceField == null) && !(_introOnStartupField == null)) { object value = _cinematicsInstanceField.GetValue(null); if (value != null) { _introOnStartupField.SetValue(value, !ShouldSkipIntro()); } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("Could not apply cinematic preference yet: " + ex.Message)); } } } internal static void DisableFirstStartupMenuAnimation(object startup) { if (!ShouldSkipIntro() || startup == null) { return; } try { object obj = AccessTools.Field(startup.GetType(), "m_menuAnimator")?.GetValue(startup); obj?.GetType().GetMethod("SetBool", BindingFlags.Instance | BindingFlags.Public, null, new Type[2] { typeof(string), typeof(bool) }, null)?.Invoke(obj, new object[2] { "FirstStartup", false }); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("Could not disable first-start menu animation: " + ex.Message)); } } } internal static bool TryShowMainMenuForSkippedVideo() { try { ResolveFejdReflection(); if (_fejdInstanceField == null || _fejdMainMenuField == null) { return false; } object value = _fejdInstanceField.GetValue(null); if (value == null) { return false; } object? value2 = _fejdMainMenuField.GetValue(value); GameObject val = (GameObject)((value2 is GameObject) ? value2 : null); if ((Object)(object)val == (Object)null) { return false; } val.SetActive(true); DisableFirstStartupMenuAnimation(value); return true; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("Could not show main menu while skipping video: " + ex.Message)); } return false; } } internal static bool HasGameStartedOnce() { try { ResolveGameReflection(); object obj = _gameHasStartedOnceField?.GetValue(null); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } internal static void AddAccessibilityToggle(Component settingsRoot) { if ((Object)(object)settingsRoot == (Object)null) { return; } Toggle val = ((IEnumerable<Toggle>)settingsRoot.GetComponentsInChildren<Toggle>(true)).FirstOrDefault((Func<Toggle, bool>)((Toggle t) => (Object)(object)t != (Object)null && ((Object)((Component)t).gameObject).name == "Moopfam.SkipIntroCinematic.AccessibilityToggle")); if ((Object)(object)val != (Object)null) { ConfigureToggle(val); return; } Toggle val2 = FindAccessibilityTemplate(settingsRoot); if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).transform.parent == (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"Could not find an Accessibility toggle to clone. Intro skipping still works from the BepInEx config file."); } return; } Transform parent = ((Component)val2).transform.parent; Toggle val3 = Object.Instantiate<Toggle>(val2, parent, false); ((Object)((Component)val3).gameObject).name = "Moopfam.SkipIntroCinematic.AccessibilityToggle"; ((Component)val3).transform.SetSiblingIndex(((Component)val2).transform.GetSiblingIndex() + 1); PositionAfterTemplateIfNeeded(val2, val3); ConfigureToggle(val3); RectTransform val4 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val4 != (Object)null) { LayoutRebuilder.ForceRebuildLayoutImmediate(val4); } ManualLogSource log2 = Log; if (log2 != null) { log2.LogDebug((object)"Added Skip intro cinematic toggle to Accessibility settings."); } } private static Toggle FindAccessibilityTemplate(Component settingsRoot) { Type type = ((object)settingsRoot).GetType(); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; List<FieldInfo> list = (from f in type.GetFields(bindingAttr) where typeof(Toggle).IsAssignableFrom(f.FieldType) select f).ToList(); string[] array = new string[5] { "block", "flashing", "immersive", "motion", "camera" }; string[] array2 = array; foreach (string value in array2) { foreach (FieldInfo item in list) { if (item.Name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { object? value2 = item.GetValue(settingsRoot); Toggle val = (Toggle)((value2 is Toggle) ? value2 : null); if ((Object)(object)val != (Object)null) { return val; } } } } Toggle[] componentsInChildren = settingsRoot.GetComponentsInChildren<Toggle>(true); if (componentsInChildren.Length == 0) { return null; } float maxX = componentsInChildren.Where((Toggle t) => (Object)(object)t != (Object)null).Max((Toggle t) => ((Component)t).transform.position.x); return (from t in componentsInChildren where (Object)(object)t != (Object)null && Math.Abs(((Component)t).transform.position.x - maxX) < 150f orderby ((Component)t).transform.position.y select t).FirstOrDefault() ?? ((IEnumerable<Toggle>)componentsInChildren).LastOrDefault((Func<Toggle, bool>)((Toggle t) => (Object)(object)t != (Object)null)); } private static void ConfigureToggle(Toggle toggle) { if ((Object)(object)toggle == (Object)null) { return; } ((UnityEventBase)toggle.onValueChanged).RemoveAllListeners(); toggle.SetIsOnWithoutNotify(ShouldSkipIntro()); ((UnityEvent<bool>)(object)toggle.onValueChanged).AddListener((UnityAction<bool>)SetSkipIntro); TMP_Text[] componentsInChildren = ((Component)toggle).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.text = "Skip intro cinematic"; } } ConfigureSettingsTooltipByReflection(toggle); } private static void ConfigureSettingsTooltipByReflection(Toggle toggle) { Component[] componentsInChildren = ((Component)toggle).GetComponentsInChildren<Component>(true); Component[] array = componentsInChildren; foreach (Component val in array) { if ((Object)(object)val == (Object)null || ((object)val).GetType().Name != "SettingsTooltip") { continue; } try { ((object)val).GetType().GetMethod("SetTexts", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(string) }, null)?.Invoke(val, new object[2] { "Skip intro cinematic", "Skip Valheim's startup cinematic and go directly to the main menu. Enabled by default." }); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogDebug((object)("Could not set Accessibility tooltip text: " + ex.Message)); } } } } private static void PositionAfterTemplateIfNeeded(Toggle template, Toggle clone) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)template == (Object)null || (Object)(object)clone == (Object)null || (Object)(object)((Component)template).transform.parent == (Object)null) { return; } Transform parent = ((Component)template).transform.parent; if (!((Object)(object)((Component)parent).GetComponent<LayoutGroup>() != (Object)null)) { Transform transform = ((Component)template).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Transform transform2 = ((Component)clone).transform; RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { float num = EstimateVerticalSpacing(parent, val); Vector2 anchoredPosition = val.anchoredPosition; val2.anchoredPosition = new Vector2(anchoredPosition.x, anchoredPosition.y - num); } } } private static float EstimateVerticalSpacing(Transform parent, RectTransform template) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) List<float> list = new List<float>(); Toggle[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Toggle>(true); foreach (Toggle val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform.parent != (Object)(object)parent)) { Transform transform = ((Component)val).transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (!((Object)(object)val2 == (Object)null) && !(Math.Abs(val2.anchoredPosition.x - template.anchoredPosition.x) > 40f)) { list.Add(val2.anchoredPosition.y); } } } float num = float.MaxValue; for (int j = 0; j < list.Count; j++) { for (int k = j + 1; k < list.Count; k++) { float num2 = Math.Abs(list[j] - list[k]); if (num2 > 8f && num2 < num) { num = num2; } } } return (num < float.MaxValue) ? num : 68f; } internal static void RefreshAccessibilityToggles() { Toggle[] array = Resources.FindObjectsOfTypeAll<Toggle>(); foreach (Toggle val in array) { if ((Object)(object)val != (Object)null && ((Object)((Component)val).gameObject).name == "Moopfam.SkipIntroCinematic.AccessibilityToggle") { val.SetIsOnWithoutNotify(ShouldSkipIntro()); } } } } [HarmonyPatch] internal static class CinematicsManagerAwakePatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("CinematicsManager"); return (type == null) ? null : AccessTools.Method(type, "Awake", (Type[])null, (Type[])null); } private static bool Prepare() { return TargetMethod() != null; } private static void Postfix() { SkipIntroCinematicPlugin.ApplyStartupCinematicSetting(); } } [HarmonyPatch] internal static class FejdStartupPlayIntroCinematicPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("FejdStartup"); return (type == null) ? null : AccessTools.Method(type, "PlayIntroCinematic", (Type[])null, (Type[])null); } private static bool Prepare() { return TargetMethod() != null; } private static void Prefix(object __instance) { SkipIntroCinematicPlugin.ApplyStartupCinematicSetting(); SkipIntroCinematicPlugin.DisableFirstStartupMenuAnimation(__instance); } } [HarmonyPatch] internal static class CinematicsManagerPlayPatch { private static MethodBase TargetMethod() { Type type = AccessTools.TypeByName("CinematicsManager"); if (type == null) { return null; } return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo method) { if (method.Name != "Play" || method.ReturnType != typeof(bool)) { return false; } ParameterInfo[] parameters = method.GetParameters(); return parameters.Length == 2 && parameters[0].ParameterType.IsEnum; }); } private static bool Prepare() { return TargetMethod() != null; } private static bool Prefix(object __0, ref bool __result) { if (!SkipIntroCinematicPlugin.ShouldSkipIntro() || __0 == null) { return true; } int num; try { num = Convert.ToInt32(__0); } catch { return true; } if (num != 2 || SkipIntroCinematicPlugin.HasGameStartedOnce()) { return true; } if (!SkipIntroCinematicPlugin.TryShowMainMenuForSkippedVideo()) { return true; } __result = true; return false; } } [HarmonyPatch] internal static class AccessibilitySettingsInitializePatch { private static Type AccessibilitySettingsType => AccessTools.TypeByName("Valheim.SettingsGui.AccessibilitySettings"); private static MethodBase TargetMethod() { Type accessibilitySettingsType = AccessibilitySettingsType; return (accessibilitySettingsType == null) ? null : AccessTools.Method(accessibilitySettingsType, "Initialize", (Type[])null, (Type[])null); } private static bool Prepare() { return TargetMethod() != null; } private static void Postfix(object __instance) { Component val = (Component)((__instance is Component) ? __instance : null); if ((Object)(object)val != (Object)null) { SkipIntroCinematicPlugin.AddAccessibilityToggle(val); } } } }