private void PacketReceived(NetIncomingMessage msg) { if (Config.Instance.SpectatorMode && !Client.Instance.InRadioMode && _currentScene.name == "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)) { if (_playerInfos[player].Count >= 3 * Client.Instance.Tickrate) { _playerInfos[player].RemoveAt(0); } _playerInfos[player].Add(player); } else { _playerInfos.Add(player, new List <PlayerInfo>() { player }); } } catch (Exception e) { #if DEBUG Misc.Logger.Exception($"Unable to parse PlayerInfo! Excpetion: {e}"); #endif } } if (_playerInfos.Count > 1 && _spectatedPlayer == null) { _spectatedPlayer = _playerInfos.First(x => !x.Key.Equals(Client.Instance.playerInfo)).Value.Last(); Misc.Logger.Info("Spectating " + _spectatedPlayer.playerName); } if (_spectatedPlayer != null) { float minOffset = _playerInfos[_spectatedPlayer].Min(x => Math.Abs(x.playerProgress - audioTimeSync.songTime)); int index = _playerInfos[_spectatedPlayer].FindIndex(x => Math.Abs(x.playerProgress - audioTimeSync.songTime) == minOffset); PlayerInfo lerpTo; float lerpProgress; if (_playerInfos[_spectatedPlayer][index].playerProgress - audioTimeSync.songTime > 0f) { _spectatedPlayer = _playerInfos[_spectatedPlayer][index]; lerpTo = _playerInfos[_spectatedPlayer][index - 1]; lerpProgress = Remap(audioTimeSync.songTime, lerpTo.playerProgress, _spectatedPlayer.playerProgress, 0f, 1f); } else { _spectatedPlayer = _playerInfos[_spectatedPlayer][index + 1]; lerpTo = _playerInfos[_spectatedPlayer][index]; lerpProgress = Remap(audioTimeSync.songTime, lerpTo.playerProgress, _spectatedPlayer.playerProgress, 0f, 1f); } if (_spectatedPlayer != null) { _spectatedPlayer.leftHandPos = Vector3.Lerp(_spectatedPlayer.leftHandPos, lerpTo.leftHandPos, 0); _spectatedPlayer.rightHandPos = Vector3.Lerp(_spectatedPlayer.rightHandPos, lerpTo.rightHandPos, 0); _spectatedPlayer.leftHandRot = Quaternion.Lerp(_spectatedPlayer.leftHandRot, lerpTo.leftHandRot, 0); _spectatedPlayer.rightHandRot = Quaternion.Lerp(_spectatedPlayer.rightHandRot, lerpTo.rightHandRot, 0); if (_spectatedPlayerAvatar == null) { _spectatedPlayerAvatar = new GameObject("Avatar").AddComponent <AvatarController>(); _spectatedPlayerAvatar.forcePlayerInfo = true; } _spectatedPlayerAvatar.SetPlayerInfo(_spectatedPlayer, 0f, false); if (_leftController != null && _rightController != null) { _leftController.SetPlayerInfo(_spectatedPlayer); _rightController.SetPlayerInfo(_spectatedPlayer); } if (_scoreController != null) { _scoreController.SetPrivateField("_prevFrameScore", (int)_spectatedPlayer.playerScore); _scoreController.SetPrivateField("_baseScore", (int)lerpTo.playerScore); _scoreController.SetPrivateField("_combo", (int)lerpTo.playerComboBlocks); } if (_playerController != null) { _playerController.OverrideHeadPos(_spectatedPlayer.headPos); } if (_playerInfos[_spectatedPlayer].Last().playerProgress - audioTimeSync.songTime > 2.5f) { #if DEBUG if (_playerInfos[_spectatedPlayer].Last().playerProgress > 2f) { Misc.Logger.Info($"Syncing song with a spectated player...\nOffset: {_playerInfos[_spectatedPlayer].Last().playerProgress - audioTimeSync.songTime}"); } #endif SetPositionInSong(_playerInfos[_spectatedPlayer].Last().playerProgress - 1f); InGameOnlineController.Instance.PauseSong(); _paused = true; } else if (_playerInfos[_spectatedPlayer].Last().playerProgress - audioTimeSync.songTime <1.5f && (audioTimeSync.songLength - audioTimeSync.songTime)> 3f) { #if DEBUG if (_playerInfos[_spectatedPlayer].Last().playerProgress > 2f) { Misc.Logger.Info($"Syncing song with a spectated player...\nOffset: {_playerInfos[_spectatedPlayer].Last().playerProgress - audioTimeSync.songTime}"); } #endif InGameOnlineController.Instance.PauseSong(); _paused = true; } } } } } }