SongBrowserApplication.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. using SongBrowser.UI;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Concurrent;
  5. using System.Linq;
  6. using UnityEngine;
  7. using UnityEngine.UI;
  8. using Logger = SongBrowser.Logging.Logger;
  9. namespace SongBrowser
  10. {
  11. public class SongBrowserApplication : MonoBehaviour
  12. {
  13. public static SongBrowserApplication Instance;
  14. // Song Browser UI Elements
  15. private SongBrowserUI _songBrowserUI;
  16. private SongBrowserModel _songBrowserModel;
  17. public static SongBrowser.UI.ProgressBar MainProgressBar;
  18. private bool _hasShownProgressBar = false;
  19. public SongBrowserModel Model
  20. {
  21. get
  22. {
  23. return _songBrowserModel;
  24. }
  25. }
  26. /// <summary>
  27. /// Load the main song browser app.
  28. /// </summary>
  29. internal static void OnLoad()
  30. {
  31. if (Instance != null)
  32. {
  33. return;
  34. }
  35. new GameObject("Beat Saber SongBrowser Plugin").AddComponent<SongBrowserApplication>();
  36. SongBrowserApplication.MainProgressBar = SongBrowser.UI.ProgressBar.Create();
  37. Plugin.Log.Info("SongBrowser Plugin OnLoad Complete");
  38. }
  39. /// <summary>
  40. /// It has awaken!
  41. /// </summary>
  42. private void Awake()
  43. {
  44. Logger.Trace("Awake-SongBrowserApplication()");
  45. Instance = this;
  46. // Init Model, load settings
  47. _songBrowserModel = new SongBrowserModel();
  48. _songBrowserModel.Init();
  49. // Init browser UI
  50. _songBrowserUI = gameObject.AddComponent<SongBrowserUI>();
  51. _songBrowserUI.Model = _songBrowserModel;
  52. }
  53. /// <summary>
  54. /// Acquire any UI elements from Beat saber that we need. Wait for the song list to be loaded.
  55. /// </summary>
  56. public void Start()
  57. {
  58. Logger.Trace("Start-SongBrowserApplication()");
  59. InstallHandlers();
  60. SongDataCore.Plugin.Songs.OnDataFinishedProcessing += OnScoreSaberDataDownloaded;
  61. if (SongCore.Loader.AreSongsLoaded)
  62. {
  63. OnSongLoaderLoadedSongs(null, SongCore.Loader.CustomLevels);
  64. }
  65. else
  66. {
  67. SongCore.Loader.SongsLoadedEvent += OnSongLoaderLoadedSongs;
  68. }
  69. // Useful to dump game objects.
  70. /*foreach (RectTransform rect in Resources.FindObjectsOfTypeAll<RectTransform>())
  71. {
  72. Logger.Debug("RectTransform: {0}", rect.name);
  73. }*/
  74. /*foreach (Sprite sprite in Resources.FindObjectsOfTypeAll<Sprite>())
  75. {
  76. Logger.Debug("Adding Icon: {0}", sprite.name);
  77. }*/
  78. }
  79. /// <summary>
  80. /// Only gets called once during boot of BeatSaber.
  81. /// </summary>
  82. /// <param name="loader"></param>
  83. /// <param name="levels"></param>
  84. private void OnSongLoaderLoadedSongs(SongCore.Loader loader, ConcurrentDictionary<string, CustomPreviewBeatmapLevel> levels)
  85. {
  86. Logger.Trace("OnSongLoaderLoadedSongs-SongBrowserApplication()");
  87. try
  88. {
  89. _songBrowserUI.UpdateLevelDataModel();
  90. _songBrowserUI.RefreshSongList();
  91. }
  92. catch (Exception e)
  93. {
  94. Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e);
  95. }
  96. }
  97. /// <summary>
  98. /// Inform browser score saber data is available.
  99. /// </summary>
  100. /// <param name="loader"></param>
  101. /// <param name="levels"></param>
  102. private void OnScoreSaberDataDownloaded()
  103. {
  104. Logger.Trace("OnScoreSaberDataDownloaded");
  105. try
  106. {
  107. // It is okay if SongDataCore beats us to initialization
  108. if (_songBrowserUI == null)
  109. {
  110. return;
  111. }
  112. StartCoroutine(_songBrowserUI.AsyncWaitForSongUIUpdate());
  113. }
  114. catch (Exception e)
  115. {
  116. Logger.Exception("Exception during OnScoreSaberDataDownloaded: ", e);
  117. }
  118. }
  119. /// <summary>
  120. /// Install Our Handlers so we can react to ingame events.
  121. /// </summary>
  122. private void InstallHandlers()
  123. {
  124. // Append our own event to appropriate events so we can refresh the song list before the user sees it.
  125. MainFlowCoordinator mainFlow = Resources.FindObjectsOfTypeAll<MainFlowCoordinator>().First();
  126. Button soloFreePlayButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "SoloButton");
  127. Button partyFreePlayButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "PartyButton");
  128. Button campaignButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "CampaignButton");
  129. soloFreePlayButton.onClick.AddListener(HandleSoloModeSelection);
  130. partyFreePlayButton.onClick.AddListener(HandlePartyModeSelection);
  131. campaignButton.onClick.AddListener(HandleCampaignModeSelection);
  132. }
  133. /// <summary>
  134. /// Handle Solo Mode
  135. /// </summary>
  136. /// <param name="arg1"></param>
  137. /// <param name="arg2"></param>
  138. private void HandleSoloModeSelection()
  139. {
  140. Logger.Trace("HandleSoloModeSelection()");
  141. HandleModeSelection(MainMenuViewController.MenuButton.SoloFreePlay);
  142. _songBrowserUI.Show();
  143. }
  144. /// <summary>
  145. /// Handle Party Mode
  146. /// </summary>
  147. /// <param name="arg1"></param>
  148. /// <param name="arg2"></param>
  149. private void HandlePartyModeSelection()
  150. {
  151. Logger.Trace("HandlePartyModeSelection()");
  152. HandleModeSelection(MainMenuViewController.MenuButton.Party);
  153. _songBrowserUI.Show();
  154. }
  155. /// <summary>
  156. /// Handle Party Mode
  157. /// </summary>
  158. /// <param name="arg1"></param>
  159. /// <param name="arg2"></param>
  160. private void HandleCampaignModeSelection()
  161. {
  162. Logger.Trace("HandleCampaignModeSelection()");
  163. HandleModeSelection(MainMenuViewController.MenuButton.SoloCampaign);
  164. _songBrowserUI.Hide();
  165. }
  166. /// <summary>
  167. /// Handle Mode
  168. /// </summary>
  169. /// <param name="arg1"></param>
  170. /// <param name="arg2"></param>
  171. private void HandleModeSelection(MainMenuViewController.MenuButton mode)
  172. {
  173. Logger.Trace("HandleModeSelection()");
  174. _songBrowserUI.CreateUI(mode);
  175. if (!_hasShownProgressBar)
  176. {
  177. SongBrowserApplication.MainProgressBar.ShowMessage("");
  178. _hasShownProgressBar = true;
  179. }
  180. StartCoroutine(UpdateBrowserUI());
  181. }
  182. /// <summary>
  183. /// Wait until the end of the frame to finish updating everything.
  184. /// </summary>
  185. /// <returns></returns>
  186. public IEnumerator UpdateBrowserUI()
  187. {
  188. yield return new WaitForEndOfFrame();
  189. _songBrowserUI.UpdateLevelDataModel();
  190. _songBrowserUI.UpdateLevelCollectionSelection();
  191. _songBrowserUI.RefreshSongList();
  192. }
  193. }
  194. }