private void PlayNow_Pressed() { SongInfo info = roomInfo.selectedSong; BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(info.levelId)) as BeatmapLevelSO; if (level == null) { SongDownloader.Instance.RequestSongByLevelID(info.levelId, (song) => { SongDownloader.Instance.DownloadSong(song, "MultiplayerSongs", () => { SongLoader.SongsLoadedEvent += PlayNow_SongsLoaded; }, (progress) => { _leaderboardViewController.SetProgressBarState((progress > 0f), progress); }); }); } else { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, (levelLoaded) => { _leaderboardViewController.SetProgressBarState(false, 0f); BeatmapCharacteristicSO characteristic = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>().FirstOrDefault(x => x.serializedName == roomInfo.startLevelInfo.characteristicName); StartLevel(levelLoaded, characteristic, roomInfo.startLevelInfo.difficulty, roomInfo.startLevelInfo.modifiers, currentTime); }); } }
public void SetSelectedSong(SongInfo info) { _selectedSong = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(info.levelId)) as BeatmapLevelSO; if (_selectedSong != null) { _selectedSongCell.SetText(_selectedSong.songName + " <size=80%>" + _selectedSong.songSubName + "</size>"); _selectedSongCell.SetSubText(_selectedSong.songAuthorName); _selectedSongCell.SetIcon(_selectedSong.coverImage); _characteristicControl.SetTexts(_selectedSong.beatmapCharacteristics.Select(x => x.characteristicName).ToArray()); int standardCharacteristicIndex = Array.FindIndex(_selectedSong.beatmapCharacteristics, x => x.serializedName == "Standard"); _characteristicControl.SelectCellWithNumber((standardCharacteristicIndex == -1 ? 0 : standardCharacteristicIndex)); _characteristicControl_didSelectCellEvent(null, (standardCharacteristicIndex == -1 ? 0 : standardCharacteristicIndex)); } else { _selectedSongCell.SetText(info.songName); _selectedSongCell.SetSubText("Loading info..."); SongDownloader.Instance.RequestSongByLevelID(info.levelId, (song) => { _selectedSongCell.SetText($"{song.songName} <size=80%>{song.songSubName}</size>"); _selectedSongCell.SetSubText(song.authorName); StartCoroutine(LoadScripts.LoadSpriteCoroutine(song.coverUrl, (cover) => { _selectedSongCell.SetIcon(cover); })); }); } }
public void ShowResultsScreen() { if (!_radioNavController.viewControllers.Contains(_resultsScreenViewController)) { PushViewControllerToNavigationController(_radioNavController, _resultsScreenViewController, null, true); if (lastDifficulty == null || lastResults == null) { _resultsScreenViewController.SetSongInfo(channelInfo.currentSong, channelInfo.currentLevelOptions.difficulty); } else { _resultsScreenViewController.SetSongInfo(lastDifficulty, lastResults); } BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(channelInfo.currentSong.levelId)) as BeatmapLevelSO; if (level != null) { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, (levelLoaded) => { PreviewPlayer.CrossfadeTo(levelLoaded.beatmapLevelData.audioClip, levelLoaded.previewStartTime, Math.Max(totalTime - currentTime, levelLoaded.previewDuration)); }); } } }
public void SetSongInfo(SongInfo songInfo) { _currentSongInfo = songInfo; if (_currentSongCell != null) { BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(songInfo.levelId)) as BeatmapLevelSO; if (level == null) { _currentSongCell.SetText(_currentSongInfo.songName); _currentSongCell.SetSubText("Loading info..."); SongDownloader.Instance.RequestSongByLevelID(_currentSongInfo.levelId, (song) => { _currentSongCell.SetText($"{song.songName} <size=80%>{song.songSubName}</size>"); _currentSongCell.SetSubText(song.authorName); StartCoroutine(LoadScripts.LoadSpriteCoroutine(song.coverUrl, (cover) => { _currentSongCell.SetIcon(cover); })); } ); } else { _currentSongCell.SetText($"{level.songName} <size=80%>{level.songSubName}</size>"); _currentSongCell.SetSubText(level.songAuthorName); _currentSongCell.SetIcon(level.coverImage); } } }
private void PlayNow_Pressed() { SongInfo info = channelInfo.currentSong; BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(info.levelId)) as BeatmapLevelSO; if (level == null) { SongDownloader.Instance.RequestSongByLevelID(info.levelId, (song) => { SongDownloader.Instance.DownloadSong(song, "RadioSongs", () => { SongLoader.SongsLoadedEvent += PlayNow_SongsLoaded; }, (progress) => { _inGameViewController.SetProgressBarState((progress < 100f), progress); }); }); } else { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, (levelLoaded) => { StartLevel(levelLoaded, _beatmapCharacteristics.First(x => x.serializedName == channelInfo.currentLevelOptions.characteristicName), channelInfo.currentLevelOptions.difficulty, channelInfo.currentLevelOptions.modifiers, currentTime); }); } }
public void SetSong(SongInfo info) { if (_songTableCell == null) { return; } _selectedSong = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(info.levelId)) as BeatmapLevelSO; if (_selectedSong != null) { _songTableCell.SetText(_selectedSong.songName + " <size=80%>" + _selectedSong.songSubName + "</size>"); _songTableCell.SetSubText(_selectedSong.songAuthorName); _songTableCell.SetIcon(_selectedSong.coverImage); } else { _songTableCell.SetText(info.songName); _songTableCell.SetSubText("Loading info..."); SongDownloader.Instance.RequestSongByLevelID(info.levelId, (song) => { _songTableCell.SetText($"{song.songName} <size=80%>{song.songSubName}</size>"); _songTableCell.SetSubText(song.authorName); StartCoroutine(LoadScripts.LoadSpriteCoroutine(song.coverUrl, (cover) => { _songTableCell.SetIcon(cover); })); }); } }
public List <BeatmapLevelSO> SortLevelsByCreationTime(List <BeatmapLevelSO> levels) { DirectoryInfo customSongsFolder = new DirectoryInfo(Environment.CurrentDirectory.Replace('\\', '/') + "/CustomSongs/"); List <string> sortedFolders = customSongsFolder.GetDirectories().OrderByDescending(x => x.CreationTime.Ticks).Select(x => x.FullName.Replace('\\', '/')).ToList(); List <string> sortedLevelIDs = new List <string>(); foreach (string path in sortedFolders) { CustomLevel song = SongLoader.CustomLevels.FirstOrDefault(x => x.customSongInfo.path.StartsWith(path)); if (song != null) { sortedLevelIDs.Add(song.levelID); } } List <BeatmapLevelSO> notSorted = new List <BeatmapLevelSO>(levels); List <BeatmapLevelSO> sortedLevels = new List <BeatmapLevelSO>(); foreach (string levelId in sortedLevelIDs) { BeatmapLevelSO data = notSorted.FirstOrDefault(x => x.levelID == levelId); if (data != null) { sortedLevels.Add(data); } } sortedLevels.AddRange(notSorted.Except(sortedLevels)); return(sortedLevels); }
private void SongSelected(BeatmapLevelSO song) { lastSelectedSong = song.levelID; Plugin.log.Warn("Selecting song with level ID: " + song.levelID); Client.Instance.SetSelectedSong(new SongInfo(song)); UpdateLevelOptions(); }
public void ShowLeaderboard(List <PlayerInfo> playerInfos, SongInfo song) { if (_leaderboardViewController == null) { _leaderboardViewController = BeatSaberUI.CreateViewController <LeaderboardViewController>(); _leaderboardViewController.playNowButtonPressed += PlayNow_Pressed; } if (_roomNavigationController.viewControllers.IndexOf(_leaderboardViewController) < 0) { PushViewControllerToNavigationController(_roomNavigationController, _leaderboardViewController, null, true); } BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(song.levelId)) as BeatmapLevelSO; if (level != null) { if (level is CustomLevel) { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, SongLoaded); } else { PreviewPlayer.CrossfadeTo(level.beatmapLevelData.audioClip, level.previewStartTime, (level.beatmapLevelData.audioClip.length - level.previewStartTime), 1f); } } _leaderboardViewController.SetLeaderboard(playerInfos); _leaderboardViewController.SetSong(song); }
public SongInfo(BeatmapLevelSO level) { songName = level.songName; songSubName = level.songSubName; authorName = level.levelAuthorName; key = ""; if (level is CustomLevel) { Regex keyMatch = new Regex("\\d+-\\d+"); var matches = keyMatch.Matches((level as CustomLevel).customSongInfo.path); if (matches.Count > 0) { key = matches[matches.Count - 1].Value; } } levelId = level.levelID.Substring(0, Math.Min(32, level.levelID.Length)); if (originalLevels.ContainsKey(levelId)) { levelId = originalLevels[levelId].levelID; } if (level.beatmapLevelData == null || level.beatmapLevelData.audioClip == null) { songDuration = 0f; } else { songDuration = level.beatmapLevelData.audioClip.length; } }
public static IDifficultyBeatmap GetDifficultyBeatmap(this BeatmapLevelSO level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, bool strictDifficulty = false) { IDifficultyBeatmapSet difficultySet = null; if (characteristic == null) { difficultySet = level.difficultyBeatmapSets.FirstOrDefault(); } else { difficultySet = level.difficultyBeatmapSets.FirstOrDefault(x => x.beatmapCharacteristic == characteristic); } if (difficultySet == null) { return(null); } IDifficultyBeatmap beatmap = difficultySet.difficultyBeatmaps.FirstOrDefault(x => x.difficulty == difficulty); if (beatmap == null && !strictDifficulty) { return(difficultySet.difficultyBeatmaps[GetClosestDifficultyIndex(difficultySet.difficultyBeatmaps, difficulty)]); } else { return(beatmap); } }
public void StartLevel(BeatmapLevelSO level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers, float startTime = 0f) { Client.Instance.playerInfo.playerComboBlocks = 0; Client.Instance.playerInfo.playerCutBlocks = 0; Client.Instance.playerInfo.playerTotalBlocks = 0; Client.Instance.playerInfo.playerEnergy = 0f; Client.Instance.playerInfo.playerScore = 0; MenuTransitionsHelperSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault(); if (_playerManagementViewController != null) { _playerManagementViewController.SetGameplayModifiers(modifiers); } if (menuSceneSetupData != null) { if (Config.Instance.SpectatorMode) { Client.Instance.playerInfo.playerState = PlayerState.Spectating; modifiers.noFail = true; } else { Client.Instance.playerInfo.playerState = PlayerState.Game; } PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings; roomInfo.roomState = RoomState.InGame; IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap(characteristic, difficulty, true); #if DEBUG Logger.Info($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={difficulty}"); #endif Client.Instance.MessageReceived -= PacketReceived; try { BS_Utils.Gameplay.Gamemode.NextLevelIsIsolated("Beat Saber Multiplayer"); } catch { } PracticeSettings practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings); practiceSettings.startSongTime = startTime + 1.5f; practiceSettings.songSpeedMul = modifiers.songSpeedMul; menuSceneSetupData.StartStandardLevel(difficultyBeatmap, modifiers, playerSettings, (startTime > 1f ? practiceSettings : null), false, () => {}, (StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, modifiers, false); }); return; } else { Logger.Error("SceneSetupData is null!"); } }
private void SongLoaded(BeatmapLevelSO song) { if (_difficultySelectionViewController != null) { _difficultySelectionViewController.SetPlayButtonInteractable(true); } PreviewPlayer.CrossfadeTo(song.beatmapLevelData.audioClip, song.previewStartTime, (song.beatmapLevelData.audioClip.length - song.previewStartTime), 1f); }
IEnumerator GetBPM() { yield return(new WaitUntil(() => Resources.FindObjectsOfTypeAll <BeatmapLevelSO>().Any())); BMD = Resources.FindObjectsOfTypeAll <BeatmapLevelSO>().FirstOrDefault(); Debug.Log("Found BPM"); Init(); }
// printing char each cycle -> going into serial monitor (Arduino IDE) -> enabling timestamps => Subtract earlier time from newer time. void Awake() { _spawnController = FindObjectOfType <BeatmapObjectManager>(); Plugin.log.Notice("Initializing.."); Plugin.log.Notice(Settings.instance.EventChoice); BSEvents.gameSceneActive += OnGameSceneActive; BSEvents.songPaused += OnSongPaused; BSEvents.songUnpaused += OnSongUnpaused; Ec = Resources.FindObjectsOfTypeAll <BeatmapObjectCallbackController>().FirstOrDefault(); Cm = Resources.FindObjectsOfTypeAll <ColorManager>().LastOrDefault(); BMD = Resources.FindObjectsOfTypeAll <BeatmapLevelSO>().FirstOrDefault(); if (Settings.instance.EventChoice == "noteCuts") { Plugin.log.Info("Adding event listner to noteCuts"); _spawnController.noteWasCutEvent += OnNoteCut; //Flash on note cuts } if (Settings.instance.EventChoice == "lightEvents") { Plugin.log.Info("Adding event listner to lightEvents"); Ec.beatmapEventDidTriggerEvent += EventHappened; //Flash on map's light events } BSEvents.menuSceneActive += menuSceneActive; C1 = Cm.ColorForNoteType(NoteType.NoteB); redLeft = Mathf.RoundToInt(C1.r * 255); greenLeft = Mathf.RoundToInt(C1.g * 255); blueLeft = Mathf.RoundToInt(C1.b * 255); C2 = Cm.ColorForNoteType(NoteType.NoteA); redRight = Mathf.RoundToInt(C2.r * 255); greenRight = Mathf.RoundToInt(C2.g * 255); blueRight = Mathf.RoundToInt(C2.b * 255); BPM = (int)BMD.beatsPerMinute; //Not used, may come useful in future Plugin.log.Info(" BPM = " + BPM.ToString()); if (Settings.arduinoPort.IsOpen) { if (Settings.instance.RainbowMode) { StartRainbowMode(Settings.arduinoPort); } else { Plugin.log.Info("Sending Color to arduino..."); SendColorToArduino(Settings.arduinoPort); } } }
public bool RemoveLevel(BeatmapLevelSO level) { var removed = _levelList.Remove(level); if (removed) { UpdateArray(); } return(removed); }
private void Awake() { Logger.log.Debug("Attempting to find BeatmapLevelSO..."); BeatmapLevelSO d = FindObjectOfType <BeatmapLevelSO>(); if (d == null) { Logger.log.Debug("Could not find BeatmapLevelSO! Destroying immediately!"); Destroy(this); } else { Logger.log.Debug("Creating new Replay object..."); replay = new Replay(d); } }
public void StartLevel(BeatmapLevelSO level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers, float startTime = 0f) { Client.Instance.playerInfo.playerComboBlocks = 0; Client.Instance.playerInfo.playerCutBlocks = 0; Client.Instance.playerInfo.playerEnergy = 0f; Client.Instance.playerInfo.playerScore = 0; MenuTransitionsHelperSO menuSceneSetupData = Resources.FindObjectsOfTypeAll <MenuTransitionsHelperSO>().FirstOrDefault(); if (menuSceneSetupData != null) { PlayerSpecificSettings playerSettings = Resources.FindObjectsOfTypeAll <PlayerDataModelSO>().FirstOrDefault().currentLocalPlayer.playerSpecificSettings; channelInfo.state = ChannelState.InGame; Client.Instance.playerInfo.playerState = PlayerState.Game; IDifficultyBeatmap difficultyBeatmap = level.GetDifficultyBeatmap(characteristic, difficulty, false); #if DEBUG Misc.Logger.Info($"Starting song: name={level.songName}, levelId={level.levelID}, difficulty={difficulty}"); #endif PracticeSettings practiceSettings = new PracticeSettings(PracticeSettings.defaultPracticeSettings); if (startTime > 1.5f) { practiceSettings.startSongTime = startTime + 1.5f; } Client.Instance.MessageReceived -= MessageReceived; try { BS_Utils.Gameplay.Gamemode.NextLevelIsIsolated("Beat Saber Multiplayer"); } catch { } menuSceneSetupData.StartStandardLevel(difficultyBeatmap, modifiers, playerSettings, (startTime > 1.5f ? practiceSettings : null), null, (StandardLevelScenesTransitionSetupDataSO sender, LevelCompletionResults levelCompletionResults) => { InGameOnlineController.Instance.SongFinished(sender, levelCompletionResults, difficultyBeatmap, modifiers, (practiceSettings != null)); }); return; } else { Misc.Logger.Error("SceneSetupData is null!"); } }
private void Update() { // NEED TO ACTUALLY ENTER THE SONG! if (beatmap == null) { beatmap = FindObjectOfType <BeatmapLevelSO>(); if (beatmap == null) { Logger.log.Debug("Waiting to start playback at right time..."); return; } Logger.log.Debug("Attempting to set the correct information for the current song..."); Logger.log.Debug("Currently ONLY does non-practice mode runs"); FindObjectOfType <SoloFreePlayFlowCoordinator>().StartLevel(null, false); //var fields = typeof(BeatmapLevelSO).GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); //foreach (var f in fields) //{ // f.SetValue(beatmap, f.GetValue(replay.BeatmapData)); //} //Logger.log.Debug("Finished setting all fields of the song BeatmapLevelSO data to the replay version!"); } if (Complete()) { Logger.log.Debug("Replay complete!"); Destroy(this); return; } if (index == 0) { Logger.log.Debug("Beginning replay!"); Logger.log.Debug("Currently does not ignore user-saber input, this will need to be resolved."); } if (controller == null) { controller = FindObjectOfType <PlayerController>(); } if (replay != null) { UpdateSaber(controller.leftSaber); UpdateSaber(controller.rightSaber); } index++; }
public void StartLevel(BeatmapLevelSO song, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers) { if (Connected && NetworkClient != null) { #if DEBUG Misc.Logger.Info("Starting level..."); #endif NetOutgoingMessage outMsg = NetworkClient.CreateMessage(); outMsg.Write((byte)CommandType.StartLevel); new StartLevelInfo(difficulty, modifiers, characteristic.serializedName).AddToMessage(outMsg); SongInfo selectedSong = new SongInfo(song); selectedSong.songDuration = selectedSong.songDuration / modifiers.songSpeedMul; selectedSong.AddToMessage(outMsg); NetworkClient.SendMessage(outMsg, NetDeliveryMethod.ReliableOrdered, 0); } }
public TableCell CellForIdx(int row) { LevelListTableCell cell = Instantiate(_songTableCellInstance); BeatmapLevelSO song = availableSongs[row]; cell.SetIcon(song.coverImage); cell.SetText($"{song.songName} <size=80%>{song.songSubName}</size>"); cell.SetSubText(song.songAuthorName); cell.reuseIdentifier = "SongCell"; cell.SetPrivateField("_beatmapCharacteristicAlphas", new float[3] { song.beatmapCharacteristics.Any(x => x.serializedName == "Standard") ? 1f : 0.1f, song.beatmapCharacteristics.Any(x => x.serializedName == "NoArrows") ? 1f : 0.1f, song.beatmapCharacteristics.Any(x => x.serializedName == "OneSaber") ? 1f : 0.1f }); cell.SetPrivateField("_beatmapCharacteristicImages", cell.GetComponentsInChildren <UnityEngine.UI.Image>().Where(x => x.name.StartsWith("LevelTypeIcon")).ToArray()); cell.SetPrivateField("_bought", true); return(cell); }
public void ShowInGameScreen() { if (!_radioNavController.viewControllers.Contains(_inGameViewController)) { PushViewControllerToNavigationController(_radioNavController, _inGameViewController, null, true); _inGameViewController.SetSongInfo(channelInfo.currentSong); BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(channelInfo.currentSong.levelId)) as BeatmapLevelSO; if (level != null) { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, (levelLoaded) => { PreviewPlayer.CrossfadeTo(levelLoaded.beatmapLevelData.audioClip, levelLoaded.previewStartTime, Math.Max(totalTime - currentTime, levelLoaded.previewDuration)); }); } else { Misc.Logger.Error("Unable to play preview for song! Level is null! levelID=" + channelInfo.currentSong.levelId); } } }
public Replay(BeatmapLevelSO so) { Data = new List <SongData>(); BeatmapData = so; SetupPreMap(); }
private void PlayPressed(BeatmapLevelSO song, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, GameplayModifiers modifiers) { Client.Instance.StartLevel(song, characteristic, difficulty, modifiers); }
public void ShowDifficultySelection(SongInfo song) { if (song == null) { return; } if (_difficultySelectionViewController == null) { _difficultySelectionViewController = BeatSaberUI.CreateViewController <DifficultySelectionViewController>(); _difficultySelectionViewController.discardPressed += DiscardPressed; _difficultySelectionViewController.playPressed += (level, characteristic, difficulty) => { PlayPressed(level, characteristic, difficulty, _playerManagementViewController.modifiers); }; _difficultySelectionViewController.levelOptionsChanged += UpdateLevelOptions; } if (!_roomNavigationController.viewControllers.Contains(_difficultySelectionViewController)) { PushViewControllerToNavigationController(_roomNavigationController, _difficultySelectionViewController, null, true); } _difficultySelectionViewController.SetSelectedSong(song); _difficultySelectionViewController.UpdateViewController(Client.Instance.isHost, roomInfo.perPlayerDifficulty); BeatmapLevelSO selectedLevel = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.Where(x => x.packID == "CustomMaps" || CustomExtensions.basePackIDs.Contains(x.packID)).SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(song.levelId)) as BeatmapLevelSO; if (selectedLevel != null) { if (selectedLevel is CustomLevel) { _difficultySelectionViewController.SetPlayButtonInteractable(false); SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)selectedLevel, SongLoaded); } else { _difficultySelectionViewController.SetPlayButtonInteractable(true); PreviewPlayer.CrossfadeTo(selectedLevel.beatmapLevelData.audioClip, selectedLevel.previewStartTime, (selectedLevel.beatmapLevelData.audioClip.length - selectedLevel.previewStartTime), 1f); } Client.Instance.SendPlayerReady(true); Client.Instance.playerInfo.playerState = PlayerState.Room; } else { Client.Instance.playerInfo.playerState = PlayerState.DownloadingSongs; Client.Instance.SendPlayerReady(false); _difficultySelectionViewController.SetPlayButtonInteractable(false); SongDownloader.Instance.RequestSongByLevelID(song.levelId, (info) => { Client.Instance.playerInfo.playerState = PlayerState.DownloadingSongs; songToDownload = info; SongDownloader.Instance.DownloadSong(songToDownload, "MultiplayerSongs", () => { Action <SongLoader, List <CustomLevel> > onLoaded = null; onLoaded = (sender, songs) => { SongLoader.SongsLoadedEvent -= onLoaded; Client.Instance.playerInfo.playerState = PlayerState.Room; selectedLevel = songs.FirstOrDefault(x => x.levelID.StartsWith(roomInfo.selectedSong.levelId)); if (selectedLevel != null) { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)selectedLevel, (levelLoaded) => { PreviewPlayer.CrossfadeTo(levelLoaded.beatmapLevelData.audioClip, levelLoaded.previewStartTime, (levelLoaded.beatmapLevelData.audioClip.length - levelLoaded.previewStartTime)); }); _difficultySelectionViewController.SetSelectedSong(song); _difficultySelectionViewController.SetPlayButtonInteractable(true); _difficultySelectionViewController.SetProgressBarState(false, 1f); Client.Instance.SendPlayerReady(true); Client.Instance.playerInfo.playerState = PlayerState.Room; } }; SongLoader.SongsLoadedEvent += onLoaded; songToDownload = null; }, (progress) => { float clampedProgress = Math.Min(progress, 0.99f); _difficultySelectionViewController.SetProgressBarState(true, clampedProgress); Client.Instance.playerInfo.playerProgress = 100f * clampedProgress; }); }); } }
private void MessageReceived(NetIncomingMessage msg) { if (msg == null) { InGameOnlineController.Instance.needToSendUpdates = false; PopAllViewControllers(); InGameOnlineController.Instance.DestroyPlayerControllers(); PreviewPlayer.CrossfadeToDefault(); joined = false; _radioNavController.DisplayError("Lost connection to the ServerHub!"); return; } CommandType commandType = (CommandType)msg.ReadByte(); if (!joined) { if (commandType == CommandType.JoinChannel) { switch (msg.ReadByte()) { case 0: { Client.Instance.playerInfo.playerState = PlayerState.Room; Client.Instance.RequestChannelInfo(channelId); Client.Instance.SendPlayerInfo(); joined = true; InGameOnlineController.Instance.needToSendUpdates = true; } break; case 1: { _radioNavController.DisplayError("Unable to join channel!\nChannel not found"); } break; default: { _radioNavController.DisplayError("Unable to join channel!\nUnknown error"); } break; } } } else { try { switch (commandType) { case CommandType.GetChannelInfo: { channelInfo = new ChannelInfo(msg); channelInfo.ip = ip; channelInfo.port = port; UpdateUI(channelInfo.state); } break; case CommandType.SetSelectedSong: { if (msg.LengthBytes > 16) { SongInfo song = new SongInfo(msg); channelInfo.currentSong = song; channelInfo.state = ChannelState.NextSong; UpdateUI(channelInfo.state); } } break; case CommandType.GetSongDuration: { SongInfo requestedSong = new SongInfo(msg); BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(channelInfo.currentSong.levelId)) as BeatmapLevelSO; if (level != null) { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, (loadedLevel) => { Client.Instance.SendSongDuration(new SongInfo(loadedLevel)); }); } } break; case CommandType.StartLevel: { if (Client.Instance.playerInfo.playerState == PlayerState.DownloadingSongs) { return; } if (nextSongSkipped) { nextSongSkipped = false; channelInfo.state = ChannelState.InGame; UpdateUI(channelInfo.state); 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) { Misc.Logger.Error("Unable to start level! Level is null! LevelID=" + songInfo.levelId); return; } SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, (levelLoaded) => { try { BS_Utils.Gameplay.Gamemode.NextLevelIsIsolated("Beat Saber Multiplayer"); } catch { } StartLevel(levelLoaded, characteristic, levelInfo.difficulty, levelInfo.modifiers); }); } break; case CommandType.LeaveRoom: { LeaveChannel(); } break; case CommandType.UpdatePlayerInfo: { if (channelInfo != null) { currentTime = msg.ReadFloat(); totalTime = msg.ReadFloat(); switch (channelInfo.state) { case ChannelState.InGame: UpdateInGameScreen(); break; case ChannelState.NextSong: UpdateNextSongScreen(); break; case ChannelState.Results: { UpdateResultsScreen(); 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! Excpetion: {e}"); #endif return; } playerInfos = playerInfos.Where(x => x.playerScore > 0 && (x.playerState == PlayerState.Game || x.playerState == PlayerState.Room)).ToList(); } break; } } } break; case CommandType.Disconnect: { InGameOnlineController.Instance.needToSendUpdates = false; if (msg.LengthBytes > 3) { string reason = msg.ReadString(); PopAllViewControllers(); InGameOnlineController.Instance.DestroyPlayerControllers(); PreviewPlayer.CrossfadeToDefault(); joined = false; _radioNavController.DisplayError(reason); } else { _radioNavController.DisplayError("ServerHub refused connection!"); } } break; } } catch (Exception e) { Misc.Logger.Exception($"Unable to parse packet! Packet={commandType}, DataLength={msg.LengthBytes}\nException: {e}"); } } }
private void SongSelected(BeatmapLevelSO song) { lastSelectedSong = song.levelID; Client.Instance.SetSelectedSong(new SongInfo(song)); UpdateLevelOptions(); }
public void UpdateUI(ChannelState state) { switch (state) { case ChannelState.NextSong: { if (!_radioNavController.viewControllers.Contains(_nextSongScreenViewController)) { PopAllViewControllers(); } ShowNextSongScreen(); BeatmapLevelSO level = SongLoader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.SelectMany(x => x.beatmapLevelCollection.beatmapLevels).FirstOrDefault(x => x.levelID.StartsWith(channelInfo.currentSong.levelId)) as BeatmapLevelSO; if (level == null) { Client.Instance.playerInfo.playerState = PlayerState.DownloadingSongs; SongDownloader.Instance.RequestSongByLevelID(channelInfo.currentSong.levelId, (song) => { SongDownloader.Instance.DownloadSong(song, "RadioSongs", () => { Action <SongLoader, List <CustomLevel> > onLoaded = null; onLoaded = (sender, songs) => { SongLoader.SongsLoadedEvent -= onLoaded; Client.Instance.playerInfo.playerState = PlayerState.Room; level = songs.FirstOrDefault(x => x.levelID.StartsWith(channelInfo.currentSong.levelId)); if (level != null) { SongLoader.Instance.LoadAudioClipForLevel((CustomLevel)level, (levelLoaded) => { PreviewPlayer.CrossfadeTo(levelLoaded.beatmapLevelData.audioClip, levelLoaded.previewStartTime, Math.Max(totalTime - currentTime, levelLoaded.previewDuration)); }); } }; SongLoader.SongsLoadedEvent += onLoaded; }, (progress) => { _nextSongScreenViewController.SetProgressBarState((progress < 100f), progress); }); }); } Client.Instance.playerInfo.playerScore = 0; Client.Instance.playerInfo.playerEnergy = 0f; Client.Instance.playerInfo.playerCutBlocks = 0; Client.Instance.playerInfo.playerComboBlocks = 0; } break; case ChannelState.InGame: { if (!_radioNavController.viewControllers.Contains(_inGameViewController)) { PopAllViewControllers(); } ShowInGameScreen(); } break; case ChannelState.Results: { if (!_radioNavController.viewControllers.Contains(_resultsScreenViewController)) { PopAllViewControllers(); } ShowResultsScreen(); } break; } }
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}"); } } }