SongBrowserApplication.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. using SongBrowser.DataAccess;
  2. using SongBrowser.UI;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using UnityEngine;
  8. using UnityEngine.UI;
  9. using Logger = SongBrowser.Logging.Logger;
  10. namespace SongBrowser
  11. {
  12. public class SongBrowserApplication : MonoBehaviour
  13. {
  14. public static SongBrowserApplication Instance;
  15. // Song Browser UI Elements
  16. private SongBrowserUI _songBrowserUI;
  17. private SongBrowserModel _songBrowserModel;
  18. public static SongBrowser.UI.ProgressBar MainProgressBar;
  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. Console.WriteLine("SongBrowser Plugin Loaded()");
  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.ScoreSaber.OnDataFinishedProcessing += OnScoreSaberDataDownloaded;
  61. SongDataCore.Plugin.BeatSaver.OnDataFinishedProcessing += OnBeatSaverDataDownloaded;
  62. if (SongCore.Loader.AreSongsLoaded)
  63. {
  64. OnSongLoaderLoadedSongs(null, SongCore.Loader.CustomLevels);
  65. }
  66. else
  67. {
  68. SongCore.Loader.SongsLoadedEvent += OnSongLoaderLoadedSongs;
  69. }
  70. // Useful to dump game objects.
  71. /*foreach (RectTransform rect in Resources.FindObjectsOfTypeAll<RectTransform>())
  72. {
  73. Logger.Debug("RectTransform: {0}", rect.name);
  74. }*/
  75. /*foreach (Sprite sprite in Resources.FindObjectsOfTypeAll<Sprite>())
  76. {
  77. Logger.Debug("Adding Icon: {0}", sprite.name);
  78. }*/
  79. }
  80. /// <summary>
  81. /// Only gets called once during boot of BeatSaber.
  82. /// </summary>
  83. /// <param name="loader"></param>
  84. /// <param name="levels"></param>
  85. private void OnSongLoaderLoadedSongs(SongCore.Loader loader, Dictionary<string, CustomPreviewBeatmapLevel> levels)
  86. {
  87. Logger.Trace("OnSongLoaderLoadedSongs-SongBrowserApplication()");
  88. try
  89. {
  90. _songBrowserUI.UpdateLevelDataModel();
  91. _songBrowserUI.RefreshSongList();
  92. }
  93. catch (Exception e)
  94. {
  95. Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e);
  96. }
  97. }
  98. /// <summary>
  99. /// Inform browser score saber data is available.
  100. /// </summary>
  101. /// <param name="loader"></param>
  102. /// <param name="levels"></param>
  103. private void OnScoreSaberDataDownloaded()
  104. {
  105. Logger.Trace("OnScoreSaberDataDownloaded");
  106. try
  107. {
  108. if (_songBrowserModel.Settings.sortMode.NeedsScoreSaberData())
  109. {
  110. _songBrowserUI.ProcessSongList();
  111. _songBrowserUI.RefreshSongUI();
  112. }
  113. else
  114. {
  115. _songBrowserUI.RefreshSortButtonUI();
  116. }
  117. }
  118. catch (Exception e)
  119. {
  120. Logger.Exception("Exception during OnScoreSaberDataDownloaded: ", e);
  121. }
  122. }
  123. /// <summary>
  124. /// Update mapping of scrapped song data.
  125. /// </summary>
  126. private void OnBeatSaverDataDownloaded()
  127. {
  128. Logger.Trace("OnBeatSaverDataDownloaded");
  129. try
  130. {
  131. if (_songBrowserModel.Settings.sortMode.NeedsBeatSaverData())
  132. {
  133. _songBrowserUI.ProcessSongList();
  134. _songBrowserUI.RefreshSongUI();
  135. }
  136. else
  137. {
  138. _songBrowserUI.RefreshSortButtonUI();
  139. }
  140. }
  141. catch (Exception e)
  142. {
  143. Logger.Exception("Exception during OnDownloaderScrappedDataDownloaded: ", e);
  144. }
  145. }
  146. /// <summary>
  147. /// Install Our Handlers so we can react to ingame events.
  148. /// </summary>
  149. private void InstallHandlers()
  150. {
  151. // Append our own event to appropriate events so we can refresh the song list before the user sees it.
  152. MainFlowCoordinator mainFlow = Resources.FindObjectsOfTypeAll<MainFlowCoordinator>().First();
  153. Button soloFreePlayButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "SoloFreePlayButton");
  154. Button partyFreePlayButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "PartyFreePlayButton");
  155. Button campaignButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "CampaignButton");
  156. soloFreePlayButton.onClick.AddListener(HandleSoloModeSelection);
  157. partyFreePlayButton.onClick.AddListener(HandlePartyModeSelection);
  158. campaignButton.onClick.AddListener(HandleCampaignModeSelection);
  159. }
  160. /// <summary>
  161. /// Handle Solo Mode
  162. /// </summary>
  163. /// <param name="arg1"></param>
  164. /// <param name="arg2"></param>
  165. private void HandleSoloModeSelection()
  166. {
  167. Logger.Trace("HandleSoloModeSelection()");
  168. HandleModeSelection(MainMenuViewController.MenuButton.SoloFreePlay);
  169. _songBrowserUI.Show();
  170. }
  171. /// <summary>
  172. /// Handle Party Mode
  173. /// </summary>
  174. /// <param name="arg1"></param>
  175. /// <param name="arg2"></param>
  176. private void HandlePartyModeSelection()
  177. {
  178. Logger.Trace("HandlePartyModeSelection()");
  179. HandleModeSelection(MainMenuViewController.MenuButton.Party);
  180. _songBrowserUI.Show();
  181. }
  182. /// <summary>
  183. /// Handle Party Mode
  184. /// </summary>
  185. /// <param name="arg1"></param>
  186. /// <param name="arg2"></param>
  187. private void HandleCampaignModeSelection()
  188. {
  189. Logger.Trace("HandleCampaignModeSelection()");
  190. HandleModeSelection(MainMenuViewController.MenuButton.SoloCampaign);
  191. _songBrowserUI.Hide();
  192. }
  193. /// <summary>
  194. /// Handle Mode
  195. /// </summary>
  196. /// <param name="arg1"></param>
  197. /// <param name="arg2"></param>
  198. private void HandleModeSelection(MainMenuViewController.MenuButton mode)
  199. {
  200. Logger.Trace("HandleModeSelection()");
  201. _songBrowserUI.CreateUI(mode);
  202. SongBrowserApplication.MainProgressBar.ShowMessage("");
  203. StartCoroutine(UpdateBrowserUI());
  204. }
  205. /// <summary>
  206. /// Wait until the end of the frame to finish updating everything.
  207. /// </summary>
  208. /// <returns></returns>
  209. public IEnumerator UpdateBrowserUI()
  210. {
  211. yield return new WaitForEndOfFrame();
  212. _songBrowserUI.UpdateLevelDataModel();
  213. _songBrowserUI.UpdateLevelPackSelection();
  214. _songBrowserUI.RefreshSongList();
  215. }
  216. }
  217. }