From c016f4d09d07a5e54f25b9b936444c9729ce5b52 Mon Sep 17 00:00:00 2001 From: Moon <5924350+MatrikMoon@users.noreply.github.com> Date: Sat, 23 Mar 2024 15:37:55 -0500 Subject: [PATCH 1/7] Update to 1.34.1 --- .../Behaviors/SharedCoroutineStarter.cs | 63 +++++++++++++++++++ TournamentAssistant/ILRepack.targets | 4 +- .../Interop/CustomNotesInterop.cs | 5 +- TournamentAssistant/Plugin.cs | 5 +- TournamentAssistant/PluginClient.cs | 3 +- .../TournamentAssistant.csproj | 27 ++++++-- .../FlowCoordinators/QualifierCoordinator.cs | 4 +- .../TournamentSelectionCoordinator.cs | 2 +- .../UI/ViewControllers/SongDetail.cs | 2 +- .../Utilities/ParallelCoroutine.cs | 1 + .../Utilities/SongDownloader.cs | 3 +- TournamentAssistant/Utilities/SongUtils.cs | 26 ++++++-- TournamentAssistant/Utilities/Updater.cs | 2 +- TournamentAssistantShared/Sockets/Client.cs | 4 +- 14 files changed, 127 insertions(+), 24 deletions(-) create mode 100644 TournamentAssistant/Behaviors/SharedCoroutineStarter.cs diff --git a/TournamentAssistant/Behaviors/SharedCoroutineStarter.cs b/TournamentAssistant/Behaviors/SharedCoroutineStarter.cs new file mode 100644 index 00000000..36c85bd2 --- /dev/null +++ b/TournamentAssistant/Behaviors/SharedCoroutineStarter.cs @@ -0,0 +1,63 @@ +using System.Runtime.CompilerServices; +using UnityEngine; + +/** + * Taken with love from Zingabopp's BeatSaberPlaylistsLib + */ + +namespace TournamentAssistant.Behaviors +{ + // Mostly a copy-paste of PersistentSingleton from game version < 1.31.0. + internal class SharedCoroutineStarter : MonoBehaviour + { + private static SharedCoroutineStarter _instance; + private static object _lock = new object(); + private static bool _applicationIsQuitting; + + public static SharedCoroutineStarter instance + { + get + { + if (_applicationIsQuitting) + { + Debug.LogWarning("[Singleton] Instance '" + nameof(SharedCoroutineStarter) + "' already destroyed on application quit. Won't create again - returning null."); + return null; + } + + lock (_lock) + { + if (_instance == null) + { + _instance = FindObjectOfType(); + + if (FindObjectsOfType().Length > 1) + { + Debug.LogError("[Singleton] Something went really wrong - there should never be more than 1 singleton! Reopening the scene might fix it."); + return _instance; + } + + if (_instance == null) + { + GameObject obj = new GameObject(); + _instance = obj.AddComponent(); + obj.name = nameof(SharedCoroutineStarter); + DontDestroyOnLoad(obj); + } + } + + return _instance; + } + } + } + + protected void OnEnable() + { + DontDestroyOnLoad(this); + } + + protected virtual void OnDestroy() + { + _applicationIsQuitting = true; + } + } +} \ No newline at end of file diff --git a/TournamentAssistant/ILRepack.targets b/TournamentAssistant/ILRepack.targets index ea1d20ee..8cbb82f9 100644 --- a/TournamentAssistant/ILRepack.targets +++ b/TournamentAssistant/ILRepack.targets @@ -4,8 +4,8 @@ - - + + diff --git a/TournamentAssistant/Interop/CustomNotesInterop.cs b/TournamentAssistant/Interop/CustomNotesInterop.cs index a49792a0..faa35cfd 100644 --- a/TournamentAssistant/Interop/CustomNotesInterop.cs +++ b/TournamentAssistant/Interop/CustomNotesInterop.cs @@ -4,12 +4,13 @@ static class CustomNotesInterop { public static void EnableHMDOnly() { - CustomNotes.Utilities.LayerUtils.EnableHMDOnly(); + // Disabled until CustomNotes updates for 1.34.2 + // CustomNotes.Utilities.LayerUtils.EnableHMDOnly(); } public static void DisableHMDOnly() { - CustomNotes.Utilities.LayerUtils.DisableHMDOnly(); + // CustomNotes.Utilities.LayerUtils.DisableHMDOnly(); } } } diff --git a/TournamentAssistant/Plugin.cs b/TournamentAssistant/Plugin.cs index bfbe8dda..d7ca7162 100644 --- a/TournamentAssistant/Plugin.cs +++ b/TournamentAssistant/Plugin.cs @@ -16,6 +16,7 @@ using TournamentAssistantShared.SimpleJSON; using UnityEngine; using UnityEngine.SceneManagement; +using Zenject; using Config = TournamentAssistantShared.Config; using Random = System.Random; @@ -180,7 +181,7 @@ private void MenuButtonPressed() _tournamentSelectionCoordinator = BeatSaberUI.CreateFlowCoordinator(); _tournamentSelectionCoordinator.DidFinishEvent += modeSelectionCoordinator_DidFinishEvent; - _mainFlowCoordinator.PresentFlowCoordinatorOrAskForTutorial(_tournamentSelectionCoordinator); + _mainFlowCoordinator.InvokeMethod("PresentFlowCoordinatorOrAskForTutorial", _tournamentSelectionCoordinator); } private void modeSelectionCoordinator_DidFinishEvent() @@ -193,7 +194,7 @@ private void modeSelectionCoordinator_DidFinishEvent() public void Dispose() { - if (MenuButtons.IsSingletonAvailable && MenuButtons.instance) + if (MenuButtons.instance != null) { MenuButtons.instance.UnregisterButton(menuButton); } diff --git a/TournamentAssistant/PluginClient.cs b/TournamentAssistant/PluginClient.cs index 4dca240b..a9e955e9 100644 --- a/TournamentAssistant/PluginClient.cs +++ b/TournamentAssistant/PluginClient.cs @@ -89,7 +89,8 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => : EnvironmentEffectsFilterPreset.AllEffects, playSong.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.StaticLights) ? EnvironmentEffectsFilterPreset.NoEffects - : EnvironmentEffectsFilterPreset.AllEffects + : EnvironmentEffectsFilterPreset.AllEffects, + 0.7f ); } diff --git a/TournamentAssistant/TournamentAssistant.csproj b/TournamentAssistant/TournamentAssistant.csproj index 2f556da3..7c9d807d 100644 --- a/TournamentAssistant/TournamentAssistant.csproj +++ b/TournamentAssistant/TournamentAssistant.csproj @@ -42,11 +42,26 @@ $(BeatSaberDir)\Libs\0Harmony.dll False + + $(BeatSaberDir)\Beat Saber_Data\Managed\AdditionalContentModel.Interfaces.dll + False + False + False $(BeatSaberDir)\Beat Saber_Data\Managed\BeatmapCore.dll False + + $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.AppFlow.dll + False + False + + + $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.UnityExtension.dll + False + False + False $(BeatSaberDir)\Plugins\BSML.dll @@ -75,6 +90,11 @@ $(BeatSaberDir)\Beat Saber_Data\Managed\GameplayCore.dll False + + $(BeatSaberDir)\Beat Saber_Data\Managed\PlatformUserModel.dll + False + False + ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll @@ -118,12 +138,6 @@ $(BeatSaberDir)\Beat Saber_Data\Managed\Polyglot.dll False - - ..\packages\protobuf-net.3.1.0\lib\net461\protobuf-net.dll - - - ..\packages\protobuf-net.Core.3.1.0\lib\net461\protobuf-net.Core.dll - False $(BeatSaberDir)\Plugins\SongCore.dll @@ -240,6 +254,7 @@ + diff --git a/TournamentAssistant/UI/FlowCoordinators/QualifierCoordinator.cs b/TournamentAssistant/UI/FlowCoordinators/QualifierCoordinator.cs index b3c6fd2c..b28874ab 100644 --- a/TournamentAssistant/UI/FlowCoordinators/QualifierCoordinator.cs +++ b/TournamentAssistant/UI/FlowCoordinators/QualifierCoordinator.cs @@ -15,7 +15,6 @@ using UnityEngine.UI; using static TournamentAssistantShared.Models.GameplayModifiers; using static TournamentAssistantShared.Models.PlayerSpecificSettings; -using Logger = TournamentAssistantShared.Logger; namespace TournamentAssistant.UI.FlowCoordinators { @@ -162,7 +161,8 @@ private void SongDetail_didPressPlayButtonEvent(IBeatmapLevel level, BeatmapChar _currentMap.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.ArcsHapticFeedback), (ArcVisibilityType)_currentMap.GameplayParameters.PlayerSettings.arc_visibility_type, _currentMap.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.StaticLights) ? EnvironmentEffectsFilterPreset.NoEffects : EnvironmentEffectsFilterPreset.AllEffects, - _currentMap.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.StaticLights) ? EnvironmentEffectsFilterPreset.NoEffects : EnvironmentEffectsFilterPreset.AllEffects + _currentMap.GameplayParameters.PlayerSettings.Options.HasFlag(PlayerOptions.StaticLights) ? EnvironmentEffectsFilterPreset.NoEffects : EnvironmentEffectsFilterPreset.AllEffects, + 0.7f ); } diff --git a/TournamentAssistant/UI/FlowCoordinators/TournamentSelectionCoordinator.cs b/TournamentAssistant/UI/FlowCoordinators/TournamentSelectionCoordinator.cs index 8d99e9fd..5d7fcfe3 100644 --- a/TournamentAssistant/UI/FlowCoordinators/TournamentSelectionCoordinator.cs +++ b/TournamentAssistant/UI/FlowCoordinators/TournamentSelectionCoordinator.cs @@ -127,7 +127,7 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => // If the user is not already in the tournament, join it else if (!client.StateManager.GetTournament(tournament.Guid).Users.Any(x => x.Guid == client.StateManager.GetSelfGuid())) { - _splashScreen = BeatSaberUI.CreateViewController(); + _splashScreen = BeatSaberUI.CreateViewController(); _splashScreen.TitleText = Plugin.GetLocalized("tournament_list"); _splashScreen.StatusText = "Joining tournament..."; SetBackButtonInteractivity(false); diff --git a/TournamentAssistant/UI/ViewControllers/SongDetail.cs b/TournamentAssistant/UI/ViewControllers/SongDetail.cs index b120f1fa..73a5d4dd 100644 --- a/TournamentAssistant/UI/ViewControllers/SongDetail.cs +++ b/TournamentAssistant/UI/ViewControllers/SongDetail.cs @@ -135,7 +135,7 @@ public void UpdateContent() if (_selectedLevel != null) { songNameText.text = _selectedLevel.songName; - durationText.text = _selectedLevel.beatmapLevelData.audioClip.length.MinSecDurationText(); + durationText.text = $"{_selectedLevel.beatmapLevelData.audioClip.length}:F2"; // Keep an eye on this one, not sure it's right after update bpmText.text = Mathf.RoundToInt(_selectedLevel.beatsPerMinute).ToString(); if (_selectedDifficultyBeatmap != null) diff --git a/TournamentAssistant/Utilities/ParallelCoroutine.cs b/TournamentAssistant/Utilities/ParallelCoroutine.cs index 92feb487..eb1f20b8 100644 --- a/TournamentAssistant/Utilities/ParallelCoroutine.cs +++ b/TournamentAssistant/Utilities/ParallelCoroutine.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Linq; +using TournamentAssistant.Behaviors; using UnityEngine; namespace TournamentAssistant.Utilities diff --git a/TournamentAssistant/Utilities/SongDownloader.cs b/TournamentAssistant/Utilities/SongDownloader.cs index 3c8a5a3d..9c27d9f4 100644 --- a/TournamentAssistant/Utilities/SongDownloader.cs +++ b/TournamentAssistant/Utilities/SongDownloader.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.IO.Compression; +using TournamentAssistant.Behaviors; using TournamentAssistantShared; using UnityEngine; using UnityEngine.Networking; @@ -69,7 +70,7 @@ private static IEnumerator DownloadSong_internal(string hash, bool refreshWhenDo } } - if (www.isNetworkError || www.isHttpError || timeout) + if (www.result == UnityWebRequest.Result.ConnectionError || www.result == UnityWebRequest.Result.ProtocolError || timeout) { Logger.Error($"Error downloading song {hash}: {www.error}"); songDownloaded?.Invoke($"custom_level_{hash.ToUpper()}", false); diff --git a/TournamentAssistant/Utilities/SongUtils.cs b/TournamentAssistant/Utilities/SongUtils.cs index 35a4ba17..a90c01e9 100644 --- a/TournamentAssistant/Utilities/SongUtils.cs +++ b/TournamentAssistant/Utilities/SongUtils.cs @@ -125,11 +125,14 @@ float hjd(float bpm, float njs, float offset) return njs * (60f / bpm) * hjd(bpm, njs, offset) * 2; } - public static async Task HasDLCLevel(string levelId, AdditionalContentModel additionalContentModel = null) + public static async Task HasDLCLevel(string levelId) { + AdditionalContentModel additionalContentModel = null; + await UnityMainThreadTaskScheduler.Factory.StartNew(() => { - additionalContentModel ??= Resources.FindObjectsOfTypeAll().FirstOrDefault(); + var beatmapLevelsModel = Resources.FindObjectsOfTypeAll().FirstOrDefault(); + additionalContentModel = beatmapLevelsModel.GetField("_additionalContentModel"); }); if (additionalContentModel != null) @@ -138,7 +141,7 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => getStatusCancellationTokenSource = new CancellationTokenSource(); var token = getStatusCancellationTokenSource.Token; - return await additionalContentModel.GetLevelEntitlementStatusAsync(levelId, token) == AdditionalContentModel.EntitlementStatus.Owned; + return await additionalContentModel.GetLevelEntitlementStatusAsync(levelId, token) == EntitlementStatus.Owned; } return false; @@ -179,13 +182,28 @@ public static async void PlaySong(IPreviewBeatmapLevel level, BeatmapCharacteris { Action SongLoaded = (loadedLevel) => { + var difficultyBeatmap = loadedLevel.beatmapLevelData.GetDifficultyBeatmap(characteristic, difficulty); + + // Try to get overridden colors if this is a custom level + ColorScheme beatmapOverrideColorScheme = null; + CustomBeatmapLevel customBeatmapLevel = loadedLevel as CustomBeatmapLevel; + if (customBeatmapLevel != null) + { + CustomDifficultyBeatmap customDifficultyBeatmap = difficultyBeatmap as CustomDifficultyBeatmap; + if (customDifficultyBeatmap != null) + { + beatmapOverrideColorScheme = customBeatmapLevel.GetBeatmapLevelColorScheme(customDifficultyBeatmap.beatmapColorSchemeIdx); + } + } + MenuTransitionsHelper _menuSceneSetupData = Resources.FindObjectsOfTypeAll().First(); _menuSceneSetupData.StartStandardLevel( "Solo", - loadedLevel.beatmapLevelData.GetDifficultyBeatmap(characteristic, difficulty), + difficultyBeatmap, loadedLevel, overrideEnvironmentSettings, colorScheme, + beatmapOverrideColorScheme, gameplayModifiers ?? new GameplayModifiers(), playerSettings ?? new PlayerSpecificSettings(), null, diff --git a/TournamentAssistant/Utilities/Updater.cs b/TournamentAssistant/Utilities/Updater.cs index 568d1541..f5b7cb7f 100644 --- a/TournamentAssistant/Utilities/Updater.cs +++ b/TournamentAssistant/Utilities/Updater.cs @@ -15,7 +15,7 @@ public static class Updater { //For easy switching if those ever changed //Moon's note: while the repo url is unlikely to change, the filenames are free game. I type and upload those manually, after all - private static readonly string _repoURL = "https://github.com/MatrikMoon/TournamentAssistant/releases/latest"; + // private static readonly string _repoURL = "https://github.com/MatrikMoon/TournamentAssistant/releases/latest"; private static readonly string _repoAPI = "https://api.github.com/repos/MatrikMoon/TournamentAssistant/releases/latest"; public static async Task GetLatestRelease() diff --git a/TournamentAssistantShared/Sockets/Client.cs b/TournamentAssistantShared/Sockets/Client.cs index 66f3bdd6..2a55fe42 100644 --- a/TournamentAssistantShared/Sockets/Client.cs +++ b/TournamentAssistantShared/Sockets/Client.cs @@ -56,7 +56,9 @@ public async Task Start() var client = player.socket; //Try to authenticate with SSL - player.sslStream = new SslStream(new NetworkStream(client, ownsSocket: true)); + //TODO: I believe a unity bug is keeping validation from functioning properly. Once the unity version changes, + //we should ABSOLUTELY remove this validation function override + player.sslStream = new SslStream(new NetworkStream(client, ownsSocket: true), false, new RemoteCertificateValidationCallback((sender, certificate, chain, sslPolicyErrors) => true)); player.sslStream.AuthenticateAsClient(endpoint); ReceiveLoop(); From 329c065e205cfa1bd7447e59f1d680280db048fa Mon Sep 17 00:00:00 2001 From: Moon <5924350+MatrikMoon@users.noreply.github.com> Date: Thu, 11 Apr 2024 00:04:45 -0500 Subject: [PATCH 2/7] I... I think this fixes the Span error? --- TournamentAssistant/ILRepack.targets | 26 +++++++++---------- .../TournamentAssistant.csproj | 26 ++++++++++++------- .../UI/ViewControllers/SongDetail.cs | 4 ++- TournamentAssistant/manifest.json | 10 ++++--- TournamentAssistant/packages.config | 12 ++++----- 5 files changed, 44 insertions(+), 34 deletions(-) diff --git a/TournamentAssistant/ILRepack.targets b/TournamentAssistant/ILRepack.targets index 8cbb82f9..bb9b7e50 100644 --- a/TournamentAssistant/ILRepack.targets +++ b/TournamentAssistant/ILRepack.targets @@ -2,26 +2,26 @@ - - - - + + + + - - - - - - + + + + + + diff --git a/TournamentAssistant/TournamentAssistant.csproj b/TournamentAssistant/TournamentAssistant.csproj index 2a26232f..a667cea1 100644 --- a/TournamentAssistant/TournamentAssistant.csproj +++ b/TournamentAssistant/TournamentAssistant.csproj @@ -95,8 +95,20 @@ False False - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.7.1\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\protobuf-net.3.2.30\lib\net462\protobuf-net.dll + + + ..\packages\protobuf-net.Core.3.2.30\lib\net462\protobuf-net.Core.dll + + + ..\packages\System.Collections.Immutable.7.0.0\lib\net462\System.Collections.Immutable.dll + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll False @@ -156,9 +168,6 @@ ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll - - ..\packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll - $(BeatSaberDir)\Beat Saber_Data\Managed\System.Data.dll False @@ -169,9 +178,6 @@ False False - - ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll - $(BeatSaberDir)\Beat Saber_Data\Managed\System.Net.Http.dll False @@ -403,12 +409,12 @@ - + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + diff --git a/TournamentAssistant/UI/ViewControllers/SongDetail.cs b/TournamentAssistant/UI/ViewControllers/SongDetail.cs index 73a5d4dd..2856a085 100644 --- a/TournamentAssistant/UI/ViewControllers/SongDetail.cs +++ b/TournamentAssistant/UI/ViewControllers/SongDetail.cs @@ -135,7 +135,9 @@ public void UpdateContent() if (_selectedLevel != null) { songNameText.text = _selectedLevel.songName; - durationText.text = $"{_selectedLevel.beatmapLevelData.audioClip.length}:F2"; // Keep an eye on this one, not sure it's right after update + + var duration = TimeSpan.FromSeconds(_selectedLevel.beatmapLevelData.audioClip.length); + durationText.text = duration.ToString(@"hh\:mm\:ss\:fff"); // Keep an eye on this one, not sure it's right after update bpmText.text = Mathf.RoundToInt(_selectedLevel.beatsPerMinute).ToString(); if (_selectedDifficultyBeatmap != null) diff --git a/TournamentAssistant/manifest.json b/TournamentAssistant/manifest.json index ffc336b8..be3e40b2 100644 --- a/TournamentAssistant/manifest.json +++ b/TournamentAssistant/manifest.json @@ -2,15 +2,17 @@ "$schema": "https://raw.githubusercontent.com/nike4613/ModSaber-MetadataFileSchema/master/Schema.json", "author": "Moon", "description": "???", - "gameVersion": "1.22.0", + "gameVersion": "1.34.2", "id": "TournamentAssistant", "name": "TournamentAssistant", "version": "0.0.0", - "features": [], - "loadAfter": [ "ScoreSaber" ], + "features": {}, + "loadAfter": [ + "ScoreSaber" + ], "dependsOn": { "BS Utils": "^1.10.0", "BeatSaberMarkupLanguage": "^1.5.3", "BSIPA": "^4.1.6" } -} +} \ No newline at end of file diff --git a/TournamentAssistant/packages.config b/TournamentAssistant/packages.config index cca50616..fa816e87 100644 --- a/TournamentAssistant/packages.config +++ b/TournamentAssistant/packages.config @@ -1,20 +1,20 @@  - + - - + + - + - + - + From 4520ee0e1b015751bfa32fe08b641c59812e60da Mon Sep 17 00:00:00 2001 From: Moon <5924350+MatrikMoon@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:05:55 -0500 Subject: [PATCH 3/7] Fix merge --- TournamentAssistant/TournamentAssistant.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/TournamentAssistant/TournamentAssistant.csproj b/TournamentAssistant/TournamentAssistant.csproj index 3e509b1f..aded729f 100644 --- a/TournamentAssistant/TournamentAssistant.csproj +++ b/TournamentAssistant/TournamentAssistant.csproj @@ -261,6 +261,7 @@ + From c38be7645f521d33141f29f6d6765f313134e01e Mon Sep 17 00:00:00 2001 From: Moon <5924350+MatrikMoon@users.noreply.github.com> Date: Fri, 19 Apr 2024 11:40:00 -0500 Subject: [PATCH 4/7] Update reflection --- TournamentAssistant/Plugin.cs | 2 +- TournamentAssistant/UnityUtilities/AntiFail.cs | 4 +++- TournamentAssistant/UnityUtilities/AntiPause.cs | 2 +- TournamentAssistant/Utilities/SongUtils.cs | 5 +++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/TournamentAssistant/Plugin.cs b/TournamentAssistant/Plugin.cs index 4b57bfa0..d878dd49 100644 --- a/TournamentAssistant/Plugin.cs +++ b/TournamentAssistant/Plugin.cs @@ -14,9 +14,9 @@ using TournamentAssistant.Utilities; using TournamentAssistantShared; using TournamentAssistantShared.SimpleJSON; +using TournamentAssistantShared.Utilities; using UnityEngine; using UnityEngine.SceneManagement; -using Zenject; using Config = TournamentAssistantShared.Config; using Random = System.Random; diff --git a/TournamentAssistant/UnityUtilities/AntiFail.cs b/TournamentAssistant/UnityUtilities/AntiFail.cs index 9bf44169..6e2f419e 100644 --- a/TournamentAssistant/UnityUtilities/AntiFail.cs +++ b/TournamentAssistant/UnityUtilities/AntiFail.cs @@ -1,6 +1,8 @@ using HarmonyLib; +using IPA.Utilities; using System.Linq; using UnityEngine; +using TournamentAssistantShared.Utilities; using Logger = TournamentAssistantShared.Logger; /** @@ -79,7 +81,7 @@ static bool SongDidFinishEvent() try { var standardLevelGameplayManager = Resources.FindObjectsOfTypeAll().First(); - standardLevelGameplayManager.HandleGameEnergyDidReach0(); + standardLevelGameplayManager.InvokeMethod("HandleGameEnergyDidReach0"); } finally { diff --git a/TournamentAssistant/UnityUtilities/AntiPause.cs b/TournamentAssistant/UnityUtilities/AntiPause.cs index 25be85da..0ead8071 100644 --- a/TournamentAssistant/UnityUtilities/AntiPause.cs +++ b/TournamentAssistant/UnityUtilities/AntiPause.cs @@ -135,7 +135,7 @@ public static void Unpause() try { var pauseController = Resources.FindObjectsOfTypeAll().First(); - pauseController.HandlePauseMenuManagerDidPressContinueButton(); + pauseController.InvokeMethod("HandlePauseMenuManagerDidPressContinueButton"); } finally { diff --git a/TournamentAssistant/Utilities/SongUtils.cs b/TournamentAssistant/Utilities/SongUtils.cs index a90c01e9..bb77efde 100644 --- a/TournamentAssistant/Utilities/SongUtils.cs +++ b/TournamentAssistant/Utilities/SongUtils.cs @@ -1,14 +1,15 @@ -using SongCore; +using IPA.Utilities; using IPA.Utilities.Async; +using SongCore; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using TournamentAssistantShared.Utilities; using UnityEngine; using Logger = TournamentAssistantShared.Logger; -using IPA.Utilities; namespace TournamentAssistant.Utilities { From c7b5cea77fe0103dbd61077550126691eb4808d8 Mon Sep 17 00:00:00 2001 From: Moon <5924350+MatrikMoon@users.noreply.github.com> Date: Mon, 6 May 2024 10:22:29 -0500 Subject: [PATCH 5/7] Switch updater to target 1.34 --- TournamentAssistant/Utilities/Updater.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TournamentAssistant/Utilities/Updater.cs b/TournamentAssistant/Utilities/Updater.cs index 9d2381ec..1253eb82 100644 --- a/TournamentAssistant/Utilities/Updater.cs +++ b/TournamentAssistant/Utilities/Updater.cs @@ -42,7 +42,7 @@ public static async Task Update(Action downloadProgressChanged) await DownloadWithProgress(updaterUrl, destinationPath, downloadProgressChanged); Logger.Success("Successfully downloaded TA updater"); - var arguments = $"/K \"\"{destinationPath}\" -plugin \"{beatSaberDirectory}\" -commandLine {Environment.CommandLine}\""; + var arguments = $"/K \"\"{destinationPath}\" -plugin134 \"{beatSaberDirectory}\" -commandLine {Environment.CommandLine}\""; arguments = arguments.Replace("\\", "\\\\"); var startInfo = new ProcessStartInfo("cmd.exe") From 3d89a25c86457f810e446c6e50f4ab5a2debfe14 Mon Sep 17 00:00:00 2001 From: Moon <5924350+MatrikMoon@users.noreply.github.com> Date: Fri, 14 Jun 2024 01:35:38 -0500 Subject: [PATCH 6/7] Fix 1.34-specific bugs --- .../UI/FlowCoordinators/RoomCoordinator.cs | 2 +- .../UI/ViewControllers/SongDetail.cs | 33 +++++++++++++++---- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs b/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs index 71512dee..ddac517e 100644 --- a/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs +++ b/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs @@ -186,7 +186,7 @@ public void DismissChildren(bool dismissModifierPanel = true) protected override void BackButtonWasPressed(ViewController topViewController) { if (topViewController is SongDetail) DismissViewController(topViewController); - else if (!_songDetail.GetField("_isInTransition")) + else if (!_songDetail.isInTransition) { DismissChildren(); DidFinishEvent?.Invoke(); diff --git a/TournamentAssistant/UI/ViewControllers/SongDetail.cs b/TournamentAssistant/UI/ViewControllers/SongDetail.cs index 22a84d61..a1293ffb 100644 --- a/TournamentAssistant/UI/ViewControllers/SongDetail.cs +++ b/TournamentAssistant/UI/ViewControllers/SongDetail.cs @@ -27,12 +27,15 @@ internal class SongDetail : BSMLAutomaticViewController public bool DisableDifficultyControl { get; set; } private bool _disablePlayButton = false; - public bool DisablePlayButton { - get { + public bool DisablePlayButton + { + get + { return _disablePlayButton; } - set { + set + { _disablePlayButton = value; buttonsRect?.gameObject.SetActive(!value); @@ -137,7 +140,24 @@ public void UpdateContent() songNameText.text = _selectedLevel.songName; var duration = TimeSpan.FromSeconds(_selectedLevel.beatmapLevelData.audioClip.length); - durationText.text = duration.ToString(@"hh\:mm\:ss\:fff"); // Keep an eye on this one, not sure it's right after update + + static string FormatDuration(TimeSpan duration) + { + if (duration.Hours > 0) + { + return duration.ToString(@"hh\:mm\:ss"); + } + else if (duration.Minutes > 0) + { + return duration.ToString(@"mm\:ss"); + } + else + { + return duration.ToString(@"ss"); + } + } + + durationText.text = FormatDuration(duration); bpmText.text = Mathf.RoundToInt(_selectedLevel.beatsPerMinute).ToString(); if (_selectedDifficultyBeatmap != null) @@ -212,10 +232,9 @@ private void SetBeatmapLevel(IBeatmapLevel beatmapLevel) Task.Run(async () => { - var coverImage = await beatmapLevel.GetCoverImageAsync(cancellationToken.Token); - - await UnityMainThreadTaskScheduler.Factory.StartNew(() => + await UnityMainThreadTaskScheduler.Factory.StartNew(async () => { + var coverImage = await beatmapLevel.GetCoverImageAsync(cancellationToken.Token); levelCoverImage.texture = coverImage.texture; }); }); From 7c16b609a69de68a6a91a16052b0a166355f5898 Mon Sep 17 00:00:00 2001 From: Pink <62712899+ModdingPink@users.noreply.github.com> Date: Sun, 10 Nov 2024 03:57:07 +0000 Subject: [PATCH 7/7] First Look at updating to 38 --- TournamentAssistant/Plugin.cs | 6 +- TournamentAssistant/PluginClient.cs | 3 +- .../TournamentAssistant.csproj | 202 ++++++++++++------ .../UI/FlowCoordinators/RoomCoordinator.cs | 9 +- .../UI/ViewControllers/SongDetail.cs | 101 +++++---- TournamentAssistant/Utilities/SongUtils.cs | 134 +++++++----- TournamentAssistant/app.config | 15 ++ 7 files changed, 297 insertions(+), 173 deletions(-) create mode 100644 TournamentAssistant/app.config diff --git a/TournamentAssistant/Plugin.cs b/TournamentAssistant/Plugin.cs index 77596ff2..72351f0f 100644 --- a/TournamentAssistant/Plugin.cs +++ b/TournamentAssistant/Plugin.cs @@ -176,7 +176,7 @@ private static void InitScoreSaber() private void CreateMenuButton() { - MenuButtons.instance.RegisterButton(menuButton); + MenuButtons.Instance.RegisterButton(menuButton); } private void MenuButtonPressed() @@ -198,9 +198,9 @@ private void tournamentSelectionCoordinator_DidFinishEvent() public void Dispose() { - if (MenuButtons.instance != null) + if (MenuButtons.Instance != null) { - MenuButtons.instance.UnregisterButton(menuButton); + MenuButtons.Instance.UnregisterButton(menuButton); } } } diff --git a/TournamentAssistant/PluginClient.cs b/TournamentAssistant/PluginClient.cs index e09de50f..782e63dd 100644 --- a/TournamentAssistant/PluginClient.cs +++ b/TournamentAssistant/PluginClient.cs @@ -21,10 +21,11 @@ public class PluginClient(string endpoint, int port) : TAClient(endpoint, port) public string CurrentMatch { get; set; } public event Func LoadedSong; - public event Func PlaySong; + public event Func PlaySong; protected override async Task Client_PacketReceived(Packet packet) { + await base.Client_PacketReceived(packet); if (packet.packetCase == Packet.packetOneofCase.Command) diff --git a/TournamentAssistant/TournamentAssistant.csproj b/TournamentAssistant/TournamentAssistant.csproj index 3d765b16..88185d03 100644 --- a/TournamentAssistant/TournamentAssistant.csproj +++ b/TournamentAssistant/TournamentAssistant.csproj @@ -37,128 +37,187 @@ false - - False + $(BeatSaberDir)\Libs\0Harmony.dll False + False $(BeatSaberDir)\Beat Saber_Data\Managed\AdditionalContentModel.Interfaces.dll False False - + + $(BeatSaberDir)\Beat Saber_Data\Managed\Analytics.Model.dll + False False + + + ..\packages\BepInEx.AssemblyPublicizer.MSBuild.0.4.2\lib\net472\AsmResolver.dll + + + ..\packages\BepInEx.AssemblyPublicizer.MSBuild.0.4.2\lib\net472\AsmResolver.DotNet.dll + + + ..\packages\BepInEx.AssemblyPublicizer.MSBuild.0.4.2\lib\net472\AsmResolver.PE.dll + + + ..\packages\BepInEx.AssemblyPublicizer.MSBuild.0.4.2\lib\net472\AsmResolver.PE.File.dll + + $(BeatSaberDir)\Beat Saber_Data\Managed\BeatmapCore.dll False + False + + + $(BeatSaberDir)\Beat Saber_Data\Managed\BeatSaber.ViewSystem.dll + False + False + + + ..\packages\BepInEx.AssemblyPublicizer.MSBuild.0.4.2\lib\net472\BepInEx.AssemblyPublicizer.dll + + + ..\packages\BepInEx.AssemblyPublicizer.MSBuild.0.4.2\lib\net472\BepInEx.AssemblyPublicizer.MSBuild.dll $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.AppFlow.dll False False + + $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.Attributes.dll + False + False + + + $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.Polyglot.dll + False + False + $(BeatSaberDir)\Beat Saber_Data\Managed\BGLib.UnityExtension.dll False False - + + $(BeatSaberDir)\Beat Saber_Data\Managed\BGNetCore.dll + False False + + $(BeatSaberDir)\Plugins\BSML.dll False - - False + + $(BeatSaberDir)\Plugins\BS_Utils.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\Colors.dll False + False $(BeatSaberDir)\Plugins\CustomNotes.dll False False + + $(BeatSaberDir)\Beat Saber_Data\Managed\DataModels.dll + False + False + ..\packages\Fleck.1.2.0\lib\net45\Fleck.dll - - False + $(BeatSaberDir)\Beat Saber_Data\Managed\GameplayCore.dll False - - - $(BeatSaberDir)\Beat Saber_Data\Managed\PlatformUserModel.dll - False False - - ..\packages\protobuf-net.3.2.30\lib\net462\protobuf-net.dll - - - ..\packages\protobuf-net.Core.3.2.30\lib\net462\protobuf-net.Core.dll - - - ..\packages\System.Collections.Immutable.7.0.0\lib\net462\System.Collections.Immutable.dll - - - ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll - - - ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll - - - False - $(BeatSaberDir)\Libs\TAAuth.dll - False - - - False + $(BeatSaberDir)\Beat Saber_Data\Managed\HMLib.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\HMUI.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\IPA.Injector.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\IPA.Loader.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\Main.dll False + False + true - + + $(BeatSaberDir)\Beat Saber_Data\Managed\MenuLightPreset.dll + False False - $(BeatSaberDir)\Libs\Newtonsoft.Json.dll + + + $(BeatSaberDir)\Beat Saber_Data\Managed\MenuSystem.dll False + False - + + $(BeatSaberDir)\Beat Saber_Data\Managed\Newtonsoft.Json.dll + False False - $(BeatSaberDir)\Beat Saber_Data\Managed\Polyglot.dll + + + $(BeatSaberDir)\Beat Saber_Data\Managed\PlatformUserModel.dll False + False + + + ..\packages\protobuf-net.3.2.30\lib\net462\protobuf-net.dll + + + ..\packages\protobuf-net.Core.3.2.30\lib\net462\protobuf-net.Core.dll - + + $(BeatSaberDir)\Beat Saber_Data\Managed\SegmentedControl.dll + False False + + $(BeatSaberDir)\Plugins\SongCore.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\Steamworks.NET.dll False + False + + + ..\packages\System.Collections.Immutable.7.0.0\lib\net462\System.Collections.Immutable.dll + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + False + $(BeatSaberDir)\Libs\TAAuth.dll + False $(BeatSaberDir)\Beat Saber_Data\Managed\System.dll @@ -202,60 +261,60 @@ False False - - False + $(BeatSaberDir)\Beat Saber_Data\Managed\Unity.TextMeshPro.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.dll False + False $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.AudioModule.dll False False - - False + $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.CoreModule.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.ImageConversionModule.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.UI.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.UIModule.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.UnityWebRequestModule.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\UnityEngine.VRModule.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\Zenject.dll False - - False + + $(BeatSaberDir)\Beat Saber_Data\Managed\Zenject-usage.dll False + False @@ -385,6 +444,7 @@ + diff --git a/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs b/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs index d483ccf2..44bf6a4e 100644 --- a/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs +++ b/TournamentAssistant/UI/FlowCoordinators/RoomCoordinator.cs @@ -441,9 +441,8 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => } } - protected async Task PlaySong(IPreviewBeatmapLevel desiredLevel, - BeatmapCharacteristicSO desiredCharacteristic, - BeatmapDifficulty desiredDifficulty, + protected async Task PlaySong(BeatmapLevel desiredLevel, + BeatmapKey beatmapKey, GameplayModifiers gameplayModifiers, PlayerSpecificSettings playerSpecificSettings, OverrideEnvironmentSettings overrideEnvironmentSettings, @@ -474,7 +473,7 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => DismissViewController(topViewController, immediately: true); } - SongUtils.PlaySong(desiredLevel, desiredCharacteristic, desiredDifficulty, overrideEnvironmentSettings, colorScheme, gameplayModifiers, playerSpecificSettings, SongFinished); + SongUtils.PlaySong(desiredLevel, beatmapKey, overrideEnvironmentSettings, colorScheme, gameplayModifiers, playerSpecificSettings, SongFinished); }); } @@ -482,7 +481,7 @@ public void SongFinished(StandardLevelScenesTransitionSetupDataSO standardLevelS { standardLevelScenesTransitionSetupData.didFinishEvent -= SongFinished; - var map = standardLevelScenesTransitionSetupData.difficultyBeatmap; + var map = standardLevelScenesTransitionSetupData.beatmapLevel; var transformedMap = standardLevelScenesTransitionSetupData.transformedBeatmapData; var localPlayer = _playerDataModel.playerData; var localResults = localPlayer.GetPlayerLevelStatsData(map.level.levelID, map.difficulty, map.parentDifficultyBeatmapSet.beatmapCharacteristic); diff --git a/TournamentAssistant/UI/ViewControllers/SongDetail.cs b/TournamentAssistant/UI/ViewControllers/SongDetail.cs index a1293ffb..c4adfc92 100644 --- a/TournamentAssistant/UI/ViewControllers/SongDetail.cs +++ b/TournamentAssistant/UI/ViewControllers/SongDetail.cs @@ -2,9 +2,9 @@ #pragma warning disable IDE0044 using BeatSaberMarkupLanguage.Attributes; using BeatSaberMarkupLanguage.ViewControllers; +using BGLib.Polyglot; using HMUI; using IPA.Utilities.Async; -using Polyglot; using SongCore; using System; using System.Collections.Generic; @@ -20,8 +20,8 @@ namespace TournamentAssistant.UI.ViewControllers { internal class SongDetail : BSMLAutomaticViewController { - public event Action DifficultyBeatmapChanged; - public event Action PlayPressed; + public event Action DifficultyBeatmapChanged; + public event Action PlayPressed; public bool DisableCharacteristicControl { get; set; } public bool DisableDifficultyControl { get; set; } @@ -42,11 +42,11 @@ public bool DisablePlayButton } } - private IBeatmapLevel _selectedLevel; - private IDifficultyBeatmap _selectedDifficultyBeatmap; + private BeatmapLevel _selectedLevel; + private BeatmapKey? _selectedDifficultyBeatmapKey; - private BeatmapDifficulty SelectedDifficulty { get { return _selectedDifficultyBeatmap?.difficulty ?? BeatmapDifficulty.ExpertPlus; } } - private BeatmapCharacteristicSO SelectedCharacteristic { get { return _selectedDifficultyBeatmap?.parentDifficultyBeatmapSet.beatmapCharacteristic; } } + private BeatmapDifficulty SelectedDifficulty { get { return _selectedDifficultyBeatmapKey?.difficulty ?? BeatmapDifficulty.ExpertPlus; } } + private BeatmapCharacteristicSO SelectedCharacteristic { get { return _selectedDifficultyBeatmapKey?.beatmapCharacteristic; } } private PlayerDataModel _playerDataModel; private List _beatmapCharacteristics = new(); @@ -118,15 +118,24 @@ public void SetupViewController() maskImage.color = new Color(0f, 0f, 0f, 0.25f); } - public void SetControlData(IDifficultyBeatmapSet[] difficultyBeatmapSets, BeatmapCharacteristicSO selectedBeatmapCharacteristic) + public void SetControlData(IEnumerable difficultyBeatmapSets, BeatmapCharacteristicSO selectedBeatmapCharacteristic) { + throw new NotImplementedException(); + _beatmapCharacteristics.Clear(); - var beatmapSetList = new List(difficultyBeatmapSets); - beatmapSetList.Sort((IDifficultyBeatmapSet a, IDifficultyBeatmapSet b) => a.beatmapCharacteristic.sortingOrder.CompareTo(b.beatmapCharacteristic.sortingOrder)); - _beatmapCharacteristics.AddRange(beatmapSetList.Select(x => x.beatmapCharacteristic)); + //var beatmapSetList = new List(difficultyBeatmapSets); + //beatmapSetList.Sort((IDifficultyBeatmapSet a, IDifficultyBeatmapSet b) => a.beatmapCharacteristic.sortingOrder.CompareTo(b.beatmapCharacteristic.sortingOrder)); + + foreach(var key in difficultyBeatmapSets) + { + if(!_beatmapCharacteristics.Contains(key.beatmapCharacteristic)) + _beatmapCharacteristics.Add(key.beatmapCharacteristic); + } - var itemArray = beatmapSetList.Select(beatmapSet => new IconSegmentedControl.DataItem(beatmapSet.beatmapCharacteristic.icon, Localization.Get(beatmapSet.beatmapCharacteristic.descriptionLocalizationKey))).ToArray(); - var selectedIndex = Math.Max(0, beatmapSetList.FindIndex(x => x.beatmapCharacteristic == selectedBeatmapCharacteristic)); + var itemArray = difficultyBeatmapSets.Select(beatmapSet => new IconSegmentedControl.DataItem(beatmapSet.beatmapCharacteristic.icon, Localization.Get(beatmapSet.beatmapCharacteristic.descriptionLocalizationKey))).ToArray(); + //var selectedIndex = Math.Max(0, beatmapSetList.FindIndex(x => x.beatmapCharacteristic == selectedBeatmapCharacteristic)); + var selectedIndex = 0; + //Literally no fucking clue characteristicControl.SetData(itemArray); characteristicControl.SelectCellWithNumber(selectedIndex); @@ -139,7 +148,7 @@ public void UpdateContent() { songNameText.text = _selectedLevel.songName; - var duration = TimeSpan.FromSeconds(_selectedLevel.beatmapLevelData.audioClip.length); + var duration = TimeSpan.FromSeconds(_selectedLevel.audioClip.length); static string FormatDuration(TimeSpan duration) { @@ -160,29 +169,29 @@ static string FormatDuration(TimeSpan duration) durationText.text = FormatDuration(duration); bpmText.text = Mathf.RoundToInt(_selectedLevel.beatsPerMinute).ToString(); - if (_selectedDifficultyBeatmap != null) + if (_selectedDifficultyBeatmapKey != null) { Task.Run(async () => { - var beatmapData = await _selectedDifficultyBeatmap.GetBeatmapDataBasicInfoAsync(); + var beatmapData = _selectedLevel.GetDifficultyBeatmapData(_selectedDifficultyBeatmapKey.Value.beatmapCharacteristic, _selectedDifficultyBeatmapKey.Value.difficulty); await UnityMainThreadTaskScheduler.Factory.StartNew(() => { var njs = 0f; - if (_selectedDifficultyBeatmap.noteJumpMovementSpeed != 0) + if (beatmapData.noteJumpMovementSpeed != 0) { - njs = _selectedDifficultyBeatmap.noteJumpMovementSpeed; + njs = beatmapData.noteJumpMovementSpeed; } else { njs = BeatmapDifficultyMethods.NoteJumpMovementSpeed(SelectedDifficulty); } - var jumpDistance = SongUtils.GetJumpDistance(_selectedLevel.beatsPerMinute, njs, _selectedDifficultyBeatmap.noteJumpStartBeatOffset); - npsText.text = (beatmapData.cuttableNotesCount / _selectedLevel.beatmapLevelData.audioClip.length).ToString("0.00"); + var jumpDistance = SongUtils.GetJumpDistance(_selectedLevel.beatsPerMinute, njs, beatmapData.noteJumpStartBeatOffset); + npsText.text = (beatmapData.notesCount / _selectedLevel.beatmapLevelData.audioClip.length).ToString("0.00"); njsText.text = njs.ToString("0.0#"); jumpDistanceText.text = jumpDistance.ToString("0.0#"); - notesCountText.text = beatmapData.cuttableNotesCount.ToString(); + notesCountText.text = beatmapData.notesCount.ToString(); obstaclesCountText.text = beatmapData.obstaclesCount.ToString(); bombsCountText.text = beatmapData.bombsCount.ToString(); }); @@ -200,7 +209,7 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => } } - public void SetSelectedSong(IBeatmapLevel selectedLevel) + public void SetSelectedSong(BeatmapLevel selectedLevel) { buttonsRect.gameObject.SetActive(!DisablePlayButton); @@ -212,23 +221,24 @@ public void SetSelectedSong(IBeatmapLevel selectedLevel) SetBeatmapLevel(_selectedLevel); } - private void SetBeatmapLevel(IBeatmapLevel beatmapLevel) + private void SetBeatmapLevel(BeatmapLevel beatmapLevel) { - if (beatmapLevel.beatmapLevelData.difficultyBeatmapSets.Any(x => x.beatmapCharacteristic == _playerDataModel.playerData.lastSelectedBeatmapCharacteristic)) + var beatmapKeys = beatmapLevel.GetBeatmapKeys(); + if (beatmapKeys.Any(x => x.beatmapCharacteristic == _playerDataModel.playerData.lastSelectedBeatmapCharacteristic)) { - _selectedDifficultyBeatmap = SongUtils.GetClosestDifficultyPreferLower(beatmapLevel, _playerDataModel.playerData.lastSelectedBeatmapDifficulty, _playerDataModel.playerData.lastSelectedBeatmapCharacteristic.serializedName); + _selectedDifficultyBeatmapKey = SongUtils.GetClosestDifficultyPreferLower(beatmapLevel, _playerDataModel.playerData.lastSelectedBeatmapDifficulty, _playerDataModel.playerData.lastSelectedBeatmapCharacteristic.serializedName); } - else if (beatmapLevel.beatmapLevelData.difficultyBeatmapSets.Count > 0) + else if (beatmapKeys.Count() > 0) { - _selectedDifficultyBeatmap = SongUtils.GetClosestDifficultyPreferLower(beatmapLevel, _playerDataModel.playerData.lastSelectedBeatmapDifficulty, beatmapLevel.beatmapLevelData.difficultyBeatmapSets[0].beatmapCharacteristic.serializedName); + _selectedDifficultyBeatmapKey = SongUtils.GetClosestDifficultyPreferLower(beatmapLevel, _playerDataModel.playerData.lastSelectedBeatmapDifficulty, beatmapKeys.FirstOrDefault().beatmapCharacteristic.serializedName); } UpdateContent(); - _playerDataModel.playerData.SetLastSelectedBeatmapCharacteristic(_selectedDifficultyBeatmap.parentDifficultyBeatmapSet.beatmapCharacteristic); - _playerDataModel.playerData.SetLastSelectedBeatmapDifficulty(_selectedDifficultyBeatmap.difficulty); + _playerDataModel.playerData.SetLastSelectedBeatmapCharacteristic(_selectedDifficultyBeatmapKey.Value.beatmapCharacteristic); + _playerDataModel.playerData.SetLastSelectedBeatmapDifficulty(_selectedDifficultyBeatmapKey.Value.difficulty); - SetControlData(_selectedLevel.beatmapLevelData.difficultyBeatmapSets.ToArray(), _playerDataModel.playerData.lastSelectedBeatmapCharacteristic); + SetControlData(beatmapKeys, _playerDataModel.playerData.lastSelectedBeatmapCharacteristic); Task.Run(async () => { @@ -250,30 +260,33 @@ public void SetSelectedCharacteristic(string serializedName) [UIAction("characteristic-selected")] public void SetSelectedCharacteristic(IconSegmentedControl _, int index) { - _playerDataModel.playerData.SetLastSelectedBeatmapCharacteristic(_beatmapCharacteristics[index]); + var characteristic = _beatmapCharacteristics[index]; + _playerDataModel.playerData.SetLastSelectedBeatmapCharacteristic(characteristic); - var diffBeatmaps = _selectedLevel.beatmapLevelData.GetDifficultyBeatmapSet(_beatmapCharacteristics[index]).difficultyBeatmaps; + var diffs = _selectedLevel.GetDifficulties(characteristic); + var diffArray = diffs.ToArray(); + var diffCount = diffs.Count(); var closestDifficulty = SongUtils.GetClosestDifficultyPreferLower(_selectedLevel, _playerDataModel.playerData.lastSelectedBeatmapDifficulty, _beatmapCharacteristics[index].serializedName); var extraData = Collections.RetrieveExtraSongData(Collections.hashForLevelID(_selectedLevel.levelID)); if (extraData != null) { - string[] difficultyLabels = new string[diffBeatmaps.Count]; + string[] difficultyLabels = new string[diffCount]; var extraDifficulties = extraData._difficulties.Where(x => x._beatmapCharacteristicName == _beatmapCharacteristics[index].serializedName || x._beatmapCharacteristicName == _beatmapCharacteristics[index].characteristicNameLocalizationKey); - for (int i = 0; i < diffBeatmaps.Count; i++) + for (int i = 0; i < diffCount; i++) { - var customDiff = extraDifficulties.FirstOrDefault(x => x._difficulty == diffBeatmaps[i].difficulty); + var customDiff = extraDifficulties.FirstOrDefault(x => x._difficulty == diffArray[i]); if (customDiff != null && !string.IsNullOrEmpty(customDiff._difficultyLabel)) difficultyLabels[i] = customDiff._difficultyLabel; - else difficultyLabels[i] = diffBeatmaps[i].difficulty.ToString().Replace("Plus", "+"); + else difficultyLabels[i] = diffArray[i].ToString().Replace("Plus", "+"); } difficultyControl.SetTexts(difficultyLabels); } - else difficultyControl.SetTexts(diffBeatmaps.Select(x => x.difficulty.ToString().Replace("Plus", "+")).ToArray()); + else difficultyControl.SetTexts(diffs.Select(x => x.ToString().Replace("Plus", "+")).ToArray()); - var diffIndex = Array.FindIndex(diffBeatmaps.ToArray(), x => x.difficulty == closestDifficulty.difficulty); + var diffIndex = Array.FindIndex(diffArray, x => x == closestDifficulty.difficulty); difficultyControl.SelectCellWithNumber(diffIndex); SetSelectedDifficulty(null, diffIndex); @@ -303,23 +316,23 @@ public void SetSelectedDifficulty(int difficulty) [UIAction("difficulty-selected")] public void SetSelectedDifficulty(TextSegmentedControl _, int index) { - var difficultyBeatmaps = _selectedLevel.beatmapLevelData.GetDifficultyBeatmapSet(_playerDataModel.playerData.lastSelectedBeatmapCharacteristic).difficultyBeatmaps; + var diffs = _selectedLevel.GetDifficulties(_playerDataModel.playerData.lastSelectedBeatmapCharacteristic).ToArray(); - if (index >= 0 && index < difficultyBeatmaps.Count) + if (index >= 0 && index < diffs.Count()) { - _selectedDifficultyBeatmap = difficultyBeatmaps[index]; - _playerDataModel.playerData.SetLastSelectedBeatmapDifficulty(_selectedDifficultyBeatmap.difficulty); + _selectedDifficultyBeatmapKey = _selectedLevel.GetBeatmapKeys().Where(x => x.beatmapCharacteristic == _playerDataModel.playerData.lastSelectedBeatmapCharacteristic && x.difficulty == diffs[index]).FirstOrDefault(); + _playerDataModel.playerData.SetLastSelectedBeatmapDifficulty(_selectedDifficultyBeatmapKey.Value.difficulty); UpdateContent(); - DifficultyBeatmapChanged?.Invoke(_selectedDifficultyBeatmap); + DifficultyBeatmapChanged?.Invoke(_selectedDifficultyBeatmapKey.Value); } } [UIAction("play-pressed")] public void PlayClicked() { - PlayPressed?.Invoke(_selectedLevel, SelectedCharacteristic, SelectedDifficulty); + PlayPressed?.Invoke(_selectedLevel, _selectedDifficultyBeatmapKey.Value); } } } diff --git a/TournamentAssistant/Utilities/SongUtils.cs b/TournamentAssistant/Utilities/SongUtils.cs index 24a31e74..6a0e12aa 100644 --- a/TournamentAssistant/Utilities/SongUtils.cs +++ b/TournamentAssistant/Utilities/SongUtils.cs @@ -7,78 +7,99 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using TournamentAssistantShared.BeatSaver; using TournamentAssistantShared.Utilities; using UnityEngine; +using static BeatSaberMarkupLanguage.Components.KEYBOARD; using Logger = TournamentAssistantShared.Logger; namespace TournamentAssistant.Utilities { public class SongUtils { + internal static BeatmapLevelsModel BeatmapLevelsModel + { + get + { + if(_beatmapLevelsModel == null) + _beatmapLevelsModel = Resources.FindObjectsOfTypeAll().First().GetField("_beatmapLevelsModel"); + return _beatmapLevelsModel; + } + } + private static BeatmapLevelsModel _beatmapLevelsModel; + private static CancellationTokenSource getLevelCancellationTokenSource; private static CancellationTokenSource getStatusCancellationTokenSource; - public static List masterLevelList; + public static List masterLevelList; public static void OnEnable() { Loader.SongsLoadedEvent += Loader_SongsLoadedEvent; } - private static void Loader_SongsLoadedEvent(Loader _, ConcurrentDictionary __) + private static void Loader_SongsLoadedEvent(Loader _, ConcurrentDictionary __) { RefreshLoadedSongs(); } // Returns the closest difficulty to the one provided, preferring lower difficulties first if any exist - public static IDifficultyBeatmap GetClosestDifficultyPreferLower(IBeatmapLevel level, BeatmapDifficulty difficulty, string characteristic) + public static BeatmapKey GetClosestDifficultyPreferLower(BeatmapLevel level, BeatmapDifficulty difficulty, string characteristic) { + var beatmapCharacteristic = Loader.beatmapCharacteristicCollection.GetBeatmapCharacteristicBySerializedName(characteristic); + // First, look at the characteristic parameter. If there's something useful in there, we try to use it, but fall back to Standard - var desiredCharacteristic = level.previewDifficultyBeatmapSets.FirstOrDefault(x => x.beatmapCharacteristic.serializedName == characteristic).beatmapCharacteristic ?? level.previewDifficultyBeatmapSets.First().beatmapCharacteristic; - var availableMaps = - level - .beatmapLevelData - .difficultyBeatmapSets - .FirstOrDefault(x => x.beatmapCharacteristic.serializedName == desiredCharacteristic.serializedName) - .difficultyBeatmaps - .OrderBy(x => x.difficulty) - .ToArray(); + + + var availableMaps = level.GetBeatmapKeys(); + return availableMaps.Where(x => x.beatmapCharacteristic == beatmapCharacteristic && x.difficulty == difficulty).FirstOrDefault(); + /* + if (level.GetDifficultyBeatmapData(beatmapCharacteristic, difficulty) != null) + var ret = availableMaps.FirstOrDefault(x => x.difficulty == difficulty); ret = ret is not CustomDifficultyBeatmap || HasRequirements(ret) ? ret : null; - ret ??= GetLowerDifficulty(availableMaps, difficulty, desiredCharacteristic); - ret ??= GetHigherDifficulty(availableMaps, difficulty, desiredCharacteristic); + ret = GetLowerDifficulty(availableMaps, difficulty); + ret ??= GetHigherDifficulty(availableMaps, difficulty); + + return ret;*/ + } - return ret; + private static bool IsCustomLevel(BeatmapLevel level) + { + return level.levelID.StartsWith("custom_level"); } // Returns the next-lowest difficulty to the one provided - private static IDifficultyBeatmap GetLowerDifficulty(IDifficultyBeatmap[] availableMaps, BeatmapDifficulty difficulty, BeatmapCharacteristicSO characteristic) + private static BeatmapKey GetLowerDifficulty(IEnumerable availableMaps, BeatmapDifficulty difficulty) { - var ret = availableMaps.TakeWhile(x => x.difficulty < difficulty).LastOrDefault(); - return ret is not CustomDifficultyBeatmap || HasRequirements(ret) ? ret : null; + return availableMaps.TakeWhile(x => x.difficulty < difficulty).LastOrDefault(); } // Returns the next-highest difficulty to the one provided - private static IDifficultyBeatmap GetHigherDifficulty(IDifficultyBeatmap[] availableMaps, BeatmapDifficulty difficulty, BeatmapCharacteristicSO characteristic) + private static BeatmapKey GetHigherDifficulty(IEnumerable availableMaps, BeatmapDifficulty difficulty) + { + return availableMaps.SkipWhile(x => x.difficulty < difficulty).FirstOrDefault(); + } + + public static IEnumerable GetAllLevelsFromRepository(BeatmapLevelsRepository repository) { - var ret = availableMaps.SkipWhile(x => x.difficulty < difficulty).FirstOrDefault(); - return ret is not CustomDifficultyBeatmap || HasRequirements(ret) ? ret : null; + return repository.GetField>("_idToBeatmapLevel").Values; } public static void RefreshLoadedSongs() { - if (_beatmapLevelsModel == null) _beatmapLevelsModel = Resources.FindObjectsOfTypeAll().First(); + masterLevelList = + [ + .. GetAllLevelsFromRepository(BeatmapLevelsModel.ostAndExtrasBeatmapLevelsRepository), + .. GetAllLevelsFromRepository(BeatmapLevelsModel.dlcBeatmapLevelsRepository), + .. GetAllLevelsFromRepository(Loader.CustomLevelsRepository), + ]; - masterLevelList = new List(); - foreach (var pack in _beatmapLevelsModel.allLoadedBeatmapLevelPackCollection.beatmapLevelPacks) - { - masterLevelList.AddRange(pack.beatmapLevelCollection.beatmapLevels); - } // This snippet helps me build the hardcoded list that ends up in OstHelper.cs /*var output = string.Join("\n", _beatmapLevelsModel.allLoadedBeatmapLevelPackCollection.beatmapLevelPacks.Select(x => $@" @@ -95,12 +116,12 @@ public static void RefreshLoadedSongs() File.WriteAllText(Environment.CurrentDirectory + "\\songs.json", output);*/ } - public static bool HasRequirements(IDifficultyBeatmap map) + public static bool HasRequirements(BeatmapLevel map, BeatmapKey key) { - var extras = Collections.RetrieveExtraSongData(map.level.levelID); - var requirements = extras?._difficulties.First(x => x._difficulty == map.difficulty).additionalDifficultyData._requirements; + var extras = Collections.RetrieveExtraSongData(map.levelID); + var requirements = extras?._difficulties.First(x => x._difficulty == key.difficulty).additionalDifficultyData._requirements; - Logger.Debug($"{map.level.songName} is a custom level, checking for requirements on {map.difficulty}..."); + Logger.Debug($"{map.songName} is a custom level, checking for requirements on {key.difficulty}..."); if ((requirements?.Count() > 0) && !requirements.All(Collections.capabilities.Contains)) { Logger.Debug($"At leat one requirement not met: {string.Join(" ", requirements)}"); @@ -132,8 +153,7 @@ public static async Task HasDLCLevel(string levelId) await UnityMainThreadTaskScheduler.Factory.StartNew(() => { - var beatmapLevelsModel = Resources.FindObjectsOfTypeAll().FirstOrDefault(); - additionalContentModel = beatmapLevelsModel.GetField("_additionalContentModel"); + additionalContentModel = BeatmapLevelsModel.GetField("_additionalContentModel"); }); if (additionalContentModel != null) @@ -148,6 +168,7 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => return false; } + /* public static Task GetLevelFromPreview(IPreviewBeatmapLevel level, BeatmapLevelsModel beatmapLevelsModel = null) { return UnityMainThreadTaskScheduler.Factory.StartNew(async () => @@ -177,13 +198,12 @@ await UnityMainThreadTaskScheduler.Factory.StartNew(() => } return null; }).Unwrap(); - } + }*/ - public static async void PlaySong(IPreviewBeatmapLevel level, BeatmapCharacteristicSO characteristic, BeatmapDifficulty difficulty, OverrideEnvironmentSettings overrideEnvironmentSettings = null, ColorScheme colorScheme = null, GameplayModifiers gameplayModifiers = null, PlayerSpecificSettings playerSettings = null, Action songFinishedCallback = null, Action songRestartedCallback = null) + public static async void PlaySong(BeatmapLevel level, BeatmapKey beatmapKey, OverrideEnvironmentSettings overrideEnvironmentSettings = null, ColorScheme colorScheme = null, GameplayModifiers gameplayModifiers = null, PlayerSpecificSettings playerSettings = null, Action songFinishedCallback = null, Action songRestartedCallback = null) { - Action SongLoaded = (loadedLevel) => + Action SongLoaded = (loadedLevel) => { - var difficultyBeatmap = loadedLevel.beatmapLevelData.GetDifficultyBeatmap(characteristic, difficulty); // Try to get overridden colors if this is a custom level ColorScheme beatmapOverrideColorScheme = null; @@ -196,25 +216,41 @@ public static async void PlaySong(IPreviewBeatmapLevel level, BeatmapCharacteris beatmapOverrideColorScheme = customBeatmapLevel.GetBeatmapLevelColorScheme(customDifficultyBeatmap.beatmapColorSchemeIdx); } } + var _playerSettings = Resources.FindObjectsOfTypeAll().FirstOrDefault().playerData; + // var _soloFreePlayFlowCoordinator = Resources.FindObjectsOfTypeAll().First(); + + if (gameplayModifiers == null) + { + gameplayModifiers = new GameplayModifiers(); + gameplayModifiers.IsWithoutModifiers(); + } + if (playerSettings == null) + playerSettings = _playerSettings.playerSpecificSettings; + MenuTransitionsHelper _menuSceneSetupData = Resources.FindObjectsOfTypeAll().First(); + _menuSceneSetupData.StartStandardLevel( "Solo", - difficultyBeatmap, - loadedLevel, - overrideEnvironmentSettings, - colorScheme, - beatmapOverrideColorScheme, - gameplayModifiers ?? new GameplayModifiers(), - playerSettings ?? new PlayerSpecificSettings(), + beatmapKey, + level, + _playerSettings.overrideEnvironmentSettings.overrideEnvironments ? _playerSettings.overrideEnvironmentSettings : null, + _playerSettings.colorSchemesSettings.overrideDefaultColors ? _playerSettings.colorSchemesSettings.GetSelectedColorScheme() : null, + level.GetColorScheme(beatmapKey.beatmapCharacteristic, beatmapKey.difficulty), + gameplayModifiers, + _playerSettings.playerSpecificSettings, + _playerSettings.practiceSettings, + //_soloFreePlayFlowCoordinator._environmentsListModel, null, "Menu", false, - false, /* TODO: start paused? Worth looking into to replace the old hacky function */ - null, - (standardLevelScenesTransitionSetupData, results) => songFinishedCallback?.Invoke(standardLevelScenesTransitionSetupData, results), - (levelScenesTransitionSetupData, results) => songRestartedCallback?.Invoke(levelScenesTransitionSetupData, results) - ); + false, + delegate { }, //before scene switch + delegate { }, //after scene switch + (standardLevelScenesTransitionSetupData, results) => songFinishedCallback?.Invoke(standardLevelScenesTransitionSetupData, results),//level finished + (levelScenesTransitionSetupData, results) => songRestartedCallback?.Invoke(levelScenesTransitionSetupData, results)); //level restarted + /* TODO: start paused? Worth looking into to replace the old hacky function */ + }; if ((level is PreviewBeatmapLevelSO && await HasDLCLevel(level.levelID)) || level is CustomPreviewBeatmapLevel) diff --git a/TournamentAssistant/app.config b/TournamentAssistant/app.config new file mode 100644 index 00000000..a1e2bff2 --- /dev/null +++ b/TournamentAssistant/app.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file