private void PacketReceived(NetIncomingMessage msg) { if (msg == null) { if (_currentScene == "GameCore" && loaded) { PropertyInfo property = typeof(StandardLevelGameplayManager).GetProperty("gameState"); property.DeclaringType.GetProperty("gameState"); property.GetSetMethod(true).Invoke(_gameManager, new object[] { StandardLevelGameplayManager.GameState.Failed }); } return; } switch ((CommandType)msg.ReadByte()) { case CommandType.UpdatePlayerInfo: { float currentTime = msg.ReadFloat(); float totalTime = msg.ReadFloat(); int playersCount = msg.ReadInt32(); List <PlayerInfo> playerInfos = new List <PlayerInfo>(); try { for (int j = 0; j < playersCount; j++) { playerInfos.Add(new PlayerInfo(msg)); } } catch (Exception e) { #if DEBUG Misc.Logger.Exception($"Unable to parse PlayerInfo! Player count={playersCount} Message size={msg.LengthBytes} Excpetion: {e}"); #endif return; } playerInfos = playerInfos.Where(x => (x.playerState == PlayerState.Game && _currentScene == "GameCore") || (x.playerState == PlayerState.Room && _currentScene == "MenuCore") || (x.playerState == PlayerState.DownloadingSongs && _currentScene == "MenuCore")).OrderByDescending(x => x.playerId).ToList(); int localPlayerIndex = playerInfos.FindIndexInList(Client.Instance.playerInfo); try { int index = 0; OnlinePlayerController player = null; foreach (PlayerInfo info in playerInfos) { try { player = _players.FirstOrDefault(x => x != null && x.PlayerInfo.Equals(info)); if (player != null) { player.PlayerInfo = info; player.avatarOffset = (index - localPlayerIndex) * (_currentScene == "GameCore" ? 5f : 0f); player.SetAvatarState(((ShowAvatarsInGame() && !Config.Instance.SpectatorMode && loaded) || ShowAvatarsInRoom()) && !Client.Instance.InRadioMode); } else { player = new GameObject("OnlinePlayerController").AddComponent <OnlinePlayerController>(); player.PlayerInfo = info; player.avatarOffset = (index - localPlayerIndex) * (_currentScene == "GameCore" ? 5f : 0f); player.SetAvatarState(((ShowAvatarsInGame() && !Config.Instance.SpectatorMode && loaded) || ShowAvatarsInRoom()) && !Client.Instance.InRadioMode); _players.Add(player); } index++; } catch (Exception e) { Console.WriteLine($"PlayerController exception: {e}"); } } if (_players.Count > playerInfos.Count) { foreach (OnlinePlayerController controller in _players.Where(x => !playerInfos.Any(y => y.Equals(x.PlayerInfo)))) { if (controller != null && !controller.destroyed) { Destroy(controller.gameObject); } } _players.RemoveAll(x => x == null || x.destroyed); } } catch (Exception e) { Console.WriteLine($"PlayerControllers exception: {e}"); } if (_currentScene == "GameCore" && loaded) { playerInfos = playerInfos.OrderByDescending(x => x.playerScore).ToList(); localPlayerIndex = playerInfos.FindIndexInList(Client.Instance.playerInfo); if (_scoreDisplays.Count < 5) { _scoreScreen = new GameObject("ScoreScreen"); _scoreScreen.transform.position = new Vector3(0f, 4f, 12f); _scoreScreen.transform.rotation = Quaternion.Euler(0f, 0f, 0f); _scoreDisplays.Clear(); for (int i = 0; i < 5; i++) { PlayerInfoDisplay buffer = new GameObject("ScoreDisplay " + i).AddComponent <PlayerInfoDisplay>(); buffer.transform.SetParent(_scoreScreen.transform); buffer.transform.localPosition = new Vector3(0f, 2.5f - i, 0); _scoreDisplays.Add(buffer); } } if (playerInfos.Count <= 5) { for (int i = 0; i < playerInfos.Count; i++) { _scoreDisplays[i].UpdatePlayerInfo(playerInfos[i], playerInfos.FindIndexInList(playerInfos[i])); } for (int i = playerInfos.Count; i < _scoreDisplays.Count; i++) { _scoreDisplays[i].UpdatePlayerInfo(null, 0); } } else { if (localPlayerIndex < 3) { for (int i = 0; i < 5; i++) { _scoreDisplays[i].UpdatePlayerInfo(playerInfos[i], playerInfos.FindIndexInList(playerInfos[i])); } } else if (localPlayerIndex > playerInfos.Count - 3) { for (int i = playerInfos.Count - 5; i < playerInfos.Count; i++) { _scoreDisplays[i - (playerInfos.Count - 5)].UpdatePlayerInfo(playerInfos[i], playerInfos.FindIndexInList(playerInfos[i])); } } else { for (int i = localPlayerIndex - 2; i < localPlayerIndex + 3; i++) { _scoreDisplays[i - (localPlayerIndex - 2)].UpdatePlayerInfo(playerInfos[i], playerInfos.FindIndexInList(playerInfos[i])); } } } } } break; case CommandType.UpdateVoIPData: { if (!Config.Instance.EnableVoiceChat) { return; } int playersCount = msg.ReadInt32(); for (int j = 0; j < playersCount; j++) { try { VoipFragment data = new VoipFragment(msg); #if DEBUG if (data.data != null && data.data.Length > 0) #else if (data.data != null && data.data.Length > 0 && data.playerId != Client.Instance.playerInfo.playerId) #endif { if (speexDec == null || speexDec.mode != data.mode) { speexDec = SpeexCodex.Create(data.mode); } _players.FirstOrDefault(x => x.PlayerInfo.playerId == data.playerId)?.PlayVoIPFragment(speexDec.Decode(data.data), data.index); } } catch (Exception e) { #if DEBUG Misc.Logger.Exception($"Unable to parse VoIP fragment! Excpetion: {e}"); #endif } } } break; case CommandType.SetGameState: { if (_currentScene == "GameCore" && loaded) { PropertyInfo property = typeof(StandardLevelGameplayManager).GetProperty("gameState"); property.DeclaringType.GetProperty("gameState"); property.GetSetMethod(true).Invoke(_gameManager, new object[] { (StandardLevelGameplayManager.GameState)msg.ReadByte() }); } } break; case CommandType.DisplayMessage: { _messageDisplayTime = msg.ReadFloat(); _messageDisplayText.fontSize = msg.ReadFloat(); _messageDisplayText.text = msg.ReadString(); if (msg.LengthBits - msg.Position >= 8) { MessagePosition position = (MessagePosition)msg.ReadByte(); switch (position) { default: case MessagePosition.Top: _messageDisplayText.transform.position = new Vector3(0f, 3.75f, 3.75f); _messageDisplayText.transform.rotation = Quaternion.Euler(-30f, 0f, 0f); break; case MessagePosition.Bottom: _messageDisplayText.transform.position = new Vector3(0f, 0f, 2.25f); _messageDisplayText.transform.rotation = Quaternion.Euler(30f, 0f, 0f); break; } } }; break; } }
public void Update() { if (Config.Instance.SpectatorMode && _currentScene == "GameCore" && active) { if (spectatedPlayer == null && _leftSaber != null && _rightSaber != null) { spectatedPlayer = new GameObject("SpectatedPlayerController").AddComponent <OnlinePlayerController>(); spectatedPlayer.SetAvatarState(Config.Instance.ShowAvatarsInGame); spectatedPlayer.SetSabers(_leftSaber, _rightSaber); ReplacePlayerController(spectatedPlayer); spectatedPlayer.noInterpolation = true; if (_leftController != null && _rightController != null) { _leftController.owner = spectatedPlayer; _rightController.owner = spectatedPlayer; } } if (Input.GetKeyDown(KeyCode.KeypadMultiply) && spectatedPlayer != null && spectatedPlayer.playerInfo != null) { int index = playerUpdates.Keys.ToList().FindIndexInList(spectatedPlayer.playerInfo.playerId); if (index >= playerUpdates.Count - 1) { index = 0; } spectatedPlayer.playerInfo = playerUpdates[playerUpdates.Keys.ElementAt(index)].playerInfo; Plugin.log.Info("Spectating player: " + spectatedPlayer.playerInfo.playerName); _spectatingText.gameObject.SetActive(true); _spectatingText.text = "Spectating " + spectatedPlayer.playerInfo.playerName; } if (Input.GetKeyDown(KeyCode.KeypadDivide) && spectatedPlayer != null && spectatedPlayer.playerInfo != null) { int index = playerUpdates.Keys.ToList().FindIndexInList(spectatedPlayer.playerInfo.playerId); if (index <= 0) { index = playerUpdates.Count - 1; } spectatedPlayer.playerInfo = playerUpdates[playerUpdates.Keys.ElementAt(index)].playerInfo; Plugin.log.Info("Spectating player: " + spectatedPlayer.playerInfo.playerName); _spectatingText.gameObject.SetActive(true); _spectatingText.text = "Spectating " + spectatedPlayer.playerInfo.playerName; } if (playerUpdates.Count > 0 && spectatedPlayer != null && spectatedPlayer.playerInfo == null) { spectatedPlayer.playerInfo = playerUpdates.FirstOrDefault(x => x.Key != Client.Instance.playerInfo.playerId).Value?.playerInfo; Plugin.log.Info("Set spectated player..."); if (spectatedPlayer.playerInfo != null) { Plugin.log.Info("Spectating player: " + spectatedPlayer.playerInfo.playerName); _spectatingText.gameObject.SetActive(true); _spectatingText.text = "Spectating " + spectatedPlayer.playerInfo.playerName; } } if (spectatedPlayer != null && spectatedPlayer.playerInfo != null) { float currentSongTime = Math.Max(0f, audioTimeSync.songTime); int index = FindClosestIndex(playerUpdates[spectatedPlayer.playerInfo.playerId].updates, currentSongTime); index = Math.Max(index, 0); (float, float)playerProgressMinMax = MinMax(playerUpdates[spectatedPlayer.playerInfo.playerId].updates); PlayerUpdate lerpFrom; PlayerUpdate lerpTo; float lerpProgress; if (playerProgressMinMax.Item2 < currentSongTime + 2f && audioTimeSync.songLength > currentSongTime + 5f && !_paused) { Plugin.log.Info($"Pausing..."); if (playerProgressMinMax.Item2 > 2.5f) { Plugin.log.Info($"Buffering..."); _bufferingText.gameObject.SetActive(true); _bufferingText.alignment = TextAlignmentOptions.Center; } InGameOnlineController.Instance.PauseSong(); _paused = true; Plugin.log.Info($"Paused!"); } if (playerProgressMinMax.Item2 - currentSongTime > 3f && _paused) { _bufferingText.gameObject.SetActive(false); Plugin.log.Info("Resuming song..."); InGameOnlineController.Instance.ResumeSong(); _paused = false; } if (_paused) { return; } if (playerProgressMinMax.Item1 < currentSongTime && playerProgressMinMax.Item2 > currentSongTime) { lerpFrom = playerUpdates[spectatedPlayer.playerInfo.playerId].updates[index]; lerpTo = playerUpdates[spectatedPlayer.playerInfo.playerId].updates[index + 1]; lerpProgress = Remap(currentSongTime, lerpFrom.playerProgress, lerpTo.playerProgress, 0f, 1f); } else { if (audioTimeSync.songLength - currentSongTime > 5f && currentSongTime > 3f) { Plugin.log.Warn($"No data recorded for that point in time!\nStart time: {playerProgressMinMax.Item1}\nStop time: {playerProgressMinMax.Item2}\nCurrent time: {currentSongTime}"); } return; } #if DEBUG && VERBOSE if (index - _prevFrameIndex > 1) { Plugin.log.Warn($"Frame skip!\nPrev index: {_prevFrameIndex}\nNew index: {index}"); } else if (index < _prevFrameIndex) { Plugin.log.Warn($"Going back in time!\nPrev index: {_prevFrameIndex}\nNew index: {index}"); } else if (_prevFrameIndex == index) { if (lerpProgress < _prevFrameLerp) { Plugin.log.Warn($"Going back in time!\nPrev lerp progress: {_prevFrameIndex}\nNew lerp progress: {lerpProgress}"); } else if (_prevFrameLerp == lerpProgress) { Plugin.log.Warn($"Staying in place! Prev lerp progress: {_prevFrameLerp}\nNew lerp progress: {lerpProgress}"); } } _prevFrameIndex = index; _prevFrameLerp = lerpProgress; #endif spectatedPlayer.playerInfo.updateInfo.leftHandPos = Vector3.Lerp(lerpFrom.leftHandPos, lerpTo.leftHandPos, lerpProgress); spectatedPlayer.playerInfo.updateInfo.rightHandPos = Vector3.Lerp(lerpFrom.rightHandPos, lerpTo.rightHandPos, lerpProgress); spectatedPlayer.playerInfo.updateInfo.headPos = Vector3.Lerp(lerpFrom.headPos, lerpTo.headPos, lerpProgress); spectatedPlayer.playerInfo.updateInfo.leftHandRot = Quaternion.Lerp(lerpFrom.leftHandRot, lerpTo.leftHandRot, lerpProgress); spectatedPlayer.playerInfo.updateInfo.rightHandRot = Quaternion.Lerp(lerpFrom.rightHandRot, lerpTo.rightHandRot, lerpProgress); spectatedPlayer.playerInfo.updateInfo.headRot = Quaternion.Lerp(lerpFrom.headRot, lerpTo.headRot, lerpProgress); if (spectatedPlayer.playerInfo.updateInfo.fullBodyTracking) { spectatedPlayer.playerInfo.updateInfo.leftLegPos = Vector3.Lerp(lerpFrom.leftLegPos, lerpTo.leftLegPos, lerpProgress); spectatedPlayer.playerInfo.updateInfo.rightLegPos = Vector3.Lerp(lerpFrom.rightLegPos, lerpTo.rightLegPos, lerpProgress); spectatedPlayer.playerInfo.updateInfo.pelvisPos = Vector3.Lerp(lerpFrom.pelvisPos, lerpTo.pelvisPos, lerpProgress); spectatedPlayer.playerInfo.updateInfo.leftLegRot = Quaternion.Lerp(lerpFrom.leftLegRot, lerpTo.leftLegRot, lerpProgress); spectatedPlayer.playerInfo.updateInfo.rightLegRot = Quaternion.Lerp(lerpFrom.rightLegRot, lerpTo.rightLegRot, lerpProgress); spectatedPlayer.playerInfo.updateInfo.pelvisRot = Quaternion.Lerp(lerpFrom.pelvisRot, lerpTo.pelvisRot, lerpProgress); } if (_scoreController != null) { _scoreController.SetPrivateField("_prevFrameRawScore", (int)lerpFrom.playerScore); _scoreController.SetPrivateField("_baseRawScore", (int)lerpTo.playerScore); _scoreController.SetPrivateField("_combo", (int)lerpTo.playerComboBlocks); } if (_energyCounter != null) { _energyCounter.SetPrivateProperty("energy", lerpTo.playerEnergy / 100f); } } } }
private void PacketReceived(NetIncomingMessage msg) { if (Config.Instance.SpectatorMode && !Client.Instance.InRadioMode && _currentScene == "GameCore") { msg.Position = 0; CommandType commandType = (CommandType)msg.ReadByte(); if (commandType == CommandType.UpdatePlayerInfo) { float currentTime = msg.ReadFloat(); float totalTime = msg.ReadFloat(); int playersCount = msg.ReadInt32(); for (int j = 0; j < playersCount; j++) { try { PlayerInfo player = new PlayerInfo(msg); if (_playerInfos.ContainsKey(player.playerId)) { if (_playerInfos[player.playerId].Count >= 3 * Client.Instance.Tickrate) { _playerInfos[player.playerId].RemoveAt(0); } _playerInfos[player.playerId].Add(player); } else { _playerInfos.Add(player.playerId, new List <PlayerInfo>() { player }); } } catch (Exception e) { #if DEBUG Misc.Logger.Exception($"Unable to parse PlayerInfo! Excpetion: {e}"); #endif } } if (_spectatedPlayer == null) { _spectatedPlayer = new GameObject("SpectatedPlayerController").AddComponent <OnlinePlayerController>(); _spectatedPlayer.noInterpolation = true; } if (_playerInfos.Count > 1 && _spectatedPlayer.PlayerInfo == null) { _spectatedPlayer.PlayerInfo = _playerInfos.FirstOrDefault(x => !x.Key.Equals(Client.Instance.playerInfo)).Value?.LastOrDefault(); if (_spectatedPlayer.PlayerInfo != null) { Misc.Logger.Info("Spectating " + _spectatedPlayer.PlayerInfo.playerName); } } if (_spectatedPlayer.PlayerInfo != null) { float minOffset = _playerInfos[_spectatedPlayer.PlayerInfo.playerId].Min(x => Math.Abs(x.playerProgress - audioTimeSync.songTime)); int index = _playerInfos[_spectatedPlayer.PlayerInfo.playerId].FindIndex(x => Math.Abs(x.playerProgress - audioTimeSync.songTime - minOffset) <= float.Epsilon); PlayerInfo lerpTo; float lerpProgress; if (_playerInfos[_spectatedPlayer.PlayerInfo.playerId][index].playerProgress - audioTimeSync.songTime > 0f) { _spectatedPlayer.PlayerInfo = _playerInfos[_spectatedPlayer.PlayerInfo.playerId][index]; lerpTo = _playerInfos[_spectatedPlayer.PlayerInfo.playerId][index - 1]; lerpProgress = Remap(audioTimeSync.songTime, lerpTo.playerProgress, _spectatedPlayer.PlayerInfo.playerProgress, 0f, 1f); } else { _spectatedPlayer.PlayerInfo = _playerInfos[_spectatedPlayer.PlayerInfo.playerId][index + 1]; lerpTo = _playerInfos[_spectatedPlayer.PlayerInfo.playerId][index]; lerpProgress = Remap(audioTimeSync.songTime, lerpTo.playerProgress, _spectatedPlayer.PlayerInfo.playerProgress, 0f, 1f); } _spectatedPlayer.PlayerInfo.leftHandPos = Vector3.Lerp(_spectatedPlayer.PlayerInfo.leftHandPos, lerpTo.leftHandPos, lerpProgress); _spectatedPlayer.PlayerInfo.rightHandPos = Vector3.Lerp(_spectatedPlayer.PlayerInfo.rightHandPos, lerpTo.rightHandPos, lerpProgress); _spectatedPlayer.PlayerInfo.headPos = Vector3.Lerp(_spectatedPlayer.PlayerInfo.headPos, lerpTo.headPos, lerpProgress); _spectatedPlayer.PlayerInfo.leftHandRot = Quaternion.Lerp(_spectatedPlayer.PlayerInfo.leftHandRot, lerpTo.leftHandRot, lerpProgress); _spectatedPlayer.PlayerInfo.rightHandRot = Quaternion.Lerp(_spectatedPlayer.PlayerInfo.rightHandRot, lerpTo.rightHandRot, lerpProgress); _spectatedPlayer.PlayerInfo.headRot = Quaternion.Lerp(_spectatedPlayer.PlayerInfo.headRot, lerpTo.headRot, lerpProgress); if (_leftController != null && _rightController != null) { _leftController.owner = _spectatedPlayer; _rightController.owner = _spectatedPlayer; } if (_scoreController != null) { _scoreController.SetPrivateField("_prevFrameScore", (int)_spectatedPlayer.PlayerInfo.playerScore); _scoreController.SetPrivateField("_baseScore", (int)lerpTo.playerScore); _scoreController.SetPrivateField("_combo", (int)lerpTo.playerComboBlocks); } if (_playerController != null) { _playerController.OverrideHeadPos(_spectatedPlayer.PlayerInfo.headPos); } if (_playerInfos[_spectatedPlayer.PlayerInfo.playerId].Last().playerProgress - audioTimeSync.songTime > 2.5f) { #if DEBUG if (_playerInfos[_spectatedPlayer.PlayerInfo.playerId].Last().playerProgress > 2f) { Misc.Logger.Info($"Syncing song with a spectated player...\nOffset: {_playerInfos[_spectatedPlayer.PlayerInfo.playerId].Last().playerProgress - audioTimeSync.songTime}"); } #endif SetPositionInSong(_playerInfos[_spectatedPlayer.PlayerInfo.playerId].Last().playerProgress - 1f); InGameOnlineController.Instance.PauseSong(); _paused = true; } else if (_playerInfos[_spectatedPlayer.PlayerInfo.playerId].Last().playerProgress - audioTimeSync.songTime <1.5f && (audioTimeSync.songLength - audioTimeSync.songTime)> 3f) { #if DEBUG if (_playerInfos[_spectatedPlayer.PlayerInfo.playerId].Last().playerProgress > 2f) { Misc.Logger.Info($"Syncing song with a spectated player...\nOffset: {_playerInfos[_spectatedPlayer.PlayerInfo.playerId].Last().playerProgress - audioTimeSync.songTime}"); } #endif InGameOnlineController.Instance.PauseSong(); _paused = true; } } } } }