Decompiled source of Prop Hunt v1.0.3

PropHuntMod.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using System.Timers;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GlobalEnums;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using InControl;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using NoRepeat;
using PropHuntMod.Commands;
using PropHuntMod.Networking.Client;
using PropHuntMod.Networking.Server;
using PropHuntMod.Patches;
using PropHuntMod.Players;
using PropHuntMod.Props;
using PropHuntMod.Utils;
using SSMP.Api.Client;
using SSMP.Api.Client.Networking;
using SSMP.Api.Command;
using SSMP.Api.Command.Client;
using SSMP.Api.Command.Server;
using SSMP.Api.Server;
using SSMP.Api.Server.Networking;
using SSMP.Game.Settings;
using SSMP.Logging;
using SSMP.Math;
using SSMP.Networking.Packet;
using SSMP.Networking.Packet.Data;
using TeamCherry.Localization;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PropHuntMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PropHuntMod")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ea9e15ba-4504-4c36-baa6-8f85bee1da18")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace NoRepeat
{
	public class NoRepeat<T>
	{
		private readonly Random random = new Random();

		public List<T> used { get; private set; }

		public List<T> inputValues { get; private set; }

		public NoRepeat(List<T> values)
		{
			inputValues = values;
			used = new List<T>();
		}

		public T GetRandom()
		{
			if (used.Count == 0 && inputValues.Count <= 1)
			{
				if (inputValues.Count == 0)
				{
					return default(T);
				}
				return inputValues[0];
			}
			int index = random.Next(inputValues.Count);
			T val = inputValues[index];
			inputValues.RemoveAt(index);
			if (inputValues.Count == 0)
			{
				inputValues.AddRange(used);
				used = new List<T>();
				Log.LogDebug("Resetting NoRepeat");
			}
			used.Add(val);
			return val;
		}

		public T GetSpecific(Func<T, bool> func)
		{
			T val = inputValues.FirstOrDefault(func);
			if (val != null)
			{
				return val;
			}
			return used.FirstOrDefault(func);
		}
	}
}
namespace PropHuntMod
{
	[BepInPlugin("com.bobbythecatfish.prophunt", "Prop Hunt", "1.0.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("Hollow Knight Silksong.exe")]
	public class PropHuntMod : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static HeroSetDelegate <>9__10_0;

			internal void <Awake>b__10_0(HeroController heroController)
			{
				AttackCooldownPatches.ModifySprintFSM();
			}
		}

		internal static PropHuntMod Instance;

		internal SelfHornetManager hornet = new SelfHornetManager();

		internal SelfCoverManager cover = new SelfCoverManager();

		private static PropMovementControls movement;

		internal static Dictionary<ushort, PlayerManager> playerManager = new Dictionary<ushort, PlayerManager>();

		internal static IClientApi client;

		internal static bool modEnabled = false;

		internal static bool showHitboxes = false;

		internal static List<Action> nextFrameActions = new List<Action>();

		private static List<Action> _nextFrames = new List<Action>();

		private void Awake()
		{
			//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_0044: Expected O, but got Unknown
			Instance = this;
			Config.LoadConfig(((BaseUnityPlugin)this).Config);
			ClientAddon.RegisterAddon((ClientAddon)(object)new Client());
			ServerAddon.RegisterAddon((ServerAddon)(object)new Server());
			object obj = <>c.<>9__10_0;
			if (obj == null)
			{
				HeroSetDelegate val = delegate
				{
					AttackCooldownPatches.ModifySprintFSM();
				};
				<>c.<>9__10_0 = val;
				obj = (object)val;
			}
			HeroController.OnHeroInstanceSet += (HeroSetDelegate)obj;
		}

		public static void Initialize(IClientApi clientApi)
		{
			Log.LogInfo("Prop Hunt mod Loaded.");
			client = clientApi;
			Harmony.CreateAndPatchAll(typeof(PropHuntMod), "prophunt");
			Harmony.CreateAndPatchAll(typeof(NoDamage), "prophunt");
			Harmony.CreateAndPatchAll(typeof(BaseCoverManager), "prophunt");
			Harmony.CreateAndPatchAll(typeof(AttackCooldownPatches), "prophunt");
			Harmony.CreateAndPatchAll(typeof(ScenePatches), "prophunt");
			modEnabled = true;
			movement = new PropMovementControls();
		}

		public static void Unload()
		{
			Harmony.UnpatchID("prophunt");
			modEnabled = false;
		}

		private bool IsInputDisabled()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			HeroController instance = HeroController.instance;
			if (instance != null && instance.IsInputBlocked() && PropMovementControls.MovementState == MovementState.Normal)
			{
				return true;
			}
			GameManager silentInstance = GameManager.SilentInstance;
			if (silentInstance != null && (int)silentInstance.GameState == 1)
			{
				return true;
			}
			GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject;
			if ((Object)(object)currentSelectedGameObject != (Object)null)
			{
				InputField component = currentSelectedGameObject.GetComponent<InputField>();
				if (component != null && ((Component)component).gameObject.activeInHierarchy)
				{
					return true;
				}
			}
			return false;
		}

		private void Update()
		{
			//IL_009c: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (!modEnabled)
			{
				return;
			}
			if (_nextFrames.Count > 0)
			{
				foreach (Action nextFrame in _nextFrames)
				{
					nextFrame();
				}
				_nextFrames.Clear();
			}
			if ((Object)(object)hornet.hornet != (Object)null)
			{
				hornet.EnsureHornetHidden();
			}
			if ((Object)(object)hornet.hornet == (Object)null)
			{
				return;
			}
			movement?.Update();
			if (!IsInputDisabled())
			{
				if (Input.GetKeyDown(Config.HideHornetKey))
				{
					hornet.ToggleHornet();
				}
				if (Input.GetKeyDown(Config.SwapPropKey))
				{
					cover.EnableRandomProp();
				}
				if (Input.GetKeyDown(Config.ResetKey))
				{
					cover.DisableProp(hornet);
				}
			}
		}

		private void LateUpdate()
		{
			if (nextFrameActions.Count > 0)
			{
				_nextFrames = nextFrameActions.ToList();
				nextFrameActions.Clear();
			}
		}
	}
}
namespace PropHuntMod.Networking.Server
{
	internal class Server : ServerAddon
	{
		public static Server instance;

		public static GameState GameState = GameState.NotStarted;

		private static readonly Dictionary<ushort, ServerPlayer> players = new Dictionary<ushort, ServerPlayer>();

		internal static IServerApi api = null;

		protected override string Name => "Prop Hunt";

		protected override string Version => "1.0.3";

		public override uint ApiVersion => 1u;

		public override bool NeedsNetwork => true;

		public SeekerTimer SeekerTimer { get; private set; }

		public override void Initialize(IServerApi serverApi)
		{
			instance = this;
			api = serverApi;
			Log.SetLogger(((ServerAddon)this).Logger);
			Log.LogInfo("Prop Hunt Server Loaded.");
			Reset();
			ServerNetwork.Init(serverApi, (ServerAddon)(object)this);
			((ICommandManager<IServerCommand>)(object)serverApi.CommandManager).RegisterCommand((IServerCommand)(object)new ServerCommands());
			serverApi.ServerManager.PlayerConnectEvent += delegate(IServerPlayer player)
			{
				ServerPlayer player2 = GetPlayer(player.Id);
				if (GameState == GameState.SeekerWait)
				{
					player2.seeker = true;
					ServerNetwork.SendRoundStart(player.Id, GameState == GameState.Playing);
				}
			};
			serverApi.ServerManager.PlayerDisconnectEvent += delegate(IServerPlayer player)
			{
				players.Remove(player.Id);
				CheckGameOver(player);
			};
		}

		public void Reset(bool disconnect = false)
		{
			Log.LogInfo("Resetting server");
			GameState = GameState.NotStarted;
			SeekerTimer?.CancelTimer();
			SeekerTimer = null;
			if (disconnect)
			{
				foreach (IServerPlayer player in api.ServerManager.Players)
				{
					api.ServerManager.DisconnectPlayer(player.Id, (DisconnectReason)0);
				}
			}
			players.Clear();
		}

		internal static ServerPlayer GetPlayer(ushort playerID)
		{
			if (!players.TryGetValue(playerID, out var value))
			{
				value = new ServerPlayer(playerID);
				players.Add(playerID, value);
			}
			return value;
		}

		public void Announce(string announcement)
		{
			Log.LogDebug("Announcement: " + announcement);
			api.ServerManager.BroadcastMessage(announcement);
		}

		public void Message(ushort recipientID, string message)
		{
			Log.LogDebug($"Message to {recipientID}: {message}");
			api.ServerManager.SendMessage(recipientID, message);
		}

		public string DetermineWinner()
		{
			string text = null;
			foreach (ServerPlayer value in players.Values)
			{
				if (!string.IsNullOrEmpty(value.propName))
				{
					if (text != null)
					{
						return null;
					}
					text = value.PlayerAvatar.Username;
				}
			}
			return text;
		}

		private void PickSeekers()
		{
			int num = Mathf.Clamp(Config.SeekerCount, 1, players.Count - 1);
			Log.LogDebug($"Choosing {num} seekers");
			for (int i = 0; i < num; i++)
			{
				List<ServerPlayer> list = players.Values.Where((ServerPlayer p) => !p.seeker).ToList();
				if (list.Count == 0)
				{
					Log.LogDebug($"Ran out of seekers to choose (Picked {i}/{num})");
					break;
				}
				ServerPlayer randomElement = Extensions.GetRandomElement<ServerPlayer>(list);
				randomElement.seeker = true;
				Log.LogDebug(randomElement.PlayerAvatar.Username + " is a seeker");
			}
		}

		private void ResetPlayers()
		{
			foreach (ServerPlayer value in players.Values)
			{
				value.seeker = false;
				value.hidden = false;
				value.swapCount = 0;
				value.ResetProp();
			}
		}

		public void GameStart()
		{
			if (players.Count < 2)
			{
				Announce("...Well that's awkward. I can't start a game without two people!");
				return;
			}
			ResetPlayers();
			PickSeekers();
			EnsureSettings();
			GameState = GameState.SeekerWait;
			int seekerCountdown = Config.SeekerCountdown;
			Announce($"The game has begun! Hiders have a {seekerCountdown} second head start. Good luck!");
			SeekerTimer = new SeekerTimer(seekerCountdown);
			ServerNetwork.BroadcastRoundStart();
		}

		public void CheckGameOver(IServerPlayer playerHit, bool canceled = false)
		{
			if (GameState != 0 && (players.Values.All((ServerPlayer p) => string.IsNullOrEmpty(p.propName)) || canceled))
			{
				ServerNetwork.BroadcastGameOver(playerHit, canceled);
				if (canceled)
				{
					Announce("The game has been stopped early!");
					SeekerTimer?.CancelTimer();
				}
				else
				{
					Announce(playerHit.Username + " was the last bug standing! Congrats!");
				}
				GameState = GameState.NotStarted;
				ResetPlayers();
			}
		}

		private void EnsureSettings()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0055: Expected O, but got Unknown
			IServerSettings serverSettings = ((ServerAddon)this).ServerApi.ServerManager.ServerSettings;
			ServerSettings val = new ServerSettings
			{
				AllowSkins = serverSettings.AllowSkins,
				DisplayNames = serverSettings.DisplayNames,
				OnlyBroadcastMapIconWithCompass = serverSettings.OnlyBroadcastMapIconWithCompass,
				TeamsEnabled = serverSettings.TeamsEnabled,
				AlwaysShowMapIcons = false,
				IsPvpEnabled = false
			};
			((ServerAddon)this).ServerApi.ServerManager.ApplyServerSettings(val);
		}
	}
	public class SeekerTimer
	{
		public int seconds;

		private Timer timer;

		private void SetTimer(int seconds)
		{
			this.seconds = seconds;
			timer = new Timer(1000.0);
			timer.Elapsed += delegate
			{
				OnSecond();
			};
			timer.AutoReset = true;
			timer.Start();
		}

		private void OnSecond()
		{
			seconds--;
			if (seconds <= 0)
			{
				timer.Stop();
				timer = null;
				Server.instance.Announce("[Seekers]: Ready or not, here we come!");
				Server.GameState = GameState.Playing;
				ServerNetwork.BroadcastSeekerStart();
			}
			else if (seconds <= 5)
			{
				Server.instance.Announce($"[Seekers]: {seconds}...");
			}
		}

		public void CancelTimer()
		{
			if (timer != null)
			{
				timer.Stop();
				timer = null;
			}
		}

		public SeekerTimer(int seconds)
		{
			SetTimer(seconds);
		}
	}
	internal class ServerPlayer
	{
		public ushort id;

		public bool hidden;

		public bool seeker;

		public string propName;

		public string propPath;

		public Vector3 propLocation = Consts.DEFAULT_LOCATION;

		public float propRotation;

		public float propScale = 1f;

		public int swapCount;

		public IServerPlayer PlayerAvatar => Server.api.ServerManager.GetPlayer(id);

		public ServerPlayer(ushort id)
		{
			this.id = id;
		}

		public void ResetProp()
		{
			propName = "";
			propPath = "";
			propLocation = Consts.DEFAULT_LOCATION;
			propRotation = 0f;
			propScale = 1f;
		}
	}
	internal struct BypassTicket
	{
		public int Id;

		public CorrectiveActions action;

		public BypassTicket(int Id = -1, CorrectiveActions action = CorrectiveActions.None)
		{
			this.Id = Id;
			this.action = action;
		}
	}
	internal static class ServerNetwork
	{
		private static IServerAddonNetworkSender<CustomPackets> sender;

		private static IServerAddonNetworkReceiver<CustomPackets> receiver;

		private static readonly Dictionary<ushort, List<BypassTicket>> tickets = new Dictionary<ushort, List<BypassTicket>>();

		private static int TicketID = 0;

		private static BypassTicket GenerateTicket(ushort playerID, CorrectiveActions action)
		{
			if (!tickets.ContainsKey(playerID))
			{
				tickets[playerID] = new List<BypassTicket>();
			}
			BypassTicket bypassTicket = default(BypassTicket);
			bypassTicket.action = action;
			bypassTicket.Id = TicketID;
			BypassTicket bypassTicket2 = bypassTicket;
			tickets[playerID].Add(bypassTicket2);
			TicketID++;
			return bypassTicket2;
		}

		private static bool IsValidTicket(ushort playerID, int ticketID, params CorrectiveActions[] action)
		{
			if (ticketID == -1)
			{
				return false;
			}
			if (!tickets.ContainsKey(playerID))
			{
				return false;
			}
			int num = tickets[playerID].FindIndex((BypassTicket t) => t.Id == ticketID && action.Contains(t.action));
			if (num == -1)
			{
				return false;
			}
			tickets[playerID].RemoveAt(num);
			return true;
		}

		public static void Broadcast(ushort senderID, CustomPackets packetID, Packet data, bool collection)
		{
			foreach (IServerPlayer player in Server.api.ServerManager.Players)
			{
				if (player.Id != senderID)
				{
					if (collection)
					{
						sender.SendCollectionData<Packet>(packetID, data, player.Id);
					}
					else
					{
						sender.SendSingleData(packetID, (IPacketData)(object)data, player.Id);
					}
				}
			}
		}

		private static void FailedAction(ushort senderID, ushort affectedID, CustomPackets packetType, CorrectiveActions fix)
		{
			int bypassTicketID = -1;
			if (fix == CorrectiveActions.ToggleHornetFalse || fix == CorrectiveActions.PreviousScene || fix == CorrectiveActions.RestoreLastProp)
			{
				bypassTicketID = GenerateTicket(senderID, fix).Id;
			}
			sender.SendCollectionData<FailedAction>(CustomPackets.FailedAction, new FailedAction
			{
				AffectedID = affectedID,
				FailedPacket = packetType,
				FixMethod = fix,
				BypassTicketID = bypassTicketID
			}, senderID);
		}

		public static void ForwardPropSwap(ushort id, string propName, string propPath)
		{
			Log.LogDebug($"Broadcasting prop swap from {id}: {propName}");
			Broadcast(id, CustomPackets.PropSwap, new PropSwap
			{
				Id = id,
				propName = propName,
				propPath = propPath
			}, collection: true);
		}

		public static void BroadcastRoundStart()
		{
			Log.LogDebug("Broadcasting round start");
			foreach (IServerPlayer player in Server.api.ServerManager.Players)
			{
				SendRoundStart(player.Id);
			}
		}

		public static void SendRoundStart(ushort id, bool started = false)
		{
			ServerPlayer player = Server.GetPlayer(id);
			RoundStart roundStart = new RoundStart
			{
				IsSeeker = player.seeker,
				PropSwapLimit = 0,
				SeekerWaitTime = ((!started) ? Server.instance.SeekerTimer.seconds : 0),
				SeekerAttackCooldown = Config.AttackCooldown
			};
			sender.SendSingleData(CustomPackets.RoundStart, (IPacketData)(object)roundStart, id);
		}

		public static void ForwardPropLocation(ushort id, Vector3 propPosition, float propRotation, float propScale)
		{
			Log.LogDebug($"Broadcasting prop location from {id}: {propPosition}, {propRotation}, {propScale}");
			BaseCoverManager.ConstrainPropLocation(ref propPosition, ref propRotation, ref propScale);
			Broadcast(id, CustomPackets.PropLocation, new PropLocation
			{
				Id = id,
				PropPosition = propPosition,
				PropRotation = propRotation,
				PropScale = propScale
			}, collection: true);
		}

		public static void ForwardHideStatus(ushort id, bool isHiding)
		{
			Log.LogDebug($"Broadcasting hide status from {id}: {isHiding}");
			Broadcast(id, CustomPackets.HideStatus, new HideStatus
			{
				Id = id,
				IsHiding = isHiding
			}, collection: true);
		}

		public static void ForwardPropFound(ushort id, ushort propOwnerID)
		{
			Log.LogDebug($"Broadcasting prop found from {id}: {propOwnerID}");
			foreach (IServerPlayer player in Server.api.ServerManager.Players)
			{
				PropFound propFound = new PropFound
				{
					IsClientFound = (player.Id == propOwnerID),
					PropOwnerID = propOwnerID
				};
				sender.SendCollectionData<PropFound>(CustomPackets.PropFound, propFound, player.Id);
			}
		}

		public static void BroadcastGameOver(IServerPlayer winner, bool canceled)
		{
			Log.LogDebug("Broadcasting game over");
			foreach (IServerPlayer player in Server.api.ServerManager.Players)
			{
				GameOver gameOver = new GameOver
				{
					IsWinner = (!canceled && ((winner != null) ? new ushort?(winner.Id) : null) == player.Id),
					WasCanceled = canceled,
					WinnerUsername = (((winner != null) ? winner.Username : null) ?? "Nobody")
				};
				sender.SendSingleData(CustomPackets.GameOver, (IPacketData)(object)gameOver, player.Id);
			}
		}

		public static void BroadcastSeekerStart()
		{
			Log.LogDebug("Broadcasting seeker start");
			sender.BroadcastSingleData(CustomPackets.SeekerStart, (IPacketData)(object)new SeekerStart());
		}

		public static void Init(IServerApi serverApi, ServerAddon serverAddon)
		{
			sender = serverApi.NetServer.GetNetworkSender<CustomPackets>(serverAddon);
			receiver = serverApi.NetServer.GetNetworkReceiver<CustomPackets>(serverAddon, (Func<CustomPackets, IPacketData>)global::PropHuntMod.Networking.Client.Packets.Instantiate);
			receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.PropSwap>(CustomPackets.PropSwap, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.PropSwap>)OnPropSwap);
			receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.PropLocation>(CustomPackets.PropLocation, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.PropLocation>)OnPropLocation);
			receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.PropFound>(CustomPackets.PropFound, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.PropFound>)OnPropFound);
			receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.Sync>(CustomPackets.Sync, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.Sync>)OnSync);
			if (Config.AllowDebugFeatures)
			{
				receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Client.HideStatus>(CustomPackets.HideStatus, (GenericServerPacketHandler<global::PropHuntMod.Networking.Client.HideStatus>)OnHideStatus);
			}
		}

		private static void OnPropSwap(ushort id, global::PropHuntMod.Networking.Client.PropSwap data)
		{
			ServerPlayer player = Server.GetPlayer(id);
			bool flag = string.IsNullOrEmpty(data.propPath);
			if (player.seeker && Server.GameState != 0 && !flag)
			{
				Server.instance.Message(id, "You're a seeker! You can't hide this round.");
				FailedAction(id, id, CustomPackets.PropSwap, CorrectiveActions.DisableClientProp);
				return;
			}
			bool flag2 = IsValidTicket(id, data.TicketID, CorrectiveActions.RestoreLastProp, CorrectiveActions.PreviousScene);
			if (flag)
			{
				player.propName = "";
				player.propPath = "";
			}
			else
			{
				player.propName = data.propName;
				player.propPath = data.propPath;
			}
			if (!flag2)
			{
				player.swapCount++;
			}
			ForwardPropSwap(id, player.propName, player.propPath);
		}

		private static void OnPropLocation(ushort id, global::PropHuntMod.Networking.Client.PropLocation data)
		{
			ServerPlayer player = Server.GetPlayer(id);
			if (player.seeker && Server.GameState != 0)
			{
				Server.instance.Message(id, "You're a seeker! You can't hide this round.");
				FailedAction(id, id, CustomPackets.PropSwap, CorrectiveActions.DisableClientProp);
				return;
			}
			player.propLocation = data.PropPosition;
			player.propRotation = data.PropRotation;
			player.propScale = data.PropScale;
			BaseCoverManager.ConstrainPropLocation(ref player.propLocation, ref player.propRotation, ref player.propScale);
			ForwardPropLocation(id, player.propLocation, player.propRotation, player.propScale);
		}

		private static void OnSync(ushort id, global::PropHuntMod.Networking.Client.Sync data)
		{
			ServerPlayer player = Server.GetPlayer(id);
			if (player.seeker)
			{
				player.ResetProp();
			}
			else
			{
				player.propName = data.PropName ?? "";
				player.propPath = data.PropPath ?? "";
				player.propLocation = data.PropLocation;
				player.propRotation = data.PropRotation;
				player.propScale = data.PropRotation;
			}
			BaseCoverManager.ConstrainPropLocation(ref player.propLocation, ref player.propRotation, ref player.propScale);
			ForwardPropSwap(id, player.propName, player.propPath);
			ForwardPropLocation(id, player.propLocation, player.propRotation, player.propScale);
			Server.instance.CheckGameOver(player.PlayerAvatar);
		}

		private static void OnHideStatus(ushort id, global::PropHuntMod.Networking.Client.HideStatus data)
		{
			ServerPlayer player = Server.GetPlayer(id);
			if (Server.GameState != 0 && player.seeker && data.IsHiding && !IsValidTicket(id, data.TicketID, CorrectiveActions.ToggleHornetFalse))
			{
				Server.instance.Message(id, "You're a seeker! You can't hide this round.");
				FailedAction(id, id, CustomPackets.HideStatus, CorrectiveActions.ToggleHornetTrue);
			}
			else
			{
				player.hidden = data.IsHiding;
				ForwardHideStatus(id, data.IsHiding);
			}
		}

		private static void OnPropFound(ushort id, global::PropHuntMod.Networking.Client.PropFound data)
		{
			ServerPlayer player = Server.GetPlayer(data.PropOwnerID);
			ServerPlayer player2 = Server.GetPlayer(id);
			if (Server.GameState == GameState.SeekerWait)
			{
				Server.instance.Message(id, "You're still in the waiting period. No seeking yet!");
				FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.RestoreTriggerHandler);
				return;
			}
			if (Server.GameState == GameState.Playing)
			{
				if (player.seeker)
				{
					Server.instance.Message(id, "That player is a seeker!");
					FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.DisablePlayerProp);
					return;
				}
				if (!player2.seeker)
				{
					Server.instance.Message(id, "You're not a seeker! You can't find people this round.");
					FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.RestoreTriggerHandler);
					return;
				}
				player.seeker = true;
			}
			if (string.IsNullOrEmpty(player.propName))
			{
				Server.instance.Message(id, "That player has already been found. You might be out of sync.");
				FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectiveActions.DisablePlayerProp);
				return;
			}
			player.ResetProp();
			ForwardPropFound(id, data.PropOwnerID);
			Server.instance.Announce(player.PlayerAvatar.Username + " was found by " + player2.PlayerAvatar.Username + "!");
			if (Server.GameState == GameState.Playing)
			{
				Server.instance.CheckGameOver(player.PlayerAvatar);
			}
		}
	}
	public class PropSwap : global::PropHuntMod.Networking.Client.PropSwap
	{
		public override bool DropReliableDataIfNewerExists => false;

		public ushort Id { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(Id);
			base.WriteData(packet);
		}

		public override void ReadData(IPacket packet)
		{
			Id = packet.ReadUShort();
			base.ReadData(packet);
		}
	}
	public class RoundStart : Packet
	{
		public bool IsSeeker;

		public ushort PropSwapLimit;

		public int SeekerWaitTime;

		public float SeekerAttackCooldown;

		public override void WriteData(IPacket packet)
		{
			packet.Write(IsSeeker);
			packet.Write(PropSwapLimit);
			packet.Write(SeekerWaitTime);
			packet.Write(SeekerAttackCooldown);
		}

		public override void ReadData(IPacket packet)
		{
			IsSeeker = packet.ReadBool();
			PropSwapLimit = packet.ReadUShort();
			SeekerWaitTime = packet.ReadInt();
			SeekerAttackCooldown = packet.ReadFloat();
		}
	}
	public class PropLocation : global::PropHuntMod.Networking.Client.PropLocation
	{
		public override bool DropReliableDataIfNewerExists => false;

		public ushort Id { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(Id);
			base.WriteData(packet);
		}

		public override void ReadData(IPacket packet)
		{
			Id = packet.ReadUShort();
			base.ReadData(packet);
		}
	}
	public class HideStatus : global::PropHuntMod.Networking.Client.HideStatus
	{
		public override bool DropReliableDataIfNewerExists => false;

		public ushort Id { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(Id);
			base.WriteData(packet);
		}

		public override void ReadData(IPacket packet)
		{
			Id = packet.ReadUShort();
			base.ReadData(packet);
		}
	}
	public class PropFound : global::PropHuntMod.Networking.Client.PropFound
	{
		public override bool DropReliableDataIfNewerExists => false;

		public bool IsClientFound { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(IsClientFound);
			base.WriteData(packet);
		}

		public override void ReadData(IPacket packet)
		{
			IsClientFound = packet.ReadBool();
			base.ReadData(packet);
		}
	}
	public class SeekerStart : Packet
	{
	}
	public class GameOver : Packet
	{
		public string WinnerUsername { get; set; }

		public bool IsWinner { get; set; }

		public bool WasCanceled { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(WinnerUsername);
			packet.Write(IsWinner);
			packet.Write(WasCanceled);
		}

		public override void ReadData(IPacket packet)
		{
			WinnerUsername = packet.ReadString();
			IsWinner = packet.ReadBool();
			WasCanceled = packet.ReadBool();
		}
	}
	public class FailedAction : Packet
	{
		public CustomPackets FailedPacket;

		public CorrectiveActions FixMethod;

		public ushort AffectedID;

		public int BypassTicketID;

		public override void WriteData(IPacket packet)
		{
			packet.Write((int)FailedPacket);
			packet.Write((int)FixMethod);
			packet.Write(AffectedID);
			packet.Write(BypassTicketID);
		}

		public override void ReadData(IPacket packet)
		{
			FailedPacket = (CustomPackets)packet.ReadInt();
			FixMethod = (CorrectiveActions)packet.ReadInt();
			AffectedID = packet.ReadUShort();
			BypassTicketID = packet.ReadUShort();
		}
	}
	public static class Packets
	{
		internal static IPacketData Instantiate(CustomPackets packetID)
		{
			return (IPacketData)(packetID switch
			{
				CustomPackets.PropSwap => new PacketDataCollection<PropSwap>(), 
				CustomPackets.RoundStart => new RoundStart(), 
				CustomPackets.PropLocation => new PacketDataCollection<PropLocation>(), 
				CustomPackets.HideStatus => new PacketDataCollection<HideStatus>(), 
				CustomPackets.PropFound => new PacketDataCollection<PropFound>(), 
				CustomPackets.GameOver => new GameOver(), 
				CustomPackets.SeekerStart => new SeekerStart(), 
				CustomPackets.FailedAction => new PacketDataCollection<FailedAction>(), 
				_ => throw new NotImplementedException(packetID.ToString()), 
			});
		}
	}
}
namespace PropHuntMod.Networking.Client
{
	internal enum Teams
	{
		Hunter = 4,
		Seeker = 3
	}
	internal class Client : ClientAddon
	{
		public static GameState GameState;

		public static bool isSeeker;

		public static ushort propSwaps;

		public static ushort maxPropSwaps;

		public static float seekerAttackCooldown;

		protected override string Name => "Prop Hunt";

		protected override string Version => "1.0.3";

		public override uint ApiVersion => 1u;

		public override bool NeedsNetwork => true;

		public override void Initialize(IClientApi clientApi)
		{
			PropHuntMod.Initialize(clientApi);
			Log.SetLogger(((ClientAddon)this).Logger);
			Log.LogInfo("Prop Hunt Client Loaded.");
			ClientNetwork.Init(clientApi, (ClientAddon)(object)this);
			clientApi.ClientManager.ConnectEvent += delegate
			{
				string[] array = new string[5] { "Prop Hunt Commands:", "/ph start: starts a round", "/ph stop: stops a round", "/ph config: configure server settings", "/sync: syncs other player's props" };
				for (int i = 0; i < array.Length; i++)
				{
					LocalMessage(array[i]);
				}
			};
			clientApi.ClientManager.DisconnectEvent += delegate
			{
				GameState = GameState.NotStarted;
				isSeeker = false;
				propSwaps = 0;
				maxPropSwaps = 0;
				PropHuntMod.playerManager.Clear();
				global::PropHuntMod.Networking.Server.Server.instance.Reset(disconnect: true);
			};
			clientApi.ClientManager.PlayerConnectEvent += delegate(IClientPlayer player)
			{
				PlayerManager.GetPlayerManager(player.Id);
			};
			clientApi.ClientManager.PlayerDisconnectEvent += delegate(IClientPlayer player)
			{
				PropHuntMod.playerManager.Remove(player.Id);
			};
			clientApi.ClientManager.PlayerEnterSceneEvent += delegate(IClientPlayer player)
			{
				PlayerManager playerManager = PlayerManager.GetPlayerManager(player.Id);
				playerManager.hornetManager.SetHornet();
				playerManager.EnsurePropCover();
			};
			((ICommandManager<IClientCommand>)(object)clientApi.CommandManager).RegisterCommand((IClientCommand)(object)new ShowHitboxes());
			((ICommandManager<IClientCommand>)(object)clientApi.CommandManager).RegisterCommand((IClientCommand)(object)new global::PropHuntMod.Commands.Sync());
		}

		public static void LocalMessage(string message)
		{
			PropHuntMod.client.UiManager.ChatBox.AddMessage(message);
		}
	}
	internal static class ClientErrorCorrection
	{
		[CompilerGenerated]
		private sealed class <PreviousScene>d__2 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public FailedAction data;

			private int <i>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Expected O, but got Unknown
				//IL_00b1: 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_00c1: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					break;
				case 1:
					<>1__state = -1;
					<i>5__2++;
					break;
				}
				if (<i>5__2 < 5 && string.IsNullOrEmpty(ScenePatches.PreviousScene))
				{
					Log.LogWarning($"Attempt {<i>5__2 + 1} to find previous scene failed");
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				if (string.IsNullOrEmpty(ScenePatches.PreviousScene))
				{
					PropHuntMod.client.ClientManager.Disconnect();
					Client.LocalMessage("Fatal Error: Unable to find previous scene.");
					return false;
				}
				SceneLoadInfo val = new SceneLoadInfo
				{
					SceneName = ScenePatches.PreviousScene,
					PreventCameraFadeOut = true,
					WaitForSceneTransitionCameraFade = false,
					Visualization = (SceneLoadVisualizations)0,
					AlwaysUnloadUnusedAssets = true,
					IsFirstLevelForPlayer = false
				};
				ScenePatches.SceneTransitionTicket = data.BypassTicketID;
				GameManager.instance.BeginSceneTransition(val);
				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 void DiagnoseError(FailedAction data)
		{
			switch (data.FixMethod)
			{
			case CorrectiveActions.DisableClientProp:
				SelfCoverManager.instance.DisableProp(logOnFail: false, isSceneChange: false, data.BypassTicketID);
				break;
			case CorrectiveActions.DisablePlayerProp:
				DisablePlayerProp(data);
				break;
			case CorrectiveActions.PreviousScene:
				((MonoBehaviour)PropHuntMod.Instance).StartCoroutine(PreviousScene(data));
				break;
			case CorrectiveActions.ToggleHornetTrue:
				SelfHornetManager.instance.ToggleHornet(show: true);
				break;
			case CorrectiveActions.ToggleHornetFalse:
				SelfHornetManager.instance.ToggleHornet(show: false, data.BypassTicketID);
				break;
			case CorrectiveActions.RestoreLastProp:
				RestoreLastProp(data);
				break;
			case CorrectiveActions.RestoreTriggerHandler:
				RestoreTriggerHandler(data);
				break;
			case CorrectiveActions.BecomeSeeker:
				BecomeSeeker();
				break;
			default:
				throw new NotImplementedException(data.FixMethod.ToString());
			case CorrectiveActions.None:
				break;
			}
		}

		private static void DisablePlayerProp(FailedAction data)
		{
			PlayerManager.GetPlayerManager(data.AffectedID).SetProp("", "");
		}

		[IteratorStateMachine(typeof(<PreviousScene>d__2))]
		private static IEnumerator PreviousScene(FailedAction data)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <PreviousScene>d__2(0)
			{
				data = data
			};
		}

		public static void RestoreLastProp(FailedAction data)
		{
			SelfCoverManager instance = SelfCoverManager.instance;
			GameObject obj = PropValidation.FindGameObject(instance.PrevCoverPath);
			Prop prop = PropValidation.PrepareProp(obj);
			if ((Object)(object)obj == (Object)null || prop == null)
			{
				Log.LogFatal("Couldn't restore previous prop " + instance.PrevCoverPath);
			}
			else
			{
				SelfCoverManager.instance.EnableProp(prop, data.BypassTicketID);
			}
		}

		private static void RestoreTriggerHandler(FailedAction data)
		{
			GameObject cover = PlayerManager.GetPlayerManager(data.AffectedID).coverManager.cover;
			if ((Object)(object)cover != (Object)null)
			{
				if ((Object)(object)cover.GetComponent<TriggerHandler>() == (Object)null)
				{
					TriggerHandler triggerHandler = cover.AddComponent<TriggerHandler>();
					triggerHandler.isRemote = true;
					triggerHandler.playerID = data.AffectedID;
				}
				else
				{
					Log.LogDebug($"Player {data.AffectedID} still had their TriggerHandler. Not restoring.");
				}
			}
			else
			{
				Log.LogError($"Player {data.AffectedID}'s prop was already destroyed. Can't restore trigger handler");
			}
		}

		private static void BecomeSeeker()
		{
			Client.isSeeker = true;
			if (Client.GameState == GameState.SeekerWait)
			{
				SelfHornetManager.instance.SetSeekerObscure(enabled: true);
			}
		}
	}
	internal static class ClientNetwork
	{
		private static IClientApi api;

		private static IClientAddonNetworkSender<CustomPackets> sender;

		private static IClientAddonNetworkReceiver<CustomPackets> receiver;

		private static void SendData(CustomPackets packetId, IPacketData data)
		{
			if (api.NetClient.IsConnected && sender != null)
			{
				sender.SendSingleData(packetId, data);
			}
		}

		private static void SendCollectionData(CustomPackets packetId, Packet data)
		{
			if (api.NetClient.IsConnected && sender != null)
			{
				sender.SendCollectionData<Packet>(packetId, data);
			}
		}

		public static void SendPropSwap(Prop prop, int ticket = -1)
		{
			Log.LogDebug("Sending prop swap: " + prop?.name);
			SendData(CustomPackets.PropSwap, (IPacketData)(object)new PropSwap
			{
				propName = (prop?.name ?? ""),
				propPath = (prop?.path ?? ""),
				TicketID = ticket
			});
		}

		public static void SendPropLocation(Vector3 propPosition, float propRotation, float propScale)
		{
			Log.LogDebug($"Sending prop location: {propPosition}, {propRotation}, {propScale}");
			SendData(CustomPackets.PropLocation, (IPacketData)(object)new PropLocation
			{
				PropPosition = propPosition,
				PropRotation = propRotation,
				PropScale = propScale
			});
		}

		public static void SendHideStatus(bool isHiding, int ticket = -1)
		{
			Log.LogDebug($"Sending hide status: {isHiding}");
			SendData(CustomPackets.HideStatus, (IPacketData)(object)new HideStatus
			{
				IsHiding = isHiding,
				TicketID = ticket
			});
		}

		public static void SendPropFound(ushort propOwnerID)
		{
			Log.LogDebug($"Sending prop found: {propOwnerID}");
			SendCollectionData(CustomPackets.PropFound, new PropFound
			{
				PropOwnerID = propOwnerID
			});
		}

		public static void SendSync(string propName, string propPath, Vector3 propPosition, float propRotation, float propScale)
		{
			Log.LogDebug($"Sending sync data: {propName}, {propPosition}, {propRotation}, {propScale}");
			SendData(CustomPackets.Sync, (IPacketData)(object)new Sync
			{
				PropName = propName,
				PropPath = propPath,
				PropLocation = propPosition,
				PropRotation = propRotation,
				PropScale = propScale
			});
		}

		public static void Init(IClientApi clientApi, ClientAddon clientAddon)
		{
			api = clientApi;
			sender = clientApi.NetClient.GetNetworkSender<CustomPackets>(clientAddon);
			receiver = clientApi.NetClient.GetNetworkReceiver<CustomPackets>(clientAddon, (Func<CustomPackets, IPacketData>)global::PropHuntMod.Networking.Server.Packets.Instantiate);
			receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.PropSwap>(CustomPackets.PropSwap, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.PropSwap>)OnPropSwap);
			receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.PropLocation>(CustomPackets.PropLocation, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.PropLocation>)OnPropLocation);
			receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.PropFound>(CustomPackets.PropFound, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.PropFound>)OnPropFound);
			receiver.RegisterPacketHandler<RoundStart>(CustomPackets.RoundStart, (GenericClientPacketHandler<RoundStart>)OnRoundStart);
			receiver.RegisterPacketHandler<GameOver>(CustomPackets.GameOver, (GenericClientPacketHandler<GameOver>)OnGameOver);
			receiver.RegisterPacketHandler<SeekerStart>(CustomPackets.SeekerStart, (GenericClientPacketHandler<SeekerStart>)OnSeekerStart);
			receiver.RegisterPacketHandler<FailedAction>(CustomPackets.FailedAction, (GenericClientPacketHandler<FailedAction>)ClientErrorCorrection.DiagnoseError);
			if (Config.AllowDebugFeatures)
			{
				receiver.RegisterPacketHandler<global::PropHuntMod.Networking.Server.HideStatus>(CustomPackets.HideStatus, (GenericClientPacketHandler<global::PropHuntMod.Networking.Server.HideStatus>)OnHideStatus);
			}
		}

		private static void OnPropSwap(global::PropHuntMod.Networking.Server.PropSwap data)
		{
			PlayerManager.GetPlayerManager(data.Id).SetProp(data.propName, data.propPath);
			Log.LogDebug($"{data.Id} prop set to {data.propName}");
		}

		private static void OnRoundStart(RoundStart data)
		{
			bool flag = data.SeekerWaitTime == 0;
			if (flag)
			{
				Client.GameState = GameState.Playing;
			}
			else
			{
				Client.GameState = GameState.SeekerWait;
			}
			Client.isSeeker = data.IsSeeker;
			Client.propSwaps = 0;
			Client.maxPropSwaps = data.PropSwapLimit;
			Client.seekerAttackCooldown = data.SeekerAttackCooldown;
			if (data.IsSeeker)
			{
				Client.LocalMessage("You're a seeker!");
				SelfCoverManager.instance.DisableProp(logOnFail: false);
				if (!flag)
				{
					SelfHornetManager.instance.SetSeekerObscure(enabled: true);
					EffectsManager.SetTitle("SEEKER", $"Wait time: {data.SeekerWaitTime} seconds", "YOUR ROLE:", large: true, 10f);
				}
				else
				{
					EffectsManager.SetTitle("SEEKER", "It's go time!", "YOUR ROLE:", large: true, 10f);
				}
			}
			else
			{
				EffectsManager.SetTitle("HIDER", "", "YOUR ROLE:");
				SelfCoverManager.instance.EnableRandomProp();
				Client.LocalMessage("You're hiding this round!");
			}
		}

		private static void OnPropLocation(global::PropHuntMod.Networking.Server.PropLocation data)
		{
			PlayerManager.GetPlayerManager(data.Id).SetPropLocation(data.PropPosition, data.PropRotation, data.PropScale);
			Log.LogDebug($"{data.Id} prop moved to {data.PropPosition}, {data.PropRotation}, {data.PropScale}");
		}

		private static void OnHideStatus(global::PropHuntMod.Networking.Server.HideStatus data)
		{
			PlayerManager.GetPlayerManager(data.Id).SetHideStatus(data.IsHiding);
			Log.LogDebug($"{data.Id} hiding status set to {data.IsHiding}");
		}

		private static void OnPropFound(global::PropHuntMod.Networking.Server.PropFound data)
		{
			if (data.IsClientFound)
			{
				Log.LogDebug("I've been found!");
				SelfCoverManager.instance.FindProp(SelfHornetManager.instance);
				if (Client.GameState == GameState.Playing)
				{
					Client.isSeeker = true;
				}
			}
			else
			{
				PlayerManager playerManager = PlayerManager.GetPlayerManager(data.PropOwnerID);
				playerManager.coverManager.FindProp(playerManager.hornetManager);
				playerManager.SetProp("", "");
				Log.LogDebug(playerManager.PlayerAvatar.Username + " has been found");
			}
			EffectsManager.PlayFoundSound(data.IsClientFound);
		}

		private static void OnGameOver(GameOver data)
		{
			Client.GameState = GameState.NotStarted;
			Client.isSeeker = false;
			Client.propSwaps = 0;
			SelfHornetManager.instance.SetSeekerObscure(enabled: false);
			SelfCoverManager.instance.DisableProp();
			EffectsManager.PlayGameOverSound(!data.WasCanceled && data.IsWinner);
			string main = (data.WasCanceled ? "Round Canceled" : (data.IsWinner ? "You Won!" : "Round Complete"));
			string sub = ((data.IsWinner || data.WasCanceled) ? "" : (data.WinnerUsername + " won!"));
			EffectsManager.SetTitle(main, sub);
			if (data.IsWinner)
			{
				EffectsManager.PlayConfetti();
			}
			GameManager.instance.FreezeMoment((FreezeMomentTypes)10, (Action)null);
		}

		private static void OnSeekerStart(SeekerStart data)
		{
			Client.GameState = GameState.Playing;
			if (Client.isSeeker)
			{
				SelfHornetManager.instance.SetSeekerObscure(enabled: false);
			}
		}
	}
	public class Packet : IPacketData
	{
		public bool IsReliable => true;

		public virtual bool DropReliableDataIfNewerExists => true;

		public virtual void ReadData(IPacket packet)
		{
		}

		public virtual void WriteData(IPacket packet)
		{
		}
	}
	public class PropSwap : Packet
	{
		public string propName = "";

		public string propPath = "";

		public int TicketID = -1;

		public override void WriteData(IPacket packet)
		{
			packet.Write(propName);
			packet.Write(propPath);
			packet.Write(TicketID);
		}

		public override void ReadData(IPacket packet)
		{
			propName = packet.ReadString();
			propPath = packet.ReadString();
			TicketID = packet.ReadInt();
		}
	}
	public class PropLocation : Packet
	{
		public Vector3 PropPosition { get; set; }

		public float PropRotation { get; set; }

		public float PropScale { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(PropPosition);
			packet.Write(PropRotation);
			packet.Write(PropScale);
		}

		public override void ReadData(IPacket packet)
		{
			PropPosition = packet.ReadVector3();
			PropRotation = packet.ReadFloat();
			PropScale = packet.ReadFloat();
		}
	}
	public class HideStatus : Packet
	{
		public int TicketID = -1;

		public bool IsHiding { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(IsHiding);
			packet.Write(TicketID);
		}

		public override void ReadData(IPacket packet)
		{
			IsHiding = packet.ReadBool();
			TicketID = packet.ReadInt();
		}
	}
	public class PropFound : Packet
	{
		public override bool DropReliableDataIfNewerExists => false;

		public ushort PropOwnerID { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(PropOwnerID);
		}

		public override void ReadData(IPacket packet)
		{
			PropOwnerID = packet.ReadUShort();
		}
	}
	public class Sync : Packet
	{
		public string PropName { get; set; }

		public string PropPath { get; set; }

		public Vector3 PropLocation { get; set; }

		public float PropRotation { get; set; }

		public float PropScale { get; set; }

		public override void WriteData(IPacket packet)
		{
			packet.Write(PropName);
			packet.Write(PropPath);
			packet.Write(PropLocation);
			packet.Write(PropRotation);
			packet.Write(PropScale);
		}

		public override void ReadData(IPacket packet)
		{
			PropName = packet.ReadString();
			PropPath = packet.ReadString();
			PropLocation = packet.ReadVector3();
			PropRotation = packet.ReadFloat();
			PropScale = packet.ReadFloat();
		}
	}
	public static class Packets
	{
		internal static IPacketData Instantiate(CustomPackets packetID)
		{
			return (IPacketData)(packetID switch
			{
				CustomPackets.PropSwap => new PropSwap(), 
				CustomPackets.PropLocation => new PropLocation(), 
				CustomPackets.HideStatus => new HideStatus(), 
				CustomPackets.PropFound => new PacketDataCollection<PropFound>(), 
				CustomPackets.Sync => new Sync(), 
				_ => throw new NotImplementedException(packetID.ToString()), 
			});
		}
	}
}
namespace PropHuntMod.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("PropHuntMod.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] bundle => (byte[])ResourceManager.GetObject("bundle", resourceCulture);

		internal static byte[] icon => (byte[])ResourceManager.GetObject("icon", resourceCulture);

		internal static byte[] manifest => (byte[])ResourceManager.GetObject("manifest", resourceCulture);

		internal Resources()
		{
		}
	}
}
namespace PropHuntMod.Props
{
	internal enum Direction
	{
		Left,
		Right,
		Up,
		Down,
		Front,
		Back,
		Reset,
		RotateLeft,
		RotateRight,
		ScaleUp,
		ScaleDown
	}
	internal class SelfCoverManager : BaseCoverManager
	{
		public static SelfCoverManager instance;

		internal bool movedRecently;

		internal SelfCoverManager()
		{
			isRemote = false;
			instance = this;
		}

		public void MoveProp(Direction direction, KeyCode key, ref bool moved, bool onlyOnce = false)
		{
			//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 (base.IsHiding && (!onlyOnce || Input.GetKeyDown(key)) && (onlyOnce || Input.GetKey(key)))
			{
				moved = true;
				float distance = ((Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307)) ? 0.01f : 0.1f);
				MoveProp(direction, distance);
			}
		}

		public void MoveProp(Direction direction, float distance = 0.1f)
		{
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			if (!base.IsHiding)
			{
				Log.LogError("No cover, can't move");
				return;
			}
			float num = base.Position.X;
			float num2 = base.Position.Y;
			float num3 = base.Position.Z;
			float num4 = base.Rotation;
			float num5 = base.Scale;
			SelfHornetManager selfHornetManager = SelfHornetManager.instance;
			if (selfHornetManager.HornetExists())
			{
				bool flag = Extensions.GetScaleX(selfHornetManager.hornet.transform) < 1f;
				switch (direction)
				{
				case Direction.Left:
					num = ((!flag) ? (num - distance) : (num + distance));
					break;
				case Direction.Right:
					num = ((!flag) ? (num + distance) : (num - distance));
					break;
				case Direction.Up:
					num2 += distance;
					break;
				case Direction.Down:
					num2 -= distance;
					break;
				case Direction.Front:
					num3 -= distance;
					break;
				case Direction.Back:
					num3 += distance;
					break;
				case Direction.ScaleUp:
					num5 *= 1f + distance / 5f;
					break;
				case Direction.ScaleDown:
					num5 /= 1f + distance / 5f;
					break;
				case Direction.RotateLeft:
					num4 = ((!flag) ? (num4 + distance * 10f) : (num4 - distance * 10f));
					break;
				case Direction.RotateRight:
					num4 = ((!flag) ? (num4 - distance * 10f) : (num4 + distance * 10f));
					break;
				case Direction.Reset:
					num = Consts.DEFAULT_LOCATION.X;
					num2 = Consts.DEFAULT_LOCATION.Y;
					num3 = Consts.DEFAULT_LOCATION.Z;
					num4 = 0f;
					num5 = 1f;
					break;
				default:
					Log.LogError($"Invalid movement direction {direction} ({(int)direction})");
					return;
				}
				Vector3 location = new Vector3(num, num2, num3);
				SetPropLocation(location, num4, num5);
				movedRecently = true;
			}
		}

		public void SendPropPosition()
		{
			if (movedRecently)
			{
				if (!base.IsHiding)
				{
					Log.LogError("No cover, can't send prop position");
				}
				else
				{
					movedRecently = false;
					ClientNetwork.SendPropLocation(base.Position, base.Rotation, base.Scale);
				}
			}
		}

		public void EnableRandomProp()
		{
			if (PropValidation.currentSceneObjects == null)
			{
				PropValidation.GetAllProps();
			}
			if (!IsSeeker())
			{
				if (Client.maxPropSwaps > 0 && Client.propSwaps >= Client.maxPropSwaps)
				{
					Client.LocalMessage($"You've reached the max number of prop swaps (${Client.maxPropSwaps}).");
					return;
				}
				Prop random = PropValidation.currentSceneObjects.GetRandom();
				EnableProp(random);
				Log.LogDebug(random.path);
				Log.LogDebug(PropValidation.FindGameObject(random.path));
			}
		}

		public bool EnableProp(Prop prop, int ticket = -1)
		{
			if (IsSeeker())
			{
				return false;
			}
			Log.LogDebug("Enabling prop");
			bool num = base.EnableProp(SelfHornetManager.instance, prop);
			if (num)
			{
				ClientNetwork.SendPropSwap(prop, ticket);
				Client.propSwaps++;
			}
			return num;
		}

		public bool DisableProp(bool logOnFail = true, bool isSceneChange = false, int ticket = -1)
		{
			bool num = base.DisableProp(SelfHornetManager.instance, logOnFail);
			if (num && !isSceneChange)
			{
				PropMovementControls.Instance.SetMovementState(MovementState.Normal);
				ClientNetwork.SendPropSwap(null, ticket);
				PropHuntMod.showHitboxes = false;
			}
			return num;
		}

		public override void OnHit(TriggerHandler handler)
		{
			Log.LogError("UH OH! ON HIT IS SUPPOSED TO BE A REMOTE PLAYER!");
		}

		private bool IsSeeker()
		{
			if (Client.isSeeker)
			{
				Client.LocalMessage("You're a seeker! You can't enable props right now.");
				return true;
			}
			return false;
		}

		public override bool EnableProp(BaseHornetManager hornet, Prop prop)
		{
			return EnableProp(prop);
		}

		public override bool DisableProp(BaseHornetManager hornet, bool logOnFail = true)
		{
			return DisableProp(logOnFail);
		}
	}
	internal class BaseCoverManager
	{
		internal GameObject cover;

		internal string CoverPath;

		internal string PrevCoverPath;

		public ushort playerID;

		internal bool isRemote = true;

		internal Vector3 Position
		{
			get
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				GameObject obj = cover;
				Vector3? val = ((obj != null) ? new Vector3?(obj.transform.localPosition) : null);
				return (val.HasValue ? ((Vector3)val.GetValueOrDefault()) : null) ?? Consts.DEFAULT_LOCATION;
			}
		}

		internal float Rotation
		{
			get
			{
				GameObject obj = cover;
				if (obj == null)
				{
					return 0f;
				}
				return Extensions.GetLocalRotation2D(obj.transform);
			}
		}

		internal float Scale { get; private set; } = 1f;


		internal Vector2 OriginalScale { get; private set; } = Vector2.one;


		public bool IsHiding => (Object)(object)cover != (Object)null;

		public void SetPropLocation(Vector3 location)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHiding)
			{
				Log.LogError("No cover, can't set prop position");
			}
			else
			{
				cover.transform.localPosition = (Vector3)location;
			}
		}

		public void SetPropRotation(float rotation)
		{
			if (!IsHiding)
			{
				Log.LogError("No cover, can't set prop rotation");
			}
			else
			{
				Extensions.SetLocalRotation2D(cover.transform, rotation);
			}
		}

		public void SetPropScale(float scale)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			Scale = scale;
			if (!IsHiding)
			{
				Log.LogError("No cover, can't set prop scale");
			}
			else
			{
				Extensions.SetScale2D(cover.transform, OriginalScale * scale);
			}
		}

		public void SetPropLocation(Vector3 location, float rotation, float scale)
		{
			if (!IsHiding)
			{
				Log.LogError("No cover, can't set any prop location");
				return;
			}
			ConstrainPropLocation(ref location, ref rotation, ref scale);
			SetPropLocation(location);
			SetPropRotation(rotation);
			SetPropScale(scale);
		}

		public static void ConstrainPropLocation(ref Vector3 location, ref float rotation, ref float scale)
		{
			location.X = Mathf.Clamp(location.X, -2f, 2f);
			location.Y = Mathf.Clamp(location.Y, -4f, 4f);
			location.Z = Mathf.Clamp(location.Z, -8f, 8f);
			rotation %= 360f;
			scale = Mathf.Clamp(scale, 0.5f, 2f);
		}

		public virtual bool DisableProp(BaseHornetManager manager, bool logOnFail = true)
		{
			if (!IsHiding)
			{
				if (logOnFail)
				{
					Log.LogError("No cover to disable");
				}
				return false;
			}
			Log.LogDebug($"Destroying prop {cover}");
			Object.Destroy((Object)(object)cover);
			cover = null;
			manager.ToggleHornet(show: true);
			return true;
		}

		public void FindProp(BaseHornetManager manager)
		{
			if (!IsHiding)
			{
				Log.LogError("No cover to disable");
				return;
			}
			cover.transform.parent = null;
			manager.ToggleHornet(show: true);
			GameObject coverCopy = cover.gameObject;
			cover = null;
			Object.Destroy((Object)(object)coverCopy.GetComponent<TriggerHandler>());
			EffectsManager.SweepGameObject(coverCopy, delegate
			{
				Object.Destroy((Object)(object)coverCopy);
			});
		}

		public virtual bool EnableProp(BaseHornetManager hornet, Prop prop)
		{
			//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)
			if (prop == null)
			{
				Client.LocalMessage("There isn't any valid cover here. Try another room.");
				Log.LogError("No valid cover found");
				return false;
			}
			if (IsHiding)
			{
				Log.LogWarning("Destroying cover...");
				PrevCoverPath = CoverPath;
				Object.Destroy((Object)(object)cover);
				cover = null;
			}
			if (!hornet.HornetExists())
			{
				return false;
			}
			try
			{
				Log.LogDebug("Creating prop");
				if (PrevCoverPath == null)
				{
					PrevCoverPath = prop.path;
				}
				cover = Object.Instantiate<GameObject>(prop.go, hornet.hornet.transform);
				((Object)cover).name = prop.name;
				CoverPath = prop.path;
				SpriteRenderer component = cover.GetComponent<SpriteRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					((Renderer)component).enabled = true;
					component.maskInteraction = (SpriteMaskInteraction)0;
				}
				OriginalScale = Vector2.op_Implicit(cover.transform.lossyScale);
				SetPropLocation(Consts.DEFAULT_LOCATION, 0f, 1f);
				cover.SetActive(true);
				cover.layer = 20;
				hornet.ToggleHornet(show: false);
				TriggerHandler component2 = cover.GetComponent<TriggerHandler>();
				component2.playerID = playerID;
				component2.isRemote = isRemote;
			}
			catch (Exception ex)
			{
				Log.LogError("Ran into an error instantiating cover.");
				Log.LogError(ex);
			}
			return true;
		}

		public virtual void OnHit(TriggerHandler handler)
		{
			Log.LogDebug($"Found {playerID}");
			Object.Destroy((Object)(object)handler);
			ClientNetwork.SendPropFound(playerID);
		}
	}
	internal class TriggerHandler : MonoBehaviour
	{
		public ushort playerID;

		public bool isRemote;

		private void OnTriggerEnter2D(Collider2D other)
		{
			if (isRemote && ((Component)other).tag == "Nail Attack" && ((Client.GameState == GameState.Playing) ? Client.isSeeker : (!SelfCoverManager.instance.IsHiding)) && Object.op_Implicit((Object)(object)((Component)other).GetComponentInParent<HeroController>()))
			{
				PlayerManager.GetPlayerManager(playerID).coverManager.OnHit(this);
			}
		}
	}
	internal class PropMovementControls
	{
		private static float StickThreshold = 0.02f;

		private static SpriteRenderer StateIndicator;

		private static Sprite MoveXY;

		private static Sprite MoveZ;

		private static Sprite Rotate;

		private static Sprite Scale;

		private bool moved;

		public static PropMovementControls Instance;

		internal static MovementState MovementState = MovementState.Normal;

		private InputBlockingMechanism blocker = new InputBlockingMechanism();

		private bool ModeSwitchPressed;

		public PropMovementControls()
		{
			if (Instance == null)
			{
				Instance = this;
			}
		}

		private void ChangeModes()
		{
			if (!SelfCoverManager.instance.IsHiding)
			{
				SetMovementState(MovementState.Normal);
			}
			else if (MovementState == MovementState.Normal)
			{
				SetMovementState(MovementState.Move2D);
			}
			else if (MovementState == MovementState.Move2D)
			{
				SetMovementState(MovementState.MoveZ);
			}
			else if (MovementState == MovementState.MoveZ)
			{
				SetMovementState(MovementState.Scale);
			}
			else if (MovementState == MovementState.Scale)
			{
				SetMovementState(MovementState.Rotate);
			}
			else
			{
				SetMovementState(MovementState.Normal);
			}
		}

		private bool ResetPosition()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(Config.PropPositionReset))
			{
				MoveProp(Direction.Reset);
				SetMovementState(MovementState.Normal);
				moved = true;
				return true;
			}
			return false;
		}

		private bool CheckStick(OneAxisInputControl input, Direction direction, bool useValue = true)
		{
			if (input.IsPressed && input.Value > StickThreshold)
			{
				float num = 0.1f;
				if (useValue)
				{
					num = input.Value / 5f;
				}
				if (((OneAxisInputControl)ManagerSingleton<InputHandler>.Instance.inputActions.Dash).IsPressed)
				{
					num /= 2f;
				}
				MoveProp(direction, num);
				return true;
			}
			return false;
		}

		private void NonKeypadUpdate(OneAxisInputControl switchModeButton, OneAxisInputControl left, OneAxisInputControl right, OneAxisInputControl up, OneAxisInputControl down, bool useValue)
		{
			left.Enabled = true;
			right.Enabled = true;
			up.Enabled = true;
			down.Enabled = true;
			switchModeButton.Enabled = true;
			((OneAxisInputControl)ManagerSingleton<InputHandler>.Instance.inputActions.Dash).Enabled = true;
			if (switchModeButton.IsPressed && !ModeSwitchPressed)
			{
				ChangeModes();
				ModeSwitchPressed = true;
			}
			else if (!switchModeButton.IsPressed)
			{
				ModeSwitchPressed = false;
			}
			if (MovementState == MovementState.Move2D)
			{
				if (!CheckStick(left, Direction.Left, useValue))
				{
					CheckStick(right, Direction.Right, useValue);
				}
				if (!CheckStick(up, Direction.Up, useValue))
				{
					CheckStick(down, Direction.Down, useValue);
				}
			}
			else if (MovementState == MovementState.MoveZ)
			{
				if (!CheckStick(left, Direction.Back, useValue))
				{
					CheckStick(right, Direction.Front, useValue);
				}
				if (!CheckStick(up, Direction.Back, useValue))
				{
					CheckStick(down, Direction.Front, useValue);
				}
			}
			else if (MovementState == MovementState.Scale)
			{
				if (!CheckStick(left, Direction.ScaleUp, useValue))
				{
					CheckStick(right, Direction.ScaleDown, useValue);
				}
				if (!CheckStick(up, Direction.ScaleUp, useValue))
				{
					CheckStick(down, Direction.ScaleDown, useValue);
				}
			}
			else if (MovementState == MovementState.Rotate && !CheckStick(left, Direction.RotateLeft, useValue))
			{
				CheckStick(right, Direction.RotateRight, useValue);
			}
		}

		private void ControllerUpdate(bool rightStick = true)
		{
			TwoAxisInputControl val = (rightStick ? InputManager.ActiveDevice.RightStick : InputManager.ActiveDevice.LeftStick);
			if (val != null)
			{
				InputControl val2 = (rightStick ? InputManager.ActiveDevice.RightStickButton : InputManager.ActiveDevice.LeftStickButton);
				if (val2 != null)
				{
					NonKeypadUpdate((OneAxisInputControl)(object)val2, val.Left, val.Right, val.Up, val.Down, useValue: true);
				}
			}
		}

		private void NumpadUpdate()
		{
			SelfCoverManager instance = SelfCoverManager.instance;
			instance.MoveProp(Direction.Left, (KeyCode)260, ref moved);
			instance.MoveProp(Direction.Right, (KeyCode)262, ref moved);
			instance.MoveProp(Direction.Up, (KeyCode)264, ref moved);
			instance.MoveProp(Direction.Down, (KeyCode)258, ref moved);
			instance.MoveProp(Direction.Front, (KeyCode)263, ref moved);
			instance.MoveProp(Direction.Back, (KeyCode)265, ref moved);
			instance.MoveProp(Direction.RotateLeft, (KeyCode)257, ref moved);
			instance.MoveProp(Direction.RotateRight, (KeyCode)259, ref moved);
			instance.MoveProp(Direction.ScaleUp, (KeyCode)270, ref moved);
			instance.MoveProp(Direction.ScaleDown, (KeyCode)269, ref moved);
		}

		private void KeyboardUpdate()
		{
			HeroActions inputActions = ManagerSingleton<InputHandler>.Instance.inputActions;
			NonKeypadUpdate((OneAxisInputControl)(object)inputActions.Taunt, (OneAxisInputControl)(object)inputActions.Left, (OneAxisInputControl)(object)inputActions.Right, (OneAxisInputControl)(object)inputActions.Up, (OneAxisInputControl)(object)inputActions.Down, useValue: false);
		}

		public void Update()
		{
			if (!ResetPosition())
			{
				switch (Config.MovementMethod)
				{
				case MovementMethods.ControllerRightStick:
					ControllerUpdate();
					break;
				case MovementMethods.ControllerLeftStick:
					ControllerUpdate(rightStick: false);
					break;
				case MovementMethods.Numpad:
					NumpadUpdate();
					break;
				case MovementMethods.KeyboardMovement:
					KeyboardUpdate();
					break;
				}
				if (!moved)
				{
					SelfCoverManager.instance.SendPropPosition();
				}
				moved = false;
			}
		}

		private void MoveProp(Direction direction, float distance = 0.1f)
		{
			moved = true;
			SelfCoverManager.instance.MoveProp(direction, distance);
		}

		public void SetMovementState(MovementState newState)
		{
			Log.LogDebug($"Movement State: {MovementState} -> {newState}");
			MovementState = newState;
			switch (newState)
			{
			case MovementState.Move2D:
				HeroController.instance.AddInputBlocker((object)blocker);
				break;
			case MovementState.Normal:
				PropHuntMod.nextFrameActions.Add(delegate
				{
					HeroController.instance.RemoveInputBlocker((object)blocker);
				});
				break;
			}
			if ((Object)(object)StateIndicator == (Object)null)
			{
				CreateMovementIndicator();
			}
			switch (newState)
			{
			case MovementState.Normal:
				StateIndicator.sprite = null;
				break;
			case MovementState.Move2D:
				StateIndicator.sprite = MoveXY;
				break;
			case MovementState.MoveZ:
				StateIndicator.sprite = MoveZ;
				break;
			case MovementState.Scale:
				StateIndicator.sprite = Scale;
				break;
			case MovementState.Rotate:
				StateIndicator.sprite = Rotate;
				break;
			}
		}

		private void CreateMovementIndicator()
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			AssetBundle obj = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "prophunt.bundle"));
			Sprite[] source = obj.LoadAllAssets<Sprite>();
			MoveXY = source.First((Sprite a) => ((Object)a).name == "MoveXY");
			MoveZ = source.First((Sprite a) => ((Object)a).name == "MoveZ");
			Rotate = source.First((Sprite a) => ((Object)a).name == "Rotate");
			Scale = source.First((Sprite a) => ((Object)a).name == "Scale");
			obj.Unload(false);
			Transform val = ((Component)GameCameras.instance.hudCamera).transform.Find("In-game/Anchor TL/Hud Canvas Offset/Hud Canvas");
			Transform val2 = val.Find("Delivery Icon/Parent/Delivery Icon Sprite");
			Transform obj2 = Object.Instantiate<Transform>(val2, val);
			((Component)obj2).transform.position = val2.position;
			((Component)obj2).gameObject.SetActive(true);
			StateIndicator = ((Component)obj2).GetComponent<SpriteRenderer>();
			StateIndicator.sprite = null;
		}
	}
	internal class InputBlockingMechanism
	{
	}
	public class Prop
	{
		public string name;

		public string path;

		public GameObject go;
	}
	internal static class PropValidation
	{
		private static readonly string[] extraNames = new string[2] { "corpse", "quest_board" };

		private static readonly PhysLayers[] invalidLayers = (PhysLayers[])(object)new PhysLayers[2]
		{
			(PhysLayers)11,
			(PhysLayers)17
		};

		private static GameObject PropParent;

		private static readonly Type[] allowedTypes = new Type[13]
		{
			typeof(Transform),
			typeof(MeshFilter),
			typeof(Renderer),
			typeof(MeshRenderer),
			typeof(SpriteRenderer),
			typeof(tk2dSprite),
			typeof(tk2dSpriteAnimator),
			typeof(tk2dSpriteAnimation),
			typeof(tk2dSpriteAnimationClip),
			typeof(tk2dSpriteAnimationFrame),
			typeof(tk2dLookAnimNPC),
			typeof(CurveRotationAnimation),
			typeof(JitterSelf)
		};

		public static NoRepeat<Prop> currentSceneObjects { get; private set; }

		private static bool HasScript(GameObject obj)
		{
			if (!Object.op_Implicit((Object)(object)obj.GetComponent<Breakable>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<PlayMakerNPC>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<BasicNPC>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<QuestBoardInteractable>()))
			{
				return Object.op_Implicit((Object)(object)obj.GetComponent<PushableRubble>());
			}
			return true;
		}

		private static void LogSpecificObj(string objectName, string condition)
		{
			if (objectName == "Bonechurch_shop")
			{
				Log.LogInfo(condition);
			}
		}

		private static bool IsValidProp(string scene, GameObject gameObject)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if (!gameObject.activeInHierarchy)
			{
				LogSpecificObj(((Object)gameObject).name, "inactive");
				return false;
			}
			if (Regex.IsMatch(((Object)gameObject).name, "^pebble$|^junk_push|^Small_bell_push|^weaver_corpse_shrine|^Weaver Corpse Glow", RegexOptions.IgnoreCase))
			{
				return false;
			}
			if (((Object)gameObject).name.Contains("(Clone)"))
			{
				LogSpecificObj(((Object)gameObject).name, "clone");
				return false;
			}
			if (invalidLayers.Contains((PhysLayers)gameObject.layer))
			{
				string name2 = ((Object)gameObject).name;
				PhysLayers val = (PhysLayers)gameObject.layer;
				LogSpecificObj(name2, "layer " + ((object)(PhysLayers)(ref val)).ToString());
				return false;
			}
			SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>();
			if ((Object)(object)renderer == (Object)null && (Object)(object)gameObject.GetComponent<tk2dSprite>() == (Object)null)
			{
				LogSpecificObj(((Object)gameObject).name, "no renderer");
				return false;
			}
			SpriteRenderer obj = renderer;
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				Sprite sprite = obj.sprite;
				obj2 = ((sprite != null) ? ((Object)sprite).name : null);
			}
			if (obj2 != null && ExtraProps.banned.Any((string p) => p == ((Object)renderer.sprite).name))
			{
				LogSpecificObj(((Object)gameObject).name, "black fader");
				return false;
			}
			SpriteRenderer obj3 = renderer;
			float num;
			if (obj3 == null)
			{
				num = 1f;
			}
			else
			{
				Color color = obj3.color;
				num = ((Color)(ref color)).grayscale;
			}
			if (num < 0.75f)
			{
				LogSpecificObj(((Object)gameObject).name, "too dark");
				return false;
			}
			LogSpecificObj(((Object)gameObject).name, "passed negative");
			if (HasScript(gameObject))
			{
				return true;
			}
			string name = ((Object)gameObject).name.ToLower();
			if (extraNames.Any((string n) => name.Contains(n)))
			{
				return true;
			}
			if (ExtraProps.IsExtraProp(scene, gameObject))
			{
				return true;
			}
			return false;
		}

		private static bool IsGameObjectDuplicate(SpriteRenderer newObjRenderer, GameObject existingGameObject)
		{
			try
			{
				SpriteRenderer renderer = GetRenderer(existingGameObject);
				if ((Object)(object)((renderer != null) ? renderer.sprite : null) == (Object)null || (Object)(object)((newObjRenderer != null) ? newObjRenderer.sprite : null) == (Object)null)
				{
					return false;
				}
				return ((Object)renderer.sprite).name == ((Object)newObjRenderer.sprite).name;
			}
			catch (Exception ex)
			{
				Log.LogError(((Object)existingGameObject).name + " failed, no sprite on one of the objects?");
				Log.LogError(ex);
				return true;
			}
		}

		private static SpriteRenderer GetRenderer(GameObject gameObject)
		{
			SpriteRenderer val = gameObject.GetComponent<SpriteRenderer>();
			if ((Object)(object)((val != null) ? val.sprite : null) == (Object)null)
			{
				val = ((IEnumerable<SpriteRenderer>)gameObject.GetComponentsInChildren<SpriteRenderer>()).FirstOrDefault((Func<SpriteRenderer, bool>)((SpriteRenderer s) => (Object)(object)s.sprite != (Object)null));
			}
			return val;
		}

		public static void GetAllProps()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			Log.LogDebug("Preparing all props for scene " + name);
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			List<GameObject> list = new List<GameObject>();
			ExtraProps.Init();
			GameObject[] array2 = array;
			foreach (GameObject val in array2)
			{
				if (IsValidProp(name, val))
				{
					LogSpecificObj(((Object)val).name, "valid prop");
					SpriteRenderer renderer = GetRenderer(val);
					if ((Object)(object)renderer == (Object)null)
					{
						LogSpecificObj(((Object)val).name, "no renderer");
					}
					else if (list.Any((GameObject o) => IsGameObjectDuplicate(renderer, o)))
					{
						LogSpecificObj(((Object)val).name, "duplicate object");
					}
					else
					{
						list.Add(val);
					}
				}
			}
			PrepareAllProps(list);
			AddPropsToOutput(name);
		}

		private static void AddPropsToOutput(string scene)
		{
			List<Prop> inputValues = currentSceneObjects.inputValues;
			string value = string.Format("{0},{1},\"{2}\"", scene, inputValues.Count, string.Join("\n", inputValues.Select((Prop x) => x.name)));
			StreamWriter streamWriter = File.AppendText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "PropReport.csv"));
			streamWriter.WriteLine(value);
			streamWriter.Close();
		}

		private static void RemoveComponents<T>(GameObject gameObject, bool keepOnParent = false) where T : Component
		{
			T[] componentsInChildren = gameObject.GetComponentsInChildren<T>();
			foreach (T val in componentsInChildren)
			{
				if (!keepOnParent || (Object)(object)((Component)val).gameObject != (Object)(object)gameObject.gameObject)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private static void StripProp(GameObject gameObject)
		{
			MonoBehaviour[] componentsInChildren = gameObject.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				Type type = ((object)val).GetType();
				if (!allowedTypes.Any((Type t) => type == t))
				{
					Object.Destroy((Object)(object)val);
				}
			}
			RemoveComponents<Collider2D>(gameObject, keepOnParent: false);
			RemoveComponents<Rigidbody2D>(gameObject, keepOnParent: true);
			Transform[] componentsInChildren2 = gameObject.GetComponentsInChildren<Transform>();
			foreach (Transform val2 in componentsInChildren2)
			{
				if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponentInChildren<Renderer>()) && !Object.op_Implicit((Object)(object)((Component)val2).GetComponentInChildren<ParticleSystem>()))
				{
					Object.Destroy((Object)(object)((Component)val2).gameObject);
				}
			}
		}

		private static string GeneratePropPath(GameObject prop)
		{
			string text = ((Object)prop).name;
			_ = prop.transform.parent;
			while ((Object)(object)prop.transform.parent != (Object)null)
			{
				prop = ((Component)prop.transform.parent).gameObject;
				text = ((Object)prop).name + "/" + text;
			}
			return text;
		}

		public static Prop PrepareProp(GameObject prop, bool assignParent = true)
		{
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prop == (Object)null)
			{
				Log.LogError("Unknown prop to prepare");
				return null;
			}
			GameObject val;
			try
			{
				if (assignParent)
				{
					val = Object.Instantiate<GameObject>(prop, PropParent.transform);
				}
				else
				{
					val = Object.Instantiate<GameObject>(prop);
					val.SetActive(false);
				}
				val.layer = 20;
				((Object)val).name = ((Object)prop).name;
				Breakable component = val.GetComponent<Breakable>();
				if ((Object)(object)component != (Object)null && component.IsBroken)
				{
					SpriteRenderer component2 = val.GetComponent<SpriteRenderer>();
					if ((Object)(object)component2 != (Object)null)
					{
						((Renderer)component2).enabled = true;
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError("Ran into an error instantiating cover " + ((Object)prop).name + ".");
				Log.LogError(ex);
				return null;
			}
			StripProp(val);
			Quaternion rotation = val.transform.rotation;
			val.transform.rotation = Quaternion.identity;
			if (!AddPropHitbox(val))
			{
				Log.LogError("Couldn't add hitbox for " + ((Object)prop).name);
				Object.Destroy((Object)(object)val);
				return null;
			}
			val.transform.rotation = rotation;
			return new Prop
			{
				name = ((Object)val).name,
				go = val,
				path = GeneratePropPath(prop)
			};
		}

		private static bool AddPropHitbox(GameObject prop)
		{
			//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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: 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)
			Renderer[] array = (from r in prop.GetComponentsInChildren<Renderer>(false)
				where !(r is LineRenderer) && !(r is ParticleSystemRenderer)
				select r).ToArray();
			if (array.Length == 0)
			{
				Log.LogError("No renderers found");
				return false;
			}
			Bounds bounds = array[0].bounds;
			Renderer[] array2 = array;
			foreach (Renderer val in array2)
			{
				string text = ((Object)val).name.ToLower();
				if (!text.StartsWith("haze") && !text.StartsWith("light") && !text.StartsWith("vignette") && !text.EndsWith("fader") && !text.EndsWith("glow") && !text.EndsWith("cutout") && !(text == "lit"))
				{
					((Bounds)(ref bounds)).Encapsulate(val.bounds);
				}
			}
			Vector3 val2 = prop.transform.InverseTransformVector(((Bounds)(ref bounds)).size);
			BoxCollider2D val3 = prop.AddComponent<BoxCollider2D>();
			((Collider2D)val3).isTrigger = true;
			((Collider2D)val3).offset = Vector2.op_Implicit(prop.transform.InverseTransformPoint(((Bounds)(ref bounds)).center));
			val3.size = new Vector2(Mathf.Abs(val2.x), Mathf.Abs(val2.y));
			if ((val3.size.x > 20f && val3.size.y > 20f) || val3.size.x >= 30f || val3.size.y >= 30f)
			{
				Log.LogError($"Prop {((Object)prop).name} was too frickin big (${val3.size})");
				return false;
			}
			Extensions.AddComponentIfNotPresent<Rigidbody2D>(prop).bodyType = (RigidbodyType2D)1;
			prop.AddComponent<LineRenderer>();
			prop.AddComponent<DebugViewCollider>();
			prop.AddComponent<TriggerHandler>();
			array2 = array;
			foreach (Renderer val4 in array2)
			{
				if (!((Object)(object)((Component)val4).gameObject == (Object)(object)prop))
				{
					Extensions.AddComponentIfNotPresent<LineRenderer>(((Component)val4).gameObject);
					((Component)val4).gameObject.AddComponent<DebugViewBounds>();
				}
			}
			return true;
		}

		private static void PrepareAllProps(List<GameObject> props)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			if ((Object)(object)PropParent != (Object)null)
			{
				Object.Destroy((Object)(object)PropParent);
			}
			PropParent = new GameObject("PROP PARENT");
			PropParent.SetActive(false);
			if (!SelfHornetManager.instance.HornetExists())
			{
				return;
			}
			List<Prop> list = new List<Prop>();
			foreach (GameObject prop2 in props)
			{
				Prop prop = PrepareProp(prop2);
				if (prop != null)
				{
					list.Add(prop);
				}
			}
			currentSceneObjects = new NoRepeat<Prop>(list);
		}

		public static void ResetProps()
		{
			Log.LogDebug("Resetting props");
			currentSceneObjects = null;
		}

		public static GameObject FindGameObject(string path)
		{
			//IL_001d: 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)
			string[] names = path.Split(new char[1] { '/' });
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject val = ((IEnumerable<GameObject>)((Scene)(ref activeScene)).GetRootGameObjects()).FirstOrDefault((Func<GameObject, bool>)((GameObject go) => ((Object)go).name == names[0]));
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			for (int i = 1; i < names.Length; i++)
			{
				GameObject val2 = FindGameObjectLayer(names[i], val);
				if ((Object)(object)val2 == (Object)null)
				{
					return null;
				}
				val = val2;
			}
			return val;
		}

		private static GameObject FindGameObjectLayer(string name, GameObject parent)
		{
			int childCount = parent.transform.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = parent.transform.GetChild(i);
				if (((Object)child).name == name)
				{
					return ((Component)child).gameObject;
				}
			}
			return null;
		}
	}
	internal class DebugViewCollider : MonoBehaviour
	{
		private Color borderColor = Color.white;

		private readonly float lineWidth = 0.05f;

		private LineRenderer lineRenderer;

		private BoxCollider2D collider;

		private bool Show => PropHuntMod.showHitboxes;

		private void Awake()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0073: 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)
			collider = ((Component)this).GetComponent<BoxCollider2D>();
			lineRenderer = ((Component)this).GetComponent<LineRenderer>();
			lineRenderer.loop = true;
			lineRenderer.useWorldSpace = true;
			lineRenderer.startWidth = lineWidth;
			lineRenderer.endWidth = lineWidth;
			((Renderer)lineRenderer).material = new Material(Shader.Find("Sprites/Default"));
			lineRenderer.startColor = borderColor;
			lineRenderer.endColor = borderColor;
		}

		private void LateUpdate()
		{
			if (Show)
			{
				DrawBox(collider);
			}
			else
			{
				lineRenderer.positionCount = 0;
			}
		}

		private void DrawBox(BoxCollider2D box)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_003a: 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_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_004d: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0071: 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_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_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_0095: 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_00a0: 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)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = box.size * 0.5f;
			Vector2 offset = ((Collider2D)box).offset;
			SetPositions((Vector3[])(object)new Vector3[4]
			{
				Vector2.op_Implicit(offset + new Vector2(0f - val.x, 0f - val.y)),
				Vector2.op_Implicit(offset + new Vector2(val.x, 0f - val.y)),
				Vector2.op_Implicit(offset + new Vector2(val.x, val.y)),
				Vector2.op_Implicit(offset + new Vector2(0f - val.x, val.y))
			});
		}

		private void SetPositions(Vector3[] localPoints)
		{
			//IL_0021: 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)
			lineRenderer.positionCount = localPoints.Length;
			for (int i = 0; i < localPoints.Length; i++)
			{
				lineRenderer.SetPosition(i, ((Component)this).transform.TransformPoint(localPoints[i]));
			}
		}
	}
	internal class DebugViewBounds : MonoBehaviour
	{
		private LineRenderer lineRenderer;

		private Renderer[] renderers;

		private Color borderColor = Color.red;

		private readonly float lineWidth = 0.05f;

		private bool Show => PropHuntMod.showHitboxes;

		private void Awake()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0067: 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)
			lineRenderer = ((Component)this).GetComponent<LineRenderer>();
			lineRenderer.loop = true;
			lineRenderer.useWorldSpace = true;
			lineRenderer.startWidth = lineWidth;
			lineRenderer.endWidth = lineWidth;
			((Renderer)lineRenderer).material = new Material(Shader.Find("Sprites/Default"));
			lineRenderer.startColor = borderColor;
			lineRenderer.endColor = borderColor;
			renderers = ((Component)this).GetComponents<Renderer>();
		}

		private void LateUpdate()
		{
			if (Show)
			{
				Renderer[] array = renderers;
				foreach (Renderer renderer in array)
				{
					DrawBox(renderer);
				}
			}
		}

		private void DrawBox(Renderer renderer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_002c: 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_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_0040: 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_004a: 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_0055: 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_0063: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_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_00c0: 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_00c8: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			Bounds localBounds = renderer.localBounds;
			Vector2 val = Vector2.op_Implicit(Extensions.DivideElements(((Bounds)(ref localBounds)).size, (float?)2.1f, (float?)2.1f, (float?)null));
			localBounds = renderer.localBounds;
			Vector2 val2 = Vector2.op_Implicit(((Bounds)(ref localBounds)).center);
			SetPositions((Vector3[])(object)new Vector3[4]
			{
				Vector2.op_Implicit(val2 + new Vector2(0f - val.x, 0f - val.y)),
				Vector2.op_Implicit(val2 + new Vector2(val.x, 0f - val.y)),
				Vector2.op_Implicit(val2 + new Vector2(val.x, val.y)),
				Vector2.op_Implicit(val2 + new Vector2(0f - val.x, val.y))
			});
		}

		private void SetPositions(Vector3[] localPoints)
		{
			//IL_0021: 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)
			lineRenderer.positionCount = localPoints.Length;
			for (int i = 0; i < localPoints.Length; i++)
			{
				lineRenderer.SetPosition(i, ((Component)this).transform.TransformPoint(localPoints[i]));
			}
		}
	}
	internal static class ExtraProps
	{
		private static string[] sceneProps;

		private static string[] scenePrefixes;

		private static string scenePrefix;

		public static string[] global = new string[0];

		public static string[] banned = new string[0];

		public static void Init()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string scene = ((Scene)(ref activeScene)).name;
			if (scenePrefixes != null)
			{
				string text = scenePrefixes.FirstOrDefault((string p) => scene.StartsWith(p));
				if (string.IsNullOrEmpty(text))
				{
					Log.LogDebug("EPI: Scene not in extra props list");
					sceneProps = null;
					scenePrefix = null;
					return;
				}
				if (text == scenePrefix)
				{
					Log.LogDebug("EPI: Scene is same.");
					return;
				}
			}
			Log.LogDebug("Proceeding with extra prop loading");
			Dictionary<string, string[]> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(File.ReadAllText(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ExtraProps.json")));
			scenePrefixes = dictionary.Keys.ToArray();
			string text2 = dictionary.Keys.FirstOrDefault((string s) => scene.StartsWith(s));
			global = dictionary["GLOBAL"];
			if (string.IsNullOrEmpty(text2))
			{
				Log.LogError("EPI: key not found");
				sceneProps = null;
				scenePrefix = null;
			}
			else
			{
				sceneProps = dictionary[text2];
				scenePrefix = text2;
				banned = dictionary["BANNED"];
			}
		}

		public static bool IsExtraProp(string scene, GameObject gameObject)
		{
			//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)
			if (string.IsNullOrEmpty(scene))
			{
				return false;
			}
			if (sceneProps == null)
			{
				return false;
			}
			SpriteRenderer renderer = gameObject.GetComponent<SpriteRenderer>();
			SpriteRenderer obj = renderer;
			if ((Object)(object)((obj != null) ? obj.sprite : null) == (Object)null)
			{
				return false;
			}
			Color color = renderer.color;
			if (((Color)(ref color)).grayscale < 0.75f)
			{
				return false;
			}
			bool flag = global.Any((string p) => ((Object)renderer.sprite).name.StartsWith(p)) || sceneProps.Any((string p) => ((Object)renderer.sprite).name.StartsWith(p));
			if (flag && banned.Any((string p) => ((Object)renderer.sprite).name == p))
			{
				flag = false;
			}
			return flag;
		}
	}
}
namespace PropHuntMod.Players
{
	internal class PlayerManager
	{
		public BaseHornetManager hornetManager;

		public BaseCoverManager coverManager;

		public string currentCoverObjName = "";

		public string currentCoverObjPath = "";

		public Vector3 currentCoverObjLocation = Consts.DEFAULT_LOCATION;

		public float currentCoverObjRotation;

		public float currentCoverObjScale = 1f;

		public bool currentHideState;

		public ushort playerID;

		public IClientPlayer PlayerAvatar => PropHuntMod.client.ClientManager.GetPlayer(playerID);

		public PlayerManager(ushort playerID)
		{
			hornetManager = new BaseHornetManager();
			coverManager = new BaseCoverManager();
			this.playerID = playerID;
			hornetManager.playerID = playerID;
			coverManager.playerID = playerID;
			IClientPlayer val = default(IClientPlayer);
			PropHuntMod.client.ClientManager.TryGetPlayer(playerID, ref val);
			if (val == null)
			{
				Log.LogError($"No remotePlayer for {playerID}. Are they remote?");
			}
			else
			{
				PropHuntMod.playerManager.Add(playerID, this);
			}
		}

		public static PlayerManager GetPlayerManager(ushort playerID)
		{
			PropHuntMod.playerManager.TryGetValue(playerID, out var value);
			if (value == null)
			{
				return new PlayerManager(playerID);
			}
			return value;
		}

		public bool IsHostInSameRoom()
		{
			//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)
			if (PlayerAvatar == null)
			{
				return false;
			}
			bool isInLocalScene = PlayerAvatar.IsInLocalScene;
			if (isInLocalScene)
			{
				Log.LogDebug($"{playerID} is in the same room");
			}
			else
			{
				object[] array = new object[1];
				object arg = playerID;
				Scene activeScene = SceneManager.GetActiveScene();
				array[0] = $"{arg} is in another room, you are in {((Scene)(ref activeScene)).name}";
				Log.LogDebug(array);
			}
			return isInLocalScene;
		}

		public void EnsurePropCover()
		{
			if (string.IsNullOrEmpty(currentCoverObjName))
			{
				coverManager.DisableProp(hornetManager);
				hornetManager.ToggleHornet(show: true);
			}
			else if (IsHostInSameRoom())
			{
				GameObject val = PropValidation.FindGameObject(currentCoverObjPath);
				if ((Object)(object)val == (Object)null)
				{
					Log.LogError($"Couldn't find prop {currentCoverObjName} for player {playerID}");
					return;
				}
				Prop prop = PropValidation.PrepareProp(val, assignParent: false);
				if (prop == null)
				{
					Log.LogError($"Couldn't prepare prop for player {playerID}");
				}
				else
				{
					coverManager.EnableProp(hornetManager, prop);
					coverManager.SetPropLocation(currentCoverObjLocation, currentCoverObjRotation, currentCoverObjScale);
					Object.Destroy((Object)(object)prop.go);
				}
			}
			else
			{
				coverManager.DisableProp(hornetManager, logOnFail: false);
			}
		}

		public void SetProp(string name, string path)
		{
			if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(path))
			{
				name = "";
				path = "";
			}
			currentCoverObjName = name;
			currentCoverObjPath = path;
			ResetCoverPosition();
			EnsurePropCover();
		}

		public void SetPropLocation(Vector3 location, float rotation, float scale)
		{
			currentCoverObjLocation = location;
			currentCoverObjRotation = rotation;
			currentCoverObjScale = scale;
			if (IsHostInSameRoom())
			{
				coverManager.SetPropLocation(location, rotation, scale);
			}
		}

		public void SetHideStatus(bool hiding)
		{
			hornetManager.shouldBeShown = !hiding;
			if (IsHostInSameRoom())
			{
				hornetManager.ToggleHornet(!hiding);
			}
		}

		public void ResetCoverPosition()
		{
			SetPropLocation(Consts.DEFAULT_LOCATION, 0f, 1f);
		}

		public static void EnsureAllPropCovers()
		{
			Debug.Log((object)$"Ensuring cover for {PropHuntMod.playerManager.Count} players");
			foreach (PlayerManager value in PropHuntMod.playerManager.Values)
			{
				value.EnsurePropCover();
			}
		}
	}
	internal class InputBlocker
	{
	}
	internal class SelfHornetManager : BaseHornetManager
	{
		private static InputBlocker blocker = new InputBlocker();

		public static SelfHornetManager instance;

		private SpriteRenderer obscurance;

		public SelfHornetManager()
		{
			isRemote = false;
			instance = this;
		}

		public void ToggleHornet()
		{
			if (Config.AllowDebugFeatures || Se