Decompiled source of BetterSwimming v1.0.0

BetterSwimming.dll

Decompiled 32 minutes 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.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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())
			{
				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);
			}
		}
	}
	[BepInPlugin("Azumatt.BetterSwimming", "BetterSwimming", "1.0.0")]
	public class BetterSwimmingPlugin : BaseUnityPlugin
	{
		public enum Toggle
		{
			On = 1,
			Off = 0
		}

		internal const string ModName = "BetterSwimming";

		internal const string ModVersion = "1.0.0";

		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> HoldToSwim;

		internal static ConfigEntry<float> SwimUpSpeed;

		internal static ConfigEntry<float> DiveSpeed;

		internal static ConfigEntry<float> SwimAccel;

		internal static ConfigEntry<float> SwimSpeedMulti;

		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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected O, but got Unknown
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: 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_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Expected O, but got Unknown
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Expected O, but got Unknown
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: 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.");
			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>()));
			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;
			HoldToSwim = null;
			SwimUpSpeed = null;
			DiveSpeed = null;
			SwimAccel = null;
			SwimSpeedMulti = 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;
		}
	}
}