using SongBrowser.UI; using System; using System.Collections; using System.Collections.Concurrent; using System.Linq; using UnityEngine; using UnityEngine.UI; using Logger = SongBrowser.Logging.Logger; namespace SongBrowser { public class SongBrowserApplication : MonoBehaviour { public static SongBrowserApplication Instance; // Song Browser UI Elements private SongBrowserUI _songBrowserUI; private SongBrowserModel _songBrowserModel; public static SongBrowser.UI.ProgressBar MainProgressBar; private bool _hasShownProgressBar = false; public SongBrowserModel Model { get { return _songBrowserModel; } } /// /// Load the main song browser app. /// internal static void OnLoad() { if (Instance != null) { return; } new GameObject("Beat Saber SongBrowser Plugin").AddComponent(); SongBrowserApplication.MainProgressBar = SongBrowser.UI.ProgressBar.Create(); Plugin.Log.Info("SongBrowser Plugin OnLoad Complete"); } /// /// It has awaken! /// private void Awake() { Logger.Trace("Awake-SongBrowserApplication()"); Instance = this; // Init Model, load settings _songBrowserModel = new SongBrowserModel(); _songBrowserModel.Init(); // Init browser UI _songBrowserUI = gameObject.AddComponent(); _songBrowserUI.Model = _songBrowserModel; } /// /// Acquire any UI elements from Beat saber that we need. Wait for the song list to be loaded. /// public void Start() { Logger.Trace("Start-SongBrowserApplication()"); InstallHandlers(); SongDataCore.Plugin.Songs.OnDataFinishedProcessing += OnScoreSaberDataDownloaded; if (SongCore.Loader.AreSongsLoaded) { OnSongLoaderLoadedSongs(null, SongCore.Loader.CustomLevels); } else { SongCore.Loader.SongsLoadedEvent += OnSongLoaderLoadedSongs; } // Useful to dump game objects. /*foreach (RectTransform rect in Resources.FindObjectsOfTypeAll()) { Logger.Debug("RectTransform: {0}", rect.name); }*/ /*foreach (Sprite sprite in Resources.FindObjectsOfTypeAll()) { Logger.Debug("Adding Icon: {0}", sprite.name); }*/ } /// /// Only gets called once during boot of BeatSaber. /// /// /// private void OnSongLoaderLoadedSongs(SongCore.Loader loader, ConcurrentDictionary levels) { Logger.Trace("OnSongLoaderLoadedSongs-SongBrowserApplication()"); try { _songBrowserUI.UpdateLevelDataModel(); _songBrowserUI.RefreshSongList(); } catch (Exception e) { Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e); } } /// /// Inform browser score saber data is available. /// /// /// private void OnScoreSaberDataDownloaded() { Logger.Trace("OnScoreSaberDataDownloaded"); try { // It is okay if SongDataCore beats us to initialization if (_songBrowserUI == null) { return; } StartCoroutine(_songBrowserUI.AsyncWaitForSongUIUpdate()); } catch (Exception e) { Logger.Exception("Exception during OnScoreSaberDataDownloaded: ", e); } } /// /// Install Our Handlers so we can react to ingame events. /// private void InstallHandlers() { // Append our own event to appropriate events so we can refresh the song list before the user sees it. MainFlowCoordinator mainFlow = Resources.FindObjectsOfTypeAll().First(); Button soloFreePlayButton = Resources.FindObjectsOfTypeAll