From 320c4abb66ba388bb19d04bb22b64cd4b56fa181 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 31 Jul 2022 20:13:06 -0700 Subject: [PATCH 01/34] Add failing online play non-current sub screen onexiting test --- .../Navigation/TestSceneScreenNavigation.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8fce43f9b0..7ee0998281 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -26,6 +26,7 @@ using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; using osu.Game.Screens.Menu; using osu.Game.Screens.OnlinePlay.Lounge; +using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Playlists; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; @@ -79,7 +80,25 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for return to playlist screen", () => playlistScreen.CurrentSubScreen is PlaylistsRoomSubScreen); + AddStep("go back to song select", () => + { + InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("wait for song select", () => (playlistScreen.CurrentSubScreen as PlaylistsSongSelect)?.BeatmapSetsLoaded == true); + + AddStep("press home button", () => + { + InputManager.MoveMouseTo(Game.Toolbar.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("confirmation dialog shown", () => Game.ChildrenOfType().Single().CurrentDialog is not null); + pushEscape(); + pushEscape(); + AddAssert("confirmation dialog shown", () => Game.ChildrenOfType().Single().CurrentDialog is not null); AddStep("confirm exit", () => InputManager.Key(Key.Enter)); From 1dbb2a4d376a61d744292967e077cd20eb0b7780 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 1 Aug 2022 07:52:07 -0700 Subject: [PATCH 02/34] Fix online play screen only accounting for current sub screen onexiting blocks --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 61ea7d68ee..ad52363c95 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -147,9 +147,14 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - var subScreen = screenStack.CurrentScreen as Drawable; - if (subScreen?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) - return true; + while (screenStack.CurrentScreen is not LoungeSubScreen) + { + var lastSubScreen = screenStack.CurrentScreen; + if (((Drawable)lastSubScreen)?.IsLoaded == true) + screenStack.Exit(); + + if (lastSubScreen == screenStack.CurrentScreen) return true; + } RoomManager.PartRoom(); From b6a6db1160342731d21f0da0645f1d0303461214 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 12:29:23 +0100 Subject: [PATCH 03/34] Add dynamic BPM counter to SkinEditor --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/BPMCounter.cs diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs new file mode 100644 index 0000000000..fec36f915d --- /dev/null +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -0,0 +1,52 @@ +// 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.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Localisation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Skinning; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class BPMCounter : RollingCounter, ISkinnableDrawable + { + [Resolved] + private IBindable beatmap { get; set; } = null!; + + [Resolved] + protected IGameplayClock GameplayClock { get; private set; } = null!; + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + Colour = colour.BlueLighter; + Current.Value = DisplayedCount = 0; + } + + protected override void Update() + { + base.Update(); + + //We dont want it going to 0 when we pause. so we block the updates + if (GameplayClock.IsPaused.Value) return; + + // We want to check Rate every update to cover windup/down + Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(GameplayClock.CurrentTime).BPM * GameplayClock.Rate; + } + + protected override OsuSpriteText CreateSpriteText() + => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f, fixedWidth: true)); + + protected override LocalisableString FormatCount(double count) + { + return $@"{count:0} BPM"; + } + + public bool UsesFixedAnchor { get; set; } + } +} From f69c08496931804c47c50a8197996383087547df Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 17:08:00 +0100 Subject: [PATCH 04/34] Add roll duration --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index fec36f915d..83569c13d9 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -15,6 +15,8 @@ namespace osu.Game.Screens.Play.HUD { public partial class BPMCounter : RollingCounter, ISkinnableDrawable { + protected override double RollingDuration => 750; + [Resolved] private IBindable beatmap { get; set; } = null!; From 9eef74b8d89ed7f8125af41be3e7dba840cd5f73 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 19:34:03 +0100 Subject: [PATCH 05/34] Add new counter to skin deserialisation test --- .../Archives/modified-default-20221205.osk | Bin 0 -> 1644 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221205.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221205.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221205.osk new file mode 100644 index 0000000000000000000000000000000000000000..ae421fc323baa8b1931a18e06e4d368adeb41352 GIT binary patch literal 1644 zcmWIWW@Zs#U|`^2csRQ?bn^awlY>BB5Hm=GfuT4%GfyuwFY{@?VHcC5fa_;F*O{7Y z&iNc}njtw;a_2;eDPg^4W#OLwrp@WM6Z*G=2M8(~#$S7L_;<~}-+%wD)QXUmi0Tde ztx$bqr9`)5zifh`Z$@If;XKC9841;FZ%;9-coJ>9WOCZ?2Hmpo6->DuIx{3z-PR~< zJJQzDCcHgvL&32fg{QNV%jBh^_%wc>xXaPzskx;w^U1TLe6!L&sJdT_oAZ0Mf8yVc z-1uywCWCZVC!GrLPwnazR7$l+PLO^PalbLN1&*>wnVcw2$w_kd8LP z(%_)WLf*w*CA~a7Jv=%*x=Dp6B&8&z9!@bfGUyGx#2EQ5X3DIHN%1V3>`nBo_4nKG zE4`Z;9y4i1_@tQ;lV;9;K6Cms{?di>tS@Y>I(TztW#!DumsN@e*PC2QL=w2B?8st7 zbvdKo73JrQ3=E+H3=CpGm-{AW=6Qs=IOpdUVBAW9GiaCw#S|&IoJEk%(o1>I~fDSL??x26q>phM{Ew-74tr?be;Fp11*l$ zHaz>9H#)7BbnEw*cv4r8nXqg@N!v*SjZ@K@Kg3t)eU)7?Q){VA`|mfc+YbG_S;zYO zYsK4x=1NivIgia~TN_n5^$3UkwtBP6`dgCEezE!*7gMD6(DT5y-JGJON^`aLU0wFh zL;C4#LFqvEb5ajaHT_kQODL7top#A-w&)z;tmM~6axc_qKRM+f`{Y;J6_ww?@4VOX zemN>zZXjsG^0C=S;8XB9@52>W#lKFzo>K1A*1DfT?QWUgo4xN}-2Gtt!}hh1{4eIk zSC<)7B_Fu8{lsh)f1P^Ihvj30V_@ZZ~@>AVQ{RPwiIsWwjzx0d$y!^Uf zSs%m`uHAYw<557y!a1_5R(J|Mc^@@r&*DRB-_N{TbH7owU~Smlviw#)Ux8juRoR9} znTHlj_3sEY3HfODK7RaaW$65B13s_&vp-*rKaf!U@8Br|ujPfa6D-w%ew)p(B{Bl2rwO;Voi)Z4fNuyD!{zNq}X*^(IVBiNPjo|#e z^x)K-)Z`Lynm8I9n|;VYr1pDwO6@zRTVGB$@@w6eJ2vA?p8g}}wdH0r)RuZW3jY5c zlxwclY-ld2$p2l%@_CWpyEW|>&gHbMsfcbUZPr<-RWtud!}4r37GZ6hX_bns9BV&t z2+dVL8t{6Ot`@Ih&X(R=>Sk4~L57-aEb`NOkBMFn3vsjsGqZ`LW`W`=;U=f$H{l&EfbuG28E+4RM_}%t6^3{@uE57zW zF!8mRvq?zii}S0X?T2qIh-)v=xa2eK*_QhZ{;JU%qYiUQKXGl`l`I`mcc<2SN7FXO z3%4v*zLJZ&RCw&irj}W$X75dt>`yNG_HUYVURSrfgW=a2p&eV2uWfyv_)2L01!Loa zTaVi=T#1){KgqseU+AS{J8s>L2+M3MVbe%WJ>?i1Df=~E{fqu(p;`JeErI0`ix{k* zt*=gh=Ca{Ed!9tay^|Yc9)4(g{7Et@?t_cG&;4Gt{^~6npYlJwI(r|Og&CPd7;u-e zz{rAtMi2!nbJ2C77g|s~3=ECWp}OEj7`j&UQUjrNAuz#UFGJAHKu=x>Gxh*03$(-* T;LXYgQosU)pMZ1 From fc630165fd612baa3043ff35d50651c5c8ed5d09 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Tue, 6 Dec 2022 15:08:21 +0100 Subject: [PATCH 06/34] Adjust formatting of BPM text --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 46 ++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 83569c13d9..8d3cab40b0 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -4,12 +4,15 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Skinning; +using osuTK; namespace osu.Game.Screens.Play.HUD { @@ -46,7 +49,48 @@ namespace osu.Game.Screens.Play.HUD protected override LocalisableString FormatCount(double count) { - return $@"{count:0} BPM"; + return $@"{count:0}"; + } + + protected override IHasText CreateText() => new TextComponent(); + + private partial class TextComponent : CompositeDrawable, IHasText + { + public LocalisableString Text + { + get => text.Text; + set => text.Text = value; + } + + private readonly OsuSpriteText text; + + public TextComponent() + { + AutoSizeAxes = Axes.Both; + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(2), + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.Numeric.With(size: 16, fixedWidth: true) + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.Numeric.With(size: 8, fixedWidth: true), + Text = @"BPM", + Padding = new MarginPadding { Bottom = 1.5f }, // align baseline better + } + } + }; + } } public bool UsesFixedAnchor { get; set; } From b06a7daf26e3656e10346b2059aa0800bab00cdb Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Tue, 20 Dec 2022 23:40:00 +0000 Subject: [PATCH 07/34] append date to score export filename --- osu.Game/Scoring/ScoreInfoExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/ScoreInfoExtensions.cs b/osu.Game/Scoring/ScoreInfoExtensions.cs index 7979ca8aaa..3cfdbe87c3 100644 --- a/osu.Game/Scoring/ScoreInfoExtensions.cs +++ b/osu.Game/Scoring/ScoreInfoExtensions.cs @@ -12,6 +12,6 @@ namespace osu.Game.Scoring /// /// A user-presentable display title representing this score. /// - public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()}"; + public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()} ({scoreInfo.Date.LocalDateTime:yyyy-MM-dd})"; } } From 498d00935bff763f0d5a7fcb5344f177e510ddb6 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Fri, 23 Dec 2022 23:01:04 +0000 Subject: [PATCH 08/34] limit date appending to `LegacyScoreExporter` only --- osu.Game/Database/LegacyExporter.cs | 2 +- osu.Game/Database/LegacyScoreExporter.cs | 20 ++++++++++++++++++++ osu.Game/Scoring/ScoreInfoExtensions.cs | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 374f9f557a..02219c4dfa 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Database /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public void Export(TModel item) + public virtual void Export(TModel item) { string itemFilename = item.GetDisplayString().GetValidFilename(); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 6fa02b957d..fc80693765 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -3,11 +3,13 @@ #nullable disable +using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; +using osu.Game.Utils; namespace osu.Game.Database { @@ -15,9 +17,27 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; + private readonly Storage exportStorage; + public LegacyScoreExporter(Storage storage) : base(storage) { + exportStorage = storage.GetStorageForDirectory(@"exports"); + } + + private string GetScoreExportString(ScoreInfo score) => $"{score.GetDisplayString()} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + + public override void Export(ScoreInfo score) + { + string scoreExportTitle = GetScoreExportString(score).GetValidFilename(); + + IEnumerable existingExports = exportStorage.GetFiles("", $"{scoreExportTitle}*{FileExtension}"); + + string scoreExportFilename = NamingUtils.GetNextBestFilename(existingExports, $"{scoreExportTitle}{FileExtension}"); + using (var stream = exportStorage.CreateFileSafely(scoreExportFilename)) + ExportModelTo(score, stream); + + exportStorage.PresentFileExternally(scoreExportFilename); } public override void ExportModelTo(ScoreInfo model, Stream outputStream) diff --git a/osu.Game/Scoring/ScoreInfoExtensions.cs b/osu.Game/Scoring/ScoreInfoExtensions.cs index 3cfdbe87c3..7979ca8aaa 100644 --- a/osu.Game/Scoring/ScoreInfoExtensions.cs +++ b/osu.Game/Scoring/ScoreInfoExtensions.cs @@ -12,6 +12,6 @@ namespace osu.Game.Scoring /// /// A user-presentable display title representing this score. /// - public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()} ({scoreInfo.Date.LocalDateTime:yyyy-MM-dd})"; + public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()}"; } } From d392d1a5c08daa0d3f857e75f1d18fbbb160138c Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sat, 24 Dec 2022 22:18:42 +0000 Subject: [PATCH 09/34] override a sub-method instead of the whole `Export()` --- osu.Game/Database/LegacyExporter.cs | 10 +++++----- osu.Game/Database/LegacyScoreExporter.cs | 22 +++++----------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 02219c4dfa..3f305fb420 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -33,17 +33,17 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } + protected virtual string GetItemExportString(TModel item) => item.GetDisplayString().GetValidFilename(); + /// /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public virtual void Export(TModel item) + public void Export(TModel item) { - string itemFilename = item.GetDisplayString().GetValidFilename(); + IEnumerable existingExports = exportStorage.GetFiles("", $"{GetItemExportString(item)}*{FileExtension}"); - IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{GetItemExportString(item)}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index fc80693765..e176449fd0 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -3,13 +3,11 @@ #nullable disable -using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; -using osu.Game.Utils; namespace osu.Game.Database { @@ -17,27 +15,17 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; - private readonly Storage exportStorage; - public LegacyScoreExporter(Storage storage) : base(storage) { - exportStorage = storage.GetStorageForDirectory(@"exports"); } - private string GetScoreExportString(ScoreInfo score) => $"{score.GetDisplayString()} ({score.Date.LocalDateTime:yyyy-MM-dd})"; - - public override void Export(ScoreInfo score) + protected override string GetItemExportString(ScoreInfo score) { - string scoreExportTitle = GetScoreExportString(score).GetValidFilename(); - - IEnumerable existingExports = exportStorage.GetFiles("", $"{scoreExportTitle}*{FileExtension}"); - - string scoreExportFilename = NamingUtils.GetNextBestFilename(existingExports, $"{scoreExportTitle}{FileExtension}"); - using (var stream = exportStorage.CreateFileSafely(scoreExportFilename)) - ExportModelTo(score, stream); - - exportStorage.PresentFileExternally(scoreExportFilename); + string scoreString = score.GetDisplayString(); + string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + + return filename.GetValidFilename(); } public override void ExportModelTo(ScoreInfo model, Stream outputStream) From 5232588a1f07529814a36439880585db96b225bd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 20:04:45 -0800 Subject: [PATCH 10/34] Use `PerformFromScreen` to exit sub screens instead --- .../Navigation/TestSceneScreenNavigation.cs | 2 +- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 89cd766842..66c4cf8686 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("go back to song select", () => { - InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); + InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); InputManager.Click(MouseButton.Left); }); diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index ff888710fe..4a3549b33e 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -45,6 +45,9 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] protected IAPIProvider API { get; private set; } + [Resolved(canBeNull: true)] + private IPerformFromScreenRunner performer { get; set; } + protected OnlinePlayScreen() { Anchor = Anchor.Centre; @@ -148,13 +151,17 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - while (screenStack.CurrentScreen is not LoungeSubScreen) + if (screenStack.CurrentScreen is not LoungeSubScreen) { - var lastSubScreen = screenStack.CurrentScreen; - if (((Drawable)lastSubScreen)?.IsLoaded == true) - screenStack.Exit(); + if (performer != null) + { + performer.PerformFromScreen(_ => e.Destination.MakeCurrent(), new[] { typeof(LoungeSubScreen) }); + return true; + } - if (lastSubScreen == screenStack.CurrentScreen) return true; + // TODO: make isolated tests work with IPerformFromScreenRunner + if ((screenStack.CurrentScreen as Drawable)?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) + return true; } RoomManager.PartRoom(); From 272288c9aa2e6b8a04be72392960ab9fe33ae3a0 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sun, 25 Dec 2022 21:50:56 +0000 Subject: [PATCH 11/34] fix code style and naming --- osu.Game/Database/LegacyExporter.cs | 8 +++++--- osu.Game/Database/LegacyScoreExporter.cs | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 3f305fb420..09d6913dd9 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -33,7 +33,7 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } - protected virtual string GetItemExportString(TModel item) => item.GetDisplayString().GetValidFilename(); + protected virtual string GetFilename(TModel item) => item.GetDisplayString(); /// /// Exports an item to a legacy (.zip based) package. @@ -41,9 +41,11 @@ namespace osu.Game.Database /// The item to export. public void Export(TModel item) { - IEnumerable existingExports = exportStorage.GetFiles("", $"{GetItemExportString(item)}*{FileExtension}"); + string itemFilename = GetFilename(item).GetValidFilename(); - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{GetItemExportString(item)}{FileExtension}"); + IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); + + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index e176449fd0..7c0ba7c6ee 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -20,12 +20,12 @@ namespace osu.Game.Database { } - protected override string GetItemExportString(ScoreInfo score) + protected override string GetFilename(ScoreInfo score) { string scoreString = score.GetDisplayString(); string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; - - return filename.GetValidFilename(); + + return filename; } public override void ExportModelTo(ScoreInfo model, Stream outputStream) From 0dba25e0abce94fe01ead03dfc30e511f511c8b0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 21:56:22 -0800 Subject: [PATCH 12/34] Refactor to just exit sub screens until lounge sub screen Co-Authored-By: Salman Ahmed --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 4a3549b33e..3d80248306 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -45,9 +45,6 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] protected IAPIProvider API { get; private set; } - [Resolved(canBeNull: true)] - private IPerformFromScreenRunner performer { get; set; } - protected OnlinePlayScreen() { Anchor = Anchor.Centre; @@ -151,17 +148,13 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - if (screenStack.CurrentScreen is not LoungeSubScreen) + while (screenStack.CurrentScreen != null && screenStack.CurrentScreen is not LoungeSubScreen) { - if (performer != null) - { - performer.PerformFromScreen(_ => e.Destination.MakeCurrent(), new[] { typeof(LoungeSubScreen) }); + var subScreen = (Screen)screenStack.CurrentScreen; + if (subScreen.IsLoaded && subScreen.OnExiting(e)) return true; - } - // TODO: make isolated tests work with IPerformFromScreenRunner - if ((screenStack.CurrentScreen as Drawable)?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) - return true; + subScreen.Exit(); } RoomManager.PartRoom(); From 13c3d2c25444aae1e3c1de607fc566659781a01f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:15:30 +0900 Subject: [PATCH 13/34] Fix retry loop for channel initialisation resulting in request pile-up Closes #22060. --- osu.Game/Online/Chat/ChannelManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 5d55374373..9741341efc 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -335,6 +335,11 @@ namespace osu.Game.Online.Chat private void initializeChannels() { + // This request is self-retrying until it succeeds. + // To avoid requests piling up when not logged in (ie. API is unavailable) exit early. + if (api.IsLoggedIn) + return; + var req = new ListChannelsRequest(); bool joinDefaults = JoinedChannels.Count == 0; @@ -350,10 +355,11 @@ namespace osu.Game.Online.Chat joinChannel(ch); } }; + req.Failure += error => { Logger.Error(error, "Fetching channel list failed"); - initializeChannels(); + Scheduler.AddDelayed(initializeChannels, 60000); }; api.Queue(req); From 22d0b34623536c46634982a02e102907b45e22a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:38:37 +0900 Subject: [PATCH 14/34] Remove flag causing intiialisation to only run once ever --- osu.Game/Online/Chat/ChannelManager.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 9741341efc..26ab9e87ba 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -71,7 +71,6 @@ namespace osu.Game.Online.Chat private UserLookupCache users { get; set; } private readonly IBindable apiState = new Bindable(); - private bool channelsInitialised; private ScheduledDelegate scheduledAck; private long? lastSilenceMessageId; @@ -95,15 +94,7 @@ namespace osu.Game.Online.Chat connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); - connector.PresenceReceived += () => Schedule(() => - { - if (!channelsInitialised) - { - channelsInitialised = true; - // we want this to run after the first presence so we can see if the user is in any channels already. - initializeChannels(); - } - }); + connector.PresenceReceived += () => Schedule(initializeChannels); connector.Start(); From 62ffb4fe78c30da147b82757a5c0d3acfb08a3b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 18:54:11 +0900 Subject: [PATCH 15/34] Pause imports during active gameplay --- osu.Game/Beatmaps/BeatmapManager.cs | 4 +++- osu.Game/Database/ModelManager.cs | 6 +++++ .../Database/RealmArchiveModelImporter.cs | 24 ++++++++++++++++++- osu.Game/OsuGame.cs | 4 ++++ osu.Game/Scoring/ScoreManager.cs | 2 ++ osu.Game/Skinning/SkinManager.cs | 2 ++ 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f0533f27be..623a657cd0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -62,6 +62,7 @@ namespace osu.Game.Beatmaps BeatmapTrackStore = audioManager.GetTrackStore(userResources); beatmapImporter = CreateBeatmapImporter(storage, realm); + beatmapImporter.PauseImports.BindTo(PauseImports); beatmapImporter.ProcessBeatmap = args => ProcessBeatmap?.Invoke(args); beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); @@ -458,7 +459,8 @@ namespace osu.Game.Beatmaps public Task Import(ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(tasks, parameters); - public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(notification, tasks, parameters); + public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => + beatmapImporter.Import(notification, tasks, parameters); public Task?> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) => beatmapImporter.Import(task, parameters, cancellationToken); diff --git a/osu.Game/Database/ModelManager.cs b/osu.Game/Database/ModelManager.cs index 5c106aa493..9a88bd5646 100644 --- a/osu.Game/Database/ModelManager.cs +++ b/osu.Game/Database/ModelManager.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Extensions; @@ -18,6 +19,11 @@ namespace osu.Game.Database public class ModelManager : IModelManager, IModelFileManager where TModel : RealmObject, IHasRealmFiles, IHasGuidPrimaryKey, ISoftDelete { + /// + /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. + /// + public readonly BindableBool PauseImports = new BindableBool(); + protected RealmAccess Realm { get; } private readonly RealmFileStore realmFileStore; diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 4e8b27e0b4..cd86a5a94c 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Humanizer; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; @@ -56,6 +57,11 @@ namespace osu.Game.Database /// private static readonly ThreadedTaskScheduler import_scheduler_batch = new ThreadedTaskScheduler(import_queue_request_concurrency, nameof(RealmArchiveModelImporter)); + /// + /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. + /// + public readonly BindableBool PauseImports = new BindableBool(); + public abstract IEnumerable HandledExtensions { get; } protected readonly RealmFileStore Files; @@ -253,7 +259,7 @@ namespace osu.Game.Database /// An optional cancellation token. public virtual Live? ImportModel(TModel item, ArchiveReader? archive = null, ImportParameters parameters = default, CancellationToken cancellationToken = default) => Realm.Run(realm => { - cancellationToken.ThrowIfCancellationRequested(); + pauseIfNecessary(cancellationToken); TModel? existing; @@ -551,6 +557,22 @@ namespace osu.Game.Database /// Whether to perform deletion. protected virtual bool ShouldDeleteArchive(string path) => false; + private void pauseIfNecessary(CancellationToken cancellationToken) + { + if (!PauseImports.Value) + return; + + Logger.Log(@"Import is being paused."); + + while (PauseImports.Value) + { + cancellationToken.ThrowIfCancellationRequested(); + Thread.Sleep(500); + } + + Logger.Log(@"Import is being resumed."); + } + private IEnumerable getIDs(IEnumerable files) { foreach (var f in files.OrderBy(f => f.Filename)) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6efa3c4172..27152743f8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,6 +307,10 @@ namespace osu.Game // Transfer any runtime changes back to configuration file. SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString(); + BeatmapManager.PauseImports.BindTo(LocalUserPlaying); + SkinManager.PauseImports.BindTo(LocalUserPlaying); + ScoreManager.PauseImports.BindTo(LocalUserPlaying); + IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 5ec96a951b..0852ab43f4 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -38,6 +38,8 @@ namespace osu.Game.Scoring { PostNotification = obj => PostNotification?.Invoke(obj) }; + + scoreImporter.PauseImports.BindTo(PauseImports); } public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index f750bfad8a..a0e7037d6d 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -79,6 +79,8 @@ namespace osu.Game.Skinning PostNotification = obj => PostNotification?.Invoke(obj), }; + skinImporter.PauseImports.BindTo(PauseImports); + var defaultSkins = new[] { DefaultClassicSkin = new DefaultLegacySkin(this), From 811a5626084e86a5fb47d002c2dc89f1f1b98012 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 01:10:20 +0900 Subject: [PATCH 16/34] Don't use bindables to avoid potential cross-usage contamination --- osu.Game/Beatmaps/BeatmapManager.cs | 11 ++++++++++- osu.Game/Database/ModelManager.cs | 3 +-- osu.Game/Database/RealmArchiveModelImporter.cs | 7 +++---- osu.Game/OsuGame.cs | 9 ++++++--- osu.Game/Scoring/ScoreManager.cs | 12 ++++++++++-- osu.Game/Skinning/SkinManager.cs | 12 ++++++++++-- 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 623a657cd0..eafd1e96e8 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -44,6 +44,16 @@ namespace osu.Game.Beatmaps public Action<(BeatmapSetInfo beatmapSet, bool isBatch)>? ProcessBeatmap { private get; set; } + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + beatmapImporter.PauseImports = value; + } + } + public BeatmapManager(Storage storage, RealmAccess realm, IAPIProvider? api, AudioManager audioManager, IResourceStore gameResources, GameHost? host = null, WorkingBeatmap? defaultBeatmap = null, BeatmapDifficultyCache? difficultyCache = null, bool performOnlineLookups = false) : base(storage, realm) @@ -62,7 +72,6 @@ namespace osu.Game.Beatmaps BeatmapTrackStore = audioManager.GetTrackStore(userResources); beatmapImporter = CreateBeatmapImporter(storage, realm); - beatmapImporter.PauseImports.BindTo(PauseImports); beatmapImporter.ProcessBeatmap = args => ProcessBeatmap?.Invoke(args); beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); diff --git a/osu.Game/Database/ModelManager.cs b/osu.Game/Database/ModelManager.cs index 9a88bd5646..7d1dc5239a 100644 --- a/osu.Game/Database/ModelManager.cs +++ b/osu.Game/Database/ModelManager.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using osu.Framework.Bindables; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Extensions; @@ -22,7 +21,7 @@ namespace osu.Game.Database /// /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. /// - public readonly BindableBool PauseImports = new BindableBool(); + public virtual bool PauseImports { get; set; } protected RealmAccess Realm { get; } diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index cd86a5a94c..1fe1569d36 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Humanizer; -using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; @@ -60,7 +59,7 @@ namespace osu.Game.Database /// /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. /// - public readonly BindableBool PauseImports = new BindableBool(); + public bool PauseImports { get; set; } public abstract IEnumerable HandledExtensions { get; } @@ -559,12 +558,12 @@ namespace osu.Game.Database private void pauseIfNecessary(CancellationToken cancellationToken) { - if (!PauseImports.Value) + if (!PauseImports) return; Logger.Log(@"Import is being paused."); - while (PauseImports.Value) + while (PauseImports) { cancellationToken.ThrowIfCancellationRequested(); Thread.Sleep(500); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 27152743f8..dc4d56de11 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,9 +307,12 @@ namespace osu.Game // Transfer any runtime changes back to configuration file. SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString(); - BeatmapManager.PauseImports.BindTo(LocalUserPlaying); - SkinManager.PauseImports.BindTo(LocalUserPlaying); - ScoreManager.PauseImports.BindTo(LocalUserPlaying); + LocalUserPlaying.BindValueChanged(p => + { + BeatmapManager.PauseImports = p.NewValue; + SkinManager.PauseImports = p.NewValue; + ScoreManager.PauseImports = p.NewValue; + }, true); IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 0852ab43f4..3217c79768 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -28,6 +28,16 @@ namespace osu.Game.Scoring private readonly OsuConfigManager configManager; private readonly ScoreImporter scoreImporter; + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + scoreImporter.PauseImports = value; + } + } + public ScoreManager(RulesetStore rulesets, Func beatmaps, Storage storage, RealmAccess realm, IAPIProvider api, OsuConfigManager configManager = null) : base(storage, realm) @@ -38,8 +48,6 @@ namespace osu.Game.Scoring { PostNotification = obj => PostNotification?.Invoke(obj) }; - - scoreImporter.PauseImports.BindTo(PauseImports); } public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index a0e7037d6d..a4cf83b32e 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -64,6 +64,16 @@ namespace osu.Game.Skinning private Skin trianglesSkin { get; } + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + skinImporter.PauseImports = value; + } + } + public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore resources, AudioManager audio, Scheduler scheduler) : base(storage, realm) { @@ -79,8 +89,6 @@ namespace osu.Game.Skinning PostNotification = obj => PostNotification?.Invoke(obj), }; - skinImporter.PauseImports.BindTo(PauseImports); - var defaultSkins = new[] { DefaultClassicSkin = new DefaultLegacySkin(this), From e35f63c001704e6914e1925955b4ddae4b0731c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 01:37:16 +0900 Subject: [PATCH 17/34] Ensure screenshot filenames are unique by locking over file creation --- osu.Game/Graphics/ScreenshotManager.cs | 40 +++++++++++++++----------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 29e9b0276c..d799e82bc9 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.IO; using System.Threading; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -117,11 +118,11 @@ namespace osu.Game.Graphics host.GetClipboard()?.SetImage(image); - string filename = getFilename(); + (string filename, var stream) = getWritableStream(); if (filename == null) return; - using (var stream = storage.CreateFileSafely(filename)) + using (stream) { switch (screenshotFormat.Value) { @@ -142,7 +143,7 @@ namespace osu.Game.Graphics notificationOverlay.Post(new SimpleNotification { - Text = $"{filename} saved!", + Text = $"Screenshot {filename} saved!", Activated = () => { storage.PresentFileExternally(filename); @@ -152,23 +153,28 @@ namespace osu.Game.Graphics } }); - private string getFilename() + private static readonly object filename_reservation_lock = new object(); + + private (string filename, Stream stream) getWritableStream() { - var dt = DateTime.Now; - string fileExt = screenshotFormat.ToString().ToLowerInvariant(); - - string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}"; - if (!storage.Exists(withoutIndex)) - return withoutIndex; - - for (ulong i = 1; i < ulong.MaxValue; i++) + lock (filename_reservation_lock) { - string indexedName = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}-{i}.{fileExt}"; - if (!storage.Exists(indexedName)) - return indexedName; - } + var dt = DateTime.Now; + string fileExt = screenshotFormat.ToString().ToLowerInvariant(); - return null; + string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}"; + if (!storage.Exists(withoutIndex)) + return (withoutIndex, storage.GetStream(withoutIndex, FileAccess.Write, FileMode.Create)); + + for (ulong i = 1; i < ulong.MaxValue; i++) + { + string indexedName = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}-{i}.{fileExt}"; + if (!storage.Exists(indexedName)) + return (indexedName, storage.GetStream(indexedName, FileAccess.Write, FileMode.Create)); + } + + return (null, null); + } } } } From a1fbfe4b8b6da1f3f7ff8415e71306ae897b13f7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 19:53:41 +0300 Subject: [PATCH 18/34] Specifiy importer name during pause/resume in logs --- osu.Game/Database/RealmArchiveModelImporter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 1fe1569d36..1ea97ba718 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -561,7 +561,7 @@ namespace osu.Game.Database if (!PauseImports) return; - Logger.Log(@"Import is being paused."); + Logger.Log($@"{GetType().Name} is being paused."); while (PauseImports) { @@ -569,7 +569,7 @@ namespace osu.Game.Database Thread.Sleep(500); } - Logger.Log(@"Import is being resumed."); + Logger.Log($@"{GetType().Name} is being resumed."); } private IEnumerable getIDs(IEnumerable files) From 8a052235916ff3b532b515b12c04f62457eab686 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 20:07:46 +0300 Subject: [PATCH 19/34] Check cancellation token if importer was resumed while sleeping --- osu.Game/Database/RealmArchiveModelImporter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 1ea97ba718..d107a6a605 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -569,6 +569,7 @@ namespace osu.Game.Database Thread.Sleep(500); } + cancellationToken.ThrowIfCancellationRequested(); Logger.Log($@"{GetType().Name} is being resumed."); } From d6f60db234d0d4e632f911d2ef2a220d798cf70f Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 18:51:51 +0100 Subject: [PATCH 20/34] Add the ability to toggle the visibility of the main bar in BarHitErrorMeter.cs --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index eeca2be7cd..d1b79afe35 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -42,6 +42,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); + [SettingSource("Bar visibility")] + public Bindable BarVisibility { get; } = new Bindable(true); + private const int judgement_line_width = 14; private const int max_concurrent_judgements = 50; @@ -178,6 +181,11 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters CentreMarkerStyle.BindValueChanged(style => recreateCentreMarker(style.NewValue), true); LabelStyle.BindValueChanged(style => recreateLabels(style.NewValue), true); + BarVisibility.BindValueChanged(visible => + { + colourBarsEarly.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); + colourBarsLate.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); + }, true); // delay the appearance animations for only the initial appearance. using (arrowContainer.BeginDelayedSequence(450)) From dbc19777e02120b1362886deec24adf3b7c8fe9c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 21:17:40 +0300 Subject: [PATCH 21/34] Move stable import buttons under "debug" section --- .../MaintenanceSettingsStrings.cs | 20 ------ .../Settings/Sections/DebugSection.cs | 12 ++-- .../DebugSettings/BatchImportSettings.cs | 66 +++++++++++++++++++ .../Sections/Maintenance/BeatmapSettings.cs | 17 +---- .../Maintenance/CollectionsSettings.cs | 17 +---- .../Sections/Maintenance/ScoreSettings.cs | 17 +---- .../Sections/Maintenance/SkinSettings.cs | 17 +---- 7 files changed, 77 insertions(+), 89 deletions(-) create mode 100644 osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs diff --git a/osu.Game/Localisation/MaintenanceSettingsStrings.cs b/osu.Game/Localisation/MaintenanceSettingsStrings.cs index 8aa0adf7a0..469f565f1e 100644 --- a/osu.Game/Localisation/MaintenanceSettingsStrings.cs +++ b/osu.Game/Localisation/MaintenanceSettingsStrings.cs @@ -54,11 +54,6 @@ namespace osu.Game.Localisation /// public static LocalisableString RestartAndReOpenRequiredForCompletion => new TranslatableString(getKey(@"restart_and_re_open_required_for_completion"), @"To complete this operation, osu! will close. Please open it again to use the new data location."); - /// - /// "Import beatmaps from stable" - /// - public static LocalisableString ImportBeatmapsFromStable => new TranslatableString(getKey(@"import_beatmaps_from_stable"), @"Import beatmaps from stable"); - /// /// "Delete ALL beatmaps" /// @@ -69,31 +64,16 @@ namespace osu.Game.Localisation /// public static LocalisableString DeleteAllBeatmapVideos => new TranslatableString(getKey(@"delete_all_beatmap_videos"), @"Delete ALL beatmap videos"); - /// - /// "Import scores from stable" - /// - public static LocalisableString ImportScoresFromStable => new TranslatableString(getKey(@"import_scores_from_stable"), @"Import scores from stable"); - /// /// "Delete ALL scores" /// public static LocalisableString DeleteAllScores => new TranslatableString(getKey(@"delete_all_scores"), @"Delete ALL scores"); - /// - /// "Import skins from stable" - /// - public static LocalisableString ImportSkinsFromStable => new TranslatableString(getKey(@"import_skins_from_stable"), @"Import skins from stable"); - /// /// "Delete ALL skins" /// public static LocalisableString DeleteAllSkins => new TranslatableString(getKey(@"delete_all_skins"), @"Delete ALL skins"); - /// - /// "Import collections from stable" - /// - public static LocalisableString ImportCollectionsFromStable => new TranslatableString(getKey(@"import_collections_from_stable"), @"Import collections from stable"); - /// /// "Delete ALL collections" /// diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index 2594962314..509410fbb1 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -3,6 +3,7 @@ #nullable disable +using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; @@ -22,11 +23,12 @@ namespace osu.Game.Overlays.Settings.Sections public DebugSection() { - Children = new Drawable[] - { - new GeneralSettings(), - new MemorySettings(), - }; + Add(new GeneralSettings()); + + if (DebugUtils.IsDebugBuild) + Add(new BatchImportSettings()); + + Add(new MemorySettings()); } } } diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs new file mode 100644 index 0000000000..1c17356313 --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs @@ -0,0 +1,66 @@ +// 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.Localisation; +using osu.Game.Database; + +namespace osu.Game.Overlays.Settings.Sections.DebugSettings +{ + public partial class BatchImportSettings : SettingsSubsection + { + protected override LocalisableString Header => @"Batch Import"; + + private SettingsButton importBeatmapsButton = null!; + private SettingsButton importCollectionsButton = null!; + private SettingsButton importScoresButton = null!; + private SettingsButton importSkinsButton = null!; + + [BackgroundDependencyLoader] + private void load(LegacyImportManager? legacyImportManager) + { + if (legacyImportManager?.SupportsImportFromStable != true) + return; + + AddRange(new[] + { + importBeatmapsButton = new SettingsButton + { + Text = @"Import beatmaps from stable", + Action = () => + { + importBeatmapsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(_ => Schedule(() => importBeatmapsButton.Enabled.Value = true)); + } + }, + importSkinsButton = new SettingsButton + { + Text = @"Import skins from stable", + Action = () => + { + importSkinsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(_ => Schedule(() => importSkinsButton.Enabled.Value = true)); + } + }, + importCollectionsButton = new SettingsButton + { + Text = @"Import collections from stable", + Action = () => + { + importCollectionsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(_ => Schedule(() => importCollectionsButton.Enabled.Value = true)); + } + }, + importScoresButton = new SettingsButton + { + Text = @"Import scores from stable", + Action = () => + { + importScoresButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Scores).ContinueWith(_ => Schedule(() => importScoresButton.Enabled.Value = true)); + } + }, + }); + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs index 9c0b86c862..4b1836ed86 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs @@ -6,7 +6,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Beatmaps; -using osu.Game.Database; using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Maintenance @@ -15,28 +14,14 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Beatmaps; - private SettingsButton importBeatmapsButton = null!; private SettingsButton deleteBeatmapsButton = null!; private SettingsButton deleteBeatmapVideosButton = null!; private SettingsButton restoreButton = null!; private SettingsButton undeleteButton = null!; [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(BeatmapManager beatmaps, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importBeatmapsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportBeatmapsFromStable, - Action = () => - { - importBeatmapsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(_ => Schedule(() => importBeatmapsButton.Enabled.Value = true)); - } - }); - } - Add(deleteBeatmapsButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllBeatmaps, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs index 4da5aaf492..09acc22c25 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs @@ -14,8 +14,6 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Collections; - private SettingsButton importCollectionsButton = null!; - [Resolved] private RealmAccess realm { get; set; } = null!; @@ -23,21 +21,8 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance private INotificationOverlay? notificationOverlay { get; set; } [BackgroundDependencyLoader] - private void load(LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importCollectionsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportCollectionsFromStable, - Action = () => - { - importCollectionsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(_ => Schedule(() => importCollectionsButton.Enabled.Value = true)); - } - }); - } - Add(new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllCollections, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs index 1f09854843..c6f4f1e1a5 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Game.Database; using osu.Game.Localisation; using osu.Game.Scoring; @@ -14,25 +13,11 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Scores; - private SettingsButton importScoresButton = null!; private SettingsButton deleteScoresButton = null!; [BackgroundDependencyLoader] - private void load(ScoreManager scores, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(ScoreManager scores, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importScoresButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportScoresFromStable, - Action = () => - { - importScoresButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Scores).ContinueWith(_ => Schedule(() => importScoresButton.Enabled.Value = true)); - } - }); - } - Add(deleteScoresButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllScores, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs index e4185fe6c2..c3ac49af6d 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Game.Database; using osu.Game.Localisation; using osu.Game.Skinning; @@ -14,25 +13,11 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Skins; - private SettingsButton importSkinsButton = null!; private SettingsButton deleteSkinsButton = null!; [BackgroundDependencyLoader] - private void load(SkinManager skins, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(SkinManager skins, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importSkinsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportSkinsFromStable, - Action = () => - { - importSkinsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(_ => Schedule(() => importSkinsButton.Enabled.Value = true)); - } - }); - } - Add(deleteSkinsButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllSkins, From 98390ea2a86b8eedadac75605a43f6ac316b4088 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 21:33:04 +0300 Subject: [PATCH 22/34] Fix condition flipped --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 26ab9e87ba..1e3921bac0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -328,7 +328,7 @@ namespace osu.Game.Online.Chat { // This request is self-retrying until it succeeds. // To avoid requests piling up when not logged in (ie. API is unavailable) exit early. - if (api.IsLoggedIn) + if (!api.IsLoggedIn) return; var req = new ListChannelsRequest(); From 602062f011e42531dc78f79b3ba099145607dd80 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 21:04:51 +0100 Subject: [PATCH 23/34] Address unclear naming issue --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index d1b79afe35..2907695ce7 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -42,8 +42,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); - [SettingSource("Bar visibility")] - public Bindable BarVisibility { get; } = new Bindable(true); + [SettingSource("Show colour bars")] + public Bindable ColourBarVisibility { get; } = new Bindable(true); private const int judgement_line_width = 14; @@ -181,7 +181,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters CentreMarkerStyle.BindValueChanged(style => recreateCentreMarker(style.NewValue), true); LabelStyle.BindValueChanged(style => recreateLabels(style.NewValue), true); - BarVisibility.BindValueChanged(visible => + ColourBarVisibility.BindValueChanged(visible => { colourBarsEarly.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); colourBarsLate.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); From f216d7264b2f10500023ec97a4348884f662af5a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 22:51:38 +0300 Subject: [PATCH 24/34] Improve missing beatmap failure logging on score import --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 13 +++++++++---- osu.Game/Scoring/ScoreImporter.cs | 10 ++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index 15ed992c3e..a507bb73c6 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; @@ -46,10 +47,12 @@ namespace osu.Game.Scoring.Legacy score.ScoreInfo = scoreInfo; int version = sr.ReadInt32(); + string beatmapHash = sr.ReadString(); + + workingBeatmap = GetBeatmap(beatmapHash); - workingBeatmap = GetBeatmap(sr.ReadString()); if (workingBeatmap is DummyWorkingBeatmap) - throw new BeatmapNotFoundException(); + throw new BeatmapNotFoundException(beatmapHash); scoreInfo.User = new APIUser { Username = sr.ReadString() }; @@ -334,9 +337,11 @@ namespace osu.Game.Scoring.Legacy public class BeatmapNotFoundException : Exception { - public BeatmapNotFoundException() - : base("No corresponding beatmap for the score could be found.") + public string Hash { get; } + + public BeatmapNotFoundException(string hash) { + Hash = hash; } } } diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index a3d7fe5de0..d63741e73b 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Newtonsoft.Json; +using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -17,6 +18,7 @@ using osu.Game.Scoring.Legacy; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using Realms; @@ -44,7 +46,9 @@ namespace osu.Game.Scoring protected override ScoreInfo? CreateModel(ArchiveReader archive) { - using (var stream = archive.GetStream(archive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase)))) + string name = archive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase)); + + using (var stream = archive.GetStream(name)) { try { @@ -52,7 +56,9 @@ namespace osu.Game.Scoring } catch (LegacyScoreDecoder.BeatmapNotFoundException e) { - Logger.Log(e.Message, LoggingTarget.Information, LogLevel.Error); + Logger.Log($@"Score '{name}' failed to import: no corresponding beatmap with the hash '{e.Hash}' could be found.", LoggingTarget.Database); + Logger.Log($@"Score '{name}' failed to import due to missing beatmap. Check database logs for more info.", LoggingTarget.Information, LogLevel.Error); + return null; } } From 20ed337ea863ce2288340f8c4fde5043e29bae82 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 23:25:52 +0300 Subject: [PATCH 25/34] Remove unused using directive --- osu.Game/Scoring/ScoreImporter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index d63741e73b..2dfd461eb9 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Newtonsoft.Json; -using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -18,7 +17,6 @@ using osu.Game.Scoring.Legacy; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; -using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using Realms; From e6479b73ded35cc109627f9bcffbbc7b8ac3c676 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 23:43:35 +0300 Subject: [PATCH 26/34] Remove one more unused using directive --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index a507bb73c6..6f0b0c62f8 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json; -using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; From f971405c8c3978d6603461316f3d37ec8be105c6 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Tue, 10 Jan 2023 00:02:31 +0000 Subject: [PATCH 27/34] append time as well --- osu.Game/Database/LegacyScoreExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 7c0ba7c6ee..01f9afdc86 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -23,7 +23,7 @@ namespace osu.Game.Database protected override string GetFilename(ScoreInfo score) { string scoreString = score.GetDisplayString(); - string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd_HH-mm})"; return filename; } From 63ce5787e7525ac0d73c3291f283946e20296f2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:06:45 +0900 Subject: [PATCH 28/34] Start bars invisible --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 2907695ce7..17d07ce16c 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -111,6 +111,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Origin = Anchor.TopCentre, Width = bar_width, RelativeSizeAxes = Axes.Y, + Alpha = 0, Height = 0.5f, Scale = new Vector2(1, -1), }, @@ -118,6 +119,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, + Alpha = 0, Width = bar_width, RelativeSizeAxes = Axes.Y, Height = 0.5f, From 3c93d0551cf4c13479fc41d6bfdee64825b5e30a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:07:15 +0900 Subject: [PATCH 29/34] Move setting up to be in line with other toggle --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 17d07ce16c..0337f66bd9 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -33,6 +33,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Precision = 0.1f, }; + [SettingSource("Show colour bars")] + public Bindable ColourBarVisibility { get; } = new Bindable(true); + [SettingSource("Show moving average arrow", "Whether an arrow should move beneath the bar showing the average error.")] public Bindable ShowMovingAverage { get; } = new BindableBool(true); @@ -42,9 +45,6 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); - [SettingSource("Show colour bars")] - public Bindable ColourBarVisibility { get; } = new Bindable(true); - private const int judgement_line_width = 14; private const int max_concurrent_judgements = 50; From 85f542c3a80a88ddc258b302ac5403b8d99c5e37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:15:08 +0900 Subject: [PATCH 30/34] Make `GameplayClock` `private` --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 8d3cab40b0..b9f5deacb0 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD private IBindable beatmap { get; set; } = null!; [Resolved] - protected IGameplayClock GameplayClock { get; private set; } = null!; + private IGameplayClock gameplayClock { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colour) @@ -38,10 +38,10 @@ namespace osu.Game.Screens.Play.HUD base.Update(); //We dont want it going to 0 when we pause. so we block the updates - if (GameplayClock.IsPaused.Value) return; + if (gameplayClock.IsPaused.Value) return; // We want to check Rate every update to cover windup/down - Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(GameplayClock.CurrentTime).BPM * GameplayClock.Rate; + Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(gameplayClock.CurrentTime).BPM * gameplayClock.Rate; } protected override OsuSpriteText CreateSpriteText() From 37d219a8ad011814c7ad93a2a10bc5d3e1f0ea2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:20:39 +0900 Subject: [PATCH 31/34] Fix comments, remove fixed width on "bpm" text and adjust baseline adjust slightly --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index b9f5deacb0..c07b203341 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Play.HUD { base.Update(); - //We dont want it going to 0 when we pause. so we block the updates + //We don't want it going to 0 when we pause. so we block the updates if (gameplayClock.IsPaused.Value) return; // We want to check Rate every update to cover windup/down @@ -84,9 +84,9 @@ namespace osu.Game.Screens.Play.HUD { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Font = OsuFont.Numeric.With(size: 8, fixedWidth: true), + Font = OsuFont.Numeric.With(size: 8), Text = @"BPM", - Padding = new MarginPadding { Bottom = 1.5f }, // align baseline better + Padding = new MarginPadding { Bottom = 2f }, // align baseline better } } }; From c6b6d0dcfee83d39e698f7787ccd681c15305919 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 13:31:29 +0300 Subject: [PATCH 32/34] Remove verbose log from notifications feed --- osu.Game/Scoring/ScoreImporter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index 2dfd461eb9..f69c1b9385 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -55,8 +55,6 @@ namespace osu.Game.Scoring catch (LegacyScoreDecoder.BeatmapNotFoundException e) { Logger.Log($@"Score '{name}' failed to import: no corresponding beatmap with the hash '{e.Hash}' could be found.", LoggingTarget.Database); - Logger.Log($@"Score '{name}' failed to import due to missing beatmap. Check database logs for more info.", LoggingTarget.Information, LogLevel.Error); - return null; } } From 0d6b9ebc0f18aa2db7cde7b9a55bf91ced958e88 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 13:32:03 +0300 Subject: [PATCH 33/34] Display number of failing models during batch-import --- osu.Game/Database/RealmArchiveModelImporter.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index d107a6a605..20cae725ad 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -154,9 +154,12 @@ namespace osu.Game.Database } else { - notification.CompletionText = imported.Count == 1 - ? $"Imported {imported.First().GetDisplayString()}!" - : $"Imported {imported.Count} {HumanisedModelName}s!"; + if (tasks.Length > imported.Count) + notification.CompletionText = $"Imported {imported.Count} out of {tasks.Length} {HumanisedModelName}s."; + else if (imported.Count > 1) + notification.CompletionText = $"Imported {imported.Count} {HumanisedModelName}s!"; + else + notification.CompletionText = $"Imported {imported.First().GetDisplayString()}!"; if (imported.Count > 0 && PresentImport != null) { From a22b7298c6facab60b864886b460d42a8d906432 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 22:27:36 +0900 Subject: [PATCH 34/34] Adjust english slightly --- osu.Game/Database/RealmArchiveModelImporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 20cae725ad..db8861c281 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -155,7 +155,7 @@ namespace osu.Game.Database else { if (tasks.Length > imported.Count) - notification.CompletionText = $"Imported {imported.Count} out of {tasks.Length} {HumanisedModelName}s."; + notification.CompletionText = $"Imported {imported.Count} of {tasks.Length} {HumanisedModelName}s."; else if (imported.Count > 1) notification.CompletionText = $"Imported {imported.Count} {HumanisedModelName}s!"; else