public IEnumerator DownloadPlaylistFile(string url, Action <string> playlistDownloaded) { yield return(null); UnityWebRequest www = UnityWebRequest.Get(url); www.timeout = 15; yield return(www.SendWebRequest()); if (www.isNetworkError || www.isHttpError) { Logger.Error($"Unable to connect to BeastSaber playlist API! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); playlistDownloaded?.Invoke(null); } else { try { string docPath = Application.dataPath; docPath = docPath.Substring(0, docPath.Length - 5); docPath = docPath.Substring(0, docPath.LastIndexOf("/")); File.WriteAllText(docPath + "/Playlists/" + Path.GetFileName(www.uri.LocalPath), www.downloadHandler.text); playlistDownloaded?.Invoke(docPath + "/Playlists/" + Path.GetFileName(www.uri.LocalPath)); } catch (Exception e) { Logger.Exception("Unable to parse response! Exception: " + e); playlistDownloaded?.Invoke(null); } } }
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 GetRatingForSong(IBeatmapLevel level) { UnityWebRequest www = UnityWebRequest.Get($"{PluginConfig.beatsaverURL}/api/songs/search/hash/{level.levelID.Substring(0, 32)}"); yield return(www.SendWebRequest()); if (www.isNetworkError || www.isHttpError) { Logger.Error($"Unable to connect to {PluginConfig.beatsaverURL}! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); } else { try { _firstVote = true; JSONNode node = JSON.Parse(www.downloadHandler.text); _lastBeatSaverSong = Song.FromSearchNode(node["songs"][0]); _ratingText.text = (int.Parse(_lastBeatSaverSong.upvotes) - int.Parse(_lastBeatSaverSong.downvotes)).ToString(); _upvoteButton.interactable = (PluginConfig.apiAccessToken != PluginConfig.apiTokenPlaceholder); _downvoteButton.interactable = (PluginConfig.apiAccessToken != PluginConfig.apiTokenPlaceholder); } catch (Exception e) { Logger.Exception("Unable to get song rating! Excpetion: " + e); } } }
public IEnumerator GetInfoForSong(Playlist playlist, PlaylistSong song, Action <Song> songCallback) { string url = $"{PluginConfig.beatsaverURL}/api/songs/detail/{song.key}"; if (!string.IsNullOrEmpty(playlist.customDetailUrl)) { url = playlist.customDetailUrl + song.key; } UnityWebRequest www = UnityWebRequest.Get(url); www.timeout = 15; yield return(www.SendWebRequest()); if (www.isNetworkError || www.isHttpError) { Logger.Error($"Unable to connect to {PluginConfig.beatsaverURL}! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); } else { try { JSONNode node = JSON.Parse(www.downloadHandler.text); songCallback?.Invoke(new Song(node["song"])); } catch (Exception e) { Logger.Exception("Unable to parse response! Exception: " + e); } } }
protected override void DidActivate(bool firstActivation, ActivationType type) { if (firstActivation && type == ActivationType.AddedToHierarchy) { RemoveCustomUIElements(rectTransform); Destroy(GetComponentsInChildren <LevelParamsPanel>().First(x => x.name == "LevelParamsPanel").gameObject); RectTransform yourStats = GetComponentsInChildren <RectTransform>(true).First(x => x.name == "YourStats"); yourStats.gameObject.SetActive(true); RectTransform buttonsRect = GetComponentsInChildren <RectTransform>().First(x => x.name == "Buttons"); buttonsRect.anchoredPosition = new Vector2(0f, 6f); TextMeshProUGUI[] _textComponents = GetComponentsInChildren <TextMeshProUGUI>(); try { songNameText = _textComponents.First(x => x.name == "SongNameText"); _textComponents.First(x => x.name == "Title").text = "Playlist"; _textComponents.First(x => x.name == "YourStatsTitle").text = "Playlist Info"; _textComponents.First(x => x.name == "HighScoreText").text = "Author"; authorText = _textComponents.First(x => x.name == "HighScoreValueText"); authorText.rectTransform.sizeDelta = new Vector2(24f, 0f); _textComponents.First(x => x.name == "MaxComboText").text = "Total songs"; totalSongsText = _textComponents.First(x => x.name == "MaxComboValueText"); _textComponents.First(x => x.name == "MaxRankText").text = "Downloaded"; _textComponents.First(x => x.name == "MaxRankText").rectTransform.sizeDelta = new Vector2(18f, 3f); downloadedSongsText = _textComponents.First(x => x.name == "MaxRankValueText"); } catch (Exception e) { Logger.Exception("Unable to convert detail view controller! Exception: " + e); } _selectButton = GetComponentsInChildren <Button>().First(x => x.name == "PlayButton"); _selectButton.SetButtonText(_selectButtonText); _selectButton.onClick.RemoveAllListeners(); _selectButton.onClick.AddListener(() => { selectButtonPressed?.Invoke(_currentPlaylist); }); if (addDownloadButton) { _downloadButton = GetComponentsInChildren <Button>().First(x => x.name == "PracticeButton"); _downloadButton.GetComponentsInChildren <Image>().First(x => x.name == "Icon").sprite = Base64Sprites.DownloadIcon; _downloadButton.onClick.RemoveAllListeners(); _downloadButton.onClick.AddListener(() => { downloadButtonPressed?.Invoke(_currentPlaylist); }); } else { Destroy(GetComponentsInChildren <Button>().First(x => x.name == "PracticeButton").gameObject); } } }
private IEnumerator GetRatingForSong(IBeatmapLevel level) { UnityWebRequest www = UnityWebRequest.Get($"{PluginConfig.beatsaverURL}/api/songs/search/hash/{level.levelID.Substring(0, 32)}"); yield return(www.SendWebRequest()); if (www.isNetworkError || www.isHttpError) { Logger.Error($"Unable to connect to {PluginConfig.beatsaverURL}! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); } else { try { _firstVote = true; JSONNode node = JSON.Parse(www.downloadHandler.text); if (node["songs"].Count > 0) { _lastBeatSaverSong = Song.FromSearchNode(node["songs"][0]); _ratingText.text = (int.Parse(_lastBeatSaverSong.upvotes) - int.Parse(_lastBeatSaverSong.downvotes)).ToString(); bool canVote = (PluginConfig.apiAccessToken != PluginConfig.apiTokenPlaceholder || (VRPlatformHelper.instance.vrPlatformSDK == VRPlatformHelper.VRPlatformSDK.OpenVR || Environment.CommandLine.ToLower().Contains("-vrmode oculus") || Environment.CommandLine.ToLower().Contains("fpfc"))); _upvoteButton.interactable = canVote; _downvoteButton.interactable = canVote; _reviewButton.interactable = true; if (PluginConfig.votedSongs.ContainsKey(_lastLevel.levelID.Substring(0, 32))) { switch (PluginConfig.votedSongs[_lastLevel.levelID.Substring(0, 32)].voteType) { case VoteType.Upvote: { _upvoteButton.interactable = false; } break; case VoteType.Downvote: { _downvoteButton.interactable = false; } break; } } } else { Logger.Error("Song doesn't exist on BeatSaver!"); } } catch (Exception e) { Logger.Exception("Unable to get song rating! Excpetion: " + e); } } }
private void OnMenuSceneLoadedFresh() { try { PluginUI.Instance.OnLoad(); VotingUI.Instance.OnLoad(); SongListTweaks.Instance.OnLoad(); GetUserInfo.GetUserName(); } catch (Exception e) { Logger.Exception("Exception on fresh menu scene change: " + e); } }
public IEnumerator GetPlaylists() { yield return(null); _loadingIndicator.SetActive(true); _playlistsListViewController.SetContent(null); UnityWebRequest www = UnityWebRequest.Get(playlistAPI_URL); www.timeout = 15; yield return(www.SendWebRequest()); if (www.isNetworkError || www.isHttpError) { Logger.Error($"Unable to connect to BeastSaber playlist API! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); _loadingIndicator.SetActive(false); } else { try { JSONNode node = JSON.Parse(www.downloadHandler.text); playlists.Clear(); for (int i = 0; i < node.Count; i++) { playlists.Add(new Playlist(node[i])); } _loadingIndicator.SetActive(false); _playlistsListViewController.SetContent(playlists); } catch (Exception e) { Logger.Exception("Unable to parse response! Exception: " + e); _loadingIndicator.SetActive(false); } } }
public IEnumerator GetSearchResults(int page, string search) { yield return(null); _moreSongsListViewController.SetLoadingState(true); _moreSongsListViewController.TogglePageUpDownButtons((page > 0), true); _moreSongsListViewController.SetContent(null); UnityWebRequest www = UnityWebRequest.Get($"{PluginConfig.beatsaverURL}/api/songs/search/all/{search}"); www.timeout = 30; yield return(www.SendWebRequest()); if (www.isNetworkError || www.isHttpError) { Logger.Error($"Unable to connect to {PluginConfig.beatsaverURL}! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); } else { try { JSONNode node = JSON.Parse(www.downloadHandler.text); currentPageSongs.Clear(); for (int i = (page * songsPerPage); i < Math.Min(node["songs"].Count, ((page + 1) * songsPerPage)); i++) { currentPageSongs.Add(Song.FromSearchNode(node["songs"][i])); } _moreSongsListViewController.SetContent(currentPageSongs); } catch (Exception e) { Logger.Exception("Unable to parse response! Exception: " + e); } } _moreSongsListViewController.SetLoadingState(false); }
//Time - Downloads //BPM - Plays //Notes - BPM //Obstacles - Upvotes //Bombs - Downvotes protected override void DidActivate(bool firstActivation, ActivationType type) { if (firstActivation) { gameObject.SetActive(true); _levelDetails = GetComponentsInChildren <StandardLevelDetailView>(true).First(x => x.name == "LevelDetail"); _levelDetails.gameObject.SetActive(true); RemoveCustomUIElements(rectTransform); _levelParams = GetComponentsInChildren <LevelParamsPanel>().First(x => x.name == "LevelParamsPanel"); foreach (HoverHint hint in _levelParams.transform.GetComponentsInChildren <HoverHint>()) { switch (hint.name) { case "Time": { hint.GetComponentInChildren <Image>().sprite = Sprites.DownloadIcon; }; break; case "BPM": { hint.GetComponentInChildren <Image>().sprite = Sprites.PlayIcon; }; break; case "NotesCount": { hint.GetComponentInChildren <Image>().sprite = Resources.FindObjectsOfTypeAll <Sprite>().First(x => x.name == "MetronomeIcon"); }; break; case "ObstaclesCount": { hint.GetComponentInChildren <Image>().sprite = Sprites.ThumbUp; }; break; case "BombsCount": { hint.GetComponentInChildren <Image>().sprite = Sprites.ThumbDown; }; break; } Destroy(hint); } RectTransform yourStats = GetComponentsInChildren <RectTransform>().First(x => x.name == "Stats"); yourStats.gameObject.SetActive(true); TextMeshProUGUI[] _textComponents = GetComponentsInChildren <TextMeshProUGUI>(); try { songNameText = _textComponents.First(x => x.name == "SongNameText"); downloadsText = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "Time"); downloadsText.fontSize = 3f; playsText = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "BPM"); playsText.fontSize = 3f; _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxRank").text = "Expert/+"; difficulty1Text = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxRank"); _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "Highscore").text = "Hard"; difficulty2Text = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "Highscore"); _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxCombo").text = "Easy/Normal"; difficulty3Text = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxCombo"); } catch (Exception e) { Logger.Exception("Unable to convert detail view controller! Exception: " + e); } _downloadButton = _levelDetails.playButton; _downloadButton.SetButtonText("DOWNLOAD"); _downloadButton.ToggleWordWrapping(false); _downloadButton.onClick.RemoveAllListeners(); _downloadButton.onClick.AddListener(() => { downloadButtonPressed?.Invoke(_currentSong); }); (_downloadButton.transform as RectTransform).sizeDelta = new Vector2(26f, 8.8f); _favoriteButton = _levelDetails.practiceButton; _favoriteButton.SetButtonIcon(Sprites.AddToFavorites); _favoriteButton.onClick.RemoveAllListeners(); _favoriteButton.onClick.AddListener(() => { favoriteButtonPressed?.Invoke(_currentSong); }); coverImage = _levelDetails.GetPrivateField <Image>("_coverImage"); } }
protected override void DidActivate(bool firstActivation, ActivationType type) { if (firstActivation && type == ActivationType.AddedToHierarchy) { gameObject.SetActive(true); _levelDetails = GetComponentsInChildren <StandardLevelDetailView>(true).First(x => x.name == "LevelDetail"); _levelDetails.gameObject.SetActive(true); RemoveCustomUIElements(rectTransform); Destroy(GetComponentsInChildren <LevelParamsPanel>().First(x => x.name == "LevelParamsPanel").gameObject); RectTransform yourStats = GetComponentsInChildren <RectTransform>(true).First(x => x.name == "Stats"); yourStats.gameObject.SetActive(true); //RectTransform buttonsRect = GetComponentsInChildren<RectTransform>().First(x => x.name == "PlayButtons"); //buttonsRect.anchoredPosition = new Vector2(0f, 6f); TextMeshProUGUI[] _textComponents = GetComponentsInChildren <TextMeshProUGUI>(); try { songNameText = _textComponents.First(x => x.name == "SongNameText"); _textComponents.First(x => x.name == "Title").text = "Playlist"; _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxCombo").text = "Author"; authorText = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxCombo"); authorText.rectTransform.sizeDelta = new Vector2(24f, 0f); _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "Highscore").text = "Total songs"; totalSongsText = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "Highscore"); _textComponents.First(x => x.name == "Title" && x.transform.parent.name == "MaxRank").text = "Downloaded"; downloadedSongsText = _textComponents.First(x => x.name == "Value" && x.transform.parent.name == "MaxRank"); } catch (Exception e) { Logger.Exception("Unable to convert detail view controller! Exception: " + e); } _selectButton = _levelDetails.playButton; _selectButton.SetButtonText(_selectButtonText); _selectButton.ToggleWordWrapping(false); _selectButton.onClick.RemoveAllListeners(); _selectButton.onClick.AddListener(() => { selectButtonPressed?.Invoke(_currentPlaylist); }); if (addDownloadButton) { _downloadButton = _levelDetails.practiceButton; _downloadButton.SetButtonIcon(Sprites.DownloadIcon); _downloadButton.onClick.RemoveAllListeners(); _downloadButton.onClick.AddListener(() => { downloadButtonPressed?.Invoke(_currentPlaylist); }); } else { Destroy(_levelDetails.practiceButton.gameObject); } coverImage = _levelDetails.GetPrivateField <Image>("_coverImage"); } }
public Playlist(JSONNode playlistNode) { string image = playlistNode["image"].Value; if (!string.IsNullOrEmpty(image)) { try { icon = Base64Sprites.Base64ToSprite(image.Substring(image.IndexOf(",") + 1)); } catch { Logger.Exception("Unable to convert playlist image to sprite!"); icon = Base64Sprites.BeastSaberLogo; } } else { icon = Base64Sprites.BeastSaberLogo; } playlistTitle = playlistNode["playlistTitle"]; playlistAuthor = playlistNode["playlistAuthor"]; customDetailUrl = playlistNode["customDetailUrl"]; customArchiveUrl = playlistNode["customArchiveUrl"]; if (!string.IsNullOrEmpty(customDetailUrl)) { if (!customDetailUrl.EndsWith("/")) { customDetailUrl += "/"; } Logger.Log("Found playlist with customDetailUrl! Name: " + playlistTitle + ", CustomDetailUrl: " + customDetailUrl); } if (!string.IsNullOrEmpty(customArchiveUrl) && customArchiveUrl.Contains("[KEY]")) { Logger.Log("Found playlist with customArchiveUrl! Name: " + playlistTitle + ", CustomArchiveUrl: " + customArchiveUrl); } songs = new List <PlaylistSong>(); foreach (JSONNode node in playlistNode["songs"].AsArray) { PlaylistSong song = new PlaylistSong(); song.key = node["key"]; song.songName = node["songName"]; song.levelId = node["levelId"]; songs.Add(song); } if (playlistNode["playlistSongCount"] != null) { songCount = playlistNode["playlistSongCount"].AsInt; } if (playlistNode["fileLoc"] != null) { fileLoc = playlistNode["fileLoc"]; } if (playlistNode["playlistURL"] != null) { fileLoc = playlistNode["playlistURL"]; } }
public IEnumerator DownloadSongCoroutine(Song songInfo) { songInfo.songQueueState = SongQueueState.Downloading; UnityWebRequest www; bool timeout = false; float time = 0f; UnityWebRequestAsyncOperation asyncRequest; try { www = UnityWebRequest.Get(songInfo.downloadUrl); asyncRequest = www.SendWebRequest(); } catch (Exception e) { Logger.Error(e); songInfo.songQueueState = SongQueueState.Error; songInfo.downloadingProgress = 1f; yield break; } while ((!asyncRequest.isDone || songInfo.downloadingProgress != 1f) && songInfo.songQueueState != SongQueueState.Error) { yield return(null); time += Time.deltaTime; if ((time >= 5f && asyncRequest.progress == 0f) || songInfo.songQueueState == SongQueueState.Error) { www.Abort(); timeout = true; Logger.Error("Connection timed out!"); } songInfo.downloadingProgress = asyncRequest.progress; } if (www.isNetworkError || www.isHttpError || timeout || songInfo.songQueueState == SongQueueState.Error) { songInfo.songQueueState = SongQueueState.Error; Logger.Error("Unable to download song! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); } else { Logger.Log("Received response from BeatSaver.com..."); string docPath = ""; string customSongsPath = ""; byte[] data = www.downloadHandler.data; Stream zipStream = null; try { docPath = Application.dataPath; docPath = docPath.Substring(0, docPath.Length - 5); docPath = docPath.Substring(0, docPath.LastIndexOf("/")); customSongsPath = docPath + "/CustomSongs/" + songInfo.id + "/"; if (!Directory.Exists(customSongsPath)) { Directory.CreateDirectory(customSongsPath); } zipStream = new MemoryStream(data); Logger.Log("Downloaded zip!"); } catch (Exception e) { Logger.Exception(e); songInfo.songQueueState = SongQueueState.Error; yield break; } yield return(new WaitWhile(() => _extractingZip)); //because extracting several songs at once sometimes hangs the game Task extract = ExtractZipAsync(songInfo, zipStream, customSongsPath); yield return(new WaitWhile(() => !extract.IsCompleted)); songDownloaded?.Invoke(songInfo); } }
public static void ReloadPlaylists(bool fullRefresh = true) { try { List <string> playlistFiles = new List <string>(); if (PluginConfig.beatDropInstalled) { string[] beatDropJSONPlaylists = Directory.GetFiles(Path.Combine(PluginConfig.beatDropPlaylistsLocation, "playlists"), "*.json"); string[] beatDropBPLISTPlaylists = Directory.GetFiles(Path.Combine(PluginConfig.beatDropPlaylistsLocation, "playlists"), "*.bplist"); playlistFiles.AddRange(beatDropJSONPlaylists); playlistFiles.AddRange(beatDropBPLISTPlaylists); Logger.Log($"Found {beatDropJSONPlaylists.Length + beatDropBPLISTPlaylists.Length} playlists in BeatDrop folder"); } string[] localJSONPlaylists = Directory.GetFiles(Path.Combine(Environment.CurrentDirectory, "Playlists"), "*.json"); string[] localBPLISTPlaylists = Directory.GetFiles(Path.Combine(Environment.CurrentDirectory, "Playlists"), "*.bplist"); playlistFiles.AddRange(localJSONPlaylists); playlistFiles.AddRange(localBPLISTPlaylists); Logger.Log($"Found {localJSONPlaylists.Length + localBPLISTPlaylists.Length} playlists in Playlists folder"); if (fullRefresh) { loadedPlaylists.Clear(); foreach (string path in playlistFiles) { try { Playlist playlist = Playlist.LoadPlaylist(path); if (Path.GetFileName(path) == "favorites.json" && playlist.playlistTitle == "Your favorite songs") { continue; } loadedPlaylists.Add(playlist); Logger.Log($"Found \"{playlist.playlistTitle}\" by {playlist.playlistAuthor}"); } catch (Exception e) { Logger.Log($"Unable to parse playlist @ {path}! Exception: {e}"); } } } else { foreach (string path in playlistFiles) { if (!loadedPlaylists.Any(x => x.fileLoc == path)) { Logger.Log("Found new playlist! Path: " + path); try { Playlist playlist = Playlist.LoadPlaylist(path); if (Path.GetFileName(path) == "favorites.json" && playlist.playlistTitle == "Your favorite songs") { continue; } loadedPlaylists.Add(playlist); Logger.Log($"Found \"{playlist.playlistTitle}\" by {playlist.playlistAuthor}"); if (SongLoader.AreSongsLoaded) { MatchSongsForPlaylist(playlist); } } catch (Exception e) { Logger.Log($"Unable to parse playlist @ {path}! Exception: {e}"); } } } } } catch (Exception e) { Logger.Exception("Unable to load playlists! Exception: " + e); } }
//Time - Downloads //BPM - Plays //Notes - BPM //Obstacles - Upvotes //Bombs - Downvotes protected override void DidActivate(bool firstActivation, ActivationType type) { if (firstActivation && type == ActivationType.AddedToHierarchy) { RemoveCustomUIElements(rectTransform); _levelDetails = GetComponentsInChildren <LevelParamsPanel>().First(x => x.name == "LevelParamsPanel"); foreach (HoverHint hint in _levelDetails.transform.GetComponentsInChildren <HoverHint>()) { switch (hint.name) { case "Time": { hint.GetComponentInChildren <Image>().sprite = Base64Sprites.DownloadIcon; }; break; case "BPM": { hint.GetComponentInChildren <Image>().sprite = Base64Sprites.PlayIcon; }; break; case "NotesCount": { hint.GetComponentInChildren <Image>().sprite = Resources.FindObjectsOfTypeAll <Sprite>().First(x => x.name == "MetronomeIcon"); }; break; case "ObstaclesCount": { hint.GetComponentInChildren <Image>().sprite = Base64Sprites.ThumbUp; }; break; case "BombsCount": { hint.GetComponentInChildren <Image>().sprite = Base64Sprites.ThumbDown; }; break; } Destroy(hint); } RectTransform yourStats = GetComponentsInChildren <RectTransform>(true).First(x => x.name == "YourStats"); yourStats.gameObject.SetActive(true); RectTransform buttonsRect = GetComponentsInChildren <RectTransform>().First(x => x.name == "Buttons"); buttonsRect.anchoredPosition = new Vector2(0f, 6f); TextMeshProUGUI[] _textComponents = GetComponentsInChildren <TextMeshProUGUI>(); try { songNameText = _textComponents.First(x => x.name == "SongNameText"); downloadsText = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "Time"); downloadsText.fontSize = 3f; playsText = _textComponents.First(x => x.name == "ValueText" && x.transform.parent.name == "BPM"); playsText.fontSize = 3f; _textComponents.First(x => x.name == "YourStatsTitle").text = "Difficulties"; _textComponents.First(x => x.name == "HighScoreText").text = "Expert/+"; difficulty1Text = _textComponents.First(x => x.name == "HighScoreValueText"); _textComponents.First(x => x.name == "MaxComboText").text = "Hard"; difficulty2Text = _textComponents.First(x => x.name == "MaxComboValueText"); _textComponents.First(x => x.name == "MaxRankText").text = "Easy/Normal"; _textComponents.First(x => x.name == "MaxRankText").rectTransform.sizeDelta = new Vector2(18f, 3f); difficulty3Text = _textComponents.First(x => x.name == "MaxRankValueText"); } catch (Exception e) { Logger.Exception("Unable to convert detail view controller! Exception: " + e); } _downloadButton = GetComponentsInChildren <Button>().First(x => x.name == "PlayButton"); _downloadButton.GetComponentsInChildren <TextMeshProUGUI>().First().text = "DOWNLOAD"; _downloadButton.onClick.RemoveAllListeners(); _downloadButton.onClick.AddListener(() => { downloadButtonPressed?.Invoke(_currentSong); }); _favoriteButton = GetComponentsInChildren <Button>().First(x => x.name == "PracticeButton"); _favoriteButton.GetComponentsInChildren <Image>().First(x => x.name == "Icon").sprite = Base64Sprites.AddToFavorites; _favoriteButton.onClick.RemoveAllListeners(); _favoriteButton.onClick.AddListener(() => { favoriteButtonPressed?.Invoke(_currentSong); }); } }
public IEnumerator GetInfoForSong(Playlist playlist, PlaylistSong song, Action <Song> songCallback) { string url = ""; bool _usingHash = false; if (!string.IsNullOrEmpty(song.key)) { url = $"{PluginConfig.beatsaverURL}/api/songs/detail/{song.key}"; if (!string.IsNullOrEmpty(playlist.customDetailUrl)) { url = playlist.customDetailUrl + song.key; } } else if (!string.IsNullOrEmpty(song.hash)) { url = $"{PluginConfig.beatsaverURL}/api/songs/search/hash/{song.hash}"; _usingHash = true; } else if (!string.IsNullOrEmpty(song.levelId)) { string hash = CustomHelpers.CheckHex(song.levelId.Substring(0, Math.Min(32, song.levelId.Length))); url = $"{PluginConfig.beatsaverURL}/api/songs/search/hash/{hash}"; _usingHash = true; } else { yield break; } UnityWebRequest www = UnityWebRequest.Get(url); www.timeout = 15; yield return(www.SendWebRequest()); if (www.isNetworkError || www.isHttpError) { Logger.Error($"Unable to connect to {PluginConfig.beatsaverURL}! " + (www.isNetworkError ? $"Network error: {www.error}" : (www.isHttpError ? $"HTTP error: {www.error}" : "Unknown error"))); } else { try { JSONNode node = JSON.Parse(www.downloadHandler.text); if (_usingHash) { if (node["songs"].Count == 0) { Logger.Error($"Song {song.songName} doesn't exist on BeatSaver!"); songCallback?.Invoke(null); yield break; } songCallback?.Invoke(Song.FromSearchNode(node["songs"][0])); } else { songCallback?.Invoke(new Song(node["song"])); } } catch (Exception e) { Logger.Exception("Unable to parse response! Exception: " + e); } } }
static TableCell Postfix(TableCell __result, LevelPackLevelsTableView __instance, int row) { try { if (!PluginConfig.enableSongIcons) { return(__result); } bool showHeader = __instance.GetPrivateField <bool>("_showLevelPackHeader"); if (row == 0 && showHeader) { return(__result); } string levelId = __instance.GetPrivateField <IBeatmapLevelPack>("_pack").beatmapLevelCollection.beatmapLevels[(showHeader ? (row - 1) : row)].levelID; levelId = levelId.Substring(0, Math.Min(32, levelId.Length)); UnityEngine.UI.Image icon = null; UnityEngine.UI.Image[] levelIcons = __result.GetPrivateField <UnityEngine.UI.Image[]>("_beatmapCharacteristicImages"); float[] levelIconAlphas = __result.GetPrivateField <float[]>("_beatmapCharacteristicAlphas"); if (levelIcons.Any(x => x.name == "LevelTypeIconExtra")) { icon = levelIcons.First(x => x.name == "LevelTypeIconExtra"); } else { icon = GameObject.Instantiate(__result.GetComponentsInChildren <UnityEngine.UI.Image>().First(x => x.name == "LevelTypeIcon0"), __result.transform, true); (icon.transform as RectTransform).anchoredPosition = new Vector2(-14.5f, 0f); icon.transform.name = "LevelTypeIconExtra"; levelIcons = levelIcons.AddToArray(icon); __result.SetPrivateField("_beatmapCharacteristicImages", levelIcons); levelIconAlphas = levelIconAlphas.AddToArray(0.1f); __result.SetPrivateField("_beatmapCharacteristicAlphas", levelIconAlphas); foreach (var levelIcon in levelIcons) { levelIcon.rectTransform.anchoredPosition = new Vector2(levelIcon.rectTransform.anchoredPosition.x, -2f); } } if (PluginConfig.favoriteSongs.Any(x => x.StartsWith(levelId))) { levelIconAlphas[3] = 1f; icon.sprite = Sprites.StarFull; } else if (PluginConfig.votedSongs.ContainsKey(levelId)) { switch (PluginConfig.votedSongs[levelId].voteType) { case VoteType.Upvote: { levelIconAlphas[3] = 1f; icon.sprite = Sprites.ThumbUp; } break; case VoteType.Downvote: { levelIconAlphas[3] = 1f; icon.sprite = Sprites.ThumbDown; } break; } } else { levelIconAlphas[3] = 0.1f; icon.sprite = Sprites.StarFull; } } catch (Exception e) { Logger.Exception("Unable to create extra icon! Exception: " + e); } return(__result); }