Decompiled source of BetterLadders v1.5.0

e3s1.BetterLadders.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterLadders.Compatibility;
using BetterLadders.Config;
using BetterLadders.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.SceneManagement;
using e3s1.BetterLadders.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("BMX.LobbyCompatibility")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("LethalConfig")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("e3s1.BetterLadders")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("[v73] Configurable climbing speed, extension ladder time, climbing with two-handed items, and more")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0+3378133b8109028859a5c07511c02330c0462007")]
[assembly: AssemblyProduct("BetterLadders")]
[assembly: AssemblyTitle("e3s1.BetterLadders")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/e3s1/BetterLadders")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 BetterLadders
{
	[BepInPlugin("e3s1.BetterLadders", "BetterLadders", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BetterLaddersPlugin : BaseUnityPlugin
	{
		private const string LethalConfigGuid = "ainavt.lc.lethalconfig";

		private const string LobbyCompatibilityGuid = "BMX.LobbyCompatibility";

		private readonly Harmony _harmony = new Harmony("e3s1.BetterLadders");

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			NetcodePatcher();
			if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"))
			{
				Logger.LogInfo((object)"LethalConfig detected");
				LethalConfig.Init();
			}
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				Logger.LogInfo((object)"LobbyCompatibility detected, registering plugin...");
				LobbyCompatibility.Init(((BaseUnityPlugin)this).Info.Metadata);
			}
			new LocalConfig(((BaseUnityPlugin)this).Config);
			SceneManager.sceneLoaded += SyncedConfig.Initialize;
			_harmony.PatchAll(typeof(AllowTwoHanded));
			_harmony.PatchAll(typeof(ClimbSpeed));
			_harmony.PatchAll(typeof(ExtensionLadderTime));
			_harmony.PatchAll(typeof(HideItems));
			_harmony.PatchAll(typeof(HoldToPickup));
			_harmony.PatchAll(typeof(HoverTip));
			_harmony.PatchAll(typeof(KillTrigger));
			Logger.LogInfo((object)"Running transpilers...");
			if (!LocalConfig.Instance.DebugMode.Value)
			{
				Logger.LogInfo((object)"Not logging IL code, DebugMode is disabled");
			}
			_harmony.PatchAll(typeof(ExtensionLadderDelay));
			_harmony.PatchAll(typeof(ExtensionLadderSpeed));
			_harmony.PatchAll(typeof(TransitionSpeed));
			Logger.LogInfo((object)"Finished loading");
		}

		private static void NetcodePatcher()
		{
			foreach (Type item in Assembly.GetExecutingAssembly().GetTypes().Where(delegate(Type t)
			{
				string? @namespace = t.Namespace;
				return @namespace == null || !@namespace.StartsWith("BetterLadders.Compatibility");
			}))
			{
				MethodInfo[] methods = item.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class TranspilerHelper
	{
		public static IEnumerable<CodeInstruction> Patch(IEnumerable<CodeInstruction> instructions, Func<List<CodeInstruction>, List<(int logStartIndex, int logEndIndex)>, bool>[] patches, [CallerMemberName] string memberName = "")
		{
			BetterLaddersPlugin.Logger.LogInfo((object)("Starting " + memberName));
			List<CodeInstruction> code = new List<CodeInstruction>(instructions);
			for (int i = 0; i < patches.Length; i++)
			{
				try
				{
					List<(int, int)> list = new List<(int, int)>();
					if (!patches[i](code, list))
					{
						BetterLaddersPlugin.Logger.LogError((object)$"No IL match found for patch #{i} in {memberName}");
						continue;
					}
					BetterLaddersPlugin.Logger.LogInfo((object)$"Completed applying patch #{i} in {memberName}");
					if (!LocalConfig.Instance.DebugMode.Value)
					{
						continue;
					}
					int num = list.Select<(int, int), List<CodeInstruction>>(((int logStartIndex, int logEndIndex) s) => code.GetRange(s.logStartIndex, s.logEndIndex - s.logStartIndex)).Max((List<CodeInstruction> codes) => codes.Max((CodeInstruction c) => ((object)c).ToString().Length));
					int count = num + 2;
					for (int j = 0; j < list.Count; j++)
					{
						(int, int) tuple = list[j];
						int item = tuple.Item1;
						int item2 = tuple.Item2;
						string text = "╞═╡";
						if (j == 0)
						{
							text = "┌─┐";
						}
						BetterLaddersPlugin.Logger.LogInfo((object)(text[0] + new string(text[1], count) + text[2]));
						for (int k = item; k < item2; k++)
						{
							string text2 = ((code[k].operand == null) ? code[k].opcode.ToString() : ((object)code[k]).ToString());
							BetterLaddersPlugin.Logger.LogInfo((object)("│ " + text2.PadRight(num) + " │"));
						}
						if (j == list.Count - 1)
						{
							BetterLaddersPlugin.Logger.LogInfo((object)("└" + new string('─', count) + "┘"));
						}
					}
				}
				catch (Exception arg)
				{
					BetterLaddersPlugin.Logger.LogError((object)$"Error running patch #{i} in {memberName}: {arg}");
				}
			}
			BetterLaddersPlugin.Logger.LogInfo((object)("Finished all patches in " + memberName));
			BetterLaddersPlugin.Logger.LogInfo((object)"");
			return code;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "e3s1.BetterLadders";

		public const string PLUGIN_NAME = "BetterLadders";

		public const string PLUGIN_VERSION = "1.5.0";
	}
}
namespace BetterLadders.Patches
{
	internal static class AllowTwoHanded
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "Interact_performed")]
		private static void LadderTwoHandedAccessPrefix(PlayerControllerB __instance)
		{
			InteractTrigger hoveringOverTrigger = __instance.hoveringOverTrigger;
			if (!((Object)(object)hoveringOverTrigger == (Object)null) && hoveringOverTrigger.isLadder)
			{
				hoveringOverTrigger.specialCharacterAnimation = !(hoveringOverTrigger.twoHandedItemAllowed = LocalConfig.Instance.AllowTwoHanded.Value || __instance.isClimbingLadder);
			}
		}
	}
	internal static class ClimbSpeed
	{
		private class TimeoutResult
		{
			public bool TimedOut;
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass7_0
		{
			public PlayerControllerB player;

			internal bool <SetClimbSpeed>b__0()
			{
				player.climbSpeed = _vanillaClimbSpeed * LocalConfig.Instance.ClimbSpeedMultiplier.Value;
				if (player.isSprinting)
				{
					PlayerControllerB obj = player;
					obj.climbSpeed *= LocalConfig.Instance.SprintingClimbSpeedMultiplier.Value;
				}
				return player.isClimbingLadder;
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass8_0
		{
			public PlayerControllerB player;

			internal bool <SetAnimationSpeed>b__0()
			{
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				float @float = player.playerBodyAnimator.GetFloat(AnimationSpeed);
				if (@float == 0f)
				{
					return player.isClimbingLadder;
				}
				bool flag = (Object)(object)player == (Object)(object)GameNetworkManager.Instance.localPlayerController;
				if (flag && player.moveInputVector.y == 0f)
				{
					player.playerBodyAnimator.SetFloat(AnimationSpeed, 0f);
					return player.isClimbingLadder;
				}
				bool num;
				if (!flag)
				{
					AnimatorStateInfo currentAnimatorStateInfo = player.playerBodyAnimator.GetCurrentAnimatorStateInfo(0);
					num = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsTag("Sprinting");
				}
				else
				{
					num = player.isSprinting;
				}
				float num2 = LocalConfig.Instance.ClimbSpeedMultiplier.Value;
				if (num)
				{
					num2 *= LocalConfig.Instance.SprintingClimbSpeedMultiplier.Value;
				}
				int num3 = ((@float > 0f) ? 1 : ((@float < 0f) ? (-1) : 0));
				int num4 = num3;
				player.playerBodyAnimator.SetFloat(AnimationSpeed, num2 * (float)num4);
				return player.isClimbingLadder;
			}
		}

		[CompilerGenerated]
		private sealed class <SetAnimationSpeed>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerControllerB player;

			private <>c__DisplayClass8_0 <>8__1;

			private TimeoutResult <timeoutResult>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SetAnimationSpeed>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<timeoutResult>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass8_0();
					<>8__1.player = player;
					BetterLaddersPlugin.Logger.LogInfo((object)("Starting SetAnimationSpeed coroutine for " + <>8__1.player.playerUsername));
					<timeoutResult>5__2 = new TimeoutResult();
					<>2__current = Timeout(<>8__1.player, <timeoutResult>5__2);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (<timeoutResult>5__2.TimedOut)
					{
						return false;
					}
					<>2__current = (object)new WaitWhile((Func<bool>)delegate
					{
						//IL_008f: Unknown result type (might be due to invalid IL or missing references)
						//IL_0094: Unknown result type (might be due to invalid IL or missing references)
						float @float = <>8__1.player.playerBodyAnimator.GetFloat(AnimationSpeed);
						if (@float == 0f)
						{
							return <>8__1.player.isClimbingLadder;
						}
						bool flag = (Object)(object)<>8__1.player == (Object)(object)GameNetworkManager.Instance.localPlayerController;
						if (flag && <>8__1.player.moveInputVector.y == 0f)
						{
							<>8__1.player.playerBodyAnimator.SetFloat(AnimationSpeed, 0f);
							return <>8__1.player.isClimbingLadder;
						}
						bool num;
						if (!flag)
						{
							AnimatorStateInfo currentAnimatorStateInfo = <>8__1.player.playerBodyAnimator.GetCurrentAnimatorStateInfo(0);
							num = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsTag("Sprinting");
						}
						else
						{
							num = <>8__1.player.isSprinting;
						}
						float num2 = LocalConfig.Instance.ClimbSpeedMultiplier.Value;
						if (num)
						{
							num2 *= LocalConfig.Instance.SprintingClimbSpeedMultiplier.Value;
						}
						int num3 = ((@float > 0f) ? 1 : ((@float < 0f) ? (-1) : 0));
						int num4 = num3;
						<>8__1.player.playerBodyAnimator.SetFloat(AnimationSpeed, num2 * (float)num4);
						return <>8__1.player.isClimbingLadder;
					});
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					BetterLaddersPlugin.Logger.LogInfo((object)("Finished SetAnimationSpeed coroutine for " + <>8__1.player.playerUsername));
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SetClimbSpeed>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerControllerB player;

			private <>c__DisplayClass7_0 <>8__1;

			private TimeoutResult <timeoutResult>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SetClimbSpeed>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>8__1 = null;
				<timeoutResult>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass7_0();
					<>8__1.player = player;
					BetterLaddersPlugin.Logger.LogInfo((object)("Starting SetClimbSpeed coroutine for " + <>8__1.player.playerUsername));
					<timeoutResult>5__2 = new TimeoutResult();
					<>2__current = Timeout(<>8__1.player, <timeoutResult>5__2);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (<timeoutResult>5__2.TimedOut)
					{
						return false;
					}
					<>2__current = (object)new WaitWhile((Func<bool>)delegate
					{
						<>8__1.player.climbSpeed = _vanillaClimbSpeed * LocalConfig.Instance.ClimbSpeedMultiplier.Value;
						if (<>8__1.player.isSprinting)
						{
							PlayerControllerB obj = <>8__1.player;
							obj.climbSpeed *= LocalConfig.Instance.SprintingClimbSpeedMultiplier.Value;
						}
						return <>8__1.player.isClimbingLadder;
					});
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					BetterLaddersPlugin.Logger.LogInfo((object)("Finished SetClimbSpeed coroutine for " + <>8__1.player.playerUsername));
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <Timeout>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerControllerB player;

			public TimeoutResult timeoutResult;

			private float <timeWaiting>5__2;

			private float <timeout>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Timeout>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<timeWaiting>5__2 = 0f;
					<timeout>5__3 = 1f / LocalConfig.Instance.TransitionSpeedMultiplier.Value;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!player.isClimbingLadder)
				{
					<timeWaiting>5__2 += Time.deltaTime;
					if (!(<timeWaiting>5__2 > <timeout>5__3))
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					BetterLaddersPlugin.Logger.LogInfo((object)$"Coroutine timed out for {player.playerUsername} after {<timeWaiting>5__2}s (max {<timeout>5__3}s)");
					timeoutResult.TimedOut = true;
				}
				BetterLaddersPlugin.Logger.LogInfo((object)$"Waited {<timeWaiting>5__2}s for {player.playerUsername} to start climbing ladder");
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static float _vanillaClimbSpeed = float.NaN;

		private static readonly int AnimationSpeed = Animator.StringToHash("animationSpeed");

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
		private static void GetVanillaClimbSpeedPatch(PlayerControllerB __instance)
		{
			if (float.IsNaN(_vanillaClimbSpeed))
			{
				_vanillaClimbSpeed = __instance.climbSpeed;
				BetterLaddersPlugin.Logger.LogInfo((object)$"Vanilla climb speed: {_vanillaClimbSpeed}");
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(InteractTrigger), "SetUsingLadderOnLocalClient")]
		private static void LadderAnimationSpeedPatch(bool isUsing)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (isUsing)
			{
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				((MonoBehaviour)localPlayerController).StartCoroutine(SetAnimationSpeed(localPlayerController));
				if (((NetworkBehaviour)SyncedConfig.Instance).IsSpawned)
				{
					SyncedConfig.Instance.RequestStartChangeAnimationSpeedRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)localPlayerController));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(InteractTrigger), "SetUsingLadderOnLocalClient")]
		private static void LadderClimbSpeedPatch(bool isUsing)
		{
			if (isUsing)
			{
				PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
				((MonoBehaviour)localPlayerController).StartCoroutine(SetClimbSpeed(localPlayerController));
			}
		}

		[IteratorStateMachine(typeof(<Timeout>d__6))]
		private static IEnumerator Timeout(PlayerControllerB player, TimeoutResult timeoutResult)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Timeout>d__6(0)
			{
				player = player,
				timeoutResult = timeoutResult
			};
		}

		[IteratorStateMachine(typeof(<SetClimbSpeed>d__7))]
		private static IEnumerator SetClimbSpeed(PlayerControllerB player)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetClimbSpeed>d__7(0)
			{
				player = player
			};
		}

		[IteratorStateMachine(typeof(<SetAnimationSpeed>d__8))]
		internal static IEnumerator SetAnimationSpeed(PlayerControllerB player)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SetAnimationSpeed>d__8(0)
			{
				player = player
			};
		}
	}
	public static class ExtensionLadderDelay
	{
		private static readonly ConstructorInfo WaitForSecondsConstructor = AccessTools.Constructor(typeof(WaitForSeconds), new Type[1] { typeof(float) }, false);

		private static readonly MethodInfo ExtensionDelayGetter = AccessTools.PropertyGetter(typeof(ExtensionLadderDelay), "ExtensionDelay");

		private static readonly MethodInfo FallDelayGetter = AccessTools.PropertyGetter(typeof(ExtensionLadderDelay), "FallDelay");

		private static float ExtensionDelay => LocalConfig.Instance.ExtensionDelay.Value;

		private static float FallDelay => LocalConfig.Instance.FallDelay.Value;

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		internal static IEnumerable<CodeInstruction> ExtensionDelayTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			return CommonTranspiler(instructions, LocalConfig.Instance.ExtensionDelay.VanillaValue, ExtensionDelayGetter, "ExtensionDelayTranspiler");
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		internal static IEnumerable<CodeInstruction> FallDelayTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			return CommonTranspiler(instructions, LocalConfig.Instance.FallDelay.VanillaValue, FallDelayGetter, "FallDelayTranspiler");
		}

		private static IEnumerable<CodeInstruction> CommonTranspiler(IEnumerable<CodeInstruction> instructions, float vanillaValue, MethodInfo getter, [CallerMemberName] string memberName = "")
		{
			return TranspilerHelper.Patch(instructions, new Func<List<CodeInstruction>, List<(int, int)>, bool>[1]
			{
				delegate(List<CodeInstruction> code, List<(int logStartIndex, int logEndIndex)> logIndices)
				{
					//IL_009d: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a3: Expected O, but got Unknown
					//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b6: Expected O, but got Unknown
					for (int i = 0; i < code.Count; i++)
					{
						if (code[i].opcode == OpCodes.Ldc_R4 && code[i].operand is float num && num == vanillaValue && code[i + 1].opcode == OpCodes.Newobj && code[i + 1].operand is ConstructorInfo constructorInfo && constructorInfo == WaitForSecondsConstructor)
						{
							code.InsertRange(i + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[2]
							{
								new CodeInstruction(OpCodes.Pop, (object)null),
								new CodeInstruction(OpCodes.Call, (object)getter)
							}));
							logIndices.Add((i, i + 3));
							return true;
						}
					}
					return false;
				}
			}, memberName);
		}
	}
	public static class ExtensionLadderSpeed
	{
		private static readonly MethodInfo ExtensionSpeedMultiplierGetter = AccessTools.PropertyGetter(typeof(ExtensionLadderSpeed), "ExtensionSpeedMultiplier");

		private static readonly MethodInfo FallSpeedMultiplierGetter = AccessTools.PropertyGetter(typeof(ExtensionLadderSpeed), "FallSpeedMultiplier");

		private static float ExtensionSpeedMultiplier => LocalConfig.Instance.ExtensionSpeedMultiplier.Value;

		private static float FallSpeedMultiplier => LocalConfig.Instance.FallSpeedMultiplier.Value;

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		internal static IEnumerable<CodeInstruction> ExtensionSpeedTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			return CommonTranspiler(instructions, ExtensionSpeedMultiplierGetter, "ExtensionSpeedTranspiler");
		}

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		internal static IEnumerable<CodeInstruction> FallSpeedTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			return CommonTranspiler(instructions, FallSpeedMultiplierGetter, "FallSpeedTranspiler");
		}

		private static IEnumerable<CodeInstruction> CommonTranspiler(IEnumerable<CodeInstruction> instructions, MethodInfo getter, [CallerMemberName] string memberName = "")
		{
			return TranspilerHelper.Patch(instructions, new Func<List<CodeInstruction>, List<(int, int)>, bool>[1]
			{
				delegate(List<CodeInstruction> code, List<(int logStartIndex, int logEndIndex)> logIndices)
				{
					//IL_0105: Unknown result type (might be due to invalid IL or missing references)
					//IL_010b: Expected O, but got Unknown
					//IL_0113: Unknown result type (might be due to invalid IL or missing references)
					//IL_0119: Expected O, but got Unknown
					for (int i = 0; i < code.Count; i++)
					{
						if (code[i].opcode == OpCodes.Ldfld && code[i].operand is FieldInfo fieldInfo && fieldInfo.Name.Contains("speedMultiplier"))
						{
							for (int j = i; j < i + 10 && j < code.Count; j++)
							{
								if (code[j - 1].opcode != OpCodes.Call && code[j].opcode == OpCodes.Mul && code[j + 1].opcode == OpCodes.Add && code[j + 2].opcode == OpCodes.Stfld && code[j + 2].operand is FieldInfo fieldInfo2 && fieldInfo2.Name.Contains("speedMultiplier"))
								{
									code.InsertRange(j + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[2]
									{
										new CodeInstruction(OpCodes.Call, (object)getter),
										new CodeInstruction(OpCodes.Mul, (object)null)
									}));
									logIndices.Add((i, j + 5));
									return true;
								}
							}
						}
					}
					return false;
				}
			}, memberName);
		}
	}
	internal static class ExtensionLadderTime
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ExtensionLadderItem), "StartLadderAnimation")]
		private static void ExtensionTimePatch(ref float ___ladderTimer)
		{
			float num = ((!(LocalConfig.Instance.ExtensionTime.Value <= 0f)) ? (LocalConfig.Instance.ExtensionTime.VanillaValue - LocalConfig.Instance.ExtensionTime.Value) : float.MinValue);
			___ladderTimer = num;
		}
	}
	internal static class HideItems
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(InteractTrigger), "SetUsingLadderOnLocalClient")]
		private static void SetVisibilityOnStartClimb(InteractTrigger __instance, bool isUsing)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (!((Object)(object)localPlayerController.currentlyHeldObjectServer == (Object)null))
			{
				bool flag = !isUsing;
				BetterLaddersPlugin.Logger.LogInfo((object)"Toggling visibility for held item");
				if ((LocalConfig.Instance.HideOneHanded.Value && !localPlayerController.twoHanded) || (LocalConfig.Instance.HideTwoHanded.Value && localPlayerController.twoHanded))
				{
					localPlayerController.currentlyHeldObjectServer.EnableItemMeshes(flag);
				}
				if (((NetworkBehaviour)SyncedConfig.Instance).IsSpawned)
				{
					SyncedConfig.Instance.RequestChangeItemVisibilityRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)localPlayerController.currentlyHeldObjectServer), flag);
				}
			}
		}
	}
	internal static class HoldToPickup
	{
		private static bool _canPickupLadder;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")]
		private static bool ControlExtLadderPickup(PlayerControllerB __instance)
		{
			if (!LocalConfig.Instance.HoldToPickup.Value)
			{
				return true;
			}
			if (!LookingAtGrabbableExtLadder(__instance, out var extLadderObj))
			{
				return true;
			}
			if ((Object)(object)extLadderObj == (Object)null || !extLadderObj.ladderActivated)
			{
				return true;
			}
			if (!_canPickupLadder)
			{
				return false;
			}
			_canPickupLadder = false;
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ClickHoldInteraction")]
		private static void ShowHoldInteractHUD(PlayerControllerB __instance)
		{
			if (LocalConfig.Instance.HoldToPickup.Value && !Object.op_Implicit((Object)(object)__instance.hoveringOverTrigger))
			{
				ExtensionLadderItem extLadderObj;
				if (!IngamePlayerSettings.Instance.playerInput.actions.FindAction("Interact", false).IsPressed())
				{
					HUDManager.Instance.holdFillAmount = 0f;
				}
				else if (LookingAtGrabbableExtLadder(__instance, out extLadderObj) && (Object)(object)extLadderObj != (Object)null && extLadderObj.ladderActivated && HUDManager.Instance.HoldInteractionFill(LocalConfig.Instance.HoldTime.Value, 1f))
				{
					_canPickupLadder = true;
					__instance.BeginGrabObject();
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "StopHoldInteractionOnTrigger")]
		private static bool StopHoldInteractionOnTrigger(PlayerControllerB __instance)
		{
			if (!LocalConfig.Instance.HoldToPickup.Value)
			{
				return true;
			}
			if (LookingAtGrabbableExtLadder(__instance, out var extLadderObj))
			{
				if ((Object)(object)extLadderObj != (Object)null && extLadderObj.ladderActivated)
				{
					if (IngamePlayerSettings.Instance.playerInput.actions.FindAction("Interact", false).IsPressed())
					{
						return false;
					}
					HUDManager.Instance.holdFillAmount = 0f;
				}
			}
			else
			{
				HUDManager.Instance.holdFillAmount = 0f;
			}
			if ((Object)(object)__instance.previousHoveringOverTrigger != (Object)null)
			{
				__instance.previousHoveringOverTrigger.StopInteraction();
			}
			if ((Object)(object)__instance.hoveringOverTrigger != (Object)null)
			{
				__instance.hoveringOverTrigger.StopInteraction();
			}
			return false;
		}

		private static bool LookingAtGrabbableExtLadder(PlayerControllerB player, out ExtensionLadderItem extLadderObj)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			bool flag = Physics.Raycast(player.interactRay, ref val, player.grabDistance, player.interactableObjectsMask) && ((Component)((RaycastHit)(ref val)).collider).gameObject.layer != 8;
			if (flag)
			{
				extLadderObj = ((Component)((RaycastHit)(ref val)).collider).gameObject.GetComponent<ExtensionLadderItem>();
				if (player.twoHanded || ((Object)(object)extLadderObj != (Object)null && !((GrabbableObject)extLadderObj).grabbable))
				{
					return false;
				}
			}
			else
			{
				extLadderObj = null;
			}
			return flag;
		}
	}
	internal static class HoverTip
	{
		private static bool? _wasTwoHanded;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "SetHoverTipAndCurrentInteractTrigger")]
		private static void LadderHoverTipPrefix(PlayerControllerB __instance)
		{
			if (!((Object)(object)__instance.hoveringOverTrigger == (Object)null) && __instance.hoveringOverTrigger.isLadder && __instance.isHoldingInteract && LocalConfig.Instance.AllowTwoHanded.Value && __instance.twoHanded)
			{
				_wasTwoHanded = true;
				__instance.twoHanded = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "SetHoverTipAndCurrentInteractTrigger")]
		private static void LadderHoverTipPostfix(PlayerControllerB __instance)
		{
			if (_wasTwoHanded.HasValue)
			{
				__instance.twoHanded = _wasTwoHanded.Value;
				_wasTwoHanded = null;
			}
		}
	}
	internal static class KillTrigger
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ExtensionLadderItem), "StartLadderAnimation")]
		private static void KillTriggerPatch(ref Collider ___killTrigger)
		{
			((Component)___killTrigger).gameObject.SetActive(LocalConfig.Instance.EnableKillTrigger.Value);
		}
	}
	internal static class TransitionSpeed
	{
		private static readonly MethodInfo DeltaTimeGetter = AccessTools.PropertyGetter(typeof(Time), "deltaTime");

		private static readonly MethodInfo MultiplierGetter = AccessTools.PropertyGetter(typeof(TransitionSpeed), "Multiplier");

		public static float Multiplier => LocalConfig.Instance.TransitionSpeedMultiplier.Value;

		[HarmonyTranspiler]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		internal static IEnumerable<CodeInstruction> TransitionSpeedTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			return TranspilerHelper.Patch(instructions, new Func<List<CodeInstruction>, List<(int, int)>, bool>[1]
			{
				delegate(List<CodeInstruction> code, List<(int logStartIndex, int logEndIndex)> logIndices)
				{
					//IL_004e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0058: Expected O, but got Unknown
					//IL_0062: Unknown result type (might be due to invalid IL or missing references)
					//IL_006c: Expected O, but got Unknown
					int num = 0;
					for (int i = 0; i < code.Count; i++)
					{
						if (code[i].opcode == OpCodes.Call && code[i].operand is MethodInfo methodInfo && methodInfo == DeltaTimeGetter)
						{
							code.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)MultiplierGetter));
							code.Insert(i + 2, new CodeInstruction(OpCodes.Mul, (object)null));
							num++;
							logIndices.Add((i, i + 3));
						}
					}
					return num > 0;
				}
			}, "TransitionSpeedTranspiler");
		}
	}
}
namespace BetterLadders.Config
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false)]
	public sealed class SourceGenAttribute : Attribute
	{
		public SourceGenAttribute(Type targetFieldType, Type targetClassType)
		{
		}
	}
	public abstract class CustomConfigEntry<T>
	{
		public ConfigEntry<T> ConfigEntry;

		public virtual T Value { get; }

		protected CustomConfigEntry(ConfigFile configFile, string section, string key, T defaultValue, ConfigDescription configDescription)
		{
			ConfigEntry = configFile.Bind<T>(section, key, defaultValue, configDescription);
		}

		protected abstract void LethalConfigCompat();

		protected void Init()
		{
			if (LethalConfig.IsInstalled)
			{
				LethalConfigCompat();
			}
		}
	}
	[SourceGen(typeof(SyncedConfigEntry<>), typeof(SyncedConfig))]
	public class LocalConfig
	{
		public readonly SyncedConfigEntry<float> ClimbSpeedMultiplier;

		public readonly SyncedConfigEntry<float> SprintingClimbSpeedMultiplier;

		public readonly SyncedConfigEntry<float> TransitionSpeedMultiplier;

		public readonly SyncedConfigEntry<bool> AllowTwoHanded;

		public readonly LocalConfigEntry<bool> ScaleAnimationSpeed;

		public readonly LocalConfigEntry<bool> HideOneHanded;

		public readonly LocalConfigEntry<bool> HideTwoHanded;

		public readonly SyncedConfigEntry<float> ExtensionTime;

		public readonly SyncedConfigEntry<float> ExtensionSpeedMultiplier;

		public readonly SyncedConfigEntry<float> ExtensionDelay;

		public readonly SyncedConfigEntry<float> FallSpeedMultiplier;

		public readonly SyncedConfigEntry<float> FallDelay;

		public readonly SyncedConfigEntry<bool> EnableKillTrigger;

		public readonly LocalConfigEntry<bool> HoldToPickup;

		public readonly LocalConfigEntry<float> HoldTime;

		public readonly LocalConfigEntry<bool> DebugMode;

		public static LocalConfig Instance { get; private set; }

		internal LocalConfig(ConfigFile configFile)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Expected O, but got Unknown
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Expected O, but got Unknown
			Instance = this;
			configFile.SaveOnConfigSet = false;
			ClimbSpeedMultiplier = new SyncedConfigEntry<float>(configFile, "General", "ClimbSpeedMultiplier", 1f, new ConfigDescription("Ladder climb speed multiplier (1 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()), 1f);
			SprintingClimbSpeedMultiplier = new SyncedConfigEntry<float>(configFile, "General", "SprintingClimbSpeedMultiplier", 1.5f, new ConfigDescription("Additional climb speed multiplier while sprinting (1 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()), 1f);
			TransitionSpeedMultiplier = new SyncedConfigEntry<float>(configFile, "General", "TransitionSpeedMultiplier", 1f, new ConfigDescription("Ladder enter/exit animation speed multiplier (1 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()), 1f);
			AllowTwoHanded = new SyncedConfigEntry<bool>(configFile, "General", "AllowTwoHanded", defaultValue: true, "Whether ladders can be climbed while carrying a two-handed object (false in vanilla)", vanillaValue: false);
			ScaleAnimationSpeed = new LocalConfigEntry<bool>(configFile, "General", "ScaleAnimationSpeed", defaultValue: true, "Whether the climbing animation is scaled to the climbing speed (false in vanilla)");
			HideOneHanded = new LocalConfigEntry<bool>(configFile, "General", "HideOneHanded", defaultValue: true, "Whether one-handed items should be hidden while climbing a ladder (false in vanilla)");
			HideTwoHanded = new LocalConfigEntry<bool>(configFile, "General", "HideTwoHanded", defaultValue: true, "Whether two-handed items should be hidden while climbing a ladder (false in vanilla)");
			ExtensionTime = new SyncedConfigEntry<float>(configFile, "Extension Ladders", "ExtensionTime", 0f, new ConfigDescription("How long extension ladders should stay extended, in seconds (0 for permanent) (20 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), Array.Empty<object>()), 20f);
			ExtensionSpeedMultiplier = new SyncedConfigEntry<float>(configFile, "Extension Ladders", "ExtensionSpeedMultiplier", 1f, new ConfigDescription("Multiplies how fast the ladder extends once activated (1 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()), 1f);
			ExtensionDelay = new SyncedConfigEntry<float>(configFile, "Extension Ladders", "ExtensionDelay", 1f, new ConfigDescription("How long before the ladder begins to extend once activated, in seconds (1 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()), 1f);
			FallSpeedMultiplier = new SyncedConfigEntry<float>(configFile, "Extension Ladders", "FallSpeedMultiplier", 1f, new ConfigDescription("Multiplies how fast the ladder falls once fully extended (1 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()), 1f);
			FallDelay = new SyncedConfigEntry<float>(configFile, "Extension Ladders", "FallDelay", 0.4f, new ConfigDescription("How long before the ladder begins to fall once fully extended, in seconds (0.4 in vanilla)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()), 0.4f);
			EnableKillTrigger = new SyncedConfigEntry<bool>(configFile, "Extension Ladders", "EnableKillTrigger", defaultValue: true, "Whether extension ladders should kill players they land on (true in vanilla)", vanillaValue: true);
			HoldToPickup = new LocalConfigEntry<bool>(configFile, "Extension Ladders", "HoldToPickup", defaultValue: true, "Whether the interact key needs to be held to pick up an activated extension ladder");
			HoldTime = new LocalConfigEntry<float>(configFile, "Extension Ladders", "HoldTime", 0.5f, new ConfigDescription("How long the interact key must be held if holdToPickup is true, in seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			DebugMode = new LocalConfigEntry<bool>(configFile, "Debug", "DebugMode", defaultValue: false, "Displays debug messages in the BepInEx console if true");
			ClearOrphanedEntries(configFile);
			configFile.Save();
			configFile.SaveOnConfigSet = true;
		}

		private static void ClearOrphanedEntries(ConfigFile configFile)
		{
			((Dictionary<ConfigDefinition, string>)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(configFile)).Clear();
		}
	}
	public class LocalConfigEntry<T> : CustomConfigEntry<T>
	{
		public override T Value => ConfigEntry.Value;

		public LocalConfigEntry(ConfigFile configFile, string section, string key, T defaultValue, ConfigDescription configDescription)
			: base(configFile, section, key, defaultValue, configDescription)
		{
			Init();
		}

		public LocalConfigEntry(ConfigFile configFile, string section, string key, T defaultValue, string configDescription)
			: this(configFile, section, key, defaultValue, new ConfigDescription(configDescription, (AcceptableValueBase)null, Array.Empty<object>()))
		{
		}//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected O, but got Unknown


		protected override void LethalConfigCompat()
		{
			LethalConfig.AddConfigEntry<T>(ConfigEntry);
		}
	}
	public class SyncedConfig : NetworkBehaviour
	{
		internal readonly NetworkVariable<float> ClimbSpeedMultiplier = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<float> SprintingClimbSpeedMultiplier = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<float> TransitionSpeedMultiplier = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<bool> AllowTwoHanded = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<float> ExtensionTime = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<float> ExtensionSpeedMultiplier = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<float> ExtensionDelay = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<float> FallSpeedMultiplier = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<float> FallDelay = new NetworkVariable<float>(0f, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal readonly NetworkVariable<bool> EnableKillTrigger = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		internal NetworkVariableBase[] NetworkVariables;

		public static SyncedConfig Instance { get; private set; }

		internal static event Action OnInitialized;

		internal static void Initialize(Scene sceneName, LoadSceneMode sceneEnum)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (!(((Scene)(ref sceneName)).name != "SampleSceneRelay"))
			{
				GameObject val = new GameObject("BetterLaddersSyncedConfig");
				val.AddComponent<NetworkObject>();
				Instance = val.AddComponent<SyncedConfig>();
				BetterLaddersPlugin.Logger.LogInfo((object)("Initialized " + ((Object)val).name));
			}
		}

		public override void OnNetworkSpawn()
		{
			BetterLaddersPlugin.Logger.LogInfo((object)"SyncedConfig network spawned");
			SyncedConfig.OnInitialized?.Invoke();
			Action onInitialized = SyncedConfig.OnInitialized;
			if (onInitialized != null)
			{
				ArrayHelpers.Clear<Delegate>(onInitialized.GetInvocationList());
			}
			BetterLaddersPlugin.Logger.LogInfo((object)"Finished initializing NetworkVariables");
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		public void RequestChangeItemVisibilityRpc(NetworkBehaviourReference itemReference, bool visible)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1)
			{
				RpcAttributeParams val = default(RpcAttributeParams);
				RpcParams val2 = default(RpcParams);
				FastBufferWriter val3 = ((NetworkBehaviour)this).__beginSendRpc(3987140488u, val2, val, (SendTo)5, (RpcDelivery)0);
				((FastBufferWriter)(ref val3)).WriteValueSafe<NetworkBehaviourReference>(ref itemReference, default(ForNetworkSerializable));
				((FastBufferWriter)(ref val3)).WriteValueSafe<bool>(ref visible, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendRpc(ref val3, 3987140488u, val2, val, (SendTo)5, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1)
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			GrabbableObject val4 = default(GrabbableObject);
			if (!((NetworkBehaviourReference)(ref itemReference)).TryGet<GrabbableObject>(ref val4, (NetworkManager)null))
			{
				BetterLaddersPlugin.Logger.LogWarning((object)"Failed to get item from reference while hiding item");
				return;
			}
			PlayerControllerB playerHeldBy = val4.playerHeldBy;
			if (!((Object)(object)playerHeldBy == (Object)null) && ((LocalConfig.Instance.HideOneHanded.Value && !playerHeldBy.twoHanded) || (LocalConfig.Instance.HideTwoHanded.Value && playerHeldBy.twoHanded)))
			{
				BetterLaddersPlugin.Logger.LogInfo((object)("Hiding item visibility for " + playerHeldBy.playerUsername));
				val4.EnableItemMeshes(visible);
			}
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		public void RequestStartChangeAnimationSpeedRpc(NetworkBehaviourReference playerReference)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1)
			{
				RpcAttributeParams val = default(RpcAttributeParams);
				RpcParams val2 = default(RpcParams);
				FastBufferWriter val3 = ((NetworkBehaviour)this).__beginSendRpc(1239607073u, val2, val, (SendTo)5, (RpcDelivery)0);
				((FastBufferWriter)(ref val3)).WriteValueSafe<NetworkBehaviourReference>(ref playerReference, default(ForNetworkSerializable));
				((NetworkBehaviour)this).__endSendRpc(ref val3, 1239607073u, val2, val, (SendTo)5, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1)
			{
				base.__rpc_exec_stage = (__RpcExecStage)0;
				PlayerControllerB val4 = default(PlayerControllerB);
				if (!((NetworkBehaviourReference)(ref playerReference)).TryGet<PlayerControllerB>(ref val4, (NetworkManager)null))
				{
					BetterLaddersPlugin.Logger.LogWarning((object)"Failed to get player from reference while starting animation speed coroutine");
				}
				else
				{
					((MonoBehaviour)val4).StartCoroutine(ClimbSpeed.SetAnimationSpeed(val4));
				}
			}
		}

		private void Awake()
		{
			NetworkVariables = (NetworkVariableBase[])(object)new NetworkVariableBase[10]
			{
				(NetworkVariableBase)ClimbSpeedMultiplier,
				(NetworkVariableBase)SprintingClimbSpeedMultiplier,
				(NetworkVariableBase)TransitionSpeedMultiplier,
				(NetworkVariableBase)AllowTwoHanded,
				(NetworkVariableBase)ExtensionTime,
				(NetworkVariableBase)ExtensionSpeedMultiplier,
				(NetworkVariableBase)ExtensionDelay,
				(NetworkVariableBase)FallSpeedMultiplier,
				(NetworkVariableBase)FallDelay,
				(NetworkVariableBase)EnableKillTrigger
			};
		}

		protected override void __initializeVariables()
		{
			if (ClimbSpeedMultiplier == null)
			{
				throw new Exception("SyncedConfig.ClimbSpeedMultiplier cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ClimbSpeedMultiplier).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ClimbSpeedMultiplier, "ClimbSpeedMultiplier");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ClimbSpeedMultiplier);
			if (SprintingClimbSpeedMultiplier == null)
			{
				throw new Exception("SyncedConfig.SprintingClimbSpeedMultiplier cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)SprintingClimbSpeedMultiplier).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)SprintingClimbSpeedMultiplier, "SprintingClimbSpeedMultiplier");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)SprintingClimbSpeedMultiplier);
			if (TransitionSpeedMultiplier == null)
			{
				throw new Exception("SyncedConfig.TransitionSpeedMultiplier cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)TransitionSpeedMultiplier).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)TransitionSpeedMultiplier, "TransitionSpeedMultiplier");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)TransitionSpeedMultiplier);
			if (AllowTwoHanded == null)
			{
				throw new Exception("SyncedConfig.AllowTwoHanded cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)AllowTwoHanded).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)AllowTwoHanded, "AllowTwoHanded");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)AllowTwoHanded);
			if (ExtensionTime == null)
			{
				throw new Exception("SyncedConfig.ExtensionTime cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ExtensionTime).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ExtensionTime, "ExtensionTime");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ExtensionTime);
			if (ExtensionSpeedMultiplier == null)
			{
				throw new Exception("SyncedConfig.ExtensionSpeedMultiplier cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ExtensionSpeedMultiplier).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ExtensionSpeedMultiplier, "ExtensionSpeedMultiplier");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ExtensionSpeedMultiplier);
			if (ExtensionDelay == null)
			{
				throw new Exception("SyncedConfig.ExtensionDelay cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)ExtensionDelay).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)ExtensionDelay, "ExtensionDelay");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)ExtensionDelay);
			if (FallSpeedMultiplier == null)
			{
				throw new Exception("SyncedConfig.FallSpeedMultiplier cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)FallSpeedMultiplier).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)FallSpeedMultiplier, "FallSpeedMultiplier");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)FallSpeedMultiplier);
			if (FallDelay == null)
			{
				throw new Exception("SyncedConfig.FallDelay cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)FallDelay).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)FallDelay, "FallDelay");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)FallDelay);
			if (EnableKillTrigger == null)
			{
				throw new Exception("SyncedConfig.EnableKillTrigger cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)EnableKillTrigger).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)EnableKillTrigger, "EnableKillTrigger");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)EnableKillTrigger);
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(3987140488u, new RpcReceiveHandler(__rpc_handler_3987140488), "RequestChangeItemVisibilityRpc");
			((NetworkBehaviour)this).__registerRpc(1239607073u, new RpcReceiveHandler(__rpc_handler_1239607073), "RequestStartChangeAnimationSpeedRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_3987140488(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkBehaviourReference itemReference = default(NetworkBehaviourReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkBehaviourReference>(ref itemReference, default(ForNetworkSerializable));
				bool visible = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref visible, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((SyncedConfig)(object)target).RequestChangeItemVisibilityRpc(itemReference, visible);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1239607073(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkBehaviourReference playerReference = default(NetworkBehaviourReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkBehaviourReference>(ref playerReference, default(ForNetworkSerializable));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((SyncedConfig)(object)target).RequestStartChangeAnimationSpeedRpc(playerReference);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "SyncedConfig";
		}
	}
	internal static class Counter
	{
		public static int Count;
	}
	public class SyncedConfigEntry<T> : CustomConfigEntry<T>
	{
		public readonly T VanillaValue;

		private readonly int _id;

		private static bool IsHost
		{
			get
			{
				if (!NetworkManager.Singleton.IsHost)
				{
					return NetworkManager.Singleton.IsServer;
				}
				return true;
			}
		}

		private static bool InMainMenu
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				Scene activeScene = SceneManager.GetActiveScene();
				return ((Scene)(ref activeScene)).name == "MainMenu";
			}
		}

		private string ConfigName => ((ConfigEntryBase)ConfigEntry).Definition.Key;

		private NetworkVariable<T> NetworkVariable => (NetworkVariable<T>)(object)SyncedConfig.Instance.NetworkVariables[_id];

		public override T Value
		{
			get
			{
				if (!IsHost && !((NetworkBehaviour)SyncedConfig.Instance).IsSpawned)
				{
					return VanillaValue;
				}
				return NetworkVariable.Value;
			}
		}

		public SyncedConfigEntry(ConfigFile configFile, string section, string key, T defaultValue, ConfigDescription configDescription, T vanillaValue)
			: base(configFile, section + " (Synced)", key, defaultValue, configDescription)
		{
			Init();
			_id = Counter.Count++;
			VanillaValue = vanillaValue;
			ConfigEntry.SettingChanged += OnSettingChanged;
			SyncedConfig.OnInitialized += delegate
			{
				if (IsHost)
				{
					BetterLaddersPlugin.Logger.LogInfo((object)$"[HOST] Setting initial value for {ConfigName} NetworkVariable to {ConfigEntry.Value}");
					NetworkVariable.Value = ConfigEntry.Value;
				}
				else
				{
					NetworkVariable<T> networkVariable = NetworkVariable;
					networkVariable.OnValueChanged = (OnValueChangedDelegate<T>)(object)Delegate.Combine((Delegate?)(object)networkVariable.OnValueChanged, (Delegate?)(object)(OnValueChangedDelegate<T>)delegate(T oldValue, T newValue)
					{
						BetterLaddersPlugin.Logger.LogInfo((object)$"[CLIENT] Host changed NetworkVariable for {ConfigName} to {newValue}");
					});
				}
			};
		}

		public SyncedConfigEntry(ConfigFile configFile, string section, string key, T defaultValue, string configDescription, T vanillaValue)
			: this(configFile, section, key, defaultValue, new ConfigDescription(configDescription, (AcceptableValueBase)null, Array.Empty<object>()), vanillaValue)
		{
		}//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Expected O, but got Unknown


		private void OnSettingChanged(object sender, EventArgs args)
		{
			T value = ConfigEntry.Value;
			if (NetworkManager.Singleton.IsHost && ((NetworkBehaviour)SyncedConfig.Instance).IsSpawned)
			{
				BetterLaddersPlugin.Logger.LogInfo((object)$"[HOST] Changed {ConfigName} to {value}, updating NetworkVariable...");
				NetworkVariable.Value = value;
			}
		}

		private (bool, string) CanModifyCallback()
		{
			if (IsHost || InMainMenu)
			{
				return (true, "");
			}
			if (!IsHost && !((NetworkBehaviour)SyncedConfig.Instance).IsSpawned && !InMainMenu)
			{
				return (false, $"Host is missing BetterLadders; using vanilla value of {VanillaValue}");
			}
			string text = ((typeof(T) == typeof(float)) ? ((float)(object)Value).ToString("0.00") : Value.ToString());
			return (false, "Using host's value of " + text);
		}

		protected override void LethalConfigCompat()
		{
			LethalConfig.AddConfigEntry<T>(ConfigEntry, CanModifyCallback);
		}
	}
}
namespace BetterLadders.Compatibility
{
	internal static class LethalConfig
	{
		internal static bool IsInstalled { get; private set; }

		internal static void Init()
		{
			IsInstalled = true;
		}

		internal static void AddConfigEntry<T>(ConfigEntry<T> configEntry, Func<(bool allowed, string reason)> canModifyCallback = null)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			BetterLaddersPlugin.Logger.LogInfo((object)("Setting up LethalConfig entry for " + ((ConfigEntryBase)configEntry).Definition.Key));
			LethalConfigManager.SkipAutoGenFor((ConfigEntryBase)(object)configEntry);
			Type typeFromHandle = typeof(T);
			BaseConfigItem val;
			if (typeFromHandle == typeof(float))
			{
				val = (BaseConfigItem)new FloatSliderConfigItem(configEntry as ConfigEntry<float>, Options<FloatSliderOptions>());
			}
			else
			{
				if (!(typeFromHandle == typeof(bool)))
				{
					throw new NotImplementedException($"{typeof(T)} not implemented for Compatibility.LethalConfig.SetupConfigEntry<T>");
				}
				val = (BaseConfigItem)new BoolCheckBoxConfigItem(configEntry as ConfigEntry<bool>, Options<BoolCheckBoxOptions>());
			}
			LethalConfigManager.AddConfigItem(val);
			TOptions Options<TOptions>() where TOptions : BaseOptions, new()
			{
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				object obj = new TOptions();
				((BaseOptions)(TOptions)obj).RequiresRestart = false;
				obj = (((BaseOptions)(TOptions)obj).CanModifyCallback = ((canModifyCallback == null) ? ((CanModifyDelegate)null) : ((CanModifyDelegate)(() => CanModifyResult.op_Implicit(canModifyCallback())))));
				return (TOptions)obj;
			}
		}
	}
	internal static class LobbyCompatibility
	{
		internal static void Init(BepInPlugin info)
		{
			PluginHelper.RegisterPlugin(info.GUID, info.Version, (CompatibilityLevel)0, (VersionStrictness)2);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<float>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<float>();
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
		}
	}
}
namespace e3s1.BetterLadders.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}