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 AutoCloseDoors v0.1.4
AutoCloseDoors.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] namespace Obelisk.AutoCloseDoors; [BepInPlugin("obelisk.valheim.autoclosedoors", "AutoCloseDoors", "0.1.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class AutoCloseDoorsPlugin : BaseUnityPlugin { public const string PluginGuid = "obelisk.valheim.autoclosedoors"; public const string PluginName = "AutoCloseDoors"; public const string PluginVersion = "0.1.4"; private static ConfigEntry<bool> _enabled; private static ConfigEntry<bool> _enableInDungeons; private static ConfigEntry<bool> _blockMonsterDoorSensors; private static ConfigEntry<float> _playerRadius; private static ConfigEntry<int> _closeDelaySeconds; private Harmony _harmony; internal static bool IsEnabled => _enabled.Value; internal static bool EnableInDungeons => _enableInDungeons.Value; internal static bool BlockMonsterDoorSensors => _blockMonsterDoorSensors.Value; internal static float PlayerRadius => Mathf.Max(0f, _playerRadius.Value); internal static float CloseDelay => Mathf.Clamp(_closeDelaySeconds.Value, 2, 10); private void Awake() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable automatic closing for opened doors and gates."); _enableInDungeons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable in dungeons", false, "Enable automatic closing while the local player is inside dungeons/interiors."); _blockMonsterDoorSensors = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "Block monster door sensors", true, "Prevents compatible door sensor mods from opening player doors for monsters."); _playerRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Player radius", 3f, new ConfigDescription("Door will wait again while any player is inside this radius.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); _closeDelaySeconds = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Close delay seconds", 5, new ConfigDescription("Seconds before an opened door can close. Allowed range: 2-10.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), Array.Empty<object>())); DoorAutoCloser.Initialize(this); DoorAutoCloser.CacheGameMethods(); _harmony = new Harmony("obelisk.valheim.autoclosedoors"); _harmony.PatchAll(); DoorAutoCloser.PatchCompatibility(_harmony); } private void OnDestroy() { DoorAutoCloser.Reset(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch(typeof(Door), "RPC_UseDoor")] internal static class DoorRpcUseDoorPatch { private static void Postfix(Door __instance) { DoorAutoCloser.OnDoorStateChanged(__instance); } } internal static class DoorAutoCloser { private const float LinkedDoorSearchRadius = 5f; private const float LinkedDoorMaxHeightDifference = 0.35f; private const float LinkedDoorMinDistance = 0.1f; private static readonly Dictionary<Door, float> OpenDoors = new Dictionary<Door, float>(); private static readonly List<Door> DueDoors = new List<Door>(); private static readonly List<Door> LinkedDoors = new List<Door>(); private static readonly List<Piece> NearbyPieces = new List<Piece>(); private static AutoCloseDoorsPlugin _plugin; private static Coroutine _checkRoutine; private static MethodInfo _playerInInteriorMethod; private static bool _compatibilityPatched; public static void Initialize(AutoCloseDoorsPlugin plugin) { _plugin = plugin; } public static void CacheGameMethods() { _playerInInteriorMethod = AccessTools.Method(typeof(Player), "InInterior", (Type[])null, (Type[])null); } public static void PatchCompatibility(Harmony harmony) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown if (!_compatibilityPatched && harmony != null) { Type type = AccessTools.TypeByName("MonsterDoorSensor"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "OpenDoor", (Type[])null, (Type[])null)); MethodInfo methodInfo2 = AccessTools.Method(typeof(MonsterDoorSensorOpenDoorPatch), "Prefix", (Type[])null, (Type[])null); if (!(methodInfo == null) && !(methodInfo2 == null)) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _compatibilityPatched = true; } } } public static void Reset() { if ((Object)(object)_plugin != (Object)null && _checkRoutine != null) { ((MonoBehaviour)_plugin).StopCoroutine(_checkRoutine); } _checkRoutine = null; OpenDoors.Clear(); DueDoors.Clear(); LinkedDoors.Clear(); NearbyPieces.Clear(); } public static void OnDoorStateChanged(Door door) { if (!AutoCloseDoorsPlugin.IsEnabled || IsDungeonDisabled() || !IsOpen(door)) { Forget(door); } else { Track(door, Time.time + AutoCloseDoorsPlugin.CloseDelay, restartRoutine: true); } } private static void Track(Door door, float nextCheckTime, bool restartRoutine) { OpenDoors[door] = nextCheckTime; if (restartRoutine) { RestartCheckRoutine(); } } private static void Forget(Door door) { if (door != null) { OpenDoors.Remove(door); } } private static void RestartCheckRoutine() { if (!((Object)(object)_plugin == (Object)null)) { if (_checkRoutine != null) { ((MonoBehaviour)_plugin).StopCoroutine(_checkRoutine); } _checkRoutine = ((MonoBehaviour)_plugin).StartCoroutine(CheckOpenDoors()); } } private static IEnumerator CheckOpenDoors() { while (OpenDoors.Count > 0) { if (!AutoCloseDoorsPlugin.IsEnabled) { OpenDoors.Clear(); break; } if (IsDungeonDisabled()) { OpenDoors.Clear(); break; } float dueDoors = GetDueDoors(Time.time); if (DueDoors.Count == 0) { float num = Mathf.Max(0.1f, dueDoors - Time.time); yield return (object)new WaitForSeconds(num); continue; } for (int i = 0; i < DueDoors.Count; i++) { Door val = DueDoors[i]; if (OpenDoors.ContainsKey(val)) { CheckDoor(val); } } DueDoors.Clear(); } _checkRoutine = null; } private static float GetDueDoors(float now) { DueDoors.Clear(); float num = float.MaxValue; foreach (KeyValuePair<Door, float> openDoor in OpenDoors) { if (!IsOpen(openDoor.Key)) { DueDoors.Add(openDoor.Key); } else if (openDoor.Value <= now) { DueDoors.Add(openDoor.Key); } else if (openDoor.Value < num) { num = openDoor.Value; } } return num; } private static void CheckDoor(Door door) { CollectLinkedOpenDoors(door); if (LinkedDoors.Count == 0) { Forget(door); } else if (IsAnyPlayerNear(LinkedDoors)) { float nextCheckTime = Time.time + AutoCloseDoorsPlugin.CloseDelay; for (int i = 0; i < LinkedDoors.Count; i++) { Track(LinkedDoors[i], nextCheckTime, restartRoutine: false); } } else { for (int j = 0; j < LinkedDoors.Count; j++) { CloseDoor(LinkedDoors[j]); Forget(LinkedDoors[j]); } } } private static void CollectLinkedOpenDoors(Door door) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) LinkedDoors.Clear(); NearbyPieces.Clear(); if (!IsOpen(door)) { return; } LinkedDoors.Add(door); Piece.GetAllPiecesInRadius(((Component)door).transform.position, 5f, NearbyPieces); for (int i = 0; i < NearbyPieces.Count; i++) { Piece val = NearbyPieces[i]; if (!((Object)(object)val == (Object)null)) { Door component = ((Component)val).GetComponent<Door>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component == (Object)(object)door) && IsOpen(component) && IsLinkedDoor(door, component)) { LinkedDoors.Add(component); } } } } private static bool IsLinkedDoor(Door door, Door otherDoor) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_009c: Unknown result type (might be due to invalid IL or missing references) //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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)door).transform; Transform transform2 = ((Component)otherDoor).transform; Vector3 position = transform.position; Vector3 position2 = transform2.position; if (Mathf.Abs(position.y - position2.y) > 0.35f) { return false; } Vector3 val = position2 - position; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 0.1f || magnitude > 5f) { return false; } Vector3 val2 = val / magnitude; Vector3 val3 = Horizontal(transform.right); Vector3 val4 = Horizontal(transform2.right); Vector3 val5 = Horizontal(transform.forward); Vector3 val6 = Horizontal(transform2.forward); if (val3 == Vector3.zero || val4 == Vector3.zero || val5 == Vector3.zero || val6 == Vector3.zero) { return false; } ((Vector3)(ref val3)).Normalize(); ((Vector3)(ref val4)).Normalize(); ((Vector3)(ref val5)).Normalize(); ((Vector3)(ref val6)).Normalize(); bool num = Mathf.Abs(Vector3.Dot(val2, val3)) >= 0.75f; bool flag = Vector3.Dot(val3, val4) <= -0.75f || Vector3.Dot(val5, val6) <= -0.75f; bool flag2 = Vector3.Dot(val3, val4) >= 0.75f && Vector3.Dot(val5, val6) >= 0.75f; if (num) { return flag || flag2; } return false; } private static bool IsAnyPlayerNear(List<Door> doors) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) float playerRadius = AutoCloseDoorsPlugin.PlayerRadius; for (int i = 0; i < doors.Count; i++) { if (Player.IsPlayerInRange(((Component)doors[i]).transform.position, playerRadius)) { return true; } } return false; } private static void CloseDoor(Door door) { if (!IsOpen(door)) { return; } ZNetView doorView = GetDoorView(door); if (!((Object)(object)doorView == (Object)null) && doorView.IsValid()) { if (!doorView.IsOwner()) { doorView.ClaimOwnership(); } doorView.GetZDO().Set(ZDOVars.s_state, 0, false); } } private static bool IsOpen(Door door) { ZNetView doorView = GetDoorView(door); if ((Object)(object)doorView == (Object)null || !doorView.IsValid()) { return false; } return doorView.GetZDO().GetInt(ZDOVars.s_state, 0) != 0; } private static ZNetView GetDoorView(Door door) { if (door == null) { return null; } return ((Component)door).GetComponent<ZNetView>(); } private static bool IsDungeonDisabled() { if (AutoCloseDoorsPlugin.EnableInDungeons) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || _playerInInteriorMethod == null) { return false; } return (bool)_playerInInteriorMethod.Invoke(localPlayer, null); } private static Vector3 Horizontal(Vector3 vector) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) vector.y = 0f; return vector; } } internal static class MonsterDoorSensorOpenDoorPatch { public static bool Prefix() { return !AutoCloseDoorsPlugin.BlockMonsterDoorSensors; } }