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 BetterStamina v1.5.7
BetterStamina.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BetterStamina.Config; using BetterStamina.Patches; using GameNetcodeStuff; using HarmonyLib; using Unity.Collections; using Unity.Netcode; 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("BetterStamina")] [assembly: AssemblyDescription("Mod made by flipf17")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BetterStamina")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1c42022e-b386-4342-baf0-67de1b7529e2")] [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 BetterStamina { [BepInPlugin("FlipMods.BetterStamina", "BetterStamina", "1.5.7")] public class Plugin : BaseUnityPlugin { private Harmony _harmony; public static Plugin instance; private static ManualLogSource logger; private void Awake() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown instance = this; CreateCustomLogger(); ConfigSettings.BindConfigSettings(); _harmony = new Harmony("BetterStamina"); PatchAll(); Log("BetterStamina loaded"); } private void PatchAll() { IEnumerable<Type> enumerable; try { enumerable = Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException ex) { enumerable = ex.Types.Where((Type t) => t != null); } foreach (Type item in enumerable) { _harmony.PatchAll(item); } } private void CreateCustomLogger() { try { logger = Logger.CreateLogSource(string.Format("{0}-{1}", "BetterStamina", "1.5.7")); } catch { logger = ((BaseUnityPlugin)this).Logger; } } public static void Log(string message) { logger.LogInfo((object)message); } public static void LogError(string message) { logger.LogError((object)message); } public static void LogWarning(string message) { logger.LogWarning((object)message); } public static bool IsModLoaded(string guid) { return Chainloader.PluginInfos.ContainsKey(guid); } } public static class PluginInfo { public const string PLUGIN_GUID = "FlipMods.BetterStamina"; public const string PLUGIN_NAME = "BetterStamina"; public const string PLUGIN_VERSION = "1.5.7"; } } namespace BetterStamina.Patches { [HarmonyPatch] public static class PlayerSpeedPatch { private static float defaultMovementSpeed = -1f; private static float defaultCrouchSpeed = 0.6666666f; private static float defaultSprintSpeed = 2.25f; private static float defaultLimpMultiplier = -1f; private static float defaultClimbSpeed = -1f; private static float defaultJumpForce = 5f; private static Dictionary<PlayerControllerB, float> previousPlayerMovementSpeeds = new Dictionary<PlayerControllerB, float>(); private static Dictionary<PlayerControllerB, float> previousPlayerClimbSpeeds = new Dictionary<PlayerControllerB, float>(); private static PlayerControllerB localPlayerController => StartOfRound.Instance?.localPlayerController; internal static void OnSyncedWithHost() { PatchLocalPlayerController(); } private static void PatchLocalPlayerController() { if (Object.op_Implicit((Object)(object)localPlayerController)) { float num = ConfigSync.instance.jumpForceMultiplier; if (localPlayerController.drunkness > 0f) { num *= ConfigSync.instance.drunkJumpForceMultiplier; } PlayerControllerB obj = localPlayerController; obj.jumpForce *= Mathf.Pow(num, 0.55f); } } [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] private static void Init() { previousPlayerMovementSpeeds?.Clear(); previousPlayerClimbSpeeds?.Clear(); } [HarmonyPatch(typeof(PlayerControllerB), "Start")] [HarmonyPostfix] private static void InitPlayer(PlayerControllerB __instance) { if (ConfigSync.isSynced && (Object)(object)__instance == (Object)(object)localPlayerController) { PatchLocalPlayerController(); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPrefix] private static void UpdatePrefix(ref bool ___isPlayerControlled, ref bool ___isWalking, ref bool ___isCrouching, ref bool ___isSprinting, ref bool ___isClimbingLadder, ref bool ___isInsideFactory, ref float ___movementSpeed, ref float ___sprintMultiplier, ref float ___climbSpeed, ref float ___drunkness, PlayerControllerB __instance) { previousPlayerMovementSpeeds[__instance] = ___movementSpeed; previousPlayerClimbSpeeds[__instance] = ___climbSpeed; if (!___isPlayerControlled || !ConfigSync.isSynced) { return; } ___movementSpeed *= ConfigSync.instance.walkSpeedMultiplier; if (___isCrouching) { ___movementSpeed *= ConfigSync.instance.crouchSpeedMultiplier / defaultCrouchSpeed; } ___movementSpeed *= (___isInsideFactory ? ConfigSync.instance.speedMultiplierInsideFactory : ConfigSync.instance.speedMultiplierOutsideFactory); ___climbSpeed *= ConfigSync.instance.ladderClimbSpeedMultiplier; if (___isClimbingLadder & ___isSprinting) { ___climbSpeed *= ConfigSync.instance.ladderSprintSpeedMultiplier; } if (___drunkness > 0f) { ___movementSpeed *= ConfigSync.instance.drunkSpeedMultiplier; ___climbSpeed *= ConfigSync.instance.drunkSpeedMultiplier; } if ((Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController) { float num = Mathf.Max((ConfigSync.instance.sprintSpeedMultiplier - defaultSprintSpeed) / defaultSprintSpeed, 0f); if (___isSprinting) { ___sprintMultiplier = Mathf.Lerp(___sprintMultiplier, ConfigSync.instance.sprintSpeedMultiplier, Time.deltaTime * num * 0.5f); } else if (!___isWalking) { ___sprintMultiplier = (ConfigSync.instance.enableInstantSprinting ? 1f : Mathf.Lerp(___sprintMultiplier, 1f, Time.deltaTime * 10f * (1f + num * 0.1f))); } else { ___sprintMultiplier = (ConfigSync.instance.enableInstantSprinting ? 1f : Mathf.Lerp(___sprintMultiplier, 1f, Time.deltaTime * 10f * num * 0.1f)); } } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void UpdatePostfix(ref float ___movementSpeed, ref float ___climbSpeed, PlayerControllerB __instance) { if (ConfigSync.isSynced && previousPlayerMovementSpeeds.ContainsKey(__instance)) { ___movementSpeed = previousPlayerMovementSpeeds[__instance]; ___climbSpeed = previousPlayerClimbSpeeds[__instance]; } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> SpoofSprintMultiplierUpdate(IEnumerable<CodeInstruction> instructions) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo method = typeof(PlayerSpeedPatch).GetMethod("GetAdjustedSprintMultiplier", BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && list[i].operand is float num && num == defaultSprintSpeed) { list[i] = new CodeInstruction(OpCodes.Call, (object)method); } } return list.AsEnumerable(); } public static float GetAdjustedSprintMultiplier() { if ((Object)(object)StartOfRound.Instance?.localPlayerController == (Object)null || !ConfigSync.isSynced) { return defaultSprintSpeed; } return ConfigSync.instance.sprintSpeedMultiplier; } } [HarmonyPatch(typeof(PlayerControllerB))] public static class PlayerWeightPenaltyPatch { [HarmonyPatch("Update")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> SpoofWeightValuesUpdate(IEnumerable<CodeInstruction> instructions) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown if (Plugin.IsModLoaded("com.malco.lethalcompany.moreshipupgrades")) { return instructions; } bool flag = false; List<CodeInstruction> list = new List<CodeInstruction>(instructions); FieldInfo field = typeof(PlayerControllerB).GetField("carryWeight", BindingFlags.Instance | BindingFlags.Public); MethodInfo method = typeof(PlayerWeightPenaltyPatch).GetMethod("GetAdjustedWeight", BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == field) { list[i] = new CodeInstruction(OpCodes.Call, (object)method); list.RemoveAt(i - 1); flag = true; } } if (!flag) { Plugin.LogError("Failed to apply Transpiler patch on PlayerControllerB.Update. Modified carry weight penalty may not work as intended."); } return list.AsEnumerable(); } [HarmonyPatch("LateUpdate")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> SpoofWeightValuesLateUpdate(IEnumerable<CodeInstruction> instructions) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown if (Plugin.IsModLoaded("com.malco.lethalcompany.moreshipupgrades")) { return instructions; } bool flag = false; List<CodeInstruction> list = new List<CodeInstruction>(instructions); FieldInfo field = typeof(PlayerControllerB).GetField("carryWeight", BindingFlags.Instance | BindingFlags.Public); MethodInfo method = typeof(PlayerWeightPenaltyPatch).GetMethod("GetAdjustedWeight", BindingFlags.Static | BindingFlags.Public); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == field) { list[i] = new CodeInstruction(OpCodes.Call, (object)method); list.RemoveAt(i - 1); flag = true; } } if (!flag) { Plugin.LogError("Failed to apply Transpiler patch on PlayerControllerB.LateUpdate. Modified carry weight penalty may not work as intended."); } return list.AsEnumerable(); } public static float GetAdjustedWeight() { if ((Object)(object)StartOfRound.Instance?.localPlayerController == (Object)null) { return 1f; } float num = StartOfRound.Instance.localPlayerController.carryWeight - 1f; return num * ConfigSync.instance.carryWeightPenaltyMultiplier + 1f; } } [HarmonyPatch(typeof(PlayerControllerB))] public static class PlayerStaminaPatch { private static float previousSprintMeter; [HarmonyPatch("LateUpdate")] [HarmonyPrefix] private static void LateUpdatePrefix(ref bool ___isPlayerControlled, ref float ___sprintMeter, PlayerControllerB __instance) { if (___isPlayerControlled && (Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController) { previousSprintMeter = ___sprintMeter; } } [HarmonyPatch("LateUpdate")] [HarmonyPostfix] private static void LateUpdatePostfix(ref bool ___isPlayerControlled, ref bool ___isWalking, ref bool ___isCrouching, ref bool ___isSprinting, ref bool ___isClimbingLadder, ref bool ___isInsideFactory, ref float ___sprintMeter, ref float ___drunkness, PlayerControllerB __instance) { if (!((ConfigSync.isSynced && (Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController) & ___isPlayerControlled)) { return; } float num = 1f; float num2 = ___sprintMeter - previousSprintMeter; if (num2 < 0f) { if (___isSprinting) { num *= ConfigSync.instance.sprintStaminaConsumptionMultiplier; } if (___drunkness > 0f) { num *= ConfigSync.instance.drunkStaminaConsumptionMultiplier; } num *= (___isInsideFactory ? ConfigSync.instance.staminaRegenMultiplierInsideFactory : ConfigSync.instance.staminaRegenMultiplierOutsideFactory); } else if (num2 > 0f) { num *= ((!___isWalking && !___isSprinting && !___isClimbingLadder) ? ConfigSync.instance.idleStaminaRegenMultiplier : ConfigSync.instance.walkStaminaRegenMultiplier); if (___isCrouching) { num *= ConfigSync.instance.crouchStaminaRegenMultiplier; } if (___drunkness > 0f) { num *= ConfigSync.instance.drunkStaminaRegenMultiplier; } num *= (___isInsideFactory ? ConfigSync.instance.staminaConsumptionMultiplierInsideFactory : ConfigSync.instance.staminaConsumptionMultiplierOutsideFactory); } if (num != 1f) { ___sprintMeter = Mathf.Clamp(previousSprintMeter + num2 * num, 0f, 1f); } } [HarmonyPatch("Jump_performed")] [HarmonyPrefix] private static void JumpPerformedPrefix(ref bool ___isPlayerControlled, ref float ___sprintMeter, PlayerControllerB __instance) { if (((Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController) & ___isPlayerControlled) { previousSprintMeter = ___sprintMeter; } else { previousSprintMeter = -1f; } } [HarmonyPatch("Jump_performed")] [HarmonyPostfix] private static void JumpPerformedPostfix(ref bool ___isPlayerControlled, ref bool ___isInsideFactory, ref float ___sprintMeter, ref float ___drunkness, PlayerControllerB __instance) { if (!((ConfigSync.isSynced && (Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController) & ___isPlayerControlled) || !(previousSprintMeter >= 0f)) { return; } float num = ___sprintMeter - previousSprintMeter; if (num < 0f) { float num2 = ConfigSync.instance.jumpStaminaConsumptionMultiplier; if (___drunkness > 0f) { num2 *= ConfigSync.instance.drunkStaminaConsumptionMultiplier; } num2 *= (___isInsideFactory ? ConfigSync.instance.staminaConsumptionMultiplierInsideFactory : ConfigSync.instance.staminaConsumptionMultiplierOutsideFactory); if (num2 != 1f) { ___sprintMeter = Mathf.Max(previousSprintMeter + num * num2, 0f); } } } } } namespace BetterStamina.Config { [Serializable] public static class ConfigSettings { public static ConfigEntry<float> carryWeightPenaltyMultiplierConfig; public static ConfigEntry<float> idleStaminaRegenMultiplierConfig; public static ConfigEntry<float> walkStaminaRegenMultiplierConfig; public static ConfigEntry<float> crouchStaminaRegenMultiplierConfig; public static ConfigEntry<float> drunkStaminaRegenMultiplierConfig; public static ConfigEntry<float> sprintStaminaConsumptionMultiplierConfig; public static ConfigEntry<float> jumpStaminaConsumptionMultiplierConfig; public static ConfigEntry<float> drunkStaminaConsumptionMultiplierConfig; public static ConfigEntry<float> walkSpeedMultiplierConfig; public static ConfigEntry<float> crouchSpeedMultiplierConfig; public static ConfigEntry<float> sprintSpeedMultiplierConfig; public static ConfigEntry<float> limpSpeedMultiplierConfig; public static ConfigEntry<float> ladderClimbSpeedMultiplierConfig; public static ConfigEntry<float> ladderSprintSpeedMultiplierConfig; public static ConfigEntry<float> drunkSpeedMultiplierConfig; public static ConfigEntry<bool> enableInstantSprintingConfig; public static ConfigEntry<float> jumpForceMultiplierConfig; public static ConfigEntry<float> drunkJumpForceMultiplierConfig; public static ConfigEntry<float> staminaRegenMultiplierInsideFactoryConfig; public static ConfigEntry<float> staminaRegenMultiplierOutsideFactoryConfig; public static ConfigEntry<float> staminaConsumptionMultiplierInsideFactoryConfig; public static ConfigEntry<float> staminaConsumptionMultiplierOutsideFactoryConfig; public static ConfigEntry<float> speedMultiplierInsideFactoryConfig; public static ConfigEntry<float> speedMultiplierOutsideFactoryConfig; public static Dictionary<string, ConfigEntryBase> currentConfigEntries = new Dictionary<string, ConfigEntryBase>(); public static List<ConfigEntryBase> configEntries = new List<ConfigEntryBase>(); public static void BindConfigSettings() { Plugin.Log("Binding Configs"); carryWeightPenaltyMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("CarryWeight", "CarryWeightPenaltyMultiplier", 0.5f, "[Host-only] Multiplier for how much your speed/stamina consumption are affected by weight. (Lower is better/forgiving)")); idleStaminaRegenMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Stamina Regen", "IdleStaminaRegenMultiplier", 1.4f, "[Host-only] Multiplier for how fast your stamina regens while idle.")); walkStaminaRegenMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Stamina Regen", "WalkStaminaRegenMultiplier", 1.25f, "[Host-only] Multiplier for how fast your stamina regens while walking.")); crouchStaminaRegenMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Stamina Regen", "CrouchStaminaRegenMultiplier", 1.2f, "[Host-only] Multiplier for how fast your stamina regens while crouching.\nThis will be applied on top of other stamina regen modifiers.\nExample multiplier while crouching and idle: 1.4 * 1.25 = 1.75")); drunkStaminaRegenMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Stamina Regen", "DrunkStaminaRegenMultiplier", 1f, "[Host-only] Multiplier for how fast your stamina regens while drunk.\nThis will be applied on top of other stamina regen modifiers.")); sprintStaminaConsumptionMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Stamina Consumption", "SprintStaminaConsumptionMultiplier", 0.75f, "[Host-only] Multiplier for how much stamina drains while sprinting.")); jumpStaminaConsumptionMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Stamina Consumption", "JumpStaminaConsumptionMultiplier", 0.75f, "[Host-only] Multiplier for how much stamina jumping consumes.")); drunkStaminaConsumptionMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Stamina Consumption", "DrunkStaminaConsumptionMultiplier", 1f, "[Host-only] Multiplier for how much stamina drains while drunk.\nThis will be applied on top of other stamina consumption modifiers.")); walkSpeedMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Movement Speed", "WalkSpeedMultiplier", 1f, "[Host-only] Movement speed multiplier while walking.\nThis modifier will ultimately affect crouching, sprinting, and limping speed.")); crouchSpeedMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Movement Speed", "CrouchSpeedMultiplier", 0.66f, "[Host-only] Movement speed multiplier while crouching.\nVanilla default: ~0.66")); sprintSpeedMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Movement Speed", "SprintSpeedMultiplier", 2.25f, "[Host-only] Movement speed multiplier while sprinting.\nVanilla default: 2.25")); limpSpeedMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Movement Speed", "LimpSpeedMultiplier", 0.2f, "[Host-only] Movement speed multiplier while limping.\nVanilla default: 0.2")); ladderClimbSpeedMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Movement Speed", "LadderClimbSpeedMultiplier", 1f, "[Host-only] Player speed multiplier while climbing ladders.")); ladderSprintSpeedMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Movement Speed", "LadderClimbSprintSpeedMultiplier", 1.5f, "[Host-only] Player sprint speed multiplier while climbing on ladders.\nSet this value to 1 if the vanilla game ever decides to implement this. This will avoid applied multiple sprint speed modifiers.")); drunkSpeedMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Movement Speed", "DrunkSpeedMultiplier", 1f, "[Host-only] Movement speed multiplier while drunk.\nThis will be applied on top of other speed modifiers.")); enableInstantSprintingConfig = AddConfigEntry<bool>(((BaseUnityPlugin)Plugin.instance).Config.Bind<bool>("Movement Speed", "EnableInstantSprinting", false, "[Host-only] If true, sprinting to max speed will be instant, rather than a build up in speed over time.")); jumpForceMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Jumping", "JumpForceMultiplier", 1f, "[Host-only] Player jump force multiplier.\nNOTE: Jump force may might represent jump height perfectly due to how Unity's force physics work.\nNOTE: You may take fall damage if this value is set too high.")); drunkJumpForceMultiplierConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Jumping", "DrunkJumpForceMultiplier", 1f, "[Host-only] Player jump height multiplier while drunk.\nThis will be applied on top of other jump force modifiers.")); staminaRegenMultiplierInsideFactoryConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Factory", "StaminaRegenMultiplierInsideFactory", 1f, "[Host-only] Multiplier for stamina regen while inside the factory/dungeon.\nThis will be applied on top of other stamina regen modifiers.")); staminaRegenMultiplierOutsideFactoryConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Factory", "StaminaRegenMultiplierOutsideFactory", 1f, "[Host-only] Multiplier for stamina regen while outside the factory/dungeon.\nThis will be applied on top of other stamina regen modifiers.")); staminaConsumptionMultiplierInsideFactoryConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Factory", "SprintStaminaConsumptionInsideFactory", 1f, "[Host-only] Multiplier for sprinting stamina consumption while inside the factory/dungeon.\nThis will be applied on top of other stamina consumption modifiers.")); staminaConsumptionMultiplierOutsideFactoryConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Factory", "SprintStaminaConsumptionOutsideFactory", 1f, "[Host-only] Multiplier for sprinting stamina consumption while outside the factory/dungeon.\nThis will be applied on top of other stamina consumption modifiers.")); speedMultiplierInsideFactoryConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Factory", "SpeedMultiplierInsideFactory", 1f, "[Host-only] Movement speed multiplier while inside the factory/dungeon.\nThis will be applied on top of other speed modifiers.")); speedMultiplierOutsideFactoryConfig = AddConfigEntry<float>(((BaseUnityPlugin)Plugin.instance).Config.Bind<float>("Factory", "SpeedMultiplierOutsideFactory", 1f, "[Host-only] Movement speed multiplier while outside the factory/dungeon.\nThis will be applied on top of other speed modifiers.")); crouchSpeedMultiplierConfig.Value = Mathf.Clamp(crouchSpeedMultiplierConfig.Value, 0f, 1f); sprintSpeedMultiplierConfig.Value = Mathf.Max(sprintSpeedMultiplierConfig.Value, 1f); limpSpeedMultiplierConfig.Value = Mathf.Clamp(limpSpeedMultiplierConfig.Value, 0f, 1f); TryRemoveOldConfigSettings(); } public static ConfigEntry<T> AddConfigEntry<T>(ConfigEntry<T> configEntry) { currentConfigEntries.Add(((ConfigEntryBase)configEntry).Definition.Key, (ConfigEntryBase)(object)configEntry); return configEntry; } public static void TryRemoveOldConfigSettings() { HashSet<string> hashSet = new HashSet<string>(); HashSet<string> hashSet2 = new HashSet<string>(); foreach (ConfigEntryBase value in currentConfigEntries.Values) { hashSet.Add(value.Definition.Section); hashSet2.Add(value.Definition.Key); } try { ConfigFile config = ((BaseUnityPlugin)Plugin.instance).Config; string configFilePath = config.ConfigFilePath; if (!File.Exists(configFilePath)) { return; } string text = File.ReadAllText(configFilePath); string[] array = File.ReadAllLines(configFilePath); string text2 = ""; for (int i = 0; i < array.Length; i++) { array[i] = array[i].Replace("\n", ""); if (array[i].Length <= 0) { continue; } if (array[i].StartsWith("[")) { if (text2 != "" && !hashSet.Contains(text2)) { text2 = "[" + text2 + "]"; int num = text.IndexOf(text2); int num2 = text.IndexOf(array[i]); text = text.Remove(num, num2 - num); } text2 = array[i].Replace("[", "").Replace("]", "").Trim(); } else { if (!(text2 != "")) { continue; } if (i <= array.Length - 4 && array[i].StartsWith("##")) { int j; for (j = 1; i + j < array.Length && array[i + j].Length > 3; j++) { } if (hashSet.Contains(text2)) { int num3 = array[i + j - 1].IndexOf("="); string item = array[i + j - 1].Substring(0, num3 - 1); if (!hashSet2.Contains(item)) { int num4 = text.IndexOf(array[i]); int num5 = text.IndexOf(array[i + j - 1]) + array[i + j - 1].Length; text = text.Remove(num4, num5 - num4); } } i += j - 1; } else if (array[i].Length > 3) { text = text.Replace(array[i], ""); } } } if (!hashSet.Contains(text2)) { text2 = "[" + text2 + "]"; int num6 = text.IndexOf(text2); text = text.Remove(num6, text.Length - num6); } while (text.Contains("\n\n\n")) { text = text.Replace("\n\n\n", "\n\n"); } File.WriteAllText(configFilePath, text); config.Reload(); } catch { } } } [Serializable] [HarmonyPatch] public class ConfigSync { public static ConfigSync instance; public static PlayerControllerB localPlayerController; public static bool isSynced; public float carryWeightPenaltyMultiplier = 1f; public float idleStaminaRegenMultiplier = 1f; public float walkStaminaRegenMultiplier = 1f; public float crouchStaminaRegenMultiplier = 1f; public float drunkStaminaRegenMultiplier = 1f; public float staminaRegenMultiplierInsideFactory = 1f; public float staminaRegenMultiplierOutsideFactory = 1f; public float sprintStaminaConsumptionMultiplier = 1f; public float jumpStaminaConsumptionMultiplier = 1f; public float drunkStaminaConsumptionMultiplier = 1f; public float staminaConsumptionMultiplierInsideFactory = 1f; public float staminaConsumptionMultiplierOutsideFactory = 1f; public float walkSpeedMultiplier = 1f; public float crouchSpeedMultiplier = 0.6666666f; public float sprintSpeedMultiplier = 2.25f; public float limpSpeedMultiplier = 0.2f; public float ladderClimbSpeedMultiplier = 1f; public float ladderSprintSpeedMultiplier = 1f; public float drunkSpeedMultiplier = 1f; public bool enableInstantSprinting = false; public float speedMultiplierInsideFactory = 1f; public float speedMultiplierOutsideFactory = 1f; public float jumpForceMultiplier = 1f; public float drunkJumpForceMultiplier = 1f; public static void BuildDefaultConfigSync() { instance = new ConfigSync(); } public static void BuildServerConfigSync() { instance = new ConfigSync(); instance.carryWeightPenaltyMultiplier = Mathf.Max(ConfigSettings.carryWeightPenaltyMultiplierConfig.Value, 0f); instance.idleStaminaRegenMultiplier = Mathf.Max(ConfigSettings.idleStaminaRegenMultiplierConfig.Value, 0f); instance.walkStaminaRegenMultiplier = Mathf.Max(ConfigSettings.walkStaminaRegenMultiplierConfig.Value, 0f); instance.crouchStaminaRegenMultiplier = Mathf.Max(ConfigSettings.crouchStaminaRegenMultiplierConfig.Value, 0f); instance.drunkStaminaRegenMultiplier = Mathf.Max(ConfigSettings.drunkStaminaRegenMultiplierConfig.Value, 0f); instance.staminaRegenMultiplierInsideFactory = Mathf.Max(ConfigSettings.staminaRegenMultiplierInsideFactoryConfig.Value, 0f); instance.staminaRegenMultiplierOutsideFactory = Mathf.Max(ConfigSettings.staminaRegenMultiplierOutsideFactoryConfig.Value, 0f); instance.sprintStaminaConsumptionMultiplier = Mathf.Max(ConfigSettings.sprintStaminaConsumptionMultiplierConfig.Value, 0f); instance.jumpStaminaConsumptionMultiplier = Mathf.Max(ConfigSettings.jumpStaminaConsumptionMultiplierConfig.Value, 0f); instance.drunkStaminaConsumptionMultiplier = Mathf.Max(ConfigSettings.drunkStaminaConsumptionMultiplierConfig.Value, 0f); instance.staminaConsumptionMultiplierInsideFactory = Mathf.Max(ConfigSettings.staminaConsumptionMultiplierInsideFactoryConfig.Value, 0f); instance.staminaConsumptionMultiplierOutsideFactory = Mathf.Max(ConfigSettings.staminaConsumptionMultiplierOutsideFactoryConfig.Value, 0f); instance.walkSpeedMultiplier = Mathf.Max(ConfigSettings.walkSpeedMultiplierConfig.Value, 0.1f); instance.crouchSpeedMultiplier = Mathf.Clamp(ConfigSettings.crouchSpeedMultiplierConfig.Value, 0f, 1f); instance.sprintSpeedMultiplier = Mathf.Max(ConfigSettings.sprintSpeedMultiplierConfig.Value, 1f); instance.limpSpeedMultiplier = Mathf.Clamp(ConfigSettings.limpSpeedMultiplierConfig.Value, 0f, 1f); instance.ladderClimbSpeedMultiplier = Mathf.Max(ConfigSettings.ladderClimbSpeedMultiplierConfig.Value, 0f); instance.ladderSprintSpeedMultiplier = Mathf.Max(ConfigSettings.ladderSprintSpeedMultiplierConfig.Value, 1f); instance.drunkSpeedMultiplier = Mathf.Max(ConfigSettings.drunkSpeedMultiplierConfig.Value, 0f); instance.enableInstantSprinting = ConfigSettings.enableInstantSprintingConfig.Value; instance.speedMultiplierInsideFactory = Mathf.Max(ConfigSettings.speedMultiplierInsideFactoryConfig.Value, 0f); instance.speedMultiplierOutsideFactory = Mathf.Max(ConfigSettings.speedMultiplierOutsideFactoryConfig.Value, 0f); instance.jumpForceMultiplier = Mathf.Max(ConfigSettings.jumpForceMultiplierConfig.Value, 0f); instance.drunkJumpForceMultiplier = Mathf.Max(ConfigSettings.drunkJumpForceMultiplierConfig.Value, 0f); } [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] public static void ResetValues() { isSynced = false; BuildDefaultConfigSync(); } [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] [HarmonyPostfix] public static void InitializeLocalPlayer(PlayerControllerB __instance) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown localPlayerController = __instance; if (NetworkManager.Singleton.IsServer) { BuildServerConfigSync(); NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("BetterStamina-OnRequestConfigSync", new HandleNamedMessageDelegate(OnReceiveConfigSyncRequest)); OnLocalClientConfigSync(); } else { isSynced = false; NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler("BetterStamina-OnReceiveConfigSync", new HandleNamedMessageDelegate(OnReceiveConfigSync)); RequestConfigSync(); } } public static void RequestConfigSync() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsClient) { Plugin.Log("Sending config sync request to server."); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(4, (Allocator)2, -1); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("BetterStamina-OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); } else { Plugin.LogError("Failed to send config sync request."); } } public static void OnReceiveConfigSyncRequest(ulong clientId, FastBufferReader reader) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsServer) { Plugin.Log("Receiving config sync request from client with id: " + clientId + ". Sending config sync to client."); byte[] array = SerializeConfigToByteArray(instance); FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(array.Length + 4, (Allocator)2, -1); int num = array.Length; ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("BetterStamina-OnReceiveConfigSync", clientId, val, (NetworkDelivery)3); } } public static void OnReceiveConfigSync(ulong clientId, FastBufferReader reader) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (((FastBufferReader)(ref reader)).TryBeginRead(num)) { Plugin.Log("Receiving config sync from server."); byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); instance = DeserializeFromByteArray(data); OnLocalClientConfigSync(); } else { Plugin.LogError("Error receiving sync from server."); } } public static void OnLocalClientConfigSync() { isSynced = true; PlayerSpeedPatch.OnSyncedWithHost(); } public static byte[] SerializeConfigToByteArray(ConfigSync config) { BinaryFormatter binaryFormatter = new BinaryFormatter(); MemoryStream memoryStream = new MemoryStream(); binaryFormatter.Serialize(memoryStream, config); return memoryStream.ToArray(); } public static ConfigSync DeserializeFromByteArray(byte[] data) { MemoryStream serializationStream = new MemoryStream(data); BinaryFormatter binaryFormatter = new BinaryFormatter(); return (ConfigSync)binaryFormatter.Deserialize(serializationStream); } } }