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 GrabRechargeMP v1.1.1
PlayerGrabRecharge.dll
Decompiled 2 weeks 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 ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PlayerGrabRecharge")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.2.0.0")] [assembly: AssemblyInformationalVersion("3.2.0")] [assembly: AssemblyProduct("PlayerGrabRecharge")] [assembly: AssemblyTitle("PlayerGrabRecharge")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.2.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace PlayerGrabRecharge { [BepInPlugin("aolion.grabrechargemp", "Player Grab Recharge MP", "3.2.1")] public class PlayerGrabRechargePlugin : BaseUnityPlugin, IOnEventCallback { public const string PLUGIN_GUID = "aolion.grabrechargemp"; public const string PLUGIN_NAME = "Player Grab Recharge MP"; public const string PLUGIN_VERSION = "3.2.1"; private const byte EVENT_CHARGE = 143; private const float MAX_POWER = 100f; private const float COOLDOWN_TIME = 3f; private const float REGEN_RATE = 5f; internal static ManualLogSource Logger = null; private Harmony _harmony; internal static bool IsRecharging = false; internal static float ModPower = 100f; internal static float Cooldown = 0f; private static float _chargeAccum = 0f; private static ItemBattery? _lastBattery = null; private static FieldInfo? _chargeTimerField; private static FieldInfo? _isChargingField; private static FieldInfo? _goalUITextField; private static FieldInfo? _energyUITextField; public static ConfigEntry<KeyCode> RechargeKey { get; private set; } = null; public static ConfigEntry<bool> ToggleMode { get; private set; } = null; public static ConfigEntry<int> RechargeRate { get; private set; } = null; public static ConfigEntry<bool> ShowUI { get; private set; } = null; public static ConfigEntry<bool> DebugLog { get; private set; } = null; public static PlayerGrabRechargePlugin? Instance { get; private set; } private void Awake() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) Instance = this; Logger = ((BaseUnityPlugin)this).Logger; RechargeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Settings", "RechargeKey", (KeyCode)122, "Key to hold (or tap in toggle mode) to recharge the grabbed item."); ToggleMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "ToggleMode", false, "False = hold to charge. True = tap to toggle."); RechargeRate = ((BaseUnityPlugin)this).Config.Bind<int>("Settings", "RechargeRate", 10, new ConfigDescription("Battery % restored per second.", (AcceptableValueBase)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); ShowUI = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowChargeBar", true, "Show the mod power bar on the HUD."); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Verbose logging — set true to diagnose issues."); _harmony = new Harmony("aolion.grabrechargemp"); _harmony.PatchAll(typeof(PlayerGrabRechargePlugin)); Logger.LogInfo((object)string.Format("[PGR] v{0} loaded. Key={1} ToggleMode={2} RatePerSec={3}", "3.2.1", RechargeKey.Value, ToggleMode.Value, RechargeRate.Value)); } private void OnDestroy() { _harmony.UnpatchSelf(); PhotonNetwork.RemoveCallbackTarget((object)this); } private static ItemBattery? GetGrabbedBattery(PlayerController pc) { GameObject physGrabObject = pc.physGrabObject; if ((Object)(object)physGrabObject == (Object)null) { return null; } Transform val = physGrabObject.transform; while ((Object)(object)val.parent != (Object)null && (Object)(object)((Component)val.parent).GetComponent<PhysGrabObject>() != (Object)null) { val = val.parent; } ItemBattery componentInChildren = ((Component)val).GetComponentInChildren<ItemBattery>(true); if (DebugLog.Value && (Object)(object)componentInChildren == (Object)null && (Object)(object)physGrabObject != (Object)null) { Logger.LogInfo((object)("[PGR] No ItemBattery found under " + ((Object)val).name + " (grabbed=" + ((Object)physGrabObject).name + ")")); } return componentInChildren; } private static void EnsureVisualFields() { if (_chargeTimerField == null) { _chargeTimerField = typeof(ItemBattery).GetField("chargeTimer", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_isChargingField == null) { _isChargingField = typeof(ItemBattery).GetField("isCharging", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } } private static void SetChargingVisual(ItemBattery battery) { EnsureVisualFields(); _chargeTimerField?.SetValue(battery, 0.3f); _isChargingField?.SetValue(battery, true); } private static void StopChargingVisual(ItemBattery? battery) { if (!((Object)(object)battery == (Object)null)) { EnsureVisualFields(); _isChargingField?.SetValue(battery, false); _chargeTimerField?.SetValue(battery, 0f); _chargeAccum = 0f; _lastBattery = null; } } private static void ApplyCharge(ItemBattery battery, float amount) { if ((Object)(object)_lastBattery != (Object)(object)battery) { _chargeAccum = 0f; _lastBattery = battery; } float num = ((battery.batteryBars > 0) ? (100f / (float)battery.batteryBars) : 100f); _chargeAccum += amount; if (_chargeAccum >= num) { _chargeAccum -= num; float batteryLife = battery.batteryLife; float num2 = Mathf.Clamp(batteryLife + num, num, 100f); if (battery.batteryLife <= 0f) { battery.batteryLife = 0.001f; } battery.SetBatteryLife(Mathf.RoundToInt(num2)); if (DebugLog.Value) { Logger.LogInfo((object)$"[PGR] Bar +1: {batteryLife:F0}→{num2:F0} bars={battery.batteryBars} barSize={num:F0}"); } } } public void OnEvent(EventData photonEvent) { if (photonEvent.Code != 143 || !PhotonNetwork.IsMasterClient) { return; } try { object[] obj = (object[])photonEvent.CustomData; int num = (int)obj[0]; float num2 = (float)obj[1]; PhotonView val = PhotonView.Find(num); if ((Object)(object)val == (Object)null) { return; } ItemBattery val2 = ((Component)val).GetComponentInChildren<ItemBattery>(true) ?? ((Component)val).GetComponentInParent<ItemBattery>(); if (!((Object)(object)val2 == (Object)null)) { ApplyCharge(val2, num2); if (DebugLog.Value) { Logger.LogInfo((object)$"[PGR:HOST] Remote charge +{num2:F3} on viewID={num} ({((Object)val).name})"); } } } catch (Exception ex) { Logger.LogWarning((object)("[PGR] OnEvent error: " + ex.Message)); } } private static void DrawPowerBar(TextMeshProUGUI? tmp) { if (!ShowUI.Value || (Object)(object)tmp == (Object)null) { return; } float num = Mathf.Clamp01(ModPower / 100f); string text = $"{Mathf.RoundToInt(num * 100f)}%"; if (Cooldown > 0f) { text += $" (CD {Cooldown:F1}s)"; } string text2 = ((num < 0.25f) ? "#ff3333" : ((num < 0.6f) ? "#ffaa00" : "#00ff66")); string text3 = "<line-height=70%>\n<color=" + text2 + "><size=22>Charge: " + text + "</size></color>"; if (!((TMP_Text)tmp).text.Contains("Charge:")) { ((TMP_Text)tmp).text = ((TMP_Text)tmp).text + text3; return; } int num2 = ((TMP_Text)tmp).text.IndexOf("Charge:", StringComparison.Ordinal); int num3 = ((TMP_Text)tmp).text.IndexOf('\n', num2 + 1); if (num3 < 0) { num3 = ((TMP_Text)tmp).text.Length; } string text4 = ((TMP_Text)tmp).text.Substring(0, num2); string text5 = ((TMP_Text)tmp).text; int num4 = num3; ((TMP_Text)tmp).text = text4 + text3 + text5.Substring(num4, text5.Length - num4); } [HarmonyPatch(typeof(PlayerController), "Update")] [HarmonyPostfix] private static void PlayerControllerUpdate_Postfix(PlayerController __instance) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Expected O, but got Unknown //IL_02a6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)PlayerController.instance) { return; } if (Cooldown > 0f) { Cooldown -= Time.deltaTime; } else if (ModPower < 100f) { ModPower = Mathf.Min(ModPower + 5f * Time.deltaTime, 100f); } if (!ToggleMode.Value) { IsRecharging = Input.GetKey(RechargeKey.Value); } else if (Input.GetKeyDown(RechargeKey.Value)) { IsRecharging = !IsRecharging; if (IsRecharging && ModPower <= 0.01f) { IsRecharging = false; } } if (IsRecharging && ModPower <= 0.01f) { Cooldown = 3f; ModPower = 0f; IsRecharging = false; } bool flag = IsRecharging && Cooldown <= 0f && ModPower > 0.01f; ItemBattery grabbedBattery = GetGrabbedBattery(__instance); if (DebugLog.Value && Input.GetKey(RechargeKey.Value)) { GameObject physGrabObject = __instance.physGrabObject; Logger.LogInfo((object)string.Format("[PGR] Z held: grabbed={0} battery={1} life={2:F1} canCharge={3} power={4:F2} cd={5:F2}", ((physGrabObject != null) ? ((Object)physGrabObject).name : null) ?? "null", ((grabbedBattery != null) ? ((Object)grabbedBattery).name : null) ?? "null", grabbedBattery?.batteryLife, flag, ModPower, Cooldown)); } if (!flag) { StopChargingVisual(grabbedBattery); return; } if ((Object)(object)grabbedBattery == (Object)null || grabbedBattery.isUnchargable || grabbedBattery.batteryLife >= 100f) { StopChargingVisual(grabbedBattery); return; } SetChargingVisual(grabbedBattery); float num = (float)RechargeRate.Value * Time.deltaTime; ModPower -= num; if (PhotonNetwork.IsMasterClient || !PhotonNetwork.IsConnectedAndReady) { ApplyCharge(grabbedBattery, num); return; } PhotonView val = ((Component)grabbedBattery).GetComponent<PhotonView>() ?? ((Component)grabbedBattery).GetComponentInParent<PhotonView>() ?? ((Component)grabbedBattery).GetComponentInChildren<PhotonView>(); if ((Object)(object)val == (Object)null) { ApplyCharge(grabbedBattery, num); if (DebugLog.Value) { Logger.LogInfo((object)"[PGR] No PhotonView on battery — charged locally"); } return; } RaiseEventOptions val2 = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; PhotonNetwork.RaiseEvent((byte)143, (object)new object[2] { val.ViewID, num }, val2, SendOptions.SendUnreliable); if (DebugLog.Value) { Logger.LogInfo((object)$"[PGR] Sent charge event viewID={val.ViewID} amount={num:F4}"); } } [HarmonyPatch(typeof(LevelGenerator), "Generate")] [HarmonyPostfix] private static void LevelGenerator_Generate_Postfix() { IsRecharging = false; ModPower = 100f; Cooldown = 0f; _chargeAccum = 0f; _lastBattery = null; PhotonNetwork.AddCallbackTarget((object)Instance); if (DebugLog.Value) { Logger.LogInfo((object)"[PGR] Level generated — state reset, Photon callbacks registered"); } } [HarmonyPatch(typeof(PlayerController), "Start")] [HarmonyPostfix] private static void PlayerControllerStart_Postfix(PlayerController __instance) { if (!((Object)(object)__instance != (Object)(object)PlayerController.instance)) { PhotonNetwork.AddCallbackTarget((object)Instance); if (DebugLog.Value) { Logger.LogInfo((object)"[PGR] PlayerController.Start — Photon callbacks registered"); } } } [HarmonyPatch(typeof(GoalUI), "Update")] [HarmonyPostfix] private static void GoalUI_Update_Postfix(GoalUI __instance) { if (SemiFunc.RunIsLevel()) { if (_goalUITextField == null) { _goalUITextField = typeof(GoalUI).GetField("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } object? obj = _goalUITextField?.GetValue(__instance); DrawPowerBar((TextMeshProUGUI?)((obj is TextMeshProUGUI) ? obj : null)); } } [HarmonyPatch(typeof(EnergyUI), "Update")] [HarmonyPostfix] private static void EnergyUI_Update_Postfix(EnergyUI __instance) { if (SemiFunc.RunIsShop()) { if (_energyUITextField == null) { _energyUITextField = typeof(EnergyUI).GetField("Text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } object? obj = _energyUITextField?.GetValue(__instance); DrawPowerBar((TextMeshProUGUI?)((obj is TextMeshProUGUI) ? obj : null)); } } [HarmonyPatch(typeof(ItemEquippable), "StateIdle")] [HarmonyPrefix] private static bool ItemEquippable_StateIdle_Prefix(ItemEquippable __instance) { if (!IsRecharging) { return true; } PlayerController instance = PlayerController.instance; if ((Object)(object)instance == (Object)null) { return true; } GameObject physGrabObject = instance.physGrabObject; if ((Object)(object)physGrabObject == (Object)null) { return true; } Transform val = physGrabObject.transform; while ((Object)(object)val.parent != (Object)null && (Object)(object)((Component)val.parent).GetComponent<PhysGrabObject>() != (Object)null) { val = val.parent; } if ((Object)(object)((Component)val).GetComponentInChildren<ItemEquippable>(true) == (Object)(object)__instance) { if (DebugLog.Value) { Logger.LogInfo((object)"[PGR] ItemEquippable.StateIdle suppressed (recharging)"); } return false; } return true; } } }