Plugin.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. using BeatSaberMarkupLanguage.Settings;
  2. using HarmonyLib;
  3. using IPA;
  4. using Newtonsoft.Json;
  5. using SongCore.UI;
  6. using SongCore.Utilities;
  7. using IPA.Utilities;
  8. using System;
  9. using System.Collections;
  10. using System.Collections.Generic;
  11. using System.IO;
  12. using System.Linq;
  13. using System.Reflection;
  14. using UnityEngine;
  15. using UnityEngine.Networking;
  16. using UnityEngine.SceneManagement;
  17. using IPALogger = IPA.Logging.Logger;
  18. namespace SongCore
  19. {
  20. [Plugin(RuntimeOptions.SingleStartInit)]
  21. public class Plugin
  22. {
  23. public static string standardCharacteristicName = "Standard";
  24. public static string oneSaberCharacteristicName = "OneSaber";
  25. public static string noArrowsCharacteristicName = "NoArrows";
  26. internal static Harmony harmony;
  27. // internal static bool ColorsInstalled = false;
  28. internal static bool PlatformsInstalled = false;
  29. internal static bool customSongColors;
  30. internal static bool customSongPlatforms;
  31. internal static bool displayDiffLabels;
  32. internal static int _currentPlatform = -1;
  33. [OnStart]
  34. public void OnApplicationStart()
  35. {
  36. BSMLSettings.instance.AddSettingsMenu("SongCore", "SongCore.UI.settings.bsml", SCSettings.instance);
  37. SceneManager.activeSceneChanged += OnActiveSceneChanged;
  38. SceneManager.sceneLoaded += OnSceneLoaded;
  39. //Delete Old Config
  40. try
  41. {
  42. if (File.Exists(Environment.CurrentDirectory + "/UserData/SongCore.ini"))
  43. File.Delete(Environment.CurrentDirectory + "/UserData/SongCore.ini");
  44. }
  45. catch
  46. {
  47. Logging.logger.Warn("Failed to delete old config file!");
  48. }
  49. // ColorsInstalled = Utils.IsModInstalled("Custom Colors") || Utils.IsModInstalled("Chroma");
  50. PlatformsInstalled = SongCore.Utilities.Utils.IsModInstalled("Custom Platforms");
  51. harmony = new Harmony("com.kyle1413.BeatSaber.SongCore");
  52. harmony.PatchAll(System.Reflection.Assembly.GetExecutingAssembly());
  53. // Collections.LoadExtraSongData();
  54. UI.BasicUI.GetIcons();
  55. BS_Utils.Utilities.BSEvents.levelSelected += BSEvents_levelSelected;
  56. BS_Utils.Utilities.BSEvents.gameSceneLoaded += BSEvents_gameSceneLoaded;
  57. BS_Utils.Utilities.BSEvents.lateMenuSceneLoadedFresh += BSEvents_menuSceneLoadedFresh;
  58. if (!File.Exists(Collections.dataPath))
  59. File.Create(Collections.dataPath);
  60. else
  61. Collections.LoadExtraSongData();
  62. Collections.RegisterCustomCharacteristic(UI.BasicUI.MissingCharIcon, "Missing Characteristic", "Missing Characteristic", "MissingCharacteristic", "MissingCharacteristic", false, false, 1000);
  63. Collections.RegisterCustomCharacteristic(UI.BasicUI.LightshowIcon, "Lightshow", "Lightshow", "Lightshow", "Lightshow", false, false, 100);
  64. Collections.RegisterCustomCharacteristic(UI.BasicUI.ExtraDiffsIcon, "Lawless", "Lawless - Anything Goes", "Lawless", "Lawless", false, false, 101);
  65. if (!File.Exists(Environment.CurrentDirectory + "/UserData/SongCore/folders.xml"))
  66. File.WriteAllBytes(Environment.CurrentDirectory + "/UserData/SongCore/folders.xml", SongCore.Utilities.Utils.GetResource(Assembly.GetExecutingAssembly(), "SongCore.Data.folders.xml"));
  67. Loader.SeperateSongFolders.InsertRange(0, Data.SeperateSongFolder.ReadSeperateFoldersFromFile(Environment.CurrentDirectory + "/UserData/SongCore/folders.xml"));
  68. }
  69. private void BSEvents_menuSceneLoadedFresh(ScenesTransitionSetupDataSO data)
  70. {
  71. Loader.OnLoad();
  72. RequirementsUI.instance.Setup();
  73. }
  74. private void BSEvents_gameSceneLoaded()
  75. {
  76. if (!BS_Utils.Plugin.LevelData.IsSet) return;
  77. // Logging.logger.Info(BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.level.songDuration.ToString());
  78. SharedCoroutineStarter.instance.StartCoroutine(DelayedNoteJumpMovementSpeedFix());
  79. }
  80. private void BSEvents_levelSelected(LevelCollectionViewController arg1, IPreviewBeatmapLevel level)
  81. {
  82. if (level is CustomPreviewBeatmapLevel)
  83. {
  84. var customLevel = level as CustomPreviewBeatmapLevel;
  85. // Logging.Log((level as CustomPreviewBeatmapLevel).customLevelPath);
  86. Data.ExtraSongData songData = Collections.RetrieveExtraSongData(Hashing.GetCustomLevelHash(customLevel), customLevel.customLevelPath);
  87. Collections.SaveExtraSongData();
  88. if (songData == null)
  89. {
  90. // Logging.Log("Null song Data");
  91. return;
  92. }
  93. // Logging.Log($"Platforms Installed: {PlatformsInstalled}. Platforms enabled: {customSongPlatforms}");
  94. /*
  95. if (PlatformsInstalled && customSongPlatforms)
  96. {
  97. if (!string.IsNullOrWhiteSpace(songData._customEnvironmentName))
  98. {
  99. if (findCustomEnvironment(songData._customEnvironmentName) == -1)
  100. {
  101. Console.WriteLine("CustomPlatform not found: " + songData._customEnvironmentName);
  102. if (!string.IsNullOrWhiteSpace(songData._customEnvironmentHash))
  103. {
  104. Console.WriteLine("Downloading with hash: " + songData._customEnvironmentHash);
  105. SharedCoroutineStarter.instance.StartCoroutine(downloadCustomPlatform(songData._customEnvironmentHash, songData._customEnvironmentName));
  106. }
  107. }
  108. }
  109. }
  110. */
  111. }
  112. }
  113. [Init]
  114. public void Init(object thisIsNull, IPALogger pluginLogger)
  115. {
  116. Utilities.Logging.logger = pluginLogger;
  117. }
  118. public void OnSceneLoaded(Scene scene, LoadSceneMode sceneMode)
  119. {
  120. }
  121. public void OnSceneUnloaded(Scene scene)
  122. {
  123. }
  124. public void OnActiveSceneChanged(Scene prevScene, Scene nextScene)
  125. {
  126. customSongColors = UI.BasicUI.ModPrefs.GetBool("SongCore", "customSongColors", true, true);
  127. customSongPlatforms = UI.BasicUI.ModPrefs.GetBool("SongCore", "customSongPlatforms", true, true);
  128. displayDiffLabels = UI.BasicUI.ModPrefs.GetBool("SongCore", "displayDiffLabels", true, true);
  129. GameObject.Destroy(GameObject.Find("SongCore Color Setter"));
  130. if (nextScene.name == "MenuViewControllers")
  131. {
  132. BS_Utils.Gameplay.Gamemode.Init();
  133. }
  134. }
  135. private IEnumerator DelayedNoteJumpMovementSpeedFix()
  136. {
  137. yield return new WaitForSeconds(0.1f);
  138. //Beat Saber 0.11.1 introduced a check for if noteJumpMovementSpeed <= 0
  139. //This breaks songs that have a negative noteJumpMovementSpeed and previously required a patcher to get working again
  140. //I've added this to add support for that again, because why not.
  141. if (BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.noteJumpMovementSpeed < 0)
  142. {
  143. var beatmapObjectSpawnController =
  144. Resources.FindObjectsOfTypeAll<BeatmapObjectSpawnController>().LastOrDefault();
  145. SetNJS(beatmapObjectSpawnController);
  146. }
  147. }
  148. public static void SetNJS(BeatmapObjectSpawnController _spawnController)
  149. {
  150. BeatmapObjectSpawnMovementData spawnMovementData =
  151. _spawnController.GetField<BeatmapObjectSpawnMovementData, BeatmapObjectSpawnController>("_beatmapObjectSpawnMovementData");
  152. float bpm = _spawnController.GetField<VariableBpmProcessor, BeatmapObjectSpawnController>("_variableBPMProcessor").currentBpm;
  153. spawnMovementData.SetField("_startNoteJumpMovementSpeed", BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.noteJumpMovementSpeed);
  154. spawnMovementData.SetField("_noteJumpStartBeatOffset", BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.noteJumpStartBeatOffset);
  155. spawnMovementData.Update(bpm,
  156. _spawnController.GetField<float, BeatmapObjectSpawnController>("_jumpOffsetY"));
  157. }
  158. public void OnApplicationQuit()
  159. {
  160. }
  161. public void OnLevelWasLoaded(int level)
  162. {
  163. }
  164. public void OnLevelWasInitialized(int level)
  165. {
  166. }
  167. public void OnUpdate()
  168. {
  169. }
  170. public void OnFixedUpdate()
  171. {
  172. }
  173. /*
  174. internal static void CheckCustomSongEnvironment(IDifficultyBeatmap song)
  175. {
  176. Data.ExtraSongData songData = Collections.RetrieveExtraSongData(Hashing.GetCustomLevelHash(song.level as CustomPreviewBeatmapLevel));
  177. if (songData == null) return;
  178. if (string.IsNullOrWhiteSpace(songData._customEnvironmentName))
  179. {
  180. _currentPlatform = -1;
  181. return;
  182. }
  183. try
  184. {
  185. int _customPlatform = customEnvironment(songData._customEnvironmentName);
  186. if (_customPlatform != -1)
  187. {
  188. _currentPlatform = CustomFloorPlugin.PlatformManager.CurrentPlatformIndex;
  189. if (customSongPlatforms && _customPlatform != _currentPlatform)
  190. {
  191. CustomFloorPlugin.PlatformManager.TempChangeToPlatform(_customPlatform);
  192. }
  193. }
  194. }
  195. catch(Exception ex)
  196. {
  197. Logging.logger.Error($"Failed to Change to Platform {songData._customEnvironmentName}\n {ex}");
  198. }
  199. }
  200. internal static int customEnvironment(string platform)
  201. {
  202. if (!PlatformsInstalled)
  203. return -1;
  204. return findCustomEnvironment(platform);
  205. }
  206. private static int findCustomEnvironment(string name)
  207. {
  208. List<CustomFloorPlugin.CustomPlatform> _customPlatformsList = CustomFloorPlugin.PlatformManager.AllPlatforms;
  209. int platIndex = 0;
  210. foreach (CustomFloorPlugin.CustomPlatform plat in _customPlatformsList)
  211. {
  212. if (plat?.platName == name)
  213. return platIndex;
  214. platIndex++;
  215. }
  216. Console.WriteLine(name + " not found!");
  217. return -1;
  218. }
  219. [Serializable]
  220. public class platformDownloadData
  221. {
  222. public string name;
  223. public string author;
  224. public string image;
  225. public string hash;
  226. public string download;
  227. public string date;
  228. }
  229. private IEnumerator downloadCustomPlatform(string hash, string name)
  230. {
  231. using (UnityWebRequest www = UnityWebRequest.Get("https://modelsaber.com/api/v1/platform/get.php?filter=hash:" + hash))
  232. {
  233. yield return www.SendWebRequest();
  234. if (www.isNetworkError || www.isHttpError)
  235. {
  236. Console.WriteLine(www.error);
  237. }
  238. else
  239. {
  240. var downloadData = JsonConvert.DeserializeObject<Dictionary<string, platformDownloadData>>(www.downloadHandler.text);
  241. platformDownloadData data = downloadData.FirstOrDefault().Value;
  242. if (data != null)
  243. if (data.name == name)
  244. {
  245. SharedCoroutineStarter.instance.StartCoroutine(_downloadCustomPlatform(data));
  246. }
  247. }
  248. }
  249. }
  250. private IEnumerator _downloadCustomPlatform(platformDownloadData downloadData)
  251. {
  252. using (UnityWebRequest www = UnityWebRequest.Get(downloadData.download))
  253. {
  254. yield return www.SendWebRequest();
  255. if (www.isNetworkError || www.isHttpError)
  256. {
  257. Console.WriteLine(www.error);
  258. }
  259. else
  260. {
  261. string customPlatformsFolderPath = Path.Combine(Environment.CurrentDirectory, "CustomPlatforms", downloadData.name);
  262. System.IO.File.WriteAllBytes(@customPlatformsFolderPath + ".plat", www.downloadHandler.data);
  263. try
  264. {
  265. CustomFloorPlugin.PlatformManager.AddPlatform(customPlatformsFolderPath + ".plat");
  266. }
  267. catch(Exception ex)
  268. {
  269. Logging.logger.Error($"Failed to add Platform {customPlatformsFolderPath}.plat \n {ex}");
  270. }
  271. }
  272. }
  273. }
  274. */
  275. }
  276. }