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 RunBasedPassives v0.2.0
plugins/RunBasedPassives.dll
Decompiled 11 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MoreUIPanel; 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("RunBasedPassives")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RunBasedPassives")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d3524128-8d57-4661-a37a-6231cfd2059c")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace RunBasedPassives; [BepInPlugin("cn_xc.RunBasedPassives", "RunBasedPassives", "0.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private ConfigEntry<bool> enableJump; private ConfigEntry<bool> enableStrength; private ConfigEntry<bool> enableStamina; private ConfigEntry<bool> enableHealth; private ConfigEntry<bool> verboseLogging; public static int JumpLevel; public static int StrengthLevel; public static int StaminaLevel; public static int HealthLevel; public static int JumpCount; public static int GrabCount; public static float MoveDistance; public static int HealCount; private static int _lastLogJump; private static int _lastLogGrab; private static float _lastLogMove; private static int _lastLogHeal; private Harmony harmony; private static FieldRef<PlayerAvatar, string> steamIDRef; private static FieldRef<PlayerAvatar, bool> isLocalRef; private static FieldRef<PlayerHealth, PlayerAvatar> healthPlayerAvatarRef; private static FieldRef<StatsManager, SortedDictionary<string, Dictionary<string, int>>> dictOfDictsRef; private bool _uiRegistered = false; private int GetJumpThreshold() { return 80 + JumpLevel * 40; } private int GetGrabThreshold() { return 50 + StrengthLevel * 10; } private float GetMoveThreshold() { return 500f + (float)StaminaLevel * 200f; } private int GetHealThreshold() { return 50 + HealthLevel * 15; } private void Awake() { //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown enableJump = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableJump", true, "启用跳跃升级"); enableStrength = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableStrength", true, "启用力量升级"); enableStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableStamina", true, "启用耐力升级"); enableHealth = ((BaseUnityPlugin)this).Config.Bind<bool>("Toggles", "EnableHealth", true, "启用生命升级"); verboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogging", true, "详细日志输出(用于调试)"); steamIDRef = AccessTools.FieldRefAccess<PlayerAvatar, string>("steamID"); isLocalRef = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isLocal"); healthPlayerAvatarRef = AccessTools.FieldRefAccess<PlayerHealth, PlayerAvatar>("playerAvatar"); dictOfDictsRef = AccessTools.FieldRefAccess<StatsManager, SortedDictionary<string, Dictionary<string, int>>>("dictionaryOfDictionaries"); Patches.isLocalRef = isLocalRef; Patches.steamIDRef = steamIDRef; Patches.healthPlayerAvatarRef = healthPlayerAvatarRef; Patches.pluginLogger = ((BaseUnityPlugin)this).Logger; Patches.verboseLogging = verboseLogging; Harmony.DEBUG = true; harmony = new Harmony("cn_xc.RunBasedPassives"); harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "Jump", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches), "JumpPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(PhysGrabObject), "GrabStarted", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "GrabStartedPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerAvatar), "Update", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "PlayerAvatarUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerHealth), "Heal", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches), "HealPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); SceneManager.sceneLoaded += OnSceneLoaded; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Harmony 补丁总数: {harmony.GetPatchedMethods().Count()}"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RunBasedPassives v0.2.0 loaded"); if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"详细日志已开启(仅在经验变化时输出)"); } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; if (_uiRegistered) { Plugin.UnregisterLine("runbasedpassives_stats"); } harmony.UnpatchAll((string)null); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ResetCounters(); } private void ResetCounters() { JumpCount = 0; GrabCount = 0; MoveDistance = 0f; HealCount = 0; Patches.ResetState(); if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[场景加载] 计数器已重置"); } } private void Update() { if ((Object)(object)PlayerAvatar.instance == (Object)null) { return; } bool flag = SemiFunc.RunIsLevel() || SemiFunc.RunIsShop(); if (flag && !_uiRegistered) { Plugin.RegisterLine("runbasedpassives_stats", (Func<string>)BuildDisplayText); _uiRegistered = true; } else if (!flag && _uiRegistered) { Plugin.UnregisterLine("runbasedpassives_stats"); _uiRegistered = false; } if (flag) { string steamID = GetSteamID(); if (!string.IsNullOrEmpty(steamID)) { JumpLevel = ReadGameDict("playerUpgradeExtraJump", steamID); StrengthLevel = ReadGameDict("playerUpgradeStrength", steamID); StaminaLevel = ReadGameDict("playerUpgradeStamina", steamID); HealthLevel = ReadGameDict("playerUpgradeHealth", steamID); } CheckUpgrades(); ApplyStats(); if (verboseLogging.Value && (JumpCount != _lastLogJump || GrabCount != _lastLogGrab || (int)MoveDistance != (int)_lastLogMove || HealCount != _lastLogHeal)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[状态] 跳跃:{JumpCount}/{GetJumpThreshold()} Lv.{JumpLevel} | 力量:{GrabCount}/{GetGrabThreshold()} Lv.{StrengthLevel} | 耐力:{MoveDistance:F0}/{GetMoveThreshold()} Lv.{StaminaLevel} | 生命:{HealCount}/{GetHealThreshold()} Lv.{HealthLevel}"); _lastLogJump = JumpCount; _lastLogGrab = GrabCount; _lastLogMove = MoveDistance; _lastLogHeal = HealCount; } } } private int ReadGameDict(string dictName, string sid) { SortedDictionary<string, Dictionary<string, int>> sortedDictionary = dictOfDictsRef.Invoke(StatsManager.instance); if (sortedDictionary != null && sortedDictionary.TryGetValue(dictName, out var value) && value != null && value.TryGetValue(sid, out var value2)) { return value2; } return 0; } private void CheckUpgrades() { string steamID = GetSteamID(); if (string.IsNullOrEmpty(steamID)) { return; } bool flag = false; if (enableJump.Value && JumpCount >= GetJumpThreshold()) { JumpCount -= GetJumpThreshold(); JumpLevel++; StatsManager instance = StatsManager.instance; if (instance != null) { instance.DictionaryUpdateValue("playerUpgradeExtraJump", steamID, JumpLevel); } if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 跳跃升级至 Lv.{JumpLevel}"); } flag = true; } if (enableStrength.Value && GrabCount >= GetGrabThreshold()) { GrabCount -= GetGrabThreshold(); StrengthLevel++; StatsManager instance2 = StatsManager.instance; if (instance2 != null) { instance2.DictionaryUpdateValue("playerUpgradeStrength", steamID, StrengthLevel); } if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 力量升级至 Lv.{StrengthLevel}"); } flag = true; } if (enableStamina.Value && MoveDistance >= GetMoveThreshold()) { MoveDistance -= GetMoveThreshold(); StaminaLevel++; StatsManager instance3 = StatsManager.instance; if (instance3 != null) { instance3.DictionaryUpdateValue("playerUpgradeStamina", steamID, StaminaLevel); } if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 耐力升级至 Lv.{StaminaLevel}"); } flag = true; } if (enableHealth.Value && HealCount >= GetHealThreshold()) { HealCount -= GetHealThreshold(); HealthLevel++; StatsManager instance4 = StatsManager.instance; if (instance4 != null) { instance4.DictionaryUpdateValue("playerUpgradeHealth", steamID, HealthLevel); } if (verboseLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"[升级] 生命升级至 Lv.{HealthLevel}"); } flag = true; } if (flag && (Object)(object)StatsUI.instance != (Object)null) { StatsUI.instance.Fetch(); } } private void ApplyStats() { if (!enableStrength.Value) { return; } PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance != (Object)null) { PhysGrabber physGrabber = instance.physGrabber; if ((Object)(object)physGrabber != (Object)null) { physGrabber.grabStrength = 1f + (float)StrengthLevel; } } } private string GetSteamID() { PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return null; } return steamIDRef.Invoke(instance); } private string BuildDisplayText() { StringBuilder stringBuilder = new StringBuilder(); if (enableJump.Value) { stringBuilder.AppendLine($"跳跃 Lv.{JumpLevel} ({JumpCount}/{GetJumpThreshold()})"); } if (enableStrength.Value) { stringBuilder.AppendLine($"力量 Lv.{StrengthLevel} ({GrabCount}/{GetGrabThreshold()})"); } if (enableStamina.Value) { stringBuilder.AppendLine($"耐力 Lv.{StaminaLevel} ({MoveDistance:F0}/{GetMoveThreshold()})"); } if (enableHealth.Value) { stringBuilder.AppendLine($"生命 Lv.{HealthLevel} ({HealCount}/{GetHealThreshold()})"); } return stringBuilder.ToString().TrimEnd(Array.Empty<char>()); } } public static class Patches { internal static FieldRef<PlayerAvatar, bool> isLocalRef; internal static FieldRef<PlayerAvatar, string> steamIDRef; internal static FieldRef<PlayerHealth, PlayerAvatar> healthPlayerAvatarRef; internal static ManualLogSource pluginLogger; internal static ConfigEntry<bool> verboseLogging; private static Vector3 lastPos; private static bool lastPosInitialized; private static readonly HashSet<int> grabbedThisLevel = new HashSet<int>(); private static bool IsInGameplay => SemiFunc.RunIsLevel() || SemiFunc.RunIsShop(); public static void ResetState() { lastPosInitialized = false; grabbedThisLevel.Clear(); } public static void JumpPrefix(PlayerAvatar __instance) { if (IsInGameplay && isLocalRef.Invoke(__instance)) { Plugin.JumpCount++; } } public static void GrabStartedPostfix(PhysGrabObject __instance) { if (!IsInGameplay || SemiFunc.RunIsShop()) { return; } int instanceID = ((Object)__instance).GetInstanceID(); if (grabbedThisLevel.Contains(instanceID)) { return; } List<PhysGrabber> playerGrabbing = __instance.playerGrabbing; if (playerGrabbing == null) { return; } foreach (PhysGrabber item in playerGrabbing) { if ((Object)(object)item.playerAvatar != (Object)null && isLocalRef.Invoke(item.playerAvatar)) { grabbedThisLevel.Add(instanceID); Plugin.GrabCount++; break; } } } public static void PlayerAvatarUpdatePostfix(PlayerAvatar __instance) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (IsInGameplay && isLocalRef.Invoke(__instance)) { Vector3 position = ((Component)__instance).transform.position; if (!lastPosInitialized) { lastPos = position; lastPosInitialized = true; } else { float num = Vector3.Distance(position, lastPos); Plugin.MoveDistance += num; lastPos = position; } } } public static void HealPrefix(int healAmount, PlayerHealth __instance) { if (IsInGameplay && !SemiFunc.RunIsShop() && healAmount > 0) { PlayerAvatar val = healthPlayerAvatarRef.Invoke(__instance); if (!((Object)(object)val == (Object)null) && isLocalRef.Invoke(val)) { Plugin.HealCount++; } } } }