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 AutoWorldStart v1.1.8
AutoWorldStart/AutoWorldStart.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.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 Hunter9732ru.AutoWorldStart { [BepInPlugin("hunter9732ru.autoworldstart", "AutoWorldStart-1.1.8", "1.1.8")] [BepInIncompatibility("com.github.abearcodes.valheim.simpleautogamestart")] public sealed class Plugin : BaseUnityPlugin { private static Plugin instance; private Harmony harmony; private ConfigEntry<bool> skipIntroVideo; private ConfigEntry<bool> pauseAfterLoad; private ConfigEntry<float> pauseInputWindow; private static readonly MethodInfo CanPauseMethod = typeof(Game).GetMethod("CanPause", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); private bool pausePending; private bool autoPauseOwned; private DateTime resumeInputBaseline; private DateTime pendingInputBaseline; private GameObject hiddenWorldPanel; private Camera hiddenMenuCamera; private int originalCullingMask; private CameraClearFlags originalClearFlags; private Color originalBackground; private FejdStartup hiddenStartup; private float restoreMenuAt; private static readonly FieldInfo StartingWorld = typeof(FejdStartup).GetField("m_startingWorld", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private float pauseDeadline; private float nextPauseCheck; private float pauseReadyAt = -1f; private ConfigEntry<bool> autoEnabled; private ConfigEntry<string> worldName; private ConfigEntry<string> playerName; private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly FieldInfo Profiles = typeof(FejdStartup).GetField("m_profiles", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo ProfileIndex = typeof(FejdStartup).GetField("m_profileIndex", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo SelectedWorld = typeof(FejdStartup).GetField("m_world", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo QueuedJoin = typeof(FejdStartup).GetField("m_queuedJoinServer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private bool finished; private bool worldAttempted; private ConfigEntry<KeyboardShortcut> togglePauseKey; private ConfigEntry<KeyboardShortcut> toggleAutoLoadKey; private float deadline; private void Awake() { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) instance = this; skipIntroVideo = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoWorldStart", "SkipIntroVideo", true, "Skip the startup video before the main menu. Does not skip loading or in-world cinematics. / Пропускать видео перед главным меню."); try { MethodInfo methodInfo = AccessTools.Method(typeof(PlatformPrefs), "GetBool", new Type[2] { typeof(string), typeof(bool) }, (Type[])null); if (methodInfo == null) { throw new MissingMethodException("PlatformPrefs.GetBool(string, bool)"); } harmony = new Harmony("hunter9732ru.autoworldstart.intro"); harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "IntroPreferencePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Intro skip unavailable; automatic world loading remains enabled: " + ex.Message)); } pauseAfterLoad = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoWorldStart", "PauseAfterLoad", true, "After entry, silently pause only if no input occurs during PauseInputWindowSeconds. / После входа пауза без Esc, если за время PauseInputWindowSeconds не было ввода."); pauseInputWindow = ((BaseUnityPlugin)this).Config.Bind<float>("AutoWorldStart", "PauseInputWindowSeconds", 1f, new ConfigDescription("Seconds after player/HUD readiness during which input cancels the pending pause. Applied on the next entry. / Сколько секунд после готовности персонажа ввод отменяет будущую паузу. По умолчанию 1; изменение действует при следующем входе.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), Array.Empty<object>())); string text = Path.Combine(Paths.ConfigPath, "com.github.abearcodes.valheim.simpleautogamestart.cfg"); bool flag = true; string text2 = ""; string text3 = ""; if (File.Exists(text)) { try { ConfigFile val = new ConfigFile(text, false) { SaveOnConfigSet = false }; flag = val.Bind<bool>("SimpleAutoGameStart", "Enabled", true, (ConfigDescription)null).Value; text2 = val.Bind<string>("SimpleAutoGameStart", "WorldName", "", (ConfigDescription)null).Value; text3 = val.Bind<string>("SimpleAutoGameStart", "PlayerName", "", (ConfigDescription)null).Value; } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Cannot read old settings: " + ex2.Message)); } } autoEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoWorldStart", "Enabled", flag, "Automatically load the named local world once when Valheim starts."); worldName = ((BaseUnityPlugin)this).Config.Bind<string>("AutoWorldStart", "WorldName", text2, "Existing world display name, exactly as shown in the game. Never creates a world."); playerName = ((BaseUnityPlugin)this).Config.Bind<string>("AutoWorldStart", "PlayerName", text3, "Existing character name, exactly as shown in the game."); togglePauseKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "TogglePauseAfterLoad", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Toggle automatic pause AFTER loading; does not open or close Esc. / Переключатель паузы после загрузки."); toggleAutoLoadKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "ToggleAutoLoad", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Toggle automatic world loading. Saved for next launch; in the initial menu can resume a cancelled attempt. / Переключатель автозагрузки мира."); ScheduleAutoLoad(); } private void ScheduleAutoLoad() { ((MonoBehaviour)this).CancelInvoke("TryStart"); if (!autoEnabled.Value || worldAttempted || (Object)(object)Player.m_localPlayer != (Object)null) { finished = true; return; } finished = false; if (string.IsNullOrWhiteSpace(worldName.Value) || string.IsNullOrWhiteSpace(playerName.Value)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Set WorldName and PlayerName in the config. Automatic start skipped."); finished = true; } else { deadline = Time.realtimeSinceStartup + 180f; ((MonoBehaviour)this).InvokeRepeating("TryStart", 0.1f, 0.5f); } } private void Finish() { finished = true; ((MonoBehaviour)this).CancelInvoke("TryStart"); if (!worldAttempted) { RestoreWorldPanel(); } } private static bool Same(string a, string b) { return string.Equals((a ?? "").Trim(), (b ?? "").Trim(), StringComparison.OrdinalIgnoreCase); } private void TryStart() { if (finished) { return; } if (!autoEnabled.Value) { Finish(); return; } try { StartFromMenu(); } catch (Exception ex) { Finish(); pausePending = false; RestoreWorldPanel(); ((BaseUnityPlugin)this).Logger.LogError((object)("Automatic start stopped; use the normal menu. " + ex)); } } private void StartFromMenu() { if (Time.realtimeSinceStartup > deadline) { Finish(); ((BaseUnityPlugin)this).Logger.LogWarning((object)"Main menu was not ready within 180 seconds. Automatic start skipped."); return; } FejdStartup val = FejdStartup.instance; if ((Object)(object)val == (Object)null || ((Object)(object)val.m_loading != (Object)null && val.m_loading.activeInHierarchy) || (Object)(object)val.m_menuList == (Object)null || !val.m_menuList.activeInHierarchy) { return; } if (Profiles == null || ProfileIndex == null || SelectedWorld == null) { throw new MissingFieldException("FejdStartup selection fields changed."); } if (!(Profiles.GetValue(val) is List<PlayerProfile> list)) { return; } if (QueuedJoin != null) { object value = QueuedJoin.GetValue(val); PropertyInfo propertyInfo = value?.GetType().GetProperty("IsValid"); if (propertyInfo != null && (bool)propertyInfo.GetValue(value, null)) { Finish(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"A server connection is queued; local automatic start skipped."); return; } } List<World> worldList = SaveSystem.GetWorldList(); if (worldList == null) { return; } int num = 0; int num2 = 0; int num3 = -1; World val2 = null; string b = worldName.Value.Trim(); string b2 = playerName.Value.Trim(); for (int i = 0; i < worldList.Count; i++) { World val3 = worldList[i]; if (Same(val3.m_worldName, b) || Same(val3.m_name, b)) { num++; val2 = val3; } } for (int j = 0; j < list.Count; j++) { if (Same(list[j].GetName(), b2)) { num2++; num3 = j; } } if (num != 1 || num2 != 1) { Finish(); ((BaseUnityPlugin)this).Logger.LogError((object)("Automatic start needs one matching world and character. World matches: " + num + "; character matches: " + num2 + ".")); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Available worlds: " + string.Join(" | ", worldList.Select((World w) => w.m_worldName).ToArray()))); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Available characters: " + string.Join(" | ", list.Select((PlayerProfile p) => p.GetName()).ToArray()))); return; } worldAttempted = true; Finish(); ProfileIndex.SetValue(val, num3); HideMenuBackground(val); val.OnCharacterStart(); SelectedWorld.SetValue(val, val2); if ((Object)(object)val.m_openServerToggle != (Object)null) { val.m_openServerToggle.isOn = false; } if ((Object)(object)val.m_publicServerToggle != (Object)null) { val.m_publicServerToggle.isOn = false; } ((BaseUnityPlugin)this).Logger.LogInfo((object)("Starting world '" + val2.m_worldName + "' with character '" + list[num3].GetName() + "'.")); val.OnWorldStart(); if (StartingWorld != null && (bool)StartingWorld.GetValue(val) && (Object)(object)val.m_startGamePanel != (Object)null) { hiddenWorldPanel = val.m_startGamePanel; hiddenStartup = val; restoreMenuAt = Time.realtimeSinceStartup + 20f; hiddenWorldPanel.SetActive(false); nextPauseCheck = 0f; pausePending = pauseAfterLoad.Value; pauseDeadline = Time.realtimeSinceStartup + 600f; pauseReadyAt = -1f; } else { RestoreWorldPanel(); pausePending = false; } } private void Update() { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if (((Object)(object)hiddenWorldPanel != (Object)null || (Object)(object)hiddenMenuCamera != (Object)null) && ((Object)(object)hiddenStartup == (Object)null || Time.realtimeSinceStartup >= restoreMenuAt)) { RestoreWorldPanel(); } if (!finished && !worldAttempted && autoEnabled.Value && (Object)(object)hiddenMenuCamera == (Object)null && (Object)(object)Player.m_localPlayer == (Object)null && (Object)(object)FejdStartup.instance != (Object)null) { HideMenuBackground(FejdStartup.instance); } if (autoPauseOwned) { UpdateAutoPause(); } KeyboardShortcut value = togglePauseKey.Value; bool flag = ((KeyboardShortcut)(ref value)).IsDown(); value = toggleAutoLoadKey.Value; bool flag2 = ((KeyboardShortcut)(ref value)).IsDown(); if ((flag || flag2) && !TypingInField()) { if (flag) { pauseAfterLoad.Value = !pauseAfterLoad.Value; SaveSettings(); Notify("Pause after load / Пауза после загрузки: " + (pauseAfterLoad.Value ? "ON / ВКЛ" : "OFF / ВЫКЛ")); } if (flag2) { autoEnabled.Value = !autoEnabled.Value; SaveSettings(); if (!autoEnabled.Value) { Finish(); } else if (!worldAttempted && (Object)(object)FejdStartup.instance != (Object)null && (Object)(object)Player.m_localPlayer == (Object)null) { ScheduleAutoLoad(); } Notify("Automatic world load / Автозагрузка: " + (autoEnabled.Value ? "ON / ВКЛ" : "OFF / ВЫКЛ")); } } if (!pausePending) { return; } if (!pauseAfterLoad.Value || Time.realtimeSinceStartup > pauseDeadline) { pausePending = false; return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (pauseReadyAt >= 0f) { if (HasInputSince(pendingInputBaseline)) { pausePending = false; return; } if (realtimeSinceStartup < pauseReadyAt) { return; } } if (realtimeSinceStartup < nextPauseCheck) { return; } nextPauseCheck = realtimeSinceStartup + 0.1f; try { Player localPlayer = Player.m_localPlayer; Menu val = Menu.instance; if ((Object)(object)localPlayer == (Object)null || (Object)(object)val == (Object)null || (Object)(object)Hud.instance == (Object)null || !Hud.instance.IsVisible() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsDead()) { pauseReadyAt = -1f; } else if (pauseReadyAt < 0f) { float num = pauseInputWindow.Value; if (float.IsNaN(num) || float.IsInfinity(num)) { num = 1f; } num = Math.Max(0.1f, Math.Min(30f, num)); pauseReadyAt = realtimeSinceStartup + num; pendingInputBaseline = ((ZInput.instance == null) ? DateTime.MinValue : ZInput.instance.GetLastInputTimer()); if (HasInputSince(pendingInputBaseline)) { pausePending = false; } } else if (!(Time.realtimeSinceStartup < pauseReadyAt)) { pausePending = false; if (!Menu.IsVisible() && CanPauseMethod != null && (bool)CanPauseMethod.Invoke(null, null) && !Game.IsPaused()) { Game.Pause(); autoPauseOwned = true; resumeInputBaseline = ((ZInput.instance == null) ? DateTime.MinValue : ZInput.instance.GetLastInputTimer()); } } } catch (Exception ex) { pausePending = false; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Cannot pause after loading: " + ex.Message)); } } private void HideMenuBackground(FejdStartup startup) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hiddenMenuCamera != (Object)null)) { Camera val = (((Object)(object)startup.m_mainCamera == (Object)null) ? null : startup.m_mainCamera.GetComponent<Camera>()); if (!((Object)(object)val == (Object)null)) { hiddenMenuCamera = val; hiddenStartup = startup; restoreMenuAt = deadline; originalCullingMask = val.cullingMask; originalClearFlags = val.clearFlags; originalBackground = val.backgroundColor; val.backgroundColor = Color.black; val.clearFlags = (CameraClearFlags)2; int num = LayerMask.NameToLayer("UI"); val.cullingMask = ((num < 0) ? originalCullingMask : (originalCullingMask & (1 << num))); } } } private void RestoreWorldPanel() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hiddenMenuCamera != (Object)null) { hiddenMenuCamera.cullingMask = originalCullingMask; hiddenMenuCamera.clearFlags = originalClearFlags; hiddenMenuCamera.backgroundColor = originalBackground; } hiddenMenuCamera = null; if ((Object)(object)hiddenWorldPanel != (Object)null) { hiddenWorldPanel.SetActive(true); } hiddenWorldPanel = null; hiddenStartup = null; } private void UpdateAutoPause() { if (Menu.IsVisible()) { autoPauseOwned = false; } else if ((Object)(object)Player.m_localPlayer == (Object)null || !pauseAfterLoad.Value || !Game.IsPaused()) { ReleaseAutoPause(); } else if (HasInputSince(resumeInputBaseline)) { ReleaseAutoPause(); } } private static bool HasInputSince(DateTime baseline) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) ZInput val = ZInput.instance; if (!Input.anyKeyDown && (val == null || !(val.GetLastInputTimer() > baseline))) { Vector2 mouseDelta = ZInput.GetMouseDelta(); if (!(((Vector2)(ref mouseDelta)).sqrMagnitude > 0f)) { return ZInput.GetMouseScrollWheel() != 0f; } } return true; } private void ReleaseAutoPause() { if (autoPauseOwned) { autoPauseOwned = false; if (!Menu.IsVisible()) { Game.Unpause(); } } } private static bool TypingInField() { EventSystem current = EventSystem.current; GameObject val = (((Object)(object)current == (Object)null) ? null : current.currentSelectedGameObject); if ((Object)(object)val != (Object)null) { if (!((Object)(object)val.GetComponent<InputField>() != (Object)null)) { return (Object)(object)val.GetComponent<TMP_InputField>() != (Object)null; } return true; } return false; } private void SaveSettings() { if (!((BaseUnityPlugin)this).Config.SaveOnConfigSet) { ((BaseUnityPlugin)this).Config.Save(); } } private void Notify(string text) { ((BaseUnityPlugin)this).Logger.LogInfo((object)text); if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false, true); } } private static void IntroPreferencePostfix(string __0, ref bool __result) { if (__0 == "SkipIntroCinematic" && (Object)(object)instance != (Object)null && instance.skipIntroVideo != null && instance.skipIntroVideo.Value) { __result = true; } } private void OnDestroy() { ((MonoBehaviour)this).CancelInvoke("TryStart"); ReleaseAutoPause(); RestoreWorldPanel(); if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } }