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 v1.0.0
AutoCloseDoors.dll
Decompiled 3 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("AutoCloseDoors")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+36b52aea168d77af850e89d6c8846c2f9324a51c")] [assembly: AssemblyProduct("AutoCloseDoors")] [assembly: AssemblyTitle("AutoCloseDoors")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [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 AutoCloseDoors { internal static class DoorCloser { private static readonly Dictionary<Door, Coroutine> pending = new Dictionary<Door, Coroutine>(); private const float RetryInterval = 0.25f; private const float RetryBudget = 2f; public static void Arm(Door door, float delay) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) Cancel(door); string prefabName = Utils.GetPrefabName(((Component)door).gameObject); pending[door] = ((MonoBehaviour)Plugin.Instance).StartCoroutine(CloseAfterDelay(door, delay, prefabName)); Plugin.Log.LogDebug((object)$"{prefabName} at {((Component)door).transform.position}: armed, closes in {delay:0.##} s"); } public static void Cancel(Door door) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (pending.TryGetValue(door, out var value)) { if (value != null) { ((MonoBehaviour)Plugin.Instance).StopCoroutine(value); } pending.Remove(door); Plugin.Log.LogDebug((object)$"{Utils.GetPrefabName(((Component)door).gameObject)} at {((Component)door).transform.position}: timer cancelled, closed by hand"); } } private static IEnumerator CloseAfterDelay(Door door, float delay, string prefabName) { try { yield return (object)new WaitForSeconds(delay); float waited = 0f; while (true) { if ((Object)(object)door == (Object)null || (Object)(object)door.m_nview == (Object)null || !door.m_nview.IsValid()) { Plugin.Log.LogDebug((object)(prefabName + ": door unloaded before its timer ran out, nothing to do")); yield break; } if (!Plugin.Enabled.Value) { yield break; } if (door.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0) == 0) { Plugin.Log.LogDebug((object)$"{prefabName} at {((Component)door).transform.position}: already closed"); yield break; } if (door.CanInteract()) { break; } if (waited >= 2f) { Plugin.Log.LogDebug((object)$"{prefabName} at {((Component)door).transform.position}: gave up, still mid-animation after {2f} s"); yield break; } waited += 0.25f; yield return (object)new WaitForSeconds(0.25f); } bool flag = door.m_nview.IsOwner(); door.m_nview.InvokeRPC("UseDoor", new object[1] { false }); Plugin.Log.LogDebug((object)$"{prefabName} at {((Component)door).transform.position}: closed (owner: {flag})"); } finally { pending.Remove(door); } } } internal sealed class DoorRule { public ConfigEntry<bool> Enabled; public ConfigEntry<float> CloseDelay; public float EffectiveDelay { get { if (!(CloseDelay.Value > 0f)) { return Plugin.CloseDelay.Value; } return CloseDelay.Value; } } } internal static class DoorRules { private static readonly Dictionary<string, DoorRule> rules = new Dictionary<string, DoorRule>(StringComparer.Ordinal); private static readonly Dictionary<string, string> displayNames = new Dictionary<string, string>(StringComparer.Ordinal) { { "wood_door", "Wood door" }, { "wood_gate", "Wood gate" }, { "wood_fence_gate", "Wood fence gate" }, { "darkwood_gate", "Darkwood gate" }, { "iron_grate", "Iron gate" }, { "stave_gate", "Stave gate" }, { "piece_dvergr_wood_door", "Dvergr wood door" }, { "piece_drawbridge", "Drawbridge" }, { "piece_drawbridge_log", "Log drawbridge" }, { "piece_hexagonal_door", "Hexagonal gate" }, { "flametal_gate", "Flametal gate" }, { "ashwood_door", "Ashwood door" }, { "piece_cloth_hanging_door", "Cloth hanging door" }, { "piece_cloth_hanging_door_blue", "Blue cloth hanging door" }, { "piece_cloth_hanging_door_blue2", "Blue cloth hanging door (wide)" } }; public static string DisplayName(string prefabName) { if (!displayNames.TryGetValue(prefabName, out var value)) { return prefabName; } return value; } public static DoorRule For(string prefabName) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown if (rules.TryGetValue(prefabName, out var value)) { return value; } string text = DisplayName(prefabName); string text2 = ((text == prefabName) ? prefabName : (text + " (" + prefabName + ")")); value = new DoorRule(); value.Enabled = Plugin.ConfigFile.Bind<bool>(prefabName, "Enabled", true, "Close " + text2 + " automatically after you open it."); value.CloseDelay = Plugin.ConfigFile.Bind<float>(prefabName, "CloseDelay", 0f, new ConfigDescription("Seconds before " + text2 + " closes itself. 0 uses General.CloseDelay.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); rules[prefabName] = value; return value; } public static void BindAll(IEnumerable<string> prefabNames) { ConfigFile configFile = Plugin.ConfigFile; bool saveOnConfigSet = configFile.SaveOnConfigSet; configFile.SaveOnConfigSet = false; int count = rules.Count; try { foreach (string prefabName in prefabNames) { For(prefabName); } } finally { configFile.SaveOnConfigSet = saveOnConfigSet; } if (saveOnConfigSet && rules.Count > count) { configFile.Save(); } } } [BepInPlugin("rhenn.autoclosedoors", "AutoCloseDoors", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "rhenn.autoclosedoors"; public const string PluginName = "AutoCloseDoors"; public const string PluginVersion = "1.0.0"; internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigFile ConfigFile; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> CloseDelay; private readonly Harmony harmony = new Harmony("rhenn.autoclosedoors"); private void Awake() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ConfigFile = ((BaseUnityPlugin)this).Config; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. Set to false and no door closes itself, whatever the door sections below say."); CloseDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "CloseDelay", 3f, new ConfigDescription("Seconds after you open a door before it closes itself. A door's own section can override it with a CloseDelay of its own.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 60f), Array.Empty<object>())); harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)string.Format("{0} {1} loaded. Enabled = {2}, CloseDelay = {3} s", "AutoCloseDoors", "1.0.0", Enabled.Value, CloseDelay.Value)); } private void OnDestroy() { harmony.UnpatchSelf(); } } } namespace AutoCloseDoors.Patches { [HarmonyPatch(typeof(Door), "Open")] internal static class Door_Open_Patch { private const int Unknown = -2; private static void Prefix(Door __instance, out int __state) { __state = -2; if ((Object)(object)__instance.m_nview != (Object)null && __instance.m_nview.IsValid()) { __state = __instance.m_nview.GetZDO().GetInt(ZDOVars.s_state, 0); } } private static void Postfix(Door __instance, int __state) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value) { return; } switch (__state) { case -2: break; default: DoorCloser.Cancel(__instance); break; case 0: { string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject); if ((Object)(object)__instance.m_keyItem != (Object)null || __instance.m_canNotBeClosed) { Plugin.Log.LogDebug((object)$"{prefabName} at {((Component)__instance).transform.position}: skipped, the game does not close this door again"); break; } DoorRule doorRule = DoorRules.For(prefabName); if (!doorRule.Enabled.Value) { Plugin.Log.LogDebug((object)$"{prefabName} at {((Component)__instance).transform.position}: auto-close is off for this door"); } else { DoorCloser.Arm(__instance, doorRule.EffectiveDelay); } break; } } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ZNetScene_Awake_Patch { private static void Postfix(ZNetScene __instance) { SortedSet<string> sortedSet = new SortedSet<string>(StringComparer.Ordinal); foreach (GameObject prefab in __instance.m_prefabs) { if (!((Object)(object)prefab == (Object)null) && !((Object)(object)prefab.GetComponent<Door>() == (Object)null)) { sortedSet.Add(((Object)prefab).name); } } DoorRules.BindAll(sortedSet); Plugin.Log.LogDebug((object)string.Format("{0} door types: {1}", sortedSet.Count, string.Join(", ", sortedSet))); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }