SongBrowserApplication.cs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. using SongBrowserPlugin.DataAccess;
  2. using SongBrowserPlugin.UI;
  3. using SongLoaderPlugin;
  4. using SongLoaderPlugin.OverrideClasses;
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using UnityEngine;
  10. using UnityEngine.UI;
  11. using Logger = SongBrowserPlugin.Logging.Logger;
  12. namespace SongBrowserPlugin
  13. {
  14. public class SongBrowserApplication : MonoBehaviour
  15. {
  16. public static SongBrowserApplication Instance;
  17. // Song Browser UI Elements
  18. private SongBrowserUI _songBrowserUI;
  19. private ScoreSaberDatabaseDownloader _ppDownloader;
  20. public Dictionary<String, Sprite> CachedIcons;
  21. public static SongBrowserPlugin.UI.ProgressBar MainProgressBar;
  22. /// <summary>
  23. /// Load the main song browser app.
  24. /// </summary>
  25. internal static void OnLoad()
  26. {
  27. if (Instance != null)
  28. {
  29. return;
  30. }
  31. new GameObject("Beat Saber SongBrowser Plugin").AddComponent<SongBrowserApplication>();
  32. SongBrowserApplication.MainProgressBar = SongBrowserPlugin.UI.ProgressBar.Create();
  33. Console.WriteLine("SongBrowser Plugin Loaded()");
  34. }
  35. /// <summary>
  36. /// It has awaken!
  37. /// </summary>
  38. private void Awake()
  39. {
  40. Logger.Trace("Awake()");
  41. Instance = this;
  42. _songBrowserUI = gameObject.AddComponent<SongBrowserUI>();
  43. _ppDownloader = gameObject.AddComponent<ScoreSaberDatabaseDownloader>();
  44. _ppDownloader.onScoreSaberDataDownloaded += OnScoreSaberDataDownloaded;
  45. }
  46. /// <summary>
  47. /// Acquire any UI elements from Beat saber that we need. Wait for the song list to be loaded.
  48. /// </summary>
  49. public void Start()
  50. {
  51. Logger.Trace("Start()");
  52. AcquireUIElements();
  53. StartCoroutine(WaitForSongListUI());
  54. }
  55. /// <summary>
  56. /// Wait for the song list to be visible to draw it.
  57. /// </summary>
  58. /// <returns></returns>
  59. private IEnumerator WaitForSongListUI()
  60. {
  61. Logger.Trace("WaitForSongListUI()");
  62. yield return new WaitUntil(delegate () { return Resources.FindObjectsOfTypeAll<SoloFreePlayFlowCoordinator>().Any() && Resources.FindObjectsOfTypeAll<SoloFreePlayFlowCoordinator>().Any(); });
  63. Logger.Debug("Found Solo and Party FreePlayFlowCoordinators...");
  64. if (SongLoaderPlugin.SongLoader.AreSongsLoaded)
  65. {
  66. OnSongLoaderLoadedSongs(null, SongLoader.CustomLevels);
  67. }
  68. else
  69. {
  70. SongLoader.SongsLoadedEvent += OnSongLoaderLoadedSongs;
  71. }
  72. _songBrowserUI.RefreshSongList();
  73. }
  74. /// <summary>
  75. /// Only gets called once during boot of BeatSaber.
  76. /// </summary>
  77. /// <param name="loader"></param>
  78. /// <param name="levels"></param>
  79. private void OnSongLoaderLoadedSongs(SongLoader loader, List<CustomLevel> levels)
  80. {
  81. Logger.Trace("OnSongLoaderLoadedSongs");
  82. try
  83. {
  84. _songBrowserUI.UpdateSongList();
  85. }
  86. catch (Exception e)
  87. {
  88. Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e);
  89. }
  90. }
  91. /// <summary>
  92. /// Inform browser score saber data is available.
  93. /// </summary>
  94. /// <param name="loader"></param>
  95. /// <param name="levels"></param>
  96. private void OnScoreSaberDataDownloaded()
  97. {
  98. Logger.Trace("OnScoreSaberDataDownloaded");
  99. try
  100. {
  101. // TODO - this should be in the SongBrowserUI which is acting like the view controller for the SongBrowser
  102. _songBrowserUI.Model.UpdateScoreSaberDataMapping();
  103. //_songBrowserUI.RefreshScoreSaberData(null);
  104. if (_songBrowserUI.Model.Settings.sortMode == SongSortMode.PP)
  105. {
  106. _songBrowserUI.Model.ProcessSongList();
  107. _songBrowserUI.RefreshSongList();
  108. }
  109. }
  110. catch (Exception e)
  111. {
  112. Logger.Exception("Exception during OnSongLoaderLoadedSongs: ", e);
  113. }
  114. }
  115. /// <summary>
  116. /// Get a handle to the view controllers we are going to add elements to.
  117. /// </summary>
  118. public void AcquireUIElements()
  119. {
  120. Logger.Trace("AcquireUIElements()");
  121. try
  122. {
  123. CachedIcons = new Dictionary<String, Sprite>();
  124. foreach (Sprite sprite in Resources.FindObjectsOfTypeAll<Sprite>())
  125. {
  126. if (CachedIcons.ContainsKey(sprite.name))
  127. {
  128. continue;
  129. }
  130. //Logger.Debug("Adding Icon: {0}", sprite.name);
  131. CachedIcons.Add(sprite.name, sprite);
  132. }
  133. // Append our own event to appropriate events so we can refresh the song list before the user sees it.
  134. MainFlowCoordinator mainFlow = Resources.FindObjectsOfTypeAll<MainFlowCoordinator>().First();
  135. Button soloFreePlayButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "SoloFreePlayButton");
  136. Button partyFreePlayButton = Resources.FindObjectsOfTypeAll<Button>().First(x => x.name == "PartyFreePlayButton");
  137. soloFreePlayButton.onClick.AddListener(HandleSoloModeSelection);
  138. partyFreePlayButton.onClick.AddListener(HandlePartyModeSelection);
  139. }
  140. catch (Exception e)
  141. {
  142. Logger.Exception("Exception AcquireUIElements(): ", e);
  143. }
  144. }
  145. /// <summary>
  146. /// Handle Solo Mode
  147. /// </summary>
  148. /// <param name="arg1"></param>
  149. /// <param name="arg2"></param>
  150. private void HandleSoloModeSelection()
  151. {
  152. Logger.Trace("HandleSoloModeSelection()");
  153. HandleModeSelection(MainMenuViewController.MenuButton.SoloFreePlay);
  154. }
  155. /// <summary>
  156. /// Handle Party Mode
  157. /// </summary>
  158. /// <param name="arg1"></param>
  159. /// <param name="arg2"></param>
  160. private void HandlePartyModeSelection()
  161. {
  162. Logger.Trace("HandlePartyModeSelection()");
  163. HandleModeSelection(MainMenuViewController.MenuButton.Party);
  164. }
  165. /// <summary>
  166. /// Handle Mode
  167. /// </summary>
  168. /// <param name="arg1"></param>
  169. /// <param name="arg2"></param>
  170. private void HandleModeSelection(MainMenuViewController.MenuButton mode)
  171. {
  172. Logger.Trace("HandleModeSelection()");
  173. this._songBrowserUI.CreateUI(mode);
  174. this._songBrowserUI.UpdateSongList();
  175. this._songBrowserUI.RefreshSongList();
  176. }
  177. /// <summary>
  178. /// Helper for invoking buttons.
  179. /// </summary>
  180. /// <param name="buttonName"></param>
  181. public static void InvokeBeatSaberButton(String buttonName)
  182. {
  183. Button buttonInstance = Resources.FindObjectsOfTypeAll<Button>().First(x => (x.name == buttonName));
  184. buttonInstance.onClick.Invoke();
  185. }
  186. /// <summary>
  187. /// Map some key presses directly to UI interactions to make testing easier.
  188. /// </summary>
  189. private void LateUpdate()
  190. {
  191. // z,x,c,v can be used to get into a song, b will hit continue button after song ends
  192. if (Input.GetKey(KeyCode.LeftShift) && Input.GetKeyDown(KeyCode.Z))
  193. {
  194. InvokeBeatSaberButton("PartyFreePlayButton");
  195. }
  196. else if (Input.GetKeyDown(KeyCode.Z))
  197. {
  198. InvokeBeatSaberButton("SoloFreePlayButton");
  199. }
  200. if (Input.GetKeyDown(KeyCode.Alpha0))
  201. {
  202. InvokeBeatSaberButton("SettingsButton");
  203. }
  204. if (Input.GetKeyDown(KeyCode.Alpha9))
  205. {
  206. InvokeBeatSaberButton("ApplyButton");
  207. }
  208. if (Input.GetKeyDown(KeyCode.Alpha8))
  209. {
  210. Console.WriteLine("CLICKING OK BUTTON");
  211. var settings = Resources.FindObjectsOfTypeAll<VRUI.VRUIViewController>().First(x => x.name == "SettingsViewController");
  212. var button = settings.GetComponentsInChildren<Button>().Where(x => x.name == "OkButton");
  213. foreach (Button b in button)
  214. {
  215. b.onClick.Invoke();
  216. }
  217. }
  218. }
  219. }
  220. }