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