From be5a21580a5cecc3274b3a37ed7b85647c427d9e Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Sun, 31 Dec 2023 20:56:42 -0500 Subject: [PATCH 1/7] Make custom colors patch more resilient to updates --- .../HarmonyPatches/CustomSongColorsPatch.cs | 35 ++----------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs index 5531e8d..2e2af09 100644 --- a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs +++ b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs @@ -12,39 +12,8 @@ internal class SceneTransitionPatch { private static IEnumerable TargetMethods() { - yield return AccessTools.Method(typeof(StandardLevelScenesTransitionSetupDataSO), nameof(StandardLevelScenesTransitionSetupDataSO.Init), - new[] - { - typeof(string), - typeof(IDifficultyBeatmap), - typeof(IPreviewBeatmapLevel), - typeof(OverrideEnvironmentSettings), - typeof(ColorScheme), - typeof(ColorScheme), - typeof(GameplayModifiers), - typeof(PlayerSpecificSettings), - typeof(PracticeSettings), - typeof(string), - typeof(bool), - typeof(bool), - typeof(BeatmapDataCache), - typeof(RecordingToolManager.SetupData?) - }); - - yield return AccessTools.Method(typeof(MultiplayerLevelScenesTransitionSetupDataSO), nameof(MultiplayerLevelScenesTransitionSetupDataSO.Init), - new[] - { - typeof(string), - typeof(IPreviewBeatmapLevel), - typeof(BeatmapDifficulty), - typeof(BeatmapCharacteristicSO), - typeof(IDifficultyBeatmap), - typeof(ColorScheme), - typeof(GameplayModifiers), - typeof(PlayerSpecificSettings), - typeof(PracticeSettings), - typeof(bool) - }); + yield return AccessTools.DeclaredMethod(typeof(StandardLevelScenesTransitionSetupDataSO), nameof(StandardLevelScenesTransitionSetupDataSO.Init)); + yield return AccessTools.DeclaredMethod(typeof(MultiplayerLevelScenesTransitionSetupDataSO), nameof(MultiplayerLevelScenesTransitionSetupDataSO.Init)); } private static void Prefix(ref IDifficultyBeatmap difficultyBeatmap, ref ColorScheme? overrideColorScheme) From b040d899150c514ed46789892290d8a2e00ef311 Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Sun, 31 Dec 2023 23:06:19 -0500 Subject: [PATCH 2/7] Fix color scheme only if it uses default value --- source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs index 2e2af09..f3ee106 100644 --- a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs +++ b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs @@ -18,18 +18,19 @@ private static IEnumerable TargetMethods() private static void Prefix(ref IDifficultyBeatmap difficultyBeatmap, ref ColorScheme? overrideColorScheme) { - if(overrideColorScheme != null) + // TODO: Remove this when it gets fixed. + if (overrideColorScheme != null) { - if(overrideColorScheme._environmentColor0Boost.a == 0) + if (overrideColorScheme._environmentColor0Boost == default) { overrideColorScheme._environmentColor0Boost = overrideColorScheme._environmentColor0; } - if (overrideColorScheme._environmentColor1Boost.a == 0) + if (overrideColorScheme._environmentColor1Boost == default) { overrideColorScheme._environmentColor1Boost = overrideColorScheme._environmentColor1; } } - + if (difficultyBeatmap == null || !Plugin.Configuration.CustomSongNoteColors && !Plugin.Configuration.CustomSongEnvironmentColors && !Plugin.Configuration.CustomSongObstacleColors) { return; From 15f39e25a6357229a322822dbdcf7ea3ebef1344 Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Sun, 31 Dec 2023 23:29:46 -0500 Subject: [PATCH 3/7] Correctly make use of the publicizer --- ...CollectionCell_RefreshAvailabilityAsync.cs | 4 +- .../CosmeticCharacteristicsPatches.cs | 21 ++++---- .../HarmonyPatches/CustomSongColorsPatch.cs | 1 - .../HarmonyPatches/LevelSelectionPatch.cs | 9 ++-- .../SongCore/HarmonyPatches/LoadingPatches.cs | 24 ++++----- .../StandardLevelDetailViewRefreshContent.cs | 50 +++++++++---------- source/SongCore/SongCore.csproj | 1 + 7 files changed, 53 insertions(+), 57 deletions(-) diff --git a/source/SongCore/HarmonyPatches/AnnotatedBeatmapLevelCollectionCell_RefreshAvailabilityAsync.cs b/source/SongCore/HarmonyPatches/AnnotatedBeatmapLevelCollectionCell_RefreshAvailabilityAsync.cs index 1e1f57b..911ff93 100644 --- a/source/SongCore/HarmonyPatches/AnnotatedBeatmapLevelCollectionCell_RefreshAvailabilityAsync.cs +++ b/source/SongCore/HarmonyPatches/AnnotatedBeatmapLevelCollectionCell_RefreshAvailabilityAsync.cs @@ -10,9 +10,9 @@ namespace SongCore.HarmonyPatches [HarmonyPatch(typeof(AnnotatedBeatmapLevelCollectionCell), nameof(AnnotatedBeatmapLevelCollectionCell.RefreshAvailabilityAsync))] internal class AnnotatedBeatmapLevelCollectionCell_RefreshAvailabilityAsync { - private static void Postfix(AnnotatedBeatmapLevelCollectionCell __instance, IAnnotatedBeatmapLevelCollection ____annotatedBeatmapLevelCollection) + private static void Postfix(AnnotatedBeatmapLevelCollectionCell __instance) { - if (____annotatedBeatmapLevelCollection is CustomBeatmapLevelPack) + if (__instance._annotatedBeatmapLevelCollection is CustomBeatmapLevelPack) { __instance.SetDownloadIconVisible(false); } diff --git a/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs b/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs index 3b953b2..36c19fe 100644 --- a/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs +++ b/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs @@ -7,7 +7,6 @@ using System.Threading.Tasks; using HarmonyLib; using HMUI; -using IPA.Utilities; using SongCore.Data; using SongCore.Utilities; using UnityEngine; @@ -53,7 +52,7 @@ private static void Prefix(GameplayCoreInstaller __instance) if (Plugin.Configuration.DisableOneSaberOverride) return; - sceneSetupData = __instance.GetField("_sceneSetupData"); + sceneSetupData = __instance._sceneSetupData; var diffBeatmapLevel = sceneSetupData.difficultyBeatmap.level; var level = diffBeatmapLevel is CustomBeatmapLevel ? diffBeatmapLevel as CustomPreviewBeatmapLevel : null; @@ -68,7 +67,7 @@ private static void Prefix(GameplayCoreInstaller __instance) if (diffData._oneSaber != null && !Plugin.Configuration.DisableOneSaberOverride) { numberOfColors = sceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.numberOfColors; - sceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.SetField("_numberOfColors", diffData._oneSaber.Value == true ? 1 : 2); + sceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic._numberOfColors = diffData._oneSaber.Value == true ? 1 : 2; } } @@ -81,7 +80,7 @@ private static void Postfix(GameplayCoreInstaller __instance) if (diffData._oneSaber != null && !Plugin.Configuration.DisableOneSaberOverride) { - sceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.SetField("_numberOfColors", numberOfColors); + sceneSetupData.difficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic._numberOfColors = numberOfColors; } } @@ -93,7 +92,7 @@ private static void Postfix(GameplayCoreInstaller __instance) internal class CosmeticCharacteristicsPatch { // public static OverrideClasses.CustomLevel previouslySelectedSong = null; - private static void Postfix(IReadOnlyList difficultyBeatmapSets, BeatmapCharacteristicSO selectedBeatmapCharacteristic, ref List ____beatmapCharacteristics, ref IconSegmentedControl ____segmentedControl) + private static void Postfix(BeatmapCharacteristicSegmentedControlController __instance, IReadOnlyList difficultyBeatmapSets, BeatmapCharacteristicSO selectedBeatmapCharacteristic) { if (!Plugin.Configuration.DisplayCustomCharacteristics) return; @@ -110,18 +109,18 @@ private static void Postfix(IReadOnlyList difficultyBeatm if (songData == null) return; if (songData._characteristicDetails == null) return; - if (____segmentedControl == null) return; + if (__instance._segmentedControl == null) return; if (songData._characteristicDetails.Length > 0) { - var dataItems = ____segmentedControl.GetField("_dataItems"); + var dataItems = __instance._segmentedControl._dataItems; List newDataItems = new List(); int i = 0; int cell = 0; foreach (var item in dataItems) { - var characteristic = ____beatmapCharacteristics[i]; + var characteristic = __instance._beatmapCharacteristics[i]; string serializedName = characteristic.serializedName; ExtraSongData.CharacteristicDetails? detail = songData._characteristicDetails.Where(x => x._beatmapCharacteristicName == serializedName).FirstOrDefault(); @@ -139,13 +138,13 @@ private static void Postfix(IReadOnlyList difficultyBeatm } if (characteristic == selectedBeatmapCharacteristic) - { + { cell = i; } i++; } - ____segmentedControl.SetData(newDataItems.ToArray()); - ____segmentedControl.SelectCellWithNumber(cell); + __instance._segmentedControl.SetData(newDataItems.ToArray()); + __instance._segmentedControl.SelectCellWithNumber(cell); } } } diff --git a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs index f3ee106..273004a 100644 --- a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs +++ b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Reflection; using HarmonyLib; -using IPA.Utilities; using SongCore.Utilities; using Utils = SongCore.Utilities.Utils; diff --git a/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs b/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs index 051476f..e0fc5ce 100644 --- a/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs +++ b/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs @@ -1,6 +1,5 @@ using System.Globalization; using HarmonyLib; -using TMPro; namespace SongCore.HarmonyPatches { @@ -8,22 +7,22 @@ namespace SongCore.HarmonyPatches [HarmonyPatch(nameof(LevelListTableCell.SetDataFromLevelAsync), MethodType.Normal)] internal class LevelListTableCellSetDataFromLevel { - private static void Postfix(IPreviewBeatmapLevel level, TextMeshProUGUI ____songAuthorText, TextMeshProUGUI ____songBpmText) + private static void Postfix(LevelListTableCell __instance, IPreviewBeatmapLevel level) { // Rounding BPM display for all maps, including official ones - ____songBpmText.text = System.Math.Round(level.beatsPerMinute).ToString(CultureInfo.InvariantCulture); + __instance._songBpmText.text = System.Math.Round(level.beatsPerMinute).ToString(CultureInfo.InvariantCulture); /* Plan B IPA.Utilities.Async.UnityMainThreadTaskScheduler.Factory.StartNew( async () => { var token = new CancellationTokenSource().Token; var audio = await level.GetPreviewAudioClipAsync(token); customLevel.SetField("_songDuration", audio.length); ____songDurationText.text = customLevel.songDuration.MinSecDurationText(); }); */ if (!string.IsNullOrWhiteSpace(level.levelAuthorName)) { - ____songAuthorText.richText = true; + __instance._songAuthorText.richText = true; //Get PinkCore'd string mapperColor = Plugin.Configuration.GreenMapperColor ? "89ff89" : "ff69b4"; - ____songAuthorText.text = $"{level.songAuthorName} [{level.levelAuthorName.Replace(@"<", "<\u200B").Replace(@">", ">\u200B")}]"; + __instance._songAuthorText.text = $"{level.songAuthorName} [{level.levelAuthorName.Replace(@"<", "<\u200B").Replace(@">", ">\u200B")}]"; } } } diff --git a/source/SongCore/HarmonyPatches/LoadingPatches.cs b/source/SongCore/HarmonyPatches/LoadingPatches.cs index f35bc24..a18e6f3 100644 --- a/source/SongCore/HarmonyPatches/LoadingPatches.cs +++ b/source/SongCore/HarmonyPatches/LoadingPatches.cs @@ -92,35 +92,33 @@ internal class StopVanillaLoadingPatch [HarmonyPatch(nameof(LevelFilteringNavigationController.UpdateCustomSongs), MethodType.Normal)] internal class StopVanillaLoadingPatch2 { - private static bool Prefix(ref LevelFilteringNavigationController __instance, LevelSearchViewController ____levelSearchViewController, - SelectLevelCategoryViewController ____selectLevelCategoryViewController, ref IBeatmapLevelPack[] ____ostBeatmapLevelPacks, ref IBeatmapLevelPack[] ____musicPacksBeatmapLevelPacks, - ref IBeatmapLevelPack[] ____customLevelPacks, ref IBeatmapLevelPack[] ____allBeatmapLevelPacks) + private static bool Prefix(LevelFilteringNavigationController __instance) { if (Loader.CustomBeatmapLevelPackCollectionSO == null) { return false; } - ____customLevelPacks = Loader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks; + __instance._customLevelPacks = Loader.CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks; IEnumerable? packs = null; - if (____ostBeatmapLevelPacks != null) + if (__instance._ostBeatmapLevelPacks != null) { - packs = ____ostBeatmapLevelPacks; + packs = __instance._ostBeatmapLevelPacks; } - if (____musicPacksBeatmapLevelPacks != null) + if (__instance._musicPacksBeatmapLevelPacks != null) { - packs = packs == null ? ____musicPacksBeatmapLevelPacks : packs.Concat(____musicPacksBeatmapLevelPacks); + packs = packs == null ? __instance._musicPacksBeatmapLevelPacks : packs.Concat(__instance._musicPacksBeatmapLevelPacks); } - if (____customLevelPacks != null) + if (__instance._customLevelPacks != null) { - packs = packs == null ? ____customLevelPacks : packs.Concat(____customLevelPacks); + packs = packs == null ? __instance._customLevelPacks : packs.Concat(__instance._customLevelPacks); } - ____allBeatmapLevelPacks = packs.ToArray(); - ____levelSearchViewController.Setup(____allBeatmapLevelPacks); - __instance.UpdateSecondChildControllerContent(____selectLevelCategoryViewController.selectedLevelCategory); + __instance._allBeatmapLevelPacks = packs.ToArray(); + __instance._levelSearchViewController.Setup(__instance._allBeatmapLevelPacks); + __instance.UpdateSecondChildControllerContent(__instance._selectLevelCategoryViewController.selectedLevelCategory); return false; } diff --git a/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs b/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs index 71c3f94..2bdbafc 100644 --- a/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs +++ b/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs @@ -45,20 +45,22 @@ internal static void ClearOverrideLabels() currentLabels.ExpertPlusOverride = null; } - private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyBeatmap ____selectedDifficultyBeatmap, ref Button ____actionButton, ref Button ____practiceButton, - ref BeatmapDifficultySegmentedControlController ____beatmapDifficultySegmentedControlController, - ref BeatmapCharacteristicSegmentedControlController ____beatmapCharacteristicSegmentedControlController) + private static void Postfix(StandardLevelDetailView __instance) { var firstSelection = false; - var level = ____selectedDifficultyBeatmap.level is CustomBeatmapLevel ? ____selectedDifficultyBeatmap.level as CustomPreviewBeatmapLevel : null; + var selectedDifficultyBeatmap = __instance.selectedDifficultyBeatmap; + var actionButton = __instance.actionButton; + var practiceButton = __instance.practiceButton; + var level = selectedDifficultyBeatmap.level is CustomBeatmapLevel ? selectedDifficultyBeatmap.level as CustomPreviewBeatmapLevel : null; + if (level != lastLevel) { firstSelection = true; lastLevel = level; } - ____actionButton.interactable = true; - ____practiceButton.interactable = true; + actionButton.interactable = true; + practiceButton.interactable = true; RequirementsUI.instance.ButtonGlowColor = false; RequirementsUI.instance.ButtonInteractable = false; @@ -77,8 +79,7 @@ private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyB } var wipFolderSong = false; - var selectedDiff = ____selectedDifficultyBeatmap; - var diffData = Collections.RetrieveDifficultyData(selectedDiff); + var diffData = Collections.RetrieveDifficultyData(selectedDifficultyBeatmap); if (diffData != null) { @@ -104,7 +105,7 @@ private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyB RequirementsUI.instance.ButtonInteractable = true; if (diffData.additionalDifficultyData._warnings.Contains("WIP")) { - ____actionButton.interactable = false; + actionButton.interactable = false; } RequirementsUI.instance.SetRainbowColors(Utilities.Utils.DiffHasColors(diffData)); } @@ -114,7 +115,7 @@ private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyB { RequirementsUI.instance.ButtonGlowColor = true; RequirementsUI.instance.ButtonInteractable = true; - ____actionButton.interactable = false; + actionButton.interactable = false; wipFolderSong = true; } @@ -124,24 +125,24 @@ private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyB { if (!Collections.capabilities.Contains(requirement)) { - ____actionButton.interactable = false; - ____practiceButton.interactable = false; + actionButton.interactable = false; + practiceButton.interactable = false; RequirementsUI.instance.ButtonGlowColor = true; RequirementsUI.instance.ButtonInteractable = true; } } } - if (selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName == "MissingCharacteristic") + if (selectedDifficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName == "MissingCharacteristic") { - ____actionButton.interactable = false; - ____practiceButton.interactable = false; + actionButton.interactable = false; + practiceButton.interactable = false; RequirementsUI.instance.ButtonGlowColor = true; RequirementsUI.instance.ButtonInteractable = true; } RequirementsUI.instance.level = level; - RequirementsUI.instance.difficultyBeatmap = ____selectedDifficultyBeatmap; + RequirementsUI.instance.difficultyBeatmap = selectedDifficultyBeatmap; RequirementsUI.instance.songData = songData; RequirementsUI.instance.diffData = diffData; RequirementsUI.instance.wipFolder = wipFolderSong; @@ -154,7 +155,7 @@ private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyB { var difficulty = diffLevel._difficulty; string characteristic = diffLevel._beatmapCharacteristicName; - if (characteristic == selectedDiff.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName) + if (characteristic == selectedDifficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic.serializedName) { currentCharacteristic = characteristic; } @@ -197,17 +198,16 @@ private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyB ClearOverrideLabels(); } - ____beatmapDifficultySegmentedControlController.SetData(____selectedDifficultyBeatmap.parentDifficultyBeatmapSet.difficultyBeatmaps, - ____beatmapDifficultySegmentedControlController.selectedDifficulty); + __instance._beatmapDifficultySegmentedControlController.SetData(selectedDifficultyBeatmap.parentDifficultyBeatmapSet.difficultyBeatmaps, + __instance._beatmapDifficultySegmentedControlController.selectedDifficulty); ClearOverrideLabels(); // TODO: Check if this whole if block is still needed if (songData._defaultCharacteristic != null && firstSelection) { - if (____beatmapCharacteristicSegmentedControlController.selectedBeatmapCharacteristic.serializedName != songData._defaultCharacteristic) + if (__instance._beatmapCharacteristicSegmentedControlController.selectedBeatmapCharacteristic.serializedName != songData._defaultCharacteristic) { - var chars = - ____beatmapCharacteristicSegmentedControlController._beatmapCharacteristics; + var chars = __instance._beatmapCharacteristicSegmentedControlController._beatmapCharacteristics; var index = 0; foreach (var characteristic in chars) { @@ -221,10 +221,10 @@ private static void Postfix(StandardLevelDetailView __instance, ref IDifficultyB if (index != chars.Count) { - ____beatmapCharacteristicSegmentedControlController._segmentedControl + __instance._beatmapCharacteristicSegmentedControlController._segmentedControl .SelectCellWithNumber(index); - ____beatmapCharacteristicSegmentedControlController.HandleDifficultySegmentedControlDidSelectCell( - ____beatmapCharacteristicSegmentedControlController._segmentedControl, index); + __instance._beatmapCharacteristicSegmentedControlController.HandleDifficultySegmentedControlDidSelectCell( + __instance._beatmapCharacteristicSegmentedControlController._segmentedControl, index); } } } diff --git a/source/SongCore/SongCore.csproj b/source/SongCore/SongCore.csproj index 6d7261a..7e1f3ba 100644 --- a/source/SongCore/SongCore.csproj +++ b/source/SongCore/SongCore.csproj @@ -64,6 +64,7 @@ $(BeatSaberDir)\Beat Saber_Data\Managed\HMUI.dll False + True $(BeatSaberDir)\Beat Saber_Data\Managed\IPA.Loader.dll From 80bfce528d644997d5713a4aabbe785f372f5620 Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:13:47 -0500 Subject: [PATCH 4/7] Remove unused stuff --- build/Configuration.cs | 2 - source/SongCore/Collections.cs | 2 +- source/SongCore/Data/SongData.cs | 6 - source/SongCore/HarmonyPatches/AprilFools.cs | 116 ------------------ .../CosmeticCharacteristicsPatches.cs | 6 - .../CustomCharacteristicsPatch.cs | 1 - .../HarmonyPatches/CustomSongColorsPatch.cs | 2 - .../HarmonyPatches/LevelSelectionPatch.cs | 3 - .../SongCore/HarmonyPatches/LoadingPatches.cs | 61 --------- .../StandardLevelDetailViewRefreshContent.cs | 1 - source/SongCore/Loader.cs | 6 - .../SongCoreBeatmapLevelPackCollectionSO.cs | 4 - source/SongCore/Plugin.cs | 33 ----- source/SongCore/SongCore.csproj | 8 -- 14 files changed, 1 insertion(+), 250 deletions(-) delete mode 100644 source/SongCore/HarmonyPatches/AprilFools.cs diff --git a/build/Configuration.cs b/build/Configuration.cs index 9c08b1a..9b22a3b 100644 --- a/build/Configuration.cs +++ b/build/Configuration.cs @@ -1,6 +1,4 @@ -using System; using System.ComponentModel; -using System.Linq; using Nuke.Common.Tooling; [TypeConverter(typeof(TypeConverter))] diff --git a/source/SongCore/Collections.cs b/source/SongCore/Collections.cs index 18900cb..6c6f8f1 100644 --- a/source/SongCore/Collections.cs +++ b/source/SongCore/Collections.cs @@ -116,7 +116,7 @@ public static void RegisterCapability(string capability) newChar._icon = icon; newChar._descriptionLocalizationKey = hintText; - newChar._serializedName= serializedName; + newChar._serializedName = serializedName; newChar._characteristicNameLocalizationKey = characteristicName; newChar._compoundIdPartName = compoundIdPartName; newChar._requires360Movement = requires360Movement; diff --git a/source/SongCore/Data/SongData.cs b/source/SongCore/Data/SongData.cs index ef4396f..ce8fd09 100644 --- a/source/SongCore/Data/SongData.cs +++ b/source/SongCore/Data/SongData.cs @@ -1,17 +1,11 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Drawing.Imaging; -using System.IO; using System.Linq; -using System.Reflection; -using HarmonyLib; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SongCore.Utilities; using UnityEngine; -using UnityEngine.UI; -using static BloomPrePassBackgroundColorsGradientFromColorSchemeColors; namespace SongCore.Data { diff --git a/source/SongCore/HarmonyPatches/AprilFools.cs b/source/SongCore/HarmonyPatches/AprilFools.cs deleted file mode 100644 index afee749..0000000 --- a/source/SongCore/HarmonyPatches/AprilFools.cs +++ /dev/null @@ -1,116 +0,0 @@ -using HarmonyLib; -using SongCore.Utilities; -using System.Linq; -using System.Collections; -using System.Collections.Generic; -namespace SongCore.HarmonyPatches.AprilFools -{ - /* - class NoteSection - { - public bool RightIsLeading { get; private set; } = true; - public float RightProportion { get; private set; } = 0.5f; - private List _notes = new List(); - public float SectionDuration { get; private set; } = 0f; - public void AddNote(NoteData note) - { - _notes.Add(note); - } - public int NoteCount() - { - return _notes.Count; - } - public NoteData LastNote() - { - return _notes.LastOrDefault(); - } - public void CalculateData() - { - _notes = _notes.OrderBy(x => x.time).ToList(); - if (_notes.Count < 3) return; - NoteData first = _notes.FirstOrDefault(x => _notes.IndexOf(x) < (_notes.Count - 1) && _notes[_notes.IndexOf(x) + 1].time != x.time); - if (first == null) return; - RightProportion = (_notes.Where(x => x.colorType == ColorType.ColorB).Count() / (float)_notes.Count); - RightIsLeading = first.colorType == ColorType.ColorB && RightProportion >= 0.4f; - SectionDuration = _notes.Last().time - _notes.First().time; - // Logging.logger.Debug($"\nNote Section Calculated\nNote Count {_notes.Count}\nFirst Note Time{_notes.First().time}\nLast Note Time{_notes.Last().time}\nSection Duration {SectionDuration}\nRight Proportion{RightProportion}\nRight Leading {RightIsLeading}"); - - } - } - [HarmonyPatch(typeof(BeatmapDataTransformHelper))] - [HarmonyPatch("CreateTransformedBeatmapData")] - class AprilFoolsLeftHandedMapsAreFinePatch - { - static void Prefix(IReadonlyBeatmapData beatmapData, ref IReadonlyBeatmapData __result, ref bool leftHanded) - { - System.DateTime time; - bool bunbundai = false; - try - { - // var userID = 0;//BS_Utils.Gameplay.GetUserInfo.GetUserID(); - // if (userID == 76561198182060577) - // bunbundai = true; - } - catch (System.Exception ex) - { - Logging.logger.Error("Error in Bunbundai Contingency"); - } - if (IPA.Utilities.Utils.CanUseDateTimeNowSafely) - time = System.DateTime.Now; - else - time = System.DateTime.UtcNow; - - if (!((time.Month == 4 && time.Day == 1) || bunbundai)) return; - - var mapNotes = new List(); - var objects = beatmapData.beatmapObjectsData; - foreach (var beatmapObject in objects) - if (beatmapObject is NoteData) mapNotes.Add(beatmapObject as NoteData); - mapNotes.RemoveAll(x => x.colorType == ColorType.None); - mapNotes = mapNotes.OrderBy(x => x.time).ToList(); - List mapData = new List(); - NoteSection lastSection = new NoteSection(); - float bpm = BS_Utils.Plugin.LevelData.GameplayCoreSceneSetupData.difficultyBeatmap.level.beatsPerMinute; - float maxNoteTimeDiff = (60f / bpm) / 2f; - foreach(var note in mapNotes) - { - NoteData lastNote = lastSection.LastNote(); - if (lastNote == null) - lastSection.AddNote(note); - else - { - float timeDiff = note.time - lastNote.time; - if (timeDiff <= maxNoteTimeDiff) - lastSection.AddNote(note); - else - { - lastSection.CalculateData(); - mapData.Add(lastSection); - lastSection = new NoteSection(); - lastSection.AddNote(note); - } - } - } - lastSection.CalculateData(); - mapData.Add(lastSection); - mapData.RemoveAll(x => x.NoteCount() < 3); - mapData.RemoveAll(x => x.SectionDuration == 0); - bool alreadyMirrored = leftHanded; - int leftNotes = mapNotes.Count(x => x.colorType == ColorType.ColorA); - int rightNotes = mapNotes.Count(x => x.colorType == ColorType.ColorB); - Logging.logger.Debug($"\nLeft Notes {leftNotes}\nRight Notes {rightNotes}"); - float leftTime = mapData.Where(x => !x.RightIsLeading).Sum(x => x.SectionDuration); - float rightTime = mapData.Where(x => x.RightIsLeading).Sum(x => x.SectionDuration); - Logging.logger.Debug($"\nLeft Time: {leftTime}\nRight Time: {rightTime}\n" + - $"Left Sections{mapData.Count(x => !x.RightIsLeading)}\nRight Sections{mapData.Count(x => x.RightIsLeading)}"); - if((rightTime > leftTime && !alreadyMirrored) || (leftTime > rightTime && alreadyMirrored)) - { - Logging.logger.Debug($"Mirroring Map. \"Left Handed\" Mode Active? {alreadyMirrored}"); - leftHanded = true; - // __result = BeatmapDataMirrorTransform.CreateTransformedData(__result); - - } - } - } - */ - } diff --git a/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs b/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs index 36c19fe..32ee6b3 100644 --- a/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs +++ b/source/SongCore/HarmonyPatches/CosmeticCharacteristicsPatches.cs @@ -1,16 +1,11 @@ -using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; using HarmonyLib; using HMUI; using SongCore.Data; using SongCore.Utilities; using UnityEngine; -using static IPA.Logging.Logger; namespace SongCore.HarmonyPatches { @@ -91,7 +86,6 @@ private static void Postfix(GameplayCoreInstaller __instance) [HarmonyPatch(nameof(BeatmapCharacteristicSegmentedControlController.SetData), MethodType.Normal)] internal class CosmeticCharacteristicsPatch { - // public static OverrideClasses.CustomLevel previouslySelectedSong = null; private static void Postfix(BeatmapCharacteristicSegmentedControlController __instance, IReadOnlyList difficultyBeatmapSets, BeatmapCharacteristicSO selectedBeatmapCharacteristic) { if (!Plugin.Configuration.DisplayCustomCharacteristics) return; diff --git a/source/SongCore/HarmonyPatches/CustomCharacteristicsPatch.cs b/source/SongCore/HarmonyPatches/CustomCharacteristicsPatch.cs index 29b3d86..3963268 100644 --- a/source/SongCore/HarmonyPatches/CustomCharacteristicsPatch.cs +++ b/source/SongCore/HarmonyPatches/CustomCharacteristicsPatch.cs @@ -7,7 +7,6 @@ namespace SongCore.HarmonyPatches [HarmonyPatch(nameof(BeatmapCharacteristicCollection.GetBeatmapCharacteristicBySerializedName), MethodType.Normal)] internal class CustomCharacteristicsPatch { - // public static OverrideClasses.CustomLevel previouslySelectedSong = null; private static void Postfix(string serializedName, ref BeatmapCharacteristicSO __result) { if (__result == null) diff --git a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs index 273004a..ccc27a2 100644 --- a/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs +++ b/source/SongCore/HarmonyPatches/CustomSongColorsPatch.cs @@ -82,8 +82,6 @@ private static void Prefix(ref IDifficultyBeatmap difficultyBeatmap, ref ColorSc : Utils.ColorFromMapColor(songData._obstacleColor); overrideColorScheme = new ColorScheme("SongCoreMapColorScheme", "SongCore Map Color Scheme", true, "SongCore Map Color Scheme", false, saberLeft, saberRight, envLeft, envRight, envWhite, true, envLeftBoost, envRightBoost, envWhiteBoost, obstacle); - overrideColorScheme._environmentColorW = envWhite; - overrideColorScheme._environmentColorWBoost = envWhiteBoost; } } } diff --git a/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs b/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs index e0fc5ce..c9a5ced 100644 --- a/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs +++ b/source/SongCore/HarmonyPatches/LevelSelectionPatch.cs @@ -12,9 +12,6 @@ private static void Postfix(LevelListTableCell __instance, IPreviewBeatmapLevel // Rounding BPM display for all maps, including official ones __instance._songBpmText.text = System.Math.Round(level.beatsPerMinute).ToString(CultureInfo.InvariantCulture); - /* Plan B - IPA.Utilities.Async.UnityMainThreadTaskScheduler.Factory.StartNew( async () => { var token = new CancellationTokenSource().Token; var audio = await level.GetPreviewAudioClipAsync(token); customLevel.SetField("_songDuration", audio.length); ____songDurationText.text = customLevel.songDuration.MinSecDurationText(); }); - */ if (!string.IsNullOrWhiteSpace(level.levelAuthorName)) { __instance._songAuthorText.richText = true; diff --git a/source/SongCore/HarmonyPatches/LoadingPatches.cs b/source/SongCore/HarmonyPatches/LoadingPatches.cs index a18e6f3..eec1da3 100644 --- a/source/SongCore/HarmonyPatches/LoadingPatches.cs +++ b/source/SongCore/HarmonyPatches/LoadingPatches.cs @@ -1,71 +1,10 @@ using HarmonyLib; -using IPA.Utilities; using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using UnityEngine; using System.Collections.Generic; using SongCore.Utilities; namespace SongCore.HarmonyPatches { - /* - [HarmonyPatch(typeof(NUnit.Framework.Assert), nameof(NUnit.Framework.Assert.IsTrue), typeof(bool), typeof(string), typeof(object[]))] - internal class WhyIsAssertMeanPatch - { - private static void Prefix(ref bool condition) - { - if (condition) - { - return; - } - - var stack = new StackTrace(); - for (var i = 0; i < stack.FrameCount; i++) - { - var callingMethodName = stack.GetFrame(i).GetMethod().Name; - if (callingMethodName.Contains("AddBeatmapEventData") || callingMethodName.Contains("AddBeatmapObjectData")) - { - Utilities.Logging.Logger.Debug("Blocking Assert Failure"); - condition = true; - return; - } - } - } - } - - [HarmonyPatch(typeof(NUnit.Framework.Assert), "LessOrEqual", typeof(float), typeof(float), typeof(string), typeof(object[]))] - internal class WhyIsAssertMeanPatch2 - { - private static bool Prefix() - { - return false; - } - } - - [HarmonyPatch(typeof(NUnit.Framework.Assert), "GreaterOrEqual", typeof(float), typeof(float), typeof(string), typeof(object[]))] - internal class WhyIsAssertMeanPatch3 - { - private static bool Prefix() - { - return false; - } - } - - [HarmonyPatch(typeof(BeatmapData), new[] - { - typeof(int) - })] - [HarmonyPatch(MethodType.Constructor)] - internal class InitializePreviousAddedBeatmapEventDataTime - { - private static void Postfix(ref float ____prevAddedBeatmapEventDataTime, ref float ____prevAddedBeatmapObjectDataTime) - { - ____prevAddedBeatmapEventDataTime = float.MinValue; - ____prevAddedBeatmapObjectDataTime = float.MinValue; - } - } - */ [HarmonyPatch(typeof(CustomBeatmapLevel))] [HarmonyPatch(new[] { diff --git a/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs b/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs index 2bdbafc..9540c14 100644 --- a/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs +++ b/source/SongCore/HarmonyPatches/StandardLevelDetailViewRefreshContent.cs @@ -3,7 +3,6 @@ using SongCore.UI; using System.Collections.Generic; using System.Linq; -using UnityEngine.UI; using SongCore.Utilities; namespace SongCore.HarmonyPatches diff --git a/source/SongCore/Loader.cs b/source/SongCore/Loader.cs index a9a8d2f..1265823 100644 --- a/source/SongCore/Loader.cs +++ b/source/SongCore/Loader.cs @@ -112,7 +112,6 @@ internal void CancelSongLoading() _loadingCancelled = true; AreSongsLoading = false; LoadingProgress = 0; - StopAllCoroutines(); _progressBar.ShowMessage("Loading cancelled\nPress Ctrl+R to refresh"); } @@ -611,7 +610,6 @@ void AddOfficialPackCollection(IBeatmapLevelPackCollection packCollection) //Handle LevelPacks if (CustomBeatmapLevelPackCollectionSO == null || CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.Length == 0) { - // var beatmapLevelPackCollectionSO = Resources.FindObjectsOfTypeAll().FirstOrDefault(); CustomBeatmapLevelPackCollectionSO = await UnityMainThreadTaskScheduler.Factory.StartNew(SongCoreBeatmapLevelPackCollectionSO.CreateNew); #region CreateLevelPacks @@ -683,10 +681,6 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => { Logging.Logger.Warn($"Song Loading Task Cancelled."); } - - // await IPA.Utilities.Async.UnityMainThreadTaskScheduler.Factory.StartNew(finish).ConfigureAwait(false); - // _loadingTask = new HMTask(job, finish); - // _loadingTask.Run(); } /// diff --git a/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs b/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs index 723dca5..9f139ee 100644 --- a/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs +++ b/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs @@ -6,10 +6,6 @@ public class SongCoreBeatmapLevelPackCollectionSO : BeatmapLevelPackCollectionSO { internal readonly List _customBeatmapLevelPacks = new List(); - public SongCoreBeatmapLevelPackCollectionSO() - { - } - public static SongCoreBeatmapLevelPackCollectionSO CreateNew() { var newCollection = CreateInstance(); diff --git a/source/SongCore/Plugin.cs b/source/SongCore/Plugin.cs index 5a19ddd..9645bbe 100644 --- a/source/SongCore/Plugin.cs +++ b/source/SongCore/Plugin.cs @@ -44,30 +44,7 @@ public void Init(IPALogger pluginLogger, PluginMetadata metadata) [OnStart] public void OnApplicationStart() { - // TODO: Remove this migration path at some point - var songCoreIniPath = Path.Combine(UnityGame.UserDataPath, nameof(SongCore), "SongCore.ini"); - if (File.Exists(songCoreIniPath)) - { - var modPrefs = new BS_Utils.Utilities.Config("SongCore/SongCore"); - - Configuration.CustomSongPlatforms = modPrefs.GetBool("SongCore", "customSongPlatforms", true, true); - Configuration.DisplayDiffLabels = modPrefs.GetBool("SongCore", "displayDiffLabels", true, true); - Configuration.ForceLongPreviews = modPrefs.GetBool("SongCore", "forceLongPreviews", false, true); - - //Delete Old Config - try - { - File.Delete(songCoreIniPath); - } - catch - { - Logging.Logger.Warn("Failed to delete old config file!"); - } - } - - BSMLSettings.instance.AddSettingsMenu("SongCore", "SongCore.UI.settings.bsml", new SCSettingsController()); - SceneManager.activeSceneChanged += OnActiveSceneChanged; _harmony = Harmony.CreateAndPatchAll(_metadata.Assembly, "com.kyle1413.BeatSaber.SongCore"); @@ -128,16 +105,6 @@ private void BSEvents_levelSelected(LevelCollectionViewController arg1, IPreview } } - private void OnActiveSceneChanged(Scene prevScene, Scene nextScene) - { - Object.Destroy(GameObject.Find("SongCore Color Setter")); - - if (nextScene.name == "MenuViewControllers") - { - BS_Utils.Gameplay.Gamemode.Init(); - } - } - [OnExit] public void OnApplicationExit() { diff --git a/source/SongCore/SongCore.csproj b/source/SongCore/SongCore.csproj index 7e1f3ba..276798d 100644 --- a/source/SongCore/SongCore.csproj +++ b/source/SongCore/SongCore.csproj @@ -24,10 +24,6 @@ $(BeatSaberDir)\Libs\0Harmony.dll False - - $(BeatSaberDir)\Beat Saber_Data\Managed\AdditionalContentModel.Interfaces.dll - false - $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.AppFlow.dll false @@ -53,10 +49,6 @@ False True - - $(BeatSaberDir)\Beat Saber_Data\Managed\GameplayCore.dll - False - $(BeatSaberDir)\Beat Saber_Data\Managed\HMLib.dll False From aa3b9ba9e44a25452412b49dc098e05a868997b3 Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Thu, 18 Jan 2024 07:57:13 -0500 Subject: [PATCH 5/7] Rework startup process of `Loader` and some minor cleanups --- source/SongCore/Loader.cs | 195 ++++++++---------- .../SongCoreBeatmapLevelPackCollectionSO.cs | 7 +- source/SongCore/Plugin.cs | 20 +- source/SongCore/UI/ColorsUI.cs | 2 +- source/SongCore/UI/RequirementsUI.cs | 4 +- source/SongCore/Utilities/Hashing.cs | 4 +- 6 files changed, 108 insertions(+), 124 deletions(-) diff --git a/source/SongCore/Loader.cs b/source/SongCore/Loader.cs index 1265823..ff1cf7e 100644 --- a/source/SongCore/Loader.cs +++ b/source/SongCore/Loader.cs @@ -19,15 +19,31 @@ namespace SongCore { public class Loader : MonoBehaviour { + private ProgressBar _progressBar; + private GameScenesManager _gameScenesManager; + private LevelFilteringNavigationController _levelFilteringNavigationController; + private Task? _loadingTask; + private CancellationTokenSource _loadingTaskCancellationTokenSource = new CancellationTokenSource(); + private bool _loadingCancelled; + private bool _isInitialized; + private string _customWIPPath; + private string _customLevelsPath; + // Actions for loading and refreshing beatmaps public static event Action? LoadingStartedEvent; public static event Action>? SongsLoadedEvent; public static event Action? OnLevelPacksRefreshed; public static event Action? DeletingSong; + + private static readonly ConcurrentDictionary OfficialSongs = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary CustomLevelsById = new ConcurrentDictionary(); public static ConcurrentDictionary CustomLevels = new ConcurrentDictionary(); public static ConcurrentDictionary CustomWIPLevels = new ConcurrentDictionary(); public static ConcurrentDictionary CachedWIPLevels = new ConcurrentDictionary(); public static readonly List SeperateSongFolders = new List(); + public static Sprite defaultCoverImage; + public static Loader Instance; + public static SongCoreCustomLevelCollection? CustomLevelsCollection { get; private set; } public static SongCoreCustomLevelCollection? WIPLevelsCollection { get; private set; } public static SongCoreCustomLevelCollection? CachedWIPLevelCollection { get; private set; } @@ -35,112 +51,85 @@ public class Loader : MonoBehaviour public static SongCoreCustomBeatmapLevelPack? WIPLevelsPack { get; private set; } public static SongCoreCustomBeatmapLevelPack? CachedWIPLevelsPack { get; private set; } public static SongCoreBeatmapLevelPackCollectionSO? CustomBeatmapLevelPackCollectionSO { get; private set; } - - private static readonly ConcurrentDictionary OfficialSongs = new ConcurrentDictionary(); - - private static readonly ConcurrentDictionary CustomLevelsById = new ConcurrentDictionary(); - public static bool AreSongsLoaded { get; private set; } public static bool AreSongsLoading { get; private set; } - public static float LoadingProgress { get; internal set; } - internal ProgressBar _progressBar; - private Task? _loadingTask; - private CancellationTokenSource _loadingTaskCancellationTokenSource = new CancellationTokenSource(); - private bool _loadingCancelled; - - internal static CustomLevelLoader _customLevelLoader; - - public static BeatmapLevelsModel BeatmapLevelsModelSO - { - get - { - if (_beatmapLevelsModel == null) - { - _beatmapLevelsModel = FindObjectOfType(); - } - - return _beatmapLevelsModel; - } - } - - internal static BeatmapLevelsModel _beatmapLevelsModel; - public static Sprite defaultCoverImage; + public static float LoadingProgress { get; private set; } + public static BeatmapLevelsModel BeatmapLevelsModelSO { get; private set; } + public static CustomLevelLoader CustomLevelLoader { get; private set; } public static CachedMediaAsyncLoader cachedMediaAsyncLoaderSO { get; private set; } public static BeatmapCharacteristicCollection beatmapCharacteristicCollection { get; private set; } - public static Loader Instance; - - public static void OnLoad() - { - if (Instance != null) - { - _beatmapLevelsModel = null; - Instance.RefreshLevelPacks(); - return; - } - - new GameObject("SongCore Loader").AddComponent(); - } - - private string _customWIPPath; - private string _customLevelsPath; - private void Awake() { _customWIPPath = Path.Combine(Application.dataPath, "CustomWIPLevels"); _customLevelsPath = Path.GetFullPath(CustomLevelPathHelper.customLevelsDirectoryPath); - _ = BeatmapLevelsModelSO; // This is to cache the BeatmapLevelsModel while we're on the main thread, since we need to access it when we're not on the main thread (which Unity debug doesn't like). - - Instance = this; _progressBar = ProgressBar.Create(); - MenuLoaded(); - Hashing.ReadCachedSongHashes(); - Hashing.ReadCachedAudioData(); + Instance = this; DontDestroyOnLoad(gameObject); - BS_Utils.Utilities.BSEvents.menuSceneLoaded += MenuLoaded; - Initialize(); } private void Initialize() { - RefreshSongs(); + BS_Utils.Utilities.BSEvents.menuSceneLoaded += MenuLoaded; + _gameScenesManager.transitionDidStartEvent += CancelSongLoading; + Hashing.ReadCachedSongHashes(); + Hashing.ReadCachedAudioData(); + _isInitialized = true; } - internal void CancelSongLoading() + internal void MenuLoadedFresh() { - _loadingTaskCancellationTokenSource.Cancel(); - _loadingCancelled = true; - AreSongsLoading = false; - LoadingProgress = 0; - _progressBar.ShowMessage("Loading cancelled\nPress Ctrl+R to refresh"); + // Ensures that the static references are still valid Unity objects. + // They'll be destroyed on internal restart. + _gameScenesManager = FindObjectOfType(); + _levelFilteringNavigationController = FindObjectOfType(true); + BeatmapLevelsModelSO = FindObjectOfType(); + CustomLevelLoader = FindObjectOfType(); + cachedMediaAsyncLoaderSO = CustomLevelLoader._cachedMediaAsyncLoader; + defaultCoverImage = CustomLevelLoader._defaultPackCover; + beatmapCharacteristicCollection = CustomLevelLoader._beatmapCharacteristicCollection; + BS_Utils.Gameplay.Gamemode.Init(); + + if (_isInitialized) + { + Instance.RefreshLevelPacks(); + } + else + { + Initialize(); + RefreshSongs(); + } + + MenuLoaded(); } - internal void MenuLoaded() + private void MenuLoaded() { - if (AreSongsLoading) + if (_loadingCancelled) { - //Scene changing while songs are loading. Since we are using a separate thread while loading, this is bad and could cause a crash. - //So we have to stop loading. - if (_loadingTask != null) - { - //_loadingTask.Cancel(); - CancelSongLoading(); - Logging.Logger.Info("Loading was cancelled by player since they loaded another scene."); - } + RefreshSongs(); } + } - BS_Utils.Gameplay.Gamemode.Init(); - if (_customLevelLoader == null) + private void CancelSongLoading(float minDuration) + { + CancelSongLoading(); + } + + private void CancelSongLoading() + { + if (AreSongsLoading) { - _customLevelLoader = FindObjectOfType(); - defaultCoverImage = _customLevelLoader._defaultPackCover; - cachedMediaAsyncLoaderSO = _customLevelLoader._cachedMediaAsyncLoader; - beatmapCharacteristicCollection = _customLevelLoader._beatmapCharacteristicCollection; + _loadingTaskCancellationTokenSource.Cancel(); + _loadingCancelled = true; + AreSongsLoading = false; + LoadingProgress = 0; + _progressBar.ShowMessage("Loading cancelled\nPress Ctrl+R to refresh"); } } /// - /// This fuction will add/remove Level Packs from the Custom Levels tab if applicable + /// This function will add/remove Level Packs from the Custom Levels tab if applicable /// public async void RefreshLevelPacks() { @@ -148,13 +137,13 @@ public async void RefreshLevelPacks() WIPLevelsCollection?.UpdatePreviewLevels(CustomWIPLevels.Values.OrderBy(l => l.songName).ToArray()); CachedWIPLevelCollection?.UpdatePreviewLevels(CachedWIPLevels.Values.OrderBy(l => l.songName).ToArray()); - if (CachedWIPLevelsPack != null) + if (CachedWIPLevelsPack != null && CustomBeatmapLevelPackCollectionSO != null) { - if (CachedWIPLevels.Count > 0 && !CustomBeatmapLevelPackCollectionSO._customBeatmapLevelPacks.Contains(CachedWIPLevelsPack)) + if (CachedWIPLevels.Count > 0) { CustomBeatmapLevelPackCollectionSO.AddLevelPack(CachedWIPLevelsPack); } - else if (CachedWIPLevels.Count == 0 && CustomBeatmapLevelPackCollectionSO._customBeatmapLevelPacks.Contains(CachedWIPLevelsPack)) + else if (CachedWIPLevels.Count == 0) { CustomBeatmapLevelPackCollectionSO.RemoveLevelPack(CachedWIPLevelsPack); } @@ -165,39 +154,27 @@ public async void RefreshLevelPacks() if (folderEntry.SongFolderEntry.Pack == FolderLevelPack.NewPack) { folderEntry.LevelCollection.UpdatePreviewLevels(folderEntry.Levels.Values.OrderBy(l => l.songName).ToArray()); - if (folderEntry.Levels.Count > 0 || (folderEntry is ModSeperateSongFolder { AlwaysShow: true })) + if (CustomBeatmapLevelPackCollectionSO != null && (folderEntry.Levels.Count > 0 || folderEntry is ModSeperateSongFolder { AlwaysShow: true })) { - if (!CustomBeatmapLevelPackCollectionSO._customBeatmapLevelPacks.Contains(folderEntry.LevelPack)) - { - CustomBeatmapLevelPackCollectionSO.AddLevelPack(folderEntry.LevelPack); - } + CustomBeatmapLevelPackCollectionSO.AddLevelPack(folderEntry.LevelPack); } } } BeatmapLevelsModelSO._customLevelPackCollection = CustomBeatmapLevelPackCollectionSO; - await UnityMainThreadTaskScheduler.Factory.StartNew(() => + BeatmapLevelsModelSO.UpdateAllLoadedBeatmapLevelPacks(); + BeatmapLevelsModelSO.UpdateLoadedPreviewLevels(); + if (_levelFilteringNavigationController.isActiveAndEnabled) { - BeatmapLevelsModelSO.UpdateAllLoadedBeatmapLevelPacks(); - BeatmapLevelsModelSO.UpdateLoadedPreviewLevels(); - var filterNav = FindObjectOfType(); - if (filterNav != null && filterNav.isActiveAndEnabled) - { - filterNav.UpdateCustomSongs(); - } + _levelFilteringNavigationController.UpdateCustomSongs(); + } - OnLevelPacksRefreshed?.Invoke(); - }); + OnLevelPacksRefreshed?.Invoke(); } public void RefreshSongs(bool fullRefresh = true) { - if (SceneManager.GetActiveScene().name == "GameCore") - { - return; - } - - if (AreSongsLoading) + if (AreSongsLoading || SceneManager.GetActiveScene().name == BS_Utils.SceneNames.Game) { return; } @@ -233,7 +210,6 @@ private async void RetrieveAllSongs(bool fullRefresh) // Clear all beatmap dictionaries on full refresh if (fullRefresh) { - CustomBeatmapLevelPackCollectionSO = null; CustomLevels.Clear(); CustomWIPLevels.Clear(); CachedWIPLevels.Clear(); @@ -610,7 +586,14 @@ void AddOfficialPackCollection(IBeatmapLevelPackCollection packCollection) //Handle LevelPacks if (CustomBeatmapLevelPackCollectionSO == null || CustomBeatmapLevelPackCollectionSO.beatmapLevelPacks.Length == 0) { - CustomBeatmapLevelPackCollectionSO = await UnityMainThreadTaskScheduler.Factory.StartNew(SongCoreBeatmapLevelPackCollectionSO.CreateNew); + if (CustomBeatmapLevelPackCollectionSO == null) + { + CustomBeatmapLevelPackCollectionSO = await UnityMainThreadTaskScheduler.Factory.StartNew(SongCoreBeatmapLevelPackCollectionSO.CreateNew); + } + else + { + CustomBeatmapLevelPackCollectionSO.ClearLevelPacks(); + } #region CreateLevelPacks @@ -814,8 +797,8 @@ private void DeleteSingleSong(string folderPath, bool deleteFolder) var shufflePeriod = saveData.shufflePeriod; var previewStartTime = saveData.previewStartTime; var previewDuration = saveData.previewDuration; - EnvironmentInfoSO environmentSceneInfo = _customLevelLoader.LoadEnvironmentInfo(saveData.environmentName, false); - EnvironmentInfoSO allDirectionEnvironmentInfo = _customLevelLoader.LoadEnvironmentInfo(saveData.allDirectionsEnvironmentName, true); + EnvironmentInfoSO environmentSceneInfo = CustomLevelLoader.LoadEnvironmentInfo(saveData.environmentName, false); + EnvironmentInfoSO allDirectionEnvironmentInfo = CustomLevelLoader.LoadEnvironmentInfo(saveData.allDirectionsEnvironmentName, true); PreviewDifficultyBeatmapSet[] beatmapsets = new PreviewDifficultyBeatmapSet[saveData.difficultyBeatmapSets.Length]; for (var i = 0; i < saveData.difficultyBeatmapSets.Length; i++) @@ -866,7 +849,7 @@ private void DeleteSingleSong(string folderPath, bool deleteFolder) environmentInfos = new EnvironmentInfoSO[saveData.environmentNames.Length]; for (var i = 0; i < saveData.environmentNames.Length; i++) { - environmentInfos[i] = _customLevelLoader._environmentSceneInfoCollection.GetEnvironmentInfoBySerializedName(saveData.environmentNames[i]); + environmentInfos[i] = CustomLevelLoader._environmentSceneInfoCollection.GetEnvironmentInfoBySerializedName(saveData.environmentNames[i]); } } diff --git a/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs b/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs index 9f139ee..78dce26 100644 --- a/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs +++ b/source/SongCore/OverrideClasses/SongCoreBeatmapLevelPackCollectionSO.cs @@ -4,7 +4,7 @@ namespace SongCore.OverrideClasses { public class SongCoreBeatmapLevelPackCollectionSO : BeatmapLevelPackCollectionSO { - internal readonly List _customBeatmapLevelPacks = new List(); + private readonly List _customBeatmapLevelPacks = new List(); public static SongCoreBeatmapLevelPackCollectionSO CreateNew() { @@ -37,6 +37,11 @@ public void RemoveLevelPack(CustomBeatmapLevelPack pack) } } + public void ClearLevelPacks() + { + _customBeatmapLevelPacks.Clear(); + } + private void UpdateArray() { _allBeatmapLevelPacks = _customBeatmapLevelPacks.ToArray(); diff --git a/source/SongCore/Plugin.cs b/source/SongCore/Plugin.cs index 9645bbe..cf9dd6d 100644 --- a/source/SongCore/Plugin.cs +++ b/source/SongCore/Plugin.cs @@ -10,9 +10,7 @@ using IPA.Config.Stores; using IPA.Loader; using UnityEngine; -using UnityEngine.SceneManagement; using IPALogger = IPA.Logging.Logger; -using Object = UnityEngine.Object; namespace SongCore { @@ -44,7 +42,7 @@ public void Init(IPALogger pluginLogger, PluginMetadata metadata) [OnStart] public void OnApplicationStart() { - BSMLSettings.instance.AddSettingsMenu("SongCore", "SongCore.UI.settings.bsml", new SCSettingsController()); + BSMLSettings.instance.AddSettingsMenu(nameof(SongCore), "SongCore.UI.settings.bsml", new SCSettingsController()); _harmony = Harmony.CreateAndPatchAll(_metadata.Assembly, "com.kyle1413.BeatSaber.SongCore"); @@ -78,21 +76,19 @@ public void OnApplicationStart() private void BSEvents_menuSceneLoadedFresh(ScenesTransitionSetupDataSO data) { - Loader.OnLoad(); + if (Loader.Instance == null) + { + new GameObject("SongCore Loader").AddComponent(); + } + + Loader.Instance!.MenuLoadedFresh(); RequirementsUI.instance.Setup(); } private void BSEvents_levelSelected(LevelCollectionViewController arg1, IPreviewBeatmapLevel level) { - if (level is CustomPreviewBeatmapLevel customLevel) + if (level is CustomPreviewBeatmapLevel customLevel && Collections.RetrieveExtraSongData(Hashing.GetCustomLevelHash(customLevel)) is { } songData) { - var songData = Collections.RetrieveExtraSongData(Hashing.GetCustomLevelHash(customLevel)); - - if (songData == null) - { - return; - } - if (Configuration.CustomSongPlatforms && !string.IsNullOrWhiteSpace(songData._customEnvironmentName)) { Logging.Logger.Debug("Custom song with platform selected"); diff --git a/source/SongCore/UI/ColorsUI.cs b/source/SongCore/UI/ColorsUI.cs index bec9866..94c622c 100644 --- a/source/SongCore/UI/ColorsUI.cs +++ b/source/SongCore/UI/ColorsUI.cs @@ -66,7 +66,7 @@ private void Parse() [UIAction("#post-parse")] private void PostParse() { - ColorSchemeView colorSchemeViewPrefab = Object.Instantiate(Resources.FindObjectsOfTypeAll().First(), selectedColorTransform); + ColorSchemeView colorSchemeViewPrefab = Object.Instantiate(Object.FindObjectOfType(true), selectedColorTransform); colorSchemeView = IPA.Utilities.ReflectionUtil.CopyComponent(colorSchemeViewPrefab, colorSchemeViewPrefab.gameObject); Object.DestroyImmediate(colorSchemeViewPrefab); modalPosition = modal.transform.localPosition; diff --git a/source/SongCore/UI/RequirementsUI.cs b/source/SongCore/UI/RequirementsUI.cs index b466723..c77bde2 100644 --- a/source/SongCore/UI/RequirementsUI.cs +++ b/source/SongCore/UI/RequirementsUI.cs @@ -83,7 +83,7 @@ public bool ButtonInteractable internal void Setup() { GetIcons(); - standardLevel = Resources.FindObjectsOfTypeAll().First(); + standardLevel = Object.FindObjectOfType(true); tweenyManager = Object.FindObjectOfType(); BSMLParser.instance.Parse(BUTTON_BSML, standardLevel.transform.Find("LevelDetail").gameObject, this); @@ -220,7 +220,7 @@ internal void ShowRequirements() { if (environmentInfoName != level.environmentInfo.serializedName) { - environmentName = Loader._customLevelLoader.LoadEnvironmentInfo(environmentInfoName, false).environmentName; + environmentName = Loader.CustomLevelLoader.LoadEnvironmentInfo(environmentInfoName, false).environmentName; } } } diff --git a/source/SongCore/Utilities/Hashing.cs b/source/SongCore/Utilities/Hashing.cs index 19de97f..8ec2a84 100644 --- a/source/SongCore/Utilities/Hashing.cs +++ b/source/SongCore/Utilities/Hashing.cs @@ -13,8 +13,8 @@ public class Hashing { internal static ConcurrentDictionary cachedSongHashData = new ConcurrentDictionary(); internal static ConcurrentDictionary cachedAudioData = new ConcurrentDictionary(); - public static readonly string cachedHashDataPath = Path.Combine(IPA.Utilities.UnityGame.InstallPath, "UserData", "SongCore", "SongHashData.dat"); - public static readonly string cachedAudioDataPath = Path.Combine(IPA.Utilities.UnityGame.InstallPath, "UserData", "SongCore", "SongDurationCache.dat"); + public static readonly string cachedHashDataPath = Path.Combine(IPA.Utilities.UnityGame.UserDataPath, nameof(SongCore), "SongHashData.dat"); + public static readonly string cachedAudioDataPath = Path.Combine(IPA.Utilities.UnityGame.UserDataPath, nameof(SongCore), "SongDurationCache.dat"); public static void ReadCachedSongHashes() { From e005f0ee95a7e778bdd69e0e175ba8b59004cd11 Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Fri, 19 Jan 2024 05:51:14 -0500 Subject: [PATCH 6/7] Keep `OnLevelPacksRefreshed` on the main thread --- source/SongCore/Loader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/SongCore/Loader.cs b/source/SongCore/Loader.cs index ff1cf7e..61ff3cc 100644 --- a/source/SongCore/Loader.cs +++ b/source/SongCore/Loader.cs @@ -169,7 +169,7 @@ public async void RefreshLevelPacks() _levelFilteringNavigationController.UpdateCustomSongs(); } - OnLevelPacksRefreshed?.Invoke(); + await UnityMainThreadTaskScheduler.Factory.StartNew(() => OnLevelPacksRefreshed?.Invoke()); } public void RefreshSongs(bool fullRefresh = true) From c12c4d5bc86ec4e472b103124c99f06f9774c29f Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Sat, 20 Jan 2024 02:00:50 -0500 Subject: [PATCH 7/7] That also should stay on the main thread --- source/SongCore/Loader.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/SongCore/Loader.cs b/source/SongCore/Loader.cs index 61ff3cc..3fbd34e 100644 --- a/source/SongCore/Loader.cs +++ b/source/SongCore/Loader.cs @@ -164,12 +164,16 @@ public async void RefreshLevelPacks() BeatmapLevelsModelSO._customLevelPackCollection = CustomBeatmapLevelPackCollectionSO; BeatmapLevelsModelSO.UpdateAllLoadedBeatmapLevelPacks(); BeatmapLevelsModelSO.UpdateLoadedPreviewLevels(); - if (_levelFilteringNavigationController.isActiveAndEnabled) + + await UnityMainThreadTaskScheduler.Factory.StartNew(() => { - _levelFilteringNavigationController.UpdateCustomSongs(); - } + if (_levelFilteringNavigationController.isActiveAndEnabled) + { + _levelFilteringNavigationController.UpdateCustomSongs(); + } - await UnityMainThreadTaskScheduler.Factory.StartNew(() => OnLevelPacksRefreshed?.Invoke()); + OnLevelPacksRefreshed?.Invoke(); + }); } public void RefreshSongs(bool fullRefresh = true)