Decompiled source of HideNSeek v1.2.0

HideNSeek.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using OPJosMod;
using OPJosMod.HideNSeek.Config;
using OPJosMod.HideNSeek.CustomRpc;
using OPJosMod.HideNSeek.Utils;
using OPJosMode.HideNSeek.Patches;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("OPJosMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OPJosMod")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("70095872-b952-4e27-bbc4-3d70d0238f39")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace OPJosMode.HideNSeek.Patches
{
	[HarmonyPatch(typeof(EntranceTeleport))]
	internal class EntranceTeleportPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("FindExitPoint")]
		[HarmonyPrefix]
		private static bool findExitPointPatch()
		{
			if (PlayerControllerBPatch.isHider)
			{
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TimeOfDay))]
	internal class TimeOfDayPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void updatePatch(TimeOfDay __instance)
		{
			int num = RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB x) => !x.playerUsername.Contains("Player #")).ToArray().Length;
			float daySpeedMultiplier = ConfigVariables.daySpeedMultiplier;
			__instance.globalTimeSpeedMultiplier = daySpeedMultiplier * 4f / (float)num;
		}
	}
	[HarmonyPatch(typeof(Turret))]
	internal class TurretPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void startPatch(Turret __instance)
		{
			__instance.turretActive = false;
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("FinishGeneratingNewLevelClientRpc")]
		[HarmonyPostfix]
		private static void finishGeneratingNewLevelClientRpcPatch(RoundManager __instance)
		{
			if (PlayerControllerBPatch.isSeeker)
			{
				PlayerControllerBPatch.SetupSeeker();
			}
			else
			{
				PlayerControllerBPatch.SetupHider();
			}
		}

		[HarmonyPatch("LoadNewLevel")]
		[HarmonyPrefix]
		private static void loadNewLevelPatch(RoundManager __instance)
		{
			//IL_0075: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			mls.LogMessage((object)"load new level patch hit");
			if (GameNetworkManager.Instance.isHostingGame)
			{
				__instance.currentMaxInsidePower = 0f;
				__instance.currentMaxOutsidePower = 0f;
				__instance.currentLevel.maxEnemyPowerCount = 0;
				__instance.currentLevel.maxOutsideEnemyPowerCount = 0;
				if (!ConfigVariables.shouldSpawnScrap)
				{
					__instance.scrapAmountMultiplier = 0f;
				}
				Vector3 position = __instance.playersManager.playerSpawnPositions[0].position;
				GeneralUtil.spawnItemAtLocation(ConfigVariables.seekerItem1, position);
				GeneralUtil.spawnItemAtLocation(ConfigVariables.seekerItem2, position);
				GeneralUtil.spawnItemAtLocation(ConfigVariables.seekerItem3, position);
				GeneralUtil.spawnItemAtLocation(ConfigVariables.seekerItem4, position);
			}
		}
	}
	[HarmonyPatch(typeof(FlashlightItem))]
	internal class FlashlightItemPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void startPatch(FlashlightItem __instance)
		{
			if (__instance.flashlightTypeID == 1)
			{
				((GrabbableObject)__instance).itemProperties.requiresBattery = false;
				__instance.flashlightBulb.intensity = __instance.flashlightBulb.intensity / (float)ConfigVariables.smallFlashlightPower;
			}
			else if (__instance.flashlightTypeID == 0)
			{
				((GrabbableObject)__instance).itemProperties.weight = 1.05f * ConfigVariables.proFlashlightWeightMultiplier;
				((GrabbableObject)__instance).itemProperties.batteryUsage = 300f * ConfigVariables.proFlashlightBatteryUsageMultiplier;
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal class TerminalPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void startPatch(Terminal __instance)
		{
			if (GameNetworkManager.Instance.isHostingGame)
			{
				__instance.groupCredits = 123456789;
				__instance.SyncGroupCreditsServerRpc(__instance.groupCredits, __instance.numberOfItemsInDropship);
			}
		}

		[HarmonyPatch("RunTerminalEvents")]
		[HarmonyPrefix]
		private static void runTerminalEventsPatch(Terminal __instance)
		{
			if (GameNetworkManager.Instance.isHostingGame)
			{
				__instance.groupCredits = 123456789;
				__instance.SyncGroupCreditsServerRpc(__instance.groupCredits, __instance.numberOfItemsInDropship);
			}
		}
	}
	[HarmonyPatch(typeof(Shovel))]
	internal class ShovelPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("HitShovel")]
		[HarmonyPrefix]
		private static void hitShovelPatch(Shovel __instance)
		{
			__instance.shovelHitForce = 30;
		}
	}
	[HarmonyPatch(typeof(StartMatchLever))]
	internal class StartMatchLeverPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("PullLever")]
		[HarmonyPrefix]
		private static void pullLeverPatch(StartMatchLever __instance)
		{
			mls.LogMessage((object)"player pulled lever, set them to seeker");
			PlayerControllerBPatch.isSeeker = true;
			PlayerControllerBPatch.isHider = false;
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	internal class HUDManagerPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("PingScan_performed")]
		[HarmonyPrefix]
		private static bool pingScan_performedPatch()
		{
			if (PlayerControllerBPatch.isSeeker)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch("FillEndGameStats")]
		[HarmonyPrefix]
		private static void fillEndGameStatsPatchPre(HUDManager __instance, ref EndOfGameStats stats)
		{
			for (int i = 0; i < RoundManager.Instance.playersManager.allPlayerScripts.Length; i++)
			{
				StartOfRound.Instance.gameStats.allPlayerStats[i].playerNotes.Clear();
				if (RoundManager.Instance.playersManager.allPlayerScripts[i].isPlayerDead)
				{
					mls.LogMessage((object)$"player{i} is dead, so they lost");
					StartOfRound.Instance.gameStats.allPlayerStats[i].playerNotes.Add("Lost the game :(");
				}
				else
				{
					mls.LogMessage((object)$"player{i} won!");
					StartOfRound.Instance.gameStats.allPlayerStats[i].playerNotes.Add("Won the game!");
				}
			}
			for (int j = 0; j < __instance.statsUIElements.playerNotesText.Length; j++)
			{
				PlayerControllerB val = RoundManager.Instance.playersManager.allPlayerScripts[j];
				TextMeshProUGUI val2 = __instance.statsUIElements.playerNotesText[j];
				if (!val.playerUsername.Contains("Player #"))
				{
					if (val.isPlayerDead)
					{
						((TMP_Text)val2).text = "They lost :(";
					}
					else
					{
						((TMP_Text)val2).text = "They Won!";
					}
				}
				else
				{
					mls.LogMessage((object)$"dont put stats for player {j}");
					((TMP_Text)val2).text = "";
				}
			}
		}

		[HarmonyPatch("FillEndGameStats")]
		[HarmonyPostfix]
		private static void fillEndGameStatsPatchPost(HUDManager __instance, ref EndOfGameStats stats)
		{
			((Component)HUDManager.Instance.statsUIElements.allPlayersDeadOverlay).gameObject.SetActive(false);
			if (StartOfRound.Instance.localPlayerController.isPlayerDead)
			{
				((TMP_Text)HUDManager.Instance.statsUIElements.gradeLetter).text = "L";
			}
			else
			{
				((TMP_Text)HUDManager.Instance.statsUIElements.gradeLetter).text = "W";
			}
		}

		[HarmonyPatch("ApplyPenalty")]
		[HarmonyPrefix]
		private static bool applyPenaltyPatch(HUDManager __instance, ref int playersDead, ref int bodiesInsured)
		{
			return false;
		}

		public static void CustomDisplayTip(string headerText, string bodyText, bool makeSound = true)
		{
			HUDManager instance = HUDManager.Instance;
			((TMP_Text)instance.tipsPanelHeader).text = headerText;
			((TMP_Text)instance.tipsPanelBody).text = bodyText;
			instance.tipsPanelAnimator.SetTrigger("TriggerHint");
			if (makeSound)
			{
				RoundManager.PlayRandomClip(instance.UIAudio, instance.tipsSFX, false, 1f, 0, 1000);
			}
		}

		public static void CustomDisplayBigMessage(string maingText, bool makeSound = true)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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)
			((Graphic)HUDManager.Instance.profitQuotaDaysLeftText).color = new Color(0.8431f, 0.2314f, 0.2196f, 1f);
			((TMP_Text)HUDManager.Instance.profitQuotaDaysLeftText).fontSize = 46f;
			((TMP_Text)HUDManager.Instance.profitQuotaDaysLeftText).fontStyle = (FontStyles)1;
			((Transform)((TMP_Text)HUDManager.Instance.profitQuotaDaysLeftText).rectTransform).localScale = new Vector3(1f, 1.04f, 1.02f);
			((TMP_Text)HUDManager.Instance.profitQuotaDaysLeftText).text = "TO MEET PROFIT QUOTA";
			Vector3 position = default(Vector3);
			((Vector3)(ref position))..ctor(-21.78f, -59.48f, 12.15f);
			((TMP_Text)HUDManager.Instance.profitQuotaDaysLeftText).transform.position = position;
			((Graphic)HUDManager.Instance.profitQuotaDaysLeftText2).color = new Color(0f, 0f, 0f, 1f);
			((TMP_Text)HUDManager.Instance.profitQuotaDaysLeftText2).text = maingText;
			((TMP_Text)HUDManager.Instance.profitQuotaDaysLeftText2).fontSize = 46f;
			HUDManager.Instance.reachedProfitQuotaAnimator.SetTrigger("displayDaysLeft");
			if (makeSound)
			{
				HUDManager.Instance.UIAudio.PlayOneShot(HUDManager.Instance.OneDayToMeetQuotaSFX);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void startPatch(StartOfRound __instance)
		{
			((TMP_Text)__instance.profitQuotaMonitorText).text = "Hide N Seek!";
			((TMP_Text)__instance.deadlineMonitorText).text = "Have fun and such";
			((Component)__instance.mapScreen).gameObject.SetActive(false);
			TimeOfDay.Instance.daysUntilDeadline = 4;
			TimeOfDay.Instance.timeUntilDeadline = 75500f;
		}

		[HarmonyPatch("ReviveDeadPlayers")]
		[HarmonyPrefix]
		private static void reviveDeadPlayersPatch(StartOfRound __instance)
		{
			mls.LogMessage((object)"revive dead players patch hit in start of round class, reset isSeeker and isHider");
			PlayerControllerBPatch.resetRoleValues();
		}

		[HarmonyPatch("ShipLeave")]
		[HarmonyPrefix]
		public static void shipLeavePatch(StartOfRound __instance)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			if (!StartOfRound.Instance.localPlayerController.isPlayerDead && PlayerControllerBPatch.isHider && TimeOfDay.Instance.currentDayTime + 10f > TimeOfDay.Instance.globalTimeAtEndOfDay)
			{
				mls.LogMessage((object)"ship taking off but player isn't dead");
				((Component)StartOfRound.Instance.localPlayerController).transform.position = RoundManager.Instance.playersManager.playerSpawnPositions[0].position;
				HUDManager.Instance.DisplayTip("Round Over!", "Stay on ship", false, false, "LC_Tip1");
			}
			if (!StartOfRound.Instance.localPlayerController.isPlayerDead && PlayerControllerBPatch.isSeeker)
			{
				int num = RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB x) => x.isPlayerControlled).Count();
				if (num == 1)
				{
					mls.LogMessage((object)"you won as seeker!");
					((Component)StartOfRound.Instance.localPlayerController).transform.position = RoundManager.Instance.playersManager.playerSpawnPositions[0].position;
					HUDManager.Instance.DisplayTip("Round Over!", "Stay on ship", false, false, "LC_Tip1");
				}
			}
			PlayerControllerBPatch.resetRoleValues();
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		public static void StartOfRoundSuitPatch(StartOfRound __instance)
		{
			if (GameNetworkManager.Instance.isHostingGame)
			{
				int[] array = new int[6] { 1, 2, 3, 24, 25, 26 };
				int[] array2 = array;
				foreach (int num in array2)
				{
					ReflectionUtils.InvokeMethod(StartOfRound.Instance, "SpawnUnlockable", new object[1] { num });
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
		[HarmonyPostfix]
		public static void ResetShipSuitPatch(StartOfRound __instance)
		{
			if (GameNetworkManager.Instance.isHostingGame)
			{
				StartOfRoundSuitPatch(__instance);
			}
		}

		[HarmonyPatch("SetPlanetsWeather")]
		[HarmonyPostfix]
		private static void setPlanetsWeatherPatch(ref SelectableLevel[] ___levels)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < ___levels.Length; i++)
			{
				___levels[i].currentWeather = (LevelWeatherType)(-1);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerBPatch
	{
		private static ManualLogSource mls;

		public static bool hasSetRole = false;

		public static bool isSeeker = false;

		public static bool isHider = false;

		private static Coroutine teleportCoroutine;

		private static Coroutine lockPlayerCoroutine;

		private static float lastCheckedTime;

		private static float checkGameOverFrequency = 5f;

		private static float lastUsedSeekerAbilityAt = Time.time;

		private static int lastCheckedAliveCount = -1;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		public static void resetRoleValues()
		{
			hasSetRole = false;
			isSeeker = false;
			isHider = false;
			lastCheckedTime = Time.time;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void updatePatch(PlayerControllerB __instance)
		{
			if (isSeeker)
			{
				if (ReflectionUtils.GetFieldValue<bool>(__instance, "isWalking"))
				{
					float fieldValue = ReflectionUtils.GetFieldValue<float>(__instance, "sprintMultiplier");
					if (__instance.isSprinting)
					{
						float num = fieldValue * ConfigVariables.seekerSprintMultiplier;
						if (num < ConfigVariables.seekerMaxSprintSpeed)
						{
							ReflectionUtils.SetFieldValue(__instance, "sprintMultiplier", num);
						}
					}
				}
				if (Mouse.current.rightButton.wasPressedThisFrame)
				{
					if (Time.time - lastUsedSeekerAbilityAt > ConfigVariables.seekerAbilityCD)
					{
						lastUsedSeekerAbilityAt = Time.time;
						makeClosestPlayerWhistle(StartOfRound.Instance.localPlayerController);
					}
					else if (Time.time - lastUsedSeekerAbilityAt > 1f)
					{
						HUDManagerPatch.CustomDisplayTip("Ability on cooldown", $"for {(int)(ConfigVariables.seekerAbilityCD - (Time.time - lastUsedSeekerAbilityAt))} seconds", makeSound: false);
					}
				}
			}
			if (Time.time - lastCheckedTime > checkGameOverFrequency)
			{
				checkIfShouldEndRound(__instance);
				lastCheckedTime = Time.time;
			}
			if (isSeeker || isHider)
			{
				HUDManager.Instance.SetClockVisible(true);
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void startPatch(PlayerControllerB __instance)
		{
			__instance.allHelmetLights[1].intensity = __instance.allHelmetLights[1].intensity / (float)ConfigVariables.smallFlashlightPower;
			__instance.jumpForce = ConfigVariables.jumpForce;
			((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = "";
			((Component)HUDManager.Instance.holdButtonToEndGameEarlyMeter).gameObject.SetActive(false);
			((TMP_Text)HUDManager.Instance.holdButtonToEndGameEarlyVotesText).text = "";
			((TMP_Text)HUDManager.Instance.holdButtonToEndGameEarlyText).text = "";
			((TMP_Text)HUDManager.Instance.spectatorTipText).text = "";
			HUDManager.Instance.gameOverAnimator.SetTrigger("gameOver");
		}

		[HarmonyPatch("KillPlayer")]
		[HarmonyPostfix]
		private static void killPlayerPatch(PlayerControllerB __instance)
		{
			if (isSeeker)
			{
				mls.LogMessage((object)"end game called as you are a seeker");
				StartOfRound.Instance.EndGameServerRpc((int)__instance.playerClientId);
			}
		}

		private static void checkIfShouldEndRound(PlayerControllerB __instance)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			int totalPlayersCount = GeneralUtil.getTotalPlayersCount();
			int num = RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB x) => x.isPlayerControlled).Count();
			Vector3 position = RoundManager.Instance.playersManager.playerSpawnPositions[0].position;
			if (num < lastCheckedAliveCount && lastCheckedAliveCount != -1)
			{
				if (isSeeker)
				{
					HUDManagerPatch.CustomDisplayTip("Someone has Died!", $"{num} players remain", makeSound: false);
				}
				else if (isHider)
				{
					HUDManagerPatch.CustomDisplayBigMessage($"Someone Died! \n {num} players remain");
				}
			}
			lastCheckedAliveCount = num;
			((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = $"|{num}/{totalPlayersCount} players remain|";
			if (num == 1)
			{
				mls.LogMessage((object)$"one person alive, round over. totalPlayers:{num}");
				StartOfRound.Instance.EndGameServerRpc((int)__instance.playerClientId);
			}
		}

		public static void SetupHider()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (!hasSetRole)
			{
				HUDManager.Instance.DisplayTip("Role Set", "You are a Hider!", false, false, "LC_Tip1");
				hasSetRole = true;
				mls.LogMessage((object)"setup player as a hider");
				PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
				isSeeker = false;
				isHider = true;
				teleportCoroutine = ((MonoBehaviour)localPlayerController).StartCoroutine(customTeleportPlayer(localPlayerController, RoundManager.FindMainEntrancePosition(false, false), 5f));
				localPlayerController.isInsideFactory = true;
			}
		}

		public static void SetupSeeker()
		{
			if (!hasSetRole)
			{
				HUDManager.Instance.DisplayTip("Role Set", "You are Seeker!", false, false, "LC_Tip1");
				hasSetRole = true;
				mls.LogMessage((object)"setup player as seeker");
				PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
				isSeeker = true;
				isHider = false;
				lockPlayerCoroutine = ((MonoBehaviour)localPlayerController).StartCoroutine(lockPlayer(localPlayerController, ConfigVariables.seekerDelay));
			}
		}

		private static IEnumerator customTeleportPlayer(PlayerControllerB player, Vector3 location, float initalDelay)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (teleportCoroutine != null)
			{
				((MonoBehaviour)player).StopCoroutine(teleportCoroutine);
			}
			yield return (object)new WaitForSeconds(initalDelay);
			player.DropAllHeldItemsAndSync();
			yield return (object)new WaitForSeconds(1f);
			GameNetworkManager.Instance.localPlayerController.TeleportPlayer(location, false, 0f, false, true);
		}

		private static IEnumerator lockPlayer(PlayerControllerB player, float lockTime)
		{
			if (lockPlayerCoroutine != null)
			{
				((MonoBehaviour)player).StopCoroutine(lockPlayerCoroutine);
			}
			yield return (object)new WaitForSeconds(1f);
			mls.LogMessage((object)"player locked in place");
			player.playerCollider.enabled = false;
			for (int i = 0; (float)i < lockTime; i++)
			{
				yield return (object)new WaitForSeconds(1f);
				HUDManagerPatch.CustomDisplayTip($"{lockTime - (float)(i + 1)}", "seconds remain", makeSound: false);
			}
			HUDManagerPatch.CustomDisplayTip("GO FIND", "THEM!", makeSound: false);
			mls.LogMessage((object)"player unlocked!");
			player.playerCollider.enabled = true;
			string message = MessageTaskUtil.GetCode(MessageTasks.StartedSeeking) + player.playerClientId;
			RpcMessage rpcMessage = new RpcMessage(message, (int)player.playerClientId, MessageCodes.Request);
			RpcMessageHandler.SendRpcMessage(rpcMessage);
			GeneralUtil.spawnHiderItem((int)player.playerClientId);
		}

		private static void makeClosestPlayerWhistle(PlayerControllerB localPlayer)
		{
			mls.LogMessage((object)"Making closest player whistle");
			HUDManagerPatch.CustomDisplayTip("Closest Player", "made a noise", makeSound: false);
			PlayerControllerB val = findClosestPlayer(localPlayer);
			PlaySounds.PlayFart(val);
			string message = MessageTaskUtil.GetCode(MessageTasks.MakePlayerWhistle) + val.playerClientId;
			RpcMessage message2 = new RpcMessage(message, (int)localPlayer.playerClientId, MessageCodes.Request);
			RpcMessageHandler.SendRpcMessage(message2);
		}

		private static PlayerControllerB findClosestPlayer(PlayerControllerB localPlayer)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB result = null;
			float num = float.MaxValue;
			PlayerControllerB[] allPlayerScripts = RoundManager.Instance.playersManager.allPlayerScripts;
			PlayerControllerB[] array = allPlayerScripts;
			foreach (PlayerControllerB val in array)
			{
				if (val.playerClientId != localPlayer.playerClientId)
				{
					float num2 = Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val).transform.position);
					if (num2 < num)
					{
						result = val;
						num = num2;
					}
				}
			}
			return result;
		}
	}
}
namespace OPJosMod
{
	public enum FlashlightTypes
	{
		ProFlashlight,
		NormalFlashlight
	}
	public enum BuyableItems
	{
		None = -1,
		WalkieTalkie,
		Flashlight,
		Shovel,
		LockPicker,
		ProFlashlight,
		StunGrenade,
		Boombox,
		TZPInhalant,
		ZapGun,
		Jetpack,
		ExtensionLadder,
		RadarBooster,
		SprayPaint
	}
	public static class GeneralUtil
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		public static void spawnItemAtLocation(BuyableItems item, Vector3 location)
		{
			//IL_0039: 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)
			if (GameNetworkManager.Instance.isHostingGame)
			{
				if (item != BuyableItems.None)
				{
					Terminal fieldValue = ReflectionUtils.GetFieldValue<Terminal>(HUDManager.Instance, "terminalScript");
					GameObject val = Object.Instantiate<GameObject>(fieldValue.buyableItemsList[(int)item].spawnPrefab, location, Quaternion.identity, StartOfRound.Instance.localPlayerController.playersManager.propsContainer);
					val.GetComponent<GrabbableObject>().fallTime = 0f;
					val.GetComponent<NetworkObject>().Spawn(false);
				}
			}
			else
			{
				mls.LogError((object)$"tried to spawn item: {item} but can't as this is not the host");
			}
		}

		public static void spawnHiderItem(int seekerId)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if (!GameNetworkManager.Instance.isHostingGame)
			{
				return;
			}
			PlayerControllerB[] allPlayersConneced = getAllPlayersConneced();
			PlayerControllerB[] array = allPlayersConneced;
			foreach (PlayerControllerB val in array)
			{
				if ((int)val.playerClientId != seekerId)
				{
					mls.LogMessage((object)$"spawn hider item at {((Component)val).transform.position}");
					spawnItemAtLocation(ConfigVariables.hiderItem, ((Component)val).transform.position);
				}
				else
				{
					mls.LogMessage((object)$"dont spawn hider item at this players position,{val.playerClientId} they are seeker");
				}
			}
		}

		public static int getTotalPlayersCount()
		{
			PlayerControllerB[] array = RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB x) => !x.playerUsername.Contains("Player #")).ToArray();
			return array.Length;
		}

		public static PlayerControllerB[] getAllPlayersConneced()
		{
			return RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB x) => !x.playerUsername.Contains("Player #")).ToArray();
		}
	}
	public static class PlaySounds
	{
		private static WhoopieCushionItem whoopieItem;

		private static AudioClip[] fartAudios;

		private static Vector3 lastPositionAtFart;

		private static int timesPlayingInOneSpot;

		public static void InitializePlaySounds()
		{
			whoopieItem = Resources.FindObjectsOfTypeAll<WhoopieCushionItem>()[0];
			fartAudios = whoopieItem.fartAudios;
		}

		public static void PlayFart(PlayerControllerB player)
		{
			//IL_0026: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			InitializePlaySounds();
			AudioSource itemAudio = player.itemAudio;
			itemAudio.volume = 0.7f;
			itemAudio.maxDistance = 80f;
			if (Vector3.Distance(lastPositionAtFart, ((Component)player).transform.position) > 2f)
			{
				timesPlayingInOneSpot = 0;
			}
			timesPlayingInOneSpot++;
			lastPositionAtFart = ((Component)player).transform.position;
			RoundManager.PlayRandomClip(itemAudio, fartAudios, true, 1f, -1, 1000);
			RoundManager.Instance.PlayAudibleNoise(((Component)player).transform.position, 22f, 0.5f, timesPlayingInOneSpot, false, 101158);
		}
	}
}
namespace OPJosMod.HideNSeek
{
	[BepInPlugin("OpJosMod.HideNSeek", "HideNSeek", "1.2.0")]
	public class OpJosMod : BaseUnityPlugin
	{
		private const string modGUID = "OpJosMod.HideNSeek";

		private const string modName = "HideNSeek";

		private const string modVersion = "1.2.0";

		private readonly Harmony harmony = new Harmony("OpJosMod.HideNSeek");

		private static OpJosMod Instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("OpJosMod.HideNSeek");
			mls.LogInfo((object)"mod has started");
			setupConfig();
			RpcMessageHandler.SetLogSource(mls);
			HUDManagerPatchForRPC.SetLogSource(mls);
			CompleteRecievedTasks.SetLogSource(mls);
			PlayerControllerBPatch.SetLogSource(mls);
			StartOfRoundPatch.SetLogSource(mls);
			StartMatchLeverPatch.SetLogSource(mls);
			RoundManagerPatch.SetLogSource(mls);
			HUDManagerPatch.SetLogSource(mls);
			EntranceTeleportPatch.SetLogSource(mls);
			ShovelPatch.SetLogSource(mls);
			TerminalPatch.SetLogSource(mls);
			GeneralUtil.SetLogSource(mls);
			FlashlightItemPatch.SetLogSource(mls);
			TurretPatch.SetLogSource(mls);
			TimeOfDayPatch.SetLogSource(mls);
			harmony.PatchAll();
		}

		private void setupConfig()
		{
			ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>("Seeker Delay", "SeekerDelay", 50f, "How long until the seeker can begin seeking");
			ConfigEntry<float> val2 = ((BaseUnityPlugin)this).Config.Bind<float>("Seeker Ability CD", "SeekerAbilityCD", 25f, "Cooldown for seekers ability");
			ConfigEntry<int> val3 = ((BaseUnityPlugin)this).Config.Bind<int>("Small Flashlight Power", "SmallFlashlightPower", 2, "Fraction of brightness, ex) 5 = 1/5th power");
			ConfigEntry<float> val4 = ((BaseUnityPlugin)this).Config.Bind<float>("Pro Flashlight Weight", "ProFlashlightWeight", 1.25f, "Weight Increase multiplier, higher number greater the weight.");
			ConfigEntry<float> val5 = ((BaseUnityPlugin)this).Config.Bind<float>("Pro Flashlight Battery Usage", "ProFlashlightBatteryUsage", 0.5f, "Influences how fast the battery depletes on the pro flashlight, 1 = games default speed");
			ConfigEntry<float> val6 = ((BaseUnityPlugin)this).Config.Bind<float>("Seeking Sprint Multiplier", "SeekingSprintMultiplier", 1.01f, "How fast you accelerate as a seeker");
			ConfigEntry<float> val7 = ((BaseUnityPlugin)this).Config.Bind<float>("Seeking Sprint Top Speed", "SeekingSprintTopSpeed", 3f, "The fastest the seeker can move");
			ConfigEntry<float> val8 = ((BaseUnityPlugin)this).Config.Bind<float>("Day Speed Multiplier", "DaySpeedMultiplier", 2.5f, "Higher the number the faster days go, day speed auto adjusts with players");
			ConfigEntry<bool> val9 = ((BaseUnityPlugin)this).Config.Bind<bool>("Spawn Scrap", "SpawnScrap", false, "should items scrap?");
			ConfigEntry<float> val10 = ((BaseUnityPlugin)this).Config.Bind<float>("Jump Force", "JumpForce", 15f, "How strong your jump is, game default is 5");
			ConfigEntry<BuyableItems> val11 = ((BaseUnityPlugin)this).Config.Bind<BuyableItems>("Seeker Item 1", "SeekerItem1", BuyableItems.Shovel, "Spawned Item for seeker");
			ConfigEntry<BuyableItems> val12 = ((BaseUnityPlugin)this).Config.Bind<BuyableItems>("Seeker Item 2", "SeekerItem2", BuyableItems.Flashlight, "Spawned Item for seeker");
			ConfigEntry<BuyableItems> val13 = ((BaseUnityPlugin)this).Config.Bind<BuyableItems>("Seeker Item 3", "SeekerItem3", BuyableItems.None, "Spawned Item for seeker");
			ConfigEntry<BuyableItems> val14 = ((BaseUnityPlugin)this).Config.Bind<BuyableItems>("Seeker Item 4", "SeekerItem4", BuyableItems.None, "Spawned Item for seeker");
			ConfigEntry<BuyableItems> val15 = ((BaseUnityPlugin)this).Config.Bind<BuyableItems>("Hider Item", "HidingItem", BuyableItems.StunGrenade, "Give Hiders some item to help");
			ConfigVariables.seekerDelay = val.Value;
			ConfigVariables.seekerAbilityCD = val2.Value;
			ConfigVariables.smallFlashlightPower = val3.Value;
			ConfigVariables.proFlashlightWeightMultiplier = val4.Value;
			ConfigVariables.proFlashlightBatteryUsageMultiplier = val5.Value;
			ConfigVariables.seekerSprintMultiplier = val6.Value;
			ConfigVariables.seekerMaxSprintSpeed = val7.Value;
			ConfigVariables.daySpeedMultiplier = val8.Value;
			ConfigVariables.shouldSpawnScrap = val9.Value;
			ConfigVariables.jumpForce = val10.Value;
			ConfigVariables.seekerItem1 = val11.Value;
			ConfigVariables.seekerItem2 = val12.Value;
			ConfigVariables.seekerItem3 = val13.Value;
			ConfigVariables.seekerItem4 = val14.Value;
			ConfigVariables.hiderItem = val15.Value;
		}
	}
}
namespace OPJosMod.HideNSeek.Utils
{
	public class ReflectionUtils
	{
		public static void InvokeMethod(object obj, string methodName, object[] parameters)
		{
			Type type = obj.GetType();
			MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			method.Invoke(obj, parameters);
		}

		public static void InvokeMethod(object obj, Type forceType, string methodName, object[] parameters)
		{
			MethodInfo method = forceType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			method.Invoke(obj, parameters);
		}

		public static void SetPropertyValue(object obj, string propertyName, object value)
		{
			Type type = obj.GetType();
			PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			property.SetValue(obj, value);
		}

		public static T InvokeMethod<T>(object obj, string methodName, object[] parameters)
		{
			Type type = obj.GetType();
			MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (T)method.Invoke(obj, parameters);
		}

		public static T GetFieldValue<T>(object obj, string fieldName)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			return (T)field.GetValue(obj);
		}

		public static void SetFieldValue(object obj, string fieldName, object value)
		{
			Type type = obj.GetType();
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			field.SetValue(obj, value);
		}
	}
}
namespace OPJosMod.HideNSeek.Config
{
	public static class ConfigVariables
	{
		public static float seekerDelay;

		public static float seekerAbilityCD;

		public static int smallFlashlightPower;

		public static float proFlashlightWeightMultiplier;

		public static float proFlashlightBatteryUsageMultiplier;

		public static float seekerSprintMultiplier;

		public static float seekerMaxSprintSpeed;

		public static float daySpeedMultiplier;

		public static bool shouldSpawnScrap;

		public static BuyableItems seekerItem1;

		public static BuyableItems seekerItem2;

		public static BuyableItems seekerItem3;

		public static BuyableItems seekerItem4;

		public static BuyableItems hiderItem;

		public static float jumpForce;
	}
}
namespace OPJosMod.HideNSeek.CustomRpc
{
	public static class CompleteRecievedTasks
	{
		private static ManualLogSource mls;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		public static void SeekingStarted(string playerIdString)
		{
			if (PlayerControllerBPatch.isHider)
			{
				if (ConfigVariables.hiderItem == BuyableItems.None)
				{
					HUDManagerPatch.CustomDisplayTip("Careful!", "Seeker is on their way!");
				}
				else
				{
					HUDManagerPatch.CustomDisplayTip("Seeker is on their way!", "an item dropped at your feet");
				}
			}
			GeneralUtil.spawnHiderItem(int.Parse(playerIdString));
		}

		public static void MakePlayerWhistle(string playerIdString)
		{
			int num = int.Parse(playerIdString);
			mls.LogMessage((object)$"make player{num} whistle");
			PlayerControllerB player = StartOfRound.Instance.allPlayerScripts[num];
			PlaySounds.PlayFart(player);
			if ((int)StartOfRound.Instance.localPlayerController.playerClientId == num)
			{
				mls.LogMessage((object)"seeker made u make noise");
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	internal class HUDManagerPatchForRPC
	{
		private static ManualLogSource mls;

		private static float lastRecieved = Time.time;

		private static float messageWaitTime = 0.1f;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		[HarmonyPatch("AddPlayerChatMessageClientRpc")]
		[HarmonyPrefix]
		private static void addPlayerChatMessageClientRpcPatch(ref string chatMessage, ref int playerId)
		{
			if (MessageCodeUtil.stringContainsMessageCode(chatMessage) && Time.time - lastRecieved > messageWaitTime)
			{
				lastRecieved = Time.time;
				RpcMessageHandler.ReceiveRpcMessage(chatMessage, playerId);
			}
		}

		[HarmonyPatch("AddChatMessage")]
		[HarmonyPrefix]
		private static bool addChatMessagePatch(ref string chatMessage)
		{
			if (MessageCodeUtil.stringContainsMessageCode(chatMessage))
			{
				return false;
			}
			return true;
		}
	}
	public enum MessageTasks
	{
		StartedSeeking,
		MakePlayerWhistle,
		ErrorNoTask
	}
	public static class MessageTaskUtil
	{
		public static string GetCode(MessageTasks code)
		{
			return code switch
			{
				MessageTasks.StartedSeeking => ":StartedSeeking:", 
				MessageTasks.MakePlayerWhistle => ":MakeWhistle:", 
				MessageTasks.ErrorNoTask => ":Error:", 
				_ => ":Error:", 
			};
		}

		public static string getMessageWithoutTask(string message)
		{
			foreach (MessageTasks value in Enum.GetValues(typeof(MessageTasks)))
			{
				string code2 = GetCode(value);
				message = message.Replace(code2, "");
			}
			return message.Trim();
		}

		public static MessageTasks getMessageTask(string givenString)
		{
			if (givenString.Contains(GetCode(MessageTasks.StartedSeeking)))
			{
				return MessageTasks.StartedSeeking;
			}
			if (givenString.Contains(GetCode(MessageTasks.MakePlayerWhistle)))
			{
				return MessageTasks.MakePlayerWhistle;
			}
			return MessageTasks.ErrorNoTask;
		}
	}
	public enum MessageCodes
	{
		Request,
		Response
	}
	public static class MessageCodeUtil
	{
		public static string GetCode(MessageCodes code)
		{
			return code switch
			{
				MessageCodes.Request => ":rpcRequest:", 
				MessageCodes.Response => ":rpcResponse:", 
				_ => ":Error:", 
			};
		}

		public static bool stringContainsMessageCode(string givenString)
		{
			return givenString.Contains(GetCode(MessageCodes.Request)) || givenString.Contains(GetCode(MessageCodes.Response));
		}

		public static string returnMessageWithoutCode(string message)
		{
			if (stringContainsMessageCode(message))
			{
				int length = GetCode(MessageCodes.Request).Length;
				return message.Substring(length);
			}
			return message;
		}
	}
	public class RpcMessage
	{
		public string Message { get; set; }

		public int FromUser { get; set; }

		public MessageCodes MessageCode { get; set; }

		public RpcMessage(string message, int user, MessageCodes code)
		{
			Message = message;
			FromUser = user;
			MessageCode = code;
		}

		public string getMessageWithCode()
		{
			return MessageCodeUtil.GetCode(MessageCode) + Message;
		}
	}
	public static class RpcMessageHandler
	{
		private static ManualLogSource mls;

		private static float lastSentTime = Time.time;

		private static float messageWaitTime = 0.5f;

		public static void SetLogSource(ManualLogSource logSource)
		{
			mls = logSource;
		}

		public static void SendRpcMessage(RpcMessage message)
		{
			if (!(Time.time - lastSentTime > messageWaitTime))
			{
				return;
			}
			lastSentTime = Time.time;
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				MethodInfo method = typeof(HUDManager).GetMethod("AddPlayerChatMessageServerRpc", BindingFlags.Instance | BindingFlags.NonPublic);
				if (method != null)
				{
					object[] parameters = new object[2]
					{
						message.getMessageWithCode(),
						message.FromUser
					};
					method.Invoke(instance, parameters);
				}
				else
				{
					mls.LogError((object)"AddPlayerChatMessageServerRpc method not found in HUDManager class.");
				}
			}
			else
			{
				mls.LogError((object)"HUDManager.Instance is null.");
			}
		}

		public static void ReceiveRpcMessage(string message, int user)
		{
			if (user != (int)StartOfRound.Instance.localPlayerController.playerClientId)
			{
				string text = MessageCodeUtil.returnMessageWithoutCode(message);
				if (message.Contains(MessageCodeUtil.GetCode(MessageCodes.Request)))
				{
					MessageTasks messageTask = MessageTaskUtil.getMessageTask(text);
					string messageWithoutTask = MessageTaskUtil.getMessageWithoutTask(text);
					handleTask(messageTask, messageWithoutTask);
					SendRpcResponse(text);
				}
				else if (message.Contains(MessageCodeUtil.GetCode(MessageCodes.Response)))
				{
					mls.LogMessage((object)"got the response that the other clients recieved this message");
				}
			}
		}

		public static void SendRpcResponse(string message)
		{
			RpcMessage message2 = new RpcMessage(message, (int)StartOfRound.Instance.localPlayerController.playerClientId, MessageCodes.Response);
			SendRpcMessage(message2);
		}

		private static void handleTask(MessageTasks task, string message)
		{
			switch (task)
			{
			case MessageTasks.StartedSeeking:
				CompleteRecievedTasks.SeekingStarted(message);
				break;
			case MessageTasks.MakePlayerWhistle:
				CompleteRecievedTasks.MakePlayerWhistle(message);
				break;
			case MessageTasks.ErrorNoTask:
				mls.LogError((object)"got an error task");
				break;
			}
		}
	}
}