using 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 UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SwimSpeed")] [assembly: AssemblyDescription("Adjust your Valheim swim speed in real-time with arrow keys.")] [assembly: AssemblyCompany("YouDied")] [assembly: AssemblyProduct("SwimSpeed")] [assembly: AssemblyCopyright("Copyright © YouDied 2024")] [assembly: ComVisible(false)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace SwimSpeed; [BepInPlugin("youdied.swimspeed", "SwimSpeed", "1.3.0")] [BepInProcess("valheim.exe")] public class SwimSpeedPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Character), "UpdateSwimming")] private static class Patch_UpdateSwimming { [HarmonyPrefix] private static void Prefix(Character __instance, out float __state) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { __state = -1f; return; } s_inSwimUpdate = true; __state = __instance.m_swimSpeed; __instance.m_swimSpeed *= GetEffectiveMultiplier(); } [HarmonyPostfix] private static void Postfix(Character __instance, float __state) { s_inSwimUpdate = false; if (!(__state < 0f)) { __instance.m_swimSpeed = __state; } } } [HarmonyPatch(typeof(Character), "Jump")] private static class Patch_Jump { [HarmonyPrefix] private static void Prefix(Character __instance, out float __state) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { __state = -1f; return; } __state = __instance.m_swimSpeed; float effectiveMultiplier = GetEffectiveMultiplier(); if (s_inSwimUpdate && effectiveMultiplier > 1f) { __instance.m_swimSpeed = __state / effectiveMultiplier; } } [HarmonyPostfix] private static void Postfix(Character __instance, float __state) { if (!(__state < 0f)) { __instance.m_swimSpeed = __state; } } } public const string PluginGUID = "youdied.swimspeed"; public const string PluginName = "SwimSpeed"; public const string PluginVersion = "1.3.0"; internal static ManualLogSource Log; private static ConfigEntry _cfgMinMultiplier; private static ConfigEntry _cfgMaxMultiplier; private static ConfigEntry _cfgStep; private static ConfigEntry _cfgCurrentMultiplier; private static ConfigEntry _cfgLudicrousEnabled; private static ConfigEntry _cfgLudicrousMultiplier; private static ConfigEntry _cfgKeyIncrease; private static ConfigEntry _cfgKeyDecrease; private static int s_multiplier = 1; internal static bool s_inSwimUpdate = false; private Harmony _harmony; private void Awake() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; _cfgMinMultiplier = ((BaseUnityPlugin)this).Config.Bind("Speed Range", "MinimumMultiplier", 1, new ConfigDescription("Lowest swim speed multiplier allowed (1 = default game speed).", (AcceptableValueBase)(object)new AcceptableValueRange(1, 10), Array.Empty())); _cfgMaxMultiplier = ((BaseUnityPlugin)this).Config.Bind("Speed Range", "MaximumMultiplier", 5, new ConfigDescription("Highest swim speed multiplier reachable with arrow keys (up to 10).", (AcceptableValueBase)(object)new AcceptableValueRange(1, 10), Array.Empty())); _cfgStep = ((BaseUnityPlugin)this).Config.Bind("Speed Range", "AdjustmentPercent", 20, new ConfigDescription("How much each arrow key press changes speed, as a percentage of MaximumMultiplier. e.g. 20% with max=5 moves 1 per press; 20% with max=10 moves 2 per press.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100), Array.Empty())); _cfgCurrentMultiplier = ((BaseUnityPlugin)this).Config.Bind("Current Speed", "CurrentMultiplier", 1, new ConfigDescription("Your last-used swim speed multiplier. Updated automatically in-game.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 10), Array.Empty())); _cfgLudicrousEnabled = ((BaseUnityPlugin)this).Config.Bind("Ludicrous Speed", "LudicrousEnabled", false, "Set to true to enable Ludicrous Speed. All swim speeds are further multiplied by LudicrousMultiplier. Edit this file and restart to toggle."); _cfgLudicrousMultiplier = ((BaseUnityPlugin)this).Config.Bind("Ludicrous Speed", "LudicrousMultiplier", 10, new ConfigDescription("Extra speed factor on top of normal multiplier when Ludicrous Speed is on. Try 4-5 before going higher.", (AcceptableValueBase)(object)new AcceptableValueRange(2, 20), Array.Empty())); _cfgKeyIncrease = ((BaseUnityPlugin)this).Config.Bind("Keybinds", "IncreaseSpeed", (KeyCode)275, "Key to increase swim speed by one step."); _cfgKeyDecrease = ((BaseUnityPlugin)this).Config.Bind("Keybinds", "DecreaseSpeed", (KeyCode)276, "Key to decrease swim speed by one step."); s_multiplier = Mathf.Clamp(_cfgCurrentMultiplier.Value, GetMin(), GetMax()); _harmony = new Harmony("youdied.swimspeed"); _harmony.PatchAll(); Log.LogInfo((object)"SwimSpeed v1.3.0 loaded."); Log.LogInfo((object)(" Speed range : " + GetMin() + "x – " + GetMax() + "x")); Log.LogInfo((object)(" Step : " + _cfgStep.Value + "%")); Log.LogInfo((object)(" Current : " + s_multiplier + "x")); Log.LogInfo((object)(" Ludicrous : " + (_cfgLudicrousEnabled.Value ? ("ON (x" + _cfgLudicrousMultiplier.Value + ")") : "off"))); ManualLogSource log = Log; KeyCode value = _cfgKeyIncrease.Value; log.LogInfo((object)(" Increase : " + ((object)(KeyCode)(ref value)).ToString())); ManualLogSource log2 = Log; value = _cfgKeyDecrease.Value; log2.LogInfo((object)(" Decrease : " + ((object)(KeyCode)(ref value)).ToString())); } private void Update() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || InventoryGui.IsVisible() || Menu.IsVisible()) { return; } int step = GetStep(); bool flag = false; if (Input.GetKeyDown(_cfgKeyIncrease.Value)) { s_multiplier = Mathf.Min(s_multiplier + step, GetMax()); flag = true; } else if (Input.GetKeyDown(_cfgKeyDecrease.Value)) { s_multiplier = Mathf.Max(s_multiplier - step, GetMin()); flag = true; } if (flag) { _cfgCurrentMultiplier.Value = s_multiplier; string text = ((s_multiplier <= GetMin()) ? " (min)" : ((s_multiplier >= GetMax()) ? " (max)" : "")); string text2 = "Swim Speed: " + s_multiplier + "x" + text; if (_cfgLudicrousEnabled.Value) { text2 = text2 + " [LUDICROUS x" + _cfgLudicrousMultiplier.Value + "]"; } ((Character)Player.m_localPlayer).Message((MessageType)1, text2, 0, (Sprite)null); Log.LogInfo((object)("Swim speed -> " + s_multiplier + "x")); } } private static int GetMin() { return Mathf.Max(1, _cfgMinMultiplier.Value); } private static int GetMax() { return Mathf.Clamp(_cfgMaxMultiplier.Value, GetMin(), 10); } private static int GetStep() { int num = Mathf.RoundToInt((float)_cfgStep.Value / 100f * (float)GetMax()); return Mathf.Max(1, num); } internal static float GetEffectiveMultiplier() { if (!_cfgLudicrousEnabled.Value) { return s_multiplier; } return s_multiplier * Mathf.Max(2, _cfgLudicrousMultiplier.Value); } private void OnDestroy() { _harmony.UnpatchSelf(); } }