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.0.0
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.0.0.0")] [assembly: AssemblyInformationalVersion("3.0.0")] [assembly: AssemblyProduct("PlayerGrabRecharge")] [assembly: AssemblyTitle("PlayerGrabRecharge")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.0.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("modx.playergrabrecharge", "Player Grab Recharge", "3.0.0")] public class PlayerGrabRechargePlugin : BaseUnityPlugin, IOnEventCallback { public const string PLUGIN_GUID = "modx.playergrabrecharge"; public const string PLUGIN_NAME = "Player Grab Recharge"; public const string PLUGIN_VERSION = "3.0.0"; private const byte EVENT_CHARGE = 143; internal static ManualLogSource Logger = null; private Harmony _harmony; internal static bool IsRecharging = false; internal static float ModPower = 10f; internal static float Cooldown = 0f; private static float _chargeAccum = 0f; private static ItemBattery? _lastBattery = null; internal const float MAX_POWER = 10f; internal const float COOLDOWN_TIME = 2f; internal const float REGEN_RATE = 0.1f; private static MethodInfo? _syncMethod; private static FieldInfo? _chargeTimerField; private static FieldInfo? _isChargingField; 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; } = null; private void Awake() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00fe: 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 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 % per second.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); ShowUI = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowChargeBar", true, "Show mod power bar on HUD."); DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Verbose logging."); _harmony = new Harmony("modx.playergrabrecharge"); _harmony.PatchAll(typeof(PlayerGrabRechargePlugin)); Logger.LogInfo((object)string.Format("[PGR] v{0} loaded. Key={1}", "3.0.0", RechargeKey.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)pc.physGrabObject != (Object)null) { Logger.LogInfo((object)("[PGR] No battery found in " + ((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.2f); _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 added! {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); ItemBattery val2 = ((val != null) ? ((Component)val).GetComponent<ItemBattery>() : null) ?? ((val != null) ? ((Component)val).GetComponentInChildren<ItemBattery>(true) : null); if (!((Object)(object)val2 == (Object)null)) { ApplyCharge(val2, num2); if (DebugLog.Value) { Logger.LogInfo((object)$"[PGR:HOST] Applied remote charge +{num2:F3} on {((Object)val2).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 / 10f); 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:"); int num3 = ((TMP_Text)tmp).text.IndexOf('\n', num2); if (num3 == -1) { 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Expected O, but got Unknown //IL_02bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance != (Object)(object)PlayerController.instance || (!SemiFunc.RunIsLevel() && !SemiFunc.RunIsShop())) { return; } if (Cooldown > 0f) { Cooldown -= Time.deltaTime; } else if (ModPower < 10f) { ModPower = Mathf.Min(ModPower + 0.1f * Time.deltaTime, 10f); } 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 = 2f; ModPower = 0f; IsRecharging = false; } bool num = IsRecharging && Cooldown <= 0f && ModPower > 0.01f; ItemBattery grabbedBattery = GetGrabbedBattery(__instance); if (!num) { StopChargingVisual(grabbedBattery); return; } if (DebugLog.Value) { ManualLogSource logger = Logger; GameObject physGrabObject = __instance.physGrabObject; logger.LogInfo((object)string.Format("[PGR] Z held: grabbed={0} battery={1} life={2:F1}", ((physGrabObject != null) ? ((Object)physGrabObject).name : null) ?? "null", ((grabbedBattery != null) ? ((Object)grabbedBattery).name : null) ?? "null", grabbedBattery?.batteryLife)); } if ((Object)(object)grabbedBattery == (Object)null || grabbedBattery.isUnchargable || grabbedBattery.batteryLife >= 100f) { StopChargingVisual(grabbedBattery); return; } SetChargingVisual(grabbedBattery); float num2 = (float)RechargeRate.Value * Time.deltaTime; ModPower -= Mathf.Min(1f * Time.deltaTime, ModPower); if (!PhotonNetwork.IsConnected || !PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { ApplyCharge(grabbedBattery, num2); if (DebugLog.Value) { Logger.LogInfo((object)$"[PGR] Charged {((Object)grabbedBattery).name} +{num2:F2} life={grabbedBattery.batteryLife:F1}"); } return; } PhotonView val = ((Component)grabbedBattery).GetComponent<PhotonView>() ?? ((Component)grabbedBattery).GetComponentInParent<PhotonView>() ?? ((Component)grabbedBattery).GetComponentInChildren<PhotonView>(); if ((Object)(object)val == (Object)null) { ApplyCharge(grabbedBattery, num2); if (DebugLog.Value) { Logger.LogInfo((object)"[PGR] No PhotonView, charged locally"); } return; } RaiseEventOptions val2 = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; PhotonNetwork.RaiseEvent((byte)143, (object)new object[2] { val.ViewID, num2 }, val2, SendOptions.SendUnreliable); if (DebugLog.Value) { Logger.LogInfo((object)$"[PGR] Sent charge event ViewID={val.ViewID}"); } } [HarmonyPatch(typeof(LevelGenerator), "Generate")] [HarmonyPostfix] private static void LevelGenerator_Generate_Postfix() { IsRecharging = false; ModPower = 10f; Cooldown = 0f; _chargeAccum = 0f; _lastBattery = null; PhotonNetwork.AddCallbackTarget((object)Instance); if (DebugLog.Value) { Logger.LogInfo((object)"[PGR] Level generated, 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 started, callbacks re-registered"); } } } [HarmonyPatch(typeof(GoalUI), "Update")] [HarmonyPostfix] private static void GoalUI_Update_Postfix(TextMeshProUGUI ___Text) { if (SemiFunc.RunIsLevel()) { DrawPowerBar(___Text); } } [HarmonyPatch(typeof(EnergyUI), "Update")] [HarmonyPostfix] private static void EnergyUI_Update_Postfix(TextMeshProUGUI ___Text) { if (SemiFunc.RunIsShop()) { DrawPowerBar(___Text); } } } }