Decompiled source of Prop Hunt v1.0.1

PropHuntMod.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
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 InControl;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using NoRepeat;
using PropHuntMod.Commands;
using PropHuntMod.Modifications;
using PropHuntMod.Server;
using PropHuntMod.Utils;
using PropHuntMod.Utils.Networking;
using PropHuntMod.Utils.Networking.FromClient;
using PropHuntMod.Utils.Networking.FromServer;
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.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.LogInfo("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
{
	public enum Teams
	{
		Hunter = 4,
		Seeker = 3
	}
	public class PropHuntClient : ClientAddon
	{
		public static GameState GameState;

		public static bool isSeeker;

		public static ushort propSwaps;

		public static ushort maxPropSwaps;

		protected override string Name => "Prop Hunt";

		protected override string Version => "1.0.1";

		public override uint ApiVersion => 1u;

		public override bool NeedsNetwork => true;

		public override void Initialize(IClientApi clientApi)
		{
			PropHuntMod.Initialize(clientApi);
			Log.LogInfo("Prop Hunt Loaded.");
			ClientNetwork.Init(clientApi, (ClientAddon)(object)this);
			clientApi.ClientManager.ConnectEvent += delegate
			{
				string[] array = new string[4] { "Prop Hunt Commands:", "/hunt: starts a round", "/stop: stops a round", "/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();
				PropHuntServer.instance.Reset(disconnect: true);
			};
			clientApi.ClientManager.PlayerConnectEvent += delegate(IClientPlayer player)
			{
				Log.LogInfo("Player " + player.Username + " connected");
				PlayerManager.GetPlayerManager(player.Id);
			};
			clientApi.ClientManager.PlayerDisconnectEvent += delegate(IClientPlayer player)
			{
				Log.LogInfo("Player " + player.Username + " disconnected");
				PropHuntMod.playerManager.Remove(player.Id);
			};
			clientApi.ClientManager.PlayerEnterSceneEvent += delegate(IClientPlayer player)
			{
				Log.LogInfo("Player " + player.Username + " entered your scene");
				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);
		}
	}
	public class PropHuntServer : ServerAddon
	{
		public static PropHuntServer instance;

		public static GameState GameState = GameState.NotStarted;

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

		internal static IServerApi _serverApi = null;

		protected override string Name => "Prop Hunt";

		protected override string Version => "1.0.1";

		public override uint ApiVersion => 1u;

		public override bool NeedsNetwork => true;

		public SeekerTimer SeekerTimer { get; private set; }

		public override void Initialize(IServerApi serverApi)
		{
			instance = this;
			_serverApi = serverApi;
			((ServerAddon)this).Logger.Info("Prop Hunt Loaded.");
			Reset();
			ServerNetwork.Init(serverApi, (ServerAddon)(object)this);
			((ICommandManager<IServerCommand>)(object)serverApi.CommandManager).RegisterCommand((IServerCommand)(object)new StartGameCommand());
			((ICommandManager<IServerCommand>)(object)serverApi.CommandManager).RegisterCommand((IServerCommand)(object)new StopGameCommand());
			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)
			{
				Log.LogInfo($"Player {player} disconnected");
				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 _serverApi.ServerManager.Players)
				{
					_serverApi.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.LogInfo("Announcement: " + announcement);
			_serverApi.ServerManager.BroadcastMessage(announcement);
		}

		public void Message(ushort recipientID, string message)
		{
			Log.LogInfo($"Message to {recipientID}: {message}");
			_serverApi.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 count = 1)
		{
			count = Mathf.Clamp(count, 1, players.Count - 1);
			Log.LogInfo($"Choosing {count} seekers");
			for (int i = 0; i < count; i++)
			{
				List<ServerPlayer> list = players.Values.Where((ServerPlayer p) => !p.seeker).ToList();
				if (list.Count == 0)
				{
					Log.LogInfo($"Ran out of seekers to choose (Picked {i}/{count})");
					break;
				}
				ServerPlayer randomElement = Extensions.GetRandomElement<ServerPlayer>(list);
				randomElement.seeker = true;
				Log.LogDebug(randomElement.PlayerAvatar.Username + " is a seeker");
			}
		}

		private void ResetPlayers()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			foreach (ServerPlayer value in players.Values)
			{
				value.seeker = false;
				value.swapCount = 0;
				value.propName = "";
				value.propRotation = 0f;
				value.propLocation = Vector3.zero;
				value.hidden = false;
			}
		}

		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 num = 30;
			Announce($"The game has begun! Hiders have a {num} second head start. Good luck!");
			SeekerTimer = new SeekerTimer(num);
			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);
		}
	}
	[BepInPlugin("com.bobbythecatfish.prophunt", "Prop Hunt", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("Hollow Knight Silksong.exe")]
	public class PropHuntMod : BaseUnityPlugin
	{
		internal static PropHuntMod Instance;

		internal SelfHornetManager hornet = new SelfHornetManager();

		internal SelfCoverManager cover = new SelfCoverManager();

		private static readonly NoDamage noDamage = new NoDamage();

		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 string CurrentScene;

		internal static string PreviousScene;

		internal static int SceneTransitionTicket = -1;

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

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

		private int logged;

		private void Awake()
		{
			Instance = this;
			Config.LoadConfig(((BaseUnityPlugin)this).Config);
			Log.SetLogger(((BaseUnityPlugin)this).Logger);
			ClientAddon.RegisterAddon((ClientAddon)(object)new PropHuntClient());
			ServerAddon.RegisterAddon((ServerAddon)(object)new PropHuntServer());
		}

		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");
			modEnabled = true;
		}

		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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			if (!modEnabled)
			{
				return;
			}
			if (_nextFrames.Count > 0)
			{
				Log.LogInfo($"Executing {_nextFrames.Count} late actions");
				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 (logged == 0)
				{
					Log.LogInfo("Input blocked");
				}
				logged = 1;
				return;
			}
			if (logged == 1)
			{
				Log.LogInfo("Input restored");
				logged = 0;
			}
			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)
			{
				Log.LogInfo($"Adding {nextFrameActions.Count} actions");
				_nextFrames = nextFrameActions.ToList();
				nextFrameActions.Clear();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SceneLoad), "Begin")]
		internal static void OnSceneChange(SceneLoad __instance)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			if (modEnabled && (int)GameManager.SilentInstance.GameState != 1)
			{
				if (movement == null)
				{
					movement = new PropMovementControls();
				}
				SelfCoverManager.instance.DisableProp(logOnFail: false, isSceneChange: true);
				PreviousScene = CurrentScene;
				CurrentScene = __instance.TargetSceneName;
				PropValidation.ResetProps();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameManager), "OnNextLevelReady")]
		internal static void OnNextLevelReady()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			if (!modEnabled || (int)GameManager.SilentInstance.GameState == 1)
			{
				return;
			}
			PropValidation.GetAllProps();
			if (PropHuntClient.GameState != 0 && !PropHuntClient.isSeeker)
			{
				if (SceneTransitionTicket != -1)
				{
					ClientErrorCorrection.RestoreLastProp(new FailedAction
					{
						AffectedID = 0,
						BypassTicketID = SceneTransitionTicket,
						FailedPacket = CustomPackets.PropSwap,
						FixMethod = CorrectionActions.PreviousScene
					});
					SceneTransitionTicket = -1;
				}
				else
				{
					SelfCoverManager.instance.EnableRandomProp();
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Breakable), "Break")]
		public static void OnBreak(Breakable __instance)
		{
		}
	}
}
namespace PropHuntMod.Utils
{
	internal static class Log
	{
		private static ManualLogSource logger;

		public static void SetLogger(ManualLogSource log)
		{
			logger = log;
		}

		public static void LogInfo(params object[] data)
		{
			foreach (object obj in data)
			{
				logger.LogInfo(obj);
			}
		}

		public static void LogWarning(params object[] data)
		{
			foreach (object obj in data)
			{
				logger.LogWarning(obj);
			}
		}

		public static void LogError(params object[] data)
		{
			foreach (object obj in data)
			{
				logger.LogError(obj);
			}
		}

		public static void LogFatal(params object[] data)
		{
			foreach (object obj in data)
			{
				logger.LogFatal(obj);
			}
		}

		public static void LogDebug(params object[] data)
		{
			foreach (object obj in data)
			{
				logger.LogDebug(obj);
			}
		}

		public static void LogMessage(params object[] data)
		{
			foreach (object obj in data)
			{
				logger.LogMessage(obj);
			}
		}
	}
	internal static class Config
	{
		public const string ModName = "Prop Hunt";

		public const string ModVersion = "1.0.1";

		public const int SSMPApiVersion = 1;

		public const int MaxSwapCount = 0;

		public const int SeekerCountdown = 30;

		public static readonly bool AllowDebugFeatures;

		private static ConfigEntry<bool> _disableDamage;

		private static ConfigEntry<KeyCode> _swapPropKey;

		private static ConfigEntry<KeyCode> _hideHornetKey;

		private static ConfigEntry<KeyCode> _resetKey;

		private static ConfigEntry<KeyCode> _propPositionReset;

		private static ConfigEntry<MovementMethods> _movementMethod;

		public static bool DisableDamage
		{
			get
			{
				if (_disableDamage.Value)
				{
					return PropHuntClient.GameState != GameState.NotStarted;
				}
				return false;
			}
		}

		public static KeyCode SwapPropKey => _swapPropKey.Value;

		public static KeyCode HideHornetKey => (KeyCode)(((??)_hideHornetKey?.Value) ?? 104);

		public static KeyCode ResetKey => _resetKey.Value;

		public static KeyCode PropPositionReset => _propPositionReset.Value;

		public static MovementMethods MovementMethod => _movementMethod.Value;

		public static void LoadConfig(ConfigFile Config)
		{
			_disableDamage = Config.Bind<bool>("General", "DisableDamage", true, "Disables all damage to the player with the exception of other players and terrain");
			_swapPropKey = Config.Bind<KeyCode>("General", "KeySwapProp", (KeyCode)112, "The key to swap props");
			_resetKey = Config.Bind<KeyCode>("General", "KeyReset", (KeyCode)114, "The key to unhide and remove the active prop");
			_movementMethod = Config.Bind<MovementMethods>("Prop Movement", "Movement Method", MovementMethods.Numpad, "Which control style to use for prop movement");
			_movementMethod.SettingChanged += delegate
			{
				PropMovementControls.MovementState = MovementState.Normal;
			};
			_propPositionReset = Config.Bind<KeyCode>("Prop Movement", "Reset Position", (KeyCode)261, "Resets the prop position");
			if (AllowDebugFeatures)
			{
				_hideHornetKey = Config.Bind<KeyCode>("General", "KeyHideHornet", (KeyCode)104, "The key to hide hornet in the event that she becomes visible while hiding");
			}
		}
	}
	public enum CustomPackets
	{
		PropSwap,
		RoundStart,
		PropLocation,
		HideStatus,
		PropFound,
		Sync,
		GameOver,
		SeekerStart,
		FailedAction
	}
	public enum GameState
	{
		NotStarted,
		SeekerWait,
		Playing
	}
	public enum CorrectionActions
	{
		None,
		DisableClientProp,
		DisablePlayerProp,
		PreviousScene,
		ToggleHornetTrue,
		ToggleHornetFalse,
		RestoreLastProp,
		RestoreTriggerHandler,
		BecomeSeeker
	}
	public enum MovementState
	{
		Normal,
		Move2D,
		MoveZ,
		Rotate
	}
	public enum MovementMethods
	{
		Numpad,
		KeyboardMovement,
		ControllerRightStick,
		ControllerLeftStick
	}
	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 bool moved;

		public static PropMovementControls Instance;

		internal static MovementState MovementState = MovementState.Normal;

		private InputBlockingMechanism blockingMechanism = new InputBlockingMechanism();

		private bool ModeSwitchPressed;

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

		private void ChangeModes()
		{
			if (MovementState == MovementState.Normal)
			{
				SetMovementState(MovementState.Move2D);
			}
			else if (MovementState == MovementState.Move2D)
			{
				SetMovementState(MovementState.MoveZ);
			}
			else if (MovementState == MovementState.MoveZ)
			{
				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 ControllerUpdate(bool rightStick = true)
		{
			TwoAxisInputControl val = (rightStick ? InputManager.ActiveDevice.RightStick : InputManager.ActiveDevice.LeftStick);
			if (val == null)
			{
				return;
			}
			val.Left.Enabled = true;
			val.Right.Enabled = true;
			val.Up.Enabled = true;
			val.Down.Enabled = true;
			InputControl val2 = (rightStick ? InputManager.ActiveDevice.RightStickButton : InputManager.ActiveDevice.LeftStickButton);
			((OneAxisInputControl)val2).Enabled = true;
			if (((OneAxisInputControl)val2).IsPressed && !ModeSwitchPressed)
			{
				ChangeModes();
				ModeSwitchPressed = true;
			}
			else if (!((OneAxisInputControl)val2).IsPressed)
			{
				ModeSwitchPressed = false;
			}
			if (MovementState == MovementState.Move2D)
			{
				if (!CheckStick(val.Left, Direction.Left))
				{
					CheckStick(val.Right, Direction.Right);
				}
				if (!CheckStick(val.Up, Direction.Up))
				{
					CheckStick(val.Down, Direction.Down);
				}
			}
			else if (MovementState == MovementState.MoveZ)
			{
				if (!CheckStick(val.Left, Direction.Back))
				{
					CheckStick(val.Right, Direction.Front);
				}
				if (!CheckStick(val.Up, Direction.Back))
				{
					CheckStick(val.Down, Direction.Front);
				}
			}
			else if (MovementState == MovementState.Rotate && !CheckStick(val.Left, Direction.RotateLeft))
			{
				CheckStick(val.Right, Direction.RotateRight);
			}
		}

		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);
		}

		private void KeyboardUpdate()
		{
			HeroActions inputActions = ManagerSingleton<InputHandler>.Instance.inputActions;
			((OneAxisInputControl)inputActions.Left).Enabled = true;
			((OneAxisInputControl)inputActions.Right).Enabled = true;
			((OneAxisInputControl)inputActions.Up).Enabled = true;
			((OneAxisInputControl)inputActions.Down).Enabled = true;
			((OneAxisInputControl)inputActions.Taunt).Enabled = true;
			((OneAxisInputControl)inputActions.Dash).Enabled = true;
			if (((OneAxisInputControl)inputActions.Taunt).IsPressed && !ModeSwitchPressed)
			{
				ChangeModes();
				ModeSwitchPressed = true;
			}
			else if (!((OneAxisInputControl)inputActions.Taunt).IsPressed)
			{
				ModeSwitchPressed = false;
			}
			if (MovementState == MovementState.Move2D)
			{
				if (!CheckStick((OneAxisInputControl)(object)inputActions.Left, Direction.Up, useValue: false))
				{
					CheckStick((OneAxisInputControl)(object)inputActions.Right, Direction.Right, useValue: false);
				}
				if (!CheckStick((OneAxisInputControl)(object)inputActions.Up, Direction.Up, useValue: false))
				{
					CheckStick((OneAxisInputControl)(object)inputActions.Down, Direction.Down, useValue: false);
				}
			}
			else if (MovementState == MovementState.MoveZ)
			{
				if (!CheckStick((OneAxisInputControl)(object)inputActions.Left, Direction.Back, useValue: false))
				{
					CheckStick((OneAxisInputControl)(object)inputActions.Right, Direction.Front, useValue: false);
				}
				if (!CheckStick((OneAxisInputControl)(object)inputActions.Up, Direction.Back, useValue: false))
				{
					CheckStick((OneAxisInputControl)(object)inputActions.Down, Direction.Front, useValue: false);
				}
			}
			else if (MovementState == MovementState.Rotate && !CheckStick((OneAxisInputControl)(object)inputActions.Left, Direction.RotateLeft, useValue: false))
			{
				CheckStick((OneAxisInputControl)(object)inputActions.Right, Direction.RotateRight, 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)blockingMechanism);
				break;
			case MovementState.Normal:
				PropHuntMod.nextFrameActions.Add(delegate
				{
					HeroController.instance.RemoveInputBlocker((object)blockingMechanism);
				});
				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.Rotate:
				StateIndicator.sprite = Rotate;
				break;
			}
		}

		private void CreateMovementIndicator()
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "prophunt.bundle"));
			Sprite[] array = val.LoadAllAssets<Sprite>();
			Sprite[] array2 = array;
			foreach (Sprite val2 in array2)
			{
				Log.LogInfo(((Object)val2).name, val2);
			}
			MoveXY = array.First((Sprite a) => ((Object)a).name == "MoveXY");
			MoveZ = array.First((Sprite a) => ((Object)a).name == "MoveZ");
			Rotate = array.First((Sprite a) => ((Object)a).name == "Rotate");
			val.Unload(false);
			Transform val3 = ((Component)GameCameras.instance.hudCamera).transform.Find("In-game/Anchor TL/Hud Canvas Offset/Hud Canvas");
			Transform val4 = val3.Find("Delivery Icon/Parent/Delivery Icon Sprite");
			Transform obj = Object.Instantiate<Transform>(val4, val3);
			((Component)obj).transform.position = val4.position;
			((Component)obj).gameObject.SetActive(true);
			StateIndicator = ((Component)obj).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)
				{
					Log.LogInfo(((Object)newObjRenderer).name + " not duplicate, a sprite was 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.LogInfo("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.LogInfo("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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			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 (((Object)prop).name == "Active")
				{
					object[] obj = new object[2] { text, null };
					Bounds bounds2 = val.bounds;
					obj[1] = ((Bounds)(ref bounds2)).size;
					Log.LogInfo(obj);
				}
				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.LogInfo("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");
					Log.LogDebug(sceneProps?.Length);
					sceneProps = null;
					scenePrefix = null;
					return;
				}
				if (text == scenePrefix)
				{
					Log.LogDebug("EPI: Scene is same.");
					Log.LogDebug(sceneProps.Length);
					return;
				}
			}
			Log.LogInfo("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();
			Log.LogInfo("Prefixes:", string.Join(", ", scenePrefixes));
			string text2 = dictionary.Keys.FirstOrDefault((string s) => scene.StartsWith(s));
			Log.LogInfo("Key: " + text2);
			global = dictionary["GLOBAL"];
			if (string.IsNullOrEmpty(text2))
			{
				Log.LogError("EPI: key not found");
				sceneProps = null;
				scenePrefix = null;
			}
			else
			{
				sceneProps = dictionary[text2];
				Log.LogInfo("Props:", string.Join(", ", sceneProps));
				scenePrefix = text2;
				banned = dictionary["BANNED"];
			}
		}

		public static bool IsExtraProp(string scene, GameObject gameObject)
		{
			//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)
			if (string.IsNullOrEmpty(scene))
			{
				Log.LogDebug("IEP: No scene name");
				return false;
			}
			if (sceneProps == null)
			{
				Log.LogDebug("IEP: No scene props");
				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.Utils.Networking
{
	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(PropHuntMod.PreviousScene))
				{
					Log.LogInfo($"Attempt {<i>5__2 + 1} to find previous scene failed");
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				if (string.IsNullOrEmpty(PropHuntMod.PreviousScene))
				{
					PropHuntMod.client.ClientManager.Disconnect();
					PropHuntClient.LocalMessage("Fatal Error: Unable to find previous scene.");
					return false;
				}
				SceneLoadInfo val = new SceneLoadInfo
				{
					SceneName = PropHuntMod.PreviousScene,
					PreventCameraFadeOut = true,
					WaitForSceneTransitionCameraFade = false,
					Visualization = (SceneLoadVisualizations)0,
					AlwaysUnloadUnusedAssets = true,
					IsFirstLevelForPlayer = false
				};
				PropHuntMod.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 CorrectionActions.DisableClientProp:
				SelfCoverManager.instance.DisableProp(logOnFail: false, isSceneChange: false, data.BypassTicketID);
				break;
			case CorrectionActions.DisablePlayerProp:
				DisablePlayerProp(data);
				break;
			case CorrectionActions.PreviousScene:
				((MonoBehaviour)PropHuntMod.Instance).StartCoroutine(PreviousScene(data));
				break;
			case CorrectionActions.ToggleHornetTrue:
				SelfHornetManager.instance.ToggleHornet(show: true);
				break;
			case CorrectionActions.ToggleHornetFalse:
				SelfHornetManager.instance.ToggleHornet(show: false, data.BypassTicketID);
				break;
			case CorrectionActions.RestoreLastProp:
				RestoreLastProp(data);
				break;
			case CorrectionActions.RestoreTriggerHandler:
				RestoreTriggerHandler(data);
				break;
			case CorrectionActions.BecomeSeeker:
				BecomeSeeker();
				break;
			default:
				throw new NotImplementedException(data.FixMethod.ToString());
			case CorrectionActions.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.LogInfo($"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()
		{
			PropHuntClient.isSeeker = true;
			if (PropHuntClient.GameState == GameState.SeekerWait)
			{
				SelfHornetManager.instance.SetSeekerObscure(enabled: true);
			}
		}
	}
	internal static class ClientNetwork
	{
		private static IClientAddonNetworkSender<CustomPackets> sender;

		private static IClientAddonNetworkReceiver<CustomPackets> receiver;

		public static void SendPropSwap(Prop prop, int ticket = -1)
		{
			Log.LogInfo("Sending prop swap: " + prop?.name);
			sender.SendSingleData(CustomPackets.PropSwap, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromClient.PropSwap
			{
				propName = (prop?.name ?? ""),
				propPath = (prop?.path ?? ""),
				TicketID = ticket
			});
		}

		public static void SendPropLocation(Vector3 propPosition, float propRotation)
		{
			//IL_000d: 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)
			Log.LogInfo($"Sending prop location: {propPosition}, {propRotation}");
			sender.SendSingleData(CustomPackets.PropLocation, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromClient.PropLocation
			{
				PropPosition = propPosition,
				PropRotation = propRotation
			});
		}

		public static void SendHideStatus(bool isHiding, int ticket = -1)
		{
			Log.LogInfo($"Sending hide status: {isHiding}");
			sender.SendSingleData(CustomPackets.HideStatus, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromClient.HideStatus
			{
				IsHiding = isHiding,
				TicketID = ticket
			});
		}

		public static void SendPropFound(ushort propOwnerID)
		{
			Log.LogInfo($"Sending prop found: {propOwnerID}");
			sender.SendSingleData(CustomPackets.PropFound, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromClient.PropFound
			{
				PropOwnerID = propOwnerID
			});
		}

		public static void SendSync(string propName, string propPath, Vector3 propPosition, float propRotation)
		{
			//IL_000e: 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)
			Log.LogInfo($"Sending sync data: {propName}, {propPosition}, {propRotation}");
			sender.SendSingleData(CustomPackets.Sync, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromClient.Sync
			{
				PropName = propName,
				PropPath = propPath,
				PropLocation = propPosition,
				PropRotation = propRotation
			});
		}

		public static void Init(IClientApi clientApi, ClientAddon clientAddon)
		{
			sender = clientApi.NetClient.GetNetworkSender<CustomPackets>(clientAddon);
			receiver = clientApi.NetClient.GetNetworkReceiver<CustomPackets>(clientAddon, (Func<CustomPackets, IPacketData>)global::PropHuntMod.Utils.Networking.FromServer.Packets.Instantiate);
			receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromServer.PropSwap>(CustomPackets.PropSwap, (GenericClientPacketHandler<global::PropHuntMod.Utils.Networking.FromServer.PropSwap>)OnPropSwap);
			receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromServer.PropLocation>(CustomPackets.PropLocation, (GenericClientPacketHandler<global::PropHuntMod.Utils.Networking.FromServer.PropLocation>)OnPropLocation);
			receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromServer.PropFound>(CustomPackets.PropFound, (GenericClientPacketHandler<global::PropHuntMod.Utils.Networking.FromServer.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.Utils.Networking.FromServer.HideStatus>(CustomPackets.HideStatus, (GenericClientPacketHandler<global::PropHuntMod.Utils.Networking.FromServer.HideStatus>)OnHideStatus);
			}
		}

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

		private static void OnRoundStart(RoundStart data)
		{
			bool flag = data.SeekerWaitTime == 0;
			if (flag)
			{
				PropHuntClient.GameState = GameState.Playing;
			}
			else
			{
				PropHuntClient.GameState = GameState.SeekerWait;
			}
			PropHuntClient.isSeeker = data.IsSeeker;
			PropHuntClient.propSwaps = 0;
			PropHuntClient.maxPropSwaps = data.PropSwapLimit;
			if (data.IsSeeker)
			{
				PropHuntClient.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();
				PropHuntClient.LocalMessage("You're hiding this round!");
			}
		}

		private static void OnPropLocation(global::PropHuntMod.Utils.Networking.FromServer.PropLocation data)
		{
			//IL_000c: 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)
			PlayerManager.GetPlayerManager(data.Id).SetPropLocation(data.PropPosition, data.PropRotation);
			Log.LogInfo($"{data.Id} prop moved to {data.PropPosition}, {data.PropRotation}");
		}

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

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

		private static void OnGameOver(GameOver data)
		{
			PropHuntClient.GameState = GameState.NotStarted;
			PropHuntClient.isSeeker = false;
			PropHuntClient.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)
		{
			PropHuntClient.GameState = GameState.Playing;
			if (PropHuntClient.isSeeker)
			{
				SelfHornetManager.instance.SetSeekerObscure(enabled: false);
			}
		}
	}
	internal struct BypassTicket
	{
		public int Id;

		public CorrectionActions action;

		public BypassTicket(int Id = -1, CorrectionActions action = CorrectionActions.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, CorrectionActions 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 CorrectionActions[] 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, IPacketData data)
		{
			foreach (IServerPlayer player in PropHuntServer._serverApi.ServerManager.Players)
			{
				if (player.Id != senderID)
				{
					sender.SendSingleData(packetID, data, player.Id);
				}
			}
		}

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

		public static void ForwardPropSwap(ushort id, string propName, string propPath)
		{
			Log.LogInfo($"Broadcasting prop swap from {id}: {propName}");
			Broadcast(id, CustomPackets.PropSwap, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromServer.PropSwap
			{
				Id = id,
				propName = propName,
				propPath = propPath
			});
		}

		public static void BroadcastRoundStart()
		{
			Log.LogInfo("Broadcasting round start");
			foreach (IServerPlayer player in PropHuntServer._serverApi.ServerManager.Players)
			{
				SendRoundStart(player.Id);
			}
		}

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

		public static void ForwardPropLocation(ushort id, Vector3 propPosition, float propRotation)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			Log.LogInfo($"Broadcasting prop location from {id}: {propPosition}, {propRotation}");
			BaseCoverManager.ConstrainPropLocation(ref propPosition, ref propRotation);
			Broadcast(id, CustomPackets.PropLocation, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromServer.PropLocation
			{
				Id = id,
				PropPosition = propPosition,
				PropRotation = propRotation
			});
		}

		public static void ForwardHideStatus(ushort id, bool isHiding)
		{
			Log.LogInfo($"Broadcasting hide status from {id}: {isHiding}");
			Broadcast(id, CustomPackets.HideStatus, (IPacketData)(object)new global::PropHuntMod.Utils.Networking.FromServer.HideStatus
			{
				Id = id,
				IsHiding = isHiding
			});
		}

		public static void ForwardPropFound(ushort id, ushort propOwnerID)
		{
			Log.LogInfo($"Broadcasting prop found from {id}: {propOwnerID}");
			foreach (IServerPlayer player in PropHuntServer._serverApi.ServerManager.Players)
			{
				global::PropHuntMod.Utils.Networking.FromServer.PropFound propFound = new global::PropHuntMod.Utils.Networking.FromServer.PropFound
				{
					IsClientFound = (player.Id == propOwnerID),
					PropOwnerID = propOwnerID
				};
				sender.SendSingleData(CustomPackets.PropFound, (IPacketData)(object)propFound, player.Id);
			}
		}

		public static void BroadcastGameOver(IServerPlayer winner, bool canceled)
		{
			Log.LogInfo("Broadcasting game over");
			foreach (IServerPlayer player in PropHuntServer._serverApi.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.LogInfo("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.Utils.Networking.FromClient.Packets.Instantiate);
			receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.PropSwap>(CustomPackets.PropSwap, (GenericServerPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.PropSwap>)OnPropSwap);
			receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.PropLocation>(CustomPackets.PropLocation, (GenericServerPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.PropLocation>)OnPropLocation);
			receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.PropFound>(CustomPackets.PropFound, (GenericServerPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.PropFound>)OnPropFound);
			receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.Sync>(CustomPackets.Sync, (GenericServerPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.Sync>)OnSync);
			if (Config.AllowDebugFeatures)
			{
				receiver.RegisterPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.HideStatus>(CustomPackets.HideStatus, (GenericServerPacketHandler<global::PropHuntMod.Utils.Networking.FromClient.HideStatus>)OnHideStatus);
			}
		}

		private static void OnPropSwap(ushort id, global::PropHuntMod.Utils.Networking.FromClient.PropSwap data)
		{
			ServerPlayer player = PropHuntServer.GetPlayer(id);
			bool flag = string.IsNullOrEmpty(data.propPath);
			if (player.seeker && PropHuntServer.GameState != 0 && !flag)
			{
				PropHuntServer.instance.Message(id, "You're a seeker! You can't hide this round.");
				FailedAction(id, id, CustomPackets.PropSwap, CorrectionActions.DisableClientProp);
				return;
			}
			bool flag2 = IsValidTicket(id, data.TicketID, CorrectionActions.RestoreLastProp, CorrectionActions.PreviousScene);
			if (flag)
			{
				player.propName = null;
				player.propPath = null;
			}
			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.Utils.Networking.FromClient.PropLocation data)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			ServerPlayer player = PropHuntServer.GetPlayer(id);
			if (player.seeker && PropHuntServer.GameState != 0)
			{
				PropHuntServer.instance.Message(id, "You're a seeker! You can't hide this round.");
				FailedAction(id, id, CustomPackets.PropSwap, CorrectionActions.DisableClientProp);
				return;
			}
			player.propLocation = data.PropPosition;
			player.propRotation = data.PropRotation;
			BaseCoverManager.ConstrainPropLocation(ref player.propLocation, ref player.propRotation);
			ForwardPropLocation(id, player.propLocation, player.propRotation);
		}

		private static void OnSync(ushort id, global::PropHuntMod.Utils.Networking.FromClient.Sync data)
		{
			//IL_0057: 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_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_0092: Unknown result type (might be due to invalid IL or missing references)
			ServerPlayer player = PropHuntServer.GetPlayer(id);
			if (player.seeker)
			{
				player.propName = "";
				player.propPath = "";
				player.propRotation = 0f;
				player.propLocation = Vector3.zero;
			}
			else
			{
				player.propName = data.PropName;
				player.propPath = data.PropPath;
				player.propLocation = data.PropLocation;
				player.propRotation = data.PropRotation;
			}
			BaseCoverManager.ConstrainPropLocation(ref player.propLocation, ref player.propRotation);
			ForwardPropSwap(id, player.propName, player.propPath);
			ForwardPropLocation(id, player.propLocation, player.propRotation);
			PropHuntServer.instance.CheckGameOver(player.PlayerAvatar);
		}

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

		private static void OnPropFound(ushort id, global::PropHuntMod.Utils.Networking.FromClient.PropFound data)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			ServerPlayer player = PropHuntServer.GetPlayer(data.PropOwnerID);
			ServerPlayer player2 = PropHuntServer.GetPlayer(id);
			if (PropHuntServer.GameState == GameState.SeekerWait)
			{
				PropHuntServer.instance.Message(id, "You're still in the waiting period. No seeking yet!");
				FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectionActions.RestoreTriggerHandler);
				return;
			}
			if (PropHuntServer.GameState == GameState.Playing)
			{
				if (player.seeker)
				{
					PropHuntServer.instance.Message(id, "That player is a seeker!");
					FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectionActions.DisablePlayerProp);
					return;
				}
				if (!player2.seeker)
				{
					PropHuntServer.instance.Message(id, "You're not a seeker! You can't find people this round.");
					FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectionActions.RestoreTriggerHandler);
					return;
				}
				player.seeker = true;
			}
			if (string.IsNullOrEmpty(player.propName))
			{
				PropHuntServer.instance.Message(id, "That player has already been found. You might be out of sync.");
				FailedAction(id, data.PropOwnerID, CustomPackets.PropFound, CorrectionActions.DisablePlayerProp);
				return;
			}
			player.propName = null;
			player.propLocation = Vector3.zero;
			player.propRotation = 0f;
			ForwardPropFound(id, data.PropOwnerID);
			PropHuntServer.instance.Announce(player.PlayerAvatar.Username + " was found by " + player2.PlayerAvatar.Username + "!");
			if (PropHuntServer.GameState == GameState.Playing)
			{
				PropHuntServer.instance.CheckGameOver(player.PlayerAvatar);
			}
		}
	}
}
namespace PropHuntMod.Utils.Networking.FromServer
{
	public class PropSwap : global::PropHuntMod.Utils.Networking.FromClient.PropSwap
	{
		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 : IPacketData
	{
		public bool IsSeeker;

		public ushort PropSwapLimit;

		public int SeekerWaitTime;

		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

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

		public void ReadData(IPacket packet)
		{
			IsSeeker = packet.ReadBool();
			PropSwapLimit = packet.ReadUShort();
			SeekerWaitTime = packet.ReadInt();
		}
	}
	public class PropLocation : global::PropHuntMod.Utils.Networking.FromClient.PropLocation
	{
		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.Utils.Networking.FromClient.HideStatus
	{
		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.Utils.Networking.FromClient.PropFound
	{
		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 : IPacketData
	{
		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

		public void WriteData(IPacket packet)
		{
		}

		public void ReadData(IPacket packet)
		{
		}
	}
	public class GameOver : IPacketData
	{
		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

		public string WinnerUsername { get; set; }

		public bool IsWinner { get; set; }

		public bool WasCanceled { get; set; }

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

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

		public CorrectionActions FixMethod;

		public ushort AffectedID;

		public int BypassTicketID;

		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

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

		public void ReadData(IPacket packet)
		{
			FailedPacket = (CustomPackets)packet.ReadInt();
			FixMethod = (CorrectionActions)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 PropSwap(), 
				CustomPackets.RoundStart => new RoundStart(), 
				CustomPackets.PropLocation => new PropLocation(), 
				CustomPackets.HideStatus => new HideStatus(), 
				CustomPackets.PropFound => new PropFound(), 
				CustomPackets.GameOver => new GameOver(), 
				CustomPackets.SeekerStart => new SeekerStart(), 
				CustomPackets.FailedAction => new FailedAction(), 
				_ => throw new NotImplementedException(packetID.ToString()), 
			});
		}
	}
}
namespace PropHuntMod.Utils.Networking.FromClient
{
	public class PropSwap : IPacketData
	{
		public string propName = "";

		public string propPath = "";

		public int TicketID = -1;

		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

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

		public virtual void ReadData(IPacket packet)
		{
			propName = packet.ReadString();
			propPath = packet.ReadString();
			TicketID = packet.ReadInt();
		}
	}
	public class PropLocation : IPacketData
	{
		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

		public Vector3 PropPosition { get; set; }

		public float PropRotation { get; set; }

		public virtual void WriteData(IPacket packet)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			packet.Write(PropPosition.x);
			packet.Write(PropPosition.y);
			packet.Write(PropPosition.z);
			packet.Write(PropRotation);
		}

		public virtual void ReadData(IPacket packet)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			PropPosition = new Vector3(packet.ReadFloat(), packet.ReadFloat(), packet.ReadFloat());
			PropRotation = packet.ReadFloat();
		}
	}
	public class HideStatus : IPacketData
	{
		public int TicketID = -1;

		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

		public bool IsHiding { get; set; }

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

		public virtual void ReadData(IPacket packet)
		{
			IsHiding = packet.ReadBool();
			TicketID = packet.ReadInt();
		}
	}
	public class PropFound : IPacketData
	{
		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

		public ushort PropOwnerID { get; set; }

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

		public virtual void ReadData(IPacket packet)
		{
			PropOwnerID = packet.ReadUShort();
		}
	}
	public class Sync : IPacketData
	{
		public bool IsReliable => true;

		public bool DropReliableDataIfNewerExists => true;

		public string PropName { get; set; }

		public string PropPath { get; set; }

		public Vector3 PropLocation { get; set; }

		public float PropRotation { get; set; }

		public virtual void WriteData(IPacket packet)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			packet.Write(PropName);
			packet.Write(PropPath);
			packet.Write(PropLocation.x);
			packet.Write(PropLocation.y);
			packet.Write(PropLocation.z);
			packet.Write(PropRotation);
		}

		public virtual void ReadData(IPacket packet)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			PropName = packet.ReadString();
			PropPath = packet.ReadString();
			PropLocation = new Vector3(packet.ReadFloat(), packet.ReadFloat(), packet.ReadFloat());
			PropRotation = 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 PropFound(), 
				CustomPackets.Sync => new Sync(), 
				_ => throw new NotImplementedException(packetID.ToString()), 
			});
		}
	}
}
namespace PropHuntMod.Server
{
	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;
				PropHuntServer.instance.Announce("[Seekers]: Ready or not, here we come!");
				PropHuntServer.GameState = GameState.Playing;
				ServerNetwork.BroadcastSeekerStart();
			}
			else if (seconds <= 5)
			{
				PropHuntServer.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 = Vector3.zero;

		public float propRotation;

		public int swapCount;

		public IServerPlayer PlayerAvatar => PropHuntServer._serverApi.ServerManager.GetPlayer(id);

		public ServerPlayer(ushort id)
		{
			//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)
			this.id = id;
		}
	}
}
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()
		{
		}
	}
	internal sealed class Settings
	{
		private void SettingChangingEventHandler(object sender, SettingChangingEventArgs e)
		{
		}

		private void SettingsSavingEventHandler(object sender, CancelEventArgs e)
		{
		}
	}
}
namespace PropHuntMod.Modifications
{
	internal class AttackCooldownPatches
	{
		private readonly TraceListener listener = new ConsoleTraceListener();

		public AttackCooldownPatches()
		{
			Trace.Listeners.Add(listener);
		}

		public static void SetAttackCooldown(ref float cooldown)
		{
			float num = 0f;
			cooldown = num;
			Log.LogInfo("cooled down");
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(HeroController), "CanAttack")]
		public static void Attack(HeroController __instance)
		{
			Console.WriteLine(new StackTrace(fNeedFileInfo: true).ToString());
		}
	}
	internal class EffectVerticalSweep : MonoBehaviour
	{
		[CompilerGenerated]
		private sealed class <Sweep>d__13 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public EffectVerticalSweep <>4__this;

			private int <i>5__2;

			private float <t>5__3;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Expected O, but got Unknown
				int num = <>1__state;
				EffectVerticalSweep effectVerticalSweep = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<i>5__2 = 0;
					goto IL_00ea;
				case 1:
					<>1__state = -1;
					goto IL_0085;
				case 2:
					{
						<>1__state = -1;
						effectVerticalSweep.SetSweep(0f);
						goto IL_00da;
					}
					IL_00ea:
					if (<i>5__2 < effectVerticalSweep.sweepCount)
					{
						<t>5__3 = 0f;
						goto IL_0085;
					}
					effectVerticalSweep.onComplete?.Invoke();
					Debug.Log((object)"Sweep finished");
					return false;
					IL_0085:
					if (<t>5__3 < effectVerticalSweep.duration)
					{
						<t>5__3 += Time.deltaTime;
						float sweep = Mathf.Clamp01(<t>5__3 / effectVerticalSweep.duration);
						effectVerticalSweep.SetSweep(sweep);
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					effectVerticalSweep.SetSweep(1f);
					if (<i>5__2 < effectVerticalSweep.sweepCount - 1)
					{
						<>2__current = (object)new WaitForSeconds(effectVerticalSweep.delayBetweenSweeps);
						<>1__state = 2;
						return true;
					}
					goto IL_00da;
					IL_00da:
					<i>5__2++;
					goto IL_00ea;
				}
			}

			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 int sweepCount = 3;

		public float duration = 1f;

		public float delayBetweenSweeps = 0.3f;

		public Action onComplete;

		private SpriteRenderer[] renderers;

		private MaterialPropertyBlock block;

		private static int MinY;

		private static int MaxY;

		private static int SweepID;

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			renderers = ((Component)this).GetComponentsInChildren<SpriteRenderer>();
			block = new MaterialPropertyBlock();
			SpriteRenderer[] array = renderers;
			for (int i = 0; i < array.Length; i++)
			{
				((Renderer)array[i]).material = new Material(EffectsManager.SweepShader);
			}
			MinY = Shader.PropertyToID("_BoundsMinY");
			MaxY = Shader.PropertyToID("_BoundsMaxY");
			SweepID = Shader.PropertyToID("_SweepPosition");
			ComputeAndApplyBounds();
		}

		private void ComputeAndApplyBounds()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			float num = float.PositiveInfinity;
			float num2 = float.NegativeInfinity;
			SpriteRenderer[] array = renderers;
			for (int i = 0; i < array.Length; i++)
			{
				Bounds bounds = ((Renderer)array[i]).bounds;
				num = Mathf.Min(num, ((Bounds)(ref bounds)).min.y);
				num2 = Mathf.Max(num2, ((Bounds)(ref bounds)).max.y);
			}
			array = renderers;
			foreach (SpriteRenderer obj in array)
			{
				((Renderer)obj).GetPropertyBlock(block);
				block.SetFloat(MinY, num);
				block.SetFloat(MaxY, num2);
				((Renderer)obj).SetPropertyBlock(block);
			}
		}

		private void Start()
		{
			Play();
		}

		private void Play()
		{
			((MonoBehaviour)this).StopAllCoroutines();
			((MonoBehaviour)this).StartCoroutine(Sweep());
		}

		[IteratorStateMachine(typeof(<Sweep>d__13))]
		private IEnumerator Sweep()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Sweep>d__13(0)
			{
				<>4__this = this
			};
		}

		private void SetSweep(float value)
		{
			SpriteRenderer[] array