private void PacketReceived(NetIncomingMessage msg) { if (msg == null) { DisconnectCommandReceived(null); return; } msg.Position = 0; CommandType commandType = (CommandType)msg.ReadByte(); if (!joined) { if (commandType == CommandType.JoinRoom) { switch (msg.ReadByte()) { case 0: { Client.Instance.playerInfo.updateInfo.playerState = PlayerState.DownloadingSongs; Client.Instance.RequestRoomInfo(); roomInfoRequestTime = Time.time; Client.Instance.SendPlayerInfo(true); Client.Instance.inRoom = true; joined = true; InGameOnlineController.Instance.needToSendUpdates = true; if (Config.Instance.EnableVoiceChat) { InGameOnlineController.Instance.VoiceChatStartRecording(); } } break; case 1: { _roomNavigationController.DisplayError("Unable to join room!\nRoom not found"); } break; case 2: { _roomNavigationController.DisplayError("Unable to join room!\nIncorrect password"); } break; case 3: { _roomNavigationController.DisplayError("Unable to join room!\nToo much players"); } break; default: { _roomNavigationController.DisplayError("Unable to join room!\nUnknown error"); } break; } } } else { try { if (roomInfo == null && commandType != CommandType.GetRoomInfo) { if (Time.time - roomInfoRequestTime < 1.5f) { return; } else { throw new ArgumentNullException("RoomInfo is null! Need to wait for it to arrive..."); } } switch (commandType) { case CommandType.GetRoomInfo: { roomInfo = new RoomInfo(msg); Client.Instance.playerInfo.updateInfo.playerState = PlayerState.Room; Client.Instance.isHost = Client.Instance.playerInfo.Equals(roomInfo.roomHost); UpdateUI(roomInfo.roomState); } break; case CommandType.SetSelectedSong: { if (msg.LengthBytes < 16) { roomInfo.roomState = RoomState.SelectingSong; roomInfo.selectedSong = null; PreviewPlayer.CrossfadeToDefault(); UpdateUI(roomInfo.roomState); if (songToDownload != null) { songToDownload.songQueueState = SongQueueState.Error; Client.Instance.playerInfo.updateInfo.playerState = PlayerState.Room; } } else { roomInfo.roomState = RoomState.Preparing; SongInfo selectedSong = new SongInfo(msg); roomInfo.selectedSong = selectedSong; if (roomInfo.startLevelInfo == null) { roomInfo.startLevelInfo = new LevelOptionsInfo(BeatmapDifficulty.Hard, GameplayModifiers.defaultModifiers, "Standard"); } if (songToDownload != null) { songToDownload.songQueueState = SongQueueState.Error; } UpdateUI(roomInfo.roomState); } } break; case CommandType.SetLevelOptions: { roomInfo.startLevelInfo = new LevelOptionsInfo(msg); _playerManagementViewController.SetGameplayModifiers(roomInfo.startLevelInfo.modifiers.ToGameplayModifiers()); if (roomInfo.roomState == RoomState.Preparing) { _difficultySelectionViewController.SetBeatmapCharacteristic(_beatmapCharacteristics.First(x => x.serializedName == roomInfo.startLevelInfo.characteristicName)); if (!roomInfo.perPlayerDifficulty) { _difficultySelectionViewController.SetBeatmapDifficulty(roomInfo.startLevelInfo.difficulty); } } } break; case CommandType.GetRandomSongInfo: { SongInfo random = new SongInfo(SongCore.Loader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).ToArray().Random()); Client.Instance.SetSelectedSong(random); } break; case CommandType.TransferHost: { roomInfo.roomHost = new PlayerInfo(msg); Client.Instance.isHost = Client.Instance.playerInfo.Equals(roomInfo.roomHost); if (Client.Instance.playerInfo.updateInfo.playerState == PlayerState.DownloadingSongs) { return; } UpdateUI(roomInfo.roomState); } break; case CommandType.StartLevel: { if (Client.Instance.playerInfo.updateInfo.playerState == PlayerState.DownloadingSongs) { return; } LevelOptionsInfo levelInfo = new LevelOptionsInfo(msg); BeatmapCharacteristicSO characteristic = _beatmapCharacteristics.First(x => x.serializedName == levelInfo.characteristicName); SongInfo songInfo = new SongInfo(msg); IPreviewBeatmapLevel level = SongCore.Loader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(songInfo.levelId)); if (level == null) { Plugin.log.Error("Unable to start level! Level is null! LevelID=" + songInfo.levelId); } else { LoadBeatmapLevelAsync(level, (status, success, beatmapLevel) => { if (roomInfo.perPlayerDifficulty && _difficultySelectionViewController != null) { StartLevel(beatmapLevel, characteristic, _difficultySelectionViewController.selectedDifficulty, levelInfo.modifiers.ToGameplayModifiers()); } else { StartLevel(beatmapLevel, characteristic, levelInfo.difficulty, levelInfo.modifiers.ToGameplayModifiers()); } }); } } break; case CommandType.LeaveRoom: { LeaveRoom(); } break; case CommandType.UpdatePlayerInfo: { if (roomInfo != null) { currentTime = msg.ReadFloat(); totalTime = msg.ReadFloat(); if (roomInfo.roomState == RoomState.InGame || roomInfo.roomState == RoomState.Results) { UpdateLeaderboard(currentTime, totalTime, roomInfo.roomState == RoomState.Results); } _playerManagementViewController.UpdatePlayerList(roomInfo.roomState); } } break; case CommandType.PlayerReady: { int playersReady = msg.ReadInt32(); int playersTotal = msg.ReadInt32(); if (roomInfo.roomState == RoomState.Preparing && _difficultySelectionViewController != null) { _difficultySelectionViewController.SetPlayersReady(playersReady, playersTotal); } } break; case CommandType.Disconnect: { DisconnectCommandReceived(msg); } break; } }catch (Exception e) { Plugin.log.Error($"Unable to parse packet! Packet={commandType}, DataLength={msg.LengthBytes}\nException: {e}"); } } }
private void PacketReceived(NetIncomingMessage msg) { if (msg == null) { DisconnectCommandReceived(null); return; } CommandType commandType = (CommandType)msg.ReadByte(); if (!joined) { if (commandType == CommandType.JoinRoom) { switch (msg.ReadByte()) { case 0: { Client.Instance.playerInfo.playerState = PlayerState.DownloadingSongs; Client.Instance.RequestRoomInfo(); Client.Instance.SendPlayerInfo(); Client.Instance.InRoom = true; joined = true; InGameOnlineController.Instance.needToSendUpdates = true; if (Config.Instance.EnableVoiceChat) { InGameOnlineController.Instance.VoiceChatStartRecording(); } } break; case 1: { _roomNavigationController.DisplayError("Unable to join room!\nRoom not found"); } break; case 2: { _roomNavigationController.DisplayError("Unable to join room!\nIncorrect password"); } break; case 3: { _roomNavigationController.DisplayError("Unable to join room!\nToo much players"); } break; default: { _roomNavigationController.DisplayError("Unable to join room!\nUnknown error"); } break; } } } else { try { switch (commandType) { case CommandType.GetRoomInfo: { Client.Instance.playerInfo.playerState = PlayerState.Room; roomInfo = new RoomInfo(msg); Client.Instance.isHost = Client.Instance.playerInfo.Equals(roomInfo.roomHost); UpdateUI(roomInfo.roomState); } break; case CommandType.SetSelectedSong: { if (msg.LengthBytes < 16) { roomInfo.roomState = RoomState.SelectingSong; roomInfo.selectedSong = null; PreviewPlayer.CrossfadeToDefault(); UpdateUI(roomInfo.roomState); if (songToDownload != null) { songToDownload.songQueueState = SongQueueState.Error; Client.Instance.playerInfo.playerState = PlayerState.Room; } } else { roomInfo.roomState = RoomState.Preparing; SongInfo selectedSong = new SongInfo(msg); roomInfo.selectedSong = selectedSong; if (roomInfo.startLevelInfo == null) { roomInfo.startLevelInfo = new StartLevelInfo(BeatmapDifficulty.Hard, GameplayModifiers.defaultModifiers, "Standard"); } if (songToDownload != null) { songToDownload.songQueueState = SongQueueState.Error; } UpdateUI(roomInfo.roomState); } } break; case CommandType.SetLevelOptions: { if (roomInfo.roomState == RoomState.SelectingSong) { roomInfo.startLevelInfo = new StartLevelInfo(msg); _playerManagementViewController.SetGameplayModifiers(roomInfo.startLevelInfo.modifiers); _difficultySelectionViewController.SetBeatmapCharacteristic(_beatmapCharacteristics.First(x => x.serializedName == roomInfo.startLevelInfo.characteristicName)); if (!roomInfo.perPlayerDifficulty) { _difficultySelectionViewController.SetBeatmapDifficulty(roomInfo.startLevelInfo.difficulty); } } } break; case CommandType.GetRandomSongInfo: { SongInfo random = new SongInfo(SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).ToArray().Random() as BeatmapLevelSO); Client.Instance.SetSelectedSong(random); } break; case CommandType.TransferHost: { roomInfo.roomHost = new PlayerInfo(msg); Client.Instance.isHost = Client.Instance.playerInfo.Equals(roomInfo.roomHost); if (Client.Instance.playerInfo.playerState == PlayerState.DownloadingSongs) { return; } UpdateUI(roomInfo.roomState); } break; case CommandType.StartLevel: { if (Client.Instance.playerInfo.playerState == PlayerState.DownloadingSongs) { return; } StartLevelInfo levelInfo = new StartLevelInfo(msg); BeatmapCharacteristicSO characteristic = _beatmapCharacteristics.First(x => x.serializedName == levelInfo.characteristicName); SongInfo songInfo = new SongInfo(msg); BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(songInfo.levelId)) as BeatmapLevelSO; if (level == null) { Logger.Error("Unable to start level! Level is null! LevelID=" + songInfo.levelId); } if (roomInfo.perPlayerDifficulty && _difficultySelectionViewController != null) { StartLevel(level, characteristic, _difficultySelectionViewController.selectedDifficulty, levelInfo.modifiers); } else { StartLevel(level, characteristic, levelInfo.difficulty, levelInfo.modifiers); } } break; case CommandType.LeaveRoom: { LeaveRoom(); } break; case CommandType.UpdatePlayerInfo: { if (roomInfo != null) { currentTime = msg.ReadFloat(); totalTime = msg.ReadFloat(); int playersCount = msg.ReadInt32(); List <PlayerInfo> playerInfos = new List <PlayerInfo>(); for (int j = 0; j < playersCount; j++) { try { playerInfos.Add(new PlayerInfo(msg)); } catch (Exception e) { #if DEBUG Misc.Logger.Exception($"Unable to parse PlayerInfo! Excpetion: {e}"); #endif } } switch (roomInfo.roomState) { case RoomState.InGame: playerInfos = playerInfos.Where(x => x.playerScore > 0 && x.playerState == PlayerState.Game).ToList(); UpdateLeaderboard(playerInfos, currentTime, totalTime, false); break; case RoomState.Results: playerInfos = playerInfos.Where(x => x.playerScore > 0 && (x.playerState == PlayerState.Game || x.playerState == PlayerState.Room)).ToList(); UpdateLeaderboard(playerInfos, currentTime, totalTime, true); break; } _playerManagementViewController.UpdatePlayerList(playerInfos, roomInfo.roomState); } } break; case CommandType.PlayerReady: { int playersReady = msg.ReadInt32(); int playersTotal = msg.ReadInt32(); if (roomInfo.roomState == RoomState.Preparing && _difficultySelectionViewController != null) { _difficultySelectionViewController.SetPlayersReady(playersReady, playersTotal); } } break; case CommandType.Disconnect: { DisconnectCommandReceived(msg); } break; } }catch (Exception e) { Logger.Exception($"Unable to parse packet! Packet={commandType}, DataLength={msg.LengthBytes}\nException: {e}"); } } }