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 Run v2.1.1
Run.dll
Decompiled 3 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; 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("Run")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("HP")] [assembly: AssemblyProduct("Run")] [assembly: AssemblyCopyright("Copyright © HP 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("07f7a2d6-6812-4679-a53d-8ba964c5b75b")] [assembly: AssemblyFileVersion("2.1.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } [CompilerGenerated] [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 Run { [BepInPlugin("YouDied.run", "Run!", "2.1.1")] public class Run : BaseUnityPlugin { public const string PluginGUID = "YouDied.run"; public const string PluginName = "Run!"; public const string PluginVersion = "2.1.1"; internal static ManualLogSource Log = null; private static ConfigEntry<int> _cfgMinMultiplier = null; private static ConfigEntry<int> _cfgMaxMultiplier = null; private static ConfigEntry<int> _cfgStep = null; private static ConfigEntry<int> _cfgCurrentMultiplier = null; private static ConfigEntry<bool> _cfgLudicrousEnabled = null; private static ConfigEntry<int> _cfgLudicrousMultiplier = null; private static ConfigEntry<KeyboardShortcut> _cfgKeyIncrease = null; private static ConfigEntry<KeyboardShortcut> _cfgKeyDecrease = null; private static int s_multiplier = 100; private static bool s_uiGuardBroken; private Harmony _harmony = null; private static FieldRef<Character, bool>? s_mRun; private static MethodInfo? s_isRunning; private void Awake() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Expected O, but got Unknown //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; _cfgMinMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("Speed Range", "MinimumMultiplier", 100, new ConfigDescription("Lowest run speed percentage allowed (100 = default game speed).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 500), Array.Empty<object>())); _cfgMaxMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("Speed Range", "MaximumMultiplier", 200, new ConfigDescription("Highest run speed percentage reachable with arrow keys.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 500), Array.Empty<object>())); _cfgStep = ((BaseUnityPlugin)this).Config.Bind<int>("Speed Range", "AdjustmentPercent", 10, new ConfigDescription("How much each arrow key press changes speed, in percentage points. e.g. 10 moves from 100% to 110% per press.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); _cfgCurrentMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("Current Speed", "CurrentMultiplier", 100, new ConfigDescription("Your last-used run speed percentage. Updated automatically in-game.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 500), Array.Empty<object>())); _cfgLudicrousEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Ludicrous Speed", "LudicrousEnabled", false, "Set to true to enable Ludicrous Speed. Run speed is further multiplied by LudicrousMultiplier on top of your current setting. Edit and restart to toggle."); _cfgLudicrousMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("Ludicrous Speed", "LudicrousMultiplier", 3, new ConfigDescription("Extra speed factor stacked on top of normal multiplier when Ludicrous Speed is on. Try 2-3 before going higher.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 10), Array.Empty<object>())); _cfgKeyIncrease = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keybinds", "IncreaseSpeed", new KeyboardShortcut((KeyCode)273, Array.Empty<KeyCode>()), "Key to increase run speed."); _cfgKeyDecrease = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keybinds", "DecreaseSpeed", new KeyboardShortcut((KeyCode)274, Array.Empty<KeyCode>()), "Key to decrease run speed."); s_multiplier = Mathf.Clamp(_cfgCurrentMultiplier.Value, GetMin(), GetMax()); _harmony = new Harmony("YouDied.run"); PatchRunSpeed(); PatchLiquidResistance(); Log.LogInfo((object)"Run! v2.1.1 by YouDied loaded."); Log.LogInfo((object)(" Speed range : " + GetMin() + "% – " + GetMax() + "%")); Log.LogInfo((object)(" Step : " + _cfgStep.Value + "%")); Log.LogInfo((object)(" Current : " + s_multiplier + "%")); Log.LogInfo((object)(" Ludicrous : " + (_cfgLudicrousEnabled.Value ? ("ON (x" + _cfgLudicrousMultiplier.Value + ")") : "off"))); Log.LogInfo((object)(" Controls : " + ((object)_cfgKeyIncrease.Value/*cast due to .constrained prefix*/).ToString() + " / " + ((object)_cfgKeyDecrease.Value/*cast due to .constrained prefix*/).ToString() + " to adjust speed")); } private void Update() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || IsUiBlocking()) { return; } bool flag = false; KeyboardShortcut value = _cfgKeyIncrease.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { s_multiplier = Mathf.Min(s_multiplier + _cfgStep.Value, GetMax()); flag = true; } else { value = _cfgKeyDecrease.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { s_multiplier = Mathf.Max(s_multiplier - _cfgStep.Value, GetMin()); flag = true; } } if (flag) { _cfgCurrentMultiplier.Value = s_multiplier; string text = ((s_multiplier <= GetMin()) ? " (min)" : ((s_multiplier >= GetMax()) ? " (max)" : "")); string text2 = "Run Speed: " + s_multiplier + "%" + text; if (_cfgLudicrousEnabled.Value) { text2 = text2 + " [LUDICROUS x" + _cfgLudicrousMultiplier.Value + "]"; } ((Character)Player.m_localPlayer).Message((MessageType)1, text2, 0, (Sprite)null, false); Log.LogInfo((object)("Run speed -> " + s_multiplier + "%")); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static int GetMin() { return Mathf.Max(100, _cfgMinMultiplier.Value); } private static int GetMax() { return Mathf.Clamp(_cfgMaxMultiplier.Value, GetMin(), 500); } private static float GetEffectiveMultiplier() { float num = (float)s_multiplier / 100f; if (!_cfgLudicrousEnabled.Value) { return num; } return num * (float)Mathf.Max(2, _cfgLudicrousMultiplier.Value); } private static bool IsUiBlocking() { if (s_uiGuardBroken) { return false; } try { return CheckUi(); } catch (Exception ex) { s_uiGuardBroken = true; Log.LogWarning((object)("Menu/chat check unavailable on this Valheim build, hotkeys will work everywhere: " + ex.Message)); return false; } } private static bool CheckUi() { if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } if (InventoryGui.IsVisible()) { return true; } if (Menu.IsVisible()) { return true; } return false; } private static bool IsSprinting(Character c) { if (s_mRun != null) { return s_mRun.Invoke(c); } if (s_isRunning != null) { object obj = s_isRunning.Invoke(c, null); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } return false; } private static void ResolveSprintState() { FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "m_run"); if (fieldInfo != null && fieldInfo.FieldType == typeof(bool)) { s_mRun = AccessTools.FieldRefAccess<Character, bool>(fieldInfo); return; } MethodInfo methodInfo = AccessTools.Method(typeof(Character), "IsRunning", Type.EmptyTypes, (Type[])null); if (methodInfo != null && methodInfo.ReturnType == typeof(bool)) { s_isRunning = methodInfo; Log.LogInfo((object)"Character.m_run not found, using Character.IsRunning() instead."); } else { Log.LogWarning((object)"Could not find Character.m_run or IsRunning(); shallow-water sprint fix disabled."); } } private void PatchRunSpeed() { MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(Player), "GetRunSpeedFactor", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Character), "GetRunSpeedFactor", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo.ReturnType != typeof(float)) { Log.LogError((object)"GetRunSpeedFactor not found on this Valheim build. Run speed cannot be changed."); } else { TryPatch(methodInfo, null, "RunSpeedPostfix"); } } private static void RunSpeedPostfix(Character __instance, ref float __result) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { __result *= GetEffectiveMultiplier(); } } private void PatchLiquidResistance() { ResolveSprintState(); if (s_mRun == null && s_isRunning == null) { return; } MethodInfo methodInfo = AccessTools.Method(typeof(Character), "ApplyLiquidResistance", (Type[])null, (Type[])null); if (methodInfo == null) { Log.LogWarning((object)"Character.ApplyLiquidResistance not found; shallow-water sprint fix disabled."); return; } ParameterInfo[] parameters = methodInfo.GetParameters(); bool flag = parameters.Length != 0 && (parameters[0].ParameterType == typeof(float) || parameters[0].ParameterType == typeof(float).MakeByRefType()); if (methodInfo.ReturnType == typeof(void)) { TryPatch(methodInfo, "LiquidPrefixVoid"); } else if (methodInfo.ReturnType == typeof(float) && flag) { TryPatch(methodInfo, "LiquidPrefixReturn"); } else { Log.LogWarning((object)("ApplyLiquidResistance has an unexpected signature (" + methodInfo?.ToString() + "); shallow-water sprint fix disabled.")); } } private static bool ShouldSkipLiquid(Character c) { Player val = (Player)(object)((c is Player) ? c : null); return val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && IsSprinting(c); } private static bool LiquidPrefixVoid(Character __instance) { return !ShouldSkipLiquid(__instance); } private static bool LiquidPrefixReturn(Character __instance, object[] __args, ref float __result) { if (!ShouldSkipLiquid(__instance)) { return true; } __result = (float)__args[0]; return false; } private void TryPatch(MethodInfo target, string? prefix = null, string? postfix = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) try { HarmonyMethod val = ((prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Run), prefix, (Type[])null)); HarmonyMethod val2 = ((postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Run), postfix, (Type[])null)); _harmony.Patch((MethodBase)target, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)("Patched " + target.DeclaringType?.Name + "." + target.Name)); } catch (Exception ex) { Log.LogError((object)("Failed to patch " + target.DeclaringType?.Name + "." + target.Name + ": " + ex)); } } } }