using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using HideAndSeekMod; using Hide_and_PEAK; using Hide_and_PEAK.Configuration; using Hide_and_PEAK.Patches; using Hide_and_PEAK.UI; using Hide_and_PEAK.Voice; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Networking; 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: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("hide_and_peak")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.3.3.0")] [assembly: AssemblyInformationalVersion("1.3.3+9003cd69e249093bd48b3125ac88077cdb9b4d83")] [assembly: AssemblyProduct("hide_and_peak")] [assembly: AssemblyTitle("hide_and_peak")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace HideAndSeekMod { public class HideAndSeekManager : MonoBehaviourPunCallbacks { public static HideAndSeekManager Instance; private readonly HashSet _processingCaught = new HashSet(); private bool _gameEndSequenceActive = false; private Coroutine _endGameCoroutine; public PhotonView View; public float HiderGracePeriod = Plugin.ConfigurationHandler.ConfigHiderGracePeriod.Value; public bool IsGameActive = false; public bool IsHider { get { object value; return ((Dictionary)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"Team", out value) && (Team)value == Team.Hider; } } public bool IsSeeker { get { object value; return ((Dictionary)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"Team", out value) && (Team)value == Team.Seeker; } } private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; View = ((Component)((Component)this).transform).GetComponent(); if ((Object)(object)View == (Object)null) { Plugin.Log.LogError((object)"No PhotonView attached!"); } Plugin.Log.LogInfo((object)$"PhotonView ID: {View.ViewID}, IsMine: {View.IsMine}, Owner: {View.Owner}"); Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } else { Plugin.Log.LogWarning((object)"[HideAndSeekManager] Instance already exists, destroying old one."); Object.Destroy((Object)(object)Instance); Instance = this; } } private void Start() { CheckIfInGame(); } private void CheckIfInGame() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Checking if in game..."); if (((Dictionary)(object)PhotonNetwork.MasterClient.CustomProperties).TryGetValue((object)"IsInGame", out object value) && (bool)value) { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Found game: Starting game..."); RejoinGame(); } } [PunRPC] public void RPC_StartGame() { StartGame(); } [PunRPC] public void RPC_RequestCurrentTimeString(int requesterActorNumber) { if (!((Object)(object)PlayerStats.Instance == (Object)null)) { float currentTime = PlayerStats.Instance._currentTime; Player val = PhotonNetwork.CurrentRoom.Players[requesterActorNumber]; if (val != null) { View.RPC("RPC_ReceiveCurrentTimeString", val, new object[1] { currentTime }); Plugin.Log.LogInfo((object)("[RPC_RequestCurrentTimeString] Sent _currentTimeString to " + val.NickName)); } } } [PunRPC] public void RPC_ReceiveCurrentTimeString(float currentTime) { if ((Object)(object)PlayerStats.Instance != (Object)null) { PlayerStats.Instance.SetCurrentTimeFromHost(currentTime); Plugin.Log.LogInfo((object)$"[RPC_ReceiveCurrentTimeString] Updated _currentTime: {currentTime}"); } } public void RejoinGame() { ((Dictionary)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"Team", out object value); Team team = (Team)value; ((Component)this).gameObject.AddComponent(); Plugin.Log.LogInfo((object)"InitiatingUI"); DeathLog.InitiateDeathLog(); IsGameActive = true; View.RPC("RPC_RequestCurrentTimeString", PhotonNetwork.MasterClient, new object[1] { PhotonNetwork.LocalPlayer.ActorNumber }); Plugin.Log.LogInfo((object)"[RequestCurrentTimeString] Requested _currentTimeString from host"); } public void StartGame() { ((Dictionary)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"Team", out object value); Team team = (Team)value; ((Component)this).gameObject.AddComponent(); Plugin.Log.LogInfo((object)"InitiatingUI"); DeathLog.InitiateDeathLog(); PlayerStats.InitiatePlayerStats(); IsGameActive = true; if (IsHost()) { View.RPC("RPC_SetHiderGracePeriod", (RpcTarget)1, new object[1] { HiderGracePeriod }); Plugin.Log.LogInfo((object)$"[HideAndSeekManager] Broadcasting HiderGracePeriod ({HiderGracePeriod}) to clients"); View.RPC("RPC_SetSoundIntervals", (RpcTarget)1, new object[2] { SoundPlayer.Instance?.nextSoundTime ?? ((float)Plugin.ConfigurationHandler.ConfigTauntStartTime.Value), SoundPlayer.Instance?.soundInterval ?? ((float)Plugin.ConfigurationHandler.ConfigTauntIntervalTime.Value) }); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Broadcasting SoundPlayer intervals to clients"); } if ((Object)(object)SoundPlayer.Instance != (Object)null) { SoundPlayer.Instance.nextSoundTime = PlayerStats.Instance._currentTime + (float)Plugin.ConfigurationHandler.ConfigTauntStartTime.Value; } } [PunRPC] public void RPC_SetSoundIntervals(float nextSound, float interval) { if ((Object)(object)SoundPlayer.Instance != (Object)null) { SoundPlayer.Instance.nextSoundTime = nextSound; SoundPlayer.Instance.soundInterval = interval; Plugin.Log.LogInfo((object)$"[HideAndSeekManager] Sound intervals synced from host: nextSound={nextSound}, interval={interval}"); } } [PunRPC] public void RPC_SetHiderGracePeriod(float gracePeriod) { HiderGracePeriod = gracePeriod; Plugin.Log.LogInfo((object)$"[HideAndSeekManager] HiderGracePeriod set to {gracePeriod} by host."); } [PunRPC] public void RPC_SetFrozenState(int viewId, bool isFrozen, float frozenHeight, float frozenStamina) { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) PhotonView val = PhotonView.Find(viewId); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)$"[FreezeSync] Could not find PhotonView for {viewId}"); return; } Character component = ((Component)val).GetComponent(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogWarning((object)$"[FreezeSync] No Character component on PhotonView {viewId}"); return; } if (!isFrozen) { Plugin.Log.LogInfo((object)("[FreezeSync] Unfreezing " + component.characterName)); return; } Bodypart bodypart = component.GetBodypart((BodypartType)2); if ((Object)(object)((bodypart != null) ? bodypart.Rig : null) != (Object)null) { Rigidbody rig = bodypart.Rig; Vector3 position = bodypart.Rig.position; position.y = frozenHeight; rig.position = position; bodypart.Rig.linearVelocity = Vector3.zero; bodypart.Rig.angularVelocity = Vector3.zero; } component.data.currentStamina = frozenStamina; component.input.movementInput = Vector2.zero; component.input.jumpIsPressed = false; component.input.crouchIsPressed = false; Plugin.Log.LogInfo((object)$"[FreezeSync] Applied freeze to {component.characterName}, height={frozenHeight}"); } public void SyncFreezeState(Character character, bool isFrozen, float frozenHeight, float frozenStamina) { if (!((Object)(object)character?.refs?.view == (Object)null)) { View.RPC("RPC_SetFrozenState", (RpcTarget)1, new object[4] { character.refs.view.ViewID, isFrozen, frozenHeight, frozenStamina }); } } [PunRPC] public void RPC_RequestCatch(int seekerViewId, int hiderViewId) { if (IsHost()) { Character val = Character.AllCharacters.Find((Character c) => c.refs.view.ViewID == seekerViewId); Character val2 = Character.AllCharacters.Find((Character c) => c.refs.view.ViewID == hiderViewId); if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { Plugin.Log.LogInfo((object)("[HideAndSeekPlayer] Host processing catch: " + val.characterName + " -> " + val2.characterName)); CatchHider(val, val2); } } } public void CatchHider(Character seekerCharacter, Character hiderCharacter) { //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Expected O, but got Unknown //IL_0197: Expected O, but got Unknown //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_01da: Expected O, but got Unknown if (!IsHost()) { return; } if (PlayerStats.Instance._currentTime < HiderGracePeriod) { Plugin.Log.LogInfo((object)"[HideAndSeekPlayer] Catch ignored, hider grace period."); return; } Player controller = hiderCharacter.view.Controller; Player controller2 = seekerCharacter.view.Controller; ((Dictionary)(object)controller.CustomProperties).TryGetValue((object)"Team", out object value); ((Dictionary)(object)controller2.CustomProperties).TryGetValue((object)"Team", out object value2); if ((Team)value != Team.Hider || (Team)value2 != Team.Seeker) { return; } int viewID = hiderCharacter.refs.view.ViewID; if (!_processingCaught.Contains(viewID)) { _processingCaught.Add(viewID); Plugin.Log.LogInfo((object)"Team swap 1"); View.RPC("RPC_ResetStamina", controller, Array.Empty()); View.RPC("RPC_AddDeath", (RpcTarget)0, new object[2] { seekerCharacter.refs.view.ViewID, hiderCharacter.refs.view.ViewID }); Plugin.Log.LogInfo((object)"Team swap 2"); Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"Team", (object)Team.Seeker); ((Dictionary)val).Add((object)"OriginalRole", (object)Team.Hider); ((Dictionary)val).Add((object)"Caught_Time", (object)PlayerStats.Instance._currentTimeString); Hashtable val2 = val; controller.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); ((Dictionary)(object)controller2.CustomProperties).TryGetValue((object)"Catches", out object value3); int num = (int)value3 + 1; Hashtable val3 = new Hashtable(); ((Dictionary)val3).Add((object)"Catches", (object)num); Hashtable val4 = val3; controller2.SetCustomProperties(val4, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)$"{controller2.NickName} now has {num} catches."); ((MonoBehaviour)this).StartCoroutine(ClearProcessingAfterDelay(viewID, 1f)); if (IsHost()) { ((MonoBehaviour)this).StartCoroutine(CheckGameEndAfterDelay(0.5f)); } } } [PunRPC] public void RPC_ResetStamina() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Resetting local character stamina"); Character localCharacter = Character.localCharacter; if (localCharacter != null) { localCharacter.AddStamina(1f); } Character localCharacter2 = Character.localCharacter; if (localCharacter2 != null) { localCharacter2.refs.afflictions.ClearAllStatus(false); } } private IEnumerator ClearProcessingAfterDelay(int viewId, float delay) { yield return (object)new WaitForSeconds(delay); _processingCaught.Remove(viewId); } public IEnumerator CheckGameEndAfterDelay(float delay) { yield return (object)new WaitForSeconds(delay); CheckForGameEnd(); } private void CheckForGameEnd() { if (!IsHost() || !IsGameActive || _gameEndSequenceActive) { return; } int num = 0; int num2 = 0; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { if (((Dictionary)(object)val.CustomProperties).TryGetValue((object)"OriginalRole", out object value) && (Team)value == Team.Hider) { num++; if (((Dictionary)(object)val.CustomProperties).TryGetValue((object)"Team", out object value2) && (Team)value2 == Team.Hider) { num2++; } } } Plugin.Log.LogInfo((object)$"[GameEnd Check] Original Hiders: {num}, Remaining: {num2}"); if (num > 0 && num2 == 0) { Plugin.Log.LogInfo((object)"[GameEnd] All hiders caught! Ending game..."); _gameEndSequenceActive = true; View.RPC("RPC_ShowEndGameScoreboard", (RpcTarget)0, Array.Empty()); View.RPC("RPC_ResetInfiniteStamina", (RpcTarget)0, Array.Empty()); } } [PunRPC] private void RPC_ResetInfiniteStamina() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Resetting local character infinite stamina"); Character.localCharacter.infiniteStam = false; } private void SaveCurrentMatch() { MatchResult matchResult = new MatchResult { Date = DateTime.Now.ToString("yyyy-MM-dd HH:mm"), Duration = (((Object)(object)PlayerStats.Instance != (Object)null) ? PlayerStats.Instance._currentTime : 0f) }; Player[] playerList = PhotonNetwork.PlayerList; foreach (Player val in playerList) { matchResult.PlayerResults.Add(new PlayerResult { PlayerName = val.NickName, Team = ((!((Dictionary)(object)val.CustomProperties).TryGetValue((object)"Team", out object value)) ? Team.Seeker : ((Team)value)), OriginalRole = ((!((Dictionary)(object)val.CustomProperties).TryGetValue((object)"OriginalRole", out object value2)) ? Team.Seeker : ((Team)value2)), CaughtTime = (((Dictionary)(object)val.CustomProperties).TryGetValue((object)"Caught_Time", out object value3) ? value3.ToString() : ""), Catches = (((Dictionary)(object)val.CustomProperties).TryGetValue((object)"Catches", out object value4) ? ((int)value4) : 0) }); } MatchHistoryManager.SaveMatch(matchResult); } [PunRPC] public void RPC_ShowEndGameScoreboard() { Plugin.Log.LogInfo((object)"[GameEnd] Received RPC: ShowEndGameScoreboard"); ShowEndGameScoreboard(); } private void ShowEndGameScoreboard() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_006a: Expected O, but got Unknown if ((Object)(object)ScoreBoardUI.Instance != (Object)null) { ScoreBoardUI.Instance.isGameOverMode = true; ScoreBoardUI.Instance.gameOverCountdown = 30f; ScoreBoardUI.Instance.SetScoreBoardUI(visible: true); ScoreBoardUI.Instance.IsOpenMode = true; Plugin.Log.LogInfo((object)"[GameEnd] Scoreboard opened"); Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"IsInGame", (object)false); Hashtable val2 = val; PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } SaveCurrentMatch(); if (_endGameCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_endGameCoroutine); } _endGameCoroutine = ((MonoBehaviour)this).StartCoroutine(EndGameTimer()); } private IEnumerator EndGameTimer() { Plugin.Log.LogInfo((object)"[GameEnd] Starting 30-second countdown..."); float elapsed = 0f; float duration = 30f; while (elapsed < duration) { if ((Object)(object)ScoreBoardUI.Instance != (Object)null) { ScoreBoardUI.Instance.gameOverCountdown = duration - elapsed; } elapsed += Time.deltaTime; yield return null; } if (elapsed >= duration) { Plugin.Log.LogInfo((object)"[GameEnd] 30 seconds elapsed, restarting game"); ScoreBoardUI.Instance.IsOpenMode = false; } if ((Object)(object)ScoreBoardUI.Instance != (Object)null && ScoreBoardUI.Instance.showUI) { ScoreBoardUI.Instance.isGameOverMode = false; ScoreBoardUI.Instance.gameOverCountdown = 0f; ScoreBoardUI.Instance.SetScoreBoardUI(visible: false); } if (IsHost()) { RestartGameForAll(); _gameEndSequenceActive = false; } _endGameCoroutine = null; } [PunRPC] public void RPC_AddDeath(int seekerViewId, int hiderViewId) { PhotonView val = PhotonView.Find(seekerViewId); PhotonView val2 = PhotonView.Find(hiderViewId); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Plugin.Log.LogError((object)$"[DeathLog] Could not resolve PhotonViews! seeker={seekerViewId}, hider={hiderViewId}"); return; } if ((Object)(object)DeathLog.Instance == (Object)null) { DeathLog.InitiateDeathLog(); } DeathLog.Instance?.AddDeath(val, val2); } private void Update() { if (!PhotonNetwork.InRoom) { return; } if (IsHost() && Plugin.ConfigurationHandler.TeamSelectionUIAction.WasPressedThisFrame()) { View.RPC("RPC_SetTeamSelectionUI", (RpcTarget)0, new object[1] { !TeamSelectionUI.Instance.showUI }); } if (Plugin.ConfigurationHandler.ScoreBoardAction.IsPressed()) { if (!ScoreBoardUI.Instance.showUI) { ScoreBoardUI.Instance.SetScoreBoardUI(visible: true); } else if (ScoreBoardUI.Instance.IsOpenMode) { ScoreBoardUI.Instance.IsOpenMode = false; ScoreBoardUI.Instance.SetScoreBoardUI(visible: false); } } else if (!ScoreBoardUI.Instance.IsOpenMode && ScoreBoardUI.Instance.showUI) { ScoreBoardUI.Instance.SetScoreBoardUI(visible: false); } } [PunRPC] public void RPC_SetTeamSelectionUI(bool visible) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown Plugin.Log.LogInfo((object)$"Received RPC: SetTeamSelectionUI -> {visible}"); if ((Object)(object)TeamSelectionUI.Instance == (Object)null) { Plugin.Log.LogInfo((object)"TeamSelectionUI.Instance was null. Creating UI GameObject on demand."); GameObject val = new GameObject("Team Selection UI"); val.AddComponent(); } TeamSelectionUI.Instance.SetTeamSelectionUI(visible); } [PunRPC] public void RPC_TestDeath() { try { if ((Object)(object)DeathLog.Instance == (Object)null) { DeathLog.InitiateDeathLog(); } Character localCharacter = Character.localCharacter; PhotonView localPV = ((!((Object)(object)localCharacter != (Object)null)) ? null : localCharacter.refs?.view); if ((Object)(object)localPV == (Object)null) { Plugin.Log.LogError((object)"[DeathLog Test] Local PhotonView not found."); return; } PhotonView hider = (from c in Character.AllCharacters where (Object)(object)c != (Object)null && (Object)(object)c.refs?.view != (Object)null && c.refs.view.ViewID != localPV.ViewID select c.refs.view).FirstOrDefault() ?? localPV; DeathLog.Instance?.AddDeath(localPV, hider); } catch (Exception arg) { Plugin.Log.LogError((object)$"[DeathLog Test] Exception: {arg}"); } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } public bool IsHost() { return PhotonNetwork.IsMasterClient; } public void DestroyGame() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00b6: Expected O, but got Unknown Plugin.Log.LogInfo((object)"[HideAndSeekManager] Destroying game state..."); IsGameActive = false; _processingCaught.Clear(); HideAndSeekPlayer component = ((Component)this).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Removed HideAndSeekPlayer component"); } if (PhotonNetwork.LocalPlayer != null) { Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"Team", (object)null); ((Dictionary)val).Add((object)"Ready", (object)false); ((Dictionary)val).Add((object)"OriginalRole", (object)null); ((Dictionary)val).Add((object)"Caught_Time", (object)""); ((Dictionary)val).Add((object)"Catches", (object)0); Hashtable val2 = val; PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Reset local player properties"); } if ((Object)(object)PlayerStats.Instance != (Object)null) { PlayerStats.Instance.ResetStats(); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Reset PlayerStats"); } if ((Object)(object)DeathLog.Instance != (Object)null) { Object.Destroy((Object)(object)((Component)DeathLog.Instance).gameObject); DeathLog.Instance = null; Plugin.Log.LogInfo((object)"[HideAndSeekManager] Cleared DeathLog"); } if ((Object)(object)TeamSelectionUI.Instance != (Object)null && TeamSelectionUI.Instance.showUI) { TeamSelectionUI.Instance.SetTeamSelectionUI(visible: false); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Closed TeamSelectionUI"); } if ((Object)(object)ScoreBoardUI.Instance != (Object)null && ScoreBoardUI.Instance.showUI) { ScoreBoardUI.Instance.SetScoreBoardUI(visible: false); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Closed ScoreBoardUI"); } Plugin.Log.LogInfo((object)"[HideAndSeekManager] Game destroyed successfully"); } public void InitializeNewGame() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Initializing new game..."); Plugin.ConfigurationHandler?.PushNameColourToPhoton(); if ((Object)(object)TeamSelectionUI.Instance != (Object)null) { TeamSelectionUI.Instance.SetTeamSelectionUI(visible: true); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Opened TeamSelectionUI for new game"); } else { Plugin.Log.LogWarning((object)"[HideAndSeekManager] TeamSelectionUI.Instance is null, cannot open"); } Plugin.Log.LogInfo((object)"[HideAndSeekManager] New game initialized"); } public void RestartGame() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Restarting game..."); DestroyGame(); InitializeNewGame(); Plugin.Log.LogInfo((object)"[HideAndSeekManager] Game restarted successfully"); } [PunRPC] public void RPC_DestroyGame() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Received RPC: DestroyGame"); DestroyGame(); } [PunRPC] public void RPC_InitializeNewGame() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Received RPC: InitializeNewGame"); InitializeNewGame(); } [PunRPC] public void RPC_RestartGame() { Plugin.Log.LogInfo((object)"[HideAndSeekManager] Received RPC: RestartGame"); RestartGame(); } public void DestroyGameForAll() { if (!IsHost()) { Plugin.Log.LogWarning((object)"[HideAndSeekManager] Only host can destroy game for all"); return; } Plugin.Log.LogInfo((object)"[HideAndSeekManager] Broadcasting destroy to all clients"); View.RPC("RPC_DestroyGame", (RpcTarget)0, Array.Empty()); } public void InitializeNewGameForAll() { if (!IsHost()) { Plugin.Log.LogWarning((object)"[HideAndSeekManager] Only host can initialize new game for all"); return; } Plugin.Log.LogInfo((object)"[HideAndSeekManager] Broadcasting new game initialization to all clients"); View.RPC("RPC_InitializeNewGame", (RpcTarget)0, Array.Empty()); } public void RestartGameForAll() { if (!IsHost()) { Plugin.Log.LogWarning((object)"[HideAndSeekManager] Only host can restart game for all"); return; } Plugin.Log.LogInfo((object)"[HideAndSeekManager] Broadcasting game restart to all clients"); View.RPC("RPC_RestartGame", (RpcTarget)0, Array.Empty()); } } } namespace Hide_and_PEAK { public class HideAndSeekPlayer : MonoBehaviour { private Vector3 _lastPosition = Vector3.zero; private Camera MainCamera = Camera.main; public bool IsHider { get { object value; return ((Dictionary)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"Team", out value) && (Team)value == Team.Hider; } } public bool IsSeeker { get { object value; return ((Dictionary)(object)PhotonNetwork.LocalPlayer.CustomProperties).TryGetValue((object)"Team", out value) && (Team)value == Team.Seeker; } } private void Start() { GlobalEvents.OnCharacterDied = (Action)Delegate.Combine(GlobalEvents.OnCharacterDied, new Action(OnCharacterDied)); } private void OnDestroy() { GlobalEvents.OnCharacterDied = (Action)Delegate.Remove(GlobalEvents.OnCharacterDied, new Action(OnCharacterDied)); } private void OnCharacterDied(Character character) { //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_012d: Expected O, but got Unknown if ((Object)(object)Character.localCharacter == (Object)null || Character.localCharacter.refs == null || !HideAndSeekManager.Instance.IsGameActive) { return; } Plugin.Log.LogInfo((object)("Death event for " + ((Object)character).name)); if (character.characterName.Equals(Character.localCharacter.characterName) && (Character.localCharacter.data.dead || Character.localCharacter.refs.customization.isDead)) { Plugin.Log.LogInfo((object)"[HideAndSeekPlayer] Local Character is dead :("); DeathLog.Instance.AddWorldDeath(Character.localCharacter.view); if (IsHider) { Plugin.Log.LogInfo((object)"[HideAndSeekPlayer] Local Character was a hider, reviving as seeker..."); Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"Team", (object)Team.Seeker); ((Dictionary)val).Add((object)"OriginalRole", (object)Team.Hider); ((Dictionary)val).Add((object)"Caught_Time", (object)PlayerStats.Instance._currentTimeString); ((Dictionary)val).Add((object)"Catches", (object)0); Hashtable val2 = val; PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); Character.localCharacter.AddStamina(100f); Character.localCharacter.AddIllegalStatus("BLIND", 10f); Plugin.Log.LogInfo((object)"[HideAndSeekPlayer] Switched local player to seeker, will revive them and apply blind!"); } ((MonoBehaviourPun)Character.localCharacter).photonView.RPC("RPCA_ReviveAtPosition", (RpcTarget)0, new object[3] { Plugin.Instance.lastDeathPosition, false, 0 }); } if (HideAndSeekManager.Instance.IsHost()) { ((MonoBehaviour)this).StartCoroutine(HideAndSeekManager.Instance.CheckGameEndAfterDelay(0.5f)); } } private void Update() { if (!((Object)(object)Character.localCharacter == (Object)null) && Character.localCharacter.refs != null && HideAndSeekManager.Instance.IsGameActive) { Character.localCharacter.refs.afflictions.hungerPerSecond = 0f; if (IsSeeker) { Character.localCharacter.infiniteStam = true; } if (IsSeeker && (Object)(object)Character.localCharacter.input != (Object)null && Character.localCharacter.input.useSecondaryIsPressed) { TryRaycastConeCatch(1.4f, 15f); } else if (IsSeeker) { TryRaycastConeCatch(0.9f, 35f); } } } private void TryRaycastConeCatch(float distance, float spreadAngle) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MainCamera == (Object)null) { MainCamera = Camera.main; if ((Object)(object)MainCamera == (Object)null) { Plugin.Log.LogError((object)"[HideAndSeekPlayer] No main camera found for raycast."); return; } } if (!Object.op_Implicit((Object)(object)HideAndSeekManager.Instance) || !HideAndSeekManager.Instance.IsGameActive) { return; } Vector3 position = ((Component)MainCamera).transform.position; Vector3 forward = ((Component)MainCamera).transform.forward; Vector3[] array = (Vector3[])(object)new Vector3[5] { forward, Quaternion.Euler(spreadAngle, 0f, 0f) * forward, Quaternion.Euler(0f - spreadAngle, 0f, 0f) * forward, Quaternion.Euler(0f, spreadAngle, 0f) * forward, Quaternion.Euler(0f, 0f - spreadAngle, 0f) * forward }; RaycastHit val2 = default(RaycastHit); foreach (Vector3 val in array) { if (Physics.Raycast(position, val, ref val2, distance)) { Character componentInParent = ((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && (!((Object)(object)Character.localCharacter != (Object)null) || !((Object)(object)componentInParent == (Object)(object)Character.localCharacter))) { Plugin.Log.LogInfo((object)("[HideAndSeekPlayer] Cone ray hit: " + componentInParent.characterName)); int viewID = Character.localCharacter.refs.view.ViewID; int viewID2 = componentInParent.refs.view.ViewID; HideAndSeekManager.Instance.View.RPC("RPC_RequestCatch", (RpcTarget)2, new object[2] { viewID, viewID2 }); break; } } } } } public static class MatchHistoryManager { [Serializable] private class MatchListWrapper { public List Matches; } private static readonly string savePath = Path.Combine(Application.persistentDataPath, "match_history.json"); private static List _matches = new List(); public static List Matches { get { if (_matches == null) { LoadMatches(); } return _matches; } } public static void SaveMatch(MatchResult match) { _matches.Add(match); string contents = JsonUtility.ToJson((object)new MatchListWrapper { Matches = _matches }, true); File.WriteAllText(savePath, contents); Debug.Log((object)("[MatchHistory] Saved match to " + savePath)); } private static void LoadMatches() { if (File.Exists(savePath)) { string text = File.ReadAllText(savePath); MatchListWrapper matchListWrapper = JsonUtility.FromJson(text); _matches = matchListWrapper.Matches ?? new List(); } else { _matches = new List(); } } } [Serializable] public class MatchResult { public string Date; public float Duration; public List PlayerResults = new List(); } [Serializable] public class PlayerResult { public string PlayerName; public Team Team; public Team OriginalRole; public string CaughtTime; public int Catches; } [BepInPlugin("hide_and_peak", "hide_and_peak", "1.3.3")] public class Plugin : BaseUnityPlugin { private Harmony _harmony; public static ConfigurationHandler ConfigurationHandler; private ModConfigurationUI _ui; private SoundPlayer _soundPlayer; public bool _isInitialised = false; private bool _pushedNameColor = false; private GameObject _teamSelectionUI; private GameObject _scoreBoardUI; private HideAndSeekManager _manager; private RichPresenceService _richPresenceService = null; public static Plugin Instance; public Vector3 lastDeathPosition = new Vector3(0f, 0f, 0f); private RichPresenceState lastState = (RichPresenceState)0; public const string Id = "hide_and_peak"; internal static ManualLogSource Log { get; private set; } public static string Name => "hide_and_peak"; public static string Version => "1.3.3"; private void Awake() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)("Plugin " + Name + " v" + Version + " loaded!")); _harmony = new Harmony("hide_and_peak"); _harmony.PatchAll(typeof(BodypartOnCollisionEnterPatch)); _harmony.PatchAll(typeof(VoiceObscuranceFilterPatch)); _harmony.PatchAll(typeof(CharacterMovementUpdatePatch)); _harmony.PatchAll(typeof(RunManagerStartRunPatch)); _harmony.PatchAll(typeof(CharacterRPCADiePatch)); _harmony.PatchAll(typeof(WindChillZoneHandleTimePatch)); ConfigurationHandler = new ConfigurationHandler(((BaseUnityPlugin)this).Config); GameObject val = new GameObject("HideAndPEAKConfigUI"); Object.DontDestroyOnLoad((Object)(object)val); _ui = val.AddComponent(); _ui.Init(new List