Decompiled source of BetterSwimming v1.0.3

BetterSwimming.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BetterSwimming")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("BetterSwimming")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("E0E2F92E-557C-4A05-9D89-AA92A0BD75C4")]
[assembly: AssemblyFileVersion("1.0.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public ExtensionMarkerAttribute(string name)
		{
		}
	}
}
namespace BetterSwimming
{
	[HarmonyPatch(typeof(PlayerMovement), "Move")]
	internal static class PlayerMovementMovePatch
	{
		private static PlayerInput? _input;

		private static InputAction? _jump;

		private static float _nextStroke;

		private static float _swimVel;

		private static bool _wasSwimming;

		internal static void RaiseSwimVel(float velY)
		{
			_swimVel = Mathf.Max(_swimVel, velY);
			_wasSwimming = true;
		}

		private static void Postfix(PlayerMovement __instance)
		{
			//IL_0030: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterSwimmingPlugin.IsEnabled || !BetterSwimmingPlugin.IsLocal(__instance))
			{
				return;
			}
			if (!__instance._isSwimming || __instance.OnBoat)
			{
				_wasSwimming = false;
				return;
			}
			Rigidbody rig = __instance._rig;
			float num = WaterManager.GetWaterHeight(rig.position) - rig.position.y;
			bool flag = BetterSwimmingPlugin.HoldToSwim.Value.IsOn() && JumpHeld();
			float num2;
			if (flag)
			{
				num2 = BetterSwimmingPlugin.SwimUpSpeed.Value;
			}
			else if (__instance._crouchInput)
			{
				num2 = 0f - BetterSwimmingPlugin.DiveSpeed.Value;
			}
			else
			{
				float num3 = num - BetterSwimmingPlugin.FloatDepth.Value;
				num2 = ((num3 > 0f) ? Mathf.Min(num3 * 2f, BetterSwimmingPlugin.BuoyancySpeed.Value) : (0f - BetterSwimmingPlugin.SinkSpeed.Value));
			}
			if (!_wasSwimming)
			{
				_swimVel = Mathf.Max(rig.linearVelocity.y, -10f);
				_wasSwimming = true;
			}
			_swimVel = Mathf.MoveTowards(_swimVel, num2, BetterSwimmingPlugin.SwimAccel.Value * Time.fixedDeltaTime);
			if (!__instance.Grounded || !(num2 <= 0f))
			{
				Vector3 linearVelocity = rig.linearVelocity;
				linearVelocity.y = _swimVel;
				rig.linearVelocity = linearVelocity;
				StrokeSound(flag);
			}
		}

		private static bool JumpHeld()
		{
			PlayerInput input = GameInfo.Input;
			if (!Object.op_Implicit((Object)(object)input))
			{
				return false;
			}
			if ((Object)(object)_input == (Object)(object)input && _jump != null)
			{
				return _jump.IsPressed();
			}
			_input = input;
			_jump = input.actions["PlayerJump"];
			return _jump.IsPressed();
		}

		private static void StrokeSound(bool swimmingUp)
		{
			if (!swimmingUp)
			{
				_nextStroke = 0f;
			}
			else if (!(Time.time < _nextStroke))
			{
				_nextStroke = Time.time + BetterSwimmingPlugin.StrokeSoundInterval.Value;
				AudioManager.PlayRandomGlobalClip(GameInfo.WaterStepSound, 1, GameInfo.StepSoundCount, true, 0.2f, 0.1f);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "Jump")]
	internal static class PlayerMovementJumpPatch
	{
		private static bool Prefix(PlayerMovement __instance)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterSwimmingPlugin.IsEnabled)
			{
				return true;
			}
			if (!__instance._isSwimming || __instance.Grounded)
			{
				return true;
			}
			if (!BetterSwimmingPlugin.IsLocal(__instance))
			{
				return true;
			}
			if (BetterSwimmingPlugin.HoldToSwim.Value.IsOn() && WaterManager.GetWaterHeight(__instance._rig.position) - __instance._rig.position.y > BetterSwimmingPlugin.FloatDepth.Value)
			{
				Vector3 linearVelocity = __instance._rig.linearVelocity;
				linearVelocity.y = Mathf.Max(linearVelocity.y, BetterSwimmingPlugin.StrokeForce.Value);
				__instance._rig.linearVelocity = linearVelocity;
				return false;
			}
			if (BetterSwimmingPlugin.UnlimitedStrokes.Value.IsOn())
			{
				__instance._swimJumpCount = 0;
			}
			return true;
		}

		private static void Postfix(PlayerMovement __instance)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (BetterSwimmingPlugin.IsEnabled && BetterSwimmingPlugin.IsLocal(__instance) && __instance._isSwimming)
			{
				PlayerMovementMovePatch.RaiseSwimVel(__instance._rig.linearVelocity.y);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "UpdateMoveSpeed")]
	internal static class PlayerMovementUpdateMoveSpeedPatch
	{
		private static void Postfix(PlayerMovement __instance)
		{
			if (BetterSwimmingPlugin.IsEnabled && __instance._isSwimming && BetterSwimmingPlugin.IsLocal(__instance))
			{
				__instance._curMoveSpeed *= BetterSwimmingPlugin.SwimSpeedMulti.Value;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "UnderWaterCheck")]
	internal static class PlayerMovementUnderWaterCheckPatch
	{
		private static void Prefix(PlayerMovement __instance)
		{
			if (BetterSwimmingPlugin.IsEnabled && BetterSwimmingPlugin.IsLocal(__instance))
			{
				__instance._damageFromWater = BetterSwimmingPlugin.UnderwaterDamage.Value;
				__instance._underwaterDamageDelay = BetterSwimmingPlugin.UnderwaterDamageDelay.Value;
			}
		}

		private static void Postfix(PlayerMovement __instance)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (BetterSwimmingPlugin.IsEnabled && BetterSwimmingPlugin.IsLocal(__instance) && !BetterSwimmingPlugin.WaveAccurate.Value.IsOff())
			{
				Vector3 position = __instance._player.Transform.position;
				__instance._isSwimming = position.y <= WaterManager.GetWaterHeight(position);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "FixedUpdate")]
	[HarmonyPriority(0)]
	[HarmonyAfter(new string[] { "com.hatsuneexo.htfslide" })]
	internal static class PlayerMovementFixedUpdatePatch
	{
		private static bool _waterLatched;

		private static float _nextLog;

		private static void Postfix(PlayerMovement __instance)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			if (!BetterSwimmingPlugin.IsEnabled || BetterSwimmingPlugin.WaterSpeedClamp.Value.IsOff() || !BetterSwimmingPlugin.IsLocal(__instance))
			{
				return;
			}
			if (BetterSwimmingPlugin.DebugLogging.Value.IsOn() && Time.time >= _nextLog)
			{
				_nextLog = Time.time + 0.25f;
				Vector3 linearVelocity = __instance._rig.linearVelocity;
				ManualLogSource betterSwimmingLogger = BetterSwimmingPlugin.BetterSwimmingLogger;
				object[] obj = new object[6] { __instance._isSwimming, __instance.Grounded, _waterLatched, null, null, null };
				Vector2 val = new Vector2(linearVelocity.x, linearVelocity.z);
				obj[3] = ((Vector2)(ref val)).magnitude;
				obj[4] = __instance._curMoveSpeed;
				obj[5] = __instance._walkSpeed;
				betterSwimmingLogger.LogInfo((object)string.Format("swim={0} ground={1} latch={2} flat={3:0.00} curMove={4:0.00} walk={5:0.00}", obj));
			}
			if (__instance.Grounded || __instance.OnBoat)
			{
				_waterLatched = false;
				return;
			}
			if (__instance._isSwimming)
			{
				_waterLatched = true;
			}
			if (_waterLatched)
			{
				SlideMomentum.Kill(__instance);
				float num = Mathf.Max(Mathf.Min(__instance._curMoveSpeed, __instance._walkSpeed * BetterSwimmingPlugin.SwimSpeedMulti.Value), 0.01f) * BetterSwimmingPlugin.WaterSpeedHeadroom.Value;
				Vector3 linearVelocity2 = __instance._rig.linearVelocity;
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(linearVelocity2.x, 0f, linearVelocity2.z);
				if (!(((Vector3)(ref val2)).sqrMagnitude <= num * num))
				{
					val2 = ((Vector3)(ref val2)).normalized * num;
					__instance._rig.linearVelocity = new Vector3(val2.x, linearVelocity2.y, val2.z);
					__instance._curVel = new Vector3(val2.x, __instance._curVel.y, val2.z);
				}
			}
		}
	}
	internal static class SlideMomentum
	{
		private static bool _resolved;

		private static FieldInfo? _airborne;

		private static FieldInfo? _momentumSpeed;

		private static MethodInfo? _endAirMomentum;

		internal static void Kill(PlayerMovement move)
		{
			if (!_resolved)
			{
				Resolve();
			}
			if (!(_airborne == null))
			{
				if ((bool)_airborne.GetValue(null) && _endAirMomentum != null)
				{
					_endAirMomentum.Invoke(null, new object[1] { move });
				}
				_momentumSpeed?.SetValue(null, 0f);
			}
		}

		private static void Resolve()
		{
			_resolved = true;
			Type type = AccessTools.TypeByName("HTFSlide.SlidePatch");
			if (!(type == null))
			{
				_airborne = AccessTools.Field(type, "_airborne");
				_momentumSpeed = AccessTools.Field(type, "_momentumSpeed");
				_endAirMomentum = AccessTools.Method(type, "EndAirMomentum", (Type[])null, (Type[])null);
			}
		}
	}
	[BepInPlugin("Azumatt.BetterSwimming", "BetterSwimming", "1.0.3")]
	public class BetterSwimmingPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		internal const string ModName = "BetterSwimming";

		internal const string ModVersion = "1.0.3";

		internal const string Author = "Azumatt";

		private const string ModGUID = "Azumatt.BetterSwimming";

		private static string ConfigFileName = "Azumatt.BetterSwimming.cfg";

		private static string ConfigFileFullPath;

		internal static string ConnectionError;

		private readonly Harmony _harmony = new Harmony("Azumatt.BetterSwimming");

		public static readonly ManualLogSource BetterSwimmingLogger;

		internal static ConfigEntry<Toggle> ModEnabled;

		internal static ConfigEntry<Toggle> DebugLogging;

		internal static ConfigEntry<Toggle> HoldToSwim;

		internal static ConfigEntry<float> SwimUpSpeed;

		internal static ConfigEntry<float> DiveSpeed;

		internal static ConfigEntry<float> SwimAccel;

		internal static ConfigEntry<float> SwimSpeedMulti;

		internal static ConfigEntry<Toggle> WaterSpeedClamp;

		internal static ConfigEntry<float> WaterSpeedHeadroom;

		internal static ConfigEntry<float> FloatDepth;

		internal static ConfigEntry<float> BuoyancySpeed;

		internal static ConfigEntry<float> SinkSpeed;

		internal static ConfigEntry<Toggle> WaveAccurate;

		internal static ConfigEntry<Toggle> UnlimitedStrokes;

		internal static ConfigEntry<float> StrokeForce;

		internal static ConfigEntry<float> StrokeSoundInterval;

		internal static ConfigEntry<int> UnderwaterDamage;

		internal static ConfigEntry<float> UnderwaterDamageDelay;

		internal static bool IsEnabled
		{
			get
			{
				ConfigEntry<Toggle> modEnabled = ModEnabled;
				if (modEnabled != null)
				{
					return modEnabled.Value == Toggle.On;
				}
				return false;
			}
		}

		public void Awake()
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Expected O, but got Unknown
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Expected O, but got Unknown
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Expected O, but got Unknown
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Expected O, but got Unknown
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			ModEnabled = config("1 - General", "Enabled", Toggle.On, "Turn the whole mod off without unloading it.");
			DebugLogging = config("1 - General", "Debug Logging", Toggle.Off, "Dumps the swim clamp numbers to the BepInEx log four times a second. Only for chasing bug reports.");
			HoldToSwim = config("2 - Swimming", "Hold To Swim Up", Toggle.On, "Hold jump to rise instead of mashing it. Off falls back to vanilla strokes.");
			SwimUpSpeed = config("2 - Swimming", "Swim Up Speed", 3.5f, new ConfigDescription("Units per second you climb while holding jump.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 15f), Array.Empty<object>()));
			DiveSpeed = config("2 - Swimming", "Dive Speed", 3f, new ConfigDescription("Units per second you go down while holding crouch. Watch the drowning timer.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			SwimAccel = config("2 - Swimming", "Swim Acceleration", 25f, new ConfigDescription("How hard vertical speed chases its target. Has to beat the game's extra gravity, so don't go tiny.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
			SwimSpeedMulti = config("2 - Swimming", "Swim Speed Multiplier", 1f, new ConfigDescription("Multiplies horizontal move speed while swimming (you can't sprint in water).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 3f), Array.Empty<object>()));
			WaterSpeedClamp = config("2 - Swimming", "Water Speed Clamp", Toggle.On, "Caps horizontal speed while you're swimming. Off lets slide/dash mods skate you across the water forever.");
			WaterSpeedHeadroom = config("2 - Swimming", "Water Speed Clamp Headroom", 1.25f, new ConfigDescription("Multiplier on your swim speed the clamp allows before it kicks in.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			FloatDepth = config("3 - Buoyancy", "Float Depth", 0.4f, new ConfigDescription("How far under the surface you settle when you're not pressing anything.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()));
			BuoyancySpeed = config("3 - Buoyancy", "Buoyancy Speed", 1.5f, new ConfigDescription("Cap on how fast you get pushed back up to the float depth.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
			SinkSpeed = config("3 - Buoyancy", "Sink Speed", 0.35f, new ConfigDescription("Idle drift downwards once you're at the float depth. Vanilla just sinks forever.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			WaveAccurate = config("3 - Buoyancy", "Wave Accurate Water Line", Toggle.On, "Use the Gerstner wave height instead of the flat water plane, so swells actually lift you.");
			UnlimitedStrokes = config("4 - Strokes", "Unlimited Strokes", Toggle.On, "Kills the stroke decay. Only matters when Hold To Swim Up is off.");
			StrokeForce = config("4 - Strokes", "Stroke Force", 3f, new ConfigDescription("Little kick a jump press gives while Hold To Swim Up is on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			StrokeSoundInterval = config("4 - Strokes", "Stroke Sound Interval", 0.55f, new ConfigDescription("Seconds between swim sounds while you hold jump. 0 spams it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()));
			UnderwaterDamage = config("5 - Drowning", "Underwater Damage", 10, new ConfigDescription("Damage per half second once your head has been under too long. 0 to never drown.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			UnderwaterDamageDelay = config("5 - Drowning", "Underwater Damage Delay", 2f, new ConfigDescription("Grace period in seconds before the drowning damage starts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			_harmony.PatchAll(executingAssembly);
			SetupWatcher();
			if (saveOnConfigSet)
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				BetterSwimmingLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
				BetterSwimmingLogger.LogError((object)"Please check your config entries for spelling and format!");
			}
		}

		internal static bool IsLocal(PlayerMovement move)
		{
			if ((Object)(object)Player.LocalPlayer != (Object)null)
			{
				return (Object)(object)move._player == (Object)(object)Player.LocalPlayer;
			}
			return false;
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
		{
			return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
		}

		private ConfigEntry<T> config<T>(string group, string name, T value, string description)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		static BetterSwimmingPlugin()
		{
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			ConnectionError = "";
			BetterSwimmingLogger = Logger.CreateLogSource("BetterSwimming");
			ModEnabled = null;
			DebugLogging = null;
			HoldToSwim = null;
			SwimUpSpeed = null;
			DiveSpeed = null;
			SwimAccel = null;
			SwimSpeedMulti = null;
			WaterSpeedClamp = null;
			WaterSpeedHeadroom = null;
			FloatDepth = null;
			BuoyancySpeed = null;
			SinkSpeed = null;
			WaveAccurate = null;
			UnlimitedStrokes = null;
			StrokeForce = null;
			StrokeSoundInterval = null;
			UnderwaterDamage = null;
			UnderwaterDamageDelay = null;
		}
	}
	public static class ToggleExtensions
	{
		[SpecialName]
		public sealed class <G>$4EFB485ABB76B8E3D0C1BC397C89D8B9
		{
			[SpecialName]
			public static class <M>$C59917F68A58EC5D02708E1A6E1BABC0
			{
			}

			[ExtensionMarker("<M>$C59917F68A58EC5D02708E1A6E1BABC0")]
			public bool IsOn()
			{
				throw null;
			}

			[ExtensionMarker("<M>$C59917F68A58EC5D02708E1A6E1BABC0")]
			public bool IsOff()
			{
				throw null;
			}
		}

		public static bool IsOn(this BetterSwimmingPlugin.Toggle toggle)
		{
			return toggle == BetterSwimmingPlugin.Toggle.On;
		}

		public static bool IsOff(this BetterSwimmingPlugin.Toggle toggle)
		{
			return toggle == BetterSwimmingPlugin.Toggle.Off;
		}
	}
}