From 2350806b4cc8fbe23ee21288e5c75d16407133a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 Nov 2021 20:26:45 +0100 Subject: [PATCH 01/12] Add failing test case for number box stack overflow scenario --- .../Settings/TestSceneSettingsNumberBox.cs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs new file mode 100644 index 0000000000..ffa1200f32 --- /dev/null +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs @@ -0,0 +1,25 @@ +// 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 NUnit.Framework; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Settings; + +namespace osu.Game.Tests.Visual.Settings +{ + public class TestSceneSettingsNumberBox : OsuTestScene + { + [Test] + public void TestLargeInteger() + { + SettingsNumberBox numberBox = null; + + AddStep("create number box", () => Child = numberBox = new SettingsNumberBox()); + + AddStep("set value to 1,000,000,000", () => numberBox.Current.Value = 1_000_000_000); + AddAssert("text box text is correct", () => numberBox.ChildrenOfType().Single().Current.Value == "1000000000"); + } + } +} From dced6a2e682a9902f43e1901e2ae1912bb637016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 Nov 2021 20:39:44 +0100 Subject: [PATCH 02/12] Add extended test coverage for desired input handling --- .../Settings/TestSceneSettingsNumberBox.cs | 65 +++++++++++++++++-- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs index ffa1200f32..c063e5526a 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs @@ -11,15 +11,68 @@ namespace osu.Game.Tests.Visual.Settings { public class TestSceneSettingsNumberBox : OsuTestScene { + private SettingsNumberBox numberBox; + private OsuTextBox textBox; + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("create number box", () => Child = numberBox = new SettingsNumberBox()); + AddStep("get inner text box", () => textBox = numberBox.ChildrenOfType().Single()); + } + [Test] public void TestLargeInteger() { - SettingsNumberBox numberBox = null; - - AddStep("create number box", () => Child = numberBox = new SettingsNumberBox()); - - AddStep("set value to 1,000,000,000", () => numberBox.Current.Value = 1_000_000_000); - AddAssert("text box text is correct", () => numberBox.ChildrenOfType().Single().Current.Value == "1000000000"); + AddStep("set current to 1,000,000,000", () => numberBox.Current.Value = 1_000_000_000); + AddAssert("text box text is correct", () => textBox.Text == "1000000000"); } + + [Test] + public void TestUserInput() + { + inputText("42"); + currentValueIs(42); + currentTextIs("42"); + + inputText(string.Empty); + currentValueIs(null); + currentTextIs(string.Empty); + + inputText("555"); + currentValueIs(555); + currentTextIs("555"); + + inputText("-4444"); + // attempting to input the minus will raise an input error, the rest will pass through fine. + currentValueIs(4444); + currentTextIs("4444"); + + // checking the upper bound. + inputText(int.MaxValue.ToString()); + currentValueIs(int.MaxValue); + currentTextIs(int.MaxValue.ToString()); + + inputText((long)int.MaxValue + 1.ToString()); + currentValueIs(int.MaxValue); + currentTextIs(int.MaxValue.ToString()); + + inputText("0"); + currentValueIs(0); + currentTextIs("0"); + + // checking that leading zeroes are stripped. + inputText("00"); + currentValueIs(0); + currentTextIs("0"); + + inputText("01"); + currentValueIs(1); + currentTextIs("1"); + } + + private void inputText(string text) => AddStep($"set textbox text to {text}", () => textBox.Text = text); + private void currentValueIs(int? value) => AddAssert($"current value is {value?.ToString() ?? "null"}", () => numberBox.Current.Value == value); + private void currentTextIs(string value) => AddAssert($"current text is {value}", () => textBox.Text == value); } } From 4a9f080f3c0c227ff17ab5b4dc1744d4c433e354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 22 Nov 2021 20:41:27 +0100 Subject: [PATCH 03/12] Accept full range of `int` in `SettingsNumberBox` This fixes stack overflow exceptions that would arise when a `Current.Value` of 1 billion or more was set on a `SettingsNumberBox`. The stack overflow was caused by the "maximum 9 digits" spec. If a value technically within `int` bounds, but larger than 1 billion (in the range [1,000,000,000; 2,147,483,647], to be more precise), a feedback loop between the setting control's `Current` and its inner text box's `Current` would occur, wherein the last digit would be trimmed and then re-appended again forevermore. To resolve, remove the offending spec and rely on `int.TryParse` entirely to be able to discern overflow range. Additionally, UX of the text box is slightly changed to notify when the `int` range is exceeded with a red flash. This behaviour would not have been possible to implement without recent framework-side fixes to text box (removal of text set scheduling). --- osu.Game/Overlays/Settings/SettingsNumberBox.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Settings/SettingsNumberBox.cs b/osu.Game/Overlays/Settings/SettingsNumberBox.cs index 545f1050b2..cbe9f7fc64 100644 --- a/osu.Game/Overlays/Settings/SettingsNumberBox.cs +++ b/osu.Game/Overlays/Settings/SettingsNumberBox.cs @@ -35,7 +35,6 @@ namespace osu.Game.Overlays.Settings { numberBox = new OutlinedNumberBox { - LengthLimit = 9, // limited to less than a value that could overflow int32 backing. Margin = new MarginPadding { Top = 5 }, RelativeSizeAxes = Axes.X, CommitOnFocusLost = true @@ -44,12 +43,19 @@ namespace osu.Game.Overlays.Settings numberBox.Current.BindValueChanged(e => { - int? value = null; + if (string.IsNullOrEmpty(e.NewValue)) + { + Current.Value = null; + return; + } if (int.TryParse(e.NewValue, out int intVal)) - value = intVal; + Current.Value = intVal; + else + numberBox.NotifyInputError(); - current.Value = value; + // trigger Current again to either restore the previous text box value, or to reformat the new value via .ToString(). + Current.TriggerChange(); }); Current.BindValueChanged(e => @@ -62,6 +68,8 @@ namespace osu.Game.Overlays.Settings private class OutlinedNumberBox : OutlinedTextBox { protected override bool CanAddCharacter(char character) => char.IsNumber(character); + + public new void NotifyInputError() => base.NotifyInputError(); } } } From 49e2a8afa3f345ec4dc12b8dc99ec546a3b06e6c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Nov 2021 14:08:03 +0900 Subject: [PATCH 04/12] Don't directly reset the database when running tests The containing storage is destroyed anyway, so this is redundant. --- osu.Game/Tests/Visual/OsuTestScene.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index fc7bc324ca..2bacfcebca 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -90,11 +90,6 @@ namespace osu.Game.Tests.Visual { var factory = new DatabaseContextFactory(LocalStorage); - // only reset the database if not using the host storage. - // if we reset the host storage, it will delete global key bindings. - if (isolatedHostStorage == null) - factory.ResetDatabase(); - using (var usage = factory.Get()) usage.Migrate(); return factory; From 5631e75f16073892a81b1c4e6af5959049ee2b0c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Nov 2021 14:11:27 +0900 Subject: [PATCH 05/12] Restructure how the headless storage is used / documented to hopefully make more sense --- osu.Game/Tests/Visual/OsuTestScene.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 2bacfcebca..cb4af67839 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -81,8 +81,7 @@ namespace osu.Game.Tests.Visual protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - if (!UseFreshStoragePerRun) - isolatedHostStorage = (parent.Get() as HeadlessGameHost)?.Storage; + isolatedHostStorage = (parent.Get() as HeadlessGameHost)?.Storage; Resources = parent.Get().Resources; @@ -149,8 +148,16 @@ namespace osu.Game.Tests.Visual } } - localStorage = - new Lazy(() => isolatedHostStorage ?? new TemporaryNativeStorage($"{GetType().Name}-{Guid.NewGuid()}")); + localStorage = new Lazy(() => + { + // When running headless, there is an opportunity to use the host storage rather than creating a second isolated one. + // This is because the host is recycled per TestScene execution in headless at an nunit level. + // Importantly, we can't use this optimisation when `UseFreshStoragePerRun` is true, as it doesn't reset per test method. + if (!UseFreshStoragePerRun && isolatedHostStorage != null) + return isolatedHostStorage; + + return new TemporaryNativeStorage($"{GetType().Name}-{Guid.NewGuid()}"); + }); } [Resolved] From 55f7d120e6325c0b003bcdb6373e31cae384149f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Nov 2021 14:11:44 +0900 Subject: [PATCH 06/12] Rename and reorder fields in `OsuTestScene` --- osu.Game/Tests/Visual/OsuTestScene.cs | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index cb4af67839..ca7b7b27b0 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -43,13 +43,6 @@ namespace osu.Game.Tests.Visual protected new OsuScreenDependencies Dependencies { get; private set; } - private DrawableRulesetDependencies rulesetDependencies; - - private Lazy localStorage; - protected Storage LocalStorage => localStorage.Value; - - private Lazy contextFactory; - protected IResourceStore Resources; protected IAPIProvider API @@ -65,23 +58,32 @@ namespace osu.Game.Tests.Visual private DummyAPIAccess dummyAPI; - protected DatabaseContextFactory ContextFactory => contextFactory.Value; - /// /// Whether this test scene requires real-world API access. /// If true, this will bypass the local and use the provided one. /// protected virtual bool UseOnlineAPI => false; + protected DatabaseContextFactory ContextFactory => contextFactory.Value; + + private Lazy contextFactory; + + protected virtual bool UseFreshStoragePerRun => false; + /// - /// When running headless, there is an opportunity to use the host storage rather than creating a second isolated one. - /// This is because the host is recycled per TestScene execution in headless at an nunit level. + /// A storage to be used by test runs. Can be isolated by setting to true. /// - private Storage isolatedHostStorage; + protected Storage LocalStorage => localStorage.Value; + + private Lazy localStorage; + + private Storage headlessHostStorage; + + private DrawableRulesetDependencies rulesetDependencies; protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - isolatedHostStorage = (parent.Get() as HeadlessGameHost)?.Storage; + headlessHostStorage = (parent.Get() as HeadlessGameHost)?.Storage; Resources = parent.Get().Resources; @@ -132,8 +134,6 @@ namespace osu.Game.Tests.Visual base.Content.Add(content = new DrawSizePreservingFillContainer()); } - protected virtual bool UseFreshStoragePerRun => false; - public virtual void RecycleLocalStorage(bool isDisposing) { if (localStorage?.IsValueCreated == true) @@ -153,8 +153,8 @@ namespace osu.Game.Tests.Visual // When running headless, there is an opportunity to use the host storage rather than creating a second isolated one. // This is because the host is recycled per TestScene execution in headless at an nunit level. // Importantly, we can't use this optimisation when `UseFreshStoragePerRun` is true, as it doesn't reset per test method. - if (!UseFreshStoragePerRun && isolatedHostStorage != null) - return isolatedHostStorage; + if (!UseFreshStoragePerRun && headlessHostStorage != null) + return headlessHostStorage; return new TemporaryNativeStorage($"{GetType().Name}-{Guid.NewGuid()}"); }); From 473f6b0347dac2494172f21d701e341ed7332954 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Nov 2021 14:14:53 +0900 Subject: [PATCH 07/12] Add more xmldoc --- osu.Game/Tests/Visual/OsuTestScene.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index ca7b7b27b0..eedf266bbe 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -64,15 +64,32 @@ namespace osu.Game.Tests.Visual /// protected virtual bool UseOnlineAPI => false; + /// + /// A database context factory to be used by test runs. Can be isolated and reset by setting to true. + /// + /// + /// In interactive runs (ie. VisualTests) this will use the user's database if is not set to true. + /// protected DatabaseContextFactory ContextFactory => contextFactory.Value; private Lazy contextFactory; + /// + /// Whether a fresh storage should be initialised per test (method) run. + /// + /// + /// By default (ie. if not set to true): + /// - in interactive runs, the user's storage will be used + /// - in headless runs, a shared temporary storage will be used per test class. + /// protected virtual bool UseFreshStoragePerRun => false; /// /// A storage to be used by test runs. Can be isolated by setting to true. /// + /// + /// In interactive runs (ie. VisualTests) this will use the user's storage if is not set to true. + /// protected Storage LocalStorage => localStorage.Value; private Lazy localStorage; From 4624977b7709876eb92a11552982a4877abafdce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Nov 2021 14:38:37 +0900 Subject: [PATCH 08/12] Fix tournament tests potentially using data left over from previous runs --- .../NonVisual/CustomTourneyDirectoryTest.cs | 36 ++++++++++++++----- .../NonVisual/IPCLocationTest.cs | 13 +++++-- .../NonVisual/TournamentHostTest.cs | 2 +- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs index fcc9f44f0c..94472a8bc7 100644 --- a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs @@ -38,7 +38,7 @@ namespace osu.Game.Tournament.Tests.NonVisual { using (HeadlessGameHost host = new HeadlessGameHost(nameof(TestCustomDirectory))) // don't use clean run as we are writing a config file. { - string osuDesktopStorage = basePath(nameof(TestCustomDirectory)); + string osuDesktopStorage = PrepareBasePath(nameof(TestCustomDirectory)); const string custom_tournament = "custom"; // need access before the game has constructed its own storage yet. @@ -60,6 +60,15 @@ namespace osu.Game.Tournament.Tests.NonVisual finally { host.Exit(); + + try + { + if (Directory.Exists(osuDesktopStorage)) + Directory.Delete(osuDesktopStorage, true); + } + catch + { + } } } } @@ -69,7 +78,7 @@ namespace osu.Game.Tournament.Tests.NonVisual { using (HeadlessGameHost host = new HeadlessGameHost(nameof(TestMigration))) // don't use clean run as we are writing test files for migration. { - string osuRoot = basePath(nameof(TestMigration)); + string osuRoot = PrepareBasePath(nameof(TestMigration)); string configFile = Path.Combine(osuRoot, "tournament.ini"); if (File.Exists(configFile)) @@ -136,18 +145,29 @@ namespace osu.Game.Tournament.Tests.NonVisual } finally { + host.Exit(); + try { - host.Storage.Delete("tournament.ini"); - host.Storage.DeleteDirectory("tournaments"); + if (Directory.Exists(osuRoot)) + Directory.Delete(osuRoot, true); + } + catch + { } - catch { } - - host.Exit(); } } } - private string basePath(string testInstance) => Path.Combine(RuntimeInfo.StartupDirectory, "headless", testInstance); + public static string PrepareBasePath(string testInstance) + { + string basePath = Path.Combine(RuntimeInfo.StartupDirectory, "headless", testInstance); + + // manually clean before starting in case there are left-over files at the test site. + if (Directory.Exists(basePath)) + Directory.Delete(basePath, true); + + return basePath; + } } } diff --git a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs index eaa009c180..22d9a4ff9d 100644 --- a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tournament.Tests.NonVisual // don't use clean run because files are being written before osu! launches. using (HeadlessGameHost host = new HeadlessGameHost(nameof(CheckIPCLocation))) { - string basePath = Path.Combine(RuntimeInfo.StartupDirectory, "headless", nameof(CheckIPCLocation)); + string basePath = CustomTourneyDirectoryTest.PrepareBasePath(nameof(CheckIPCLocation)); // Set up a fake IPC client for the IPC Storage to switch to. string testStableInstallDirectory = Path.Combine(basePath, "stable-ce"); @@ -42,9 +42,16 @@ namespace osu.Game.Tournament.Tests.NonVisual } finally { - host.Storage.DeleteDirectory(testStableInstallDirectory); - host.Storage.DeleteDirectory("tournaments"); host.Exit(); + + try + { + if (Directory.Exists(basePath)) + Directory.Delete(basePath, true); + } + catch + { + } } } } diff --git a/osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs b/osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs index 319a768e65..bf99f69b2a 100644 --- a/osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tournament.Tests.NonVisual return tournament; } - public static void WaitForOrAssert(Func result, string failureMessage, int timeout = 90000) + public static void WaitForOrAssert(Func result, string failureMessage, int timeout = 30000) { Task task = Task.Run(() => { From b596a0204c5d4a48965812dbba173d3fa4729577 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 23 Nov 2021 06:43:17 +0100 Subject: [PATCH 09/12] Rewrite overflow test step for legibility --- .../Visual/Settings/TestSceneSettingsNumberBox.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs index c063e5526a..334a814688 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsNumberBox.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Settings currentValueIs(int.MaxValue); currentTextIs(int.MaxValue.ToString()); - inputText((long)int.MaxValue + 1.ToString()); + inputText(smallestOverflowValue.ToString()); currentValueIs(int.MaxValue); currentTextIs(int.MaxValue.ToString()); @@ -74,5 +74,10 @@ namespace osu.Game.Tests.Visual.Settings private void inputText(string text) => AddStep($"set textbox text to {text}", () => textBox.Text = text); private void currentValueIs(int? value) => AddAssert($"current value is {value?.ToString() ?? "null"}", () => numberBox.Current.Value == value); private void currentTextIs(string value) => AddAssert($"current text is {value}", () => textBox.Text == value); + + /// + /// The smallest number that overflows . + /// + private static long smallestOverflowValue => 1L + int.MaxValue; } } From 6fb27577397056e76ac64be9b974b312a6be8ef3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Nov 2021 14:58:18 +0900 Subject: [PATCH 10/12] Remove usage of `Nuget.Packaging` extension methods for `IList.AddRange` --- osu.Game/Extensions/CollectionExtensions.cs | 22 ++++++++++++++++++++ osu.Game/Stores/BeatmapImporter.cs | 1 - osu.Game/Stores/RealmArchiveModelImporter.cs | 1 - 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Extensions/CollectionExtensions.cs diff --git a/osu.Game/Extensions/CollectionExtensions.cs b/osu.Game/Extensions/CollectionExtensions.cs new file mode 100644 index 0000000000..473dc4b8f4 --- /dev/null +++ b/osu.Game/Extensions/CollectionExtensions.cs @@ -0,0 +1,22 @@ +// 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; + +namespace osu.Game.Extensions +{ + public static class CollectionExtensions + { + public static void AddRange(this ICollection collection, IEnumerable items) + { + // List has a potentially more optimal path to adding a range. + if (collection is List list) + list.AddRange(items); + else + { + foreach (T obj in items) + collection.Add(obj); + } + } + } +} diff --git a/osu.Game/Stores/BeatmapImporter.cs b/osu.Game/Stores/BeatmapImporter.cs index dad2b29dd0..32f0cd3d7a 100644 --- a/osu.Game/Stores/BeatmapImporter.cs +++ b/osu.Game/Stores/BeatmapImporter.cs @@ -7,7 +7,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using NuGet.Packaging; using osu.Framework.Audio.Track; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; diff --git a/osu.Game/Stores/RealmArchiveModelImporter.cs b/osu.Game/Stores/RealmArchiveModelImporter.cs index 5b8c73b218..6370d4ebe4 100644 --- a/osu.Game/Stores/RealmArchiveModelImporter.cs +++ b/osu.Game/Stores/RealmArchiveModelImporter.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Humanizer; -using NuGet.Packaging; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; From a8c4fd694fcccd257f35ec07dd83d977c70f5ce3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 23 Nov 2021 15:04:44 +0900 Subject: [PATCH 11/12] Add `BannedSymbols` entry for `NuGet.Packaging` --- CodeAnalysis/BannedSymbols.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CodeAnalysis/BannedSymbols.txt b/CodeAnalysis/BannedSymbols.txt index ea3e25142c..b72803482d 100644 --- a/CodeAnalysis/BannedSymbols.txt +++ b/CodeAnalysis/BannedSymbols.txt @@ -8,4 +8,5 @@ M:osu.Framework.Graphics.Sprites.SpriteText.#ctor;Use OsuSpriteText. M:osu.Framework.Bindables.IBindableList`1.GetBoundCopy();Fails on iOS. Use manual ctor + BindTo instead. (see https://github.com/mono/mono/issues/19900) T:Microsoft.EntityFrameworkCore.Internal.EnumerableExtensions;Don't use internal extension methods. T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods. -M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast() instead. \ No newline at end of file +T:NuGet.Packaging.CollectionExtensions;Don't use internal extension methods. +M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast() instead. From 0cf5a738dc9a0851e74d546ad155001f0e8ca646 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 23 Nov 2021 16:32:44 +0900 Subject: [PATCH 12/12] Remove unused using --- osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs index 22d9a4ff9d..db89855db7 100644 --- a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs @@ -3,7 +3,6 @@ using System.IO; using NUnit.Framework; -using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Platform; using osu.Game.Tournament.IO;