From 3b600f0a7b2dda8fa17ba85ee1563526bad44ece Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 20 Nov 2020 10:45:19 +0300 Subject: [PATCH 001/113] Target net5.0 instead of netcoreapp3 --- global.json | 2 +- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Game.Benchmarks/osu.Game.Benchmarks.csproj | 2 +- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/global.json b/global.json index 10b61047ac..2cb4c02970 100644 --- a/global.json +++ b/global.json @@ -2,7 +2,7 @@ "sdk": { "allowPrerelease": false, "rollForward": "minor", - "version": "3.1.100" + "version": "5.0.100" }, "msbuild-sdks": { "Microsoft.Build.Traversal": "2.2.3" diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 62e8f7c518..7f5154f456 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -1,6 +1,6 @@  - netcoreapp3.1 + net5.0 WinExe true A free-to-win rhythm game. Rhythm is just a *click* away! diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj index ff26f4afaa..7805bfcefc 100644 --- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj +++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net5.0 Exe false diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index dfe3bf8af4..a51b9830be 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -9,7 +9,7 @@ WinExe - netcoreapp3.1 + net5.0 diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index 892f27d27f..d314671bce 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -9,7 +9,7 @@ WinExe - netcoreapp3.1 + net5.0 diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 3639c3616f..b0799bd3f5 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -9,7 +9,7 @@ WinExe - netcoreapp3.1 + net5.0 diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index b59f3a4344..d3dbba4bfc 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -9,7 +9,7 @@ WinExe - netcoreapp3.1 + net5.0 diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index c692bcd5e4..34de54411b 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -10,7 +10,7 @@ WinExe - netcoreapp3.1 + net5.0 diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index 5d55196dcf..d820794980 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -11,7 +11,7 @@ WinExe - netcoreapp3.1 + net5.0 From ca0e1c8cee1ffd03b2bb5fe773741012b90bb654 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 20 Nov 2020 10:47:57 +0300 Subject: [PATCH 002/113] Update NuGet packages --- osu.Desktop/osu.Desktop.csproj | 4 ++-- osu.Game.Tournament/osu.Game.Tournament.csproj | 2 +- osu.Game/osu.Game.csproj | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 7f5154f456..2052c4bc25 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -24,11 +24,11 @@ - + - + diff --git a/osu.Game.Tournament/osu.Game.Tournament.csproj b/osu.Game.Tournament/osu.Game.Tournament.csproj index 9cce40c9d3..b049542bb0 100644 --- a/osu.Game.Tournament/osu.Game.Tournament.csproj +++ b/osu.Game.Tournament/osu.Game.Tournament.csproj @@ -9,6 +9,6 @@ - + \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 54f3fcede6..1670bf5b11 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -21,8 +21,8 @@ - - + + @@ -31,6 +31,6 @@ - + From f562a7ea0df68baee20551108bb4bd9fd13d5747 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 20 Nov 2020 11:52:17 +0300 Subject: [PATCH 003/113] Fix FileNotFoundException on startup --- osu.Desktop/osu.Desktop.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 2052c4bc25..53b9cdcf92 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -24,6 +24,8 @@ + + From 044622036cbc94adae124f68ec5fbff18befb2b4 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 20 Nov 2020 11:53:17 +0300 Subject: [PATCH 004/113] Disable CA1416 --- osu.Desktop/OsuGameDesktop.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 0feab9a717..e2a06d7877 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -58,8 +58,10 @@ namespace osu.Desktop try { +#pragma warning disable CA1416 // Validate platform compatibility using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty).ToString()?.Split('"')[1].Replace("osu!.exe", ""); +#pragma warning restore CA1416 // Validate platform compatibility if (checkExists(stableInstallPath)) return stableInstallPath; From 1a676ef0d82c4d4cfd0d7fbac2338da3a763272f Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 20 Nov 2020 12:06:08 +0300 Subject: [PATCH 005/113] Resolve CA1416 properly using new API --- osu.Desktop/OsuGameDesktop.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index e2a06d7877..f9c932b260 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -5,6 +5,7 @@ using System; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.Versioning; using System.Threading.Tasks; using Microsoft.Win32; using osu.Desktop.Overlays; @@ -56,19 +57,12 @@ namespace osu.Desktop string stableInstallPath; - try + if (OperatingSystem.IsWindows()) { -#pragma warning disable CA1416 // Validate platform compatibility - using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) - stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty).ToString()?.Split('"')[1].Replace("osu!.exe", ""); -#pragma warning restore CA1416 // Validate platform compatibility - + stableInstallPath = getStableInstallPathFromRegistry(); if (checkExists(stableInstallPath)) return stableInstallPath; } - catch - { - } stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!"); if (checkExists(stableInstallPath)) @@ -81,6 +75,13 @@ namespace osu.Desktop return null; } + [SupportedOSPlatform("windows")] + private string getStableInstallPathFromRegistry() + { + using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) + return key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty).ToString()?.Split('"')[1].Replace("osu!.exe", ""); + } + protected override UpdateManager CreateUpdateManager() { switch (RuntimeInfo.OS) From 743541649706d9b9165197421860dfd0b3cf264d Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Fri, 20 Nov 2020 14:13:16 +0300 Subject: [PATCH 006/113] Workaround FileNotFoundException in a test projects --- osu.Desktop/osu.Desktop.csproj | 2 -- osu.Game/osu.Game.csproj | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 53b9cdcf92..2052c4bc25 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -24,8 +24,6 @@ - - diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1670bf5b11..1c6139b519 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,6 +18,8 @@ + + From 1feda1152da0b15835af3ce83bed31faf5fbed65 Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Sat, 21 Nov 2020 02:06:20 +0300 Subject: [PATCH 007/113] Fix InspectCode warnings --- osu.Desktop/OsuGameDesktop.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs | 5 +++++ osu.Game.Tournament/IPC/FileBasedIPC.cs | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index f9c932b260..dbbf6d048b 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -79,7 +79,7 @@ namespace osu.Desktop private string getStableInstallPathFromRegistry() { using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) - return key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty).ToString()?.Split('"')[1].Replace("osu!.exe", ""); + return key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty)?.ToString()?.Split('"')[1].Replace("osu!.exe", ""); } protected override UpdateManager CreateUpdateManager() diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index 35473ee76c..58992366ff 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.Diagnostics; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; @@ -73,6 +74,8 @@ namespace osu.Game.Tests.Visual.Gameplay switch (args.Action) { case NotifyCollectionChangedAction.Add: + Debug.Assert(args.NewItems != null, "args.NewItems != null"); + foreach (int user in args.NewItems) { if (user == api.LocalUser.Value.Id) @@ -82,6 +85,8 @@ namespace osu.Game.Tests.Visual.Gameplay break; case NotifyCollectionChangedAction.Remove: + Debug.Assert(args.OldItems != null, "args.OldItems != null"); + foreach (int user in args.OldItems) { if (user == api.LocalUser.Value.Id) diff --git a/osu.Game.Tournament/IPC/FileBasedIPC.cs b/osu.Game.Tournament/IPC/FileBasedIPC.cs index 999ce61ac8..99147951b2 100644 --- a/osu.Game.Tournament/IPC/FileBasedIPC.cs +++ b/osu.Game.Tournament/IPC/FileBasedIPC.cs @@ -243,7 +243,7 @@ namespace osu.Game.Tournament.IPC string stableInstallPath; using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu")) - stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty).ToString().Split('"')[1].Replace("osu!.exe", ""); + stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty)?.ToString().Split('"')[1].Replace("osu!.exe", ""); if (ipcFileExistsInDirectory(stableInstallPath)) return stableInstallPath; From 5d7294451f1a5a24a7eabdf7a738e6fc07278b17 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 16 Dec 2020 14:28:16 +0100 Subject: [PATCH 008/113] Refactor Import() overload to take a list of import tasks instead. --- osu.Android/OsuGameActivity.cs | 3 ++- osu.Game/Database/ArchiveModelManager.cs | 4 ++-- osu.Game/Database/ICanAcceptFiles.cs | 7 ++----- osu.Game/OsuGame.cs | 6 +++--- osu.Game/OsuGameBase.cs | 6 +++--- osu.Game/Screens/Edit/Setup/ResourcesSection.cs | 2 +- 6 files changed, 13 insertions(+), 15 deletions(-) diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs index e801c2ca6e..bd5523f0e2 100644 --- a/osu.Android/OsuGameActivity.cs +++ b/osu.Android/OsuGameActivity.cs @@ -11,6 +11,7 @@ using Android.OS; using Android.Provider; using Android.Views; using osu.Framework.Android; +using osu.Game.Database; namespace osu.Android { @@ -82,7 +83,7 @@ namespace osu.Android using (var stream = ContentResolver.OpenInputStream(uri)) await stream.CopyToAsync(copy); - await game.Import(copy, filename); + await game.Import(new ImportTask(copy, filename)); }, TaskCreationOptions.LongRunning); } } diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 36cc4cce39..9f69ad035f 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -115,13 +115,13 @@ namespace osu.Game.Database return Import(notification, paths.Select(p => new ImportTask(p)).ToArray()); } - public Task Import(Stream stream, string filename) + public Task Import(params ImportTask[] tasks) { var notification = new ProgressNotification { State = ProgressNotificationState.Active }; PostNotification?.Invoke(notification); - return Import(notification, new ImportTask(stream, filename)); + return Import(notification, tasks); } protected async Task> Import(ProgressNotification notification, params ImportTask[] tasks) diff --git a/osu.Game/Database/ICanAcceptFiles.cs b/osu.Game/Database/ICanAcceptFiles.cs index 276c284c9f..5ec187975a 100644 --- a/osu.Game/Database/ICanAcceptFiles.cs +++ b/osu.Game/Database/ICanAcceptFiles.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; -using System.IO; using System.Threading.Tasks; namespace osu.Game.Database @@ -19,11 +18,9 @@ namespace osu.Game.Database Task Import(params string[] paths); /// - /// Import the provided stream as a simple item. + /// Import the specified files from the given import tasks. /// - /// The stream to import files from. Should be in a supported archive format. - /// The filename of the archive being imported. - Task Import(Stream stream, string filename); + Task Import(params ImportTask[] tasks); /// /// An array of accepted file extensions (in the standard format of ".abc"). diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index d67d790ce2..1f5b991758 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -52,7 +52,7 @@ using osu.Game.Updater; using osu.Game.Utils; using LogLevel = osu.Framework.Logging.LogLevel; using osu.Game.Users; -using System.IO; +using osu.Game.Database; namespace osu.Game { @@ -427,10 +427,10 @@ namespace osu.Game }, validScreens: new[] { typeof(PlaySongSelect) }); } - public override Task Import(Stream stream, string filename) + public override Task Import(params ImportTask[] imports) { // encapsulate task as we don't want to begin the import process until in a ready state. - var importTask = new Task(async () => await base.Import(stream, filename)); + var importTask = new Task(async () => await base.Import(imports)); waitForReady(() => this, _ => importTask.Start()); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 150569f1dd..0a579cc347 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -395,14 +395,14 @@ namespace osu.Game } } - public virtual async Task Import(Stream stream, string filename) + public virtual async Task Import(params ImportTask[] tasks) { - var extension = Path.GetExtension(filename)?.ToLowerInvariant(); + var extension = Path.GetExtension(tasks.First().Path)?.ToLowerInvariant(); foreach (var importer in fileImporters) { if (importer.HandledExtensions.Contains(extension)) - await importer.Import(stream, Path.GetFileNameWithoutExtension(filename)); + await importer.Import(tasks); } } diff --git a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs index 0c957b80af..fe9b10667a 100644 --- a/osu.Game/Screens/Edit/Setup/ResourcesSection.cs +++ b/osu.Game/Screens/Edit/Setup/ResourcesSection.cs @@ -100,7 +100,7 @@ namespace osu.Game.Screens.Edit.Setup return Task.CompletedTask; } - Task ICanAcceptFiles.Import(Stream stream, string filename) => throw new NotImplementedException(); + Task ICanAcceptFiles.Import(params ImportTask[] tasks) => throw new NotImplementedException(); protected override void LoadComplete() { From 9d8906924580cc3886759de27dbbb05fb5460b00 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 16 Dec 2020 20:33:29 +0100 Subject: [PATCH 009/113] Add ability to import multiple files at once on android. --- osu.Android/OsuGameActivity.cs | 63 ++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs index bd5523f0e2..bf73f33b74 100644 --- a/osu.Android/OsuGameActivity.cs +++ b/osu.Android/OsuGameActivity.cs @@ -1,7 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Threading.Tasks; using Android.App; using Android.Content; @@ -16,7 +18,7 @@ using osu.Game.Database; namespace osu.Android { [Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullUser, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = false)] - [IntentFilter(new[] { Intent.ActionDefault, Intent.ActionSend }, Categories = new[] { Intent.CategoryDefault }, DataPathPatterns = new[] { ".*\\.osz", ".*\\.osk" }, DataMimeType = "application/*")] + [IntentFilter(new[] { Intent.ActionDefault, Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, DataPathPatterns = new[] { ".*\\.osz", ".*\\.osk" }, DataMimeType = "application/*")] public class OsuGameActivity : AndroidGameActivity { private OsuGameAndroid game; @@ -49,41 +51,64 @@ namespace osu.Android { case Intent.ActionDefault: if (intent.Scheme == ContentResolver.SchemeContent) - handleImportFromUri(intent.Data); + handleImportFromUris(intent.Data); break; case Intent.ActionSend: { var content = intent.ClipData?.GetItemAt(0); if (content != null) - handleImportFromUri(content.Uri); + handleImportFromUris(content.Uri); + break; + } + + case Intent.ActionSendMultiple: + { + var uris = new List(); + for (int i = 0; i < intent.ClipData?.ItemCount; i++) + { + var content = intent.ClipData?.GetItemAt(i); + if (content != null) + uris.Add(content.Uri); + } + handleImportFromUris(uris.ToArray()); break; } } } - private void handleImportFromUri(Uri uri) => Task.Factory.StartNew(async () => + private void handleImportFromUris(params Uri[] uris) => Task.Factory.StartNew(async () => { - // there are more performant overloads of this method, but this one is the most backwards-compatible - // (dates back to API 1). - var cursor = ContentResolver?.Query(uri, null, null, null, null); + var tasks = new List(); - if (cursor == null) - return; + await Task.WhenAll(uris.Select(async uri => + { + // there are more performant overloads of this method, but this one is the most backwards-compatible + // (dates back to API 1). + var cursor = ContentResolver?.Query(uri, null, null, null, null); - cursor.MoveToFirst(); + if (cursor == null) + return; - var filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName); - string filename = cursor.GetString(filenameColumn); + cursor.MoveToFirst(); - // SharpCompress requires archive streams to be seekable, which the stream opened by - // OpenInputStream() seems to not necessarily be. - // copy to an arbitrary-access memory stream to be able to proceed with the import. - var copy = new MemoryStream(); - using (var stream = ContentResolver.OpenInputStream(uri)) - await stream.CopyToAsync(copy); + var filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName); + string filename = cursor.GetString(filenameColumn); - await game.Import(new ImportTask(copy, filename)); + // SharpCompress requires archive streams to be seekable, which the stream opened by + // OpenInputStream() seems to not necessarily be. + // copy to an arbitrary-access memory stream to be able to proceed with the import. + var copy = new MemoryStream(); + using (var stream = ContentResolver.OpenInputStream(uri)) + await stream.CopyToAsync(copy); + + lock (tasks) + { + tasks.Add(new ImportTask(copy, filename)); + } + })); + + await game.Import(tasks.ToArray()); }, TaskCreationOptions.LongRunning); } } From cc0442a9a17880bd6f427638f831f97f6f50cb50 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 16 Dec 2020 20:42:30 +0100 Subject: [PATCH 010/113] Fix CI inspections. --- osu.Game/OsuGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 0a579cc347..521778a9cd 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -397,7 +397,7 @@ namespace osu.Game public virtual async Task Import(params ImportTask[] tasks) { - var extension = Path.GetExtension(tasks.First().Path)?.ToLowerInvariant(); + var extension = Path.GetExtension(tasks.First().Path).ToLowerInvariant(); foreach (var importer in fileImporters) { From 926281831b85353c1ddf878167abfbbad965a56f Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 19 Dec 2020 10:36:27 +0100 Subject: [PATCH 011/113] Fix missing XMLDoc bit. --- osu.Game/Database/ICanAcceptFiles.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Database/ICanAcceptFiles.cs b/osu.Game/Database/ICanAcceptFiles.cs index 5ec187975a..74fd6fcc36 100644 --- a/osu.Game/Database/ICanAcceptFiles.cs +++ b/osu.Game/Database/ICanAcceptFiles.cs @@ -20,6 +20,7 @@ namespace osu.Game.Database /// /// Import the specified files from the given import tasks. /// + /// The import tasks from which the files should be imported. Task Import(params ImportTask[] tasks); /// From 4fba0c8e6a3279216294a5a75fa2f79687d0a0c1 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 19 Dec 2020 10:55:39 +0100 Subject: [PATCH 012/113] Remove not used using statement. --- osu.Game/OsuGame.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4ebf7fbe63..e382ff5d48 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -51,7 +51,6 @@ using osu.Game.Screens.Select; using osu.Game.Updater; using osu.Game.Utils; using LogLevel = osu.Framework.Logging.LogLevel; -using osu.Game.Users; using osu.Game.Database; namespace osu.Game From f1aefcdf86a9ef784644614915bd11c1476c9816 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 19 Dec 2020 22:48:39 +0100 Subject: [PATCH 013/113] Handle multiple extensions in the import files. --- osu.Game/OsuGameBase.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 521778a9cd..ca87772209 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -397,13 +397,18 @@ namespace osu.Game public virtual async Task Import(params ImportTask[] tasks) { - var extension = Path.GetExtension(tasks.First().Path).ToLowerInvariant(); + var importTasks = new List(); - foreach (var importer in fileImporters) + foreach (var extension in tasks.Select(t => Path.GetExtension(t.Path)).Distinct()) { - if (importer.HandledExtensions.Contains(extension)) - await importer.Import(tasks); + var importList = tasks.Where(t => t.Path.EndsWith(extension, StringComparison.OrdinalIgnoreCase)); + var importer = fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(extension)); + + if (importer != null) + importTasks.Add(importer.Import(importList.ToArray())); } + + await Task.WhenAll(importTasks); } public IEnumerable HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions); From 6a80e1303d540187093c794302f5982fa171ae0e Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 23 Dec 2020 12:56:04 +0100 Subject: [PATCH 014/113] LINQ-ify Import() logic and ignore case of file extensions. --- osu.Game/OsuGameBase.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index ca87772209..7def93255b 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -397,18 +397,13 @@ namespace osu.Game public virtual async Task Import(params ImportTask[] tasks) { - var importTasks = new List(); - - foreach (var extension in tasks.Select(t => Path.GetExtension(t.Path)).Distinct()) + var extensions = tasks.Select(t => Path.GetExtension(t.Path).ToLowerInvariant()).Distinct(); + await Task.WhenAll(extensions.Select(ext => { - var importList = tasks.Where(t => t.Path.EndsWith(extension, StringComparison.OrdinalIgnoreCase)); - var importer = fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(extension)); + var imports = tasks.Where(t => t.Path.EndsWith(ext, StringComparison.OrdinalIgnoreCase)); - if (importer != null) - importTasks.Add(importer.Import(importList.ToArray())); - } - - await Task.WhenAll(importTasks); + return fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(ext))?.Import(imports.ToArray()) ?? Task.CompletedTask; + })); } public IEnumerable HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions); From e9e0e18dc53a83c18c6aff7a2aac27b92445c1cb Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 27 Dec 2020 14:11:30 +0100 Subject: [PATCH 015/113] Fix missed change in merge conflict... --- osu.Android/OsuGameActivity.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs index c397608bc6..7f2ef82d12 100644 --- a/osu.Android/OsuGameActivity.cs +++ b/osu.Android/OsuGameActivity.cs @@ -54,7 +54,7 @@ namespace osu.Android { case Intent.ActionDefault: if (intent.Scheme == ContentResolver.SchemeContent) - handleImportFromUri(intent.Data); + handleImportFromUris(intent.Data); else if (osu_url_schemes.Contains(intent.Scheme)) game.HandleLink(intent.DataString); break; From 4266c67bb66dc58fcdbc4406afe38a7d47c392d9 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 2 Jan 2021 19:19:55 +0100 Subject: [PATCH 016/113] Remove duplicated code path in switch. --- osu.Android/OsuGameActivity.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs index 42d9ad33ab..788e5f82be 100644 --- a/osu.Android/OsuGameActivity.cs +++ b/osu.Android/OsuGameActivity.cs @@ -62,13 +62,6 @@ namespace osu.Android break; case Intent.ActionSend: - { - var content = intent.ClipData?.GetItemAt(0); - if (content != null) - handleImportFromUris(content.Uri); - break; - } - case Intent.ActionSendMultiple: { var uris = new List(); From 249be461d511b10f541ef331b3b1aebe666d74be Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 12 Jan 2021 11:09:55 +0300 Subject: [PATCH 017/113] Add "explicit maps" search filter control --- .../Online/API/Requests/SearchBeatmapSetsRequest.cs | 8 +++++++- .../BeatmapListing/BeatmapListingFilterControl.cs | 4 +++- .../BeatmapListing/BeatmapListingSearchControl.cs | 6 +++++- osu.Game/Overlays/BeatmapListing/SearchExplicit.cs | 11 +++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapListing/SearchExplicit.cs diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index bbaa7e745f..939d3c6cb4 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -30,6 +30,8 @@ namespace osu.Game.Online.API.Requests public SearchPlayed Played { get; } + public SearchExplicit Explicit { get; } + [CanBeNull] public IReadOnlyCollection Ranks { get; } @@ -50,7 +52,8 @@ namespace osu.Game.Online.API.Requests SearchLanguage language = SearchLanguage.Any, IReadOnlyCollection extra = null, IReadOnlyCollection ranks = null, - SearchPlayed played = SearchPlayed.Any) + SearchPlayed played = SearchPlayed.Any, + SearchExplicit explicitMaps = SearchExplicit.Hide) { this.query = string.IsNullOrEmpty(query) ? string.Empty : System.Uri.EscapeDataString(query); this.ruleset = ruleset; @@ -64,6 +67,7 @@ namespace osu.Game.Online.API.Requests Extra = extra; Ranks = ranks; Played = played; + Explicit = explicitMaps; } protected override WebRequest CreateWebRequest() @@ -93,6 +97,8 @@ namespace osu.Game.Online.API.Requests if (Played != SearchPlayed.Any) req.AddParameter("played", Played.ToString().ToLowerInvariant()); + req.AddParameter("nsfw", Explicit == SearchExplicit.Show ? "true" : "false"); + req.AddCursor(cursor); return req; diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs index d991dcfcfb..650adcb4a9 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs @@ -141,6 +141,7 @@ namespace osu.Game.Overlays.BeatmapListing searchControl.Extra.CollectionChanged += (_, __) => queueUpdateSearch(); searchControl.Ranks.CollectionChanged += (_, __) => queueUpdateSearch(); searchControl.Played.BindValueChanged(_ => queueUpdateSearch()); + searchControl.Explicit.BindValueChanged(_ => queueUpdateSearch()); sortCriteria.BindValueChanged(_ => queueUpdateSearch()); sortDirection.BindValueChanged(_ => queueUpdateSearch()); @@ -193,7 +194,8 @@ namespace osu.Game.Overlays.BeatmapListing searchControl.Language.Value, searchControl.Extra, searchControl.Ranks, - searchControl.Played.Value); + searchControl.Played.Value, + searchControl.Explicit.Value); getSetsRequest.Success += response => { diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs index e232bf045f..c14d693f7d 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs @@ -42,6 +42,8 @@ namespace osu.Game.Overlays.BeatmapListing public Bindable Played => playedFilter.Current; + public Bindable Explicit => explicitFilter.Current; + public BeatmapSetInfo BeatmapSet { set @@ -65,6 +67,7 @@ namespace osu.Game.Overlays.BeatmapListing private readonly BeatmapSearchMultipleSelectionFilterRow extraFilter; private readonly BeatmapSearchScoreFilterRow ranksFilter; private readonly BeatmapSearchFilterRow playedFilter; + private readonly BeatmapSearchFilterRow explicitFilter; private readonly Box background; private readonly UpdateableBeatmapSetCover beatmapCover; @@ -125,7 +128,8 @@ namespace osu.Game.Overlays.BeatmapListing languageFilter = new BeatmapSearchFilterRow(@"Language"), extraFilter = new BeatmapSearchMultipleSelectionFilterRow(@"Extra"), ranksFilter = new BeatmapSearchScoreFilterRow(), - playedFilter = new BeatmapSearchFilterRow(@"Played") + playedFilter = new BeatmapSearchFilterRow(@"Played"), + explicitFilter = new BeatmapSearchFilterRow(@"Explicit Maps"), } } } diff --git a/osu.Game/Overlays/BeatmapListing/SearchExplicit.cs b/osu.Game/Overlays/BeatmapListing/SearchExplicit.cs new file mode 100644 index 0000000000..3e57cdd48c --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/SearchExplicit.cs @@ -0,0 +1,11 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Overlays.BeatmapListing +{ + public enum SearchExplicit + { + Hide, + Show + } +} From 24c18397397648894f0b943ec98e2f63735c71cf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 12 Jan 2021 11:10:25 +0300 Subject: [PATCH 018/113] Add global web setting for allowing explicit content --- osu.Game/Configuration/OsuConfigManager.cs | 3 +++ .../BeatmapListing/BeatmapListingSearchControl.cs | 12 +++++++++++- .../Overlays/Settings/Sections/Online/WebSettings.cs | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index eb34a0885d..5e7a843baf 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -60,6 +60,8 @@ namespace osu.Game.Configuration Set(OsuSetting.ExternalLinkWarning, true); Set(OsuSetting.PreferNoVideo, false); + Set(OsuSetting.AllowExplicitContent, false); + // Audio Set(OsuSetting.VolumeInactive, 0.25, 0, 1, 0.01); @@ -270,5 +272,6 @@ namespace osu.Game.Configuration EditorWaveformOpacity, DiscordRichPresence, AutomaticallyDownloadWhenSpectating, + AllowExplicitContent, } } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs index c14d693f7d..3761aee312 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs @@ -11,6 +11,7 @@ using osu.Framework.Bindables; using osu.Framework.Input.Events; using osu.Game.Beatmaps.Drawables; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osuTK.Graphics; @@ -140,10 +141,19 @@ namespace osu.Game.Overlays.BeatmapListing categoryFilter.Current.Value = SearchCategory.Leaderboard; } + private IBindable allowExplicitContent; + [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load(OverlayColourProvider colourProvider, OsuConfigManager config) { background.Colour = colourProvider.Dark6; + + allowExplicitContent = config.GetBindable(OsuSetting.AllowExplicitContent); + allowExplicitContent.BindValueChanged(allow => + { + // Update search control if global "explicit allowed" setting changed. + Explicit.Value = allow.NewValue ? SearchExplicit.Show : SearchExplicit.Hide; + }, true); } public void TakeFocus() => textBox.TakeFocus(); diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index 8134c350a6..da7ef46f65 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -33,6 +33,12 @@ namespace osu.Game.Overlays.Settings.Sections.Online Keywords = new[] { "spectator" }, Current = config.GetBindable(OsuSetting.AutomaticallyDownloadWhenSpectating), }, + new SettingsCheckbox + { + LabelText = "Hide warnings for explicit content in beatmaps", + Keywords = new[] { "nsfw", "18+", "offensive" }, + Current = config.GetBindable(OsuSetting.AllowExplicitContent), + } }; } } From 80fa2cf69330ff805c1de0f4464682a8f79b5156 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 12 Jan 2021 11:14:05 +0300 Subject: [PATCH 019/113] Add test coverage --- .../TestSceneBeatmapListingSearchControl.cs | 71 +++++++++++++------ 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs index 3f757031f8..cb86047dea 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.BeatmapListing; @@ -19,9 +20,18 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private readonly BeatmapListingSearchControl control; + private BeatmapListingSearchControl control; - public TestSceneBeatmapListingSearchControl() + private OsuConfigManager localConfig; + + [BackgroundDependencyLoader] + private void load() + { + Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage)); + } + + [SetUp] + public void SetUp() => Schedule(() => { OsuSpriteText query; OsuSpriteText ruleset; @@ -31,30 +41,34 @@ namespace osu.Game.Tests.Visual.UserInterface OsuSpriteText extra; OsuSpriteText ranks; OsuSpriteText played; + OsuSpriteText explicitMap; - Add(control = new BeatmapListingSearchControl + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); - - Add(new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - Children = new Drawable[] + control = new BeatmapListingSearchControl { - query = new OsuSpriteText(), - ruleset = new OsuSpriteText(), - category = new OsuSpriteText(), - genre = new OsuSpriteText(), - language = new OsuSpriteText(), - extra = new OsuSpriteText(), - ranks = new OsuSpriteText(), - played = new OsuSpriteText() + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + query = new OsuSpriteText(), + ruleset = new OsuSpriteText(), + category = new OsuSpriteText(), + genre = new OsuSpriteText(), + language = new OsuSpriteText(), + extra = new OsuSpriteText(), + ranks = new OsuSpriteText(), + played = new OsuSpriteText(), + explicitMap = new OsuSpriteText(), + } } - }); + }; control.Query.BindValueChanged(q => query.Text = $"Query: {q.NewValue}", true); control.Ruleset.BindValueChanged(r => ruleset.Text = $"Ruleset: {r.NewValue}", true); @@ -64,7 +78,8 @@ namespace osu.Game.Tests.Visual.UserInterface control.Extra.BindCollectionChanged((u, v) => extra.Text = $"Extra: {(control.Extra.Any() ? string.Join('.', control.Extra.Select(i => i.ToString().ToLowerInvariant())) : "")}", true); control.Ranks.BindCollectionChanged((u, v) => ranks.Text = $"Ranks: {(control.Ranks.Any() ? string.Join('.', control.Ranks.Select(i => i.ToString())) : "")}", true); control.Played.BindValueChanged(p => played.Text = $"Played: {p.NewValue}", true); - } + control.Explicit.BindValueChanged(e => explicitMap.Text = $"Explicit Maps: {e.NewValue}", true); + }); [Test] public void TestCovers() @@ -74,6 +89,16 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Set null beatmap", () => control.BeatmapSet = null); } + [Test] + public void TestExplicitConfig() + { + AddStep("configure explicit content to allowed", () => localConfig.Set(OsuSetting.AllowExplicitContent, true)); + AddAssert("explicit control set to show", () => control.Explicit.Value == SearchExplicit.Show); + + AddStep("configure explicit content to disallowed", () => localConfig.Set(OsuSetting.AllowExplicitContent, false)); + AddAssert("explicit control set to hide", () => control.Explicit.Value == SearchExplicit.Hide); + } + private static readonly BeatmapSetInfo beatmap_set = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo From 5f10bcce02411a22f783ba3a5bbb9d7ab66f43af Mon Sep 17 00:00:00 2001 From: Mysfit Date: Wed, 13 Jan 2021 00:09:22 -0500 Subject: [PATCH 020/113] Added beatmap colour settings checkbox and associated tests. --- .../TestSceneLegacyBeatmapSkin.cs | 78 +++++++++++++++++-- .../TestSceneSkinFallbacks.cs | 25 ++++++ osu.Game/Configuration/OsuConfigManager.cs | 2 + .../Overlays/Settings/Sections/SkinSection.cs | 5 ++ .../Play/PlayerSettings/VisualSettings.cs | 3 + .../Skinning/BeatmapSkinProvidingContainer.cs | 7 +- 6 files changed, 110 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index a768626005..83b1e28476 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -7,9 +7,12 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Bindables; using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Play; using osu.Game.Skinning; @@ -24,34 +27,81 @@ namespace osu.Game.Rulesets.Osu.Tests [Resolved] private AudioManager audio { get; set; } - [TestCase(true)] - [TestCase(false)] - public void TestBeatmapComboColours(bool customSkinColoursPresent) + private readonly Bindable beatmapSkins = new Bindable(); + private readonly Bindable beatmapColours = new Bindable(); + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + config.BindWith(OsuSetting.BeatmapSkins, beatmapSkins); + config.BindWith(OsuSetting.BeatmapColours, beatmapColours); + } + + [TestCase(true, true, true)] + [TestCase(true, false, true)] + [TestCase(false, true, true)] + [TestCase(false, false, true)] + public void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin, bool useBeatmapColour) { ExposedPlayer player = null; - AddStep("load coloured beatmap", () => player = loadBeatmap(customSkinColoursPresent, true)); + configureSettings(useBeatmapSkin, useBeatmapColour); + AddStep("load coloured beatmap", () => player = loadBeatmap(userHasCustomColours, true)); AddUntilStep("wait for player", () => player.IsLoaded); AddAssert("is beatmap skin colours", () => player.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours)); } - [Test] - public void TestBeatmapNoComboColours() + [TestCase(true, false)] + [TestCase(false, false)] + public void TestBeatmapComboColoursOverride(bool useBeatmapSkin, bool useBeatmapColour) { ExposedPlayer player = null; + configureSettings(useBeatmapSkin, useBeatmapColour); + AddStep("load coloured beatmap", () => player = loadBeatmap(true, true)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is user custom skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); + } + + [TestCase(true, false)] + [TestCase(false, false)] + public void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin, bool useBeatmapColour) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, useBeatmapColour); + AddStep("load coloured beatmap", () => player = loadBeatmap(false, true)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); + } + + [TestCase(true, true)] + [TestCase(false, true)] + [TestCase(true, false)] + [TestCase(false, false)] + public void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, useBeatmapColour); AddStep("load no-colour beatmap", () => player = loadBeatmap(false, false)); AddUntilStep("wait for player", () => player.IsLoaded); AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); } - [Test] - public void TestBeatmapNoComboColoursSkinOverride() + [TestCase(true, true)] + [TestCase(false, true)] + [TestCase(true, false)] + [TestCase(false, false)] + public void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour) { ExposedPlayer player = null; + configureSettings(useBeatmapSkin, useBeatmapColour); AddStep("load custom-skin colour", () => player = loadBeatmap(true, false)); AddUntilStep("wait for player", () => player.IsLoaded); @@ -69,6 +119,18 @@ namespace osu.Game.Rulesets.Osu.Tests return player; } + private void configureSettings(bool beatmapSkins, bool beatmapColours) + { + AddStep($"{(beatmapSkins ? "enable" : "disable")} beatmap skins", () => + { + this.beatmapSkins.Value = beatmapSkins; + }); + AddStep($"{(beatmapColours ? "enable" : "disable")} beatmap colours", () => + { + this.beatmapColours.Value = beatmapColours; + }); + } + private class ExposedPlayer : Player { private readonly bool userHasCustomColours; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs index 856bfd7e80..10baca438d 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs @@ -52,6 +52,31 @@ namespace osu.Game.Rulesets.Osu.Tests checkNextHitObject(null); } + [Test] + public void TestBeatmapColourDefault() + { + AddStep("enable user provider", () => testUserSkin.Enabled = true); + + AddStep("enable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, true)); + AddStep("enable beatmap colours", () => LocalConfig.Set(OsuSetting.BeatmapColours, true)); + checkNextHitObject("beatmap"); + + AddStep("enable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, true)); + AddStep("disable beatmap colours", () => LocalConfig.Set(OsuSetting.BeatmapColours, false)); + checkNextHitObject("beatmap"); + + AddStep("disable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, false)); + AddStep("enable beatmap colours", () => LocalConfig.Set(OsuSetting.BeatmapColours, true)); + checkNextHitObject("user"); + + AddStep("disable beatmap skin", () => LocalConfig.Set(OsuSetting.BeatmapSkins, false)); + AddStep("disable beatmap colours", () => LocalConfig.Set(OsuSetting.BeatmapColours, false)); + checkNextHitObject("user"); + + AddStep("disable user provider", () => testUserSkin.Enabled = false); + checkNextHitObject(null); + } + private void checkNextHitObject(string skin) => AddUntilStep($"check skin from {skin}", () => { diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index eb34a0885d..5a8f7b4477 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -82,6 +82,7 @@ namespace osu.Game.Configuration Set(OsuSetting.ShowStoryboard, true); Set(OsuSetting.BeatmapSkins, true); + Set(OsuSetting.BeatmapColours, true); Set(OsuSetting.BeatmapHitsounds, true); Set(OsuSetting.CursorRotation, true); @@ -250,6 +251,7 @@ namespace osu.Game.Configuration ScreenshotCaptureMenuCursor, SongSelectRightMouseScroll, BeatmapSkins, + BeatmapColours, BeatmapHitsounds, IncreaseFirstObjectVisibility, ScoreDisplayMode, diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 5898482e4a..e29f97c33e 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -70,6 +70,11 @@ namespace osu.Game.Overlays.Settings.Sections Current = config.GetBindable(OsuSetting.BeatmapSkins) }, new SettingsCheckbox + { + LabelText = "Beatmap colours", + Current = config.GetBindable(OsuSetting.BeatmapColours) + }, + new SettingsCheckbox { LabelText = "Beatmap hitsounds", Current = config.GetBindable(OsuSetting.BeatmapHitsounds) diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 8f29fe7893..a97078c461 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -14,6 +14,7 @@ namespace osu.Game.Screens.Play.PlayerSettings private readonly PlayerSliderBar blurSliderBar; private readonly PlayerCheckbox showStoryboardToggle; private readonly PlayerCheckbox beatmapSkinsToggle; + private readonly PlayerCheckbox beatmapColorsToggle; private readonly PlayerCheckbox beatmapHitsoundsToggle; public VisualSettings() @@ -43,6 +44,7 @@ namespace osu.Game.Screens.Play.PlayerSettings }, showStoryboardToggle = new PlayerCheckbox { LabelText = "Storyboard / Video" }, beatmapSkinsToggle = new PlayerCheckbox { LabelText = "Beatmap skins" }, + beatmapColorsToggle = new PlayerCheckbox { LabelText = "Beatmap colours" }, beatmapHitsoundsToggle = new PlayerCheckbox { LabelText = "Beatmap hitsounds" } }; } @@ -54,6 +56,7 @@ namespace osu.Game.Screens.Play.PlayerSettings blurSliderBar.Current = config.GetBindable(OsuSetting.BlurLevel); showStoryboardToggle.Current = config.GetBindable(OsuSetting.ShowStoryboard); beatmapSkinsToggle.Current = config.GetBindable(OsuSetting.BeatmapSkins); + beatmapColorsToggle.Current = config.GetBindable(OsuSetting.BeatmapColours); beatmapHitsoundsToggle.Current = config.GetBindable(OsuSetting.BeatmapHitsounds); } } diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index fc01f0bd31..ffc35b3ab6 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -15,6 +15,7 @@ namespace osu.Game.Skinning public class BeatmapSkinProvidingContainer : SkinProvidingContainer { private Bindable beatmapSkins; + private Bindable beatmapColours; private Bindable beatmapHitsounds; protected override bool AllowConfigurationLookup @@ -24,10 +25,10 @@ namespace osu.Game.Skinning if (beatmapSkins == null) throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed."); - return beatmapSkins.Value; + return beatmapColours.Value; } } - + protected override bool AllowDrawableLookup(ISkinComponent component) { if (beatmapSkins == null) @@ -62,6 +63,7 @@ namespace osu.Game.Skinning var config = parent.Get(); beatmapSkins = config.GetBindable(OsuSetting.BeatmapSkins); + beatmapColours = config.GetBindable(OsuSetting.BeatmapColours); beatmapHitsounds = config.GetBindable(OsuSetting.BeatmapHitsounds); return base.CreateChildDependencies(parent); @@ -71,6 +73,7 @@ namespace osu.Game.Skinning private void load() { beatmapSkins.BindValueChanged(_ => TriggerSourceChanged()); + beatmapColours.BindValueChanged(_ => TriggerSourceChanged()); beatmapHitsounds.BindValueChanged(_ => TriggerSourceChanged()); } } From 7bfb5954a8e7553dbd429f5901865525045d809a Mon Sep 17 00:00:00 2001 From: Mysfit Date: Wed, 13 Jan 2021 00:25:54 -0500 Subject: [PATCH 021/113] Fix whitespace formatting. --- osu.Game/Skinning/BeatmapSkinProvidingContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index ffc35b3ab6..c16547589d 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Skinning return beatmapColours.Value; } } - + protected override bool AllowDrawableLookup(ISkinComponent component) { if (beatmapSkins == null) From 80bcd78a4802131d02576bebcf87c16f8297f2af Mon Sep 17 00:00:00 2001 From: Mysfit Date: Wed, 13 Jan 2021 02:04:59 -0500 Subject: [PATCH 022/113] Removed unnecessary using. --- osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 83b1e28476..138182c7c4 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -12,7 +12,6 @@ using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Screens.Play; using osu.Game.Skinning; From e8daea91d22e87e95d2deaf8caf70817c6277ebc Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 12 Jan 2021 18:13:05 +0300 Subject: [PATCH 023/113] Add online beatmap "explicit content" property --- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 5 +++++ osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 06dee4d3f5..48f1f0ce68 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -31,6 +31,11 @@ namespace osu.Game.Beatmaps /// public BeatmapSetOnlineStatus Status { get; set; } + /// + /// Whether or not this beatmap set has explicit content. + /// + public bool HasExplicitContent { get; set; } + /// /// Whether or not this beatmap set has a background video. /// diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 720d6bfff4..bd1800e9f7 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -42,6 +42,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"bpm")] private double bpm { get; set; } + [JsonProperty(@"nsfw")] + private bool hasExplicitContent { get; set; } + [JsonProperty(@"video")] private bool hasVideo { get; set; } @@ -94,6 +97,7 @@ namespace osu.Game.Online.API.Requests.Responses FavouriteCount = favouriteCount, BPM = bpm, Status = Status, + HasExplicitContent = hasExplicitContent, HasVideo = hasVideo, HasStoryboard = hasStoryboard, Submitted = submitted, From ee6baeb57e0d51e8d65a3c8c70e25701cc58ada8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 12 Jan 2021 18:15:00 +0300 Subject: [PATCH 024/113] Add "explicit" marker pill --- .../BeatmapSet/ExplicitBeatmapPill.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs new file mode 100644 index 0000000000..77528c65c3 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.BeatmapSet +{ + public class ExplicitBeatmapPill : CompositeDrawable + { + public ExplicitBeatmapPill() + { + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader(true)] + private void load(OsuColour colours, OverlayColourProvider colourProvider) + { + InternalChild = new CircularContainer + { + Masking = true, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider?.Background5 ?? colours.Gray2, + }, + new OsuSpriteText + { + Margin = new MarginPadding { Horizontal = 10f, Vertical = 2f }, + Text = "EXPLICIT", + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), + // todo: this is --hsl-orange-2 from the new palette in https://github.com/ppy/osu-web/blob/8ceb46f/resources/assets/less/colors.less#L128-L151, + // should probably take the whole palette from there onto OsuColour for a nicer look in code. + Colour = Color4.FromHsl(new Vector4(45f / 360, 0.8f, 0.6f, 1f)), + } + } + }; + } + } +} From f6637eec36a460c5551e81d5b8776c12fad0caa9 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:29:30 +0300 Subject: [PATCH 025/113] Add explicit pill to beatmap panels --- .../BeatmapListing/Panels/GridBeatmapPanel.cs | 29 +++++++++++++++---- .../BeatmapListing/Panels/ListBeatmapPanel.cs | 27 ++++++++++++++--- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs b/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs index 28c36e6c56..b7002a96e5 100644 --- a/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs +++ b/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs @@ -14,6 +14,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.BeatmapSet; using osuTK; using osuTK.Graphics; @@ -24,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels private const float horizontal_padding = 10; private const float vertical_padding = 5; - private FillFlowContainer bottomPanel, statusContainer; + private FillFlowContainer bottomPanel, statusContainer, titleContainer; private PlayButton playButton; private Box progressBar; @@ -73,12 +74,20 @@ namespace osu.Game.Overlays.BeatmapListing.Panels AutoSizeAxes = Axes.Both, Padding = new MarginPadding { Left = horizontal_padding, Right = horizontal_padding }, Direction = FillDirection.Vertical, - Children = new[] + Children = new Drawable[] { - new OsuSpriteText + titleContainer = new FillFlowContainer { - Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), - Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new OsuSpriteText + { + Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + }, + } }, new OsuSpriteText { @@ -194,6 +203,16 @@ namespace osu.Game.Overlays.BeatmapListing.Panels }, }); + if (SetInfo.OnlineInfo?.HasExplicitContent ?? false) + { + titleContainer.Add(new ExplicitBeatmapPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 10f, Top = 2f }, + }); + } + if (SetInfo.OnlineInfo?.HasVideo ?? false) { statusContainer.Add(new IconPill(FontAwesome.Solid.Film)); diff --git a/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs b/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs index 433ea37f06..69671ab75b 100644 --- a/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs +++ b/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs @@ -14,6 +14,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.BeatmapSet; using osuTK; using osuTK.Graphics; @@ -26,7 +27,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels private const float vertical_padding = 5; private const float height = 70; - private FillFlowContainer statusContainer; + private FillFlowContainer statusContainer, titleContainer; protected BeatmapPanelDownloadButton DownloadButton; private PlayButton playButton; private Box progressBar; @@ -98,10 +99,18 @@ namespace osu.Game.Overlays.BeatmapListing.Panels Direction = FillDirection.Vertical, Children = new Drawable[] { - new OsuSpriteText + titleContainer = new FillFlowContainer { - Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), - Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + new OsuSpriteText + { + Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + }, + } }, new OsuSpriteText { @@ -208,6 +217,16 @@ namespace osu.Game.Overlays.BeatmapListing.Panels }, }); + if (SetInfo.OnlineInfo?.HasExplicitContent ?? false) + { + titleContainer.Add(new ExplicitBeatmapPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 10f, Top = 2f }, + }); + } + if (SetInfo.OnlineInfo?.HasVideo ?? false) { statusContainer.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) }); From 78631323ba35174543cbb09d2c8fd4f545888077 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:32:36 +0300 Subject: [PATCH 026/113] Add explicit pill to beatmap overlay --- osu.Game/Overlays/BeatmapSet/Header.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 321e496511..fbdee91d42 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -34,6 +34,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Box coverGradient; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; + private readonly ExplicitBeatmapPill explicitPill; private readonly FillFlowContainer downloadButtonsContainer; private readonly BeatmapAvailability beatmapAvailability; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; @@ -146,6 +147,13 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.BottomLeft, Margin = new MarginPadding { Left = 3, Bottom = 4 }, // To better lineup with the font }, + explicitPill = new ExplicitBeatmapPill + { + Alpha = 0f, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 10f, Top = 4 }, + } } }, artist = new OsuSpriteText @@ -253,6 +261,8 @@ namespace osu.Game.Overlays.BeatmapSet title.Text = setInfo.NewValue.Metadata.Title ?? string.Empty; artist.Text = setInfo.NewValue.Metadata.Artist ?? string.Empty; + explicitPill.Alpha = setInfo.NewValue.OnlineInfo.HasExplicitContent ? 1 : 0; + onlineStatusPill.FadeIn(500, Easing.OutQuint); onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status; From 1502b07ea86d7673dbbffa2fc2ec83612ca8d81c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:33:00 +0300 Subject: [PATCH 027/113] Add explicit pill to playlist items --- .../OnlinePlay/DrawableRoomPlaylistItem.cs | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs index e3bce4029f..7987d715e3 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs @@ -23,6 +23,7 @@ using osu.Game.Online; using osu.Game.Online.Chat; using osu.Game.Online.Rooms; using osu.Game.Overlays.BeatmapListing.Panels; +using osu.Game.Overlays.BeatmapSet; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play.HUD; @@ -41,6 +42,7 @@ namespace osu.Game.Screens.OnlinePlay private Container difficultyIconContainer; private LinkFlowContainer beatmapText; private LinkFlowContainer authorText; + private ExplicitBeatmapPill explicitPill; private ModDisplay modDisplay; private readonly Bindable beatmap = new Bindable(); @@ -116,6 +118,9 @@ namespace osu.Game.Screens.OnlinePlay authorText.AddUserLink(Item.Beatmap.Value?.Metadata.Author); } + bool hasExplicitContent = Item.Beatmap.Value.BeatmapSet.OnlineInfo?.HasExplicitContent == true; + explicitPill.Alpha = hasExplicitContent ? 1 : 0; + modDisplay.Current.Value = requiredMods.ToArray(); } @@ -165,18 +170,37 @@ namespace osu.Game.Screens.OnlinePlay { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(15, 0), + Spacing = new Vector2(10f, 0), Children = new Drawable[] { - authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, - modDisplay = new ModDisplay + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10f, 0), + Children = new Drawable[] + { + authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, + explicitPill = new ExplicitBeatmapPill + { + Alpha = 0f, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Top = 3f }, + } + }, + }, + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.4f), - DisplayUnrankedText = false, - ExpansionMode = ExpansionMode.AlwaysExpanded + Child = modDisplay = new ModDisplay + { + Scale = new Vector2(0.4f), + DisplayUnrankedText = false, + ExpansionMode = ExpansionMode.AlwaysExpanded + } } } } From 7fd55efc434fb5522de44429cc27e27c32cd6969 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:57:29 +0300 Subject: [PATCH 028/113] Add test cases for displaying explicit beatmaps --- .../Multiplayer/TestSceneDrawableRoomPlaylist.cs | 9 +++++++++ .../Visual/Online/TestSceneBeatmapSetOverlay.cs | 11 +++++++++++ osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs | 7 ++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 65c0cfd328..17d85d1120 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -222,6 +222,15 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("download buttons shown", () => playlist.ChildrenOfType().All(d => d.IsPresent)); } + [Test] + public void TestExplicitBeatmapItem() + { + var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo; + beatmap.BeatmapSet.OnlineInfo.HasExplicitContent = true; + + createPlaylist(beatmap); + } + private void moveToItem(int index, Vector2? offset = null) => AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType>().ElementAt(index), offset)); diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index c5d1fd6887..689321698a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -235,6 +235,17 @@ namespace osu.Game.Tests.Visual.Online AddAssert("left-most beatmap selected", () => overlay.Header.Picker.Difficulties.First().State == BeatmapPicker.DifficultySelectorState.Selected); } + [Test] + public void TestExplicitBeatmap() + { + AddStep("show explicit map", () => + { + var beatmapSet = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet; + beatmapSet.OnlineInfo.HasExplicitContent = true; + overlay.ShowBeatmapSet(beatmapSet); + }); + } + [Test] public void TestHide() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 74ece5da05..fd5f306e07 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -99,13 +99,16 @@ namespace osu.Game.Tests.Visual.Online [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - var normal = CreateWorkingBeatmap(Ruleset.Value).BeatmapSetInfo; + var normal = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet; normal.OnlineInfo.HasVideo = true; normal.OnlineInfo.HasStoryboard = true; var undownloadable = getUndownloadableBeatmapSet(); var manyDifficulties = getManyDifficultiesBeatmapSet(rulesets); + var explicitMap = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet; + explicitMap.OnlineInfo.HasExplicitContent = true; + Child = new BasicScrollContainer { RelativeSizeAxes = Axes.Both, @@ -121,9 +124,11 @@ namespace osu.Game.Tests.Visual.Online new GridBeatmapPanel(normal), new GridBeatmapPanel(undownloadable), new GridBeatmapPanel(manyDifficulties), + new GridBeatmapPanel(explicitMap), new ListBeatmapPanel(normal), new ListBeatmapPanel(undownloadable), new ListBeatmapPanel(manyDifficulties), + new ListBeatmapPanel(explicitMap) }, }, }; From f827c620813468f2c670f393c424b84e8b11f634 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:58:55 +0300 Subject: [PATCH 029/113] Add empty online info to test beatmap This is for `BeatmapSetOverlay` to not eat a null reference trying to access `Beatmap.OnlineInfo`. --- osu.Game/Tests/Beatmaps/TestBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index 035cb64099..fa6dc5647d 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -32,6 +32,7 @@ namespace osu.Game.Tests.Beatmaps BeatmapInfo.BeatmapSet.Files = new List(); BeatmapInfo.BeatmapSet.Beatmaps = new List { BeatmapInfo }; BeatmapInfo.Length = 75000; + BeatmapInfo.OnlineInfo = new BeatmapOnlineInfo(); BeatmapInfo.BeatmapSet.OnlineInfo = new BeatmapSetOnlineInfo { Status = BeatmapSetOnlineStatus.Ranked, From 268f9d661f16c55aa1c8ebadb4f44e05baa7373a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 13:00:14 +0300 Subject: [PATCH 030/113] Dispose of local config on disposal --- .../UserInterface/TestSceneBeatmapListingSearchControl.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs index cb86047dea..dc46da6293 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs @@ -99,6 +99,12 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("explicit control set to hide", () => control.Explicit.Value == SearchExplicit.Hide); } + protected override void Dispose(bool isDisposing) + { + localConfig?.Dispose(); + base.Dispose(isDisposing); + } + private static readonly BeatmapSetInfo beatmap_set = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo From 9d59d784f8674b1319a175c1edb74d079de76dfe Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 17:06:44 +0300 Subject: [PATCH 031/113] Add Colour{1-4} properties to `OverlayColourProvider` --- osu.Game/Overlays/OverlayColourProvider.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index 9816f313ad..f33223d7aa 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -16,6 +16,11 @@ namespace osu.Game.Overlays this.colourScheme = colourScheme; } + public Color4 Colour1 => getColour(1, 0.7f); + public Color4 Colour2 => getColour(0.8f, 0.6f); + public Color4 Colour3 => getColour(0.6f, 0.5f); + public Color4 Colour4 => getColour(0.4f, 0.3f); + public Color4 Highlight1 => getColour(1, 0.7f); public Color4 Content1 => getColour(0.4f, 1); public Color4 Content2 => getColour(0.4f, 0.9f); From e275dd02e08ab8d9e890d2d0a2b1f822e1c53f6c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 17:07:11 +0300 Subject: [PATCH 032/113] Create static colour properties for now --- osu.Game/Overlays/OverlayColourProvider.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index f33223d7aa..abd1e43f25 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -11,6 +11,13 @@ namespace osu.Game.Overlays { private readonly OverlayColourScheme colourScheme; + public static OverlayColourProvider Red { get; } = new OverlayColourProvider(OverlayColourScheme.Red); + public static OverlayColourProvider Pink { get; } = new OverlayColourProvider(OverlayColourScheme.Pink); + public static OverlayColourProvider Orange { get; } = new OverlayColourProvider(OverlayColourScheme.Orange); + public static OverlayColourProvider Green { get; } = new OverlayColourProvider(OverlayColourScheme.Green); + public static OverlayColourProvider Purple { get; } = new OverlayColourProvider(OverlayColourScheme.Purple); + public static OverlayColourProvider Blue { get; } = new OverlayColourProvider(OverlayColourScheme.Blue); + public OverlayColourProvider(OverlayColourScheme colourScheme) { this.colourScheme = colourScheme; From 43daa7c7c09463acac11095bc93f304e1c20ae83 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 17:07:42 +0300 Subject: [PATCH 033/113] Use `Colour2` of orange theme for explicit pill --- osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs index 77528c65c3..ad19dffccb 100644 --- a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs +++ b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs @@ -7,8 +7,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { @@ -38,9 +36,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Horizontal = 10f, Vertical = 2f }, Text = "EXPLICIT", Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), - // todo: this is --hsl-orange-2 from the new palette in https://github.com/ppy/osu-web/blob/8ceb46f/resources/assets/less/colors.less#L128-L151, - // should probably take the whole palette from there onto OsuColour for a nicer look in code. - Colour = Color4.FromHsl(new Vector4(45f / 360, 0.8f, 0.6f, 1f)), + Colour = OverlayColourProvider.Orange.Colour2, } } }; From 1248d39d7e5fa6a7a30271a1346059594e0e021d Mon Sep 17 00:00:00 2001 From: Mysfit Date: Wed, 13 Jan 2021 13:07:07 -0500 Subject: [PATCH 034/113] Reverted change to AllowConfigurationLookup and added a separate AllowColourLookup bool with config case based on lookup type in SkinProvidingContainer GetConfig call. --- .../Skinning/BeatmapSkinProvidingContainer.cs | 11 ++++++ osu.Game/Skinning/SkinProvidingContainer.cs | 34 ++++++++++++++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index c16547589d..57c08a903f 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs @@ -25,6 +25,17 @@ namespace osu.Game.Skinning if (beatmapSkins == null) throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed."); + return beatmapSkins.Value; + } + } + + protected override bool AllowColourLookup + { + get + { + if (beatmapColours == null) + throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed."); + return beatmapColours.Value; } } diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index adf62ed452..3232a30110 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -32,6 +32,8 @@ namespace osu.Game.Skinning protected virtual bool AllowConfigurationLookup => true; + protected virtual bool AllowColourLookup => true; + public SkinProvidingContainer(ISkin skin) { this.skin = skin; @@ -68,11 +70,35 @@ namespace osu.Game.Skinning public IBindable GetConfig(TLookup lookup) { - if (AllowConfigurationLookup && skin != null) + if (skin != null) { - var bindable = skin.GetConfig(lookup); - if (bindable != null) - return bindable; + switch (lookup) + { + // todo: the GlobalSkinColours switch is pulled from LegacySkin and should not exist. + // will likely change based on how databased storage of skin configuration goes. + case GlobalSkinColours global: + switch (global) + { + case GlobalSkinColours.ComboColours: + var bindable = skin.GetConfig(lookup); + if (bindable != null && AllowColourLookup) + return bindable; + else + return fallbackSource?.GetConfig(lookup); + } + + break; + + default: + if (AllowConfigurationLookup) + { + var bindable = skin.GetConfig(lookup); + if (bindable != null) + return bindable; + } + + break; + } } return fallbackSource?.GetConfig(lookup); From 8b95817f7abf8f5674ffa11d37c1eb37ce259806 Mon Sep 17 00:00:00 2001 From: Mysfit Date: Wed, 13 Jan 2021 16:05:46 -0500 Subject: [PATCH 035/113] Moved SkinProvidingContainer bindable fetching to common method. Replaced redundant test boolean declarations with inline values. --- .../TestSceneLegacyBeatmapSkin.cs | 28 +++++++++---------- osu.Game/Skinning/SkinProvidingContainer.cs | 24 ++++++++-------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 138182c7c4..22b028906f 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -36,41 +36,41 @@ namespace osu.Game.Rulesets.Osu.Tests config.BindWith(OsuSetting.BeatmapColours, beatmapColours); } - [TestCase(true, true, true)] - [TestCase(true, false, true)] - [TestCase(false, true, true)] - [TestCase(false, false, true)] - public void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin, bool useBeatmapColour) + [TestCase(true, true)] + [TestCase(true, false)] + [TestCase(false, true)] + [TestCase(false, false)] + public void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin) { ExposedPlayer player = null; - configureSettings(useBeatmapSkin, useBeatmapColour); + configureSettings(useBeatmapSkin, true); AddStep("load coloured beatmap", () => player = loadBeatmap(userHasCustomColours, true)); AddUntilStep("wait for player", () => player.IsLoaded); AddAssert("is beatmap skin colours", () => player.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours)); } - [TestCase(true, false)] - [TestCase(false, false)] - public void TestBeatmapComboColoursOverride(bool useBeatmapSkin, bool useBeatmapColour) + [TestCase(true)] + [TestCase(false)] + public void TestBeatmapComboColoursOverride(bool useBeatmapSkin) { ExposedPlayer player = null; - configureSettings(useBeatmapSkin, useBeatmapColour); + configureSettings(useBeatmapSkin, false); AddStep("load coloured beatmap", () => player = loadBeatmap(true, true)); AddUntilStep("wait for player", () => player.IsLoaded); AddAssert("is user custom skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); } - [TestCase(true, false)] - [TestCase(false, false)] - public void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin, bool useBeatmapColour) + [TestCase(true)] + [TestCase(false)] + public void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin) { ExposedPlayer player = null; - configureSettings(useBeatmapSkin, useBeatmapColour); + configureSettings(useBeatmapSkin, false); AddStep("load coloured beatmap", () => player = loadBeatmap(false, true)); AddUntilStep("wait for player", () => player.IsLoaded); diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 3232a30110..ae9a84932a 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -80,30 +80,28 @@ namespace osu.Game.Skinning switch (global) { case GlobalSkinColours.ComboColours: - var bindable = skin.GetConfig(lookup); - if (bindable != null && AllowColourLookup) - return bindable; - else - return fallbackSource?.GetConfig(lookup); + return getBindable(lookup, AllowColourLookup); } break; default: - if (AllowConfigurationLookup) - { - var bindable = skin.GetConfig(lookup); - if (bindable != null) - return bindable; - } - - break; + return getBindable(lookup, AllowConfigurationLookup); } } return fallbackSource?.GetConfig(lookup); } + private IBindable getBindable(TLookup lookup, bool bindableReturnCheck) + { + var bindable = skin.GetConfig(lookup); + if (bindable != null && bindableReturnCheck) + return bindable; + else + return fallbackSource?.GetConfig(lookup); + } + protected virtual void TriggerSourceChanged() => SourceChanged?.Invoke(); protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) From 562634dfd2de90736dfb812c9d8834c0c97bcb4c Mon Sep 17 00:00:00 2001 From: Jesse Myers Date: Wed, 13 Jan 2021 16:49:14 -0500 Subject: [PATCH 036/113] Improve naming around the config lookup with fallback private method. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Skinning/SkinProvidingContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index ae9a84932a..2dc19667e4 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -93,10 +93,10 @@ namespace osu.Game.Skinning return fallbackSource?.GetConfig(lookup); } - private IBindable getBindable(TLookup lookup, bool bindableReturnCheck) + private IBindable lookupWithFallback(TLookup lookup, bool canUseSkinLookup) { var bindable = skin.GetConfig(lookup); - if (bindable != null && bindableReturnCheck) + if (bindable != null && canUseSkinLookup) return bindable; else return fallbackSource?.GetConfig(lookup); From abf718242b11519825228a2f6098dff745231608 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 14 Jan 2021 05:40:43 +0300 Subject: [PATCH 037/113] Make explicit marker font semi-bold --- osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs index ad19dffccb..aefb3299a5 100644 --- a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs +++ b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.BeatmapSet { Margin = new MarginPadding { Horizontal = 10f, Vertical = 2f }, Text = "EXPLICIT", - Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), + Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold), Colour = OverlayColourProvider.Orange.Colour2, } } From 6281c1086ac377503c89a5648608e47ab6b71e89 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 14 Jan 2021 05:41:09 +0300 Subject: [PATCH 038/113] Space out explicit marker in beatmap overlay --- osu.Game/Overlays/BeatmapSet/Header.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index fbdee91d42..9f2b40dfa4 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -152,7 +152,7 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0f, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 10f, Top = 4 }, + Margin = new MarginPadding { Left = 15f, Top = 4 }, } } }, From 99e43c77c23709c90100cea34210c5a2d054a206 Mon Sep 17 00:00:00 2001 From: Mysfit Date: Thu, 14 Jan 2021 16:53:55 -0500 Subject: [PATCH 039/113] Simplified colour config checks in SkinProvidingContainer.cs --- osu.Game/Skinning/SkinProvidingContainer.cs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index 2dc19667e4..d2645eff68 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Textures; using osu.Game.Audio; +using osuTK.Graphics; namespace osu.Game.Skinning { @@ -72,22 +73,12 @@ namespace osu.Game.Skinning { if (skin != null) { - switch (lookup) - { - // todo: the GlobalSkinColours switch is pulled from LegacySkin and should not exist. - // will likely change based on how databased storage of skin configuration goes. - case GlobalSkinColours global: - switch (global) - { - case GlobalSkinColours.ComboColours: - return getBindable(lookup, AllowColourLookup); - } + TValue tValueTypeCheck = default; - break; - - default: - return getBindable(lookup, AllowConfigurationLookup); - } + if (lookup is GlobalSkinColours || tValueTypeCheck is Color4) + return lookupWithFallback(lookup, AllowColourLookup); + else + return lookupWithFallback(lookup, AllowConfigurationLookup); } return fallbackSource?.GetConfig(lookup); From dc8e38cf4d8dfcdb0a33a6d4c73147ce43fe4c05 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 15 Jan 2021 07:20:13 +0300 Subject: [PATCH 040/113] Remove pointless inline comment --- osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs index 3761aee312..5c6267b726 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs @@ -151,7 +151,6 @@ namespace osu.Game.Overlays.BeatmapListing allowExplicitContent = config.GetBindable(OsuSetting.AllowExplicitContent); allowExplicitContent.BindValueChanged(allow => { - // Update search control if global "explicit allowed" setting changed. Explicit.Value = allow.NewValue ? SearchExplicit.Show : SearchExplicit.Hide; }, true); } From 4cccde9007cdb1646f041da71d77184c51f490d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 13:20:46 +0900 Subject: [PATCH 041/113] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 492c88c7e4..919d83f8db 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ff016199d3..ac014f2964 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -28,7 +28,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 93be3645ee..799042626b 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -88,7 +88,7 @@ - + From 0c01a3a685c9ba1ca5c29f5e124043780c9f1d61 Mon Sep 17 00:00:00 2001 From: Mysfit Date: Thu, 14 Jan 2021 23:30:24 -0500 Subject: [PATCH 042/113] Found a better solution than TValue type checking for additional beatmap colour settings. Added unit tests for Catch Beatmap Skin settings. --- .../TestSceneLegacyBeatmapSkin.cs | 360 ++++++++++++++++++ osu.Game/Skinning/SkinProvidingContainer.cs | 5 +- 2 files changed, 361 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs new file mode 100644 index 0000000000..12ceaaa6fa --- /dev/null +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs @@ -0,0 +1,360 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Bindables; +using osu.Framework.IO.Stores; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.Skinning; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Objects; +using osu.Game.Screens.Play; +using osu.Game.Skinning; +using osu.Game.Tests.Visual; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Tests +{ + public class TestSceneLegacyBeatmapSkin : ScreenTestScene + { + [Resolved] + private AudioManager audio { get; set; } + + private readonly Bindable beatmapSkins = new Bindable(); + private readonly Bindable beatmapColours = new Bindable(); + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + config.BindWith(OsuSetting.BeatmapSkins, beatmapSkins); + config.BindWith(OsuSetting.BeatmapColours, beatmapColours); + } + + [TestCase(true, true)] + [TestCase(true, false)] + [TestCase(false, true)] + [TestCase(false, false)] + public void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, true); + AddStep("load coloured beatmap", () => player = loadBeatmap(userHasCustomColours, true)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is beatmap skin colours", () => player.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours)); + } + + [TestCase(true)] + [TestCase(false)] + public void TestBeatmapComboColoursOverride(bool useBeatmapSkin) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, false); + AddStep("load coloured beatmap", () => player = loadBeatmap(true, true)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is user custom skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); + } + + [TestCase(true)] + [TestCase(false)] + public void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, false); + AddStep("load coloured beatmap", () => player = loadBeatmap(false, true)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); + } + + [TestCase(true, true)] + [TestCase(false, true)] + [TestCase(true, false)] + [TestCase(false, false)] + public void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, useBeatmapColour); + AddStep("load no-colour beatmap", () => player = loadBeatmap(false, false)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); + } + + [TestCase(true, true)] + [TestCase(false, true)] + [TestCase(true, false)] + [TestCase(false, false)] + public void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, useBeatmapColour); + AddStep("load custom-skin colour", () => player = loadBeatmap(true, false)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is custom user skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); + } + + [TestCase(true)] + [TestCase(false)] + public void TestBeatmapHyperDashColours(bool useBeatmapSkin) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, true); + AddStep("load custom-skin colour", () => player = loadBeatmap(true, true)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is custom hyper dash colours", () => player.UsableHyperDashColour == TestBeatmapSkin.HYPER_DASH_COLOUR); + AddAssert("is custom hyper dash after image colours", () => player.UsableHyperDashAfterImageColour == TestBeatmapSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); + AddAssert("is custom hyper dash fruit colours", () => player.UsableHyperDashFruitColour == TestBeatmapSkin.HYPER_DASH_FRUIT_COLOUR); + } + + [TestCase(true)] + [TestCase(false)] + public void TestBeatmapHyperDashColoursOverride(bool useBeatmapSkin) + { + ExposedPlayer player = null; + + configureSettings(useBeatmapSkin, false); + AddStep("load custom-skin colour", () => player = loadBeatmap(true, true)); + AddUntilStep("wait for player", () => player.IsLoaded); + + AddAssert("is custom hyper dash colours", () => player.UsableHyperDashColour == TestSkin.HYPER_DASH_COLOUR); + AddAssert("is custom hyper dash after image colours", () => player.UsableHyperDashAfterImageColour == TestSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); + AddAssert("is custom hyper dash fruit colours", () => player.UsableHyperDashFruitColour == TestSkin.HYPER_DASH_FRUIT_COLOUR); + } + + private ExposedPlayer loadBeatmap(bool userHasCustomColours, bool beatmapHasColours) + { + ExposedPlayer player; + + Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours); + + LoadScreen(player = new ExposedPlayer(userHasCustomColours)); + + return player; + } + + private void configureSettings(bool beatmapSkins, bool beatmapColours) + { + AddStep($"{(beatmapSkins ? "enable" : "disable")} beatmap skins", () => + { + this.beatmapSkins.Value = beatmapSkins; + }); + AddStep($"{(beatmapColours ? "enable" : "disable")} beatmap colours", () => + { + this.beatmapColours.Value = beatmapColours; + }); + } + + private class ExposedPlayer : Player + { + private readonly bool userHasCustomColours; + + public ExposedPlayer(bool userHasCustomColours) + : base(new PlayerConfiguration + { + AllowPause = false, + ShowResults = false, + }) + { + this.userHasCustomColours = userHasCustomColours; + } + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + dependencies.CacheAs(new TestSkin(userHasCustomColours)); + return dependencies; + } + + public IReadOnlyList UsableComboColours => + GameplayClockContainer.ChildrenOfType() + .First() + .GetConfig>(GlobalSkinColours.ComboColours)?.Value; + + public Color4 UsableHyperDashColour => + GameplayClockContainer.ChildrenOfType() + .First() + .GetConfig(new SkinCustomColourLookup(CatchSkinColour.HyperDash))? + .Value ?? Color4.Red; + + public Color4 UsableHyperDashAfterImageColour => + GameplayClockContainer.ChildrenOfType() + .First() + .GetConfig(new SkinCustomColourLookup(CatchSkinColour.HyperDashAfterImage))? + .Value ?? Color4.Red; + + public Color4 UsableHyperDashFruitColour => + GameplayClockContainer.ChildrenOfType() + .First() + .GetConfig(new SkinCustomColourLookup(CatchSkinColour.HyperDashFruit))? + .Value ?? Color4.Red; + } + + private class TestJuiceStream : JuiceStream + { + public TestJuiceStream(float x) + { + X = x; + + Path = new SliderPath(new[] + { + new PathControlPoint(Vector2.Zero), + new PathControlPoint(new Vector2(30, 0)), + }); + } + } + + private class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap + { + private readonly bool hasColours; + + public CustomSkinWorkingBeatmap(AudioManager audio, bool hasColours) + : base(createBeatmap(new CatchRuleset().RulesetInfo), null, null, audio) + { + this.hasColours = hasColours; + } + + protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); + + private static IBeatmap createBeatmap(RulesetInfo ruleset) + { + var beatmap = new Beatmap + { + BeatmapInfo = + { + Ruleset = ruleset, + BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f } + } + }; + + beatmap.ControlPointInfo.Add(0, new TimingControlPoint()); + + // Should produce a hyper-dash (edge case test) + beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true }); + beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true }); + + double startTime = 3000; + + const float left_x = 0.02f * CatchPlayfield.WIDTH; + const float right_x = 0.98f * CatchPlayfield.WIDTH; + + createObjects(() => new Fruit { X = left_x }); + createObjects(() => new TestJuiceStream(right_x), 1); + createObjects(() => new TestJuiceStream(left_x), 1); + createObjects(() => new Fruit { X = right_x }); + createObjects(() => new Fruit { X = left_x }); + createObjects(() => new Fruit { X = right_x }); + createObjects(() => new TestJuiceStream(left_x), 1); + + beatmap.ControlPointInfo.Add(startTime, new TimingControlPoint + { + BeatLength = 50 + }); + + createObjects(() => new TestJuiceStream(left_x) + { + Path = new SliderPath(new[] + { + new PathControlPoint(Vector2.Zero), + new PathControlPoint(new Vector2(512, 0)) + }) + }, 1); + + return beatmap; + + void createObjects(Func createObject, int count = 3) + { + const float spacing = 140; + + for (int i = 0; i < count; i++) + { + var hitObject = createObject(); + hitObject.StartTime = startTime + i * spacing; + beatmap.HitObjects.Add(hitObject); + } + + startTime += 700; + } + } + } + + private class TestBeatmapSkin : LegacyBeatmapSkin + { + public static Color4[] Colours { get; } = + { + new Color4(50, 100, 150, 255), + new Color4(40, 80, 120, 255), + }; + + public static readonly Color4 HYPER_DASH_COLOUR = Color4.DarkBlue; + + public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.DarkCyan; + + public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.DarkGoldenrod; + + public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) + : base(beatmap, new ResourceStore(), null) + { + if (hasColours) + { + Configuration.AddComboColours(Colours); + Configuration.CustomColours.Add(CatchSkinColour.HyperDash.ToString(), HYPER_DASH_COLOUR); + Configuration.CustomColours.Add(CatchSkinColour.HyperDashAfterImage.ToString(), HYPER_DASH_AFTER_IMAGE_COLOUR); + Configuration.CustomColours.Add(CatchSkinColour.HyperDashFruit.ToString(), HYPER_DASH_FRUIT_COLOUR); + } + } + } + + private class TestSkin : LegacySkin, ISkinSource + { + public static Color4[] Colours { get; } = + { + new Color4(150, 100, 50, 255), + new Color4(20, 20, 20, 255), + }; + + public static readonly Color4 HYPER_DASH_COLOUR = Color4.LightBlue; + + public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.LightCoral; + + public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.LightCyan; + + public TestSkin(bool hasCustomColours) + : base(new SkinInfo(), new ResourceStore(), null, string.Empty) + { + if (hasCustomColours) + { + Configuration.AddComboColours(Colours); + Configuration.CustomColours.Add(CatchSkinColour.HyperDash.ToString(), HYPER_DASH_COLOUR); + Configuration.CustomColours.Add(CatchSkinColour.HyperDashAfterImage.ToString(), HYPER_DASH_AFTER_IMAGE_COLOUR); + Configuration.CustomColours.Add(CatchSkinColour.HyperDashFruit.ToString(), HYPER_DASH_FRUIT_COLOUR); + } + } + + public event Action SourceChanged + { + add { } + remove { } + } + } + } +} diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index d2645eff68..e97822b86e 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Textures; using osu.Game.Audio; -using osuTK.Graphics; namespace osu.Game.Skinning { @@ -73,9 +72,7 @@ namespace osu.Game.Skinning { if (skin != null) { - TValue tValueTypeCheck = default; - - if (lookup is GlobalSkinColours || tValueTypeCheck is Color4) + if (lookup is GlobalSkinColours || lookup is SkinCustomColourLookup) return lookupWithFallback(lookup, AllowColourLookup); else return lookupWithFallback(lookup, AllowConfigurationLookup); From ebbc32adfa9c4652cadff32dc5c429af9867ff09 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 14:51:26 +0900 Subject: [PATCH 043/113] Change conditional used to decide legacy judgement animation to match stable In stable, the type of legacy judgement to show is based on the presence of particle textures in the skin. We were using the skin version instead, which turns out to be incorrect and not what some user skins expect. Closes #11078. --- osu.Game/Skinning/LegacySkin.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index e4e5bf2f75..7397e3d08b 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -378,8 +378,12 @@ namespace osu.Game.Skinning // kind of wasteful that we throw this away, but should do for now. if (createDrawable() != null) { - if (Configuration.LegacyVersion > 1) - return new LegacyJudgementPieceNew(resultComponent.Component, createDrawable, getParticleTexture(resultComponent.Component)); + var particle = getParticleTexture(resultComponent.Component); + + if (particle != null) + { + return new LegacyJudgementPieceNew(resultComponent.Component, createDrawable, particle); + } else return new LegacyJudgementPieceOld(resultComponent.Component, createDrawable); } From 86f66727de47175b8045523c56f719a8051041a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 13:29:37 +0900 Subject: [PATCH 044/113] Update KeyBinding usages in line with interface changes --- osu.Game/Database/OsuDbContext.cs | 2 ++ osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs | 2 +- osu.Game/Input/Bindings/GlobalActionContainer.cs | 2 +- osu.Game/Input/KeyBindingStore.cs | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs index 2ae07b3cf8..2aae62edea 100644 --- a/osu.Game/Database/OsuDbContext.cs +++ b/osu.Game/Database/OsuDbContext.cs @@ -135,6 +135,8 @@ namespace osu.Game.Database modelBuilder.Entity().HasIndex(b => new { b.RulesetID, b.Variant }); modelBuilder.Entity().HasIndex(b => b.IntAction); + modelBuilder.Entity().Ignore(b => b.KeyCombination); + modelBuilder.Entity().Ignore(b => b.Action); modelBuilder.Entity().HasIndex(b => new { b.RulesetID, b.Variant }); diff --git a/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs index 94edc33099..d12eaa10f6 100644 --- a/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs +++ b/osu.Game/Input/Bindings/DatabasedKeyBindingContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Input.Bindings private KeyBindingStore store; - public override IEnumerable DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings(variant ?? 0); + public override IEnumerable DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings(variant ?? 0); /// /// Create a new instance. diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index b8c2fa201f..8ccdb9249e 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Input.Bindings handler = game; } - public override IEnumerable DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings).Concat(EditorKeyBindings); + public override IEnumerable DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings).Concat(EditorKeyBindings); public IEnumerable GlobalKeyBindings => new[] { diff --git a/osu.Game/Input/KeyBindingStore.cs b/osu.Game/Input/KeyBindingStore.cs index bc73d74d74..b25b00eb84 100644 --- a/osu.Game/Input/KeyBindingStore.cs +++ b/osu.Game/Input/KeyBindingStore.cs @@ -49,7 +49,7 @@ namespace osu.Game.Input } } - private void insertDefaults(IEnumerable defaults, int? rulesetId = null, int? variant = null) + private void insertDefaults(IEnumerable defaults, int? rulesetId = null, int? variant = null) { using (var usage = ContextFactory.GetForWrite()) { From 51255033e24c2afbbac85573ef5e7edf610eb920 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 13:41:35 +0900 Subject: [PATCH 045/113] Update some missed usages of KeyBindingContainer in tests --- osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs index b2ad7ca5b4..802dbf2021 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecorder.cs @@ -244,7 +244,7 @@ namespace osu.Game.Tests.Visual.Gameplay internal class TestKeyBindingContainer : KeyBindingContainer { - public override IEnumerable DefaultKeyBindings => new[] + public override IEnumerable DefaultKeyBindings => new[] { new KeyBinding(InputKey.MouseLeft, TestAction.Down), }; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs index 40c4214749..6e338b7202 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayRecording.cs @@ -179,7 +179,7 @@ namespace osu.Game.Tests.Visual.Gameplay internal class TestKeyBindingContainer : KeyBindingContainer { - public override IEnumerable DefaultKeyBindings => new[] + public override IEnumerable DefaultKeyBindings => new[] { new KeyBinding(InputKey.MouseLeft, TestAction.Down), }; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index b9ff95cb29..8278ff9adf 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -303,7 +303,7 @@ namespace osu.Game.Tests.Visual.Gameplay internal class TestKeyBindingContainer : KeyBindingContainer { - public override IEnumerable DefaultKeyBindings => new[] + public override IEnumerable DefaultKeyBindings => new[] { new KeyBinding(InputKey.MouseLeft, TestAction.Down), }; From f42a6270bbd750e2539ddad3ff97c0adb29ee521 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 14:53:55 +0900 Subject: [PATCH 046/113] Update framework (again) for native libs fix --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 919d83f8db..db5c933c41 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ac014f2964..5e9e90c78f 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -28,7 +28,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 799042626b..225cf981f2 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -88,7 +88,7 @@ - + From e0a4a666c8e5fa8224fae065d3597b49fa747103 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 15:01:16 +0900 Subject: [PATCH 047/113] Remove unnecessary workaround (mentioned package is pinned by SignalR to a working version) --- osu.Game/osu.Game.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5e9e90c78f..301ee39a61 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,8 +18,6 @@ - - From 7c612ec5561225b2a618bf11915aa693e20e7cf6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 15:11:03 +0900 Subject: [PATCH 048/113] Remove global.json --- global.json | 10 ---------- osu.sln | 1 - 2 files changed, 11 deletions(-) delete mode 100644 global.json diff --git a/global.json b/global.json deleted file mode 100644 index f5aaffcd3d..0000000000 --- a/global.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "sdk": { - "allowPrerelease": false, - "rollForward": "minor", - "version": "5.0.100" - }, - "msbuild-sdks": { - "Microsoft.Build.Traversal": "3.0.2" - } -} \ No newline at end of file diff --git a/osu.sln b/osu.sln index 1d64f6ff10..c9453359b1 100644 --- a/osu.sln +++ b/osu.sln @@ -57,7 +57,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig Directory.Build.props = Directory.Build.props - global.json = global.json osu.Android.props = osu.Android.props osu.iOS.props = osu.iOS.props CodeAnalysis\osu.ruleset = CodeAnalysis\osu.ruleset From 3f8834030416aeb80f5746a37999a83c16064d86 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 15:17:38 +0900 Subject: [PATCH 049/113] Restore previous exception handling flow for stable path lookup --- osu.Desktop/OsuGameDesktop.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 55e42b160e..d1515acafa 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -59,10 +59,14 @@ namespace osu.Desktop if (OperatingSystem.IsWindows()) { - stableInstallPath = getStableInstallPathFromRegistry(); + try + { + stableInstallPath = getStableInstallPathFromRegistry(); - if (checkExists(stableInstallPath)) - return stableInstallPath; + if (!string.IsNullOrEmpty(stableInstallPath) && checkExists(stableInstallPath)) + return stableInstallPath; + } + catch { } } stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!"); From d023ad8ad1a03b500f13b90ca5d1d24a75e182ea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 15:18:29 +0900 Subject: [PATCH 050/113] Remove assert messages --- osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs index 8278ff9adf..35b3bfc1f8 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorPlayback.cs @@ -75,7 +75,7 @@ namespace osu.Game.Tests.Visual.Gameplay switch (args.Action) { case NotifyCollectionChangedAction.Add: - Debug.Assert(args.NewItems != null, "args.NewItems != null"); + Debug.Assert(args.NewItems != null); foreach (int user in args.NewItems) { @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.Gameplay break; case NotifyCollectionChangedAction.Remove: - Debug.Assert(args.OldItems != null, "args.OldItems != null"); + Debug.Assert(args.OldItems != null); foreach (int user in args.OldItems) { From b8c85ef017184b8672adb80401375bd3c8c8e224 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Jan 2021 16:03:12 +0900 Subject: [PATCH 051/113] Revert polling changes to fix participant list display It turns out this polling was necessary to get extra data that isn't included in the main listing request. It was removed deemed useless, and in order to fix the order of rooms changing when selecting a room. Weirdly, I can't reproduce this happening any more, and on close inspection of the code can't see how it could happen in the first place. For now, let's revert this change and iterate from there, if/when the same issue arises again. I've discussed avoiding this second poll by potentially including more data (just `user_id`s?) in the main listing request, but not 100% sure on this - even if the returned data is minimal it's an extra join server-side, which could cause performance issues for large numbers of rooms. --- .../TestSceneMultiplayerRoomManager.cs | 1 + .../OnlinePlay/Multiplayer/Multiplayer.cs | 5 +++- .../Multiplayer/MultiplayerRoomManager.cs | 28 ++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs index 80d1acd145..7a3845cbf3 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs @@ -143,6 +143,7 @@ namespace osu.Game.Tests.Visual.Multiplayer RoomManager = { TimeBetweenListingPolls = { Value = 1 }, + TimeBetweenSelectionPolls = { Value = 1 } } }; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs index 310617a0bc..76f5c74433 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs @@ -33,6 +33,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer if (!this.IsCurrentScreen()) { multiplayerRoomManager.TimeBetweenListingPolls.Value = 0; + multiplayerRoomManager.TimeBetweenSelectionPolls.Value = 0; } else { @@ -40,16 +41,18 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { case LoungeSubScreen _: multiplayerRoomManager.TimeBetweenListingPolls.Value = isIdle ? 120000 : 15000; + multiplayerRoomManager.TimeBetweenSelectionPolls.Value = isIdle ? 120000 : 15000; break; // Don't poll inside the match or anywhere else. default: multiplayerRoomManager.TimeBetweenListingPolls.Value = 0; + multiplayerRoomManager.TimeBetweenSelectionPolls.Value = 0; break; } } - Logger.Log($"Polling adjusted (listing: {multiplayerRoomManager.TimeBetweenListingPolls.Value})"); + Logger.Log($"Polling adjusted (listing: {multiplayerRoomManager.TimeBetweenListingPolls.Value}, selection: {multiplayerRoomManager.TimeBetweenSelectionPolls.Value})"); } protected override Room CreateNewRoom() diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs index 5c327266a3..3cb263298f 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private StatefulMultiplayerClient multiplayerClient { get; set; } public readonly Bindable TimeBetweenListingPolls = new Bindable(); - + public readonly Bindable TimeBetweenSelectionPolls = new Bindable(); private readonly IBindable isConnected = new Bindable(); private readonly Bindable allowPolling = new Bindable(); @@ -119,6 +119,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer TimeBetweenPolls = { BindTarget = TimeBetweenListingPolls }, AllowPolling = { BindTarget = allowPolling } }, + new MultiplayerSelectionPollingComponent + { + TimeBetweenPolls = { BindTarget = TimeBetweenSelectionPolls }, + AllowPolling = { BindTarget = allowPolling } + } }; private class MultiplayerListingPollingComponent : ListingPollingComponent @@ -141,5 +146,26 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer protected override Task Poll() => !AllowPolling.Value ? Task.CompletedTask : base.Poll(); } + + private class MultiplayerSelectionPollingComponent : SelectionPollingComponent + { + public readonly IBindable AllowPolling = new Bindable(); + + protected override void LoadComplete() + { + base.LoadComplete(); + + AllowPolling.BindValueChanged(allowPolling => + { + if (!allowPolling.NewValue) + return; + + if (IsLoaded) + PollImmediately(); + }); + } + + protected override Task Poll() => !AllowPolling.Value ? Task.CompletedTask : base.Poll(); + } } } From ede5abdba4eb0f88806c38790c7a622546f70af9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Jan 2021 18:05:29 +0900 Subject: [PATCH 052/113] Fix unstable multiplayer room ordering when selection is made --- .../OnlinePlay/Components/SelectionPollingComponent.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs index 0eec155060..dcf3c94b76 100644 --- a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -47,9 +48,11 @@ namespace osu.Game.Screens.OnlinePlay.Components pollReq.Success += result => { - var rooms = new List(roomManager.Rooms); + // existing rooms need to be ordered by their position because the received of NotifyRoomsReceives expects to be able to sort them based on this order. + var rooms = new List(roomManager.Rooms.OrderBy(r => r.Position.Value)); int index = rooms.FindIndex(r => r.RoomID.Value == result.RoomID.Value); + if (index < 0) return; From 2b578e97e532fc0bb215566b8bd34df25d1d4625 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Jan 2021 18:25:32 +0900 Subject: [PATCH 053/113] Fix deadlock scenario when calculating fallback difficulty The previous code would run a calcaulation for the beatmap's own ruleset if the current one failed. While this does make sense, with the current way we use this component (and the implementation flow) it is quite unsafe. The to the call on `.Result` in the `catch` block, this would 100% deadlock due to the thread concurrency of the `ThreadedTaskScheduler` being 1. Even if the nested run could be run inline (it should be), the task scheduler won't even get to the point of checking whether this is feasible due to it being saturated by the already running task. I'm not sure if we still need this fallback lookup logic. After removing it, it's feasible that 0 stars will be returned during the scenario that previously caused a deadlock, but I don't necessarily think this is incorrect. There may be another reason for this needing to exist which I'm not aware of (diffcalc?) but if that's the case we may want to move the try-catch handling to the point of usage. To reproduce the deadlock scenario with 100% success (the repro instructions in the linked issue aren't that simple and require some patience and good timing), the main portion of the lookup can be changed to randomly trigger a nested lookup: ``` if (RNG.NextSingle() > 0.5f) return GetAsync(new DifficultyCacheLookup(key.Beatmap, key.Beatmap.Ruleset, key.OrderedMods)).Result; else return new StarDifficulty(attributes); ``` After switching beatmap once or twice, pausing debug and viewing the state of threads should show exactly what is going on. --- osu.Game/Beatmaps/BeatmapDifficultyCache.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs index 3b58062add..37d262abe5 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs @@ -260,17 +260,10 @@ namespace osu.Game.Beatmaps } catch (BeatmapInvalidForRulesetException e) { - // Conversion has failed for the given ruleset, so return the difficulty in the beatmap's default ruleset. - - // Ensure the beatmap's default ruleset isn't the one already being converted to. - // This shouldn't happen as it means something went seriously wrong, but if it does an endless loop should be avoided. if (rulesetInfo.Equals(beatmapInfo.Ruleset)) - { Logger.Error(e, $"Failed to convert {beatmapInfo.OnlineBeatmapID} to the beatmap's default ruleset ({beatmapInfo.Ruleset})."); - return new StarDifficulty(); - } - return GetAsync(new DifficultyCacheLookup(key.Beatmap, key.Beatmap.Ruleset, key.OrderedMods)).Result; + return new StarDifficulty(); } catch { From ed78be825f9a988df3920fdbda730120bebfe125 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 15:47:41 +0900 Subject: [PATCH 054/113] Fix editor timeline not snapping on non-precise wheel scroll For wheel input with precision, we still prefer exact tracking for now. May change this in the future based on feedback from mappers, but it makes little sense to do non-snapped scrolling when input is coming from a non-precise source. --- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 20836c0e68..12f7625bf9 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -138,6 +138,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline scrollToTrackTime(); } + protected override bool OnScroll(ScrollEvent e) + { + // if this is not a precision scroll event, let the editor handle the seek itself (for snapping support) + if (!e.AltPressed && !e.IsPrecise) + return false; + + return base.OnScroll(e); + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); From 88a27124c095f5a3cff7eaddaaab92cfe1832d55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 17:13:27 +0900 Subject: [PATCH 055/113] Make long spinner test longer and fix step name --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index 496b1b3559..c22b1dc407 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Tests [TestCase(true)] public void TestLongSpinner(bool autoplay) { - AddStep("Very short spinner", () => SetContents(() => testSingle(5, autoplay, 2000))); + AddStep("Very long spinner", () => SetContents(() => testSingle(5, autoplay, 4000))); AddUntilStep("Wait for completion", () => drawableSpinner.Result.HasResult); AddUntilStep("Check correct progress", () => drawableSpinner.Progress == (autoplay ? 1 : 0)); } From 6adb6b6700b4b19336955b397d5939679919d70b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 17:13:52 +0900 Subject: [PATCH 056/113] Fix spinner tests not playing spinning sound due to empty hitsamples --- osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs index c22b1dc407..f697a77d94 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinner.cs @@ -1,9 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Graphics; +using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Mods; @@ -55,7 +57,11 @@ namespace osu.Game.Rulesets.Osu.Tests var spinner = new Spinner { StartTime = Time.Current + delay, - EndTime = Time.Current + delay + length + EndTime = Time.Current + delay + length, + Samples = new List + { + new HitSampleInfo("hitnormal") + } }; spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize }); From 8a6857f151373dc2bb6edeb5239efef9932e447f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 17:16:12 +0900 Subject: [PATCH 057/113] Add support for playing a SkinnableSample without restarting it --- osu.Game/Skinning/PausableSkinnableSound.cs | 4 ++-- osu.Game/Skinning/SkinnableSound.cs | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/PausableSkinnableSound.cs b/osu.Game/Skinning/PausableSkinnableSound.cs index 4b6099e85f..cb5234c847 100644 --- a/osu.Game/Skinning/PausableSkinnableSound.cs +++ b/osu.Game/Skinning/PausableSkinnableSound.cs @@ -67,7 +67,7 @@ namespace osu.Game.Skinning } } - public override void Play() + public override void Play(bool restart = true) { cancelPendingStart(); RequestedPlaying = true; @@ -75,7 +75,7 @@ namespace osu.Game.Skinning if (samplePlaybackDisabled.Value) return; - base.Play(); + base.Play(restart); } public override void Stop() diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index 645c08cd00..b841f99598 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -119,12 +119,13 @@ namespace osu.Game.Skinning /// /// Plays the samples. /// - public virtual void Play() + /// Whether to play the sample from the beginning. + public virtual void Play(bool restart = true) { samplesContainer.ForEach(c => { if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0) - c.Play(); + c.Play(restart); }); } From 767c76921faa69b9f648e14fec3ab95f466abce1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 17:17:10 +0900 Subject: [PATCH 058/113] Adjust transition time of spinner sound --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 1f3bcece0c..4f61ab4a9a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -131,11 +131,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (tracking.NewValue) { spinningSample?.Play(); - spinningSample?.VolumeTo(1, 200); + spinningSample?.VolumeTo(1, 300); } else { - spinningSample?.VolumeTo(0, 200).Finally(_ => spinningSample.Stop()); + spinningSample?.VolumeTo(0, 300).Finally(_ => spinningSample.Stop()); } } From 311f8b70178cb5ebf0fdc23824fdae53b8336a7f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 17:17:51 +0900 Subject: [PATCH 059/113] Only restart spinning sample if it was not already playing --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 4f61ab4a9a..c5ae195274 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -130,7 +130,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { if (tracking.NewValue) { - spinningSample?.Play(); + spinningSample?.Play(!spinningSample.IsPlaying); spinningSample?.VolumeTo(1, 300); } else From 14b33236828438a72b5c6b4acc4edbba9e26d985 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jan 2021 17:18:15 +0900 Subject: [PATCH 060/113] Use OnComplete instead of Finally to avoid potentially stopping on aborted transforms --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index c5ae195274..56aedebed3 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } else { - spinningSample?.VolumeTo(0, 300).Finally(_ => spinningSample.Stop()); + spinningSample?.VolumeTo(0, 300).OnComplete(_ => spinningSample.Stop()); } } From 3c1a86d11deefc694a00ebad3369c563a07168de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 15 Jan 2021 22:04:45 +0100 Subject: [PATCH 061/113] Trim braces for consistency --- osu.Game/Skinning/LegacySkin.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 7397e3d08b..090ffaebd7 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -381,9 +381,7 @@ namespace osu.Game.Skinning var particle = getParticleTexture(resultComponent.Component); if (particle != null) - { return new LegacyJudgementPieceNew(resultComponent.Component, createDrawable, particle); - } else return new LegacyJudgementPieceOld(resultComponent.Component, createDrawable); } From 112967c1e8d0fd75c24aed6276afd95140687e79 Mon Sep 17 00:00:00 2001 From: Mysfit Date: Fri, 15 Jan 2021 23:46:46 -0500 Subject: [PATCH 062/113] Created base class for testing beatmap colours. --- .../TestSceneLegacyBeatmapSkin.cs | 191 +++++------------- .../TestSceneLegacyBeatmapSkin.cs | 178 +++++----------- .../Beatmaps/LegacyBeatmapSkinColourTest.cs | 147 ++++++++++++++ 3 files changed, 245 insertions(+), 271 deletions(-) create mode 100644 osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs index 12ceaaa6fa..89298242e5 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs @@ -2,13 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Bindables; -using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -17,179 +14,114 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Skinning; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Objects; -using osu.Game.Screens.Play; using osu.Game.Skinning; -using osu.Game.Tests.Visual; +using osu.Game.Tests.Beatmaps; using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests { - public class TestSceneLegacyBeatmapSkin : ScreenTestScene + public class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest { [Resolved] private AudioManager audio { get; set; } - private readonly Bindable beatmapSkins = new Bindable(); - private readonly Bindable beatmapColours = new Bindable(); - [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.BeatmapSkins, beatmapSkins); - config.BindWith(OsuSetting.BeatmapColours, beatmapColours); + config.BindWith(OsuSetting.BeatmapSkins, BeatmapSkins); + config.BindWith(OsuSetting.BeatmapColours, BeatmapColours); } [TestCase(true, true)] [TestCase(true, false)] [TestCase(false, true)] [TestCase(false, false)] - public void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin) + public override void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, true); - AddStep("load coloured beatmap", () => player = loadBeatmap(userHasCustomColours, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is beatmap skin colours", () => player.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours)); + TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true); + base.TestBeatmapComboColours(userHasCustomColours, useBeatmapSkin); + AddAssert("is beatmap skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours)); } [TestCase(true)] [TestCase(false)] - public void TestBeatmapComboColoursOverride(bool useBeatmapSkin) + public override void TestBeatmapComboColoursOverride(bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, false); - AddStep("load coloured beatmap", () => player = loadBeatmap(true, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is user custom skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); + TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true); + base.TestBeatmapComboColoursOverride(useBeatmapSkin); + AddAssert("is user custom skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours)); } [TestCase(true)] [TestCase(false)] - public void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin) + public override void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, false); - AddStep("load coloured beatmap", () => player = loadBeatmap(false, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); + TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true); + base.TestBeatmapComboColoursOverrideWithDefaultColours(useBeatmapSkin); + AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); } [TestCase(true, true)] [TestCase(false, true)] [TestCase(true, false)] [TestCase(false, false)] - public void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour) + public override void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, useBeatmapColour); - AddStep("load no-colour beatmap", () => player = loadBeatmap(false, false)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); + TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, false); + base.TestBeatmapNoComboColours(useBeatmapSkin, useBeatmapColour); + AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); } [TestCase(true, true)] [TestCase(false, true)] [TestCase(true, false)] [TestCase(false, false)] - public void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour) + public override void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, useBeatmapColour); - AddStep("load custom-skin colour", () => player = loadBeatmap(true, false)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is custom user skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); + TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, false); + base.TestBeatmapNoComboColoursSkinOverride(useBeatmapSkin, useBeatmapColour); + AddAssert("is custom user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours)); } [TestCase(true)] [TestCase(false)] public void TestBeatmapHyperDashColours(bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, true); - AddStep("load custom-skin colour", () => player = loadBeatmap(true, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is custom hyper dash colours", () => player.UsableHyperDashColour == TestBeatmapSkin.HYPER_DASH_COLOUR); - AddAssert("is custom hyper dash after image colours", () => player.UsableHyperDashAfterImageColour == TestBeatmapSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); - AddAssert("is custom hyper dash fruit colours", () => player.UsableHyperDashFruitColour == TestBeatmapSkin.HYPER_DASH_FRUIT_COLOUR); + TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true); + ConfigureTest(useBeatmapSkin, true, true); + AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == CatchTestBeatmapSkin.HYPER_DASH_COLOUR); + AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == CatchTestBeatmapSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); + AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == CatchTestBeatmapSkin.HYPER_DASH_FRUIT_COLOUR); } [TestCase(true)] [TestCase(false)] public void TestBeatmapHyperDashColoursOverride(bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, false); - AddStep("load custom-skin colour", () => player = loadBeatmap(true, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is custom hyper dash colours", () => player.UsableHyperDashColour == TestSkin.HYPER_DASH_COLOUR); - AddAssert("is custom hyper dash after image colours", () => player.UsableHyperDashAfterImageColour == TestSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); - AddAssert("is custom hyper dash fruit colours", () => player.UsableHyperDashFruitColour == TestSkin.HYPER_DASH_FRUIT_COLOUR); + TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true); + ConfigureTest(useBeatmapSkin, false, true); + AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == CatchTestSkin.HYPER_DASH_COLOUR); + AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == CatchTestSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); + AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == CatchTestSkin.HYPER_DASH_FRUIT_COLOUR); } - private ExposedPlayer loadBeatmap(bool userHasCustomColours, bool beatmapHasColours) + protected override ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new CatchExposedPlayer(userHasCustomColours); + + private class CatchExposedPlayer : ExposedPlayer { - ExposedPlayer player; - - Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours); - - LoadScreen(player = new ExposedPlayer(userHasCustomColours)); - - return player; - } - - private void configureSettings(bool beatmapSkins, bool beatmapColours) - { - AddStep($"{(beatmapSkins ? "enable" : "disable")} beatmap skins", () => + public CatchExposedPlayer(bool userHasCustomColours) + : base(userHasCustomColours) { - this.beatmapSkins.Value = beatmapSkins; - }); - AddStep($"{(beatmapColours ? "enable" : "disable")} beatmap colours", () => - { - this.beatmapColours.Value = beatmapColours; - }); - } - - private class ExposedPlayer : Player - { - private readonly bool userHasCustomColours; - - public ExposedPlayer(bool userHasCustomColours) - : base(new PlayerConfiguration - { - AllowPause = false, - ShowResults = false, - }) - { - this.userHasCustomColours = userHasCustomColours; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(new TestSkin(userHasCustomColours)); + dependencies.CacheAs(new CatchTestSkin(UserHasCustomColours)); return dependencies; } - public IReadOnlyList UsableComboColours => - GameplayClockContainer.ChildrenOfType() - .First() - .GetConfig>(GlobalSkinColours.ComboColours)?.Value; - public Color4 UsableHyperDashColour => GameplayClockContainer.ChildrenOfType() .First() @@ -223,17 +155,14 @@ namespace osu.Game.Rulesets.Catch.Tests } } - private class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap + private class CatchCustomSkinWorkingBeatmap : CustomSkinWorkingBeatmap { - private readonly bool hasColours; - - public CustomSkinWorkingBeatmap(AudioManager audio, bool hasColours) - : base(createBeatmap(new CatchRuleset().RulesetInfo), null, null, audio) + public CatchCustomSkinWorkingBeatmap(AudioManager audio, bool hasColours) + : base(createBeatmap(new CatchRuleset().RulesetInfo), audio, hasColours) { - this.hasColours = hasColours; } - protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); + protected override ISkin GetSkin() => new CatchTestBeatmapSkin(BeatmapInfo, HasColours); private static IBeatmap createBeatmap(RulesetInfo ruleset) { @@ -297,26 +226,19 @@ namespace osu.Game.Rulesets.Catch.Tests } } - private class TestBeatmapSkin : LegacyBeatmapSkin + private class CatchTestBeatmapSkin : TestBeatmapSkin { - public static Color4[] Colours { get; } = - { - new Color4(50, 100, 150, 255), - new Color4(40, 80, 120, 255), - }; - public static readonly Color4 HYPER_DASH_COLOUR = Color4.DarkBlue; public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.DarkCyan; public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.DarkGoldenrod; - public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) - : base(beatmap, new ResourceStore(), null) + public CatchTestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) + : base(beatmap, hasColours) { if (hasColours) { - Configuration.AddComboColours(Colours); Configuration.CustomColours.Add(CatchSkinColour.HyperDash.ToString(), HYPER_DASH_COLOUR); Configuration.CustomColours.Add(CatchSkinColour.HyperDashAfterImage.ToString(), HYPER_DASH_AFTER_IMAGE_COLOUR); Configuration.CustomColours.Add(CatchSkinColour.HyperDashFruit.ToString(), HYPER_DASH_FRUIT_COLOUR); @@ -324,37 +246,24 @@ namespace osu.Game.Rulesets.Catch.Tests } } - private class TestSkin : LegacySkin, ISkinSource + private class CatchTestSkin : TestSkin { - public static Color4[] Colours { get; } = - { - new Color4(150, 100, 50, 255), - new Color4(20, 20, 20, 255), - }; - public static readonly Color4 HYPER_DASH_COLOUR = Color4.LightBlue; public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.LightCoral; public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.LightCyan; - public TestSkin(bool hasCustomColours) - : base(new SkinInfo(), new ResourceStore(), null, string.Empty) + public CatchTestSkin(bool hasCustomColours) + : base(hasCustomColours) { if (hasCustomColours) { - Configuration.AddComboColours(Colours); Configuration.CustomColours.Add(CatchSkinColour.HyperDash.ToString(), HYPER_DASH_COLOUR); Configuration.CustomColours.Add(CatchSkinColour.HyperDashAfterImage.ToString(), HYPER_DASH_AFTER_IMAGE_COLOUR); Configuration.CustomColours.Add(CatchSkinColour.HyperDashFruit.ToString(), HYPER_DASH_FRUIT_COLOUR); } } - - public event Action SourceChanged - { - add { } - remove { } - } } } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 22b028906f..095ce63ec5 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -1,168 +1,113 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Bindables; -using osu.Framework.IO.Stores; -using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Screens.Play; using osu.Game.Skinning; -using osu.Game.Tests.Visual; +using osu.Game.Tests.Beatmaps; using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneLegacyBeatmapSkin : ScreenTestScene + public class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest { [Resolved] private AudioManager audio { get; set; } - private readonly Bindable beatmapSkins = new Bindable(); - private readonly Bindable beatmapColours = new Bindable(); - [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.BeatmapSkins, beatmapSkins); - config.BindWith(OsuSetting.BeatmapColours, beatmapColours); + config.BindWith(OsuSetting.BeatmapSkins, BeatmapSkins); + config.BindWith(OsuSetting.BeatmapColours, BeatmapColours); } [TestCase(true, true)] [TestCase(true, false)] [TestCase(false, true)] [TestCase(false, false)] - public void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin) + public override void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, true); - AddStep("load coloured beatmap", () => player = loadBeatmap(userHasCustomColours, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is beatmap skin colours", () => player.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours)); + TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, true); + base.TestBeatmapComboColours(userHasCustomColours, useBeatmapSkin); + AddAssert("is beatmap skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours)); } [TestCase(true)] [TestCase(false)] - public void TestBeatmapComboColoursOverride(bool useBeatmapSkin) + public override void TestBeatmapComboColoursOverride(bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, false); - AddStep("load coloured beatmap", () => player = loadBeatmap(true, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is user custom skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); + TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, true); + base.TestBeatmapComboColoursOverride(useBeatmapSkin); + AddAssert("is user custom skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours)); } [TestCase(true)] [TestCase(false)] - public void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin) + public override void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, false); - AddStep("load coloured beatmap", () => player = loadBeatmap(false, true)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); + TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, true); + base.TestBeatmapComboColoursOverrideWithDefaultColours(useBeatmapSkin); + AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); } [TestCase(true, true)] [TestCase(false, true)] [TestCase(true, false)] [TestCase(false, false)] - public void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour) + public override void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, useBeatmapColour); - AddStep("load no-colour beatmap", () => player = loadBeatmap(false, false)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); + TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, false); + base.TestBeatmapNoComboColours(useBeatmapSkin, useBeatmapColour); + AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours)); } [TestCase(true, true)] [TestCase(false, true)] [TestCase(true, false)] [TestCase(false, false)] - public void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour) + public override void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour) { - ExposedPlayer player = null; - - configureSettings(useBeatmapSkin, useBeatmapColour); - AddStep("load custom-skin colour", () => player = loadBeatmap(true, false)); - AddUntilStep("wait for player", () => player.IsLoaded); - - AddAssert("is custom user skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours)); + TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, false); + base.TestBeatmapNoComboColoursSkinOverride(useBeatmapSkin, useBeatmapColour); + AddAssert("is custom user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours)); } - private ExposedPlayer loadBeatmap(bool userHasCustomColours, bool beatmapHasColours) + protected override ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new OsuExposedPlayer(userHasCustomColours); + + private class OsuExposedPlayer : ExposedPlayer { - ExposedPlayer player; - - Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours); - - LoadScreen(player = new ExposedPlayer(userHasCustomColours)); - - return player; - } - - private void configureSettings(bool beatmapSkins, bool beatmapColours) - { - AddStep($"{(beatmapSkins ? "enable" : "disable")} beatmap skins", () => + public OsuExposedPlayer(bool userHasCustomColours) + : base(userHasCustomColours) { - this.beatmapSkins.Value = beatmapSkins; - }); - AddStep($"{(beatmapColours ? "enable" : "disable")} beatmap colours", () => - { - this.beatmapColours.Value = beatmapColours; - }); - } - - private class ExposedPlayer : Player - { - private readonly bool userHasCustomColours; - - public ExposedPlayer(bool userHasCustomColours) - : base(new PlayerConfiguration - { - AllowPause = false, - ShowResults = false, - }) - { - this.userHasCustomColours = userHasCustomColours; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(new TestSkin(userHasCustomColours)); + dependencies.CacheAs(new OsuTestSkin(UserHasCustomColours)); return dependencies; } - - public IReadOnlyList UsableComboColours => - GameplayClockContainer.ChildrenOfType() - .First() - .GetConfig>(GlobalSkinColours.ComboColours)?.Value; } - private class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap + private class OsuCustomSkinWorkingBeatmap : CustomSkinWorkingBeatmap { private readonly bool hasColours; - public CustomSkinWorkingBeatmap(AudioManager audio, bool hasColours) - : base(new Beatmap + public OsuCustomSkinWorkingBeatmap(AudioManager audio, bool hasColours) + : base(createBeatmap(), audio, hasColours) + { + this.hasColours = hasColours; + } + + protected override ISkin GetSkin() => new OsuTestBeatmapSkin(BeatmapInfo, hasColours); + + private static IBeatmap createBeatmap() => + new Beatmap { BeatmapInfo = { @@ -170,49 +115,22 @@ namespace osu.Game.Rulesets.Osu.Tests Ruleset = new OsuRuleset().RulesetInfo, }, HitObjects = { new HitCircle { Position = new Vector2(256, 192) } } - }, null, null, audio) - { - this.hasColours = hasColours; - } - - protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours); + }; } - private class TestBeatmapSkin : LegacyBeatmapSkin + private class OsuTestBeatmapSkin : TestBeatmapSkin { - public static Color4[] Colours { get; } = + public OsuTestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) + : base(beatmap, hasColours) { - new Color4(50, 100, 150, 255), - new Color4(40, 80, 120, 255), - }; - - public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) - : base(beatmap, new ResourceStore(), null) - { - if (hasColours) - Configuration.AddComboColours(Colours); } } - private class TestSkin : LegacySkin, ISkinSource + private class OsuTestSkin : TestSkin { - public static Color4[] Colours { get; } = + public OsuTestSkin(bool hasCustomColours) + : base(hasCustomColours) { - new Color4(150, 100, 50, 255), - new Color4(20, 20, 20, 255), - }; - - public TestSkin(bool hasCustomColours) - : base(new SkinInfo(), null, null, string.Empty) - { - if (hasCustomColours) - Configuration.AddComboColours(Colours); - } - - public event Action SourceChanged - { - add { } - remove { } } } } diff --git a/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs b/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs new file mode 100644 index 0000000000..b42c3ea70d --- /dev/null +++ b/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs @@ -0,0 +1,147 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Bindables; +using osu.Framework.IO.Stores; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Screens.Play; +using osu.Game.Skinning; +using osu.Game.Tests.Visual; +using osuTK.Graphics; + +namespace osu.Game.Tests.Beatmaps +{ + public class LegacyBeatmapSkinColourTest : ScreenTestScene + { + protected readonly Bindable BeatmapSkins = new Bindable(); + protected readonly Bindable BeatmapColours = new Bindable(); + protected ExposedPlayer TestPlayer; + protected WorkingBeatmap TestBeatmap; + + public virtual void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin) => ConfigureTest(useBeatmapSkin, true, userHasCustomColours); + + public virtual void TestBeatmapComboColoursOverride(bool useBeatmapSkin) => ConfigureTest(useBeatmapSkin, false, true); + + public virtual void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin) => ConfigureTest(useBeatmapSkin, false, false); + + public virtual void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour) => ConfigureTest(useBeatmapSkin, useBeatmapColour, false); + + public virtual void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour) => ConfigureTest(useBeatmapSkin, useBeatmapColour, true); + + protected virtual void ConfigureTest(bool useBeatmapSkin, bool useBeatmapColours, bool userHasCustomColours) + { + configureSettings(useBeatmapSkin, useBeatmapColours); + AddStep($"load {(((CustomSkinWorkingBeatmap)TestBeatmap).HasColours ? "coloured " : "")} beatmap", () => TestPlayer = LoadBeatmap(userHasCustomColours)); + AddUntilStep("wait for player load", () => TestPlayer.IsLoaded); + } + + private void configureSettings(bool beatmapSkins, bool beatmapColours) + { + AddStep($"{(beatmapSkins ? "enable" : "disable")} beatmap skins", () => + { + BeatmapSkins.Value = beatmapSkins; + }); + AddStep($"{(beatmapColours ? "enable" : "disable")} beatmap colours", () => + { + BeatmapColours.Value = beatmapColours; + }); + } + + protected virtual ExposedPlayer LoadBeatmap(bool userHasCustomColours) + { + ExposedPlayer player; + + Beatmap.Value = TestBeatmap; + + LoadScreen(player = CreateTestPlayer(userHasCustomColours)); + + return player; + } + + protected virtual ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new ExposedPlayer(userHasCustomColours); + + protected class ExposedPlayer : Player + { + protected readonly bool UserHasCustomColours; + + public ExposedPlayer(bool userHasCustomColours) + : base(new PlayerConfiguration + { + AllowPause = false, + ShowResults = false, + }) + { + UserHasCustomColours = userHasCustomColours; + } + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + dependencies.CacheAs(new TestSkin(UserHasCustomColours)); + return dependencies; + } + + public IReadOnlyList UsableComboColours => + GameplayClockContainer.ChildrenOfType() + .First() + .GetConfig>(GlobalSkinColours.ComboColours)?.Value; + } + + protected class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap + { + public readonly bool HasColours; + + public CustomSkinWorkingBeatmap(IBeatmap beatmap, AudioManager audio, bool hasColours) + : base(beatmap, null, null, audio) + { + HasColours = hasColours; + } + + protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, HasColours); + } + + protected class TestBeatmapSkin : LegacyBeatmapSkin + { + public static Color4[] Colours { get; } = + { + new Color4(50, 100, 150, 255), + new Color4(40, 80, 120, 255), + }; + + public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) + : base(beatmap, new ResourceStore(), null) + { + if (hasColours) + Configuration.AddComboColours(Colours); + } + } + + protected class TestSkin : LegacySkin, ISkinSource + { + public static Color4[] Colours { get; } = + { + new Color4(150, 100, 50, 255), + new Color4(20, 20, 20, 255), + }; + + public TestSkin(bool hasCustomColours) + : base(new SkinInfo(), new ResourceStore(), null, string.Empty) + { + if (hasCustomColours) + Configuration.AddComboColours(Colours); + } + + public event Action SourceChanged + { + add { } + remove { } + } + } + } +} From a3535f4b79a3634e31fe9fd935545b653558787f Mon Sep 17 00:00:00 2001 From: Mysfit Date: Sat, 16 Jan 2021 02:09:35 -0500 Subject: [PATCH 063/113] Further simplified beatmap colouring tests. --- .../TestSceneLegacyBeatmapSkin.cs | 144 ++---------------- .../TestSceneLegacyBeatmapSkin.cs | 38 ----- .../Beatmaps/LegacyBeatmapSkinColourTest.cs | 22 +++ 3 files changed, 35 insertions(+), 169 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs index 89298242e5..eea83ef7c1 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs @@ -1,22 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Testing; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Configuration; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Skinning; -using osu.Game.Rulesets.Catch.UI; -using osu.Game.Rulesets.Objects; using osu.Game.Skinning; using osu.Game.Tests.Beatmaps; -using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests @@ -90,9 +85,9 @@ namespace osu.Game.Rulesets.Catch.Tests { TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true); ConfigureTest(useBeatmapSkin, true, true); - AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == CatchTestBeatmapSkin.HYPER_DASH_COLOUR); - AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == CatchTestBeatmapSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); - AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == CatchTestBeatmapSkin.HYPER_DASH_FRUIT_COLOUR); + AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == TestBeatmapSkin.HYPER_DASH_COLOUR); + AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == TestBeatmapSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); + AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == TestBeatmapSkin.HYPER_DASH_FRUIT_COLOUR); } [TestCase(true)] @@ -101,9 +96,9 @@ namespace osu.Game.Rulesets.Catch.Tests { TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true); ConfigureTest(useBeatmapSkin, false, true); - AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == CatchTestSkin.HYPER_DASH_COLOUR); - AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == CatchTestSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); - AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == CatchTestSkin.HYPER_DASH_FRUIT_COLOUR); + AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == TestSkin.HYPER_DASH_COLOUR); + AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == TestSkin.HYPER_DASH_AFTER_IMAGE_COLOUR); + AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == TestSkin.HYPER_DASH_FRUIT_COLOUR); } protected override ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new CatchExposedPlayer(userHasCustomColours); @@ -115,13 +110,6 @@ namespace osu.Game.Rulesets.Catch.Tests { } - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(new CatchTestSkin(UserHasCustomColours)); - return dependencies; - } - public Color4 UsableHyperDashColour => GameplayClockContainer.ChildrenOfType() .First() @@ -141,129 +129,23 @@ namespace osu.Game.Rulesets.Catch.Tests .Value ?? Color4.Red; } - private class TestJuiceStream : JuiceStream - { - public TestJuiceStream(float x) - { - X = x; - - Path = new SliderPath(new[] - { - new PathControlPoint(Vector2.Zero), - new PathControlPoint(new Vector2(30, 0)), - }); - } - } - private class CatchCustomSkinWorkingBeatmap : CustomSkinWorkingBeatmap { public CatchCustomSkinWorkingBeatmap(AudioManager audio, bool hasColours) - : base(createBeatmap(new CatchRuleset().RulesetInfo), audio, hasColours) + : base(createBeatmap(), audio, hasColours) { } - protected override ISkin GetSkin() => new CatchTestBeatmapSkin(BeatmapInfo, HasColours); - - private static IBeatmap createBeatmap(RulesetInfo ruleset) - { - var beatmap = new Beatmap + private static IBeatmap createBeatmap() => + new Beatmap { BeatmapInfo = { - Ruleset = ruleset, - BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f } - } + BeatmapSet = new BeatmapSetInfo(), + Ruleset = new CatchRuleset().RulesetInfo + }, + HitObjects = { new Fruit { StartTime = 1816, X = 56, NewCombo = true } } }; - - beatmap.ControlPointInfo.Add(0, new TimingControlPoint()); - - // Should produce a hyper-dash (edge case test) - beatmap.HitObjects.Add(new Fruit { StartTime = 1816, X = 56, NewCombo = true }); - beatmap.HitObjects.Add(new Fruit { StartTime = 2008, X = 308, NewCombo = true }); - - double startTime = 3000; - - const float left_x = 0.02f * CatchPlayfield.WIDTH; - const float right_x = 0.98f * CatchPlayfield.WIDTH; - - createObjects(() => new Fruit { X = left_x }); - createObjects(() => new TestJuiceStream(right_x), 1); - createObjects(() => new TestJuiceStream(left_x), 1); - createObjects(() => new Fruit { X = right_x }); - createObjects(() => new Fruit { X = left_x }); - createObjects(() => new Fruit { X = right_x }); - createObjects(() => new TestJuiceStream(left_x), 1); - - beatmap.ControlPointInfo.Add(startTime, new TimingControlPoint - { - BeatLength = 50 - }); - - createObjects(() => new TestJuiceStream(left_x) - { - Path = new SliderPath(new[] - { - new PathControlPoint(Vector2.Zero), - new PathControlPoint(new Vector2(512, 0)) - }) - }, 1); - - return beatmap; - - void createObjects(Func createObject, int count = 3) - { - const float spacing = 140; - - for (int i = 0; i < count; i++) - { - var hitObject = createObject(); - hitObject.StartTime = startTime + i * spacing; - beatmap.HitObjects.Add(hitObject); - } - - startTime += 700; - } - } - } - - private class CatchTestBeatmapSkin : TestBeatmapSkin - { - public static readonly Color4 HYPER_DASH_COLOUR = Color4.DarkBlue; - - public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.DarkCyan; - - public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.DarkGoldenrod; - - public CatchTestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) - : base(beatmap, hasColours) - { - if (hasColours) - { - Configuration.CustomColours.Add(CatchSkinColour.HyperDash.ToString(), HYPER_DASH_COLOUR); - Configuration.CustomColours.Add(CatchSkinColour.HyperDashAfterImage.ToString(), HYPER_DASH_AFTER_IMAGE_COLOUR); - Configuration.CustomColours.Add(CatchSkinColour.HyperDashFruit.ToString(), HYPER_DASH_FRUIT_COLOUR); - } - } - } - - private class CatchTestSkin : TestSkin - { - public static readonly Color4 HYPER_DASH_COLOUR = Color4.LightBlue; - - public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.LightCoral; - - public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.LightCyan; - - public CatchTestSkin(bool hasCustomColours) - : base(hasCustomColours) - { - if (hasCustomColours) - { - Configuration.CustomColours.Add(CatchSkinColour.HyperDash.ToString(), HYPER_DASH_COLOUR); - Configuration.CustomColours.Add(CatchSkinColour.HyperDashAfterImage.ToString(), HYPER_DASH_AFTER_IMAGE_COLOUR); - Configuration.CustomColours.Add(CatchSkinColour.HyperDashFruit.ToString(), HYPER_DASH_FRUIT_COLOUR); - } - } } } } diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 095ce63ec5..c26419b0e8 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -77,35 +77,13 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("is custom user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours)); } - protected override ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new OsuExposedPlayer(userHasCustomColours); - - private class OsuExposedPlayer : ExposedPlayer - { - public OsuExposedPlayer(bool userHasCustomColours) - : base(userHasCustomColours) - { - } - - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(new OsuTestSkin(UserHasCustomColours)); - return dependencies; - } - } - private class OsuCustomSkinWorkingBeatmap : CustomSkinWorkingBeatmap { - private readonly bool hasColours; - public OsuCustomSkinWorkingBeatmap(AudioManager audio, bool hasColours) : base(createBeatmap(), audio, hasColours) { - this.hasColours = hasColours; } - protected override ISkin GetSkin() => new OsuTestBeatmapSkin(BeatmapInfo, hasColours); - private static IBeatmap createBeatmap() => new Beatmap { @@ -117,21 +95,5 @@ namespace osu.Game.Rulesets.Osu.Tests HitObjects = { new HitCircle { Position = new Vector2(256, 192) } } }; } - - private class OsuTestBeatmapSkin : TestBeatmapSkin - { - public OsuTestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) - : base(beatmap, hasColours) - { - } - } - - private class OsuTestSkin : TestSkin - { - public OsuTestSkin(bool hasCustomColours) - : base(hasCustomColours) - { - } - } } } diff --git a/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs b/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs index b42c3ea70d..fb3432fbae 100644 --- a/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs +++ b/osu.Game/Tests/Beatmaps/LegacyBeatmapSkinColourTest.cs @@ -114,11 +114,22 @@ namespace osu.Game.Tests.Beatmaps new Color4(40, 80, 120, 255), }; + public static readonly Color4 HYPER_DASH_COLOUR = Color4.DarkBlue; + + public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.DarkCyan; + + public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.DarkGoldenrod; + public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours) : base(beatmap, new ResourceStore(), null) { if (hasColours) + { Configuration.AddComboColours(Colours); + Configuration.CustomColours.Add("HyperDash", HYPER_DASH_COLOUR); + Configuration.CustomColours.Add("HyperDashAfterImage", HYPER_DASH_AFTER_IMAGE_COLOUR); + Configuration.CustomColours.Add("HyperDashFruit", HYPER_DASH_FRUIT_COLOUR); + } } } @@ -130,11 +141,22 @@ namespace osu.Game.Tests.Beatmaps new Color4(20, 20, 20, 255), }; + public static readonly Color4 HYPER_DASH_COLOUR = Color4.LightBlue; + + public static readonly Color4 HYPER_DASH_AFTER_IMAGE_COLOUR = Color4.LightCoral; + + public static readonly Color4 HYPER_DASH_FRUIT_COLOUR = Color4.LightCyan; + public TestSkin(bool hasCustomColours) : base(new SkinInfo(), new ResourceStore(), null, string.Empty) { if (hasCustomColours) + { Configuration.AddComboColours(Colours); + Configuration.CustomColours.Add("HyperDash", HYPER_DASH_COLOUR); + Configuration.CustomColours.Add("HyperDashAfterImage", HYPER_DASH_AFTER_IMAGE_COLOUR); + Configuration.CustomColours.Add("HyperDashFruit", HYPER_DASH_FRUIT_COLOUR); + } } public event Action SourceChanged From bb0d2899931bbefedf3229d2b963a5d368fc6177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 16 Jan 2021 23:24:28 +0100 Subject: [PATCH 064/113] Split variable for readability --- osu.Game/OsuGameBase.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index d3273ba170..716796a585 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -426,7 +426,8 @@ namespace osu.Game { var imports = tasks.Where(t => t.Path.EndsWith(ext, StringComparison.OrdinalIgnoreCase)); - return fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(ext))?.Import(imports.ToArray()) ?? Task.CompletedTask; + var importer = fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(ext)); + return importer?.Import(imports.ToArray()) ?? Task.CompletedTask; })); } From dee46d7ba201e70c463f68f5b4cf38c43a87d085 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 16 Jan 2021 23:42:28 +0100 Subject: [PATCH 065/113] Use GroupBy() instead --- osu.Game/OsuGameBase.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 716796a585..1f8ae54e55 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -421,13 +421,11 @@ namespace osu.Game public virtual async Task Import(params ImportTask[] tasks) { - var extensions = tasks.Select(t => Path.GetExtension(t.Path).ToLowerInvariant()).Distinct(); - await Task.WhenAll(extensions.Select(ext => + var tasksPerExtension = tasks.GroupBy(t => Path.GetExtension(t.Path).ToLowerInvariant()); + await Task.WhenAll(tasksPerExtension.Select(taskGroup => { - var imports = tasks.Where(t => t.Path.EndsWith(ext, StringComparison.OrdinalIgnoreCase)); - - var importer = fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(ext)); - return importer?.Import(imports.ToArray()) ?? Task.CompletedTask; + var importer = fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(taskGroup.Key)); + return importer?.Import(taskGroup.ToArray()) ?? Task.CompletedTask; })); } From 816cc7a59b146cff51773d9f3ec862e0d61af7ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 17 Jan 2021 00:35:23 +0100 Subject: [PATCH 066/113] Adjust explicit label spacing on beatmap set overlay --- osu.Game/Overlays/BeatmapSet/Header.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 9f2b40dfa4..a84ed5ac29 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -145,14 +145,14 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 3, Bottom = 4 }, // To better lineup with the font + Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font }, explicitPill = new ExplicitBeatmapPill { Alpha = 0f, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 15f, Top = 4 }, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10, Bottom = 4 }, } } }, From eb53e32792dcb36c1aac9d612dc24f09733487dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 17 Jan 2021 14:40:22 +0100 Subject: [PATCH 067/113] Use task completion source for room join flow On Android, users were unable to join or create multiplayer rooms. The root cause of that was that the both the wait and set of the `ManualResetEvent` in `getRoomUsers` occurred on the same thread, which created a chicken-and-egg situation - the set could not proceed until the wait had actually completed. Resolve by substituting the `ManualResetEvent` for a `TaskCompletionSource` to achieve a promise-style task, which the previous code was a crude approximation of anyway. Closes #11385. --- .../Multiplayer/StatefulMultiplayerClient.cs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs b/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs index fbdfb6a8c5..f0e11b2b8b 100644 --- a/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs +++ b/osu.Game/Online/Multiplayer/StatefulMultiplayerClient.cs @@ -7,7 +7,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using System.Threading; using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -128,7 +127,8 @@ namespace osu.Game.Online.Multiplayer Debug.Assert(Room != null); - var users = getRoomUsers(); + var users = await getRoomUsers(); + Debug.Assert(users != null); await Task.WhenAll(users.Select(PopulateUser)); @@ -437,24 +437,20 @@ namespace osu.Game.Online.Multiplayer /// This should be used whenever accessing users from outside of an Update thread context (ie. when not calling ). /// /// A copy of users in the current room, or null if unavailable. - private List? getRoomUsers() + private Task?> getRoomUsers() { - List? users = null; - - ManualResetEventSlim resetEvent = new ManualResetEventSlim(); + var tcs = new TaskCompletionSource?>(); // at some point we probably want to replace all these schedule calls with Room.LockForUpdate. // for now, as this would require quite some consideration due to the number of accesses to the room instance, // let's just add a manual schedule for the non-scheduled usages instead. Scheduler.Add(() => { - users = Room?.Users.ToList(); - resetEvent.Set(); + var users = Room?.Users.ToList(); + tcs.SetResult(users); }, false); - resetEvent.Wait(100); - - return users; + return tcs.Task; } /// From 5fd644fc576de33cab2f4b0daeb323b262b3b98e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 17 Jan 2021 22:40:24 +0900 Subject: [PATCH 068/113] Unify variable names --- .../TestSceneBeatmapListingSearchControl.cs | 10 +++++----- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- .../Online/API/Requests/SearchBeatmapSetsRequest.cs | 8 ++++---- .../BeatmapListing/BeatmapListingFilterControl.cs | 4 ++-- .../BeatmapListing/BeatmapListingSearchControl.cs | 10 +++++----- .../Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs | 2 +- .../Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs | 2 +- ...citBeatmapPill.cs => ExplicitContentBeatmapPill.cs} | 4 ++-- osu.Game/Overlays/BeatmapSet/Header.cs | 6 +++--- .../Overlays/Settings/Sections/Online/WebSettings.cs | 2 +- .../Screens/OnlinePlay/DrawableRoomPlaylistItem.cs | 6 +++--- 11 files changed, 29 insertions(+), 29 deletions(-) rename osu.Game/Overlays/BeatmapSet/{ExplicitBeatmapPill.cs => ExplicitContentBeatmapPill.cs} (92%) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs index dc46da6293..a9747e73f9 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchControl.cs @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Visual.UserInterface control.Extra.BindCollectionChanged((u, v) => extra.Text = $"Extra: {(control.Extra.Any() ? string.Join('.', control.Extra.Select(i => i.ToString().ToLowerInvariant())) : "")}", true); control.Ranks.BindCollectionChanged((u, v) => ranks.Text = $"Ranks: {(control.Ranks.Any() ? string.Join('.', control.Ranks.Select(i => i.ToString())) : "")}", true); control.Played.BindValueChanged(p => played.Text = $"Played: {p.NewValue}", true); - control.Explicit.BindValueChanged(e => explicitMap.Text = $"Explicit Maps: {e.NewValue}", true); + control.ExplicitContent.BindValueChanged(e => explicitMap.Text = $"Explicit Maps: {e.NewValue}", true); }); [Test] @@ -92,11 +92,11 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestExplicitConfig() { - AddStep("configure explicit content to allowed", () => localConfig.Set(OsuSetting.AllowExplicitContent, true)); - AddAssert("explicit control set to show", () => control.Explicit.Value == SearchExplicit.Show); + AddStep("configure explicit content to allowed", () => localConfig.Set(OsuSetting.ShowOnlineExplicitContent, true)); + AddAssert("explicit control set to show", () => control.ExplicitContent.Value == SearchExplicit.Show); - AddStep("configure explicit content to disallowed", () => localConfig.Set(OsuSetting.AllowExplicitContent, false)); - AddAssert("explicit control set to hide", () => control.Explicit.Value == SearchExplicit.Hide); + AddStep("configure explicit content to disallowed", () => localConfig.Set(OsuSetting.ShowOnlineExplicitContent, false)); + AddAssert("explicit control set to hide", () => control.ExplicitContent.Value == SearchExplicit.Hide); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 5e7a843baf..6b48501dac 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -60,7 +60,7 @@ namespace osu.Game.Configuration Set(OsuSetting.ExternalLinkWarning, true); Set(OsuSetting.PreferNoVideo, false); - Set(OsuSetting.AllowExplicitContent, false); + Set(OsuSetting.ShowOnlineExplicitContent, false); // Audio Set(OsuSetting.VolumeInactive, 0.25, 0, 1, 0.01); @@ -272,6 +272,6 @@ namespace osu.Game.Configuration EditorWaveformOpacity, DiscordRichPresence, AutomaticallyDownloadWhenSpectating, - AllowExplicitContent, + ShowOnlineExplicitContent, } } diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index 939d3c6cb4..5360d36f3d 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -30,7 +30,7 @@ namespace osu.Game.Online.API.Requests public SearchPlayed Played { get; } - public SearchExplicit Explicit { get; } + public SearchExplicit ExplicitContent { get; } [CanBeNull] public IReadOnlyCollection Ranks { get; } @@ -53,7 +53,7 @@ namespace osu.Game.Online.API.Requests IReadOnlyCollection extra = null, IReadOnlyCollection ranks = null, SearchPlayed played = SearchPlayed.Any, - SearchExplicit explicitMaps = SearchExplicit.Hide) + SearchExplicit explicitContent = SearchExplicit.Hide) { this.query = string.IsNullOrEmpty(query) ? string.Empty : System.Uri.EscapeDataString(query); this.ruleset = ruleset; @@ -67,7 +67,7 @@ namespace osu.Game.Online.API.Requests Extra = extra; Ranks = ranks; Played = played; - Explicit = explicitMaps; + ExplicitContent = explicitContent; } protected override WebRequest CreateWebRequest() @@ -97,7 +97,7 @@ namespace osu.Game.Online.API.Requests if (Played != SearchPlayed.Any) req.AddParameter("played", Played.ToString().ToLowerInvariant()); - req.AddParameter("nsfw", Explicit == SearchExplicit.Show ? "true" : "false"); + req.AddParameter("nsfw", ExplicitContent == SearchExplicit.Show ? "true" : "false"); req.AddCursor(cursor); diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs index 650adcb4a9..bcc5a91677 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingFilterControl.cs @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.BeatmapListing searchControl.Extra.CollectionChanged += (_, __) => queueUpdateSearch(); searchControl.Ranks.CollectionChanged += (_, __) => queueUpdateSearch(); searchControl.Played.BindValueChanged(_ => queueUpdateSearch()); - searchControl.Explicit.BindValueChanged(_ => queueUpdateSearch()); + searchControl.ExplicitContent.BindValueChanged(_ => queueUpdateSearch()); sortCriteria.BindValueChanged(_ => queueUpdateSearch()); sortDirection.BindValueChanged(_ => queueUpdateSearch()); @@ -195,7 +195,7 @@ namespace osu.Game.Overlays.BeatmapListing searchControl.Extra, searchControl.Ranks, searchControl.Played.Value, - searchControl.Explicit.Value); + searchControl.ExplicitContent.Value); getSetsRequest.Success += response => { diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs index 5c6267b726..b138a5ac52 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchControl.cs @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.BeatmapListing public Bindable Played => playedFilter.Current; - public Bindable Explicit => explicitFilter.Current; + public Bindable ExplicitContent => explicitContentFilter.Current; public BeatmapSetInfo BeatmapSet { @@ -68,7 +68,7 @@ namespace osu.Game.Overlays.BeatmapListing private readonly BeatmapSearchMultipleSelectionFilterRow extraFilter; private readonly BeatmapSearchScoreFilterRow ranksFilter; private readonly BeatmapSearchFilterRow playedFilter; - private readonly BeatmapSearchFilterRow explicitFilter; + private readonly BeatmapSearchFilterRow explicitContentFilter; private readonly Box background; private readonly UpdateableBeatmapSetCover beatmapCover; @@ -130,7 +130,7 @@ namespace osu.Game.Overlays.BeatmapListing extraFilter = new BeatmapSearchMultipleSelectionFilterRow(@"Extra"), ranksFilter = new BeatmapSearchScoreFilterRow(), playedFilter = new BeatmapSearchFilterRow(@"Played"), - explicitFilter = new BeatmapSearchFilterRow(@"Explicit Maps"), + explicitContentFilter = new BeatmapSearchFilterRow(@"Explicit Content"), } } } @@ -148,10 +148,10 @@ namespace osu.Game.Overlays.BeatmapListing { background.Colour = colourProvider.Dark6; - allowExplicitContent = config.GetBindable(OsuSetting.AllowExplicitContent); + allowExplicitContent = config.GetBindable(OsuSetting.ShowOnlineExplicitContent); allowExplicitContent.BindValueChanged(allow => { - Explicit.Value = allow.NewValue ? SearchExplicit.Show : SearchExplicit.Hide; + ExplicitContent.Value = allow.NewValue ? SearchExplicit.Show : SearchExplicit.Hide; }, true); } diff --git a/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs b/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs index b7002a96e5..c1d366bb82 100644 --- a/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs +++ b/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs @@ -205,7 +205,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels if (SetInfo.OnlineInfo?.HasExplicitContent ?? false) { - titleContainer.Add(new ExplicitBeatmapPill + titleContainer.Add(new ExplicitContentBeatmapPill { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs b/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs index 69671ab75b..76a30d1c11 100644 --- a/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs +++ b/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs @@ -219,7 +219,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels if (SetInfo.OnlineInfo?.HasExplicitContent ?? false) { - titleContainer.Add(new ExplicitBeatmapPill + titleContainer.Add(new ExplicitContentBeatmapPill { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs b/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs similarity index 92% rename from osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs rename to osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs index aefb3299a5..329f8ee0a2 100644 --- a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs +++ b/osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs @@ -10,9 +10,9 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.BeatmapSet { - public class ExplicitBeatmapPill : CompositeDrawable + public class ExplicitContentBeatmapPill : CompositeDrawable { - public ExplicitBeatmapPill() + public ExplicitContentBeatmapPill() { AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 876a7e8917..916c21c010 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Box coverGradient; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; - private readonly ExplicitBeatmapPill explicitPill; + private readonly ExplicitContentBeatmapPill explicitContentPill; private readonly FillFlowContainer downloadButtonsContainer; private readonly BeatmapAvailability beatmapAvailability; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; @@ -147,7 +147,7 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.BottomLeft, Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font }, - explicitPill = new ExplicitBeatmapPill + explicitContentPill = new ExplicitContentBeatmapPill { Alpha = 0f, Anchor = Anchor.BottomLeft, @@ -261,7 +261,7 @@ namespace osu.Game.Overlays.BeatmapSet title.Text = setInfo.NewValue.Metadata.Title ?? string.Empty; artist.Text = setInfo.NewValue.Metadata.Artist ?? string.Empty; - explicitPill.Alpha = setInfo.NewValue.OnlineInfo.HasExplicitContent ? 1 : 0; + explicitContentPill.Alpha = setInfo.NewValue.OnlineInfo.HasExplicitContent ? 1 : 0; onlineStatusPill.FadeIn(500, Easing.OutQuint); onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status; diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index da7ef46f65..3e1cc1d91e 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Settings.Sections.Online { LabelText = "Hide warnings for explicit content in beatmaps", Keywords = new[] { "nsfw", "18+", "offensive" }, - Current = config.GetBindable(OsuSetting.AllowExplicitContent), + Current = config.GetBindable(OsuSetting.ShowOnlineExplicitContent), } }; } diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs index 7987d715e3..b16f82fce9 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.OnlinePlay private Container difficultyIconContainer; private LinkFlowContainer beatmapText; private LinkFlowContainer authorText; - private ExplicitBeatmapPill explicitPill; + private ExplicitContentBeatmapPill explicitContentPill; private ModDisplay modDisplay; private readonly Bindable beatmap = new Bindable(); @@ -119,7 +119,7 @@ namespace osu.Game.Screens.OnlinePlay } bool hasExplicitContent = Item.Beatmap.Value.BeatmapSet.OnlineInfo?.HasExplicitContent == true; - explicitPill.Alpha = hasExplicitContent ? 1 : 0; + explicitContentPill.Alpha = hasExplicitContent ? 1 : 0; modDisplay.Current.Value = requiredMods.ToArray(); } @@ -181,7 +181,7 @@ namespace osu.Game.Screens.OnlinePlay Children = new Drawable[] { authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, - explicitPill = new ExplicitBeatmapPill + explicitContentPill = new ExplicitContentBeatmapPill { Alpha = 0f, Anchor = Anchor.CentreLeft, From 5278cad393aeb1d76f7603cda445fb67b2d46234 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 17 Jan 2021 22:40:58 +0900 Subject: [PATCH 069/113] Reword setting to make more sense --- osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index 3e1cc1d91e..59bcbe4d89 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Settings.Sections.Online }, new SettingsCheckbox { - LabelText = "Hide warnings for explicit content in beatmaps", + LabelText = "Show explicit content in search results", Keywords = new[] { "nsfw", "18+", "offensive" }, Current = config.GetBindable(OsuSetting.ShowOnlineExplicitContent), } From 39746cb3de8ad11221ff1766822f720918d49858 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 00:11:35 +0900 Subject: [PATCH 070/113] Test removing nuget restore from iOS/Android build scripts --- fastlane/Fastfile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 8c278604aa..18b5907e82 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -48,10 +48,6 @@ desc 'Deploy to play store' desc 'Compile the project' lane :build do |options| - nuget_restore( - project_path: 'osu.sln' - ) - souyuz( build_configuration: 'Release', solution_path: 'osu.sln', @@ -107,10 +103,6 @@ platform :ios do desc 'Compile the project' lane :build do - nuget_restore( - project_path: 'osu.sln' - ) - souyuz( platform: "ios", plist_path: "osu.iOS/Info.plist" From 585aa87c5389b16dc9c8d4c17c38365cb0100174 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 17 Jan 2021 19:17:14 +0300 Subject: [PATCH 071/113] Fix playlist item download button never shown back after hiding --- .../Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs | 8 +++++++- osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 17d85d1120..c6cfd3c64a 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -201,11 +201,17 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] - public void TestDownloadButtonHiddenInitiallyWhenBeatmapExists() + public void TestDownloadButtonHiddenWhenBeatmapExists() { createPlaylist(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo); AddAssert("download button hidden", () => !playlist.ChildrenOfType().Single().IsPresent); + + AddStep("delete beatmap set", () => manager.Delete(manager.QueryBeatmapSets(_ => true).Single())); + AddUntilStep("download button shown", () => playlist.ChildrenOfType().Single().IsPresent); + + AddStep("undelete beatmap set", () => manager.Undelete(manager.QueryBeatmapSets(_ => true).Single())); + AddUntilStep("download button hidden", () => !playlist.ChildrenOfType().Single().IsPresent); } [Test] diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs index b16f82fce9..f8982582d5 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs @@ -249,6 +249,8 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] private BeatmapManager beatmapManager { get; set; } + public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks; + public PlaylistDownloadButton(PlaylistItem playlistItem) : base(playlistItem.Beatmap.Value.BeatmapSet) { From 2b23c8eabd02a1c3743d7538bbecb9ae3d224333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 17 Jan 2021 18:08:58 +0100 Subject: [PATCH 072/113] Use alpha directly for checking visibility in test `IsPresent` is no longer synonymous with being visible, after applying the fix to the issue in question. --- .../Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index c6cfd3c64a..874c1694eb 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -205,13 +205,16 @@ namespace osu.Game.Tests.Visual.Multiplayer { createPlaylist(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo); - AddAssert("download button hidden", () => !playlist.ChildrenOfType().Single().IsPresent); + assertDownloadButtonVisible(false); AddStep("delete beatmap set", () => manager.Delete(manager.QueryBeatmapSets(_ => true).Single())); - AddUntilStep("download button shown", () => playlist.ChildrenOfType().Single().IsPresent); + assertDownloadButtonVisible(true); AddStep("undelete beatmap set", () => manager.Undelete(manager.QueryBeatmapSets(_ => true).Single())); - AddUntilStep("download button hidden", () => !playlist.ChildrenOfType().Single().IsPresent); + assertDownloadButtonVisible(false); + + void assertDownloadButtonVisible(bool visible) => AddUntilStep($"download button {(visible ? "shown" : "hidden")}", + () => playlist.ChildrenOfType().Single().Alpha == (visible ? 1 : 0)); } [Test] From ec00aaef90a9bfe8d768f01148f99a78d043401e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jan 2021 19:13:55 +0900 Subject: [PATCH 073/113] Add nuget deploys for all rulesets --- appveyor_deploy.yml | 73 +++++++++++++++---- .../osu.Game.Rulesets.Catch.csproj | 7 ++ .../osu.Game.Rulesets.Mania.csproj | 7 ++ .../osu.Game.Rulesets.Osu.csproj | 7 ++ .../osu.Game.Rulesets.Taiko.csproj | 7 ++ 5 files changed, 88 insertions(+), 13 deletions(-) diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml index bb4482f501..737e5c43ab 100644 --- a/appveyor_deploy.yml +++ b/appveyor_deploy.yml @@ -1,21 +1,68 @@ clone_depth: 1 version: '{build}' image: Visual Studio 2019 -dotnet_csproj: - patch: true - file: 'osu.Game\osu.Game.csproj' # Use wildcard when it's able to exclude Xamarin projects - version: $(APPVEYOR_REPO_TAG_NAME) -before_build: - - ps: dotnet --info # Useful when version mismatch between CI and local - - ps: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects test: off skip_non_tags: true configuration: Release -build: - project: build\Desktop.proj # Skipping Xamarin Release that's slow and covered by fastlane - parallel: true - verbosity: minimal - publish_nuget: true + +environment: + matrix: + - job_name: osu-game + - job_name: osu-ruleset + job_depends_on: osu-game + - job_name: taiko-ruleset + job_depends_on: osu-game + - job_name: catch-ruleset + job_depends_on: osu-game + - job_name: mania-ruleset + job_depends_on: osu-game + +nuget: + project_feed: true + +for: + - + matrix: + only: + - job_name: osu-game + build_script: + - cmd: dotnet pack osu.Game\osu.Game.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME% + - + matrix: + only: + - job_name: osu-ruleset + build_script: + - cmd: dotnet remove osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj reference osu.Game\osu.Game.csproj + - cmd: dotnet add osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME% + - cmd: dotnet pack osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME% + - + matrix: + only: + - job_name: taiko-ruleset + build_script: + - cmd: dotnet remove osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj reference osu.Game\osu.Game.csproj + - cmd: dotnet add osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME% + - cmd: dotnet pack osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME% + - + matrix: + only: + - job_name: catch-ruleset + build_script: + - cmd: dotnet remove osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj reference osu.Game\osu.Game.csproj + - cmd: dotnet add osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME% + - cmd: dotnet pack osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME% + - + matrix: + only: + - job_name: mania-ruleset + build_script: + - cmd: dotnet remove osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj reference osu.Game\osu.Game.csproj + - cmd: dotnet add osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME% + - cmd: dotnet pack osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME% + +artifacts: + - path: '**\*.nupkg' + deploy: - provider: Environment - name: nuget + name: nuget \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index b19affbf9f..5bdf39824c 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -5,6 +5,13 @@ true catch the fruit. to the beat. + + + osu!catch + ppy.osu.Game.Rulesets.Catch + true + + diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 07ef1022ae..c30fe8494f 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -5,6 +5,13 @@ true smash the keys. to the beat. + + + osu!mania + ppy.osu.Game.Rulesets.Mania + true + + diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index bffeaabb55..36ee804259 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -5,6 +5,13 @@ true click the circles. to the beat. + + + osu!standard + ppy.osu.Game.Rulesets.Osu + true + + diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index ebed8c6d7c..00deb719e1 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -5,6 +5,13 @@ true bash the drum. to the beat. + + + osu!taiko + ppy.osu.Game.Rulesets.Taiko + true + + From 1b166d809eb5bb5f04bdbcfabfba3916cd66a114 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jan 2021 11:07:54 +0900 Subject: [PATCH 074/113] Adjust package titles --- osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj | 2 +- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 2 +- osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj | 2 +- osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 5bdf39824c..e2f95ca177 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -7,7 +7,7 @@ - osu!catch + osu!catch (ruleset) ppy.osu.Game.Rulesets.Catch true diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index c30fe8494f..4f6840f9ca 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -7,7 +7,7 @@ - osu!mania + osu!mania (ruleset) ppy.osu.Game.Rulesets.Mania true diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 36ee804259..98f1e69bd1 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -7,7 +7,7 @@ - osu!standard + osu! (ruleset) ppy.osu.Game.Rulesets.Osu true diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 00deb719e1..b752c13d18 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -7,7 +7,7 @@ - osu!taiko + osu!taiko (ruleset) ppy.osu.Game.Rulesets.Taiko true From 94fee8c31d123b940ddf636cf6982152479cc7ed Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 16:13:58 +0900 Subject: [PATCH 075/113] Avoid doing a config lookup if initial conditional fails --- osu.Game/Skinning/SkinProvidingContainer.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Skinning/SkinProvidingContainer.cs b/osu.Game/Skinning/SkinProvidingContainer.cs index e97822b86e..27cf0c697a 100644 --- a/osu.Game/Skinning/SkinProvidingContainer.cs +++ b/osu.Game/Skinning/SkinProvidingContainer.cs @@ -74,8 +74,8 @@ namespace osu.Game.Skinning { if (lookup is GlobalSkinColours || lookup is SkinCustomColourLookup) return lookupWithFallback(lookup, AllowColourLookup); - else - return lookupWithFallback(lookup, AllowConfigurationLookup); + + return lookupWithFallback(lookup, AllowConfigurationLookup); } return fallbackSource?.GetConfig(lookup); @@ -83,11 +83,14 @@ namespace osu.Game.Skinning private IBindable lookupWithFallback(TLookup lookup, bool canUseSkinLookup) { - var bindable = skin.GetConfig(lookup); - if (bindable != null && canUseSkinLookup) - return bindable; - else - return fallbackSource?.GetConfig(lookup); + if (canUseSkinLookup) + { + var bindable = skin.GetConfig(lookup); + if (bindable != null) + return bindable; + } + + return fallbackSource?.GetConfig(lookup); } protected virtual void TriggerSourceChanged() => SourceChanged?.Invoke(); From 02d2b2742b66d1bf6b9899430d90580f69872db1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 16:57:36 +0900 Subject: [PATCH 076/113] Fix selection box not updating with hitcircles/sliders far in the future or past --- .../Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs | 2 +- .../Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs index 093bae854e..abbb54e3c1 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCircleSelectionBlueprint.cs @@ -30,6 +30,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.HitArea.ReceivePositionalInputAt(screenSpacePos); - public override Quad SelectionQuad => DrawableObject.HitArea.ScreenSpaceDrawQuad; + public override Quad SelectionQuad => CirclePiece.ScreenSpaceDrawQuad; } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index d592e129d9..3d3dff653a 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -44,6 +44,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders [Resolved(CanBeNull = true)] private IEditorChangeHandler changeHandler { get; set; } + public override Quad SelectionQuad => BodyPiece.ScreenSpaceDrawQuad; + private readonly BindableList controlPoints = new BindableList(); private readonly IBindable pathVersion = new Bindable(); From c79ab63743e14b4205e40f33d5ae4519dfbeb58e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 16:56:10 +0900 Subject: [PATCH 077/113] Fix sliders with an even number of repeats not allowing rotation/scale transforms --- osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index 660e1844aa..91bb665ee2 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -236,7 +236,18 @@ namespace osu.Game.Rulesets.Osu.Edit /// /// The hit objects to calculate a quad for. private Quad getSurroundingQuad(OsuHitObject[] hitObjects) => - getSurroundingQuad(hitObjects.SelectMany(h => new[] { h.Position, h.EndPosition })); + getSurroundingQuad(hitObjects.SelectMany(h => + { + if (h is IHasPath path) + return new[] + { + h.Position, + // can't use EndPosition for reverse slider cases. + h.Position + path.Path.PositionAt(1) + }; + + return new[] { h.Position }; + })); /// /// Returns a gamefield-space quad surrounding the provided points. From 2f1d4bf51b0964aded4fa5d31be592c7da3eb482 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 17:13:47 +0900 Subject: [PATCH 078/113] Add missing braces --- osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index 91bb665ee2..871339ae7b 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -239,12 +239,14 @@ namespace osu.Game.Rulesets.Osu.Edit getSurroundingQuad(hitObjects.SelectMany(h => { if (h is IHasPath path) + { return new[] { h.Position, // can't use EndPosition for reverse slider cases. h.Position + path.Path.PositionAt(1) }; + } return new[] { h.Position }; })); From 0b165dce4bbbb0647ccbdae48b8d2621173655f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 17:50:32 +0900 Subject: [PATCH 079/113] Fix multiplayer mod select showing autoplay as a choice --- osu.Game/OsuGameBase.cs | 1 + osu.Game/Overlays/Mods/ModSelectOverlay.cs | 7 +++++-- .../OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs | 5 +++++ osu.Game/Screens/Select/SongSelect.cs | 8 +++----- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 1f8ae54e55..20d88d33f2 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -327,6 +327,7 @@ namespace osu.Game if (!SelectedMods.Disabled) SelectedMods.Value = Array.Empty(); + AvailableMods.Value = dict; } diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 0c8245bebe..b93602116b 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -30,6 +30,7 @@ namespace osu.Game.Overlays.Mods { public class ModSelectOverlay : WaveOverlayContainer { + private readonly Func isValidMod; public const float HEIGHT = 510; protected readonly TriangleButton DeselectAllButton; @@ -60,8 +61,10 @@ namespace osu.Game.Overlays.Mods private SampleChannel sampleOn, sampleOff; - public ModSelectOverlay() + public ModSelectOverlay(Func isValidMod = null) { + this.isValidMod = isValidMod ?? (m => true); + Waves.FirstWaveColour = Color4Extensions.FromHex(@"19b0e2"); Waves.SecondWaveColour = Color4Extensions.FromHex(@"2280a2"); Waves.ThirdWaveColour = Color4Extensions.FromHex(@"005774"); @@ -403,7 +406,7 @@ namespace osu.Game.Overlays.Mods if (mods.NewValue == null) return; foreach (var section in ModSectionsContainer.Children) - section.Mods = mods.NewValue[section.ModType]; + section.Mods = mods.NewValue[section.ModType].Where(isValidMod); } private void selectedModsChanged(ValueChangedEvent> mods) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 36dbb9e792..ebc06d2445 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Online.Rooms; +using osu.Game.Overlays.Mods; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Select; @@ -109,5 +110,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer } protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea(); + + protected override ModSelectOverlay CreateModSelectOverlay() => new ModSelectOverlay(isValidMod); + + private bool isValidMod(Mod mod) => !(mod is ModAutoplay) && (mod as MultiMod)?.Mods.Any(mm => mm is ModAutoplay) != true; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6c0bd3a228..4fca77a176 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -251,11 +251,7 @@ namespace osu.Game.Screens.Select Children = new Drawable[] { BeatmapOptions = new BeatmapOptionsOverlay(), - ModSelect = new ModSelectOverlay - { - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, - } + ModSelect = CreateModSelectOverlay() } } } @@ -305,6 +301,8 @@ namespace osu.Game.Screens.Select } } + protected virtual ModSelectOverlay CreateModSelectOverlay() => new ModSelectOverlay(); + protected virtual void ApplyFilterToCarousel(FilterCriteria criteria) { // if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter). From 1359153382232fc303dd1ded30048545c4aa0638 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 17:54:22 +0900 Subject: [PATCH 080/113] Revert "Test removing nuget restore from iOS/Android build scripts" This reverts commit 39746cb3de8ad11221ff1766822f720918d49858. --- fastlane/Fastfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 18b5907e82..8c278604aa 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -48,6 +48,10 @@ desc 'Deploy to play store' desc 'Compile the project' lane :build do |options| + nuget_restore( + project_path: 'osu.sln' + ) + souyuz( build_configuration: 'Release', solution_path: 'osu.sln', @@ -103,6 +107,10 @@ platform :ios do desc 'Compile the project' lane :build do + nuget_restore( + project_path: 'osu.sln' + ) + souyuz( platform: "ios", plist_path: "osu.iOS/Info.plist" From 46681322d0489d0829114fc87071b7e5c8f0c525 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 17:56:00 +0900 Subject: [PATCH 081/113] Restore nuget packages per project to avoid toolchain incompatibilities with net50 --- fastlane/Fastfile | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 8c278604aa..1823b9e924 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -48,9 +48,8 @@ desc 'Deploy to play store' desc 'Compile the project' lane :build do |options| - nuget_restore( - project_path: 'osu.sln' - ) + nuget_restore(project_path: 'osu.Android/osu.Android.csproj') + nuget_restore(project_path: 'osu.Game/osu.Game.csproj') souyuz( build_configuration: 'Release', @@ -107,9 +106,8 @@ platform :ios do desc 'Compile the project' lane :build do - nuget_restore( - project_path: 'osu.sln' - ) + nuget_restore(project_path: 'osu.iOS/osu.iOS.csproj') + nuget_restore(project_path: 'osu.Game/osu.Game.csproj') souyuz( platform: "ios", From 0560eb41201d0094d8321927bc3498502065c994 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 18:22:21 +0900 Subject: [PATCH 082/113] Reduce final fill alpha of main menu confirm-to-exit --- osu.Game/Overlays/HoldToConfirmOverlay.cs | 13 +++++++++++-- osu.Game/Screens/Menu/ExitConfirmOverlay.cs | 5 +++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/HoldToConfirmOverlay.cs b/osu.Game/Overlays/HoldToConfirmOverlay.cs index eb325d8dd3..0542f66b5b 100644 --- a/osu.Game/Overlays/HoldToConfirmOverlay.cs +++ b/osu.Game/Overlays/HoldToConfirmOverlay.cs @@ -24,6 +24,13 @@ namespace osu.Game.Overlays [Resolved] private AudioManager audio { get; set; } + private readonly float finalFillAlpha; + + protected HoldToConfirmOverlay(float finalFillAlpha = 1) + { + this.finalFillAlpha = finalFillAlpha; + } + [BackgroundDependencyLoader] private void load() { @@ -42,8 +49,10 @@ namespace osu.Game.Overlays Progress.ValueChanged += p => { - audioVolume.Value = 1 - p.NewValue; - overlay.Alpha = (float)p.NewValue; + var target = p.NewValue * finalFillAlpha; + + audioVolume.Value = 1 - target; + overlay.Alpha = (float)target; }; audio.Tracks.AddAdjustment(AdjustableProperty.Volume, audioVolume); diff --git a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs index db2faeb60a..a491283e5f 100644 --- a/osu.Game/Screens/Menu/ExitConfirmOverlay.cs +++ b/osu.Game/Screens/Menu/ExitConfirmOverlay.cs @@ -13,6 +13,11 @@ namespace osu.Game.Screens.Menu public void Abort() => AbortConfirm(); + public ExitConfirmOverlay() + : base(0.7f) + { + } + public bool OnPressed(GlobalAction action) { if (action == GlobalAction.Back) From 12443e39ae70060657f1b097bc7b9c6e35345e08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 19:16:32 +0900 Subject: [PATCH 083/113] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index db5c933c41..9ad5946311 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 301ee39a61..2b8f81532d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -26,7 +26,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 225cf981f2..4732620085 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -88,7 +88,7 @@ - + From ced7a36788d7f61ce1163f043d872eb97ad44a02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 21:24:10 +0900 Subject: [PATCH 084/113] Update namespaces --- osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs | 1 - osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs | 2 +- osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs | 1 - osu.Game/Rulesets/UI/Playfield.cs | 2 +- osu.Game/Skinning/PoolableSkinnableSample.cs | 2 +- osu.Game/Skinning/SkinnableSound.cs | 2 +- 6 files changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs index 33e3c7cb8c..987a5812db 100644 --- a/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs +++ b/osu.Game.Tests/Rulesets/TestSceneDrawableRulesetDependencies.cs @@ -9,7 +9,6 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs index 80f1b02794..97087e31ab 100644 --- a/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs +++ b/osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; +using osu.Framework.Audio.Sample; using osu.Framework.Configuration.Tracking; using osu.Framework.Graphics.Textures; using osu.Framework.IO.Stores; diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs index b13b20dae2..81ec73a6c5 100644 --- a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs +++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics.OpenGL.Textures; using osu.Framework.Graphics.Textures; diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index b4e0025351..c40ab4bd94 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -8,7 +8,6 @@ using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics.Containers; @@ -20,6 +19,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Skinning; using osuTK; using System.Diagnostics; +using osu.Framework.Audio.Sample; namespace osu.Game.Rulesets.UI { diff --git a/osu.Game/Skinning/PoolableSkinnableSample.cs b/osu.Game/Skinning/PoolableSkinnableSample.cs index cc6b85a13e..2a0f480b48 100644 --- a/osu.Game/Skinning/PoolableSkinnableSample.cs +++ b/osu.Game/Skinning/PoolableSkinnableSample.cs @@ -5,7 +5,7 @@ using System; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; +using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index b841f99598..a874e9a0db 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -7,7 +7,7 @@ using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; +using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; From e74ecebfd61440a47c7423b0802491ccc1930b7e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jan 2021 23:45:57 +0900 Subject: [PATCH 085/113] nuget restore other rulesets --- fastlane/Fastfile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 1823b9e924..cc5abf5b03 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -50,6 +50,10 @@ desc 'Deploy to play store' lane :build do |options| nuget_restore(project_path: 'osu.Android/osu.Android.csproj') nuget_restore(project_path: 'osu.Game/osu.Game.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj') souyuz( build_configuration: 'Release', @@ -108,6 +112,10 @@ platform :ios do lane :build do nuget_restore(project_path: 'osu.iOS/osu.iOS.csproj') nuget_restore(project_path: 'osu.Game/osu.Game.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj') + nuget_restore(project_path: 'osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj') souyuz( platform: "ios", From 7476cb3047b400489d39af6494c782de531313ed Mon Sep 17 00:00:00 2001 From: rednir Date: Mon, 18 Jan 2021 19:51:42 +0000 Subject: [PATCH 086/113] Sort SkinSection in alphabetical order --- .../Overlays/Settings/Sections/SkinSection.cs | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 5898482e4a..0bfa0ba4f0 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -107,21 +107,20 @@ namespace osu.Game.Overlays.Settings.Sections private void updateItems() { skinItems = skins.GetAllUsableSkins(); - - // insert after lazer built-in skins - int firstNonDefault = skinItems.FindIndex(s => s.ID > 0); - if (firstNonDefault < 0) - firstNonDefault = skinItems.Count; - - skinItems.Insert(firstNonDefault, random_skin_info); - + skinItems = sortList(skinItems); + skinDropdown.Items = skinItems; } private void itemUpdated(ValueChangedEvent> weakItem) { if (weakItem.NewValue.TryGetTarget(out var item)) - Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => !i.Equals(item)).Append(item).ToArray()); + { + List newDropdownItems = skinDropdown.Items.ToList(); + newDropdownItems.Add(item); + newDropdownItems = sortList(newDropdownItems); + Schedule(() => skinDropdown.Items = newDropdownItems.ToArray()); + } } private void itemRemoved(ValueChangedEvent> weakItem) @@ -130,6 +129,24 @@ namespace osu.Game.Overlays.Settings.Sections Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => i.ID != item.ID).ToArray()); } + private List sortList(List skinsList) + { + skinsList.Sort((a, b) => String.Compare(a.Name, b.Name, StringComparison.Ordinal)); + for (int i = 0; i < skinsList.Count; i++) + { + // insert lazer built-in skins before user skins + if (skinsList[i].ID <= 0) { + var itemToMove = skinsList[i]; + skinsList.RemoveAt(i); + skinsList.Insert(0, itemToMove); + } + } + skinsList.RemoveAll(s => s.ID == SkinInfo.RANDOM_SKIN); + skinsList.Insert(0, random_skin_info); + + return skinsList; + } + private class SkinSettingsDropdown : SettingsDropdown { protected override OsuDropdown CreateDropdown() => new SkinDropdownControl(); From 0b65c0cd25a727fbfa121395e515fe9e8bd295b1 Mon Sep 17 00:00:00 2001 From: rednir Date: Mon, 18 Jan 2021 20:17:42 +0000 Subject: [PATCH 087/113] Remove whitespace --- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 8e78940ac2..20953b7a9b 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -113,7 +113,6 @@ namespace osu.Game.Overlays.Settings.Sections { skinItems = skins.GetAllUsableSkins(); skinItems = sortList(skinItems); - skinDropdown.Items = skinItems; } From 5233a0449a63b3db599d11535b3484c8ebc50f47 Mon Sep 17 00:00:00 2001 From: Mysfit Date: Mon, 18 Jan 2021 16:08:06 -0500 Subject: [PATCH 088/113] Hide main room subscreen on initial mp room creation. Toggle mp room subscreen visibility based on settings overlay visibility before room is created. --- .../Multiplayer/MultiplayerMatchSubScreen.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 80991569dc..df61a0ad21 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -39,6 +39,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private MultiplayerMatchSettingsOverlay settingsOverlay; + private readonly Bindable settingsOverlayVisibility = new Bindable(); + + private GridContainer subScreenContainer; + private IBindable isConnected; [CanBeNull] @@ -55,7 +59,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { InternalChildren = new Drawable[] { - new GridContainer + subScreenContainer = new GridContainer { RelativeSizeAxes = Axes.Both, Content = new[] @@ -178,6 +182,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer State = { Value = client.Room == null ? Visibility.Visible : Visibility.Hidden } } }; + + subScreenContainer.Hide(); + settingsOverlayVisibility.BindTo(settingsOverlay.State); + settingsOverlayVisibility.ValueChanged += settingsOverlayVisibilityChanged; } protected override void LoadComplete() @@ -258,6 +266,22 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer readyClickOperation = null; } + private void settingsOverlayVisibilityChanged(ValueChangedEvent settingsOverlayVisibilityChangedEvent) + { + if (client.Room != null) + { + subScreenContainer.Show(); + settingsOverlayVisibility.ValueChanged -= settingsOverlayVisibilityChanged; + } + else + { + if (settingsOverlayVisibilityChangedEvent.NewValue == Visibility.Visible) + subScreenContainer.Hide(); + else + subScreenContainer.Show(); + } + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From cbfb999c2845074d799d1126296584898d9be52b Mon Sep 17 00:00:00 2001 From: Mysfit Date: Mon, 18 Jan 2021 17:13:24 -0500 Subject: [PATCH 089/113] Use the client.RoomUpdated action instead of binding the value of the settings overlay visibility and creating an event from it based on its ValueChanged action. --- .../Multiplayer/MultiplayerMatchSubScreen.cs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index df61a0ad21..38c2ca7e0c 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -39,8 +39,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private MultiplayerMatchSettingsOverlay settingsOverlay; - private readonly Bindable settingsOverlayVisibility = new Bindable(); - private GridContainer subScreenContainer; private IBindable isConnected; @@ -184,8 +182,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer }; subScreenContainer.Hide(); - settingsOverlayVisibility.BindTo(settingsOverlay.State); - settingsOverlayVisibility.ValueChanged += settingsOverlayVisibilityChanged; + client.RoomUpdated += roomUpdated; } protected override void LoadComplete() @@ -266,19 +263,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer readyClickOperation = null; } - private void settingsOverlayVisibilityChanged(ValueChangedEvent settingsOverlayVisibilityChangedEvent) + private void roomUpdated() { if (client.Room != null) { + // If the room is updated and is not null, show the room sub screen container and unsubscribe. subScreenContainer.Show(); - settingsOverlayVisibility.ValueChanged -= settingsOverlayVisibilityChanged; - } - else - { - if (settingsOverlayVisibilityChangedEvent.NewValue == Visibility.Visible) - subScreenContainer.Hide(); - else - subScreenContainer.Show(); + client.RoomUpdated -= roomUpdated; } } From f0add0a7cff7b6fe63ca0ccbf0de4caa130fd30d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 19 Jan 2021 01:34:37 +0300 Subject: [PATCH 090/113] Make BeatmapSetOverlay use OverlayHeader --- .../Online/TestSceneBeatmapSetOverlay.cs | 2 +- .../Overlays/BeatmapSet/BeatmapSetHeader.cs | 300 ++++++++++++++++- osu.Game/Overlays/BeatmapSet/Header.cs | 313 ------------------ osu.Game/Overlays/BeatmapSetOverlay.cs | 9 +- 4 files changed, 302 insertions(+), 322 deletions(-) delete mode 100644 osu.Game/Overlays/BeatmapSet/Header.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 689321698a..7ff978c7ca 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -315,7 +315,7 @@ namespace osu.Game.Tests.Visual.Online private class TestBeatmapSetOverlay : BeatmapSetOverlay { - public new Header Header => base.Header; + public new BeatmapSetHeader Header => base.Header; } } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index 6511b15fc8..bc9008d1f5 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -1,23 +1,319 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online; +using osu.Game.Online.API; +using osu.Game.Overlays.BeatmapListing.Panels; +using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { public class BeatmapSetHeader : OverlayHeader { - public readonly Bindable Ruleset = new Bindable(); + private const float transition_duration = 200; + private const float buttons_height = 45; + private const float buttons_spacing = 5; + + public readonly Bindable BeatmapSet = new Bindable(); + + public bool DownloadButtonsVisible => downloadButtonsContainer.Any(); + + public BeatmapPicker Picker { get; private set; } public BeatmapRulesetSelector RulesetSelector { get; private set; } + private IBindable state => downloadTracker.State; + + [Cached(typeof(IBindable))] + private readonly Bindable ruleset = new Bindable(); + + [Resolved] + private IAPIProvider api { get; set; } + + private readonly DownloadTracker downloadTracker; + private OsuSpriteText title, artist; + private AuthorInfo author; + private ExplicitContentBeatmapPill explicitContentPill; + private FillFlowContainer downloadButtonsContainer; + private BeatmapAvailability beatmapAvailability; + private BeatmapSetOnlineStatusPill onlineStatusPill; + private ExternalLinkButton externalLink; + private UpdateableBeatmapSetCover cover; + private Box coverGradient; + private FillFlowContainer fadeContent; + private FavouriteButton favouriteButton; + private LoadingSpinner loading; + private Details details; + + public BeatmapSetHeader() + { + Masking = true; + + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }; + + AddInternal(downloadTracker = new DownloadTracker + { + BeatmapSet = { BindTarget = BeatmapSet } + }); + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Picker.Beatmap.ValueChanged += b => + { + details.Beatmap = b.NewValue; + externalLink.Link = $@"{api.WebsiteRootUrl}/beatmapsets/{BeatmapSet.Value?.OnlineBeatmapSetID}#{b.NewValue?.Ruleset.ShortName}/{b.NewValue?.OnlineBeatmapID}"; + }; + + coverGradient.Colour = ColourInfo.GradientVertical(colourProvider.Background6.Opacity(0.3f), colourProvider.Background6.Opacity(0.8f)); + onlineStatusPill.BackgroundColour = colourProvider.Background6; + + state.BindValueChanged(_ => updateDownloadButtons()); + + BeatmapSet.BindValueChanged(setInfo => + { + Picker.BeatmapSet = RulesetSelector.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = details.BeatmapSet = setInfo.NewValue; + cover.BeatmapSet = setInfo.NewValue; + + if (setInfo.NewValue == null) + { + onlineStatusPill.FadeTo(0.5f, 500, Easing.OutQuint); + fadeContent.Hide(); + + loading.Show(); + + downloadButtonsContainer.FadeOut(transition_duration); + favouriteButton.FadeOut(transition_duration); + } + else + { + fadeContent.FadeIn(500, Easing.OutQuint); + + loading.Hide(); + + title.Text = setInfo.NewValue.Metadata.Title ?? string.Empty; + artist.Text = setInfo.NewValue.Metadata.Artist ?? string.Empty; + + explicitContentPill.Alpha = setInfo.NewValue.OnlineInfo.HasExplicitContent ? 1 : 0; + + onlineStatusPill.FadeIn(500, Easing.OutQuint); + onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status; + + downloadButtonsContainer.FadeIn(transition_duration); + favouriteButton.FadeIn(transition_duration); + + updateDownloadButtons(); + } + }, true); + } + + protected override Drawable CreateContent() => new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + cover = new UpdateableBeatmapSetCover + { + RelativeSizeAxes = Axes.Both, + Masking = true, + }, + coverGradient = new Box + { + RelativeSizeAxes = Axes.Both + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding + { + Vertical = BeatmapSetOverlay.Y_PADDING, + Left = BeatmapSetOverlay.X_PADDING, + Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, + }, + Children = new Drawable[] + { + fadeContent = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = Picker = new BeatmapPicker(), + }, + new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 15 }, + Children = new Drawable[] + { + title = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) + }, + externalLink = new ExternalLinkButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font + }, + explicitContentPill = new ExplicitContentBeatmapPill + { + Alpha = 0f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10, Bottom = 4 }, + } + } + }, + artist = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), + Margin = new MarginPadding { Bottom = 20 } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = author = new AuthorInfo(), + }, + beatmapAvailability = new BeatmapAvailability(), + new Container + { + RelativeSizeAxes = Axes.X, + Height = buttons_height, + Margin = new MarginPadding { Top = 10 }, + Children = new Drawable[] + { + favouriteButton = new FavouriteButton + { + BeatmapSet = { BindTarget = BeatmapSet } + }, + downloadButtonsContainer = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, + Spacing = new Vector2(buttons_spacing), + }, + }, + }, + }, + }, + } + }, + loading = new LoadingSpinner + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(1.5f), + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(10), + Children = new Drawable[] + { + onlineStatusPill = new BeatmapSetOnlineStatusPill + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + TextSize = 14, + TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 } + }, + details = new Details(), + }, + }, + } + }; + + private void updateDownloadButtons() + { + if (BeatmapSet.Value == null) return; + + if ((BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) && state.Value != DownloadState.LocallyAvailable) + { + downloadButtonsContainer.Clear(); + return; + } + + switch (state.Value) + { + case DownloadState.LocallyAvailable: + // temporary for UX until new design is implemented. + downloadButtonsContainer.Child = new BeatmapPanelDownloadButton(BeatmapSet.Value) + { + Width = 50, + RelativeSizeAxes = Axes.Y, + SelectedBeatmap = { BindTarget = Picker.Beatmap } + }; + break; + + case DownloadState.Downloading: + case DownloadState.Importing: + // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. + downloadButtonsContainer.Child = new HeaderDownloadButton(BeatmapSet.Value); + break; + + default: + downloadButtonsContainer.Child = new HeaderDownloadButton(BeatmapSet.Value); + if (BeatmapSet.Value.OnlineInfo.HasVideo) + downloadButtonsContainer.Add(new HeaderDownloadButton(BeatmapSet.Value, true)); + break; + } + } + + private class DownloadTracker : BeatmapDownloadTrackingComposite + { + public new Bindable State => base.State; + } + protected override OverlayTitle CreateTitle() => new BeatmapHeaderTitle(); protected override Drawable CreateTitleContent() => RulesetSelector = new BeatmapRulesetSelector { - Current = Ruleset + Current = ruleset }; private class BeatmapHeaderTitle : OverlayTitle diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs deleted file mode 100644 index 916c21c010..0000000000 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps.Drawables; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online; -using osu.Game.Online.API; -using osu.Game.Overlays.BeatmapListing.Panels; -using osu.Game.Overlays.BeatmapSet.Buttons; -using osu.Game.Rulesets; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.BeatmapSet -{ - public class Header : BeatmapDownloadTrackingComposite - { - private const float transition_duration = 200; - private const float buttons_height = 45; - private const float buttons_spacing = 5; - - private readonly UpdateableBeatmapSetCover cover; - private readonly Box coverGradient; - private readonly OsuSpriteText title, artist; - private readonly AuthorInfo author; - private readonly ExplicitContentBeatmapPill explicitContentPill; - private readonly FillFlowContainer downloadButtonsContainer; - private readonly BeatmapAvailability beatmapAvailability; - private readonly BeatmapSetOnlineStatusPill onlineStatusPill; - public Details Details; - - public bool DownloadButtonsVisible => downloadButtonsContainer.Any(); - - [Resolved] - private IAPIProvider api { get; set; } - - public BeatmapRulesetSelector RulesetSelector => beatmapSetHeader.RulesetSelector; - public readonly BeatmapPicker Picker; - - private readonly FavouriteButton favouriteButton; - private readonly FillFlowContainer fadeContent; - private readonly LoadingSpinner loading; - private readonly BeatmapSetHeader beatmapSetHeader; - - [Cached(typeof(IBindable))] - private readonly Bindable ruleset = new Bindable(); - - public Header() - { - ExternalLinkButton externalLink; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Masking = true; - - EdgeEffect = new EdgeEffectParameters - { - Colour = Color4.Black.Opacity(0.25f), - Type = EdgeEffectType.Shadow, - Radius = 3, - Offset = new Vector2(0f, 1f), - }; - - InternalChild = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - beatmapSetHeader = new BeatmapSetHeader - { - Ruleset = { BindTarget = ruleset }, - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - cover = new UpdateableBeatmapSetCover - { - RelativeSizeAxes = Axes.Both, - Masking = true, - }, - coverGradient = new Box - { - RelativeSizeAxes = Axes.Both - }, - }, - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding - { - Vertical = BeatmapSetOverlay.Y_PADDING, - Left = BeatmapSetOverlay.X_PADDING, - Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, - }, - Children = new Drawable[] - { - fadeContent = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = Picker = new BeatmapPicker(), - }, - new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 15 }, - Children = new Drawable[] - { - title = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) - }, - externalLink = new ExternalLinkButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font - }, - explicitContentPill = new ExplicitContentBeatmapPill - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10, Bottom = 4 }, - } - } - }, - artist = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), - Margin = new MarginPadding { Bottom = 20 } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = author = new AuthorInfo(), - }, - beatmapAvailability = new BeatmapAvailability(), - new Container - { - RelativeSizeAxes = Axes.X, - Height = buttons_height, - Margin = new MarginPadding { Top = 10 }, - Children = new Drawable[] - { - favouriteButton = new FavouriteButton - { - BeatmapSet = { BindTarget = BeatmapSet } - }, - downloadButtonsContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, - Spacing = new Vector2(buttons_spacing), - }, - }, - }, - }, - }, - } - }, - loading = new LoadingSpinner - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(1.5f), - }, - new FillFlowContainer - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(10), - Children = new Drawable[] - { - onlineStatusPill = new BeatmapSetOnlineStatusPill - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - TextSize = 14, - TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 } - }, - Details = new Details(), - }, - }, - }, - }, - } - }; - - Picker.Beatmap.ValueChanged += b => - { - Details.Beatmap = b.NewValue; - externalLink.Link = $@"{api.WebsiteRootUrl}/beatmapsets/{BeatmapSet.Value?.OnlineBeatmapSetID}#{b.NewValue?.Ruleset.ShortName}/{b.NewValue?.OnlineBeatmapID}"; - }; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - coverGradient.Colour = ColourInfo.GradientVertical(colourProvider.Background6.Opacity(0.3f), colourProvider.Background6.Opacity(0.8f)); - onlineStatusPill.BackgroundColour = colourProvider.Background6; - - State.BindValueChanged(_ => updateDownloadButtons()); - - BeatmapSet.BindValueChanged(setInfo => - { - Picker.BeatmapSet = RulesetSelector.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = Details.BeatmapSet = setInfo.NewValue; - cover.BeatmapSet = setInfo.NewValue; - - if (setInfo.NewValue == null) - { - onlineStatusPill.FadeTo(0.5f, 500, Easing.OutQuint); - fadeContent.Hide(); - - loading.Show(); - - downloadButtonsContainer.FadeOut(transition_duration); - favouriteButton.FadeOut(transition_duration); - } - else - { - fadeContent.FadeIn(500, Easing.OutQuint); - - loading.Hide(); - - title.Text = setInfo.NewValue.Metadata.Title ?? string.Empty; - artist.Text = setInfo.NewValue.Metadata.Artist ?? string.Empty; - - explicitContentPill.Alpha = setInfo.NewValue.OnlineInfo.HasExplicitContent ? 1 : 0; - - onlineStatusPill.FadeIn(500, Easing.OutQuint); - onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status; - - downloadButtonsContainer.FadeIn(transition_duration); - favouriteButton.FadeIn(transition_duration); - - updateDownloadButtons(); - } - }, true); - } - - private void updateDownloadButtons() - { - if (BeatmapSet.Value == null) return; - - if ((BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) && State.Value != DownloadState.LocallyAvailable) - { - downloadButtonsContainer.Clear(); - return; - } - - switch (State.Value) - { - case DownloadState.LocallyAvailable: - // temporary for UX until new design is implemented. - downloadButtonsContainer.Child = new BeatmapPanelDownloadButton(BeatmapSet.Value) - { - Width = 50, - RelativeSizeAxes = Axes.Y, - SelectedBeatmap = { BindTarget = Picker.Beatmap } - }; - break; - - case DownloadState.Downloading: - case DownloadState.Importing: - // temporary to avoid showing two buttons for maps with novideo. will be fixed in new beatmap overlay design. - downloadButtonsContainer.Child = new HeaderDownloadButton(BeatmapSet.Value); - break; - - default: - downloadButtonsContainer.Child = new HeaderDownloadButton(BeatmapSet.Value); - if (BeatmapSet.Value.OnlineInfo.HasVideo) - downloadButtonsContainer.Add(new HeaderDownloadButton(BeatmapSet.Value, true)); - break; - } - } - } -} diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index bbec62a85a..86f0f4f614 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -19,15 +19,12 @@ using osuTK; namespace osu.Game.Overlays { - public class BeatmapSetOverlay : FullscreenOverlay // we don't provide a standard header for now. + public class BeatmapSetOverlay : FullscreenOverlay { public const float X_PADDING = 40; public const float Y_PADDING = 25; public const float RIGHT_WIDTH = 275; - //todo: should be an OverlayHeader? or maybe not? - protected new readonly Header Header; - [Resolved] private RulesetStore rulesets { get; set; } @@ -39,7 +36,7 @@ namespace osu.Game.Overlays private readonly Box background; public BeatmapSetOverlay() - : base(OverlayColourScheme.Blue, null) + : base(OverlayColourScheme.Blue, new BeatmapSetHeader()) { OverlayScrollContainer scroll; Info info; @@ -72,7 +69,7 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - Header = new Header(), + Header, info = new Info() } }, From 1e99357a9790884a7a84e4c052a6ab65921586a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 19 Jan 2021 12:13:27 +0900 Subject: [PATCH 091/113] Update build configurations to net5.0 paths --- .../.idea/runConfigurations/Benchmarks.xml | 6 +++--- .../runConfigurations/CatchRuleset__Tests_.xml | 6 +++--- .../runConfigurations/ManiaRuleset__Tests_.xml | 6 +++--- .../runConfigurations/OsuRuleset__Tests_.xml | 6 +++--- .../runConfigurations/TaikoRuleset__Tests_.xml | 6 +++--- .../.idea/runConfigurations/Tournament.xml | 6 +++--- .../runConfigurations/Tournament__Tests_.xml | 6 +++--- .../.idea/runConfigurations/osu_.xml | 6 +++--- .../.idea/runConfigurations/osu___Tests_.xml | 6 +++--- .../runConfigurations/osu___legacy_osuTK_.xml | 6 +++--- .vscode/launch.json | 18 +++++++++--------- .../.vscode/launch.json | 4 ++-- .../.vscode/launch.json | 4 ++-- .../.vscode/launch.json | 4 ++-- .../.vscode/launch.json | 4 ++-- osu.Game.Tournament.Tests/.vscode/launch.json | 4 ++-- 16 files changed, 49 insertions(+), 49 deletions(-) diff --git a/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml b/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml index 1815c271b4..8fa7608b8e 100644 --- a/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml +++ b/.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml @@ -1,8 +1,8 @@ -