Decompiled source of IamScoutmaster v0.7.3

plugins/Thanks.I_am_Scoutmaster.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Thanks.I_am_Scoutmaster")]
[assembly: AssemblyDescription("Control the PEAK Scoutmaster as the local player.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Thanks")]
[assembly: AssemblyProduct("I'm Scoutmaster")]
[assembly: AssemblyCopyright("Copyright 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0ee091f4-9b49-4593-a95d-af67533313c8")]
[assembly: AssemblyFileVersion("0.7.14.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.7.14.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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;
		}
	}
}
namespace ImScoutmaster
{
	public sealed class ControlledScoutmasterVisualSync : MonoBehaviour
	{
		private Character _character;

		private PhotonView _view;

		public void Initialize(Character character, PhotonView view)
		{
			_character = (((Object)(object)character != (Object)null) ? character : ((Component)this).GetComponent<Character>());
			_view = (((Object)(object)view != (Object)null) ? view : ((Component)this).GetComponent<PhotonView>());
		}

		private void Awake()
		{
			Initialize(_character, _view);
		}

		private void Update()
		{
			if ((Object)(object)_character == (Object)null)
			{
				_character = ((Component)this).GetComponent<Character>();
			}
			if ((Object)(object)_character != (Object)null)
			{
				Plugin.EnsureControlledScoutmasterRegistered(_character);
			}
		}

		private void OnDestroy()
		{
			Plugin.UnregisterControlledScoutmasterInstance(_character, _view);
		}
	}
	[BepInPlugin("com.github.Thanks.ImScoutmaster", "I'm Scoutmaster", "0.7.14")]
	public sealed class Plugin : BaseUnityPlugin, IInRoomCallbacks
	{
		private enum ConfigKey
		{
			ToggleKey,
			StaminaRefill,
			ThrowForce,
			ThrowUpBias,
			ThrowFallSeconds,
			ThrowMaxDistance,
			ThirdPersonHeightOffset,
			ThirdPersonDistance,
			SourceStashDistance,
			RestoreAtScoutmasterPosition,
			RestoreGroundOffset,
			HideHudWhileTransformed,
			VerboseLogs
		}

		private readonly struct RendererVisualState
		{
			public readonly bool Enabled;

			public readonly bool ForceRenderingOff;

			public RendererVisualState(bool enabled, bool forceRenderingOff)
			{
				Enabled = enabled;
				ForceRenderingOff = forceRenderingOff;
			}
		}

		private sealed class ActiveScoutmasterSession
		{
			private readonly struct BodypartPhysicsState
			{
				public readonly Rigidbody Rig;

				public readonly bool IsKinematic;

				public readonly bool DetectCollisions;

				public readonly bool UseGravity;

				public BodypartPhysicsState(Rigidbody rig)
				{
					Rig = rig;
					IsKinematic = (Object)(object)rig != (Object)null && rig.isKinematic;
					DetectCollisions = (Object)(object)rig != (Object)null && rig.detectCollisions;
					UseGravity = (Object)(object)rig != (Object)null && rig.useGravity;
				}
			}

			private Character _sourceCharacter;

			private readonly GameObject _scoutmasterObject;

			private readonly Scoutmaster _scoutmaster;

			private readonly Character _scoutmasterCharacter;

			private readonly Vector3 _sourceStartPosition;

			private readonly Vector3 _sourceStashPosition;

			private readonly Quaternion _sourceStartRotation;

			private readonly bool _sourceWasActive;

			private readonly List<BodypartPhysicsState> _sourceBodypartPhysicsStates = new List<BodypartPhysicsState>();

			private PlayerScoutmasterController _controller;

			private bool _sourcePhysicsSuspended;

			private bool _sourceViewDisabledByMod;

			private bool _sourceViewSyncFrozenByMod;

			private ViewSynchronization _sourceViewSynchronizationBackup;

			private bool _sourceSyncerDisabledByMod;

			private bool _sourceStashBroadcastPending;

			private float _nextSourceStashReaffirmTime;

			private const float MaxUnsafeRestoreFallbackVerticalDrift = 10f;

			private const float MaxRestoreAnchorHorizontalDrift = 4f;

			private const float MaxRestoreVerticalError = 8f;

			public bool IsActive
			{
				get
				{
					if ((Object)(object)_sourceCharacter != (Object)null && (Object)(object)_scoutmasterObject != (Object)null && (Object)(object)_scoutmaster != (Object)null)
					{
						return (Object)(object)_scoutmasterCharacter != (Object)null;
					}
					return false;
				}
			}

			public ActiveScoutmasterSession(Character sourceCharacter, GameObject scoutmasterObject, Scoutmaster scoutmaster, Character scoutmasterCharacter, bool sourceWasActive, Vector3 transformAnchor)
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				_sourceCharacter = sourceCharacter;
				_scoutmasterObject = scoutmasterObject;
				_scoutmaster = scoutmaster;
				_scoutmasterCharacter = scoutmasterCharacter;
				_sourceStartPosition = transformAnchor;
				_sourceStashPosition = ResolveSourceStashPosition(_sourceStartPosition);
				_sourceStartRotation = GetSpawnRotation(sourceCharacter);
				_sourceWasActive = sourceWasActive;
			}

			private static Vector3 ResolveSourceStashPosition(Vector3 startPosition)
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				float num = Mathf.Max(SourceStashDistance.Value, 10f);
				if (TryFindStandingGroundBelow(startPosition, 600f, out var groundHit))
				{
					return ((RaycastHit)(ref groundHit)).point + Vector3.down * Mathf.Max(num, 25f);
				}
				return startPosition + Vector3.down * (num + 400f);
			}

			public IEnumerator Enter()
			{
				PreconfigureScoutmasterForLocalControl();
				_controller = _scoutmasterObject.GetComponent<PlayerScoutmasterController>() ?? _scoutmasterObject.AddComponent<PlayerScoutmasterController>();
				_controller.Initialize(_sourceCharacter, _scoutmaster, _scoutmasterCharacter);
				RegisterControlledScoutmaster(_scoutmaster);
				Character.localCharacter = _scoutmasterCharacter;
				SetGameObjectActive(_scoutmasterObject, active: true);
				AlignScoutmasterBodyToSource();
				yield return null;
				AlignScoutmasterBodyToSource();
				PrepareScoutmaster();
				CopyLookStateForRestore(_sourceCharacter, _scoutmasterCharacter, _sourceStartRotation);
				SetCameraOverride(_scoutmasterCharacter);
				_viewScoutmasterObject = _scoutmasterObject;
				UpdateScoutmasterHudState();
				RestoreRendererVisibility(_scoutmasterObject);
				if (!_scoutmasterPhysicsWarmedUp)
				{
					yield return (object)new WaitForSecondsRealtime(0.25f);
					EnableScoutmasterPhysics();
					_scoutmasterPhysicsWarmedUp = true;
				}
				_controller.ActivateDynamicRagdollControl();
				HideSourceCharacter();
				yield return (object)new WaitForSecondsRealtime(0.1f);
				if (PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)
				{
					try
					{
						PhotonNetwork.SendAllOutgoingCommands();
					}
					catch (Exception ex)
					{
						LogVerbose("Failed to flush source stash position over network: " + ex.Message);
					}
				}
				FreezeSourceNetworkSync();
				_sourceStashBroadcastPending = false;
				Character.localCharacter = _scoutmasterCharacter;
				LogVerbose("Entered Scoutmaster form.");
				LogPhotonViewDuplicateScan("entered-scoutmaster-form");
			}

			private void PreconfigureScoutmasterForLocalControl()
			{
				_scoutmasterCharacter.isScoutmaster = true;
				_scoutmasterCharacter.isZombie = false;
			}

			private void AlignScoutmasterBodyToSource()
			{
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: 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_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: 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_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null || (Object)(object)_scoutmasterObject == (Object)null)
				{
					return;
				}
				try
				{
					Vector3 val = (IsFiniteVector(_sourceStartPosition) ? _sourceStartPosition : _sourceCharacter.Center);
					SetCharacterPositionImmediate(_scoutmasterCharacter, val, _sourceStartRotation);
					Vector3 center = _scoutmasterCharacter.Center;
					if (!IsFiniteVector(center) || !IsFiniteVector(val) || Vector3.Distance(center, val) > 3f)
					{
						ReanchorScoutmasterBodyToSource(val);
					}
					AlignCharacterFeetToGround(_scoutmasterCharacter, _sourceCharacter);
					_scoutmasterCharacter.data.currentRagdollControll = 1f;
					_scoutmasterCharacter.data.fallSeconds = 0f;
					_scoutmasterCharacter.data.isGrounded = (Object)(object)_sourceCharacter.data != (Object)null && _sourceCharacter.data.isGrounded;
					_scoutmasterCharacter.data.groundPos = (((Object)(object)_sourceCharacter.data != (Object)null) ? _sourceCharacter.data.groundPos : _sourceCharacter.Center);
					Physics.SyncTransforms();
					if (_scoutmasterPhysicsWarmedUp)
					{
						EnableScoutmasterPhysics();
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to align controlled body: " + ex.Message));
					}
				}
			}

			private void ReanchorScoutmasterBodyToSource(Vector3 sourceCenter)
			{
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: 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_0100: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				//IL_0110: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				if (_scoutmasterCharacter?.refs?.ragdoll?.partList == null || _sourceCharacter?.refs?.ragdoll?.partList == null)
				{
					return;
				}
				try
				{
					((Component)_scoutmasterCharacter).transform.SetPositionAndRotation(sourceCenter, _sourceStartRotation);
					List<Bodypart> partList = _sourceCharacter.refs.ragdoll.partList;
					List<Bodypart> partList2 = _scoutmasterCharacter.refs.ragdoll.partList;
					for (int i = 0; i < partList2.Count; i++)
					{
						Bodypart val = partList2[i];
						if ((Object)(object)val == (Object)null)
						{
							continue;
						}
						Vector3 position = sourceCenter;
						if (i < partList.Count && (Object)(object)partList[i] != (Object)null)
						{
							Bodypart val2 = partList[i];
							Vector3 val3 = (((Object)(object)val2.Rig != (Object)null) ? val2.Rig.position : val2.transform.position);
							if (IsFiniteVector(val3))
							{
								position = val3;
							}
						}
						if ((Object)(object)val.Rig != (Object)null)
						{
							val.Rig.position = position;
							if (!val.Rig.isKinematic)
							{
								val.Rig.linearVelocity = Vector3.zero;
								val.Rig.angularVelocity = Vector3.zero;
							}
						}
						else if ((Object)(object)val.transform != (Object)null)
						{
							val.transform.position = position;
						}
					}
				}
				catch
				{
				}
			}

			private void EnableScoutmasterPhysics()
			{
				if ((Object)(object)_scoutmasterCharacter == (Object)null || _scoutmasterCharacter.refs?.ragdoll?.partList == null)
				{
					return;
				}
				try
				{
					foreach (Bodypart part in _scoutmasterCharacter.refs.ragdoll.partList)
					{
						Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
						if (!((Object)(object)val == (Object)null))
						{
							val.isKinematic = false;
							val.detectCollisions = true;
							val.useGravity = true;
							val.WakeUp();
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to enable controlled physics: " + ex.Message));
					}
				}
			}

			public void Tick()
			{
				if (!IsActive)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[I'm Scoutmaster] Session became inactive.");
					}
					Instance?.ExitScoutmasterForm(restorePlayer: true);
					return;
				}
				Character.localCharacter = _scoutmasterCharacter;
				KeepScoutmasterAwake();
				if (!_sourceStashBroadcastPending)
				{
					KeepSourceOutOfPlay();
					FollowSourceCharacterToControlledBodySafely();
				}
			}

			private void FollowSourceCharacterToControlledBody()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0110: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null)
				{
					return;
				}
				try
				{
					Vector3 center = _scoutmasterCharacter.Center;
					if (!IsFiniteVector(center))
					{
						return;
					}
					Vector3 val = center - _sourceCharacter.Center;
					if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
					{
						return;
					}
					Transform transform = ((Component)_sourceCharacter).transform;
					transform.position += val;
					if (_sourceCharacter.refs?.ragdoll?.partList == null)
					{
						return;
					}
					foreach (Bodypart part in _sourceCharacter.refs.ragdoll.partList)
					{
						if (!((Object)(object)part == (Object)null))
						{
							if ((Object)(object)part.Rig != (Object)null)
							{
								Rigidbody rig = part.Rig;
								rig.position += val;
							}
							else if ((Object)(object)part.transform != (Object)null)
							{
								Transform transform2 = part.transform;
								transform2.position += val;
							}
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to follow source character to controlled body: " + ex.Message));
					}
				}
			}

			private void FollowSourceCharacterToControlledBodySafely()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: 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_0073: 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_004b: 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_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: 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)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null)
				{
					return;
				}
				try
				{
					Vector3 center = _scoutmasterCharacter.Center;
					if (!IsFiniteVector(center))
					{
						return;
					}
					Vector3 center2 = _sourceCharacter.Center;
					if (IsFiniteVector(center2))
					{
						Vector3 val = center - center2;
						if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
						{
							return;
						}
					}
					Quaternion val2 = ((Component)_scoutmasterCharacter).transform.rotation;
					if (!IsFiniteQuaternion(val2))
					{
						val2 = _sourceStartRotation;
					}
					SetCharacterPositionImmediate(_sourceCharacter, center, val2);
					SanitizeCharacterBodyparts(_sourceCharacter, center, val2);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to safely follow source character to controlled body: " + ex.Message));
					}
				}
			}

			public void Exit(bool restorePlayer)
			{
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				if (restorePlayer && (Object)(object)_sourceCharacter == (Object)null)
				{
					Character val = TryRecoverOriginalLocalCharacter();
					if ((Object)(object)val != (Object)null)
					{
						_sourceCharacter = val;
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)("[I'm Scoutmaster] Recovered source character reference during exit: " + ((Object)val).name + "."));
						}
					}
				}
				Vector3 position = ResolveRestorePosition();
				Quaternion val2 = ResolveRestoreRotation();
				if ((Object)(object)_controller != (Object)null)
				{
					((Behaviour)_controller).enabled = false;
				}
				RestoreRendererVisibility(_scoutmasterObject);
				ClearCameraOverride();
				_viewScoutmasterObject = null;
				RestoreHudAfterScoutmaster();
				if (restorePlayer && (Object)(object)_sourceCharacter != (Object)null)
				{
					CopyLookStateForRestore(_scoutmasterCharacter, _sourceCharacter, val2);
					RestoreSourceCharacter(position, val2);
					SanitizeCharacterLookState(_sourceCharacter);
					ForcePlayerCharacterLookup(_sourceCharacter);
					Character.localCharacter = _sourceCharacter;
					BeginCameraRestoreAssist(_sourceCharacter);
				}
				UnregisterStashedSourceCharacter(_sourceCharacter);
				ResumeSourceNetworkSync();
				UnregisterControlledScoutmaster(_scoutmaster);
				BeginPeakStatsCleanupGraceWindow();
				CleanupPeakStatsUi(aggressive: true);
				DestroyScoutmasterObject(_scoutmasterObject);
				LogVerbose("Exited Scoutmaster form.");
				LogPhotonViewDuplicateScan("exited-scoutmaster-form");
			}

			private Vector3 ResolveRestorePosition()
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: 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)
				//IL_006c: 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_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				bool num = RestoreAtScoutmasterPosition == null || RestoreAtScoutmasterPosition.Value;
				Vector3 requestedPosition = _sourceStartPosition;
				if (num && (Object)(object)_scoutmasterCharacter != (Object)null)
				{
					Vector3 center = _scoutmasterCharacter.Center;
					if (IsFiniteVector(center))
					{
						requestedPosition = center;
					}
					else
					{
						Vector3 position = ((Component)_scoutmasterCharacter).transform.position;
						if (IsFiniteVector(position))
						{
							requestedPosition = position;
						}
					}
				}
				return ResolveSafeRestorePosition(requestedPosition, _scoutmasterCharacter, _sourceCharacter, _sourceStartPosition);
			}

			private Quaternion ResolveRestoreRotation()
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: 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_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_scoutmasterCharacter == (Object)null)
				{
					return _sourceStartRotation;
				}
				Vector3 val = Vector3.ProjectOnPlane(((Component)_scoutmasterCharacter).transform.rotation * Vector3.forward, Vector3.up);
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null)
				{
					val = _scoutmasterCharacter.data.lookDirection_Flat;
				}
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null)
				{
					val = Vector3.ProjectOnPlane(_scoutmasterCharacter.data.lookDirection, Vector3.up);
				}
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
				{
					return _sourceStartRotation;
				}
				return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
			}

			private static Character TryRecoverOriginalLocalCharacter()
			{
				try
				{
					Player localPlayer = Player.localPlayer;
					object obj;
					if (localPlayer == null)
					{
						obj = null;
					}
					else
					{
						PhotonView photonView = ((MonoBehaviourPun)localPlayer).photonView;
						obj = ((photonView != null) ? photonView.Owner : null);
					}
					Player val = (Player)obj;
					if (val == null || Character.AllCharacters == null)
					{
						return null;
					}
					foreach (Character allCharacter in Character.AllCharacters)
					{
						if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && !((Object)(object)((MonoBehaviourPun)allCharacter).photonView == (Object)null) && ((MonoBehaviourPun)allCharacter).photonView.Owner == val && !IsControlledScoutmasterCharacter(allCharacter) && !allCharacter.isZombie && !allCharacter.isScoutmaster)
						{
							return allCharacter;
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to recover original local character: " + ex.Message));
					}
				}
				return null;
			}

			private static Vector3 GetRestoreAnchor(Character character)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: 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)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: 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_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: 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_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: 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_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)character == (Object)null)
				{
					return Vector3.zero;
				}
				Vector3 center = character.Center;
				if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos))
				{
					Vector3 groundPos = character.data.groundPos;
					Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up);
					if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f)
					{
						return groundPos;
					}
				}
				if (IsFiniteVector(center))
				{
					return center;
				}
				Vector3 head = character.Head;
				if (!IsFiniteVector(head))
				{
					return ((Component)character).transform.position;
				}
				return head;
			}

			private static void AlignCharacterFeetToGround(Character controlledCharacter, Character sourceCharacter)
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//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_006b: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)controlledCharacter == (Object)null) && !((Object)(object)sourceCharacter == (Object)null) && TryGetCharacterGroundY(sourceCharacter, out var groundY) && TryGetCharacterGroundY(controlledCharacter, out var groundY2))
				{
					float num = groundY - groundY2;
					if (!float.IsNaN(num) && !float.IsInfinity(num) && !(num <= 0.001f) && !(num > 2f))
					{
						SetCharacterPositionImmediate(controlledCharacter, controlledCharacter.Center + Vector3.up * num, ((Component)controlledCharacter).transform.rotation);
					}
				}
			}

			private static bool TryGetCharacterGroundY(Character character, out float groundY)
			{
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: 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_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: 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_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: 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_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				groundY = 0f;
				if ((Object)(object)character == (Object)null)
				{
					return false;
				}
				Vector3 center = character.Center;
				if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos))
				{
					Vector3 groundPos = character.data.groundPos;
					Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up);
					if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f)
					{
						groundY = groundPos.y;
						return true;
					}
				}
				if (TryGetCharacterColliderBottomY(character, out groundY))
				{
					return true;
				}
				if (IsFiniteVector(center))
				{
					groundY = center.y;
					return true;
				}
				Vector3 position = ((Component)character).transform.position;
				if (!IsFiniteVector(position))
				{
					return false;
				}
				groundY = position.y;
				return true;
			}

			private static bool TryGetCharacterColliderBottomY(Character character, out float bottomY)
			{
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: 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_0094: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				bottomY = 0f;
				if (character?.refs?.ragdoll?.partList == null)
				{
					return false;
				}
				bool flag = false;
				foreach (Bodypart part in character.refs.ragdoll.partList)
				{
					if ((Object)(object)part == (Object)null)
					{
						continue;
					}
					Collider[] componentsInChildren = ((Component)part).GetComponentsInChildren<Collider>(true);
					if (componentsInChildren != null)
					{
						Collider[] array = componentsInChildren;
						foreach (Collider val in array)
						{
							if (!((Object)(object)val == (Object)null) && val.enabled)
							{
								Bounds bounds = val.bounds;
								Vector3 min = ((Bounds)(ref bounds)).min;
								if (IsFiniteVector(min) && (!flag || min.y < bottomY))
								{
									bottomY = min.y;
									flag = true;
								}
							}
						}
					}
					Vector3 val2 = (((Object)(object)part.Rig != (Object)null) ? part.Rig.position : part.transform.position);
					if (IsFiniteVector(val2) && (!flag || val2.y < bottomY))
					{
						bottomY = val2.y;
						flag = true;
					}
				}
				return flag;
			}

			private unsafe static Vector3 ResolveSafeRestorePosition(Vector3 requestedPosition, Character scoutmasterCharacter, Character sourceCharacter, Vector3 fallbackPosition)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: 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_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: 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_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0116: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_0117: 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_012f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: Unknown result type (might be due to invalid IL or missing references)
				//IL_0188: Unknown result type (might be due to invalid IL or missing references)
				//IL_0189: Unknown result type (might be due to invalid IL or missing references)
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0194: Unknown result type (might be due to invalid IL or missing references)
				float num = Mathf.Clamp(RestoreGroundOffset.Value, 0.2f, 5f);
				Vector3 val = (IsFiniteVector(requestedPosition) ? requestedPosition : fallbackPosition);
				if (!IsFiniteVector(val))
				{
					val = (((Object)(object)sourceCharacter != (Object)null) ? ((Component)sourceCharacter).transform.position : Vector3.zero);
				}
				if (TryFindRestoreGround(val + Vector3.up * 5f, 30f, scoutmasterCharacter, sourceCharacter, out var groundHit) || TryFindRestoreGround(val + Vector3.up * 12f, 80f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGroundUpward(val, 80f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGround(fallbackPosition + Vector3.up * 5f, 60f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGround(fallbackPosition + Vector3.up * 60f, 200f, scoutmasterCharacter, sourceCharacter, out groundHit))
				{
					return ((RaycastHit)(ref groundHit)).point + Vector3.up * num;
				}
				Vector3 val2 = (IsFiniteVector(fallbackPosition) ? fallbackPosition : val);
				if ((Object)(object)sourceCharacter != (Object)null && !IsFiniteVector(val2))
				{
					val2 = ((Component)sourceCharacter).transform.position;
				}
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[I'm Scoutmaster] No restore ground found below or above anchor " + ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString() + "; restoring at safe fallback " + ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString() + " instead."));
				}
				return val2 + Vector3.up * num;
			}

			private static bool TryFindRestoreGroundUpward(Vector3 origin, float distance, Character scoutmasterCharacter, Character sourceCharacter, out RaycastHit groundHit)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				groundHit = default(RaycastHit);
				if (!IsFiniteVector(origin))
				{
					return false;
				}
				RaycastHit[] array;
				try
				{
					array = Physics.RaycastAll(origin, Vector3.up, distance, -1, (QueryTriggerInteraction)1);
				}
				catch
				{
					return false;
				}
				Array.Sort(array, (RaycastHit left, RaycastHit right) => ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance));
				RaycastHit[] array2 = array;
				for (int num = 0; num < array2.Length; num++)
				{
					RaycastHit val = array2[num];
					if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).collider.isTrigger && !(Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up) > 0.2f) && !IsRestoreIgnoredCollider(((RaycastHit)(ref val)).collider, scoutmasterCharacter, sourceCharacter))
					{
						if (TryFindRestoreGround(((RaycastHit)(ref val)).point + Vector3.up * 12f, 30f, scoutmasterCharacter, sourceCharacter, out var groundHit2))
						{
							groundHit = groundHit2;
						}
						else
						{
							groundHit = val;
						}
						return true;
					}
				}
				return false;
			}

			private static bool TryFindRestoreGround(Vector3 origin, float distance, Character scoutmasterCharacter, Character sourceCharacter, out RaycastHit groundHit)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: 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)
				groundHit = default(RaycastHit);
				if (!IsFiniteVector(origin))
				{
					return false;
				}
				RaycastHit[] array;
				try
				{
					array = Physics.RaycastAll(origin, Vector3.down, distance, -1, (QueryTriggerInteraction)1);
				}
				catch
				{
					return false;
				}
				Array.Sort(array, (RaycastHit left, RaycastHit right) => ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance));
				RaycastHit[] array2 = array;
				for (int num = 0; num < array2.Length; num++)
				{
					RaycastHit val = array2[num];
					if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).collider.isTrigger && !(Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up) < -0.2f) && !IsRestoreIgnoredCollider(((RaycastHit)(ref val)).collider, scoutmasterCharacter, sourceCharacter))
					{
						groundHit = val;
						return true;
					}
				}
				return false;
			}

			private static bool IsRestoreIgnoredCollider(Collider collider, Character scoutmasterCharacter, Character sourceCharacter)
			{
				if ((Object)(object)collider == (Object)null)
				{
					return true;
				}
				Transform transform = ((Component)collider).transform;
				if (!IsColliderOwnedBy(transform, scoutmasterCharacter))
				{
					return IsColliderOwnedBy(transform, sourceCharacter);
				}
				return true;
			}

			private static bool IsColliderOwnedBy(Transform colliderTransform, Character character)
			{
				if ((Object)(object)colliderTransform == (Object)null || (Object)(object)character == (Object)null)
				{
					return false;
				}
				Transform transform = ((Component)character).transform;
				if (!((Object)(object)colliderTransform == (Object)(object)transform))
				{
					return colliderTransform.IsChildOf(transform);
				}
				return true;
			}

			private static bool IsFiniteVector(Vector3 value)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if (IsFiniteFloat(value.x) && IsFiniteFloat(value.y))
				{
					return IsFiniteFloat(value.z);
				}
				return false;
			}

			private static bool IsFiniteFloat(float value)
			{
				if (!float.IsNaN(value))
				{
					return !float.IsInfinity(value);
				}
				return false;
			}

			private void PrepareScoutmaster()
			{
				ClearScoutmasterAiState(_scoutmaster);
				_scoutmasterCharacter.isScoutmaster = true;
				_scoutmasterCharacter.isZombie = false;
				_scoutmasterCharacter.data.isScoutmaster = true;
				SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false);
				_scoutmasterCharacter.data.zombified = false;
				_scoutmasterCharacter.data.passedOut = false;
				_scoutmasterCharacter.data.fullyPassedOut = false;
				_scoutmasterCharacter.data.fallSeconds = 0f;
				_scoutmasterCharacter.data.currentRagdollControll = 1f;
				_scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill());
				_scoutmasterCharacter.data.extraStamina = 0f;
				ClearAssistJumpState(_scoutmasterCharacter);
			}

			private void HideSourceCharacter()
			{
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null)
				{
					return;
				}
				try
				{
					_sourceStashBroadcastPending = true;
					RegisterStashedSourceCharacter(_sourceCharacter);
					_sourceCharacter.data.fallSeconds = 0f;
					_sourceCharacter.data.passedOut = false;
					_sourceCharacter.data.fullyPassedOut = false;
					ClearAssistJumpState(_sourceCharacter);
					if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf)
					{
						((Component)_sourceCharacter).gameObject.SetActive(true);
					}
					HideSourceRenderers(((Component)_sourceCharacter).gameObject);
					SetCharacterPositionImmediate(_sourceCharacter, _sourceStashPosition, ((Component)_sourceCharacter).transform.rotation);
					SuspendSourcePhysics();
					SendSourceCharacterOutOfPlay(_sourceStashPosition);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to stash source character: " + ex.Message));
					}
				}
			}

			private void RestoreSourceCharacter(Vector3 position, Quaternion rotation)
			{
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_0103: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: Unknown result type (might be due to invalid IL or missing references)
				//IL_0150: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					_sourceStashBroadcastPending = false;
					if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf)
					{
						((Component)_sourceCharacter).gameObject.SetActive(true);
					}
					SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false);
					_sourceCharacter.data.zombified = false;
					_sourceCharacter.isZombie = false;
					_sourceCharacter.data.passedOut = false;
					_sourceCharacter.data.fullyPassedOut = false;
					_sourceCharacter.data.fallSeconds = 0f;
					_sourceCharacter.data.deathTimer = 0f;
					_sourceCharacter.data.currentRagdollControll = 1f;
					_sourceCharacter.data.isGrounded = false;
					_sourceCharacter.data.sinceGrounded = 0f;
					_sourceCharacter.data.groundedFor = 0f;
					_sourceCharacter.data.groundPos = position;
					_sourceCharacter.data.avarageVelocity = Vector3.zero;
					_sourceCharacter.data.avarageLastFrameVelocity = Vector3.zero;
					ClearAssistJumpState(_sourceCharacter);
					SetCharacterPositionImmediate(_sourceCharacter, position, rotation);
					SanitizeCharacterBodyparts(_sourceCharacter, position, rotation);
					ResumeSourceNetworkSync();
					SendSourceCharacterRestore(position);
					SetCharacterPositionImmediate(_sourceCharacter, position, rotation);
					SanitizeCharacterBodyparts(_sourceCharacter, position, rotation);
					RestoreSourcePhysics();
					RestoreSourceRenderers(((Component)_sourceCharacter).gameObject);
					UnregisterStashedSourceCharacter(_sourceCharacter);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source character: " + ex.Message));
					}
				}
			}

			private void SendSourceCharacterOutOfPlay(Vector3 stashPosition)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				SendSourceCharacterStateRpc(stashPosition, "[I'm Scoutmaster] Failed to move source character out of play: ");
			}

			private void FreezeSourceNetworkSync()
			{
				//IL_0077: 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_0069: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null)
				{
					return;
				}
				try
				{
					PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView;
					if ((Object)(object)photonView != (Object)null)
					{
						if (((Behaviour)photonView).enabled)
						{
							((Behaviour)photonView).enabled = false;
							_sourceViewDisabledByMod = true;
							LogVerbose("Froze source character network sync while stashed.");
							LogObjectPhotonViewState("freeze-source", ((Component)_sourceCharacter).gameObject);
						}
						if (!_sourceViewSyncFrozenByMod)
						{
							_sourceViewSynchronizationBackup = photonView.Synchronization;
							_sourceViewSyncFrozenByMod = true;
						}
						photonView.Synchronization = (ViewSynchronization)0;
					}
					CharacterSyncer component = ((Component)_sourceCharacter).GetComponent<CharacterSyncer>();
					if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled)
					{
						((Behaviour)component).enabled = false;
						_sourceSyncerDisabledByMod = true;
						LogVerbose("Disabled source CharacterSyncer while stashed.");
					}
				}
				catch (Exception ex)
				{
					LogVerbose("Failed to freeze source character network sync: " + ex.Message);
				}
			}

			private void ResumeSourceNetworkSync()
			{
				//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)
				if ((!_sourceViewDisabledByMod && !_sourceViewSyncFrozenByMod && !_sourceSyncerDisabledByMod) || (Object)(object)_sourceCharacter == (Object)null)
				{
					return;
				}
				try
				{
					PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView;
					if ((Object)(object)photonView != (Object)null)
					{
						if (_sourceViewDisabledByMod && !((Behaviour)photonView).enabled)
						{
							((Behaviour)photonView).enabled = true;
							LogVerbose("Resumed source character network sync for restore.");
						}
						if (_sourceViewSyncFrozenByMod)
						{
							photonView.Synchronization = _sourceViewSynchronizationBackup;
							_sourceViewSyncFrozenByMod = false;
						}
					}
					if (_sourceSyncerDisabledByMod)
					{
						CharacterSyncer component = ((Component)_sourceCharacter).GetComponent<CharacterSyncer>();
						if ((Object)(object)component != (Object)null && !((Behaviour)component).enabled)
						{
							((Behaviour)component).enabled = true;
							LogVerbose("Re-enabled source CharacterSyncer for restore.");
						}
						_sourceSyncerDisabledByMod = false;
					}
					LogObjectPhotonViewState("resume-source", ((Component)_sourceCharacter).gameObject);
					LogPhotonViewDuplicateScan("after-resume-source");
					_sourceViewDisabledByMod = false;
				}
				catch (Exception ex)
				{
					LogVerbose("Failed to resume source character network sync: " + ex.Message);
				}
			}

			private void ReaffirmSourceStashOverNetworkThrottled()
			{
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				if (Time.unscaledTime < _nextSourceStashReaffirmTime)
				{
					return;
				}
				_nextSourceStashReaffirmTime = Time.unscaledTime + 10f;
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode))
				{
					return;
				}
				try
				{
					((MonoBehaviourPun)_sourceCharacter).photonView.RPC("WarpPlayerRPC", (RpcTarget)1, new object[2] { _sourceStashPosition, false });
				}
				catch (Exception ex)
				{
					LogVerbose("Failed to reaffirm source stash position: " + ex.Message);
				}
			}

			internal void PushSourceStashPositionToPlayer(Player player)
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				if (player == null || (Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode))
				{
					return;
				}
				try
				{
					((MonoBehaviourPun)_sourceCharacter).photonView.RPC("WarpPlayerRPC", player, new object[2] { _sourceStashPosition, false });
					_nextSourceStashReaffirmTime = Time.unscaledTime + 10f;
					LogVerbose("Pushed source stash position to joining player " + player.ActorNumber + ".");
				}
				catch (Exception ex)
				{
					LogVerbose("Failed to push source stash position to joining player: " + ex.Message);
				}
			}

			private void SendSourceCharacterRestore(Vector3 restorePosition)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				SendSourceCharacterStateRpc(restorePosition, "[I'm Scoutmaster] Failed to restore source character over network: ");
			}

			private void SendSourceCharacterStateRpc(Vector3 position, string warningPrefix)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode))
				{
					return;
				}
				try
				{
					PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView;
					photonView.RPC("RPCA_UnFall", (RpcTarget)1, Array.Empty<object>());
					photonView.RPC("ReviveCharacter", (RpcTarget)1, new object[1] { false });
					photonView.RPC("WarpPlayerRPC", (RpcTarget)1, new object[2] { position, false });
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)(warningPrefix + ex.Message));
					}
				}
			}

			private void SuspendSourcePhysics()
			{
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || _sourceCharacter.refs?.ragdoll?.partList == null)
				{
					return;
				}
				try
				{
					if (!_sourcePhysicsSuspended)
					{
						_sourceBodypartPhysicsStates.Clear();
					}
					foreach (Bodypart part in _sourceCharacter.refs.ragdoll.partList)
					{
						Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
						if (!((Object)(object)val == (Object)null))
						{
							if (!_sourcePhysicsSuspended)
							{
								_sourceBodypartPhysicsStates.Add(new BodypartPhysicsState(val));
							}
							if (!val.isKinematic)
							{
								val.linearVelocity = Vector3.zero;
								val.angularVelocity = Vector3.zero;
							}
							val.detectCollisions = false;
							val.useGravity = false;
							val.isKinematic = true;
						}
					}
					_sourcePhysicsSuspended = true;
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to suspend source physics: " + ex.Message));
					}
				}
			}

			private void RestoreSourcePhysics()
			{
				//IL_0045: 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)
				if (!_sourcePhysicsSuspended)
				{
					return;
				}
				try
				{
					foreach (BodypartPhysicsState sourceBodypartPhysicsState in _sourceBodypartPhysicsStates)
					{
						Rigidbody rig = sourceBodypartPhysicsState.Rig;
						if (!((Object)(object)rig == (Object)null))
						{
							rig.isKinematic = sourceBodypartPhysicsState.IsKinematic;
							if (!rig.isKinematic)
							{
								rig.linearVelocity = Vector3.zero;
								rig.angularVelocity = Vector3.zero;
							}
							rig.detectCollisions = sourceBodypartPhysicsState.DetectCollisions;
							rig.useGravity = sourceBodypartPhysicsState.UseGravity;
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source physics: " + ex.Message));
					}
				}
				finally
				{
					_sourceBodypartPhysicsStates.Clear();
					_sourcePhysicsSuspended = false;
				}
			}

			private void KeepScoutmasterAwake()
			{
				if (!((Object)(object)_scoutmasterCharacter?.data == (Object)null))
				{
					ClearScoutmasterAiState(_scoutmaster);
					SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false);
					_scoutmasterCharacter.isScoutmaster = true;
					_scoutmasterCharacter.isZombie = false;
					_scoutmasterCharacter.data.isScoutmaster = true;
					_scoutmasterCharacter.data.zombified = false;
					if (!IsControlledScoutmasterIncapacitated(_scoutmasterCharacter))
					{
						_scoutmasterCharacter.data.passedOut = false;
						_scoutmasterCharacter.data.fullyPassedOut = false;
						_scoutmasterCharacter.data.fallSeconds = 0f;
						_scoutmasterCharacter.data.currentRagdollControll = 1f;
						_scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill());
						_scoutmasterCharacter.data.extraStamina = 0f;
						ClearAssistJumpState(_scoutmasterCharacter);
					}
				}
			}

			private void KeepSourceOutOfPlay()
			{
				if (!((Object)(object)_sourceCharacter == (Object)null) && !((Object)(object)_sourceCharacter.data == (Object)null))
				{
					if ((Object)(object)_sourceCharacter == (Object)(object)Character.localCharacter && (Object)(object)_scoutmasterCharacter != (Object)null)
					{
						Character.localCharacter = _scoutmasterCharacter;
					}
					SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false);
					_sourceCharacter.data.zombified = false;
					_sourceCharacter.data.passedOut = false;
					_sourceCharacter.data.fullyPassedOut = false;
					_sourceCharacter.data.fallSeconds = 0f;
					ClearAssistJumpState(_sourceCharacter);
					HideSourceRenderers(((Component)_sourceCharacter).gameObject);
					SuspendSourcePhysics();
					ReaffirmSourceStashOverNetworkThrottled();
				}
			}
		}

		private sealed class ImScoutmasterPrefabPool : IPunPrefabPool
		{
			private readonly IPunPrefabPool _inner;

			private static GameObject _cachedScoutmasterPrefab;

			private static GameObject _runtimePrefabRoot;

			private static bool _loggedMissingScoutmasterPrefab;

			private static GameObject _cachedCharacterPrefab;

			private static GameObject _runtimeCharacterPrefabRoot;

			private static bool _loggedMissingCharacterPrefab;

			public IPunPrefabPool Inner => _inner;

			public ImScoutmasterPrefabPool(IPunPrefabPool inner)
			{
				_inner = inner;
			}

			private static bool PruneStaleDefaultPoolResourceCache()
			{
				bool flag = false;
				try
				{
					Type typeFromHandle = typeof(DefaultPool);
					FieldInfo field = typeFromHandle.GetField("ResourceCache", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field == null)
					{
						return false;
					}
					HashSet<object> hashSet = new HashSet<object>();
					Queue<object> queue = new Queue<object>();
					IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
					if (prefabPool != null)
					{
						queue.Enqueue(prefabPool);
					}
					while (queue.Count > 0)
					{
						object obj = queue.Dequeue();
						if (obj == null || !hashSet.Add(obj))
						{
							continue;
						}
						if (typeFromHandle.IsInstanceOfType(obj))
						{
							flag |= PruneSingleDefaultPoolCache(field, obj);
						}
						Type type = obj.GetType();
						FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						foreach (FieldInfo fieldInfo in fields)
						{
							object obj2 = null;
							try
							{
								obj2 = fieldInfo.GetValue(obj);
							}
							catch
							{
							}
							if (obj2 == null)
							{
								continue;
							}
							if (typeFromHandle.IsInstanceOfType(obj2))
							{
								flag |= PruneSingleDefaultPoolCache(field, obj2);
								continue;
							}
							IPunPrefabPool val = (IPunPrefabPool)((obj2 is IPunPrefabPool) ? obj2 : null);
							if (val != null)
							{
								queue.Enqueue(val);
							}
						}
						PropertyInfo property = type.GetProperty("Inner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (!(property != null))
						{
							continue;
						}
						try
						{
							object? value = property.GetValue(obj);
							IPunPrefabPool val2 = (IPunPrefabPool)((value is IPunPrefabPool) ? value : null);
							if (val2 != null)
							{
								queue.Enqueue(val2);
							}
						}
						catch
						{
						}
					}
				}
				catch
				{
				}
				return flag;
			}

			private static bool PruneSingleDefaultPoolCache(FieldInfo resourceCacheField, object defaultPoolInstance)
			{
				try
				{
					if (resourceCacheField.GetValue(defaultPoolInstance) is IDictionary dictionary)
					{
						List<object> list = new List<object>();
						foreach (DictionaryEntry item in dictionary)
						{
							object? value = item.Value;
							Object val = (Object)((value is Object) ? value : null);
							if (val != null && val == (Object)null)
							{
								list.Add(item.Key);
							}
						}
						foreach (object item2 in list)
						{
							dictionary.Remove(item2);
						}
						return list.Count > 0;
					}
				}
				catch
				{
				}
				return false;
			}

			public GameObject Instantiate(string prefabId, Vector3 position, Quaternion rotation)
			{
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: 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_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
				bool flag = string.Equals(prefabId, "Character", StringComparison.Ordinal);
				bool flag2 = string.Equals(prefabId, "Character_Scoutmaster", StringComparison.Ordinal);
				if (!flag && !flag2)
				{
					try
					{
						IPunPrefabPool inner = _inner;
						return (inner != null) ? inner.Instantiate(prefabId, position, rotation) : null;
					}
					catch (Exception ex)
					{
						if (!PruneStaleDefaultPoolResourceCache())
						{
							throw;
						}
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogWarning((object)("[I'm Scoutmaster] Pruned stale Photon prefab cache for '" + prefabId + "' after instantiate failure (" + ex.Message + "); retrying."));
						}
						IPunPrefabPool inner2 = _inner;
						return (inner2 != null) ? inner2.Instantiate(prefabId, position, rotation) : null;
					}
				}
				GameObject val = null;
				try
				{
					IPunPrefabPool inner3 = _inner;
					val = ((inner3 != null) ? inner3.Instantiate(prefabId, position, rotation) : null);
				}
				catch (Exception ex2)
				{
					LogVerbose("Inner prefab pool failed to instantiate " + prefabId + ": " + ex2.Message);
					if (PruneStaleDefaultPoolResourceCache())
					{
						try
						{
							IPunPrefabPool inner4 = _inner;
							val = ((inner4 != null) ? inner4.Instantiate(prefabId, position, rotation) : null);
						}
						catch (Exception ex3)
						{
							LogVerbose("Retry failed for " + prefabId + ": " + ex3.Message);
						}
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					if (flag)
					{
						CacheCharacterPrefabBackup(val, "successful Character instantiation");
					}
					else
					{
						CacheScoutmasterPrefabBackup(val, "successful Scoutmaster instantiation");
					}
					LogObjectPhotonViewState("pool-instantiate(" + prefabId + ")", val);
					return val;
				}
				if (flag)
				{
					GameObject val2 = TryInstantiateCachedCharacterPrefab(position, rotation);
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
					if (!_loggedMissingCharacterPrefab)
					{
						_loggedMissingCharacterPrefab = true;
						ManualLogSource log2 = Log;
						if (log2 != null)
						{
							log2.LogWarning((object)"[I'm Scoutmaster] Could not instantiate Character from any pool, Resources, or cached runtime backup.");
						}
					}
					return null;
				}
				GameObject val3 = ResolveScoutmasterPrefab();
				if ((Object)(object)val3 == (Object)null)
				{
					if (!_loggedMissingScoutmasterPrefab)
					{
						_loggedMissingScoutmasterPrefab = true;
						ManualLogSource log3 = Log;
						if (log3 != null)
						{
							log3.LogWarning((object)"[I'm Scoutmaster] Could not resolve Character_Scoutmaster from the active prefab pool, Resources, or loaded Scoutmaster objects.");
						}
					}
					return null;
				}
				return InstantiatePrefabAsRuntimeObject(val3, position, rotation);
			}

			internal static GameObject ResolveScoutmasterPrefab()
			{
				if ((Object)(object)_cachedScoutmasterPrefab != (Object)null)
				{
					return _cachedScoutmasterPrefab;
				}
				_cachedScoutmasterPrefab = Resources.Load<GameObject>("Character_Scoutmaster");
				if ((Object)(object)_cachedScoutmasterPrefab != (Object)null)
				{
					return _cachedScoutmasterPrefab;
				}
				try
				{
					Scoutmaster val = FindLoadedScoutmasterPrefabSource();
					if ((Object)(object)val == (Object)null)
					{
						return null;
					}
					CacheScoutmasterPrefabBackup(((Component)val).gameObject, "loaded Scoutmaster object");
					return _cachedScoutmasterPrefab;
				}
				catch (Exception ex)
				{
					LogVerbose("Failed to build Character_Scoutmaster runtime prefab backup: " + ex.Message);
					return null;
				}
			}

			internal static void CacheScoutmasterPrefabBackup(GameObject sourceObject, string reason)
			{
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Expected O, but got Unknown
				if ((Object)(object)_cachedScoutmasterPrefab != (Object)null || (Object)(object)sourceObject == (Object)null)
				{
					return;
				}
				try
				{
					if (IsRuntimeScoutmasterPrefabBackup(sourceObject))
					{
						return;
					}
					Scoutmaster component = sourceObject.GetComponent<Scoutmaster>();
					Character component2 = sourceObject.GetComponent<Character>();
					PhotonView component3 = sourceObject.GetComponent<PhotonView>();
					if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null) && !((Object)(object)component3 == (Object)null))
					{
						if ((Object)(object)_runtimePrefabRoot == (Object)null)
						{
							_runtimePrefabRoot = new GameObject("ImScoutmaster_RuntimePrefabRoot");
							_runtimePrefabRoot.SetActive(false);
							Object.DontDestroyOnLoad((Object)(object)_runtimePrefabRoot);
						}
						_cachedScoutmasterPrefab = Object.Instantiate<GameObject>(sourceObject, _runtimePrefabRoot.transform);
						((Object)_cachedScoutmasterPrefab).name = "Character_Scoutmaster";
						_cachedScoutmasterPrefab.SetActive(false);
						ResetPhotonViewsForPrefabBackup(_cachedScoutmasterPrefab);
						_loggedMissingScoutmasterPrefab = false;
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)("[I'm Scoutmaster] Registered runtime network prefab backup for Character_Scoutmaster from " + reason + "."));
						}
					}
				}
				catch (Exception ex)
				{
					_cachedScoutmasterPrefab = null;
					LogVerbose("Failed to cache Character_Scoutmaster runtime prefab backup: " + ex.Message);
				}
			}

			private static Scoutmaster FindLoadedScoutmasterPrefabSource()
			{
				try
				{
					if (ScoutmasterAllScoutmastersField?.GetValue(null) is IEnumerable enumerable)
					{
						foreach (object item in enumerable)
						{
							Scoutmaster val = (Scoutmaster)((item is Scoutmaster) ? item : null);
							if (IsUsableScoutmasterPrefabSource(val, exactName: true))
							{
								return val;
							}
						}
						foreach (object item2 in enumerable)
						{
							Scoutmaster val2 = (Scoutmaster)((item2 is Scoutmaster) ? item2 : null);
							if (IsUsableScoutmasterPrefabSource(val2, exactName: false))
							{
								return val2;
							}
						}
					}
				}
				catch
				{
				}
				Scoutmaster[] array = Resources.FindObjectsOfTypeAll<Scoutmaster>();
				Scoutmaster[] array2 = array;
				foreach (Scoutmaster val3 in array2)
				{
					if (IsUsableScoutmasterPrefabSource(val3, exactName: true))
					{
						return val3;
					}
				}
				array2 = array;
				foreach (Scoutmaster val4 in array2)
				{
					if (IsUsableScoutmasterPrefabSource(val4, exactName: false))
					{
						return val4;
					}
				}
				try
				{
					GameObject[] array3 = Resources.FindObjectsOfTypeAll<GameObject>();
					foreach (GameObject val5 in array3)
					{
						if (!((Object)(object)val5 == (Object)null) && !IsRuntimeScoutmasterPrefabBackup(val5) && string.Equals(((Object)val5).name, "Character_Scoutmaster", StringComparison.Ordinal))
						{
							Scoutmaster component = val5.GetComponent<Scoutmaster>();
							if ((Object)(object)component != (Object)null && (Object)(object)val5.GetComponent<Character>() != (Object)null && (Object)(object)val5.GetComponent<PhotonView>() != (Object)null)
							{
								return component;
							}
						}
					}
				}
				catch
				{
				}
				return null;
			}

			private static bool IsUsableScoutmasterPrefabSource(Scoutmaster candidate, bool exactName)
			{
				if ((Object)(object)candidate == (Object)null || (Object)(object)((Component)candidate).gameObject == (Object)null || IsRuntimeScoutmasterPrefabBackup(((Component)candidate).gameObject))
				{
					return false;
				}
				if (exactName && !string.Equals(((Object)((Component)candidate).gameObject).name, "Character_Scoutmaster", StringComparison.Ordinal) && !string.Equals(((Object)((Component)candidate).gameObject).name, "Character_Scoutmaster(Clone)", StringComparison.Ordinal))
				{
					return false;
				}
				if ((Object)(object)((Component)candidate).GetComponent<Character>() != (Object)null)
				{
					return (Object)(object)((Component)candidate).GetComponent<PhotonView>() != (Object)null;
				}
				return false;
			}

			private static bool IsRuntimeScoutmasterPrefabBackup(GameObject obj)
			{
				if ((Object)(object)obj == (Object)null)
				{
					return false;
				}
				if ((Object)(object)_cachedScoutmasterPrefab != (Object)null && (Object)(object)obj == (Object)(object)_cachedScoutmasterPrefab)
				{
					return true;
				}
				Transform transform = obj.transform;
				if ((Object)(object)_runtimePrefabRoot != (Object)null && (Object)(object)transform != (Object)null)
				{
					if (!((Object)(object)transform == (Object)(object)_runtimePrefabRoot.transform))
					{
						return transform.IsChildOf(_runtimePrefabRoot.transform);
					}
					return true;
				}
				return false;
			}

			private static void ResetPhotonViewsForPrefabBackup(GameObject backup)
			{
				PhotonView[] componentsInChildren = backup.GetComponentsInChildren<PhotonView>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].ViewID = 0;
					componentsInChildren[i].sceneViewId = 0;
				}
			}

			private static void CacheCharacterPrefabBackup(GameObject sourceInstance, string reason)
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Expected O, but got Unknown
				if ((Object)(object)_cachedCharacterPrefab != (Object)null || (Object)(object)sourceInstance == (Object)null)
				{
					return;
				}
				try
				{
					if (!IsRuntimeCharacterPrefabBackup(sourceInstance) && !((Object)(object)sourceInstance.GetComponent<Character>() == (Object)null))
					{
						if ((Object)(object)_runtimeCharacterPrefabRoot == (Object)null)
						{
							_runtimeCharacterPrefabRoot = new GameObject("ImScoutmaster_RuntimeCharacterPrefabRoot");
							_runtimeCharacterPrefabRoot.SetActive(false);
							Object.DontDestroyOnLoad((Object)(object)_runtimeCharacterPrefabRoot);
						}
						_cachedCharacterPrefab = Object.Instantiate<GameObject>(sourceInstance, _runtimeCharacterPrefabRoot.transform);
						((Object)_cachedCharacterPrefab).name = "Character";
						_cachedCharacterPrefab.SetActive(false);
						ResetPhotonViewsForPrefabBackup(_cachedCharacterPrefab);
						_loggedMissingCharacterPrefab = false;
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)("[I'm Scoutmaster] Cached runtime Character prefab backup from " + reason + "."));
						}
					}
				}
				catch (Exception ex)
				{
					_cachedCharacterPrefab = null;
					LogVerbose("Failed to cache Character runtime prefab backup: " + ex.Message);
				}
			}

			private static bool IsRuntimeCharacterPrefabBackup(GameObject obj)
			{
				if ((Object)(object)obj == (Object)null)
				{
					return false;
				}
				if ((Object)(object)_cachedCharacterPrefab != (Object)null && (Object)(object)obj == (Object)(object)_cachedCharacterPrefab)
				{
					return true;
				}
				Transform transform = obj.transform;
				if ((Object)(object)_runtimeCharacterPrefabRoot != (Object)null && (Object)(object)transform != (Object)null)
				{
					if (!((Object)(object)transform == (Object)(object)_runtimeCharacterPrefabRoot.transform))
					{
						return transform.IsChildOf(_runtimeCharacterPrefabRoot.transform);
					}
					return true;
				}
				return false;
			}

			internal static bool IsRuntimePrefabBackupObject(GameObject obj)
			{
				if (!IsRuntimeScoutmasterPrefabBackup(obj))
				{
					return IsRuntimeCharacterPrefabBackup(obj);
				}
				return true;
			}

			private static GameObject TryInstantiateCachedCharacterPrefab(Vector3 position, Quaternion rotation)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_cachedCharacterPrefab != (Object)null)
				{
					GameObject val = InstantiatePrefabAsRuntimeObject(_cachedCharacterPrefab, position, rotation);
					if ((Object)(object)val != (Object)null)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogWarning((object)"[I'm Scoutmaster] Instantiated Character from cached runtime backup (small-exit recovery).");
						}
						return val;
					}
				}
				GameObject val2 = Resources.Load<GameObject>("Character");
				if ((Object)(object)val2 != (Object)null)
				{
					CacheCharacterPrefabBackup(val2, "Resources");
					return InstantiatePrefabAsRuntimeObject(val2, position, rotation);
				}
				if (TryCaptureCharacterPrefabFromChain(out var prefab))
				{
					CacheCharacterPrefabBackup(prefab, "prefab pool chain");
					return InstantiatePrefabAsRuntimeObject(prefab, position, rotation);
				}
				return null;
			}

			private static bool TryCaptureCharacterPrefabFromChain(out GameObject prefab)
			{
				prefab = null;
				try
				{
					HashSet<object> hashSet = new HashSet<object>();
					Queue<object> queue = new Queue<object>();
					IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool;
					if (prefabPool != null)
					{
						queue.Enqueue(prefabPool);
					}
					while (queue.Count > 0)
					{
						object obj = queue.Dequeue();
						if (obj == null || !hashSet.Add(obj))
						{
							continue;
						}
						Type type = obj.GetType();
						BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
						FieldInfo[] fields = type.GetFields(bindingAttr);
						foreach (FieldInfo fieldInfo in fields)
						{
							object value = null;
							try
							{
								value = fieldInfo.GetValue(fieldInfo.IsStatic ? null : obj);
							}
							catch
							{
							}
							if (TryUseCharacterPrefabPoolValue(value, queue, out prefab))
							{
								return true;
							}
						}
						PropertyInfo[] properties = type.GetProperties(bindingAttr);
						foreach (PropertyInfo propertyInfo in properties)
						{
							if (propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.CanRead)
							{
								object value2 = null;
								try
								{
									MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
									value2 = propertyInfo.GetValue((getMethod != null && getMethod.IsStatic) ? null : obj);
								}
								catch
								{
								}
								if (TryUseCharacterPrefabPoolValue(value2, queue, out prefab))
								{
									return true;
								}
							}
						}
					}
				}
				catch
				{
				}
				return false;
			}

			private static bool TryUseCharacterPrefabPoolValue(object value, Queue<object> pendingPools, out GameObject prefab)
			{
				prefab = null;
				if (value == null)
				{
					return false;
				}
				if (value is Dictionary<string, GameObject> dictionary && dictionary.TryGetValue("Character", out var value2) && IsUsableCharacterPrefabCandidate(value2))
				{
					prefab = value2;
					return true;
				}
				if (value is IDictionary dictionary2 && dictionary2.Contains("Character") && IsUsableCharacterPrefabCandidate((GameObject)/*isinst with value type is only supported in some contexts*/))
				{
					object? obj = dictionary2["Character"];
					prefab = (GameObject)((obj is GameObject) ? obj : null);
					return true;
				}
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if (val != null && IsUsableCharacterPrefabCandidate(val))
				{
					prefab = val;
					return true;
				}
				IPunPrefabPool val2 = (IPunPrefabPool)((value is IPunPrefabPool) ? value : null);
				if (val2 != null)
				{
					pendingPools.Enqueue(val2);
				}
				return false;
			}

			private static bool IsUsableCharacterPrefabCandidate(GameObject candidate)
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)candidate == (Object)null || (Object)(object)candidate.GetComponent<Character>() == (Object)null)
				{
					return false;
				}
				if (IsRuntimeCharacterPrefabBackup(candidate))
				{
					return true;
				}
				PhotonView component = candidate.GetComponent<PhotonView>();
				bool flag = (Object)(object)component != (Object)null && component.ViewID > 0;
				Scene scene = candidate.scene;
				bool num = !((Scene)(ref scene)).IsValid();
				bool flag2 = ((Object)candidate).name != null && ((Object)candidate).name.IndexOf("Backup", StringComparison.OrdinalIgnoreCase) >= 0;
				bool flag3 = !candidate.activeInHierarchy && !flag;
				return num || flag2 || flag3;
			}

			private static GameObject InstantiatePrefabAsRuntimeObject(GameObject prefab, Vector3 position, Quaternion rotation)
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)prefab == (Object)null)
				{
					return null;
				}
				bool activeSelf = prefab.activeSelf;
				if (activeSelf)
				{
					prefab.SetActive(false);
				}
				GameObject result = Object.Instantiate<GameObject>(prefab, position, rotation);
				if (activeSelf)
				{
					prefab.SetActive(true);
				}
				return result;
			}

			public void Destroy(GameObject gameObject)
			{
				IPunPrefabPool inner = _inner;
				if (inner != null)
				{
					inner.Destroy(gameObject);
				}
			}
		}

		public const string Id = "com.github.Thanks.ImScoutmaster";

		public const string Name = "I'm Scoutmaster";

		public const string Version = "0.7.14";

		private const string ScoutmasterResourceName = "Character_Scoutmaster";

		private const string CharacterResourceName = "Character";

		private const float ToggleHoldSeconds = 1f;

		private const float ManualFallShortPressMaxSeconds = 0.3f;

		private const float ToggleDebounceSeconds = 0.35f;

		private const int SimplifiedChineseLanguageIndex = 9;

		private const string ControlsConfigSectionName = "Controls";

		private const string ScoutmasterControlConfigSectionName = "Scoutmaster Control";

		private const string CameraConfigSectionName = "Camera";

		private const string PlayerRestoreConfigSectionName = "Player Restore";

		private const string HudConfigSectionName = "HUD";

		private const string DiagnosticsConfigSectionName = "Diagnostics";

		private const string ModConfigPluginGuid = "com.github.PEAKModding.PEAKLib.ModConfig";

		private const float ModConfigUiLocalizationIntervalSeconds = 0.25f;

		private const float CameraRestoreAssistSeconds = 0.4f;

		private const float CameraHealSeconds = 8f;

		private const float CameraHealMaxDistance = 100f;

		private const float CameraHealDefaultFieldOfView = 70f;

		private const float CameraPatrolIntervalSeconds = 0.5f;

		private const float CameraPatrolBackoffSeconds = 10f;

		private const int CameraPatrolMaxConsecutiveRepairs = 4;

		private const float ThirdPersonHeadTargetLiftMin = 0.35f;

		private const float ThirdPersonHeadTargetLiftMax = 1.35f;

		private const float ThirdPersonConfiguredTargetBlend = 0.25f;

		private const float ThirdPersonGroundMinHeight = 1.55f;

		private const float ThirdPersonCrouchGroundMinHeight = 1.15f;

		private const float ThirdPersonBodyFrameBlendStart = 0.45f;

		private const float ThirdPersonBodyFrameBlendFull = 0.95f;

		private const float ThirdPersonBodyFrameDownMaxBlend = 0.42f;

		private const float ThirdPersonBodyFrameUpMaxBlend = 0.3f;

		private const float ThirdPersonFocusForwardMin = 1.75f;

		private const float ThirdPersonFocusForwardMax = 4.25f;

		private const float ThirdPersonDownFocusDropMax = 1.15f;

		private const float ThirdPersonUpFocusLiftMax = 0.8f;

		private const float ThirdPartyCompatibilityRetryIntervalSeconds = 1f;

		private const float ClearBoostReticleTimer = 10f;

		private const float ControlledScoutmasterJumpVelocity = 10.5f;

		private const float ControlledScoutmasterJumpGroundClearance = 0.12f;

		private const float ControlledScoutmasterManualFallSeconds = 1.25f;

		private const float ControlledGrabAttachPointMaxHandDistance = 3.5f;

		private const string ControlledScoutmasterInstantiationMarker = "ImScoutmaster.ControlledScoutmaster";

		private const int ControlledScoutmasterNetworkProtocol = 1;

		private const float PrefabPoolWrapperRetryIntervalSeconds = 0.5f;

		private const float ScoutmasterPrefabRetrySeconds = 8f;

		private const float ScoutmasterPrefabWarmIntervalSeconds = 2f;

		private static readonly BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly PropertyInfo ConfigFileEntriesProperty = typeof(ConfigFile).GetProperty("Entries", InstanceFlags);

		private static readonly FieldInfo CharacterViewField = typeof(Character).GetField("view", InstanceFlags);

		private static readonly FieldInfo CharacterStartedField = typeof(Character).GetField("started", InstanceFlags);

		private static readonly FieldInfo CharacterSmoothedCamPosField = typeof(Character).GetField("smoothedCamPos", InstanceFlags);

		private static readonly MethodInfo CharacterGetBodypartMethod = typeof(Character).GetMethod("GetBodypart", InstanceFlags);

		private static readonly MethodInfo CharacterGetPartTypeMethod = typeof(Character).GetMethod("GetPartType", InstanceFlags);

		private static readonly FieldInfo CharacterDataCharacterField = typeof(CharacterData).GetField("character", InstanceFlags);

		private static readonly FieldInfo CharacterDataDeadField = typeof(CharacterData).GetField("_dead", InstanceFlags);

		private static readonly FieldInfo CharacterDataGrabbedPlayerField = typeof(CharacterData).GetField("grabbedPlayer", InstanceFlags);

		private static readonly MethodInfo CharacterFallMethod = typeof(Character).GetMethod("Fall", InstanceFlags, null, new Type[2]
		{
			typeof(float),
			typeof(float)
		}, null);

		private static readonly FieldInfo CharacterCustomizationCharacterField = typeof(CharacterCustomization).GetField("_character", InstanceFlags);

		private static readonly FieldInfo BodypartCharacterField = typeof(Bodypart).GetField("character", InstanceFlags);

		private static readonly FieldInfo ScoutmasterCurrentTargetField = typeof(Scoutmaster).GetField("_currentTarget", InstanceFlags);

		private static readonly FieldInfo ScoutmasterTargetForcedUntilField = typeof(Scoutmaster).GetField("targetForcedUntil", InstanceFlags);

		private static readonly FieldInfo ScoutmasterChillForSecondsField = typeof(Scoutmaster).GetField("chillForSeconds", InstanceFlags);

		private static readonly FieldInfo ScoutmasterIsThrowingField = typeof(Scoutmaster).GetField("isThrowing", InstanceFlags);

		private static readonly FieldInfo ScoutmasterAllScoutmastersField = typeof(Scoutmaster).GetField("AllScoutmasters", StaticFlags);

		private static readonly PropertyInfo MainCameraSpecCharacterProperty = typeof(MainCameraMovement).GetProperty("specCharacter", StaticFlags);

		private static readonly FieldInfo MainCameraIsSpectatingField = typeof(MainCameraMovement).GetField("isSpectating", InstanceFlags);

		private static readonly FieldInfo MainCameraRagdollCamField = typeof(MainCameraMovement).GetField("ragdollCam", InstanceFlags);

		private static readonly FieldInfo MainCameraCurrentForwardOffsetField = typeof(MainCameraMovement).GetField("currentForwardOffset", InstanceFlags);

		private static readonly FieldInfo MainCameraTargetPlayerPovPositionField = typeof(MainCameraMovement).GetField("targetPlayerPovPosition", InstanceFlags);

		private static readonly FieldInfo MainCameraPhysicsRotField = typeof(MainCameraMovement).GetField("physicsRot", InstanceFlags);

		private static readonly MethodInfo FindObjectsOfTypeByTypeMethod = typeof(Object).GetMethod("FindObjectsOfType", new Type[1] { typeof(Type) });

		private static readonly MethodInfo CharacterClimbingCanClimbMethod = typeof(CharacterClimbing).GetMethod("CanClimb", InstanceFlags, null, Type.EmptyTypes, null);

		private static readonly MethodInfo CharacterClimbingStartClimbRpcMethod = FindCharacterClimbingStartClimbRpcMethod();

		private static readonly FieldInfo CharacterClimbingClimbToggledOnField = typeof(CharacterClimbing).GetField("climbToggledOn", InstanceFlags);

		private static readonly FieldInfo CharacterClimbingSinceLastClimbStartedField = typeof(CharacterClimbing).GetField("sinceLastClimbStarted", InstanceFlags);

		private static readonly FieldInfo CharacterClimbingPlayerSlideField = typeof(CharacterClimbing).GetField("playerSlide", InstanceFlags);

		private static readonly FieldInfo CharacterClimbingPlayerSlideFieldRenamed = typeof(CharacterClimbing).GetField("_playerSlide", InstanceFlags);

		private static readonly PropertyInfo CharacterClimbingPlayerSlideProperty = typeof(CharacterClimbing).GetProperty("playerSlide", InstanceFlags);

		private static readonly MethodInfo CharacterGrabbingGrabAttachMethod = typeof(CharacterGrabbing).GetMethod("RPCA_GrabAttach", InstanceFlags);

		private static readonly PropertyInfo PlayerHandlerInstanceProperty = typeof(PlayerHandler).GetProperty("Instance", StaticFlags);

		private static readonly FieldInfo PlayerHandlerCharacterLookupField = typeof(PlayerHandler).GetField("m_playerCharacterLookup", InstanceFlags);

		private static readonly FieldInfo CharacterItemsCurrentSelectedSlotField = typeof(CharacterItems).GetField("currentSelectedSlot", InstanceFlags);

		private static readonly FieldInfo CharacterItemsLastSelectedSlotField = typeof(CharacterItems).GetField("lastSelectedSlot", InstanceFlags);

		private static readonly FieldInfo CharacterAfflictionsCharacterField = typeof(CharacterAfflictions).GetField("character", InstanceFlags);

		private static readonly object CharacterItemsNoneSlotValue = CreateOptionableNoneValue(CharacterItemsCurrentSelectedSlotField?.FieldType);

		private static FieldInfo PeakStatsStaminaBarsField;

		private static FieldInfo PeakStatsObservedCharacterField;

		private static FieldInfo PeakStatsAfflictionBarField;

		private static Type PeakStatsStaminaBarType;

		private static Type PeakStatsAfflictionType;

		private static float _peakStatsCleanupGraceUntil;

		private static bool _skipControlledCharacterFixedUpdate;

		private bool _characterFixedUpdateCompatibilityConfigured;

		private bool _loggedWaitingForPeakerHook;

		private bool _loggedPeakStatsTypesMissing;

		private float _nextPeakerGuardAttemptTime;

		private bool _peakStatsCompatibilityConfigured;

		private float _nextThirdPartyCompatibilityAttemptTime;

		private static ImScoutmasterPrefabPool _prefabPoolWrapper;

		private static float _nextPrefabPoolWrapperEnsureTime;

		private static bool _scoutmasterPhysicsWarmedUp;

		private static float _nextScoutmasterPrefabWarmTime;

		private readonly Harmony _harmony = new Harmony("com.github.Thanks.ImScoutmaster");

		private ActiveScoutmasterSession _session;

		private bool _switching;

		private float _lastToggleTime;

		private float _toggleHoldStartTime = -1f;

		private bool _toggleHoldTriggered;

		private bool _lastDetectedChineseLanguage;

		private bool _isRefreshingLanguage;

		private bool _pendingConfigFileLocalizationRefresh;

		private bool _pendingConfigFileLocalizationSave;

		private float _nextModConfigUiLocalizationTime;

		private static Transform _controlledScoutmasterCreationRoot;

		private static readonly HashSet<int> _controlledScoutmasterInstanceIds = new HashSet<int>();

		private static readonly HashSet<int> _controlledScoutmasterViewIds = new HashSet<int>();

		private static readonly HashSet<int> _controlledScoutmasterCharacterInstanceIds = new HashSet<int>();

		private static readonly Dictionary<int, int> _controlledScoutmasterOwnerActorNumbersByViewId = new Dictionary<int, int>();

		private static readonly Dictionary<int, Character> _controlledScoutmasterByOwnerActorNumber = new Dictionary<int, Character>();

		private static readonly HashSet<int> _stashedSourceCharacterIds = new HashSet<int>();

		private static readonly Dictionary<int, RendererVisualState> _rendererVisualStates = new Dictionary<int, RendererVisualState>();

		private static readonly Dictionary<int, RendererVisualState> _sourceRendererVisualStates = new Dictionary<int, RendererVisualState>();

		private static readonly Dictionary<int, bool> _sourceLightVisualStates = new Dictionary<int, bool>();

		private static Character _cameraOverrideCharacter;

		private static Character _cameraRestoreCharacter;

		private static float _cameraRestoreUntil;

		private static float _cameraHealUntil;

		private static float _nextCameraPatrolTime;

		private static int _cameraPatrolConsecutiveRepairs;

		private static Character _lastCameraPatrolCharacter;

		private static GameObject _viewScoutmasterObject;

		private static bool _hasSmoothedThirdPersonCameraPose;

		private static Vector3 _smoothedThirdPersonCameraPosition;

		private static Quaternion _smoothedThirdPersonCameraRotation = Quaternion.identity;

		private static GameObject _hudCanvasObject;

		private static GameObject _namesCanvasObject;

		private static bool _hudPreviousKnown;

		private static bool _namesPreviousKnown;

		private static bool _hudPreviousActive;

		private static bool _namesPreviousActive;

		private static bool _hudHiddenForScoutmaster;

		private const float MaxTransformGroundProbeDistance = 40f;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<KeyCode> ToggleKey { get; private set; }

		internal static ConfigEntry<float> StaminaRefill { get; private set; }

		internal static ConfigEntry<float> ThrowForce { get; private set; }

		internal static ConfigEntry<float> ThrowUpBias { get; private set; }

		internal static ConfigEntry<float> ThrowFallSeconds { get; private set; }

		internal static ConfigEntry<float> ThrowMaxDistance { get; private set; }

		internal static ConfigEntry<float> ThirdPersonHeightOffset { get; private set; }

		internal static ConfigEntry<float> ThirdPersonDistance { get; private set; }

		internal static ConfigEntry<float> SourceStashDistance { get; private set; }

		internal static ConfigEntry<bool> RestoreAtScoutmasterPosition { get; private set; }

		internal static ConfigEntry<float> RestoreGroundOffset { get; private set; }

		internal static ConfigEntry<bool> HideHudWhileTransformed { get; private set; }

		internal static ConfigEntry<bool> VerboseLogs { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_lastDetectedChineseLanguage = DetectChineseLanguage();
			BindConfig(_lastDetectedChineseLanguage);
			RegisterConfigChangeHandlers();
			MarkConfigFileLocalizationDirty(saveConfigFile: true);
			PatchHarmonyTolerantly();
			ConfigureCharacterFixedUpdateCompatibility();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Loaded version 0.7.14.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[I'm Scoutmaster] Config language: " + BuildLanguageDetectionSummary(_lastDetectedChineseLanguage)));
			ValidateReflectionMembers();
			PhotonNetwork.AddCallbackTarget((object)this);
		}

		private void PatchHarmonyTolerantly()
		{
			int num = 0;
			int num2 = 0;
			Type[] types = typeof(ScoutmasterHarmonyPatches).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type == null || !type.IsClass || (type.IsAbstract && !type.IsSealed) || !type.IsDefined(typeof(HarmonyPatch), inherit: false))
				{
					continue;
				}
				try
				{
					_harmony.CreateClassProcessor(type).Patch();
					num++;
				}
				catch (Exception ex)
				{
					num2++;
					ManualLogSource logger = ((BaseUnityPlugin)