using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Extensions; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SpeedyPathsPresets")] [assembly: AssemblyDescription("Preset switcher for the Valheim SpeedyPaths mod.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("gisanka")] [assembly: AssemblyProduct("SpeedyPathsPresets")] [assembly: AssemblyCopyright("Copyright © 2026 gisanka")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("0.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] namespace SpeedyPathsPresets; [BepInPlugin("maxime.SpeedyPathsPresets", "SpeedyPaths Preset Switcher", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class SpeedyPathsPresets : BaseUnityPlugin { private class PresetConfig { public string Name; public ConfigEntry UseGlobalValues; public ConfigEntry SpeedModifierGlobal; public ConfigEntry StaminaModifierGlobal; } public const string PluginGUID = "maxime.SpeedyPathsPresets"; public const string PluginName = "SpeedyPaths Preset Switcher"; public const string PluginVersion = "0.1.0"; private const string SpeedyPathsGuid = "nex.SpeedyPaths"; private ConfigFile _speedyPathsConfig; private static readonly string[] SpeedyPathsValueSections = new string[4] { "SpeedModifiers", "StaminaModifiers", "SpeedModifiers_Biomes", "StaminaModifiers_Biomes" }; private ConfigEntry _toggleKey; private ConfigEntry _presetNames; private ConfigEntry _generatePresetConfigs; private string[] _presets; private int _currentPreset; private Harmony _harmony; internal static SpeedyPathsPresets Instance; private readonly Dictionary _presetConfigs = new Dictionary(); private void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) Instance = this; _harmony = new Harmony("maxime.SpeedyPathsPresets"); _harmony.PatchAll(); _toggleKey = ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, "General", "ToggleKey", new KeyboardShortcut((KeyCode)285, Array.Empty()), "Key used to switch to the next SpeedyPaths preset.", false, true, true, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); _presetNames = ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, "Presets", "PresetNames", "Default,FastTravel", "Comma-separated list of preset names.", false, true, true, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); _generatePresetConfigs = ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, "Presets", "GeneratePresetConfigs", false, "I changed the preset list, please generate configuration options (button will reset automatically when ingame, please reopen configuration manager window or run game once)", false, true, true, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); _generatePresetConfigs.SettingChanged += delegate { if (_generatePresetConfigs.Value) { CreatePresetConfigs(); _generatePresetConfigs.Value = false; Logger.LogInfo((object)"Preset configuration options regenerated."); } }; BaseUnityPlugin speedyPathsPlugin = GetSpeedyPathsPlugin(); if ((Object)(object)speedyPathsPlugin != (Object)null) { _speedyPathsConfig = speedyPathsPlugin.Config; Logger.LogInfo((object)("Found " + speedyPathsPlugin.Info.Metadata.Name)); } CreatePresetConfigs(); Logger.LogInfo((object)"SpeedyPaths Configuration Switcher has loaded"); } private void ApplyPresetByIndex(int presetIndex) { if (_presets == null || _presets.Length == 0) { return; } if (presetIndex < 0 || presetIndex >= _presets.Length) { Logger.LogWarning((object)$"Invalid preset index: {presetIndex}"); return; } string text = _presets[presetIndex].Trim(); if (!_presetConfigs.TryGetValue(text, out var value)) { Logger.LogWarning((object)("No config found for preset: " + text)); return; } if (value.UseGlobalValues.Value) { ApplyGlobalPreset(value.SpeedModifierGlobal.Value, value.StaminaModifierGlobal.Value); } else { ApplyDetailedPreset(value); } MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)1, "SpeedyPaths Preset: " + text, 0, (Sprite)null, false); } Logger.LogInfo((object)("Applied preset: " + text)); } private void ApplyGlobalPreset(float speedModifier, float staminaModifier) { if (IsSpeedyPathsConfigAvailable()) { SetAllSpeedyPathsValuesInSection(_speedyPathsConfig, "SpeedModifiers", speedModifier); SetAllSpeedyPathsValuesInSection(_speedyPathsConfig, "StaminaModifiers", staminaModifier); SetAllSpeedyPathsValuesInSection(_speedyPathsConfig, "SpeedModifiers_Biomes", speedModifier); SetAllSpeedyPathsValuesInSection(_speedyPathsConfig, "StaminaModifiers_Biomes", staminaModifier); Logger.LogInfo((object)$"Applied global preset to SpeedyPaths: Speed={speedModifier}, Stamina={staminaModifier}"); } } private void SetAllSpeedyPathsValuesInSection(ConfigFile config, string section, float value) { foreach (ConfigDefinition key in config.Keys) { if (!(key.Section != section)) { SetSpeedyPathsValue(config, key.Section, key.Key, value); } } } private void ApplyDetailedPreset(PresetConfig presetConfig) { if (IsSpeedyPathsConfigAvailable()) { string section = ((ConfigEntryBase)presetConfig.UseGlobalValues).Definition.Section; string[] speedyPathsValueSections = SpeedyPathsValueSections; foreach (string sourceSection in speedyPathsValueSections) { ApplyDetailedPresetSection(section, _speedyPathsConfig, sourceSection); } Logger.LogInfo((object)("Applied detailed preset to SpeedyPaths: " + presetConfig.Name)); } } private void ApplyDetailedPresetSection(string presetSection, ConfigFile speedyPathsConfig, string sourceSection) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown ConfigEntry val2 = default(ConfigEntry); foreach (ConfigDefinition key in speedyPathsConfig.Keys) { if (!(key.Section != sourceSection)) { ConfigDefinition val = new ConfigDefinition(presetSection, key.Key); if (!((BaseUnityPlugin)this).Config.TryGetEntry(val, ref val2)) { Logger.LogWarning((object)("Could not find preset config value: [" + presetSection + "] " + key.Key)); } else { SetSpeedyPathsValue(speedyPathsConfig, key.Section, key.Key, val2.Value); } } } } private void SetSpeedyPathsValue(ConfigFile config, string section, string key, float value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ConfigDefinition val = new ConfigDefinition(section, key); ConfigEntry val2 = default(ConfigEntry); if (!config.TryGetEntry(val, ref val2)) { Logger.LogWarning((object)("Could not find SpeedyPaths config value: [" + section + "] " + key)); } else { val2.Value = value; } } private void CreatePresetConfigs() { _presets = _presetNames.Value.Split(new char[1] { ',' }); string[] presets = _presets; for (int i = 0; i < presets.Length; i++) { string text = presets[i].Trim(); if (string.IsNullOrWhiteSpace(text)) { continue; } string text2 = "Preset: " + text; bool flag = text.Equals("FastTravel", StringComparison.OrdinalIgnoreCase); float num = (flag ? 3f : 1f); float num2 = (flag ? 0.1f : 1f); if (!_presetConfigs.TryGetValue(text, out var value)) { value = new PresetConfig { Name = text, UseGlobalValues = ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, text2, "SetAllValuesToSameLevel", flag, "Set all SpeedyPaths speed and stamina values in this preset to the same level. (ignore detailed settings)", false, true, true, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null), SpeedModifierGlobal = ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, text2, "SpeedModifier_Global", num, "Global speed modifier for this preset.", false, true, true, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null), StaminaModifierGlobal = ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, text2, "StaminaModifier_Global", num2, "Global stamina modifier for this preset.", false, true, true, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null) }; _presetConfigs[text] = value; } if (IsSpeedyPathsConfigAvailable()) { string[] speedyPathsValueSections = SpeedyPathsValueSections; foreach (string sourceSection in speedyPathsValueSections) { CreatePresetValuesFromSpeedyPaths(value, _speedyPathsConfig, sourceSection, text2); } } } } private void CreatePresetValuesFromSpeedyPaths(PresetConfig presetConfig, ConfigFile speedyPathsConfig, string sourceSection, string section) { ConfigEntry val = default(ConfigEntry); foreach (ConfigDefinition key in speedyPathsConfig.Keys) { if (!(key.Section != sourceSection) && speedyPathsConfig.TryGetEntry(key, ref val)) { ConfigFileExtensions.BindConfigInOrder(((BaseUnityPlugin)this).Config, section, key.Key, (float)((ConfigEntryBase)val).DefaultValue, ((ConfigEntryBase)val).Description.Description, false, true, true, (AcceptableValueBase)null, (Action)null, (ConfigurationManagerAttributes)null); } } } private BaseUnityPlugin GetSpeedyPathsPlugin() { if (!Chainloader.PluginInfos.TryGetValue("nex.SpeedyPaths", out var value)) { Logger.LogWarning((object)"SpeedyPaths plugin not found."); return null; } return value.Instance; } private bool IsSpeedyPathsConfigAvailable() { if (_speedyPathsConfig != null) { return true; } Logger.LogWarning((object)"SpeedyPaths config is not available."); return false; } private void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = _toggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _currentPreset++; if (_currentPreset >= _presets.Length) { _currentPreset = 0; } ApplyPresetByIndex(_currentPreset); } } internal void ApplyDefaultPreset() { _currentPreset = 0; ApplyPresetByIndex(_currentPreset); } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class Player_OnSpawned_Patch { private static void Postfix() { SpeedyPathsPresets.Instance?.ApplyDefaultPreset(); } }