Decompiled source of PossessMonster v1.0.11

PossessMonster.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Evo")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.11.0")]
[assembly: AssemblyInformationalVersion("1.0.11+475c919fdfe06408df3ba7876add9037e5ecd66f")]
[assembly: AssemblyProduct("PossessMonster")]
[assembly: AssemblyTitle("PossessMonster")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.11.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PossessMonster
{
	[RequireComponent(typeof(PhotonView))]
	[RequireComponent(typeof(Rigidbody))]
	public class PossessionController : MonoBehaviourPunCallbacks, IPunOwnershipCallbacks
	{
		private Camera? playerCamera;

		private Transform? cameraHolder;

		private Rigidbody? rb;

		private Animator? animator;

		private NavMeshAgent? navAgent;

		private List<Behaviour> disabledComponents = new List<Behaviour>();

		private static readonly string[] aiComponentNames = new string[8] { "EnemyRunner", "EnemyBeamer", "EnemyWalker", "EnemyShooter", "EnemyAI", "EnemyController", "AttackController", "EnemyRigidbody" };

		private float currentPitch = 0f;

		private bool isInitialized = false;

		public bool IsPossessedByPlayer => ((MonoBehaviourPun)this).photonView.IsMine && !IsServerControlled();

		private void Awake()
		{
			rb = ((Component)this).GetComponent<Rigidbody>();
			animator = ((Component)this).GetComponent<Animator>();
			navAgent = ((Component)this).GetComponent<NavMeshAgent>();
			PhotonNetwork.AddCallbackTarget((object)this);
			isInitialized = true;
		}

		private void OnDestroy()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
			ClientCleanup();
		}

		private bool IsServerControlled()
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			return !PossessMonsterPlugin.IsPossessing || (Object)(object)PossessMonsterPlugin.Instance == (Object)null;
		}

		public void OnOwnershipRequest(PhotonView targetView, Player requestingPlayer)
		{
			if (!((Object)(object)targetView != (Object)(object)((MonoBehaviourPun)this).photonView))
			{
				((MonoBehaviourPun)this).photonView.TransferOwnership(requestingPlayer);
			}
		}

		public void OnOwnershipTransfered(PhotonView targetView, Player previousOwner)
		{
			if (!((Object)(object)targetView != (Object)(object)((MonoBehaviourPun)this).photonView))
			{
				PossessMonsterPlugin.Logger.LogInfo((object)$"[Controller] Смена владельца: {previousOwner} -> {((MonoBehaviourPun)this).photonView.Owner}");
				if (((MonoBehaviourPun)this).photonView.IsMine)
				{
					OnPossessStart();
				}
				else
				{
					OnPossessEnd();
				}
			}
		}

		public void OnOwnershipTransferFailed(PhotonView targetView, Player senderOfFailedRequest)
		{
			PossessMonsterPlugin.Logger.LogWarning((object)$"[Controller] Не удалось передать права игроку {senderOfFailedRequest}");
		}

		public void OnPossessStart()
		{
			PossessMonsterPlugin.Logger.LogInfo((object)"[Controller] Я получил управление монстром!");
			DisableAI();
			SetupCamera();
			if ((Object)(object)PossessMonsterPlugin.Instance != (Object)null)
			{
				PossessMonsterPlugin.Instance.OnPossessionStart();
			}
		}

		public void ReleaseControl()
		{
			if (((MonoBehaviourPun)this).photonView.IsMine)
			{
				PossessMonsterPlugin.Logger.LogInfo((object)"[Controller] Отпускаю управление...");
				ClientCleanup();
				((MonoBehaviourPun)this).photonView.TransferOwnership(PhotonNetwork.MasterClient);
				if ((Object)(object)PossessMonsterPlugin.Instance != (Object)null)
				{
					PossessMonsterPlugin.Instance.OnPossessionEnd();
				}
			}
		}

		private void OnPossessEnd()
		{
			if ((Object)(object)cameraHolder != (Object)null)
			{
				ClientCleanup();
				if ((Object)(object)PossessMonsterPlugin.Instance != (Object)null)
				{
					PossessMonsterPlugin.Instance.OnPossessionEnd();
				}
			}
			if (PhotonNetwork.IsMasterClient && ((MonoBehaviourPun)this).photonView.IsMine)
			{
				EnableAI();
			}
		}

		private void Update()
		{
			if (isInitialized && IsPossessedByPlayer && !PossessMonsterPlugin.ShowMenu)
			{
				HandleCameraRotation();
				HandleInput();
			}
		}

		private void HandleInput()
		{
			if (Input.GetMouseButtonDown(0))
			{
				PerformAttack();
			}
		}

		private void FixedUpdate()
		{
			if (isInitialized && IsPossessedByPlayer)
			{
				HandleMovement();
			}
		}

		private void HandleMovement()
		{
			//IL_0072: 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)
			//IL_0083: 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_008e: 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_0097: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_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_00c8: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rb == (Object)null)
			{
				return;
			}
			float axis = Input.GetAxis("Horizontal");
			float axis2 = Input.GetAxis("Vertical");
			float value = PossessMonsterPlugin.monsterMoveSpeed.Value;
			float num = Input.GetAxis("Mouse X") * 2f;
			if (!PossessMonsterPlugin.ShowMenu)
			{
				((Component)this).transform.Rotate(Vector3.up, num);
			}
			Vector3 val = ((Component)this).transform.forward * axis2 + ((Component)this).transform.right * axis;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			if (((Vector3)(ref normalized)).magnitude > 0.1f)
			{
				Vector3 val2 = normalized * value;
				val2.y = rb.velocity.y;
				rb.velocity = Vector3.Lerp(rb.velocity, val2, Time.fixedDeltaTime * 10f);
				if ((Object)(object)animator != (Object)null)
				{
					animator.SetBool("IsWalking", true);
					animator.SetFloat("Speed", ((Vector3)(ref normalized)).magnitude);
				}
				return;
			}
			Vector3 velocity = rb.velocity;
			velocity.x = 0f;
			velocity.z = 0f;
			rb.velocity = velocity;
			if ((Object)(object)animator != (Object)null)
			{
				animator.SetBool("IsWalking", false);
				animator.SetFloat("Speed", 0f);
			}
		}

		private void HandleCameraRotation()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)cameraHolder == (Object)null))
			{
				float num = Input.GetAxis("Mouse Y") * 2f;
				currentPitch = Mathf.Clamp(currentPitch - num, -80f, 80f);
				cameraHolder.localRotation = Quaternion.Euler(currentPitch, 0f, 0f);
			}
		}

		private void PerformAttack()
		{
			if ((Object)(object)animator != (Object)null)
			{
				animator.SetTrigger("Attack");
			}
			Enemy component = ((Component)this).GetComponent<Enemy>();
			if ((Object)(object)component != (Object)null)
			{
				MethodInfo method = ((object)component).GetType().GetMethod("Attack", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null)
				{
					method.Invoke(component, null);
				}
			}
		}

		private void DisableAI()
		{
			if ((Object)(object)navAgent != (Object)null && ((Behaviour)navAgent).enabled)
			{
				navAgent.isStopped = true;
				((Behaviour)navAgent).enabled = false;
			}
			Behaviour[] components = ((Component)this).GetComponents<Behaviour>();
			Behaviour[] array = components;
			foreach (Behaviour val in array)
			{
				if (!((Object)(object)val == (Object)(object)this) && !(val is PhotonView) && !(val is Animator))
				{
					string name = ((object)val).GetType().Name;
					if (aiComponentNames.Contains(name) && val.enabled)
					{
						val.enabled = false;
						disabledComponents.Add(val);
					}
				}
			}
			if ((Object)(object)rb != (Object)null)
			{
				rb.isKinematic = false;
				rb.useGravity = true;
				rb.interpolation = (RigidbodyInterpolation)1;
				rb.freezeRotation = true;
			}
		}

		private void EnableAI()
		{
			if ((Object)(object)navAgent != (Object)null)
			{
				((Behaviour)navAgent).enabled = true;
			}
			foreach (Behaviour disabledComponent in disabledComponents)
			{
				if ((Object)(object)disabledComponent != (Object)null)
				{
					disabledComponent.enabled = true;
				}
			}
			disabledComponents.Clear();
			if ((Object)(object)rb != (Object)null)
			{
				rb.freezeRotation = false;
			}
		}

		private void SetupCamera()
		{
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = PossessMonsterPlugin.LocalPlayerHead;
			if ((Object)(object)val == (Object)null && (Object)(object)Camera.main != (Object)null)
			{
				val = ((Component)Camera.main).gameObject;
			}
			if ((Object)(object)val == (Object)null)
			{
				PossessMonsterPlugin.Logger.LogError((object)"Не удалось найти камеру для вселения!");
				return;
			}
			playerCamera = val.GetComponent<Camera>();
			if ((Object)(object)playerCamera == (Object)null)
			{
				return;
			}
			if ((Object)(object)cameraHolder == (Object)null)
			{
				cameraHolder = new GameObject("PossessCameraHolder").transform;
				Transform val2 = ((Component)this).transform.Find("Head");
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)this).transform.Find("head");
				}
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = ((Component)this).transform;
				}
				cameraHolder.SetParent(val2);
				cameraHolder.localPosition = Vector3.up * 1.5f;
				cameraHolder.localRotation = Quaternion.identity;
			}
			((Component)playerCamera).transform.SetParent(cameraHolder);
			((Component)playerCamera).transform.localPosition = Vector3.zero;
			((Component)playerCamera).transform.localRotation = Quaternion.identity;
			((Component)playerCamera).gameObject.SetActive(true);
		}

		private void ClientCleanup()
		{
			if ((Object)(object)playerCamera != (Object)null)
			{
				((Component)playerCamera).transform.SetParent((Transform)null);
				playerCamera = null;
			}
			if ((Object)(object)cameraHolder != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)cameraHolder).gameObject);
				cameraHolder = null;
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.evoscript.repo.possessmonster";

		public const string PLUGIN_NAME = "PossessMonster";

		public const string PLUGIN_VERSION = "1.0.11";
	}
	[BepInPlugin("com.evoscript.repo.possessmonster", "PossessMonster", "1.0.11")]
	public class PossessMonsterPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger = null;

		internal static PossessMonsterPlugin Instance = null;

		private Harmony harmony = null;

		internal static bool IsPlayerDead = false;

		internal static bool IsPossessing = false;

		internal static bool ShowMenu = false;

		internal static GameObject? LocalPlayerBody = null;

		internal static GameObject? LocalPlayerHead = null;

		internal static readonly List<GameObject> ActiveMonsters = new List<GameObject>();

		internal static ConfigEntry<KeyCode> toggleMenuKey = null;

		internal static ConfigEntry<KeyCode> exitPossessionKey = null;

		internal static ConfigEntry<float> monsterMoveSpeed = null;

		internal static ConfigEntry<bool> allowSpawnMonsters = null;

		private Vector2 scrollPosition;

		private float updateListTimer = 0f;

		private List<GameObject> uiCachedMonsters = new List<GameObject>();

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			LoadConfig();
			harmony = new Harmony("com.evoscript.repo.possessmonster");
			harmony.PatchAll();
			Logger.LogInfo((object)"Plugin PossessMonster initialized!");
		}

		private void LoadConfig()
		{
			toggleMenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Управление", "ToggleMenuKey", (KeyCode)109, "Показать/скрыть меню выбора монстров (если мертв)");
			exitPossessionKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Управление", "ExitPossessionKey", (KeyCode)103, "Клавиша для выхода из монстра");
			monsterMoveSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Геймплей", "MonsterMoveSpeed", 5f, "Скорость передвижения монстра");
			allowSpawnMonsters = ((BaseUnityPlugin)this).Config.Bind<bool>("Геймплей", "AllowSpawn", true, "Разрешить спавн новых монстров, если нет живых");
		}

		public void OnPlayerSpawned(GameObject playerBody)
		{
			Logger.LogInfo((object)">>> Игрок ВОЗРОДИЛСЯ");
			if (IsPossessing)
			{
				PossessNetwork.Instance?.RequestStopPossession();
			}
			IsPlayerDead = false;
			IsPossessing = false;
			ShowMenu = false;
			LocalPlayerBody = playerBody;
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
			LocalPlayerHead = null;
		}

		public void OnPlayerDied(GameObject playerBody)
		{
			if (!IsPlayerDead)
			{
				Logger.LogInfo((object)">>> Игрок УМЕР. Открываем меню выбора.");
				IsPlayerDead = true;
				IsPossessing = false;
				ShowMenu = true;
				LocalPlayerBody = playerBody;
				if ((Object)(object)PlayerController.instance != (Object)null && (Object)(object)PlayerController.instance.cameraGameObject != (Object)null)
				{
					LocalPlayerHead = PlayerController.instance.cameraGameObject;
				}
				else if ((Object)(object)Camera.main != (Object)null)
				{
					LocalPlayerHead = ((Component)Camera.main).gameObject;
				}
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		private void Update()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			if (Time.frameCount % 60 == 0)
			{
				ActiveMonsters.RemoveAll((GameObject m) => (Object)(object)m == (Object)null);
			}
			if (!IsPlayerDead)
			{
				return;
			}
			if (Input.GetKeyDown(toggleMenuKey.Value))
			{
				ShowMenu = !ShowMenu;
				if (!IsPossessing)
				{
					Cursor.lockState = (CursorLockMode)((!ShowMenu) ? 1 : 0);
					Cursor.visible = ShowMenu;
				}
			}
			if (IsPossessing && Input.GetKeyDown(exitPossessionKey.Value))
			{
				PossessNetwork.Instance?.RequestStopPossession();
				IsPossessing = false;
				ShowMenu = true;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}

		private void OnGUI()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			if (!IsPlayerDead || !ShowMenu || IsPossessing)
			{
				return;
			}
			if (Time.time - updateListTimer > 0.5f)
			{
				uiCachedMonsters = ActiveMonsters.Where((GameObject m) => (Object)(object)m != (Object)null).ToList();
				updateListTimer = Time.time;
			}
			float num = 300f;
			float num2 = 20f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)Screen.width - num - num2, num2, num, (float)Screen.height - num2 * 2f);
			GUI.Box(val, "Меню Вселения");
			GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 30f, ((Rect)(ref val)).width - 20f, ((Rect)(ref val)).height - 40f));
			if (GUILayout.Button("Обновить список", Array.Empty<GUILayoutOption>()))
			{
				uiCachedMonsters = ActiveMonsters.Where((GameObject m) => (Object)(object)m != (Object)null).ToList();
			}
			GUILayout.Space(10f);
			GUILayout.Label($"Доступно монстров: {uiCachedMonsters.Count}", Array.Empty<GUILayoutOption>());
			scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
			if (uiCachedMonsters.Count > 0)
			{
				GUI.backgroundColor = Color.yellow;
				if (GUILayout.Button("СЛУЧАЙНЫЙ МОНСТР", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }))
				{
					GameObject monster = uiCachedMonsters[Random.Range(0, uiCachedMonsters.Count)];
					TryPossess(monster);
				}
				GUI.backgroundColor = Color.white;
				GUILayout.Space(10f);
			}
			foreach (GameObject uiCachedMonster in uiCachedMonsters)
			{
				if (!((Object)(object)uiCachedMonster == (Object)null))
				{
					string arg = ((Object)uiCachedMonster).name.Replace("(Clone)", "");
					float num3 = Vector3.Distance(((Object)(object)LocalPlayerBody != (Object)null) ? LocalPlayerBody.transform.position : Vector3.zero, uiCachedMonster.transform.position);
					if (GUILayout.Button($"{arg} ({num3:F0}m)", Array.Empty<GUILayoutOption>()))
					{
						TryPossess(uiCachedMonster);
					}
				}
			}
			if (allowSpawnMonsters.Value)
			{
				GUILayout.Space(20f);
				GUILayout.Label("--- Спавн ---", Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Заспавнить Runner", Array.Empty<GUILayoutOption>()))
				{
					SpawnAndPossess("Enemies/Enemy - Runner");
				}
			}
			GUILayout.EndScrollView();
			GUILayout.EndArea();
		}

		private void TryPossess(GameObject monster)
		{
			if (!((Object)(object)monster == (Object)null))
			{
				PhotonView component = monster.GetComponent<PhotonView>();
				if ((Object)(object)component == (Object)null)
				{
					Logger.LogError((object)"У монстра нет PhotonView!");
					return;
				}
				if ((Object)(object)PossessNetwork.Instance == (Object)null)
				{
					Logger.LogError((object)"PossessNetwork не инициализирован!");
					return;
				}
				Logger.LogInfo((object)$"Попытка вселения в {((Object)monster).name} (ID: {component.ViewID})");
				PossessNetwork.Instance.RequestPossess(component.ViewID);
				ShowMenu = false;
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
		}

		private void SpawnAndPossess(string prefabName)
		{
			if ((Object)(object)PossessNetwork.Instance != (Object)null)
			{
				PossessNetwork.Instance.RequestSpawnAndPossess(prefabName);
				ShowMenu = false;
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
			}
		}

		public void OnPossessionStart()
		{
			IsPossessing = true;
			ShowMenu = false;
			Logger.LogInfo((object)"Режим вселения активирован.");
		}

		public void OnPossessionEnd()
		{
			IsPossessing = false;
			if (IsPlayerDead)
			{
				ShowMenu = true;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
			Logger.LogInfo((object)"Режим вселения деактивирован.");
		}
	}
	public class PossessNetwork : MonoBehaviour, IOnEventCallback
	{
		[CompilerGenerated]
		private sealed class <HandleSpawnRequest>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string prefabPath;

			public int requestorActorNr;

			public PossessNetwork <>4__this;

			private Player <requestor>5__1;

			private Vector3 <spawnPos>5__2;

			private GameObject <monster>5__3;

			private Exception <ex>5__4;

			private PhotonView <view>5__5;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<requestor>5__1 = null;
				<monster>5__3 = null;
				<ex>5__4 = null;
				<view>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//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)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: 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_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_0086: 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_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<requestor>5__1 = PhotonNetwork.CurrentRoom.GetPlayer(requestorActorNr, false);
					<spawnPos>5__2 = Vector3.zero;
					if ((Object)(object)PossessMonsterPlugin.LocalPlayerBody != (Object)null)
					{
						<spawnPos>5__2 = PossessMonsterPlugin.LocalPlayerBody.transform.position;
					}
					<spawnPos>5__2 += Vector3.up * 1f;
					PossessMonsterPlugin.Logger.LogInfo((object)$"[HOST] Спавн {prefabPath} для актера {requestorActorNr}");
					<monster>5__3 = null;
					try
					{
						<monster>5__3 = PhotonNetwork.InstantiateRoomObject(prefabPath, <spawnPos>5__2, Quaternion.identity, (byte)0, (object[])null);
					}
					catch (Exception ex)
					{
						<ex>5__4 = ex;
						PossessMonsterPlugin.Logger.LogError((object)("[HOST] Ошибка PhotonNetwork.Instantiate: " + <ex>5__4.Message));
						return false;
					}
					if ((Object)(object)<monster>5__3 != (Object)null)
					{
						<view>5__5 = <monster>5__3.GetComponent<PhotonView>();
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					break;
				case 1:
					<>1__state = -1;
					if ((Object)(object)<view>5__5 != (Object)null && <requestor>5__1 != null)
					{
						PossessMonsterPlugin.Logger.LogInfo((object)$"[HOST] Передача прав игроку {requestorActorNr}...");
						<view>5__5.TransferOwnership(<requestor>5__1);
					}
					<view>5__5 = null;
					break;
				}
				return false;
			}

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

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

		public static PossessNetwork? Instance;

		private const byte SpawnMonsterEventCode = 155;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}

		private void OnEnable()
		{
			PhotonNetwork.AddCallbackTarget((object)this);
		}

		private void OnDisable()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
		}

		public void RequestPossess(int viewID)
		{
			PhotonView val = PhotonView.Find(viewID);
			if ((Object)(object)val != (Object)null)
			{
				PossessMonsterPlugin.Logger.LogInfo((object)$"[CLIENT] Запрос прав на монстра {viewID}...");
				if ((Object)(object)((Component)val).GetComponent<PossessionController>() == (Object)null)
				{
					((Component)val).gameObject.AddComponent<PossessionController>();
				}
				val.RequestOwnership();
			}
			else
			{
				PossessMonsterPlugin.Logger.LogError((object)$"[CLIENT] Монстр {viewID} не найден!");
			}
		}

		public void RequestStopPossession()
		{
			PossessionController[] array = Object.FindObjectsOfType<PossessionController>();
			foreach (PossessionController possessionController in array)
			{
				if (((MonoBehaviourPun)possessionController).photonView.IsMine && possessionController.IsPossessedByPlayer)
				{
					PossessMonsterPlugin.Logger.LogInfo((object)"[CLIENT] Возврат управления...");
					possessionController.ReleaseControl();
					break;
				}
			}
		}

		public void RequestSpawnAndPossess(string prefabName)
		{
			//IL_0039: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			PossessMonsterPlugin.Logger.LogInfo((object)("[CLIENT] Запрос спавна " + prefabName + "..."));
			object[] array = new object[2]
			{
				prefabName,
				PhotonNetwork.LocalPlayer.ActorNumber
			};
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)2
			};
			PhotonNetwork.RaiseEvent((byte)155, (object)array, val, SendOptions.SendReliable);
		}

		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code == 155 && PhotonNetwork.IsMasterClient && photonEvent.CustomData is object[] array && array.Length >= 2)
			{
				string text = array[0] as string;
				int requestorActorNr = (int)array[1];
				if (!string.IsNullOrEmpty(text))
				{
					((MonoBehaviour)this).StartCoroutine(HandleSpawnRequest(text, requestorActorNr));
				}
			}
		}

		[IteratorStateMachine(typeof(<HandleSpawnRequest>d__9))]
		private IEnumerator HandleSpawnRequest(string prefabPath, int requestorActorNr)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <HandleSpawnRequest>d__9(0)
			{
				<>4__this = this,
				prefabPath = prefabPath,
				requestorActorNr = requestorActorNr
			};
		}
	}
}
namespace PossessMonster.Patches
{
	[HarmonyPatch(typeof(PlayerAvatar), "LoadingLevelAnimationCompleted")]
	internal class GamePatches
	{
		[HarmonyPostfix]
		private static void SpawnNetworkManager()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			if ((Object)(object)PossessNetwork.Instance == (Object)null)
			{
				PossessMonsterPlugin.Logger.LogInfo((object)"Инициализация локального PossessNetwork...");
				GameObject val = new GameObject("PossessNetworkManager");
				val.AddComponent<PossessNetwork>();
				PossessMonsterPlugin.Logger.LogInfo((object)"PossessNetwork готов к работе (Event System).");
			}
		}
	}
	[HarmonyPatch(typeof(Enemy))]
	internal class MonsterPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void SpawnPatch(Enemy __instance)
		{
			GameObject gameObject = ((Component)__instance).gameObject;
			if (!PossessMonsterPlugin.ActiveMonsters.Contains(gameObject))
			{
				PossessMonsterPlugin.ActiveMonsters.Add(gameObject);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar))]
	internal class PlayerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("PlayerDeath")]
		private static void DeathPatch(PlayerAvatar __instance)
		{
			if (__instance.photonView.IsMine)
			{
				PossessMonsterPlugin.Logger.LogDebug((object)"Перехвачена смерть локального игрока.");
				PossessMonsterPlugin.Instance.OnPlayerDied(((Component)__instance).gameObject);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("ReviveRPC")]
		private static void RevivePatch(PlayerAvatar __instance)
		{
			if (__instance.photonView.IsMine)
			{
				PossessMonsterPlugin.Logger.LogDebug((object)"Перехвачено возрождение локального игрока.");
				PossessMonsterPlugin.Instance.OnPlayerSpawned(((Component)__instance).gameObject);
			}
		}
	}
}