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 HealthRegenMod v1.1.4
HealthRegenMod.dll
Decompiled 3 months agousing System; 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: AssemblyTitle("HealthRegenMod")] [assembly: AssemblyDescription("Health regeneration mod with god mode and one-shot protection")] [assembly: AssemblyCompany("hyy")] [assembly: AssemblyProduct("HealthRegenMod")] [assembly: AssemblyFileVersion("1.1.4.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 HealthRegenMod { public static class HealthRegenAPI { public static bool SetMaxHealth(int maxHealth) { try { if (maxHealth < 1 || maxHealth > 10000000) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)$"SetMaxHealth: Value {maxHealth} out of range (1-10000000)"); } return false; } PluginConfig.MaxHealth.Value = maxHealth; if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"API: MaxHealth set to {maxHealth}"); } return true; } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("API: SetMaxHealth error: " + ex.Message)); } return false; } } public static int GetMaxHealth() { return PluginConfig.MaxHealth.Value; } public static bool SetGodMode(bool enabled) { try { PluginConfig.EnableGodMode.Value = enabled; if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"API: GodMode set to {enabled}"); } return true; } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("API: SetGodMode error: " + ex.Message)); } return false; } } public static bool GetGodMode() { return PluginConfig.EnableGodMode.Value; } public static bool SetHealthRegenRate(int regenAmount) { try { if (regenAmount < 0 || regenAmount > 1000) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)$"SetHealthRegenRate: Value {regenAmount} out of range (0-1000)"); } return false; } PluginConfig.HealthRegenPerFrame.Value = regenAmount; if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"API: HealthRegenRate set to {regenAmount}"); } return true; } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("API: SetHealthRegenRate error: " + ex.Message)); } return false; } } public static int GetHealthRegenRate() { return PluginConfig.HealthRegenPerFrame.Value; } public static bool SetPlayerHealth(int health) { try { Type type = Type.GetType("PlayerHealth, Assembly-CSharp"); if (type == null) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)"API: PlayerHealth type not found"); } return false; } Object val = Object.FindObjectOfType(type); if (val == (Object)null) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)"API: PlayerHealth instance not found"); } return false; } FieldInfo field = type.GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)"API: health field not found"); } return false; } field.SetValue(val, health); if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"API: Player health set to {health}"); } return true; } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("API: SetPlayerHealth error: " + ex.Message)); } return false; } } public static int GetPlayerHealth() { try { Type type = Type.GetType("PlayerHealth, Assembly-CSharp"); if (type == null) { return -1; } Object val = Object.FindObjectOfType(type); if (val == (Object)null) { return -1; } FieldInfo field = type.GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return -1; } return (int)field.GetValue(val); } catch { return -1; } } public static bool SaveConfig() { try { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)"API: Configuration saved"); } return true; } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("API: SaveConfig error: " + ex.Message)); } return false; } } } public static class PluginConfig { public static ConfigEntry<bool> EnableLogging { get; private set; } public static ConfigEntry<bool> EnableGodMode { get; private set; } public static ConfigEntry<int> MaxHealth { get; private set; } public static ConfigEntry<int> HealthRegenPerFrame { get; private set; } public static ConfigEntry<bool> ShowDebugInfo { get; private set; } public static ConfigEntry<bool> EnableOneShotProtection { get; private set; } public static ConfigEntry<int> OneShotMinHealth { get; private set; } public static ConfigEntry<int> MaxSingleDamage { get; private set; } public static void InitConfig(ConfigFile config) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown try { EnableLogging = config.Bind<bool>("General", "EnableLogging", false, "Enable logging to the console for debugging purposes"); EnableGodMode = config.Bind<bool>("Gameplay", "EnableGodMode", true, "Enable god mode - health never decreases below max value"); MaxHealth = config.Bind<int>("Gameplay", "MaxHealth", 10000, new ConfigDescription("Maximum health value for the player", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10000000), Array.Empty<object>())); HealthRegenPerFrame = config.Bind<int>("Gameplay", "HealthRegenPerFrame", 0, new ConfigDescription("Amount of health regenerated per frame. Set to 0 for instant full heal when god mode is enabled", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())); ShowDebugInfo = config.Bind<bool>("UI", "ShowDebugInfo", false, "Show debug information on screen (if supported by the game)"); EnableOneShotProtection = config.Bind<bool>("Protection", "EnableOneShotProtection", true, "Prevent instant death from one-shot kills by limiting maximum damage taken"); OneShotMinHealth = config.Bind<int>("Protection", "OneShotMinHealth", 1, new ConfigDescription("Minimum health to remain after taking massive damage (only works when one-shot protection is enabled)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000), Array.Empty<object>())); MaxSingleDamage = config.Bind<int>("Protection", "MaxSingleDamage", 500, new ConfigDescription("Maximum damage that can be taken in a single hit. Damage exceeding this will be reduced (0 = unlimited)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); if (EnableLogging.Value) { Plugin.ModLog.LogInfo((object)"Configuration initialized successfully"); } } catch (Exception ex) { Plugin.ModLog.LogError((object)("Failed to initialize configuration: " + ex.Message)); throw; } } } [BepInPlugin("hyy.HealthRegenMod", "HealthRegenMod", "1.1.4")] [BepInProcess("REPO.exe")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource ModLog; private static Harmony _harmony; private void Awake() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown ModLog = ((BaseUnityPlugin)this).Logger; try { PluginConfig.InitConfig(((BaseUnityPlugin)this).Config); _harmony = new Harmony("hyy.HealthRegenMod"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); if (PluginConfig.EnableLogging.Value) { ModLog.LogInfo((object)"HealthRegenMod loaded successfully!"); ModLog.LogInfo((object)$"Configuration loaded - MaxHealth: {PluginConfig.MaxHealth.Value}, GodMode: {PluginConfig.EnableGodMode.Value}, RegenPerFrame: {PluginConfig.HealthRegenPerFrame.Value}"); ModLog.LogInfo((object)$"OneShotProtection: {PluginConfig.EnableOneShotProtection.Value}, MinHealth: {PluginConfig.OneShotMinHealth.Value}, MaxDamage: {PluginConfig.MaxSingleDamage.Value}"); ModLog.LogInfo((object)"author: lingzhu"); ModLog.LogInfo((object)"version: 1.1.4"); ModLog.LogInfo((object)"=========================================="); } } catch (Exception ex) { ModLog.LogError((object)("Load error: " + ex.Message)); } } } [HarmonyPatch(typeof(PlayerHealth), "Start")] public class SetMaxHealthPatch { private static FieldInfo maxHealthField; [HarmonyPostfix] private static void Postfix(PlayerHealth __instance) { try { if (!PluginConfig.EnableGodMode.Value) { return; } if (maxHealthField == null) { maxHealthField = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (!((Object)(object)__instance != (Object)null) || !(maxHealthField != null)) { return; } int value = PluginConfig.MaxHealth.Value; int num = (int)maxHealthField.GetValue(__instance); if (num != value) { maxHealthField.SetValue(__instance, value); if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"Set max health to {value}"); } } } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("Error in SetMaxHealthPatch: " + ex.Message)); } } } } [HarmonyPatch(typeof(PlayerHealth), "Update")] public class KeepHealthAtMaxPatch { private static FieldInfo healthField; private static FieldInfo maxHealthField; [HarmonyPrefix] private static void Prefix(PlayerHealth __instance) { try { if (healthField == null) { healthField = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (maxHealthField == null) { maxHealthField = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (!((Object)(object)__instance != (Object)null) || !(healthField != null) || !(maxHealthField != null)) { return; } int num = (int)healthField.GetValue(__instance); int num2 = (int)maxHealthField.GetValue(__instance); int value = PluginConfig.MaxHealth.Value; if (num2 != value) { maxHealthField.SetValue(__instance, value); num2 = value; } if (PluginConfig.EnableGodMode.Value) { if (num < num2) { healthField.SetValue(__instance, num2); if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogDebug((object)$"God mode active: Health restored to {num2}"); } } } else { if (PluginConfig.HealthRegenPerFrame.Value <= 0) { return; } int value2 = PluginConfig.HealthRegenPerFrame.Value; int num3 = Mathf.Min(num + value2, num2); if (num3 != num) { healthField.SetValue(__instance, num3); if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogDebug((object)$"Health regen: {num} -> {num3} (+{value2})"); } } } } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("Error in KeepHealthAtMaxPatch: " + ex.Message)); } } } } [HarmonyPatch] public class OneShotProtectionPatch { private static MethodBase TargetMethod() { try { Type typeFromHandle = typeof(PlayerHealth); string[] array = new string[6] { "TakeDamage", "Damage", "ApplyDamage", "OnDamage", "ReceiveDamage", "Hit" }; string[] array2 = array; foreach (string value in array2) { MethodInfo[] methods = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo[] array3 = methods; foreach (MethodInfo methodInfo in array3) { if (!methodInfo.Name.Equals(value, StringComparison.OrdinalIgnoreCase)) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); ParameterInfo[] array4 = parameters; foreach (ParameterInfo parameterInfo in array4) { if (parameterInfo.ParameterType == typeof(int) || parameterInfo.ParameterType == typeof(float)) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)("Found damage method: " + methodInfo.Name)); } return methodInfo; } } } } if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogWarning((object)"No damage method found in PlayerHealth class"); } return null; } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("Error finding damage method: " + ex.Message)); } return null; } } [HarmonyPrefix] private static bool Prefix(object __instance, ref object __0, ref object __1, ref object __2, ref object __3) { try { if (PluginConfig.EnableGodMode.Value) { return false; } if (!PluginConfig.EnableOneShotProtection.Value) { return true; } int num = 0; object[] array = new object[4] { __0, __1, __2, __3 }; for (int i = 0; i < array.Length; i++) { if (array[i] != null) { if (array[i] is int num2) { num = num2; break; } if (array[i] is float num3) { num = (int)num3; break; } } } if (num <= 0) { return true; } int num4 = num; int value = PluginConfig.MaxSingleDamage.Value; int value2 = PluginConfig.OneShotMinHealth.Value; if (value > 0 && num > value) { num = value; if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"One-shot protection: Reduced damage from {num4} to {value}"); } } FieldInfo field = typeof(PlayerHealth).GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = typeof(PlayerHealth).GetField("maxHealth", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && __instance != null) { int num5 = (int)field.GetValue(__instance); int value3 = PluginConfig.MaxHealth.Value; if (field2 != null) { value3 = (int)field2.GetValue(__instance); } int num6 = num5 - num; if (num6 < value2 && num6 > 0) { num = num5 - value2; if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"One-shot protection: Adjusted damage to keep minimum {value2} health"); } } else if (num6 <= 0) { num = 0; if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogInfo((object)$"One-shot protection: Prevented fatal damage, kept {num5} health"); } } } if (__0 is int) { __0 = num; } else if (__0 is float) { __0 = (float)num; } else if (__1 is int) { __1 = num; } else if (__1 is float) { __1 = (float)num; } else if (__2 is int) { __2 = num; } else if (__2 is float) { __2 = (float)num; } else if (__3 is int) { __3 = num; } else if (__3 is float) { __3 = (float)num; } return true; } catch (Exception ex) { if (PluginConfig.EnableLogging.Value) { Plugin.ModLog.LogError((object)("Error in OneShotProtectionPatch: " + ex.Message)); } return true; } } } }