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 Health Regen v2.8.6
plugins/HealthRegen.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("HealthRegen Mod Reborn")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("HealthRegen Mod Reborn")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6e057aef-14c1-4898-8cea-05c265beced3")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] [BepInPlugin("com.rybirb.healthregen", "HealthRegen", "2.8.6")] public class HealthRegenMod : BaseUnityPlugin { [HarmonyPatch(typeof(PlayerHealth), "Start")] public class RegenPatch { private static void Postfix(PlayerHealth __instance) { if ((Object)(object)__instance != (Object)null) { GameObject gameObject = ((Component)__instance).gameObject; if ((Object)(object)gameObject.GetComponent<RegenUpdater>() == (Object)null) { gameObject.AddComponent<RegenUpdater>().Init(__instance); Log.LogInfo((object)$"[{DateTime.Now:HH:mm:ss}] [Patch] RegenUpdater attached to {((Object)__instance).name}."); } } } } public class RegenUpdater : MonoBehaviour { private float updateThrottle = 0f; private static float timeSinceLastRegen = 0f; private static float timeSinceLastLog = 0f; private static Dictionary<string, int> lastKnownHealth = new Dictionary<string, int>(); private static bool isMultiplayer = false; private PlayerHealth playerHealth; private FieldInfo healthField; private FieldInfo maxHealthField; private FieldInfo playerAvatarField; public void Init(PlayerHealth instance) { playerHealth = instance; Type type = ((object)playerHealth).GetType(); healthField = type.GetField("health", BindingFlags.Instance | BindingFlags.NonPublic); maxHealthField = type.GetField("maxHealth", BindingFlags.Instance | BindingFlags.NonPublic); playerAvatarField = type.GetField("playerAvatar", BindingFlags.Instance | BindingFlags.NonPublic); LogInfo("[Init] Reflection setup complete."); } private void Start() { isMultiplayer = PhotonNetwork.IsConnected; LogInfo("[Start] RegenUpdater Start() called for " + ((Object)playerHealth).name + ". Game mode: " + (isMultiplayer ? "Multiplayer" : "Singleplayer")); } private void Update() { //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) updateThrottle += Time.deltaTime; if (updateThrottle < 1f) { return; } updateThrottle = 0f; if (isMultiplayer && !PhotonNetwork.IsMasterClient) { LogInfo("[Update] Skipping regen — not master client."); return; } timeSinceLastRegen += 1f; timeSinceLastLog += 1f; PlayerHealth[] array = Object.FindObjectsOfType<PlayerHealth>(); int num = 0; PlayerHealth[] array2 = array; foreach (PlayerHealth obj in array2) { int num2 = (int)healthField.GetValue(obj); if (num2 > 0) { num++; } } int num3 = 20 * (int)Mathf.Pow(2f, (float)Mathf.Max(0, num - 1)); if (timeSinceLastLog >= 5f) { LogInfo("------------------------------------"); object arg = array.Length; object arg2 = num; Scene activeScene = SceneManager.GetActiveScene(); LogInfo($"[Log] Player count: {arg}, Alive: {arg2} — Scene: {((Scene)(ref activeScene)).name}"); LogInfo($"[Log] Regen Interval: {num3} seconds"); int num4 = 1; PlayerHealth[] array3 = array; foreach (PlayerHealth val in array3) { object avatarObj = playerAvatarField?.GetValue(val); string nickname = GetNickname(avatarObj); int num5 = (int)healthField.GetValue(val); int num6 = (int)maxHealthField.GetValue(val); LogInfo($"Player {num4++}: {((Object)val).name} ({nickname}) — {num5}/{num6} HP"); } LogInfo("------------------------------------"); timeSinceLastLog = 0f; } if (!(timeSinceLastRegen >= (float)num3)) { return; } PlayerHealth[] array4 = array; int value = default(int); foreach (PlayerHealth val2 in array4) { object obj2 = playerAvatarField?.GetValue(val2); PlayerAvatar val3 = (PlayerAvatar)((obj2 is PlayerAvatar) ? obj2 : null); if (val3 == null) { LogInfo("[Regen] Skipping player — Avatar is null or invalid."); continue; } int num7 = (int)healthField.GetValue(val2); int num8 = (int)maxHealthField.GetValue(val2); string key = SemiFunc.PlayerGetSteamID(val3); if (!lastKnownHealth.ContainsKey(key)) { lastKnownHealth[key] = num7; } if (num7 < lastKnownHealth[key]) { LogInfo($"[Detect] Health dropped! {num7}/{num8} (was {lastKnownHealth[key]})"); } lastKnownHealth[key] = num7; if (num7 >= num8) { LogInfo("[Regen] Skipping " + GetNickname(val3) + " — already at max HP."); continue; } int num9 = 1; StatsManager instance = StatsManager.instance; if (instance != null && (instance.playerUpgradeHealth?.TryGetValue(key, out value)).GetValueOrDefault()) { num9 += value; } int num10 = Mathf.Min(num7 + num9, num8); if (isMultiplayer) { PhotonView component = ((Component)val2).GetComponent<PhotonView>(); if (component != null) { component.RPC("UpdateHealthRPC", (RpcTarget)0, new object[3] { num10, num8, false }); } } else { healthField.SetValue(val2, num10); } LogInfo($"[Regen] {GetNickname(val3)} → +{num9} → {num10}/{num8}"); lastKnownHealth[key] = num10; } timeSinceLastRegen = 0f; } private string GetNickname(object avatarObj) { try { object obj = ((avatarObj is PlayerAvatar) ? avatarObj : null); object obj2; if (obj == null) { obj2 = null; } else { PhotonView photonView = ((PlayerAvatar)obj).photonView; if (photonView == null) { obj2 = null; } else { Player owner = photonView.Owner; obj2 = ((owner != null) ? owner.NickName : null); } } if (obj2 == null) { obj2 = "Unknown"; } return (string)obj2; } catch { return "Unknown"; } } private void LogInfo(string msg) { Log.LogInfo((object)$"[{DateTime.Now:HH:mm:ss}] {msg}"); } } internal static ManualLogSource Log; private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Init] HealthRegen is loading..."); Harmony val = new Harmony("com.rybirb.healthregen"); val.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Init] Patching complete."); } }