Decompiled source of BetterStamina v1.5.4

BetterStamina.dll

Decompiled 2 months ago
using 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.Configuration;
using BepInEx.Logging;
using BetterStamina.Config;
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.4")]
	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.4"));
			}
			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 class PluginInfo
	{
		public const string PLUGIN_GUID = "FlipMods.BetterStamina";

		public const string PLUGIN_NAME = "BetterStamina";

		public const string PLUGIN_VERSION = "1.5.4";
	}
}
namespace BetterStamina.Patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	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 = -1f;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void InitializeDefaultValues(ref float ___movementSpeed, ref float ___limpMultiplier, ref float ___climbSpeed, ref float ___jumpForce)
		{
			if (defaultMovementSpeed <= 0f)
			{
				defaultMovementSpeed = ___movementSpeed;
			}
			if (defaultLimpMultiplier <= 0f)
			{
				defaultLimpMultiplier = ___limpMultiplier;
			}
			if (defaultClimbSpeed <= 0f)
			{
				defaultClimbSpeed = ___climbSpeed;
			}
			if (defaultJumpForce <= 0f)
			{
				defaultJumpForce = ___jumpForce;
			}
		}

		[HarmonyPatch("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 ___jumpForce, ref float ___climbSpeed, ref float ___drunkness, PlayerControllerB __instance)
		{
			if (!___isPlayerControlled)
			{
				return;
			}
			___movementSpeed = defaultMovementSpeed;
			___climbSpeed = defaultClimbSpeed;
			___jumpForce = defaultJumpForce;
			if (ConfigSync.isSynced)
			{
				___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;
				}
				float num = ConfigSync.instance.jumpForceMultiplier;
				if (___drunkness > 0f)
				{
					___movementSpeed *= ConfigSync.instance.drunkSpeedMultiplier;
					___climbSpeed *= ConfigSync.instance.drunkSpeedMultiplier;
					num *= ConfigSync.instance.drunkJumpForceMultiplier;
				}
				___jumpForce *= Mathf.Pow(num, 0.55f);
			}
			if (ConfigSync.isSynced && (Object)(object)__instance == (Object)(object)StartOfRound.Instance?.localPlayerController)
			{
				if (!___isWalking)
				{
					___sprintMultiplier = (ConfigSync.instance.enableInstantSprinting ? 1f : Mathf.Lerp(___sprintMultiplier, 1f, Time.deltaTime * 10f));
				}
				else if (___isSprinting && ConfigSync.instance.enableInstantSprinting)
				{
					___sprintMultiplier = ConfigSync.instance.sprintSpeedMultiplier;
				}
			}
		}

		[HarmonyPatch("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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			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;
		}

		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);
		}
	}
}