private void _simpleDialog_didFinishEvent(SimpleDialogPromptViewController sender, bool delete) { _freePlayFlowCoordinator.InvokePrivateMethod("DismissViewController", new object[] { _simpleDialog, null, false }); if (delete) { try { SongDownloader.Instance.DeleteSong(new Song(SongLoader.CustomLevels.First(x => x.levelID == _detailViewController.difficultyBeatmap.level.levelID))); List <IBeatmapLevel> levels = _levelListViewController.GetPrivateField <IBeatmapLevel[]>("_levels").ToList(); int selectedIndex = levels.IndexOf(_detailViewController.difficultyBeatmap.level); if (selectedIndex > -1) { int removedLevels = levels.RemoveAll(x => x == _detailViewController.difficultyBeatmap.level); Logger.Log("Removed " + removedLevels + " level(s) from song list!"); if (selectedIndex > 0) { selectedIndex--; } _levelListViewController.SetLevels(levels.ToArray()); TableView listTableView = _levelListViewController.GetPrivateField <LevelListTableView>("_levelListTableView").GetPrivateField <TableView>("_tableView"); listTableView.ScrollToRow(selectedIndex, false); listTableView.SelectRow(selectedIndex, true); } }catch (Exception e) { Logger.Error("Unable to delete song! Exception: " + e); } } }
private void SceneManager_activeSceneChanged(Scene from, Scene to) { Logger.Log($"Active scene changed from \"{from.name}\" to \"{to.name}\""); if (from.name == "EmptyTransition" && to.name.Contains("Menu")) { try { PluginUI.Instance.OnLoad(); VotingUI.Instance.OnLoad(); //TagUI.Instance.OnLoad(); if (!PluginConfig.disableSongListTweaks) { SongListTweaks.Instance.OnLoad(); } }catch (Exception e) { Logger.Exception("Exception on scene change: " + e); } } else if (from.name == "GameCore" && to.name.Contains("Menu")) { TagUI.Instance.OnLoad(); } }
private IEnumerator VoteForSong(bool upvote) { Logger.Log($"Voting..."); _upvoteButton.interactable = false; _downvoteButton.interactable = false; UnityWebRequest voteWWW = UnityWebRequest.Get($"{PluginConfig.beatsaverURL}/api/songs/vote/{_lastBeatSaverSong.id}/{(upvote ? 1 : 0)}/{PluginConfig.apiAccessToken}"); voteWWW.timeout = 30; yield return(voteWWW.SendWebRequest()); if (voteWWW.isNetworkError || voteWWW.isHttpError) { Logger.Error(voteWWW.error); _ratingText.text = voteWWW.error; } else { if (!_firstVote) { yield return(new WaitForSecondsRealtime(3f)); } _firstVote = false; _upvoteButton.interactable = true; _downvoteButton.interactable = true; switch (voteWWW.responseCode) { case 200: { JSONNode node = JSON.Parse(voteWWW.downloadHandler.text); _ratingText.text = (int.Parse(node["upVotes"]) - int.Parse(node["downVotes"])).ToString(); }; break; case 403: { _ratingText.text = "Read-only token"; }; break; case 401: { _ratingText.text = "Token not found"; }; break; case 400: { _ratingText.text = "Bad token"; }; break; default: { _ratingText.text = "Error " + voteWWW.responseCode; }; break; } } }
public void DownloadAllSongsFromQueue() { Logger.Log("Downloading all songs from queue..."); for (int i = 0; i < Math.Min(PluginConfig.maxSimultaneousDownloads, queuedSongs.Count); i++) { StartCoroutine(DownloadSong(queuedSongs[i])); } }
public void AbortDownloads() { Logger.Log("Cancelling downloads..."); foreach (Song song in queuedSongs.Where(x => x.songQueueState == SongQueueState.Downloading || x.songQueueState == SongQueueState.Queued)) { song.songQueueState = SongQueueState.Error; } Refresh(); allSongsDownloaded?.Invoke(); }
private void SceneManager_activeSceneChanged(Scene from, Scene to) { Logger.Log($"Active scene changed from \"{from.name}\" to \"{to.name}\""); if (from.name == "EmptyTransition" && to.name.Contains("Menu")) { PluginUI.Instance.OnLoad(); VotingUI.Instance.OnLoad(); if (!PluginConfig.disableSongListTweaks) { SongListTweaks.Instance.OnLoad(); } } }
public void Refresh() { int removed = queuedSongs.RemoveAll(x => x.songQueueState == SongQueueState.Downloaded || x.songQueueState == SongQueueState.Error); Logger.Log($"Removed {removed} songs from queue"); _queuedSongsTableView.ReloadData(); _queuedSongsTableView.ScrollToRow(0, true); if (queuedSongs.Count(x => x.songQueueState == SongQueueState.Downloading || x.songQueueState == SongQueueState.Queued) == 0) { Logger.Log("All songs downloaded!"); allSongsDownloaded?.Invoke(); } if (queuedSongs.Count(x => x.songQueueState == SongQueueState.Downloading) < PluginConfig.maxSimultaneousDownloads && queuedSongs.Any(x => x.songQueueState == SongQueueState.Queued)) { StartCoroutine(DownloadSong(queuedSongs.First(x => x.songQueueState == SongQueueState.Queued))); } }
public void AddDefaultPlaylists() { Logger.Log("Creating default playlists..."); List <LevelSO> levels = _levelCollection.levels.ToList(); Playlist _allPlaylist = new Playlist() { playlistTitle = "All songs", playlistAuthor = "", image = Base64Sprites.BeastSaberLogoB64, icon = Base64Sprites.BeastSaberLogo, fileLoc = "" }; _allPlaylist.songs = new List <PlaylistSong>(); _allPlaylist.songs.AddRange(levels.Select(x => new PlaylistSong() { songName = $"{x.songName} {x.songSubName}", level = x, oneSaber = x.beatmapCharacteristics.Any(y => y.characteristicName == "One Saber"), path = "", key = "", levelId = x.levelID })); Logger.Log($"Created \"{_allPlaylist.playlistTitle}\" playlist with {_allPlaylist.songs.Count} songs!"); Playlist _favPlaylist = new Playlist() { playlistTitle = "Your favorite songs", playlistAuthor = "", image = Base64Sprites.BeastSaberLogoB64, icon = Base64Sprites.BeastSaberLogo, fileLoc = "" }; _favPlaylist.songs = new List <PlaylistSong>(); _favPlaylist.songs.AddRange(levels.Where(x => PluginConfig.favoriteSongs.Contains(x.levelID)).Select(x => new PlaylistSong() { songName = $"{x.songName} {x.songSubName}", level = x, oneSaber = x.beatmapCharacteristics.Any(y => y.characteristicName == "One Saber"), path = "", key = "", levelId = x.levelID })); Logger.Log($"Created \"{_favPlaylist.playlistTitle}\" playlist with {_favPlaylist.songs.Count} songs!"); if (PlaylistsCollection.loadedPlaylists.Any(x => x.playlistTitle == "All songs" || x.playlistTitle == "Your favorite songs")) { PlaylistsCollection.loadedPlaylists.RemoveAll(x => x.playlistTitle == "All songs" || x.playlistTitle == "Your favorite songs"); } PlaylistsCollection.loadedPlaylists.Insert(0, _favPlaylist); PlaylistsCollection.loadedPlaylists.Insert(0, _allPlaylist); _favPlaylist.SavePlaylist("Playlists\\favorites.json"); }
public void AddDefaultPlaylists() { Logger.Log("Creating default playlists..."); List <BeatmapLevelSO> levels = _levelCollection.GetPrivateField <BeatmapLevelSO[]>("_beatmapLevels").ToList(); Playlist _allPlaylist = new Playlist() { playlistTitle = "All songs", playlistAuthor = "", image = Sprites.SpriteToBase64(Sprites.BeastSaberLogo), icon = Sprites.BeastSaberLogo, fileLoc = "" }; _allPlaylist.songs = new List <PlaylistSong>(); _allPlaylist.songs.AddRange(levels.Select(x => new PlaylistSong() { songName = $"{x.songName} {x.songSubName}", level = x, oneSaber = x.beatmapCharacteristics.Any(y => y.characteristicName == "One Saber"), path = "", key = "", levelId = x.levelID, hash = CustomHelpers.CheckHex(x.levelID.Substring(0, Math.Min(32, x.levelID.Length))) })); Logger.Log($"Created \"{_allPlaylist.playlistTitle}\" playlist with {_allPlaylist.songs.Count} songs!"); Playlist _favPlaylist = new Playlist() { playlistTitle = "Your favorite songs", playlistAuthor = "", image = Sprites.SpriteToBase64(Sprites.BeastSaberLogo), icon = Sprites.BeastSaberLogo, fileLoc = "" }; _favPlaylist.songs = new List <PlaylistSong>(); _favPlaylist.songs.AddRange(levels.Where(x => PluginConfig.favoriteSongs.Contains(x.levelID)).Select(x => new PlaylistSong() { songName = $"{x.songName} {x.songSubName}", level = x, oneSaber = x.beatmapCharacteristics.Any(y => y.characteristicName == "One Saber"), path = "", key = "", levelId = x.levelID, hash = CustomHelpers.CheckHex(x.levelID.Substring(0, Math.Min(32, x.levelID.Length))) })); Logger.Log($"Created \"{_favPlaylist.playlistTitle}\" playlist with {_favPlaylist.songs.Count} songs!"); if (PlaylistsCollection.loadedPlaylists.Any(x => x.playlistTitle == "All songs" || x.playlistTitle == "Your favorite songs")) { PlaylistsCollection.loadedPlaylists.RemoveAll(x => x.playlistTitle == "All songs" || x.playlistTitle == "Your favorite songs"); } PlaylistsCollection.loadedPlaylists.Insert(0, _favPlaylist); PlaylistsCollection.loadedPlaylists.Insert(0, _allPlaylist); _favPlaylist.SavePlaylist("Playlists\\favorites.json"); }
public IEnumerator DownloadPlaylist(Playlist playlist) { PlaylistsCollection.MatchSongsForPlaylist(playlist, true); List <PlaylistSong> needToDownload = playlist.songs.Where(x => x.level == null).ToList(); Logger.Log($"Need to download {needToDownload.Count} songs"); _downloadingPlaylist = true; foreach (var item in needToDownload) { Song beatSaverSong = null; if (String.IsNullOrEmpty(playlist.customArchiveUrl)) { Logger.Log("Obtaining hash and url for " + item.key + ": " + item.songName); yield return(GetInfoForSong(playlist, item, (Song song) => { beatSaverSong = song; })); } else { string archiveUrl = playlist.customArchiveUrl.Replace("[KEY]", item.key); beatSaverSong = new Song() { songName = item.songName, id = item.key, downloadingProgress = 0f, hash = (item.levelId == null ? "" : item.levelId), downloadUrl = archiveUrl }; } if (beatSaverSong != null && !SongLoader.CustomLevels.Any(x => x.levelID.Substring(0, 32) == beatSaverSong.hash.ToUpper())) { _downloadQueueViewController.EnqueueSong(beatSaverSong, true); } } _downloadingPlaylist = false; }
private void DeletePressed() { IBeatmapLevel level = _detailViewController.selectedDifficultyBeatmap.level; _simpleDialog.Init("Delete song", $"Do you really want to delete \"{ level.songName} {level.songSubName}\"?", "Delete", "Cancel", (selectedButton) => { freePlayFlowCoordinator.InvokePrivateMethod("DismissViewController", new object[] { _simpleDialog, null, false }); if (selectedButton == 0) { try { var levelsTableView = _levelListViewController.GetPrivateField <LevelPackLevelsTableView>("_levelPackLevelsTableView"); List <IPreviewBeatmapLevel> levels = levelsTableView.GetPrivateField <IBeatmapLevelPack>("_pack").beatmapLevelCollection.beatmapLevels.ToList(); int selectedIndex = levels.FindIndex(x => x.levelID == _detailViewController.selectedDifficultyBeatmap.level.levelID); SongDownloader.Instance.DeleteSong(new Song(SongLoader.CustomLevels.First(x => x.levelID == _detailViewController.selectedDifficultyBeatmap.level.levelID))); if (selectedIndex > -1) { int removedLevels = levels.RemoveAll(x => x.levelID == _detailViewController.selectedDifficultyBeatmap.level.levelID); Logger.Log("Removed " + removedLevels + " level(s) from song list!"); _levelListViewController.SetData(CustomHelpers.GetLevelPackWithLevels(levels.Cast <BeatmapLevelSO>().ToArray(), lastPlaylist?.playlistTitle ?? "Custom Songs", lastPlaylist?.icon)); TableView listTableView = levelsTableView.GetPrivateField <TableView>("_tableView"); listTableView.ScrollToCellWithIdx(selectedIndex, TableView.ScrollPositionType.Beginning, false); levelsTableView.SetPrivateField("_selectedRow", selectedIndex); listTableView.SelectCellWithIdx(selectedIndex, true); } } catch (Exception e) { Logger.Error("Unable to delete song! Exception: " + e); } } }); freePlayFlowCoordinator.InvokePrivateMethod("PresentViewController", new object[] { _simpleDialog, null, false }); }
private IEnumerator VoteWithSteamID(bool upvote) { if (!SteamManager.Initialized) { Logger.Error($"SteamManager is not initialized!"); } _upvoteButton.interactable = false; _downvoteButton.interactable = false; Logger.Log($"Getting a ticket..."); var steamId = SteamUser.GetSteamID(); string authTicketHexString = ""; byte[] authTicket = new byte[1024]; var authTicketResult = SteamUser.GetAuthSessionTicket(authTicket, 1024, out var length); if (authTicketResult != HAuthTicket.Invalid) { var beginAuthSessionResult = SteamUser.BeginAuthSession(authTicket, (int)length, steamId); switch (beginAuthSessionResult) { case EBeginAuthSessionResult.k_EBeginAuthSessionResultOK: var result = SteamUser.UserHasLicenseForApp(steamId, new AppId_t(620980)); SteamUser.EndAuthSession(steamId); switch (result) { case EUserHasLicenseForAppResult.k_EUserHasLicenseResultDoesNotHaveLicense: _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "User does not\nhave license"; yield break; case EUserHasLicenseForAppResult.k_EUserHasLicenseResultHasLicense: if (SteamHelper.m_GetAuthSessionTicketResponse == null) { SteamHelper.m_GetAuthSessionTicketResponse = Callback <GetAuthSessionTicketResponse_t> .Create(OnAuthTicketResponse); } SteamHelper.lastTicket = SteamUser.GetAuthSessionTicket(authTicket, 1024, out length); if (SteamHelper.lastTicket != HAuthTicket.Invalid) { Array.Resize(ref authTicket, (int)length); authTicketHexString = BitConverter.ToString(authTicket).Replace("-", ""); } break; case EUserHasLicenseForAppResult.k_EUserHasLicenseResultNoAuth: _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "User is not\nauthenticated"; yield break; } break; default: _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Auth\nfailed"; yield break; } } Logger.Log("Waiting for Steam callback..."); float startTime = Time.time; yield return(new WaitWhile(() => { return SteamHelper.lastTicketResult != EResult.k_EResultOK && (Time.time - startTime) < 20f; })); if (SteamHelper.lastTicketResult != EResult.k_EResultOK) { Logger.Error($"Auth ticket callback timeout"); _upvoteButton.interactable = true; _downvoteButton.interactable = true; _ratingText.text = "Callback\ntimeout"; yield break; } SteamHelper.lastTicketResult = EResult.k_EResultRevoked; Logger.Log($"Voting..."); Dictionary <string, string> formData = new Dictionary <string, string> (); formData.Add("id", steamId.m_SteamID.ToString()); formData.Add("ticket", authTicketHexString); UnityWebRequest voteWWW = UnityWebRequest.Post($"{PluginConfig.beatsaverURL}/api/songs/voteById/{_lastBeatSaverSong.id}/{(upvote ? 1 : 0)}", formData); voteWWW.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded"); voteWWW.timeout = 30; yield return(voteWWW.SendWebRequest()); if (voteWWW.isNetworkError) { Logger.Error(voteWWW.error); _ratingText.text = voteWWW.error; } else { if (!_firstVote) { yield return(new WaitForSecondsRealtime(2f)); } _firstVote = false; switch (voteWWW.responseCode) { case 200: { JSONNode node = JSON.Parse(voteWWW.downloadHandler.text); _ratingText.text = (int.Parse(node["upVotes"]) - int.Parse(node["downVotes"])).ToString(); if (upvote) { _upvoteButton.interactable = false; _downvoteButton.interactable = true; } else { _downvoteButton.interactable = false; _upvoteButton.interactable = true; } if (!PluginConfig.votedSongs.ContainsKey(_lastLevel.levelID.Substring(0, 32))) { PluginConfig.votedSongs.Add(_lastLevel.levelID.Substring(0, 32), new SongVote(_lastBeatSaverSong.id, upvote ? VoteType.Upvote : VoteType.Downvote)); PluginConfig.SaveConfig(); } else if (PluginConfig.votedSongs[_lastLevel.levelID.Substring(0, 32)].voteType != (upvote ? VoteType.Upvote : VoteType.Downvote)) { PluginConfig.votedSongs[_lastLevel.levelID.Substring(0, 32)] = new SongVote(_lastBeatSaverSong.id, upvote ? VoteType.Upvote : VoteType.Downvote); PluginConfig.SaveConfig(); } }; break; case 500: { _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Steam API\nerror"; Logger.Error("Error: " + voteWWW.downloadHandler.text); }; break; case 401: { _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Invalid\nauth ticket"; Logger.Error("Error: " + voteWWW.downloadHandler.text); }; break; case 403: { _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Steam ID\nmismatch"; Logger.Error("Error: " + voteWWW.downloadHandler.text); }; break; case 400: { _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Bad\nrequest"; Logger.Error("Error: " + voteWWW.downloadHandler.text); }; break; default: { _upvoteButton.interactable = true; _downvoteButton.interactable = true; _ratingText.text = "Error\n" + voteWWW.responseCode; Logger.Error("Error: " + voteWWW.downloadHandler.text); }; break; } } }
private IEnumerator VoteWithAccessToken(bool upvote) { Logger.Log($"Voting..."); _upvoteButton.interactable = false; _downvoteButton.interactable = false; UnityWebRequest voteWWW = UnityWebRequest.Get($"{PluginConfig.beatsaverURL}/api/songs/vote/{_lastBeatSaverSong.id}/{(upvote ? 1 : 0)}/{PluginConfig.apiAccessToken}"); voteWWW.timeout = 30; yield return(voteWWW.SendWebRequest()); if (voteWWW.isNetworkError) { Logger.Error(voteWWW.error); _ratingText.text = voteWWW.error; } else { if (!_firstVote) { yield return(new WaitForSecondsRealtime(3f)); } _firstVote = false; switch (voteWWW.responseCode) { case 200: { JSONNode node = JSON.Parse(voteWWW.downloadHandler.text); _ratingText.text = (int.Parse(node["upVotes"]) - int.Parse(node["downVotes"])).ToString(); if (upvote) { _upvoteButton.interactable = false; _downvoteButton.interactable = true; } else { _downvoteButton.interactable = false; _upvoteButton.interactable = true; } if (!PluginConfig.votedSongs.ContainsKey(_lastLevel.levelID.Substring(0, 32))) { PluginConfig.votedSongs.Add(_lastLevel.levelID.Substring(0, 32), new SongVote(_lastBeatSaverSong.id, upvote ? VoteType.Upvote : VoteType.Downvote)); PluginConfig.SaveConfig(); } else if (PluginConfig.votedSongs[_lastLevel.levelID.Substring(0, 32)].voteType != (upvote ? VoteType.Upvote : VoteType.Downvote)) { PluginConfig.votedSongs[_lastLevel.levelID.Substring(0, 32)] = new SongVote(_lastBeatSaverSong.id, upvote ? VoteType.Upvote : VoteType.Downvote); PluginConfig.SaveConfig(); } }; break; case 403: { _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Read-only\ntoken"; }; break; case 401: { _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Token\nnot found"; }; break; case 400: { _upvoteButton.interactable = false; _downvoteButton.interactable = false; _ratingText.text = "Bad\ntoken"; }; break; default: { _upvoteButton.interactable = true; _downvoteButton.interactable = true; _ratingText.text = "Error\n" + voteWWW.responseCode; }; break; } } }
private void SceneManager_sceneLoaded(Scene to, LoadSceneMode loadMode) { Logger.Log($"Loaded scene \"{to.name}\""); }
private void SetupTweaks() { if (initialized || PluginConfig.disableSongListTweaks) { return; } Logger.Log("Setting up song list tweaks..."); _playlistsFlowCoordinator = (new GameObject("PlaylistsFlowCoordinator")).AddComponent <PlaylistsFlowCoordinator>(); _playlistsFlowCoordinator.didFinishEvent += _playlistsFlowCoordinator_didFinishEvent; _beatmapCharacteristics = Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSO>(); _lastCharacteristic = _beatmapCharacteristics.First(x => x.characteristicName == "Standard"); Resources.FindObjectsOfTypeAll <BeatmapCharacteristicSelectionViewController>().First().didSelectBeatmapCharacteristicEvent += (BeatmapCharacteristicSelectionViewController sender, BeatmapCharacteristicSO selected) => { _lastCharacteristic = selected; }; if (SongLoader.AreSongsLoaded) { _levelCollection = SongLoader.CustomLevelCollectionSO; } else { SongLoader.SongsLoadedEvent += (SongLoader sender, List <CustomLevel> levels) => { _levelCollection = SongLoader.CustomLevelCollectionSO; }; } _mainFlowCoordinator = Resources.FindObjectsOfTypeAll <MainFlowCoordinator>().FirstOrDefault(); _mainFlowCoordinator.GetPrivateField <MainMenuViewController>("_mainMenuViewController").didFinishEvent += SongListTweaks_didFinishEvent; _simpleDialog = ReflectionUtil.GetPrivateField <SimpleDialogPromptViewController>(_mainFlowCoordinator, "_simpleDialogPromptViewController"); _simpleDialog = Instantiate(_simpleDialog.gameObject, _simpleDialog.transform.parent).GetComponent <SimpleDialogPromptViewController>(); _difficultyViewController = Resources.FindObjectsOfTypeAll <BeatmapDifficultyViewController>().FirstOrDefault(); _difficultyViewController.didSelectDifficultyEvent += _difficultyViewController_didSelectDifficultyEvent; _levelListViewController = Resources.FindObjectsOfTypeAll <LevelListViewController>().FirstOrDefault(); _levelListViewController.didSelectLevelEvent += _levelListViewController_didSelectLevelEvent;; RectTransform _tableViewRectTransform = _levelListViewController.GetComponentsInChildren <RectTransform>().First(x => x.name == "TableViewContainer"); _tableViewRectTransform.sizeDelta = new Vector2(0f, -20f); _tableViewRectTransform.anchoredPosition = new Vector2(0f, -2.5f); RectTransform _pageUp = _tableViewRectTransform.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "PageUpButton"); _pageUp.anchoredPosition = new Vector2(0f, -1f); RectTransform _pageDown = _tableViewRectTransform.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "PageDownButton"); _pageDown.anchoredPosition = new Vector2(0f, 1f); _searchButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(-20f, 36.25f), new Vector2(20f, 6f), SearchPressed, "Search"); _searchButton.SetButtonTextSize(3f); _searchButton.ToggleWordWrapping(false); _sortByButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(0f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.SortBy); }, "Sort By"); _sortByButton.SetButtonTextSize(3f); _sortByButton.ToggleWordWrapping(false); _playlistsButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(20f, 36.25f), new Vector2(20f, 6f), PlaylistsButtonPressed, "Playlists"); _playlistsButton.SetButtonTextSize(3f); _playlistsButton.ToggleWordWrapping(false); _defButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(-20f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.Select); SetLevels(_lastCharacteristic, SortMode.Default, ""); }, "Default"); _defButton.SetButtonTextSize(3f); _defButton.ToggleWordWrapping(false); _defButton.gameObject.SetActive(false); _newButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(0f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.Select); SetLevels(_lastCharacteristic, SortMode.Newest, ""); }, "Newest"); _newButton.SetButtonTextSize(3f); _newButton.ToggleWordWrapping(false); _newButton.gameObject.SetActive(false); _authorButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(20f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.Select); SetLevels(_lastCharacteristic, SortMode.Difficulty, ""); }, "Difficulty"); _authorButton.SetButtonTextSize(3f); _authorButton.ToggleWordWrapping(false); _authorButton.gameObject.SetActive(false); _detailViewController = Resources.FindObjectsOfTypeAll <StandardLevelDetailViewController>().First(x => x.name == "StandardLevelDetailViewController"); RectTransform buttonsRect = _detailViewController.GetComponentsInChildren <RectTransform>().First(x => x.name == "Buttons"); buttonsRect.anchoredPosition = new Vector2(0f, 10.75f); RectTransform customButtonsRect = Instantiate(buttonsRect, buttonsRect.parent, true); Destroy(customButtonsRect.GetComponent <ContentSizeFitter>()); Destroy(customButtonsRect.GetComponent <HorizontalLayoutGroup>()); customButtonsRect.name = "CustomUIButtonsHolder"; customButtonsRect.anchoredPosition = new Vector2(0f, 1.25f); _favoriteButton = customButtonsRect.GetComponentsInChildren <Button>().First(x => x.name == "PracticeButton"); _favoriteButton.SetButtonIcon(Base64Sprites.AddToFavorites); _favoriteButton.onClick.AddListener(() => { if (PluginConfig.favoriteSongs.Any(x => x.Contains(_detailViewController.difficultyBeatmap.level.levelID))) { PluginConfig.favoriteSongs.Remove(_detailViewController.difficultyBeatmap.level.levelID); PluginConfig.SaveConfig(); _favoriteButton.SetButtonIcon(Base64Sprites.AddToFavorites); PlaylistsCollection.RemoveLevelFromPlaylist(PlaylistsCollection.loadedPlaylists.First(x => x.playlistTitle == "Your favorite songs"), _detailViewController.difficultyBeatmap.level.levelID); } else { PluginConfig.favoriteSongs.Add(_detailViewController.difficultyBeatmap.level.levelID); PluginConfig.SaveConfig(); _favoriteButton.SetButtonIcon(Base64Sprites.RemoveFromFavorites); PlaylistsCollection.AddSongToPlaylist(PlaylistsCollection.loadedPlaylists.First(x => x.playlistTitle == "Your favorite songs"), new PlaylistSong() { levelId = _detailViewController.difficultyBeatmap.level.levelID, songName = _detailViewController.difficultyBeatmap.level.songName, level = SongDownloader.GetLevel(_detailViewController.difficultyBeatmap.level.levelID) }); } }); _deleteButton = customButtonsRect.GetComponentsInChildren <Button>().First(x => x.name == "PlayButton"); _deleteButton.SetButtonText("Delete"); _deleteButton.ToggleWordWrapping(false); _deleteButton.onClick.AddListener(DeletePressed); _deleteButton.GetComponentsInChildren <RectTransform>().First(x => x.name == "GlowContainer").gameObject.SetActive(false); _deleteButton.interactable = !PluginConfig.disableDeleteButton; //based on https://github.com/halsafar/BeatSaberSongBrowser/blob/master/SongBrowserPlugin/UI/Browser/SongBrowserUI.cs#L192 var statsPanel = _detailViewController.GetComponentsInChildren <CanvasRenderer>(true).First(x => x.name == "LevelParamsPanel"); var statTransforms = statsPanel.GetComponentsInChildren <RectTransform>(); var valueTexts = statsPanel.GetComponentsInChildren <TextMeshProUGUI>().Where(x => x.name == "ValueText").ToList(); foreach (RectTransform r in statTransforms) { if (r.name == "Separator") { continue; } r.sizeDelta = new Vector2(r.sizeDelta.x * 0.85f, r.sizeDelta.y * 0.85f); } var _starStatTransform = Instantiate(statTransforms[1], statsPanel.transform, false); _starStatText = _starStatTransform.GetComponentInChildren <TextMeshProUGUI>(); _starStatTransform.GetComponentInChildren <UnityEngine.UI.Image>().sprite = Base64Sprites.StarFull; _starStatText.text = "--"; initialized = true; }
private void SceneManager_activeSceneChanged(Scene arg0, Scene arg1) { Logger.Log($"Active scene changed from \"{arg0.name}\" to \"{arg1.name}\""); }
private void SetupTweaks() { _mainFlowCoordinator = FindObjectOfType <MainFlowCoordinator>(); _mainFlowCoordinator.GetPrivateField <MainMenuViewController>("_mainMenuViewController").didFinishEvent += SongListTweaks_didFinishEvent; RectTransform viewControllersContainer = FindObjectsOfType <RectTransform>().First(x => x.name == "ViewControllers"); if (initialized || PluginConfig.disableSongListTweaks) { return; } Logger.Log("Setting up song list tweaks..."); try { var harmony = HarmonyInstance.Create("BeatSaverDownloaderHarmonyInstance"); harmony.PatchAll(Assembly.GetExecutingAssembly()); } catch (Exception e) { Logger.Log("Unable to patch level list! Exception: " + e); } _playlistsFlowCoordinator = new GameObject("PlaylistsFlowCoordinator").AddComponent <PlaylistsFlowCoordinator>(); _playlistsFlowCoordinator.didFinishEvent += _playlistsFlowCoordinator_didFinishEvent; if (SongLoader.AreSongsLoaded) { _levelCollection = SongLoader.CustomLevelCollectionSO; } else { SongLoader.SongsLoadedEvent += (SongLoader sender, List <CustomLevel> levels) => { _levelCollection = SongLoader.CustomLevelCollectionSO; }; } _simpleDialog = ReflectionUtil.GetPrivateField <SimpleDialogPromptViewController>(_mainFlowCoordinator, "_simpleDialogPromptViewController"); _simpleDialog = Instantiate(_simpleDialog.gameObject, _simpleDialog.transform.parent).GetComponent <SimpleDialogPromptViewController>(); _levelListViewController = viewControllersContainer.GetComponentInChildren <LevelPackLevelsViewController>(true); _levelListViewController.didSelectLevelEvent += _levelListViewController_didSelectLevelEvent; _levelPacksViewController = viewControllersContainer.GetComponentInChildren <LevelPacksViewController>(true); _levelPacksViewController.didSelectPackEvent += _levelPacksViewController_didSelectPackEvent; TableView _songSelectionTableView = _levelListViewController.GetComponentsInChildren <TableView>(true).First(); RectTransform _tableViewRectTransform = _levelListViewController.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "LevelsTableView"); _tableViewRectTransform.sizeDelta = new Vector2(0f, -20.5f); _tableViewRectTransform.anchoredPosition = new Vector2(0f, -2.5f); Button _pageUp = _tableViewRectTransform.GetComponentsInChildren <Button>(true).First(x => x.name == "PageUpButton"); (_pageUp.transform as RectTransform).anchoredPosition = new Vector2(0f, -1f); Button _pageDown = _tableViewRectTransform.GetComponentsInChildren <Button>(true).First(x => x.name == "PageDownButton"); (_pageDown.transform as RectTransform).anchoredPosition = new Vector2(0f, 1f); _fastPageUpButton = Instantiate(_pageUp, _tableViewRectTransform, false); (_fastPageUpButton.transform as RectTransform).anchorMin = new Vector2(0.5f, 1f); (_fastPageUpButton.transform as RectTransform).anchorMax = new Vector2(0.5f, 1f); (_fastPageUpButton.transform as RectTransform).anchoredPosition = new Vector2(-26f, 1f); (_fastPageUpButton.transform as RectTransform).sizeDelta = new Vector2(8f, 6f); _fastPageUpButton.GetComponentsInChildren <RectTransform>().First(x => x.name == "BG").sizeDelta = new Vector2(8f, 6f); _fastPageUpButton.GetComponentsInChildren <UnityEngine.UI.Image>().First(x => x.name == "Arrow").sprite = Sprites.DoubleArrow; _fastPageUpButton.onClick.AddListener(delegate() { FastScrollUp(_songSelectionTableView, PluginConfig.fastScrollSpeed); }); _fastPageDownButton = Instantiate(_pageDown, _tableViewRectTransform, false); (_fastPageDownButton.transform as RectTransform).anchorMin = new Vector2(0.5f, 0f); (_fastPageDownButton.transform as RectTransform).anchorMax = new Vector2(0.5f, 0f); (_fastPageDownButton.transform as RectTransform).anchoredPosition = new Vector2(-26f, -1f); (_fastPageDownButton.transform as RectTransform).sizeDelta = new Vector2(8f, 6f); _fastPageDownButton.GetComponentsInChildren <RectTransform>().First(x => x.name == "BG").sizeDelta = new Vector2(8f, 6f); _fastPageDownButton.GetComponentsInChildren <UnityEngine.UI.Image>().First(x => x.name == "Arrow").sprite = Sprites.DoubleArrow; _fastPageDownButton.onClick.AddListener(delegate() { FastScrollDown(_songSelectionTableView, PluginConfig.fastScrollSpeed); }); _randomButton = Instantiate(viewControllersContainer.GetComponentsInChildren <Button>(true).First(x => x.name == "PracticeButton"), _levelListViewController.rectTransform, false); _randomButton.onClick = new Button.ButtonClickedEvent(); _randomButton.onClick.AddListener(() => { int randomRow = UnityEngine.Random.Range(0, _songSelectionTableView.dataSource.NumberOfCells()); _songSelectionTableView.ScrollToCellWithIdx(randomRow, TableView.ScrollPositionType.Beginning, false); _songSelectionTableView.SelectCellWithIdx(randomRow, true); }); _randomButton.name = "CustomUIButton"; (_randomButton.transform as RectTransform).anchorMin = new Vector2(0.5f, 0.5f); (_randomButton.transform as RectTransform).anchorMax = new Vector2(0.5f, 0.5f); (_randomButton.transform as RectTransform).anchoredPosition = new Vector2(35f, 36.25f); (_randomButton.transform as RectTransform).sizeDelta = new Vector2(8.8f, 6f); _randomButton.SetButtonText(""); _randomButton.SetButtonIcon(Sprites.RandomIcon); _randomButton.GetComponentsInChildren <UnityEngine.UI.Image>().First(x => x.name == "Stroke").sprite = Resources.FindObjectsOfTypeAll <Sprite>().First(x => x.name == "RoundRectSmallStroke"); var _randomIconLayout = _randomButton.GetComponentsInChildren <HorizontalLayoutGroup>().First(x => x.name == "Content"); _randomIconLayout.padding = new RectOffset(0, 0, 0, 0); _searchButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(-20f, 36.25f), new Vector2(20f, 6f), SearchPressed, "Search"); _searchButton.SetButtonTextSize(3f); _searchButton.ToggleWordWrapping(false); _sortByButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(0f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.SortBy); }, "Sort By"); _sortByButton.SetButtonTextSize(3f); _sortByButton.ToggleWordWrapping(false); _playlistsButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(20f, 36.25f), new Vector2(20f, 6f), PlaylistsButtonPressed, "Playlists"); _playlistsButton.SetButtonTextSize(3f); _playlistsButton.ToggleWordWrapping(false); _defButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(-20f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.Select); SetLevels(SortMode.Default, ""); }, "Default"); _defButton.SetButtonTextSize(3f); _defButton.ToggleWordWrapping(false); _defButton.gameObject.SetActive(false); _newButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(0f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.Select); SetLevels(SortMode.Newest, ""); }, "Newest"); _newButton.SetButtonTextSize(3f); _newButton.ToggleWordWrapping(false); _newButton.gameObject.SetActive(false); _difficultyButton = _levelListViewController.CreateUIButton("CreditsButton", new Vector2(20f, 36.25f), new Vector2(20f, 6f), () => { SelectTopButtons(TopButtonsState.Select); SetLevels(SortMode.Difficulty, ""); }, "Difficulty"); _difficultyButton.SetButtonTextSize(3f); _difficultyButton.ToggleWordWrapping(false); _difficultyButton.gameObject.SetActive(false); _detailViewController = viewControllersContainer.GetComponentsInChildren <StandardLevelDetailViewController>(true).First(x => x.name == "LevelDetailViewController"); _detailViewController.didChangeDifficultyBeatmapEvent += _difficultyViewController_didSelectDifficultyEvent; RectTransform buttonsRect = _detailViewController.GetComponentsInChildren <RectTransform>(true).First(x => x.name == "PlayButtons"); _favoriteButton = Instantiate(viewControllersContainer.GetComponentsInChildren <Button>(true).First(x => x.name == "PracticeButton"), buttonsRect, false); _favoriteButton.onClick = new Button.ButtonClickedEvent(); _favoriteButton.onClick.AddListener(() => { if (PluginConfig.favoriteSongs.Any(x => x.Contains(_detailViewController.selectedDifficultyBeatmap.level.levelID))) { PluginConfig.favoriteSongs.Remove(_detailViewController.selectedDifficultyBeatmap.level.levelID); PluginConfig.SaveConfig(); _favoriteButton.SetButtonIcon(Sprites.AddToFavorites); PlaylistsCollection.RemoveLevelFromPlaylist(PlaylistsCollection.loadedPlaylists.First(x => x.playlistTitle == "Your favorite songs"), _detailViewController.selectedDifficultyBeatmap.level.levelID); } else { PluginConfig.favoriteSongs.Add(_detailViewController.selectedDifficultyBeatmap.level.levelID); PluginConfig.SaveConfig(); _favoriteButton.SetButtonIcon(Sprites.RemoveFromFavorites); PlaylistsCollection.AddSongToPlaylist(PlaylistsCollection.loadedPlaylists.First(x => x.playlistTitle == "Your favorite songs"), new PlaylistSong() { levelId = _detailViewController.selectedDifficultyBeatmap.level.levelID, songName = _detailViewController.selectedDifficultyBeatmap.level.songName, level = SongDownloader.GetLevel(_detailViewController.selectedDifficultyBeatmap.level.levelID) }); } }); _favoriteButton.name = "CustomUIButton"; _favoriteButton.SetButtonIcon(Sprites.AddToFavorites); (_favoriteButton.transform as RectTransform).sizeDelta = new Vector2(12f, 8.8f); var _favoriteIconLayout = _favoriteButton.GetComponentsInChildren <HorizontalLayoutGroup>().First(x => x.name == "Content"); _favoriteIconLayout.padding = new RectOffset(3, 3, 0, 0); _favoriteButton.transform.SetAsFirstSibling(); Button practiceButton = buttonsRect.GetComponentsInChildren <Button>().First(x => x.name == "PracticeButton"); (practiceButton.transform as RectTransform).sizeDelta = new Vector2(12f, 8.8f); var _practiceIconLayout = practiceButton.GetComponentsInChildren <HorizontalLayoutGroup>().First(x => x.name == "Content"); _practiceIconLayout.padding = new RectOffset(3, 3, 0, 0); _deleteButton = Instantiate(viewControllersContainer.GetComponentsInChildren <Button>(true).First(x => x.name == "PracticeButton"), buttonsRect, false); _deleteButton.onClick = new Button.ButtonClickedEvent(); _deleteButton.onClick.AddListener(DeletePressed); _deleteButton.name = "CustomUIButton"; _deleteButton.SetButtonIcon(Sprites.DeleteIcon); _deleteButton.interactable = !PluginConfig.disableDeleteButton; (_deleteButton.transform as RectTransform).sizeDelta = new Vector2(8.8f, 8.8f); _deleteButton.GetComponentsInChildren <UnityEngine.UI.Image>().First(x => x.name == "Stroke").sprite = Resources.FindObjectsOfTypeAll <Sprite>().First(x => x.name == "RoundRectSmallStroke"); var _deleteIconLayout = _deleteButton.GetComponentsInChildren <HorizontalLayoutGroup>().First(x => x.name == "Content"); _deleteIconLayout.padding = new RectOffset(0, 0, 1, 1); _deleteButton.transform.SetAsLastSibling(); //based on https://github.com/halsafar/BeatSaberSongBrowser/blob/master/SongBrowserPlugin/UI/Browser/SongBrowserUI.cs#L192 var statsPanel = _detailViewController.GetComponentsInChildren <LevelParamsPanel>(true).First(x => x.name == "LevelParamsPanel"); var statTransforms = statsPanel.GetComponentsInChildren <RectTransform>(true); var valueTexts = statsPanel.GetComponentsInChildren <TextMeshProUGUI>(true).Where(x => x.name == "ValueText").ToList(); foreach (RectTransform r in statTransforms) { if (r.name == "Separator") { continue; } r.sizeDelta = new Vector2(r.sizeDelta.x * 0.85f, r.sizeDelta.y * 0.85f); } var _starStatTransform = Instantiate(statTransforms[1], statsPanel.transform, false); _starStatText = _starStatTransform.GetComponentInChildren <TextMeshProUGUI>(true); _starStatTransform.GetComponentInChildren <UnityEngine.UI.Image>(true).sprite = Sprites.StarFull; _starStatText.text = "--"; ResultsViewController _standardLevelResultsViewController = viewControllersContainer.GetComponentsInChildren <ResultsViewController>(true).First(x => x.name == "StandardLevelResultsViewController"); _standardLevelResultsViewController.continueButtonPressedEvent += _standardLevelResultsViewController_continueButtonPressedEvent; initialized = true; }