Decompiled source of MovementCompany Enhanced v1.2.1

MovementCompanyEnhanced.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Lib;
using CSync.Util;
using GameNetcodeStuff;
using HarmonyLib;
using LC_API.ServerAPI;
using Microsoft.CodeAnalysis;
using MovementCompanyEnhanced.Component;
using MovementCompanyEnhanced.Core;
using MovementCompanyEnhanced.Patches;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("MovementCompanyEnhanced")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("General purpose movement mod, fully configurable and allows bhopping.")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+182845fbaf341a8641eec816c4ac5da02174d425")]
[assembly: AssemblyProduct("MovementCompanyEnhanced")]
[assembly: AssemblyTitle("MovementCompanyEnhanced")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MovementCompanyEnhanced
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MovementCompanyEnhanced";

		public const string PLUGIN_NAME = "MovementCompanyEnhanced";

		public const string PLUGIN_VERSION = "1.2.0";
	}
}
namespace MovementCompanyEnhanced.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal class NetworkManagerPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("StartDisconnect")]
		public static void PlayerLeave()
		{
			if (SyncedInstance<Config>.Default.SYNC_TO_CLIENTS.Value)
			{
				SyncedInstance<Config>.RevertSync();
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerPatch
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnRequestSync;

			public static HandleNamedMessageDelegate <1>__OnReceiveSync;

			public static Action<CallbackContext> <2>__CrouchCanceled;
		}

		internal static CustomMovement movementScript;

		private static bool removeFirstDelay => SyncedInstance<Config>.Instance.REMOVE_FIRST_JUMP_DELAY.Value;

		private static bool removeSecondDelay => SyncedInstance<Config>.Instance.REMOVE_SECOND_JUMP_DELAY.Value;

		private static InputActionAsset Actions => IngamePlayerSettings.Instance.playerInput.actions;

		[HarmonyPostfix]
		[HarmonyPatch("ConnectClientToPlayerObject")]
		public static void InitializeLocalPlayer()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if (SyncedInstance<Config>.IsHost)
			{
				CustomMessagingManager messageManager = SyncedInstance<Config>.MessageManager;
				object obj = <>O.<0>__OnRequestSync;
				if (obj == null)
				{
					HandleNamedMessageDelegate val = Config.OnRequestSync;
					<>O.<0>__OnRequestSync = val;
					obj = (object)val;
				}
				messageManager.RegisterNamedMessageHandler("MCE_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
				SyncedInstance<Config>.Synced = true;
				return;
			}
			SyncedInstance<Config>.Synced = false;
			CustomMessagingManager messageManager2 = SyncedInstance<Config>.MessageManager;
			object obj2 = <>O.<1>__OnReceiveSync;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = Config.OnReceiveSync;
				<>O.<1>__OnReceiveSync = val2;
				obj2 = (object)val2;
			}
			messageManager2.RegisterNamedMessageHandler("MCE_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
			Config.RequestSync();
		}

		[HarmonyPostfix]
		[HarmonyPatch("SpawnPlayerAnimation")]
		public static void GiveMovementScript(PlayerControllerB __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance) && !((Object)(object)((Component)__instance).GetComponentInChildren<CustomMovement>() != (Object)null) && ((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
			{
				movementScript = ((Component)__instance).gameObject.AddComponent<CustomMovement>();
				movementScript.player = __instance;
				Plugin.Logger.LogInfo((object)"Client player was given the movement script.");
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		public static IEnumerable<CodeInstruction> RemoveJumpDelay(IEnumerable<CodeInstruction> instructions)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			if (!removeFirstDelay && !removeSecondDelay)
			{
				return list;
			}
			int num = 0;
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (!(val.opcode != OpCodes.Newobj) && (val.operand as ConstructorInfo)?.DeclaringType == typeof(WaitForSeconds) && (num != 0 || removeFirstDelay) && (num != 1 || removeSecondDelay))
				{
					list[i] = new CodeInstruction(OpCodes.Ldnull, (object)null);
					list.RemoveAt(i - 1);
					i--;
					num++;
				}
			}
			return list;
		}

		[HarmonyPrefix]
		[HarmonyPatch("DamagePlayer")]
		public static bool OverrideFallDamage(ref int damageNumber, ref bool fallDamage)
		{
			if (SyncedInstance<Config>.Default.FALL_DAMAGE_ENABLED.Value)
			{
				damageNumber = Mathf.Clamp(Mathf.RoundToInt(SyncedInstance<Config>.Instance.FALL_DAMAGE.Value), 0, 100);
				return true;
			}
			return !fallDamage;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Crouch_performed")]
		public static bool OnCrouch()
		{
			if (SyncedInstance<Config>.Default.HOLD_TO_CROUCH.Value)
			{
				movementScript.player.Crouch(true);
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnEnable")]
		public static void CrouchHold()
		{
			if (SyncedInstance<Config>.Default.HOLD_TO_CROUCH.Value)
			{
				RegisterActionCancel(Actions.FindAction("Crouch", true), CrouchCanceled);
			}
		}

		public static void RegisterActionCancel(InputAction action, Action<CallbackContext> callback, bool unregister = false)
		{
			if (unregister)
			{
				action.canceled -= callback;
			}
			else
			{
				action.canceled += callback;
			}
		}

		private static void CrouchCanceled(CallbackContext _)
		{
			movementScript.player.Crouch(false);
		}
	}
}
namespace MovementCompanyEnhanced.Core
{
	[BepInPlugin("MovementCompany-Enhanced", "MovementCompany-Enhanced", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony patcher;

		internal static ManualLogSource Logger { get; private set; }

		public static Config Config { get; private set; }

		private void Awake()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Config = new Config(((BaseUnityPlugin)this).Config);
			if (!PluginEnabled(logIfDisabled: true))
			{
				return;
			}
			Config.InitBindings();
			try
			{
				patcher = new Harmony("MovementCompany-Enhanced");
				patcher.PatchAll();
				Logger.LogInfo((object)"Plugin loaded.");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)ex);
			}
		}

		public void OnDestroy()
		{
			if (PluginEnabled())
			{
				ModdedServer.SetServerModdedOnly();
			}
		}

		public bool PluginEnabled(bool logIfDisabled = false)
		{
			bool value = Config.PLUGIN_ENABLED.Value;
			if (!value && logIfDisabled)
			{
				Logger.LogInfo((object)"MovementCompanyEnhanced disabled globally.");
			}
			return value;
		}
	}
	public struct ConfigCategory
	{
		public static ConfigCategory GENERAL => new ConfigCategory("0 >> General << 0");

		public static ConfigCategory MOVEMENT => new ConfigCategory("1 >> Movement << 1");

		public static ConfigCategory STAMINA => new ConfigCategory("2 >> Stamina << 2");

		public static ConfigCategory BHOP => new ConfigCategory("3 >> Bhopping << 3");

		public static ConfigCategory MISC => new ConfigCategory("4 >> Miscellaneous << 4");

		public string Value { get; private set; }

		private ConfigCategory(string value)
		{
			Value = value;
		}
	}
	[DataContract]
	public class Config : SyncedInstance<Config>
	{
		[NonSerialized]
		private readonly ConfigFile configFile;

		public ConfigEntry<bool> PLUGIN_ENABLED { get; private set; }

		public ConfigEntry<bool> DISPLAY_DEBUG_INFO { get; private set; }

		[DataMember]
		public SyncedEntry<bool> SYNC_TO_CLIENTS { get; private set; }

		[DataMember]
		public SyncedEntry<bool> HOLD_TO_CROUCH { get; private set; }

		[DataMember]
		public SyncedEntry<bool> REMOVE_FIRST_JUMP_DELAY { get; private set; }

		[DataMember]
		public SyncedEntry<bool> REMOVE_SECOND_JUMP_DELAY { get; private set; }

		[DataMember]
		public SyncedEntry<float> MOVEMENT_SPEED { get; private set; }

		[DataMember]
		public SyncedEntry<float> CLIMB_SPEED { get; private set; }

		[DataMember]
		public SyncedEntry<float> SINK_SPEED_MULTIPLIER { get; private set; }

		[DataMember]
		public SyncedEntry<bool> FALL_DAMAGE_ENABLED { get; private set; }

		[DataMember]
		public SyncedEntry<float> FALL_DAMAGE { get; private set; }

		[DataMember]
		public SyncedEntry<bool> INFINITE_STAMINA { get; private set; }

		[DataMember]
		public SyncedEntry<float> MAX_STAMINA { get; private set; }

		[DataMember]
		public SyncedEntry<bool> BHOP_IN_FACTORY { get; private set; }

		[DataMember]
		public SyncedEntry<bool> BHOP_IN_SHIP { get; private set; }

		[DataMember]
		public SyncedEntry<float> MAX_JUMP_DURATION { get; private set; }

		[DataMember]
		public SyncedEntry<float> ROTATION_THRESHOLD { get; private set; }

		[DataMember]
		public SyncedEntry<float> JUMP_TIME_MULTIPLIER { get; private set; }

		[DataMember]
		public SyncedEntry<float> MAX_AIR_VELOCITY { get; private set; }

		[DataMember]
		public SyncedEntry<float> FORWARD_VELOCITY_DAMPER { get; private set; }

		[DataMember]
		public SyncedEntry<float> AIR_VELOCITY_MULTIPLIER { get; private set; }

		[DataMember]
		public SyncedEntry<float> GROUND_VELOCITY_MULTIPLIER { get; private set; }

		public Config(ConfigFile cfg)
		{
			base.InitInstance(this);
			configFile = cfg;
			PLUGIN_ENABLED = NewEntry(ConfigCategory.GENERAL, "bEnabled", defaultVal: true, "Enable or disable the plugin globally.");
		}

		private ConfigEntry<V> NewEntry<V>(ConfigCategory category, string key, V defaultVal, string desc)
		{
			return configFile.Bind<V>(category.Value, key, defaultVal, desc);
		}

		private SyncedEntry<V> NewSyncedEntry<V>(ConfigCategory category, string key, V defaultVal, string desc) where V : unmanaged
		{
			return Extensions.BindSyncedEntry<V>(configFile, category.Value, key, defaultVal, desc);
		}

		public void InitBindings()
		{
			DISPLAY_DEBUG_INFO = NewEntry(ConfigCategory.GENERAL, "bDisplayDebugInfo", defaultVal: false, "Whether to display coordinates, velocity and other debug info.");
			SYNC_TO_CLIENTS = NewSyncedEntry(ConfigCategory.GENERAL, "bSyncToClients", defaultVal: true, "As the host, should clients be forced to use our config values?\nSetting this to `false` will allow clients to use their own config.");
			MOVEMENT_SPEED = NewSyncedEntry(ConfigCategory.MOVEMENT, "fMovementSpeed", 4.1f, "The base speed at which the player moves. This is NOT a multiplier.");
			CLIMB_SPEED = NewSyncedEntry(ConfigCategory.MOVEMENT, "fClimbSpeed", 3.9f, "The base speed at which the player climbs. This is NOT a multiplier.");
			SINK_SPEED_MULTIPLIER = NewSyncedEntry(ConfigCategory.MOVEMENT, "fSinkSpeedMultiplier", 0.16f, "Value to multiply the sinking speed by when in quicksand.\nDon't want to sink as fast? Decrease this value.");
			HOLD_TO_CROUCH = NewSyncedEntry(ConfigCategory.MOVEMENT, "bHoldToCrouch", defaultVal: true, "Whether the player should hold to crouch instead of a toggle.\nNOTE: This setting is client-side and cannot be forced by the host.");
			REMOVE_FIRST_JUMP_DELAY = NewSyncedEntry(ConfigCategory.MOVEMENT, "bRemoveFirstJumpDelay", defaultVal: true, "Removes the immediate jump delay of 150ms after jumping.");
			REMOVE_SECOND_JUMP_DELAY = NewSyncedEntry(ConfigCategory.MOVEMENT, "bRemoveSecondJumpDelay", defaultVal: true, "Removes the jump delay of 100ms before jumping can end.");
			FALL_DAMAGE_ENABLED = NewSyncedEntry(ConfigCategory.MOVEMENT, "bFallDamageEnabled", defaultVal: true, "Whether you take fall damage. 4Head");
			FALL_DAMAGE = NewSyncedEntry(ConfigCategory.MOVEMENT, "fFallDamage", 16.5f, "How much base HP the player loses from every fall. Clamped between 0-100.");
			INFINITE_STAMINA = NewSyncedEntry(ConfigCategory.STAMINA, "bInfiniteStamina", defaultVal: true, "Whether the player has infinite stamina (essential for bhopping).\nOnly applies wherever bhopping is allowed.\nNOTE: THIS WILL BE REPLACED IN FUTURE.");
			MAX_STAMINA = NewSyncedEntry(ConfigCategory.STAMINA, "fMaxStamina", 200f, "The amount at which the sprint meter (aka stamina) is considered full.\nClamped between 0 and 1 in the base game.");
			BHOP_IN_FACTORY = NewSyncedEntry(ConfigCategory.BHOP, "bBhopInFactory", defaultVal: false, "Whether bhopping (not general movement) is allowed inside the factory.");
			BHOP_IN_SHIP = NewSyncedEntry(ConfigCategory.BHOP, "bBhopInFactory", defaultVal: false, "Whether bhopping (not general movement) is allowed inside the ship.");
			MAX_JUMP_DURATION = NewSyncedEntry(ConfigCategory.BHOP, "fMaxJumpDuration", 0.0025f, "The maximum amount of time a jump can last for.");
			ROTATION_THRESHOLD = NewSyncedEntry(ConfigCategory.BHOP, "fRotationThreshold", 0.0115f, "The magnitude at which to begin applying velocity. Higher = more rotation required.");
			JUMP_TIME_MULTIPLIER = NewSyncedEntry(ConfigCategory.BHOP, "fJumpTimeMultiplier", 29f, "The value to multiply 'jump time' by, affecting how quickly you hit MaxJumpDuration.\nLower values will cause the player to feel more weightless.");
			MAX_AIR_VELOCITY = NewSyncedEntry(ConfigCategory.BHOP, "fMaxAirVelocity", 60f, "The value at which velocity will stop being applied when airborne.");
			FORWARD_VELOCITY_DAMPER = NewSyncedEntry(ConfigCategory.BHOP, "fForwardVelocityDamper", 1.65f, "After jumping, a forward velocity is applied - which is first dampened by this value.\nNote: Increasing this value too much may hinder bhopping.");
			AIR_VELOCITY_MULTIPLIER = NewSyncedEntry(ConfigCategory.BHOP, "fAirVelocityMultiplier", 0.0046f, "The value to multiply the player's velocity by when airborne.\nNote: Do not let the small value fool you, anything above the default is veryy fast!");
			GROUND_VELOCITY_MULTIPLIER = NewSyncedEntry(ConfigCategory.BHOP, "fGroundVelocityMultiplier", 1.9f, "The value determining how quickly velocity decreases when not airborne.\nEssentially, this affects how much the player is slowed down when hitting the ground.");
		}

		internal static void RequestSync()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsClient)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(ByteSerializer<Config>.IntSize, (Allocator)2, -1);
			try
			{
				Extensions.SendMessage(val, "MCE_OnRequestConfigSync", 0uL);
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		internal static void OnRequestSync(ulong clientId, FastBufferReader _)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!SyncedInstance<Config>.IsHost)
			{
				return;
			}
			Plugin.Logger.LogDebug((object)$"Config sync request received from client: {clientId}");
			byte[] array = ByteSerializer<Config>.SerializeToBytes(SyncedInstance<Config>.Instance);
			int num = array.Length;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(num + ByteSerializer<Config>.IntSize, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
				Extensions.SendMessage(val, "MCE_OnReceiveConfigSync", clientId);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
			}
			finally
			{
				((IDisposable)(FastBufferWriter)(ref val)).Dispose();
			}
		}

		internal static void OnReceiveSync(ulong _, FastBufferReader reader)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(ByteSerializer<Config>.IntSize))
			{
				Plugin.Logger.LogError((object)"Config sync error: Could not begin reading buffer.");
				return;
			}
			int num = default(int);
			((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
			if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
			{
				Plugin.Logger.LogError((object)"Config sync error: Host could not sync.");
				return;
			}
			byte[] array = new byte[num];
			((FastBufferReader)(ref reader)).ReadBytesSafe(ref array, num, 0);
			try
			{
				SyncedInstance<Config>.SyncInstance(array);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Error syncing config instance!\n{arg}");
			}
			PlayerControllerPatch.movementScript.ApplyConfigSpeeds();
		}
	}
	internal static class Metadata
	{
		public const string GUID = "MovementCompany-Enhanced";

		public const string NAME = "MovementCompany-Enhanced";

		public const string VERSION = "1.2.0";
	}
}
namespace MovementCompanyEnhanced.Component
{
	internal class CustomMovement : MonoBehaviour
	{
		private float jumpTime;

		private bool inAir;

		private Vector3 wantedVelToAdd;

		private Vector3 velToAdd;

		private Vector3 previousForward;

		public PlayerControllerB player { get; internal set; }

		internal Config cfg => SyncedInstance<Config>.Instance;

		private void OnGUI()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			if (SyncedInstance<Config>.Default.DISPLAY_DEBUG_INFO.Value && !((Object)(object)player.thisController == (Object)null))
			{
				Vector3 position = ((Component)player.thisController).transform.position;
				GUI.Label(new Rect(10f, 10f, 500f, 500f), Vec3ToString(position));
				GUI.Label(new Rect(10f, 40f, 500f, 500f), "Current Velocity: " + Math.Round(CurrentVelocity(), 3));
				GUI.Label(new Rect(10f, 60f, 500f, 500f), "Wanted Velocity: " + Math.Round(((Vector3)(ref wantedVelToAdd)).magnitude, 3));
				GUI.Label(new Rect(10f, 90f, 500f, 500f), "Jump Time: " + jumpTime);
				GUI.Label(new Rect(10f, 110f, 500f, 500f), "Airborne: " + inAir);
				GUI.Label(new Rect(10f, 130f, 500f, 500f), "Airborne (Actual): " + Airborne());
			}
		}

		private void Start()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (SyncedInstance<Config>.IsHost)
			{
				ApplyConfigSpeeds(host: true);
			}
			velToAdd = new Vector3(0.0002f, 0.0002f, 0.0002f);
			MovePlayer(0f, -0.5f, 0f);
		}

		private void Update()
		{
			if (Object.op_Implicit((Object)(object)player) && (!player.isInHangarShipRoom || cfg.BHOP_IN_SHIP.Value) && (!player.isInsideFactory || cfg.BHOP_IN_FACTORY.Value))
			{
				Animator playerBodyAnimator = player.playerBodyAnimator;
				bool jumping = playerBodyAnimator != null && playerBodyAnimator.GetBool("Jumping");
				if (cfg.INFINITE_STAMINA.Value)
				{
					SetStamina(cfg.MAX_STAMINA.Value);
				}
				UpdateJumpTime(jumping);
				if (!Airborne())
				{
					LerpToGround();
				}
				else if (!ReachedMaxVelocity())
				{
					ApplyBhop();
				}
			}
		}

		internal void ApplyConfigSpeeds(bool host = false)
		{
			string arg = (host ? "Host" : "Client");
			Plugin.Logger.LogDebug((object)$"{arg} - move speed set to: {cfg?.MOVEMENT_SPEED?.Value}");
			player.movementSpeed = ValNonNegative(cfg.MOVEMENT_SPEED.Value);
			player.climbSpeed = ValNonNegative(cfg.CLIMB_SPEED.Value);
			player.sinkingSpeedMultiplier = ValNonNegative(cfg.SINK_SPEED_MULTIPLIER.Value);
		}

		private void UpdateJumpTime(bool jumping)
		{
			if (jumping && jumpTime < cfg.MAX_JUMP_DURATION.Value)
			{
				player.fallValue = player.jumpForce;
				jumpTime += Time.deltaTime * cfg.JUMP_TIME_MULTIPLIER.Value / 100f;
			}
		}

		private void LerpToGround()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			float num = Time.deltaTime * cfg.GROUND_VELOCITY_MULTIPLIER.Value;
			wantedVelToAdd = Vector3.Lerp(wantedVelToAdd, Vector3.zero, num);
			inAir = false;
			jumpTime = 0f;
		}

		private void ApplyBhop()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!inAir)
			{
				inAir = true;
				AddJumpVelocity(cfg.AIR_VELOCITY_MULTIPLIER.Value);
			}
			wantedVelToAdd.y = 0f;
			MovePlayer(CurrentForward() * (((Vector3)(ref wantedVelToAdd)).magnitude / cfg.FORWARD_VELOCITY_DAMPER.Value));
			AddRotationVelocity(cfg.ROTATION_THRESHOLD.Value);
		}

		private void AddJumpVelocity(float multiplier)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = player.thisController.velocity;
			velocity.y = 0f;
			if (((Vector3)(ref wantedVelToAdd)).magnitude < 0.2f)
			{
				wantedVelToAdd += velocity * multiplier;
			}
		}

		private void AddRotationVelocity(float threshold)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = CurrentForward() - previousForward;
			if (((Vector3)(ref val)).magnitude > threshold)
			{
				wantedVelToAdd += velToAdd;
			}
			previousForward = CurrentForward();
		}

		private void MovePlayer(Vector3 motion)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			player.thisController.Move(motion);
		}

		private void MovePlayer(float x, float y, float z)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			player.thisController.Move(new Vector3(x, y, z));
		}

		public bool Airborne()
		{
			if (!player.thisController.isGrounded)
			{
				return !player.isClimbingLadder;
			}
			return false;
		}

		public Vector3 CurrentForward()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)player).transform.forward;
		}

		public float CurrentVelocity()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = player.thisController.velocity;
			return ((Vector3)(ref velocity)).magnitude;
		}

		public bool ReachedMaxVelocity()
		{
			return CurrentVelocity() >= cfg.MAX_AIR_VELOCITY.Value;
		}

		private void SetStamina(float val)
		{
			player.sprintMeter = ValNonNegative(val);
		}

		private float ValNonNegative(float newVal)
		{
			if (newVal <= 0f)
			{
				newVal = 0f;
			}
			return newVal;
		}

		public string Vec3ToString(Vector3 vec)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)Math.Round(vec.x, 1);
			float num2 = (float)Math.Round(vec.y, 1);
			float num3 = (float)Math.Round(vec.z, 1);
			return $"X: {num}, Y: {num2}, Z: {num3}";
		}
	}
}