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 StructureDamageManager v1.0.0
StructureDamageManager.dll
Decompiled 2 weeks 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.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("StructureDamageManager")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a59541c05bc4a4c108b884cdfa3e1722c866c52c")] [assembly: AssemblyProduct("StructureDamageManager")] [assembly: AssemblyTitle("StructureDamageManager")] [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 StructureDamageManager { internal static class AutoRepair { private static readonly Dictionary<WearNTear, float> damagedSince = new Dictionary<WearNTear, float>(); internal static void Visit(WearNTear wnt, float time) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.AutoRepairEnabled.Value) { return; } if (wnt.m_healthPercentage >= 1f) { if (damagedSince.Count > 0) { damagedSince.Remove(wnt); } } else { if (!ProtectedPieces.IsProtected(wnt) || !wnt.m_nview.IsValid()) { return; } if (wnt.m_nview.GetZDO().GetFloat(ZDOVars.s_health, wnt.m_health) >= wnt.m_health) { damagedSince.Remove(wnt); return; } if (!damagedSince.TryGetValue(wnt, out var value)) { value = time; damagedSince[wnt] = value; } if (!(time - value < Plugin.AutoRepairDelay.Value) && PrivateArea.CheckAccess(((Component)wnt).transform.position, 0f, false, false)) { damagedSince.Remove(wnt); if (wnt.Repair()) { Plugin.Log.LogDebug((object)$"Repaired {((Object)((Component)wnt).gameObject).name} at {((Component)wnt).transform.position} after {time - value:F0} s (owner: {wnt.m_nview.IsOwner()})"); } } } } internal static void Forget(WearNTear wnt) { if (damagedSince.Count > 0) { damagedSince.Remove(wnt); } } internal static void Reset() { damagedSince.Clear(); } } public enum DamageMode { Off, NonEnvironment, Friendly, All } [BepInPlugin("rhenn.structuredamagemanager", "StructureDamageManager", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "rhenn.structuredamagemanager"; public const string PluginName = "StructureDamageManager"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry<bool> PreventRainDamage; internal static ConfigEntry<DamageMode> Mode; internal static ConfigEntry<bool> AutoRepairEnabled; internal static ConfigEntry<float> AutoRepairDelay; private readonly Harmony harmony = new Harmony("rhenn.structuredamagemanager"); private void Awake() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; PreventRainDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PreventRainDamage", true, "Player-built pieces take no damage from rain or from standing in water. They still look wet. The only setting that is on by default."); Mode = ((BaseUnityPlugin)this).Config.Bind<DamageMode>("General", "DamageMode", DamageMode.Off, "Which damage player-built pieces are immune to.\nOff: vanilla, only PreventRainDamage applies.\nNonEnvironment: no damage from enemy creatures, tamed creatures or players (yourself included).\nFriendly: no damage from tamed creatures or players (yourself included); enemies still hit.\nAll: no damage of any kind: hits, rain, water, loss of support, ash, lava, snow, falling trees, fire, events."); AutoRepairEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoRepair", "Enabled", false, "Damaged player-built pieces near you repair themselves to full health, silently, without a hammer or workbench. Pieces inside a ward you have no access to are left alone."); AutoRepairDelay = ((BaseUnityPlugin)this).Config.Bind<float>("AutoRepair", "DelaySeconds", 60f, new ConfigDescription("How long a piece must stay damaged before it is repaired. 0 repairs at once; a delay lets a raid leave its marks until it is over.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), Array.Empty<object>())); AutoRepairEnabled.SettingChanged += delegate { AutoRepair.Reset(); }; harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)(string.Format("{0} {1} loaded. PreventRainDamage = {2}, ", "StructureDamageManager", "1.0.0", PreventRainDamage.Value) + $"DamageMode = {Mode.Value}, AutoRepair = {AutoRepairEnabled.Value} ({AutoRepairDelay.Value} s)")); } private void OnDestroy() { harmony.UnpatchSelf(); } } internal static class ProtectedPieces { private static readonly HashSet<WearNTear> vehicles = new HashSet<WearNTear>(); internal static void Register(WearNTear wnt) { if ((Object)(object)((Component)wnt).GetComponent<Ship>() != (Object)null || (Object)(object)((Component)wnt).GetComponent<Vagon>() != (Object)null) { vehicles.Add(wnt); } } internal static void Forget(WearNTear wnt) { vehicles.Remove(wnt); } internal static bool IsProtected(WearNTear wnt) { if ((Object)(object)wnt.m_piece != (Object)null && wnt.m_piece.IsPlacedByPlayer()) { return !vehicles.Contains(wnt); } return false; } } } namespace StructureDamageManager.Patches { [HarmonyPatch(typeof(WearNTear), "Awake")] internal static class WearNTear_Awake_Patch { private static void Postfix(WearNTear __instance) { ProtectedPieces.Register(__instance); } } [HarmonyPatch(typeof(WearNTear), "OnDestroy")] internal static class WearNTear_OnDestroy_Patch { private static void Postfix(WearNTear __instance) { ProtectedPieces.Forget(__instance); AutoRepair.Forget(__instance); } } [HarmonyPatch(typeof(WearNTear), "UpdateWear")] internal static class WearNTear_UpdateWear_Patch { private static void Prefix(WearNTear __instance, float time) { if ((Plugin.PreventRainDamage.Value || Plugin.Mode.Value == DamageMode.All) && ProtectedPieces.IsProtected(__instance)) { __instance.m_rainTimer = time; } } private static void Postfix(WearNTear __instance, float time) { AutoRepair.Visit(__instance, time); } } [HarmonyPatch(typeof(WearNTear), "RPC_Damage")] internal static class WearNTear_RPC_Damage_Patch { private static bool Prefix(WearNTear __instance, long sender, HitData hit) { DamageMode value = Plugin.Mode.Value; if (value == DamageMode.Off || !ProtectedPieces.IsProtected(__instance)) { return true; } if (value == DamageMode.All) { return false; } Character attacker = hit.GetAttacker(); if ((Object)(object)attacker == (Object)null) { return true; } bool flag = attacker.IsPlayer() || attacker.IsTamed(); bool flag2 = flag || value == DamageMode.NonEnvironment; if (flag2) { Plugin.Log.LogDebug((object)string.Format("Blocked {0:F0} damage to {1} from {2} ({3}, {4})", hit.GetTotalDamage(), ((Object)((Component)__instance).gameObject).name, attacker.m_name, flag ? "friendly" : "enemy", value)); } return !flag2; } } [HarmonyPatch(typeof(WearNTear), "ApplyDamage")] internal static class WearNTear_ApplyDamage_Patch { private static bool Prefix(WearNTear __instance, ref bool __result) { if (Plugin.Mode.Value != DamageMode.All || !ProtectedPieces.IsProtected(__instance)) { return true; } __result = false; return false; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }