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 MoreDungeonResets v1.0.0
MoreDungeonResets.dll
Decompiled 4 days agousing System; 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("MoreDungeonResets")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Valheim mod to automatically and safely reset dungeons on a schedule.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b5c927effd9df04016f44334c844368a17f792f0")] [assembly: AssemblyProduct("MoreDungeonResets")] [assembly: AssemblyTitle("MoreDungeonResets")] [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 MoreDungeonResets { [HarmonyPatch(typeof(Terminal), "Awake")] public static class AdminCommands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__1_0; internal void <Postfix>b__1_0(ConsoleEventArgs args) { //IL_0088: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { args.Context.AddString("You must be an admin/server host to run this command."); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("You must be spawned in the world to use this command."); return; } DungeonGenerator val = null; float num = 50f; DungeonGenerator[] array = Object.FindObjectsOfType<DungeonGenerator>(); Vector3 val3 = default(Vector3); foreach (DungeonGenerator val2 in array) { float num2 = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val2).transform.position); ((Vector3)(ref val3))..ctor(((Component)val2).transform.position.x, ((Component)localPlayer).transform.position.y, ((Component)val2).transform.position.z); float num3 = Vector3.Distance(((Component)localPlayer).transform.position, val3); float num4 = Mathf.Min(num2, num3); if (num4 < num) { num = num4; val = val2; } } if ((Object)(object)val != (Object)null) { string text = ((Object)val).name.Replace("(Clone)", "").Trim(); args.Context.AddString("[MoreDungeonResets] Forcing manual reset of " + text + "..."); Plugin.Log.LogInfo((object)("Admin manually triggered reset for " + text + ".")); DungeonResetter.ResetDungeonSafe(val); args.Context.AddString("[MoreDungeonResets] Reset complete!"); } else { args.Context.AddString("No dungeon found within 50 meters."); } } } private static bool _initialized; private static void Postfix() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (_initialized) { return; } _initialized = true; object obj = <>c.<>9__1_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0088: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { args.Context.AddString("You must be an admin/server host to run this command."); } else { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("You must be spawned in the world to use this command."); } else { DungeonGenerator val2 = null; float num = 50f; DungeonGenerator[] array = Object.FindObjectsOfType<DungeonGenerator>(); Vector3 val4 = default(Vector3); foreach (DungeonGenerator val3 in array) { float num2 = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val3).transform.position); ((Vector3)(ref val4))..ctor(((Component)val3).transform.position.x, ((Component)localPlayer).transform.position.y, ((Component)val3).transform.position.z); float num3 = Vector3.Distance(((Component)localPlayer).transform.position, val4); float num4 = Mathf.Min(num2, num3); if (num4 < num) { num = num4; val2 = val3; } } if ((Object)(object)val2 != (Object)null) { string text = ((Object)val2).name.Replace("(Clone)", "").Trim(); args.Context.AddString("[MoreDungeonResets] Forcing manual reset of " + text + "..."); Plugin.Log.LogInfo((object)("Admin manually triggered reset for " + text + ".")); DungeonResetter.ResetDungeonSafe(val2); args.Context.AddString("[MoreDungeonResets] Reset complete!"); } else { args.Context.AddString("No dungeon found within 50 meters."); } } } }; <>c.<>9__1_0 = val; obj = (object)val; } new ConsoleCommand("mdr_reset", "Forces a reset of the closest dungeon within 50 meters.", (ConsoleEvent)obj, true, false, true, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } public class DungeonResetter { [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScene_Awake_Patch { private static void Postfix(ZNetScene __instance) { if ((Object)(object)__instance == (Object)null || __instance.m_prefabs == null) { return; } foreach (GameObject prefab in __instance.m_prefabs) { if ((Object)(object)prefab.GetComponent<DungeonGenerator>() != (Object)null) { string text = ((Object)prefab).name.Replace("(Clone)", "").Trim(); if (!Plugin.DungeonToggles.ContainsKey(text)) { Plugin.RegisterDungeon(text, text); } } } } } [HarmonyPatch(typeof(EnvMan), "OnMorning")] public static class EnvMan_OnMorning_Patch { private static void Postfix() { if (Plugin.EnableAutoReset.Value) { DungeonGenerator[] array = Object.FindObjectsOfType<DungeonGenerator>(); foreach (DungeonGenerator dg in array) { EvaluateDungeon(dg); } } } } [HarmonyPatch(typeof(DungeonGenerator), "Awake")] public static class DungeonGenerator_Awake_Patch { private static void Postfix(DungeonGenerator __instance) { if (Plugin.EnableAutoReset.Value) { EvaluateDungeon(__instance); } } } public static void EvaluateDungeon(DungeonGenerator dg) { ZNetView component = ((Component)dg).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { return; } string text = ((Object)dg).name.Replace("(Clone)", "").Trim(); if (Plugin.DungeonToggles.TryGetValue(text, out var value) && !value.Value) { return; } int day = EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds()); int num = component.GetZDO().GetInt("MDR_LastResetDay", day); if (component.GetZDO().GetInt("MDR_LastResetDay", -1) == -1) { component.GetZDO().Set("MDR_LastResetDay", day); } else { if (day - num < Plugin.ResetIntervalDays.Value) { return; } if (IsPlayerInside(dg)) { if (Plugin.EnableDebugLogging.Value) { Plugin.Log.LogInfo((object)("[MoreDungeonResets] Player inside " + text + ". Skipping reset.")); } return; } if (Plugin.EnableDebugLogging.Value) { Plugin.Log.LogInfo((object)("[MoreDungeonResets] Wiping and Regenerating " + text + "...")); } component.GetZDO().Set("MDR_LastResetDay", day); ResetDungeonSafe(dg); } } public static bool IsPlayerInside(DungeonGenerator dg) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) List<Player> list = new List<Player>(); Player.GetPlayersInRange(((Component)dg).transform.position, Mathf.Max(new float[3] { dg.m_zoneSize.x, dg.m_zoneSize.y, dg.m_zoneSize.z }) + 15f, list); return list.Count > 0; } public static void ResetDungeonSafe(DungeonGenerator dg) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) if (((Component)dg).transform.position.y < 1000f) { Plugin.Log.LogWarning((object)$"[MoreDungeonResets] SAFETY ABORT: Dungeon {((Object)dg).name} is too low (Y: {((Component)dg).transform.position.y}). Skipping to protect world data."); return; } Vector3 position = ((Component)dg).transform.position; Bounds val = default(Bounds); ((Bounds)(ref val))..ctor(position, dg.m_zoneSize); List<ZDO> list = new List<ZDO>(); if (ZDOMan.instance != null) { Dictionary<ZDOID, ZDO> dictionary = AccessTools.FieldRefAccess<ZDOMan, Dictionary<ZDOID, ZDO>>("m_objectsByID").Invoke(ZDOMan.instance); if (dictionary != null) { foreach (KeyValuePair<ZDOID, ZDO> item in dictionary) { ZDO value = item.Value; if (((Bounds)(ref val)).Contains(value.GetPosition())) { GameObject prefab = ZNetScene.instance.GetPrefab(value.GetPrefab()); if (!((Object)(object)prefab != (Object)null) || (!((Object)(object)prefab.GetComponent<Player>() != (Object)null) && !((Object)(object)prefab.GetComponent<DungeonGenerator>() != (Object)null) && !((Object)(object)prefab.GetComponent<LocationProxy>() != (Object)null))) { list.Add(value); } } } } } foreach (ZDO item2 in list) { ZDOMan.instance.DestroyZDO(item2); } if (Plugin.EnableDebugLogging.Value) { Plugin.Log.LogInfo((object)$"[MoreDungeonResets] Wiped {list.Count} objects from interior. Regenerating..."); } dg.Generate((SpawnMode)0); string text = ((Object)dg).name.Replace("(Clone)", "").Trim(); if (text == "DG_DvergrBoss" || text == "Mistlands_DvergrBossEntrance1") { ApplyQueenFix(dg); } } private static void ApplyQueenFix(DungeonGenerator dg) { //IL_0029: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) if (Plugin.EnableDebugLogging.Value) { Plugin.Log.LogInfo((object)"[MoreDungeonResets] Applying special Queen Fix logic..."); } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(((Component)dg).transform.position.x, ((Component)dg).transform.position.z); int stableHashCode = StringExtensionMethods.GetStableHashCode("dvergr_boss_door"); int stableHashCode2 = StringExtensionMethods.GetStableHashCode("Spawner_SeekerQueen"); bool flag = false; Bounds val2 = default(Bounds); ((Bounds)(ref val2))..ctor(((Component)dg).transform.position, dg.m_zoneSize); if (ZDOMan.instance != null) { Dictionary<ZDOID, ZDO> dictionary = AccessTools.FieldRefAccess<ZDOMan, Dictionary<ZDOID, ZDO>>("m_objectsByID").Invoke(ZDOMan.instance); if (dictionary != null) { Vector2 val3 = default(Vector2); foreach (KeyValuePair<ZDOID, ZDO> item in dictionary) { ZDO value = item.Value; if (value.GetPrefab() == StringExtensionMethods.GetStableHashCode("dungeon_queen_door") || value.GetPrefab() == StringExtensionMethods.GetStableHashCode("piece_queendoor") || value.GetPrefab() == StringExtensionMethods.GetStableHashCode("dvergr_boss_door")) { ((Vector2)(ref val3))..ctor(value.GetPosition().x, value.GetPosition().z); if (Vector2.Distance(val, val3) < 150f) { value.Set("state", 0); if (Plugin.EnableDebugLogging.Value) { Plugin.Log.LogInfo((object)"[MoreDungeonResets] Queen Sealbreaker door has been successfully resealed!"); } } } if (value.GetPrefab() == stableHashCode2 && ((Bounds)(ref val2)).Contains(value.GetPosition())) { flag = true; value.Set("alive_time", 0L); } } } } if (!flag) { Plugin.Log.LogWarning((object)"[MoreDungeonResets] Queen spawner was missing after regen! Injecting a new one manually."); Vector3 val4 = ((Component)dg).transform.position + new Vector3(0f, 5f, 0f); GameObject prefab = ZNetScene.instance.GetPrefab("Spawner_SeekerQueen"); if ((Object)(object)prefab != (Object)null) { Object.Instantiate<GameObject>(prefab, val4, Quaternion.identity); } } } } [BepInPlugin("com.loathe.MoreDungeonResets", "More Dungeon Resets", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.loathe.MoreDungeonResets"; public const string PluginName = "More Dungeon Resets"; public const string PluginVersion = "1.0.0"; private readonly Harmony _harmony = new Harmony("com.loathe.MoreDungeonResets"); public static Plugin Instance; public static ManualLogSource Log; public static ConfigEntry<bool> EnableAutoReset; public static ConfigEntry<int> ResetIntervalDays; public static ConfigEntry<bool> EnableDebugLogging; public static Dictionary<string, ConfigEntry<bool>> DungeonToggles = new Dictionary<string, ConfigEntry<bool>>(); private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; EnableAutoReset = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Global", "Enable Auto Reset", true, "Enable the automatic lazy-resetting of dungeons."); ResetIntervalDays = ((BaseUnityPlugin)this).Config.Bind<int>("1 - Global", "Reset Interval (Days)", 30, "How many in-game days must pass before a dungeon is eligible to be reset again."); EnableDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Global", "Enable Debug Logging", true, "Prints detailed logs to the console about ZDO deletions and reset math."); RegisterDungeon("Crypt", "Sunken Crypts", "2 - Dungeons", defaultValue: true, "Enable resetting of Swamp Sunken Crypts."); RegisterDungeon("TrollCave", "Troll Caves", "2 - Dungeons", defaultValue: true, "Enable resetting of Black Forest Troll Caves."); RegisterDungeon("TrollCave02", "Troll Caves 02", "2 - Dungeons", defaultValue: true, "Enable resetting of Black Forest Troll Caves variant."); RegisterDungeon("BurialChamber", "Burial Chambers", "2 - Dungeons", defaultValue: true, "Enable resetting of Black Forest Burial Chambers."); RegisterDungeon("MountainCave", "Frost Caves", "2 - Dungeons", defaultValue: true, "Enable resetting of Mountain Frost Caves."); RegisterDungeon("Mistlands_DvergrTownEntrance", "Infested Mines", "2 - Dungeons", defaultValue: true, "Enable resetting of Mistlands Infested Mines."); RegisterDungeon("Mistlands_DvergrBossEntrance1", "Queen Citadel", "2 - Dungeons", defaultValue: true, "Enable resetting of the Queen's Infested Citadel (Includes the custom door/spawner fix)."); RegisterDungeon("Hildir_cave", "Smouldering Tombs", "3 - Hildir", defaultValue: true, "Enable resetting of Hildir's Smouldering Tombs."); RegisterDungeon("Hildir_crypt", "Howling Caverns", "3 - Hildir", defaultValue: true, "Enable resetting of Hildir's Howling Caverns."); RegisterDungeon("Hildir_camp", "Sealed Tower", "3 - Hildir", defaultValue: false, "Enable resetting of Hildir's Sealed Tower (Note: This is mostly an exterior structure)."); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.loathe.MoreDungeonResets is loaded!"); } public static void RegisterDungeon(string prefabName, string displayName, string category = "4 - Modded Dungeons", bool defaultValue = true, string description = "") { string text = prefabName.Replace("(Clone)", "").Trim(); if (!DungeonToggles.ContainsKey(text)) { if (string.IsNullOrEmpty(description)) { description = "Enable resetting of " + displayName + " (" + text + ")"; } ConfigEntry<bool> value = ((BaseUnityPlugin)Instance).Config.Bind<bool>(category, "Reset " + displayName, defaultValue, description); DungeonToggles[text] = value; Log.LogInfo((object)("Registered config for dungeon: " + text + " as '" + displayName + "'")); } } } public static class PluginInfo { public const string PLUGIN_GUID = "MoreDungeonResets"; public const string PLUGIN_NAME = "MoreDungeonResets"; public const string PLUGIN_VERSION = "1.0.0"; } }