using System.Collections.Generic; using BlockSpace.Voxels; using Photon.Pun; using Photon.Realtime; using Photon.VR; using UnityEngine; [DisallowMultipleComponent] public sealed class NodePlayerFreezeRpc : MonoBehaviourPun { private readonly Dictionary cachedStates = new Dictionary(); private float unfreezeAt = float.NegativeInfinity; private bool frozen; public static NodePlayerFreezeRpc Ensure() { NodePlayerFreezeRpc nodePlayerFreezeRpc = Object.FindAnyObjectByType(); if (nodePlayerFreezeRpc != null) { return nodePlayerFreezeRpc; } GameObject gameObject = ((NodeGraphManager.Instance != null) ? NodeGraphManager.Instance.gameObject : null); if (gameObject == null || gameObject.GetComponent() == null) { VoxelGroupPhotonSync voxelGroupPhotonSync = Object.FindAnyObjectByType(); if (voxelGroupPhotonSync != null) { gameObject = voxelGroupPhotonSync.gameObject; } } if (gameObject == null) { gameObject = ((PhotonVRManager.Manager != null) ? PhotonVRManager.Manager.gameObject : null); } if (gameObject == null) { return null; } return gameObject.GetComponent() ?? gameObject.AddComponent(); } private void Update() { if (frozen && unfreezeAt > 0f && Time.unscaledTime >= unfreezeAt) { UnfreezeLocal(); } } public bool TryFreezePlayer(int playerId, float seconds) { if (playerId <= 0) { return false; } if (NodePlayerUtility.IsLocalPlayerId(playerId)) { FreezeLocal(seconds); return true; } if (!PhotonNetwork.InRoom || base.photonView == null || base.photonView.ViewID == 0) { return false; } Player player = PhotonNetwork.CurrentRoom?.GetPlayer(playerId); if (player == null) { return false; } base.photonView.RPC("RPC_FreezeLocal", player, seconds); return true; } public bool TryUnfreezePlayer(int playerId) { if (playerId <= 0) { return false; } if (NodePlayerUtility.IsLocalPlayerId(playerId)) { UnfreezeLocal(); return true; } if (!PhotonNetwork.InRoom || base.photonView == null || base.photonView.ViewID == 0) { return false; } Player player = PhotonNetwork.CurrentRoom?.GetPlayer(playerId); if (player == null) { return false; } base.photonView.RPC("RPC_UnfreezeLocal", player); return true; } private void FreezeLocal(float seconds) { VoxelGroupManager instance = VoxelGroupManager.Instance; if (instance != null && instance.CreatorMode) { return; } if (!frozen) { cachedStates.Clear(); Behaviour[] array = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); foreach (Behaviour behaviour in array) { if (!(behaviour == null) && !(behaviour == this) && IsMovementBehaviour(behaviour)) { cachedStates[behaviour] = behaviour.enabled; behaviour.enabled = false; } } } frozen = true; unfreezeAt = ((seconds > 0f) ? (Time.unscaledTime + seconds) : (-1f)); } private void UnfreezeLocal() { if (!frozen) { return; } foreach (KeyValuePair cachedState in cachedStates) { if (cachedState.Key != null) { cachedState.Key.enabled = cachedState.Value; } } cachedStates.Clear(); frozen = false; unfreezeAt = float.NegativeInfinity; } private static bool IsMovementBehaviour(Behaviour behaviour) { if (behaviour == null) { return false; } string text = behaviour.GetType().Name; if (!((behaviour.GetType().FullName ?? string.Empty) == "GorillaLocomotion.Player") && !(text == "DesktopRigController") && !(text == "CreatorFlightController") && !text.Contains("LocomotionProvider") && !text.Contains("MoveProvider") && !text.Contains("TurnProvider") && !text.Contains("JumpProvider") && !text.Contains("TeleportationProvider") && !text.Contains("ClimbProvider") && !text.Contains("ContinuousMove") && !text.Contains("DynamicMove") && !text.Contains("SnapTurn")) { return text.Contains("SmoothTurn"); } return true; } [PunRPC] private void RPC_FreezeLocal(float seconds) { FreezeLocal(seconds); } [PunRPC] private void RPC_UnfreezeLocal() { UnfreezeLocal(); } }