From 97041de09f5230e2fe1d5d9004e74b920be8b42b Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Wed, 11 Aug 2021 11:23:12 +0800 Subject: [PATCH 01/83] Preparation for localisation. --- osu.Game/Overlays/Settings/SettingsSection.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs index 4143605c28..f993a46dc6 100644 --- a/osu.Game/Overlays/Settings/SettingsSection.cs +++ b/osu.Game/Overlays/Settings/SettingsSection.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK.Graphics; @@ -19,10 +20,10 @@ namespace osu.Game.Overlays.Settings protected override Container Content => FlowContent; public abstract Drawable CreateIcon(); - public abstract string Header { get; } + public abstract LocalisableString Header { get; } public IEnumerable FilterableChildren => Children.OfType(); - public virtual IEnumerable FilterTerms => new[] { Header }; + public virtual IEnumerable FilterTerms => new[] { Header.ToString() }; private const int header_size = 26; private const int margin = 20; From 9a5d4ffd43e1fc2fed39cf03992ff7e503cd5473 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Wed, 11 Aug 2021 15:25:08 +0800 Subject: [PATCH 02/83] Add GeneralSettingsStrings --- .../Localisation/GeneralSettingsStrings.cs | 59 +++++++++++++++++++ .../Sections/General/LanguageSettings.cs | 6 +- .../Sections/General/UpdateSettings.cs | 11 ++-- .../Settings/Sections/GeneralSection.cs | 4 +- 4 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 osu.Game/Localisation/GeneralSettingsStrings.cs diff --git a/osu.Game/Localisation/GeneralSettingsStrings.cs b/osu.Game/Localisation/GeneralSettingsStrings.cs new file mode 100644 index 0000000000..19fb8de972 --- /dev/null +++ b/osu.Game/Localisation/GeneralSettingsStrings.cs @@ -0,0 +1,59 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class GeneralSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.GeneralSettings"; + + /// + /// "General" + /// + public static LocalisableString GeneralSectionHeader => new TranslatableString(getKey(@"general_section_header"), @"General"); + + /// + /// "Language" + /// + public static LocalisableString LanguageHeader => new TranslatableString(getKey(@"language_header"), @"Language"); + + /// + /// "Language" + /// + public static LocalisableString LanguageDropdown => new TranslatableString(getKey(@"language_dropdown"), @"Language"); + + /// + /// "Prefer metadata in original language" + /// + public static LocalisableString PreferOriginal => new TranslatableString(getKey(@"prefer_original"), @"Prefer metadata in original language"); + + /// + /// "Updates" + /// + public static LocalisableString UpdateHeader => new TranslatableString(getKey(@"update_header"), @"Updates"); + + /// + /// "Release stream" + /// + public static LocalisableString ReleaseStream => new TranslatableString(getKey(@"release_stream"), @"Release stream"); + + /// + /// "Check for updates" + /// + public static LocalisableString CheckUpdate => new TranslatableString(getKey(@"check_update"), @"Check for updates"); + + /// + /// "Open osu! folder" + /// + public static LocalisableString OpenOsuFolder => new TranslatableString(getKey(@"open_osu_folder"), @"Open osu! folder"); + + /// + /// "Change folder location..." + /// + public static LocalisableString ChangeFolderLocation => new TranslatableString(getKey(@"change_folder_location"), @"Change folder location..."); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index c6c752e2fd..ac95a713bf 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.General private SettingsDropdown languageSelection; private Bindable frameworkLocale; - protected override LocalisableString Header => "Language"; + protected override LocalisableString Header => GeneralSettingsStrings.LanguageHeader; [BackgroundDependencyLoader] private void load(FrameworkConfigManager frameworkConfig) @@ -27,11 +27,11 @@ namespace osu.Game.Overlays.Settings.Sections.General { languageSelection = new SettingsEnumDropdown { - LabelText = "Language", + LabelText = GeneralSettingsStrings.LanguageDropdown, }, new SettingsCheckbox { - LabelText = "Prefer metadata in original language", + LabelText = GeneralSettingsStrings.PreferOriginal, Current = frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode) }, }; diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index dd20e1d7ef..aa37748653 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -9,6 +9,7 @@ using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Framework.Screens; using osu.Game.Configuration; +using osu.Game.Localisation; using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Settings.Sections.Maintenance; using osu.Game.Updater; @@ -20,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.General [Resolved(CanBeNull = true)] private UpdateManager updateManager { get; set; } - protected override LocalisableString Header => "Updates"; + protected override LocalisableString Header => GeneralSettingsStrings.UpdateHeader; private SettingsButton checkForUpdatesButton; @@ -32,7 +33,7 @@ namespace osu.Game.Overlays.Settings.Sections.General { Add(new SettingsEnumDropdown { - LabelText = "Release stream", + LabelText = GeneralSettingsStrings.ReleaseStream, Current = config.GetBindable(OsuSetting.ReleaseStream), }); @@ -40,7 +41,7 @@ namespace osu.Game.Overlays.Settings.Sections.General { Add(checkForUpdatesButton = new SettingsButton { - Text = "Check for updates", + Text = GeneralSettingsStrings.CheckUpdate, Action = () => { checkForUpdatesButton.Enabled.Value = false; @@ -65,13 +66,13 @@ namespace osu.Game.Overlays.Settings.Sections.General { Add(new SettingsButton { - Text = "Open osu! folder", + Text = GeneralSettingsStrings.OpenOsuFolder, Action = storage.OpenInNativeExplorer, }); Add(new SettingsButton { - Text = "Change folder location...", + Text = GeneralSettingsStrings.ChangeFolderLocation, Action = () => game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())) }); } diff --git a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs index fefc3fe6a7..87e9f34833 100644 --- a/osu.Game/Overlays/Settings/Sections/GeneralSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GeneralSection.cs @@ -3,13 +3,15 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.General; namespace osu.Game.Overlays.Settings.Sections { public class GeneralSection : SettingsSection { - public override string Header => "General"; + public override LocalisableString Header => GeneralSettingsStrings.GeneralSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { From 078953980e65c4639899833556b6cd3969e6fd1c Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Wed, 11 Aug 2021 16:48:37 +0800 Subject: [PATCH 03/83] Add GraphicsSettingsStrings --- osu.Game/Localisation/CommonStrings.cs | 7 +- .../Localisation/GraphicsSettingsStrings.cs | 119 ++++++++++++++++++ .../Sections/Graphics/DetailSettings.cs | 11 +- .../Sections/Graphics/LayoutSettings.cs | 25 ++-- .../Sections/Graphics/RendererSettings.cs | 13 +- .../Settings/Sections/GraphicsSection.cs | 4 +- 6 files changed, 152 insertions(+), 27 deletions(-) create mode 100644 osu.Game/Localisation/GraphicsSettingsStrings.cs diff --git a/osu.Game/Localisation/CommonStrings.cs b/osu.Game/Localisation/CommonStrings.cs index bf488d2590..5e4ce235b4 100644 --- a/osu.Game/Localisation/CommonStrings.cs +++ b/osu.Game/Localisation/CommonStrings.cs @@ -19,6 +19,11 @@ namespace osu.Game.Localisation /// public static LocalisableString Enabled => new TranslatableString(getKey(@"enabled"), @"Enabled"); + /// + /// "Default" + /// + public static LocalisableString Default => new TranslatableString(getKey(@"default"), @"Default"); + /// /// "Width" /// @@ -31,4 +36,4 @@ namespace osu.Game.Localisation private static string getKey(string key) => $@"{prefix}:{key}"; } -} \ No newline at end of file +} diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs new file mode 100644 index 0000000000..841635649e --- /dev/null +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -0,0 +1,119 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class GraphicsSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.GraphicsSettings"; + + /// + /// "Graphics" + /// + public static LocalisableString GraphicsSectionHeader => new TranslatableString(getKey(@"graphics_section_header"), @"Graphics"); + + /// + /// "Renderer" + /// + public static LocalisableString RendererHeader => new TranslatableString(getKey(@"renderer_header"), @"Renderer"); + + /// + /// "Frame limiter" + /// + public static LocalisableString FrameLimiter => new TranslatableString(getKey(@"frame_limiter"), @"Frame limiter"); + + /// + /// "Threading mode" + /// + public static LocalisableString ThreadingMode => new TranslatableString(getKey(@"threading_mode"), @"Threading mode"); + + /// + /// "Show FPS" + /// + public static LocalisableString ShowFPS => new TranslatableString(getKey(@"show_fps"), @"Show FPS"); + + /// + /// "Using unlimited frame limiter can lead to stutters, bad performance and overheating. It will not improve perceived latency. "2x refresh rate" is recommended." + /// + public static LocalisableString UnlimitedFramesNote => new TranslatableString(getKey(@"unlimited_frames_note"), @"Using unlimited frame limiter can lead to stutters, bad performance and overheating. It will not improve perceived latency. ""2x refresh rate"" is recommended."); + + /// + /// "Layout" + /// + public static LocalisableString LayoutHeader => new TranslatableString(getKey(@"layout_header"), @"Layout"); + + /// + /// "Screen mode" + /// + public static LocalisableString ScreenMode => new TranslatableString(getKey(@"screen_mode"), @"Screen mode"); + + /// + /// "Resolution" + /// + public static LocalisableString Resolution => new TranslatableString(getKey(@"resolution"), @"Resolution"); + + /// + /// "UI Scaling" + /// + public static LocalisableString UIScaling => new TranslatableString(getKey(@"ui_scaling"), @"UI Scaling"); + + /// + /// "Screen Scaling" + /// + public static LocalisableString ScreenScaling => new TranslatableString(getKey(@"screen_scaling"), @"Screen Scaling"); + + /// + /// "Horizontal position" + /// + public static LocalisableString HorizontalPosition => new TranslatableString(getKey(@"horizontal_position"), @"Horizontal position"); + + /// + /// "Vertical position" + /// + public static LocalisableString VerticalPosition => new TranslatableString(getKey(@"vertical_position"), @"Vertical position"); + + /// + /// "Horizontal scale" + /// + public static LocalisableString HorizontalScale => new TranslatableString(getKey(@"horizontal_scale"), @"Horizontal scale"); + + /// + /// "Vertical scale" + /// + public static LocalisableString VerticalScale => new TranslatableString(getKey(@"vertical_scale"), @"Vertical scale"); + + /// + /// "Running without fullscreen mode will increase your input latency!" + /// + public static LocalisableString NotFullscreenNote => new TranslatableString(getKey(@"not_fullscreen_note"), @"Running without fullscreen mode will increase your input latency!"); + + /// + /// "Detail Settings" + /// + public static LocalisableString DetailSettingsHeader => new TranslatableString(getKey(@"detail_settings_header"), @"Detail Settings"); + + /// + /// "Storyboard / Video" + /// + public static LocalisableString StoryboardVideo => new TranslatableString(getKey(@"storyboard_video"), @"Storyboard / Video"); + + /// + /// "Hit Lighting" + /// + public static LocalisableString HitLighting => new TranslatableString(getKey(@"hit_lighting"), @"Hit Lighting"); + + /// + /// "Screenshot format" + /// + public static LocalisableString ScreenshotFormat => new TranslatableString(getKey(@"screenshot_format"), @"Screenshot format"); + + /// + /// "Show menu cursor in screenshots" + /// + public static LocalisableString ShowCursorInScreenshots => new TranslatableString(getKey(@""), @"Show menu cursor in screenshots"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs index f889cfca0f..20b1d8d801 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/DetailSettings.cs @@ -5,12 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Graphics { public class DetailSettings : SettingsSubsection { - protected override LocalisableString Header => "Detail Settings"; + protected override LocalisableString Header => GraphicsSettingsStrings.DetailSettingsHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -19,22 +20,22 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { new SettingsCheckbox { - LabelText = "Storyboard / Video", + LabelText = GraphicsSettingsStrings.StoryboardVideo, Current = config.GetBindable(OsuSetting.ShowStoryboard) }, new SettingsCheckbox { - LabelText = "Hit Lighting", + LabelText = GraphicsSettingsStrings.HitLighting, Current = config.GetBindable(OsuSetting.HitLighting) }, new SettingsEnumDropdown { - LabelText = "Screenshot format", + LabelText = GraphicsSettingsStrings.ScreenshotFormat, Current = config.GetBindable(OsuSetting.ScreenshotFormat) }, new SettingsCheckbox { - LabelText = "Show menu cursor in screenshots", + LabelText = GraphicsSettingsStrings.ShowCursorInScreenshots, Current = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor) } }; diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 91208cb78a..50bd8184ee 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -16,13 +16,14 @@ using osu.Framework.Platform; using osu.Game.Configuration; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osuTK.Graphics; namespace osu.Game.Overlays.Settings.Sections.Graphics { public class LayoutSettings : SettingsSubsection { - protected override LocalisableString Header => "Layout"; + protected override LocalisableString Header => GraphicsSettingsStrings.LayoutHeader; private FillFlowContainer> scalingSettings; @@ -67,20 +68,20 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { windowModeDropdown = new SettingsDropdown { - LabelText = "Screen mode", + LabelText = GraphicsSettingsStrings.ScreenMode, ItemSource = windowModes, Current = config.GetBindable(FrameworkSetting.WindowMode), }, resolutionDropdown = new ResolutionSettingsDropdown { - LabelText = "Resolution", + LabelText = GraphicsSettingsStrings.Resolution, ShowsDefaultIndicator = false, ItemSource = resolutions, Current = sizeFullscreen }, new SettingsSlider { - LabelText = "UI Scaling", + LabelText = GraphicsSettingsStrings.UIScaling, TransferValueOnCommit = true, Current = osuConfig.GetBindable(OsuSetting.UIScale), KeyboardStep = 0.01f, @@ -88,7 +89,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics }, new SettingsEnumDropdown { - LabelText = "Screen Scaling", + LabelText = GraphicsSettingsStrings.ScreenScaling, Current = osuConfig.GetBindable(OsuSetting.Scaling), Keywords = new[] { "scale", "letterbox" }, }, @@ -104,28 +105,28 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { new SettingsSlider { - LabelText = "Horizontal position", + LabelText = GraphicsSettingsStrings.HorizontalPosition, Current = scalingPositionX, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = "Vertical position", + LabelText = GraphicsSettingsStrings.VerticalPosition, Current = scalingPositionY, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = "Horizontal scale", + LabelText = GraphicsSettingsStrings.HorizontalScale, Current = scalingSizeX, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = "Vertical scale", + LabelText = GraphicsSettingsStrings.VerticalScale, Current = scalingSizeY, KeyboardStep = 0.01f, DisplayAsPercentage = true @@ -145,9 +146,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { updateResolutionDropdown(); - const string not_fullscreen_note = "Running without fullscreen mode will increase your input latency!"; - - windowModeDropdown.WarningText = mode.NewValue != WindowMode.Fullscreen ? not_fullscreen_note : string.Empty; + windowModeDropdown.WarningText = mode.NewValue != WindowMode.Fullscreen ? GraphicsSettingsStrings.NotFullscreenNote : string.Empty; }, true); windowModes.BindCollectionChanged((sender, args) => @@ -245,7 +244,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics protected override LocalisableString GenerateItemText(Size item) { if (item == new Size(9999, 9999)) - return "Default"; + return CommonStrings.Default; return $"{item.Width}x{item.Height}"; } diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 2210c7911e..9747f6b373 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -7,12 +7,13 @@ using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Framework.Platform; using osu.Game.Configuration; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Graphics { public class RendererSettings : SettingsSubsection { - protected override LocalisableString Header => "Renderer"; + protected override LocalisableString Header => GraphicsSettingsStrings.RendererHeader; private SettingsEnumDropdown frameLimiterDropdown; @@ -25,17 +26,17 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics // TODO: this needs to be a custom dropdown at some point frameLimiterDropdown = new SettingsEnumDropdown { - LabelText = "Frame limiter", + LabelText = GraphicsSettingsStrings.FrameLimiter, Current = config.GetBindable(FrameworkSetting.FrameSync) }, new SettingsEnumDropdown { - LabelText = "Threading mode", + LabelText = GraphicsSettingsStrings.ThreadingMode, Current = config.GetBindable(FrameworkSetting.ExecutionMode) }, new SettingsCheckbox { - LabelText = "Show FPS", + LabelText = GraphicsSettingsStrings.ShowFPS, Current = osuConfig.GetBindable(OsuSetting.ShowFpsDisplay) }, }; @@ -47,9 +48,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics frameLimiterDropdown.Current.BindValueChanged(limit => { - const string unlimited_frames_note = "Using unlimited frame limiter can lead to stutters, bad performance and overheating. It will not improve perceived latency. \"2x refresh rate\" is recommended."; - - frameLimiterDropdown.WarningText = limit.NewValue == FrameSync.Unlimited ? unlimited_frames_note : string.Empty; + frameLimiterDropdown.WarningText = limit.NewValue == FrameSync.Unlimited ? GraphicsSettingsStrings.UnlimitedFramesNote : string.Empty; }, true); } } diff --git a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs index 4ade48031f..fd0718f9f2 100644 --- a/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/GraphicsSection.cs @@ -3,13 +3,15 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.Graphics; namespace osu.Game.Overlays.Settings.Sections { public class GraphicsSection : SettingsSection { - public override string Header => "Graphics"; + public override LocalisableString Header => GraphicsSettingsStrings.GraphicsSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { From b2986e99d30a8e638e53047dd3b594343a18e073 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Wed, 11 Aug 2021 17:10:08 +0800 Subject: [PATCH 04/83] Add AudioSettingsStrings --- osu.Game/Localisation/AudioSettingsStrings.cs | 64 +++++++++++++++++++ .../Sections/Audio/AudioDevicesSettings.cs | 5 +- .../Settings/Sections/Audio/OffsetSettings.cs | 7 +- .../Settings/Sections/Audio/VolumeSettings.cs | 11 ++-- .../Settings/Sections/AudioSection.cs | 4 +- 5 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Localisation/AudioSettingsStrings.cs diff --git a/osu.Game/Localisation/AudioSettingsStrings.cs b/osu.Game/Localisation/AudioSettingsStrings.cs new file mode 100644 index 0000000000..aa6eabd7d1 --- /dev/null +++ b/osu.Game/Localisation/AudioSettingsStrings.cs @@ -0,0 +1,64 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class AudioSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.AudioSettings"; + + /// + /// "Audio" + /// + public static LocalisableString AudioSectionHeader => new TranslatableString(getKey(@"audio_section_header"), @"Audio"); + + /// + /// "Devices" + /// + public static LocalisableString AudioDevicesHeader => new TranslatableString(getKey(@"audio_devices_header"), @"Devices"); + + /// + /// "Volume" + /// + public static LocalisableString VolumeHeader => new TranslatableString(getKey(@"volume_header"), @"Volume"); + + /// + /// "Master" + /// + public static LocalisableString MasterVolume => new TranslatableString(getKey(@"master_volume"), @"Master"); + + /// + /// "Master (window inactive)" + /// + public static LocalisableString MasterVolumeInactive => new TranslatableString(getKey(@"master_volume_inactive"), @"Master (window inactive)"); + + /// + /// "Effect" + /// + public static LocalisableString EffectVolume => new TranslatableString(getKey(@"effect_volume"), @"Effect"); + + /// + /// "Music" + /// + public static LocalisableString MusicVolume => new TranslatableString(getKey(@"music_volume"), @"Music"); + + /// + /// "Offset Adjustment" + /// + public static LocalisableString OffsetHeader => new TranslatableString(getKey(@"offset_header"), @"Offset Adjustment"); + + /// + /// "Audio offset" + /// + public static LocalisableString AudioOffset => new TranslatableString(getKey(@"audio_offset"), @"Audio offset"); + + /// + /// "Offset wizard" + /// + public static LocalisableString OffsetWizard => new TranslatableString(getKey(@"offset_wizard"), @"Offset wizard"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index d64f176468..501f1b86b8 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -8,12 +8,13 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Audio { public class AudioDevicesSettings : SettingsSubsection { - protected override LocalisableString Header => "Devices"; + protected override LocalisableString Header => AudioSettingsStrings.AudioDevicesHeader; [Resolved] private AudioManager audio { get; set; } @@ -78,7 +79,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio private class AudioDeviceDropdownControl : DropdownControl { protected override LocalisableString GenerateItemText(string item) - => string.IsNullOrEmpty(item) ? "Default" : base.GenerateItemText(item); + => string.IsNullOrEmpty(item) ? CommonStrings.Default : base.GenerateItemText(item); } } } diff --git a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs index 7f2e377c83..85973c81c9 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs @@ -6,12 +6,13 @@ using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Audio { public class OffsetSettings : SettingsSubsection { - protected override LocalisableString Header => "Offset Adjustment"; + protected override LocalisableString Header => AudioSettingsStrings.OffsetHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -20,13 +21,13 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { new SettingsSlider { - LabelText = "Audio offset", + LabelText = AudioSettingsStrings.AudioOffset, Current = config.GetBindable(OsuSetting.AudioOffset), KeyboardStep = 1f }, new SettingsButton { - Text = "Offset wizard" + Text = AudioSettingsStrings.OffsetWizard } }; } diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index 8f88b03471..00c1cb8f43 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -6,12 +6,13 @@ using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Audio { public class VolumeSettings : SettingsSubsection { - protected override LocalisableString Header => "Volume"; + protected override LocalisableString Header => AudioSettingsStrings.VolumeHeader; [BackgroundDependencyLoader] private void load(AudioManager audio, OsuConfigManager config) @@ -20,28 +21,28 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { new SettingsSlider { - LabelText = "Master", + LabelText = AudioSettingsStrings.MasterVolume, Current = audio.Volume, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = "Master (window inactive)", + LabelText = AudioSettingsStrings.MasterVolumeInactive, Current = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = "Effect", + LabelText = AudioSettingsStrings.EffectVolume, Current = audio.VolumeSample, KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = "Music", + LabelText = AudioSettingsStrings.MusicVolume, Current = audio.VolumeTrack, KeyboardStep = 0.01f, DisplayAsPercentage = true diff --git a/osu.Game/Overlays/Settings/Sections/AudioSection.cs b/osu.Game/Overlays/Settings/Sections/AudioSection.cs index 7072d8e63d..694da0529a 100644 --- a/osu.Game/Overlays/Settings/Sections/AudioSection.cs +++ b/osu.Game/Overlays/Settings/Sections/AudioSection.cs @@ -3,15 +3,17 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Localisation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.Audio; namespace osu.Game.Overlays.Settings.Sections { public class AudioSection : SettingsSection { - public override string Header => "Audio"; + public override LocalisableString Header => AudioSettingsStrings.AudioSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { From 2cc89f50cce503ed8ecd3a86206b8cd6a50660ea Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 09:14:49 +0800 Subject: [PATCH 05/83] Add missing key --- osu.Game/Localisation/GraphicsSettingsStrings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs index 841635649e..989eaf19b9 100644 --- a/osu.Game/Localisation/GraphicsSettingsStrings.cs +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -112,7 +112,7 @@ namespace osu.Game.Localisation /// /// "Show menu cursor in screenshots" /// - public static LocalisableString ShowCursorInScreenshots => new TranslatableString(getKey(@""), @"Show menu cursor in screenshots"); + public static LocalisableString ShowCursorInScreenshots => new TranslatableString(getKey(@"show_cursor_in_screenshots"), @"Show menu cursor in screenshots"); private static string getKey(string key) => $"{prefix}:{key}"; } From 03013d0d307480f3589714dd4b6043555fb4943d Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 09:53:31 +0800 Subject: [PATCH 06/83] Add InputSettingsStrings Existed strings files keep no change --- osu.Game/Localisation/CommonStrings.cs | 5 ++ osu.Game/Localisation/InputSettingsStrings.cs | 59 +++++++++++++++++++ .../Input/GlobalKeyBindingsSection.cs | 11 ++-- .../Sections/Input/KeyBindingPanel.cs | 3 +- .../Settings/Sections/Input/KeyBindingRow.cs | 5 +- .../Sections/Input/KeyBindingsSubsection.cs | 3 +- .../Sections/Input/RulesetBindingsSection.cs | 3 +- .../Settings/Sections/InputSection.cs | 5 +- 8 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 osu.Game/Localisation/InputSettingsStrings.cs diff --git a/osu.Game/Localisation/CommonStrings.cs b/osu.Game/Localisation/CommonStrings.cs index 5e4ce235b4..432c1c6255 100644 --- a/osu.Game/Localisation/CommonStrings.cs +++ b/osu.Game/Localisation/CommonStrings.cs @@ -14,6 +14,11 @@ namespace osu.Game.Localisation /// public static LocalisableString Cancel => new TranslatableString(getKey(@"cancel"), @"Cancel"); + /// + /// "Clear" + /// + public static LocalisableString Clear => new TranslatableString(getKey(@"clear"), @"Clear"); + /// /// "Enabled" /// diff --git a/osu.Game/Localisation/InputSettingsStrings.cs b/osu.Game/Localisation/InputSettingsStrings.cs new file mode 100644 index 0000000000..e46b4cecf3 --- /dev/null +++ b/osu.Game/Localisation/InputSettingsStrings.cs @@ -0,0 +1,59 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class InputSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.InputSettings"; + + /// + /// "Input" + /// + public static LocalisableString InputSectionHeader => new TranslatableString(getKey(@"input_section_header"), @"Input"); + + /// + /// "Global" + /// + public static LocalisableString GlobalKeyBindingHeader => new TranslatableString(getKey(@"global_key_binding_header"), @"Global"); + + /// + /// "Song Select" + /// + public static LocalisableString SongSelectSection => new TranslatableString(getKey(@"song_select_section"), @"Song Select"); + + /// + /// "In Game" + /// + public static LocalisableString InGameSection => new TranslatableString(getKey(@"in_game_section"), @"In Game"); + + /// + /// "Audio" + /// + public static LocalisableString AudioSection => new TranslatableString(getKey(@"audio_section"), @"Audio"); + + /// + /// "Editor" + /// + public static LocalisableString EditorSection => new TranslatableString(getKey(@"editor_section"), @"Editor"); + + /// + /// "Reset all bindings in section" + /// + public static LocalisableString ResetSectionButton => new TranslatableString(getKey(@"reset_section_button"), @"Reset all bindings in section"); + + /// + /// "key configuration" + /// + public static LocalisableString KeyBindingPanelHeader => new TranslatableString(getKey(@"key_binding_panel_header"), @"key configuration"); + + /// + /// "Customise your keys!" + /// + public static LocalisableString KeyBindingPanelDescription => new TranslatableString(getKey(@"key_binding_panel_description"), @"Customise your keys!"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs index 9898a50320..3350ff4eaa 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/GlobalKeyBindingsSection.cs @@ -5,6 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Input.Bindings; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Input { @@ -15,7 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input Icon = FontAwesome.Solid.Globe }; - public override string Header => "Global"; + public override LocalisableString Header => InputSettingsStrings.GlobalKeyBindingHeader; public GlobalKeyBindingsSection(GlobalActionContainer manager) { @@ -39,7 +40,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input private class SongSelectKeyBindingSubsection : KeyBindingsSubsection { - protected override LocalisableString Header => "Song Select"; + protected override LocalisableString Header => InputSettingsStrings.SongSelectSection; public SongSelectKeyBindingSubsection(GlobalActionContainer manager) : base(null) @@ -50,7 +51,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input private class InGameKeyBindingsSubsection : KeyBindingsSubsection { - protected override LocalisableString Header => "In Game"; + protected override LocalisableString Header => InputSettingsStrings.InGameSection; public InGameKeyBindingsSubsection(GlobalActionContainer manager) : base(null) @@ -61,7 +62,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input private class AudioControlKeyBindingsSubsection : KeyBindingsSubsection { - protected override LocalisableString Header => "Audio"; + protected override LocalisableString Header => InputSettingsStrings.AudioSection; public AudioControlKeyBindingsSubsection(GlobalActionContainer manager) : base(null) @@ -72,7 +73,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input private class EditorKeyBindingsSubsection : KeyBindingsSubsection { - protected override LocalisableString Header => "Editor"; + protected override LocalisableString Header => InputSettingsStrings.EditorSection; public EditorKeyBindingsSubsection(GlobalActionContainer manager) : base(null) diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs index 7cdc739b7c..67f1bb8d3e 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingPanel.cs @@ -4,13 +4,14 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Input.Bindings; +using osu.Game.Localisation; using osu.Game.Rulesets; namespace osu.Game.Overlays.Settings.Sections.Input { public class KeyBindingPanel : SettingsSubPanel { - protected override Drawable CreateHeader() => new SettingsHeader("key configuration", "Customise your keys!"); + protected override Drawable CreateHeader() => new SettingsHeader(InputSettingsStrings.KeyBindingPanelHeader, InputSettingsStrings.KeyBindingPanelDescription); [BackgroundDependencyLoader(permitNulls: true)] private void load(RulesetStore rulesets, GlobalActionContainer global) diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs index 6e018597be..c38c516f21 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingRow.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Input.Bindings; +using osu.Game.Localisation; using osuTK; using osuTK.Graphics; using osuTK.Input; @@ -385,7 +386,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { public CancelButton() { - Text = "Cancel"; + Text = CommonStrings.Cancel; Size = new Vector2(80, 20); } } @@ -394,7 +395,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { public ClearButton() { - Text = "Clear"; + Text = CommonStrings.Clear; Size = new Vector2(80, 20); } } diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs index d65684fd37..ef5ccae1a0 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs @@ -10,6 +10,7 @@ using osu.Game.Database; using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Rulesets; +using osu.Game.Localisation; using osuTK; namespace osu.Game.Overlays.Settings.Sections.Input @@ -64,7 +65,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input [BackgroundDependencyLoader] private void load() { - Text = "Reset all bindings in section"; + Text = InputSettingsStrings.ResetSectionButton; RelativeSizeAxes = Axes.X; Width = 0.5f; Anchor = Anchor.TopCentre; diff --git a/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs b/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs index 81a4d7eccd..5246051a4a 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/RulesetBindingsSection.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Rulesets; @@ -15,7 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input Icon = OsuIcon.Hot }; - public override string Header => ruleset.Name; + public override LocalisableString Header => ruleset.Name; private readonly RulesetInfo ruleset; diff --git a/osu.Game/Overlays/Settings/Sections/InputSection.cs b/osu.Game/Overlays/Settings/Sections/InputSection.cs index 366f39388a..d282ba5318 100644 --- a/osu.Game/Overlays/Settings/Sections/InputSection.cs +++ b/osu.Game/Overlays/Settings/Sections/InputSection.cs @@ -11,6 +11,7 @@ using osu.Framework.Input.Handlers.Mouse; using osu.Framework.Input.Handlers.Tablet; using osu.Framework.Localisation; using osu.Framework.Platform; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.Input; namespace osu.Game.Overlays.Settings.Sections @@ -19,7 +20,7 @@ namespace osu.Game.Overlays.Settings.Sections { private readonly KeyBindingPanel keyConfig; - public override string Header => "Input"; + public override LocalisableString Header => InputSettingsStrings.InputSectionHeader; [Resolved] private GameHost host { get; set; } @@ -95,7 +96,7 @@ namespace osu.Game.Overlays.Settings.Sections { new SettingsCheckbox { - LabelText = "Enabled", + LabelText = CommonStrings.Enabled, Current = handler.Enabled }, }; From 7adf2bb64c3be39f920cb074781fe032af3d0e9b Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 10:48:29 +0800 Subject: [PATCH 07/83] Add UserInterfaceStrings --- osu.Game/Localisation/UserInterfaceStrings.cs | 114 ++++++++++++++++++ .../Sections/UserInterface/GeneralSettings.cs | 11 +- .../UserInterface/MainMenuSettings.cs | 17 ++- .../UserInterface/SongSelectSettings.cs | 15 +-- .../Settings/Sections/UserInterfaceSection.cs | 4 +- 5 files changed, 139 insertions(+), 22 deletions(-) create mode 100644 osu.Game/Localisation/UserInterfaceStrings.cs diff --git a/osu.Game/Localisation/UserInterfaceStrings.cs b/osu.Game/Localisation/UserInterfaceStrings.cs new file mode 100644 index 0000000000..18a9257732 --- /dev/null +++ b/osu.Game/Localisation/UserInterfaceStrings.cs @@ -0,0 +1,114 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class UserInterfaceStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.UserInterface"; + + /// + /// "User Interface" + /// + public static LocalisableString UserInterfaceSectionHeader => new TranslatableString(getKey(@"user_interface_section_header"), @"User Interface"); + + /// + /// "General" + /// + public static LocalisableString GeneralHeader => new TranslatableString(getKey(@"general_header"), @"General"); + + /// + /// "Rotate cursor when dragging" + /// + public static LocalisableString CursorRotation => new TranslatableString(getKey(@"cursor_rotation"), @"Rotate cursor when dragging"); + + /// + /// "Menu cursor size" + /// + public static LocalisableString MenuCursorSize => new TranslatableString(getKey(@"menu_cursor_size"), @"Menu cursor size"); + + /// + /// "Parallax" + /// + public static LocalisableString Parallax => new TranslatableString(getKey(@"parallax"), @"Parallax"); + + /// + /// "Hold-to-confirm activation time" + /// + public static LocalisableString HoldActivationDelay => new TranslatableString(getKey(@"hold_activation_delay"), @"Hold-to-confirm activation time"); + + /// + /// "Main Menu" + /// + public static LocalisableString MainMenuHeader => new TranslatableString(getKey(@"main_menu_header"), @"Main Menu"); + + /// + /// "Interface voices" + /// + public static LocalisableString InterfaceVoices => new TranslatableString(getKey(@"interface_voices"), @"Interface voices"); + + /// + /// "osu! music theme" + /// + public static LocalisableString OsuMusicTheme => new TranslatableString(getKey(@"osu_music_theme"), @"osu! music theme"); + + /// + /// "Intro sequence" + /// + public static LocalisableString IntroSequence => new TranslatableString(getKey(@"intro_sequence"), @"Intro sequence"); + + /// + /// "Background source" + /// + public static LocalisableString BackgroundSource => new TranslatableString(getKey(@"background_source"), @"Background source"); + + /// + /// "Seasonal backgrounds" + /// + public static LocalisableString SeasonalBackgrounds => new TranslatableString(getKey(@"seasonal_backgrounds"), @"Seasonal backgrounds"); + + /// + /// "Changes to this setting will only apply with an active osu!supporter tag." + /// + public static LocalisableString NotSupporterNote => new TranslatableString(getKey(@"not_supporter_note"), @"Changes to this setting will only apply with an active osu!supporter tag."); + + /// + /// "Song Select" + /// + public static LocalisableString SoneSelectHeader => new TranslatableString(getKey(@"song_select_header"), @"Song Select"); + + /// + /// "Right mouse drag to absolute scroll" + /// + public static LocalisableString RightMouseScroll => new TranslatableString(getKey(@"right_mouse_scroll"), @"Right mouse drag to absolute scroll"); + + /// + /// "Show converted beatmaps" + /// + public static LocalisableString ShowConvertedBeatmaps => new TranslatableString(getKey(@"show_converted_beatmaps"), @"Show converted beatmaps"); + + /// + /// "Display beatmaps from" + /// + public static LocalisableString StarsMinimum => new TranslatableString(getKey(@"stars_minimum"), @"Display beatmaps from"); + + /// + /// "up to" + /// + public static LocalisableString StarsMaximum => new TranslatableString(getKey(@"stars_maximum"), @"up to"); + + /// + /// "Random selection algorithm" + /// + public static LocalisableString RandomSelectionAlgorithm => new TranslatableString(getKey(@"random_selection_algorithm"), @"Random selection algorithm"); + + /// + /// "no limit" + /// + public static LocalisableString NoLimit => new TranslatableString(getKey(@"no_limit"), @"no limit"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs index 4b26645ef3..b26363a9da 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs @@ -6,12 +6,13 @@ using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.UserInterface { public class GeneralSettings : SettingsSubsection { - protected override LocalisableString Header => "General"; + protected override LocalisableString Header => UserInterfaceStrings.GeneralHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -20,23 +21,23 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface { new SettingsCheckbox { - LabelText = "Rotate cursor when dragging", + LabelText = UserInterfaceStrings.CursorRotation, Current = config.GetBindable(OsuSetting.CursorRotation) }, new SettingsSlider { - LabelText = "Menu cursor size", + LabelText = UserInterfaceStrings.MenuCursorSize, Current = config.GetBindable(OsuSetting.MenuCursorSize), KeyboardStep = 0.01f }, new SettingsCheckbox { - LabelText = "Parallax", + LabelText = UserInterfaceStrings.Parallax, Current = config.GetBindable(OsuSetting.MenuParallax) }, new SettingsSlider { - LabelText = "Hold-to-confirm activation time", + LabelText = UserInterfaceStrings.HoldActivationDelay, Current = config.GetBindable(OsuSetting.UIHoldActivationDelay), KeyboardStep = 50 }, diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs index 81bbcbb54a..976893bf0a 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Users; @@ -13,7 +14,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface { public class MainMenuSettings : SettingsSubsection { - protected override LocalisableString Header => "Main Menu"; + protected override LocalisableString Header => UserInterfaceStrings.MainMenuHeader; private IBindable user; @@ -28,27 +29,27 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface { new SettingsCheckbox { - LabelText = "Interface voices", + LabelText = UserInterfaceStrings.InterfaceVoices, Current = config.GetBindable(OsuSetting.MenuVoice) }, new SettingsCheckbox { - LabelText = "osu! music theme", + LabelText = UserInterfaceStrings.OsuMusicTheme, Current = config.GetBindable(OsuSetting.MenuMusic) }, new SettingsEnumDropdown { - LabelText = "Intro sequence", + LabelText = UserInterfaceStrings.IntroSequence, Current = config.GetBindable(OsuSetting.IntroSequence), }, backgroundSourceDropdown = new SettingsEnumDropdown { - LabelText = "Background source", + LabelText = UserInterfaceStrings.BackgroundSource, Current = config.GetBindable(OsuSetting.MenuBackgroundSource), }, new SettingsEnumDropdown { - LabelText = "Seasonal backgrounds", + LabelText = UserInterfaceStrings.SeasonalBackgrounds, Current = config.GetBindable(OsuSetting.SeasonalBackgroundMode), } }; @@ -60,9 +61,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface user.BindValueChanged(u => { - const string not_supporter_note = "Changes to this setting will only apply with an active osu!supporter tag."; - - backgroundSourceDropdown.WarningText = u.NewValue?.IsSupporter != true ? not_supporter_note : string.Empty; + backgroundSourceDropdown.WarningText = u.NewValue?.IsSupporter != true ? UserInterfaceStrings.NotSupporterNote : string.Empty; }, true); } } diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs index 587155eb0d..8596cecbb8 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.UserInterface { @@ -16,7 +17,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface private Bindable minStars; private Bindable maxStars; - protected override LocalisableString Header => "Song Select"; + protected override LocalisableString Header => UserInterfaceStrings.SoneSelectHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -31,31 +32,31 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface { new SettingsCheckbox { - LabelText = "Right mouse drag to absolute scroll", + LabelText = UserInterfaceStrings.RightMouseScroll, Current = config.GetBindable(OsuSetting.SongSelectRightMouseScroll), }, new SettingsCheckbox { - LabelText = "Show converted beatmaps", + LabelText = UserInterfaceStrings.ShowConvertedBeatmaps, Current = config.GetBindable(OsuSetting.ShowConvertedBeatmaps), }, new SettingsSlider { - LabelText = "Display beatmaps from", + LabelText = UserInterfaceStrings.StarsMinimum, Current = config.GetBindable(OsuSetting.DisplayStarsMinimum), KeyboardStep = 0.1f, Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsSlider { - LabelText = "up to", + LabelText = UserInterfaceStrings.StarsMaximum, Current = config.GetBindable(OsuSetting.DisplayStarsMaximum), KeyboardStep = 0.1f, Keywords = new[] { "minimum", "maximum", "star", "difficulty" } }, new SettingsEnumDropdown { - LabelText = "Random selection algorithm", + LabelText = UserInterfaceStrings.RandomSelectionAlgorithm, Current = config.GetBindable(OsuSetting.RandomSelectAlgorithm), } }; @@ -63,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface private class MaximumStarsSlider : StarsSlider { - public override LocalisableString TooltipText => Current.IsDefault ? "no limit" : base.TooltipText; + public override LocalisableString TooltipText => Current.IsDefault ? UserInterfaceStrings.NoLimit : base.TooltipText; } private class StarsSlider : OsuSliderBar diff --git a/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs b/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs index 718fea5f2b..6228c4c99a 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterfaceSection.cs @@ -3,13 +3,15 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.UserInterface; namespace osu.Game.Overlays.Settings.Sections { public class UserInterfaceSection : SettingsSection { - public override string Header => "User Interface"; + public override LocalisableString Header => UserInterfaceStrings.UserInterfaceSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { From 31ffaf15d4866275f1c86c0dbecd67af5eba59ff Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 11:11:22 +0800 Subject: [PATCH 08/83] Add GameplaySettingsStrings --- .../Localisation/GameplaySettingsStrings.cs | 95 +++++++++++++++++++ .../Sections/Gameplay/GeneralSettings.cs | 27 +++--- .../Sections/Gameplay/ModsSettings.cs | 5 +- .../Settings/Sections/GameplaySection.cs | 4 +- 4 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 osu.Game/Localisation/GameplaySettingsStrings.cs diff --git a/osu.Game/Localisation/GameplaySettingsStrings.cs b/osu.Game/Localisation/GameplaySettingsStrings.cs new file mode 100644 index 0000000000..172387bbb8 --- /dev/null +++ b/osu.Game/Localisation/GameplaySettingsStrings.cs @@ -0,0 +1,95 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class GameplaySettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.GameplaySettings"; + + /// + /// "Gameplay" + /// + public static LocalisableString GameplaySectionHeader => new TranslatableString(getKey(@"gameplay_section_header"), @"Gameplay"); + + /// + /// "General" + /// + public static LocalisableString GeneralHeader => new TranslatableString(getKey(@"general_header"), @"General"); + + /// + /// "Background dim" + /// + public static LocalisableString Dim => new TranslatableString(getKey(@"dim"), @"Background dim"); + + /// + /// "Background blur" + /// + public static LocalisableString Blur => new TranslatableString(getKey(@"blur"), @"Background blur"); + + /// + /// "Lighten playfield during breaks" + /// + public static LocalisableString LightenDuringBreaks => new TranslatableString(getKey(@"lighten_during_breaks"), @"Lighten playfield during breaks"); + + /// + /// "HUD overlay visibility mode" + /// + public static LocalisableString HUDVisibilityMode => new TranslatableString(getKey(@"hud_visibility_mode"), @"HUD overlay visibility mode"); + + /// + /// "Show difficulty graph on progress bar" + /// + public static LocalisableString ShowProgressGraph => new TranslatableString(getKey(@"show_progress_graph"), @"Show difficulty graph on progress bar"); + + /// + /// "Show health display even when you can't fail" + /// + public static LocalisableString ShowHealthDisplayWhenCantFail => new TranslatableString(getKey(@"show_health_display_when_cant_fail"), @"Show health display even when you can't fail"); + + /// + /// "Fade playfield to red when health is low" + /// + public static LocalisableString FadePlayfieldWhenHealthLow => new TranslatableString(getKey(@"fade_playfield_when_health_low"), @"Fade playfield to red when health is low"); + + /// + /// "Always show key overlay" + /// + public static LocalisableString KeyOverlay => new TranslatableString(getKey(@"key_overlay"), @"Always show key overlay"); + + /// + /// "Positional hitsounds" + /// + public static LocalisableString PositionalHitsounds => new TranslatableString(getKey(@"positional_hitsounds"), @"Positional hitsounds"); + + /// + /// "Always play first combo break sound" + /// + public static LocalisableString AlwaysPlayFirstComboBreak => new TranslatableString(getKey(@"always_play_first_combo_break"), @"Always play first combo break sound"); + + /// + /// "Score display mode" + /// + public static LocalisableString ScoreDisplayMode => new TranslatableString(getKey(@"score_display_mode"), @"Score display mode"); + + /// + /// "Disable Windows key during gameplay" + /// + public static LocalisableString DisableWinKey => new TranslatableString(getKey(@"disable_win_key"), @"Disable Windows key during gameplay"); + + /// + /// "Mods" + /// + public static LocalisableString ModsHeader => new TranslatableString(getKey(@"mods_header"), @"Mods"); + + /// + /// "Increase visibility of first object when visual impairment mods are enabled" + /// + public static LocalisableString IncreaseFirstObjectVisibility => new TranslatableString(getKey(@"increase_first_object_visibility"), @"Increase visibility of first object when visual impairment mods are enabled"); + + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 353292606f..efb586fdca 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -6,13 +6,14 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; using osu.Game.Rulesets.Scoring; namespace osu.Game.Overlays.Settings.Sections.Gameplay { public class GeneralSettings : SettingsSubsection { - protected override LocalisableString Header => "General"; + protected override LocalisableString Header => GameplaySettingsStrings.GeneralHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -21,62 +22,62 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { new SettingsSlider { - LabelText = "Background dim", + LabelText = GameplaySettingsStrings.Dim, Current = config.GetBindable(OsuSetting.DimLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = "Background blur", + LabelText = GameplaySettingsStrings.Blur, Current = config.GetBindable(OsuSetting.BlurLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsCheckbox { - LabelText = "Lighten playfield during breaks", + LabelText = GameplaySettingsStrings.LightenDuringBreaks, Current = config.GetBindable(OsuSetting.LightenDuringBreaks) }, new SettingsEnumDropdown { - LabelText = "HUD overlay visibility mode", + LabelText = GameplaySettingsStrings.HUDVisibilityMode, Current = config.GetBindable(OsuSetting.HUDVisibilityMode) }, new SettingsCheckbox { - LabelText = "Show difficulty graph on progress bar", + LabelText = GameplaySettingsStrings.ShowProgressGraph, Current = config.GetBindable(OsuSetting.ShowProgressGraph) }, new SettingsCheckbox { - LabelText = "Show health display even when you can't fail", + LabelText = GameplaySettingsStrings.ShowHealthDisplayWhenCantFail, Current = config.GetBindable(OsuSetting.ShowHealthDisplayWhenCantFail), Keywords = new[] { "hp", "bar" } }, new SettingsCheckbox { - LabelText = "Fade playfield to red when health is low", + LabelText = GameplaySettingsStrings.FadePlayfieldWhenHealthLow, Current = config.GetBindable(OsuSetting.FadePlayfieldWhenHealthLow), }, new SettingsCheckbox { - LabelText = "Always show key overlay", + LabelText = GameplaySettingsStrings.KeyOverlay, Current = config.GetBindable(OsuSetting.KeyOverlay) }, new SettingsCheckbox { - LabelText = "Positional hitsounds", + LabelText = GameplaySettingsStrings.PositionalHitsounds, Current = config.GetBindable(OsuSetting.PositionalHitSounds) }, new SettingsCheckbox { - LabelText = "Always play first combo break sound", + LabelText = GameplaySettingsStrings.AlwaysPlayFirstComboBreak, Current = config.GetBindable(OsuSetting.AlwaysPlayFirstComboBreak) }, new SettingsEnumDropdown { - LabelText = "Score display mode", + LabelText = GameplaySettingsStrings.ScoreDisplayMode, Current = config.GetBindable(OsuSetting.ScoreDisplayMode), Keywords = new[] { "scoring" } }, @@ -86,7 +87,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { Add(new SettingsCheckbox { - LabelText = "Disable Windows key during gameplay", + LabelText = GameplaySettingsStrings.DisableWinKey, Current = config.GetBindable(OsuSetting.GameplayDisableWinKey) }); } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs index ec9ddde2da..dfa060e8d5 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs @@ -6,12 +6,13 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Gameplay { public class ModsSettings : SettingsSubsection { - protected override LocalisableString Header => "Mods"; + protected override LocalisableString Header => GameplaySettingsStrings.ModsHeader; public override IEnumerable FilterTerms => base.FilterTerms.Concat(new[] { "mod" }); @@ -22,7 +23,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { new SettingsCheckbox { - LabelText = "Increase visibility of first object when visual impairment mods are enabled", + LabelText = GameplaySettingsStrings.IncreaseFirstObjectVisibility, Current = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility), }, }; diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index acb94a6a01..42d9d48d73 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -9,12 +9,14 @@ using osu.Game.Rulesets; using System.Linq; using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; +using osu.Framework.Localisation; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections { public class GameplaySection : SettingsSection { - public override string Header => "Gameplay"; + public override LocalisableString Header => GameplaySettingsStrings.GameplaySectionHeader; public override Drawable CreateIcon() => new SpriteIcon { From 61502e977afcaa4731fb8d6f2b3d2f6c46eb11b8 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 11:40:22 +0800 Subject: [PATCH 09/83] Add SkinSettingsStrings --- osu.Game/Localisation/SkinSettingsStrings.cs | 54 +++++++++++++++++++ .../Overlays/Settings/Sections/SkinSection.cs | 17 +++--- 2 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 osu.Game/Localisation/SkinSettingsStrings.cs diff --git a/osu.Game/Localisation/SkinSettingsStrings.cs b/osu.Game/Localisation/SkinSettingsStrings.cs new file mode 100644 index 0000000000..848c01b93a --- /dev/null +++ b/osu.Game/Localisation/SkinSettingsStrings.cs @@ -0,0 +1,54 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class SkinSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.SkinSettings"; + + /// + /// "Skin" + /// + public static LocalisableString SkinSectionHeader => new TranslatableString(getKey(@"skin_section_header"), @"Skin"); + + /// + /// "Skin layout editor" + /// + public static LocalisableString SkinLayoutEditor => new TranslatableString(getKey(@"skin_layout_editor"), @"Skin layout editor"); + + /// + /// "Gameplay cursor size" + /// + public static LocalisableString CursorSize => new TranslatableString(getKey(@"cursor_size"), @"Gameplay cursor size"); + + /// + /// "Adjust gameplay cursor size based on current beatmap" + /// + public static LocalisableString AutoCursorSize => new TranslatableString(getKey(@"auto_cursor_size"), @"Adjust gameplay cursor size based on current beatmap"); + + /// + /// "Beatmap skins" + /// + public static LocalisableString BeatmapSkins => new TranslatableString(getKey(@"beatmap_skins"), @"Beatmap skins"); + + /// + /// "Beatmap colours" + /// + public static LocalisableString BeatmapColours => new TranslatableString(getKey(@"beatmap_colours"), @"Beatmap colours"); + + /// + /// "Beatmap hitsounds" + /// + public static LocalisableString BeatmapHitsounds => new TranslatableString(getKey(@"beatmap_hitsounds"), @"Beatmap hitsounds"); + + /// + /// "Export selected skin" + /// + public static LocalisableString ExportSkinButton => new TranslatableString(getKey(@"export_skin_button"), @"Export selected skin"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 9f3543d059..007302c584 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -13,6 +13,7 @@ using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Game.Configuration; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Skinning; using osu.Game.Skinning.Editor; using osuTK; @@ -23,7 +24,7 @@ namespace osu.Game.Overlays.Settings.Sections { private SkinSettingsDropdown skinDropdown; - public override string Header => "Skin"; + public override LocalisableString Header => SkinSettingsStrings.SkinSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { @@ -69,34 +70,34 @@ namespace osu.Game.Overlays.Settings.Sections skinDropdown = new SkinSettingsDropdown(), new SettingsButton { - Text = "Skin layout editor", + Text = SkinSettingsStrings.SkinLayoutEditor, Action = () => skinEditor?.Toggle(), }, new ExportSkinButton(), new SettingsSlider { - LabelText = "Gameplay cursor size", + LabelText = SkinSettingsStrings.CursorSize, Current = config.GetBindable(OsuSetting.GameplayCursorSize), KeyboardStep = 0.01f }, new SettingsCheckbox { - LabelText = "Adjust gameplay cursor size based on current beatmap", + LabelText = SkinSettingsStrings.AutoCursorSize, Current = config.GetBindable(OsuSetting.AutoCursorSize) }, new SettingsCheckbox { - LabelText = "Beatmap skins", + LabelText = SkinSettingsStrings.BeatmapSkins, Current = config.GetBindable(OsuSetting.BeatmapSkins) }, new SettingsCheckbox { - LabelText = "Beatmap colours", + LabelText = SkinSettingsStrings.BeatmapColours, Current = config.GetBindable(OsuSetting.BeatmapColours) }, new SettingsCheckbox { - LabelText = "Beatmap hitsounds", + LabelText = SkinSettingsStrings.BeatmapHitsounds, Current = config.GetBindable(OsuSetting.BeatmapHitsounds) }, }; @@ -200,7 +201,7 @@ namespace osu.Game.Overlays.Settings.Sections [BackgroundDependencyLoader] private void load() { - Text = "Export selected skin"; + Text = SkinSettingsStrings.ExportSkinButton; Action = export; currentSkin = skins.CurrentSkin.GetBoundCopy(); From 9d391ad13817df8a81c5733fa7ee4f759852e095 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 11:57:51 +0800 Subject: [PATCH 10/83] Add OnlineSettingsStrings --- .../Localisation/OnlineSettingsStrings.cs | 69 +++++++++++++++++++ .../Online/AlertsAndPrivacySettings.cs | 7 +- .../Sections/Online/IntegrationSettings.cs | 5 +- .../Settings/Sections/Online/WebSettings.cs | 11 +-- .../Settings/Sections/OnlineSection.cs | 4 +- 5 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Localisation/OnlineSettingsStrings.cs diff --git a/osu.Game/Localisation/OnlineSettingsStrings.cs b/osu.Game/Localisation/OnlineSettingsStrings.cs new file mode 100644 index 0000000000..0ef98a720c --- /dev/null +++ b/osu.Game/Localisation/OnlineSettingsStrings.cs @@ -0,0 +1,69 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class OnlineSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.OnlineSettings"; + + /// + /// "Online" + /// + public static LocalisableString OnlineSectionHeader => new TranslatableString(getKey(@"online_section_header"), @"Online"); + + /// + /// "Alerts and Privacy" + /// + public static LocalisableString AlertsAndPrivacyHeader => new TranslatableString(getKey(@"alerts_and_privacy_header"), @"Alerts and Privacy"); + + /// + /// "Show a notification when someone mentions your name" + /// + public static LocalisableString NotifyOnMentioned => new TranslatableString(getKey(@"notify_on_mentioned"), @"Show a notification when someone mentions your name"); + + /// + /// "Show a notification when you receive a private message" + /// + public static LocalisableString NotifyOnPM => new TranslatableString(getKey(@"notify_on_pm"), @"Show a notification when you receive a private message"); + + /// + /// "Integrations" + /// + public static LocalisableString IntegrationHeader => new TranslatableString(getKey(@"integration_header"), @"Integrations"); + + /// + /// "Discord Rich Presence" + /// + public static LocalisableString DiscordRichPresence => new TranslatableString(getKey(@"discord_rich_presence"), @"Discord Rich Presence"); + + /// + /// "Web" + /// + public static LocalisableString WebHeader => new TranslatableString(getKey(@"web_header"), @"Web"); + + /// + /// "Warn about opening external links" + /// + public static LocalisableString ExternalLinkWarning => new TranslatableString(getKey(@"external_link_warning"), @"Warn about opening external links"); + + /// + /// "Prefer downloads without video" + /// + public static LocalisableString PreferNoVideo => new TranslatableString(getKey(@"prefer_no_video"), @"Prefer downloads without video"); + + /// + /// "Automatically download beatmaps when spectating" + /// + public static LocalisableString AutomaticallyDownload => new TranslatableString(getKey(@"automatically_download"), @"Automatically download beatmaps when spectating"); + + /// + /// "Show explicit content in search results" + /// + public static LocalisableString ShowExplicitContent => new TranslatableString(getKey(@"show_explicit_content"), @"Show explicit content in search results"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs b/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs index 3a2de2ee36..1728b565c2 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs @@ -5,12 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Online { public class AlertsAndPrivacySettings : SettingsSubsection { - protected override LocalisableString Header => "Alerts and Privacy"; + protected override LocalisableString Header => OnlineSettingsStrings.AlertsAndPrivacyHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -19,12 +20,12 @@ namespace osu.Game.Overlays.Settings.Sections.Online { new SettingsCheckbox { - LabelText = "Show a notification when someone mentions your name", + LabelText = OnlineSettingsStrings.NotifyOnMentioned, Current = config.GetBindable(OsuSetting.NotifyOnUsernameMentioned) }, new SettingsCheckbox { - LabelText = "Show a notification when you receive a private message", + LabelText = OnlineSettingsStrings.NotifyOnPM, Current = config.GetBindable(OsuSetting.NotifyOnPrivateMessage) }, }; diff --git a/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs index f2012f0d9c..f2a516feef 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs @@ -5,12 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Online { public class IntegrationSettings : SettingsSubsection { - protected override LocalisableString Header => "Integrations"; + protected override LocalisableString Header => OnlineSettingsStrings.IntegrationHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -19,7 +20,7 @@ namespace osu.Game.Overlays.Settings.Sections.Online { new SettingsEnumDropdown { - LabelText = "Discord Rich Presence", + LabelText = OnlineSettingsStrings.DiscordRichPresence, Current = config.GetBindable(OsuSetting.DiscordRichPresence) } }; diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index 89e7b096f3..4200ddda3d 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -5,12 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Configuration; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Online { public class WebSettings : SettingsSubsection { - protected override LocalisableString Header => "Web"; + protected override LocalisableString Header => OnlineSettingsStrings.WebHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) @@ -19,24 +20,24 @@ namespace osu.Game.Overlays.Settings.Sections.Online { new SettingsCheckbox { - LabelText = "Warn about opening external links", + LabelText = OnlineSettingsStrings.ExternalLinkWarning, Current = config.GetBindable(OsuSetting.ExternalLinkWarning) }, new SettingsCheckbox { - LabelText = "Prefer downloads without video", + LabelText = OnlineSettingsStrings.PreferNoVideo, Keywords = new[] { "no-video" }, Current = config.GetBindable(OsuSetting.PreferNoVideo) }, new SettingsCheckbox { - LabelText = "Automatically download beatmaps when spectating", + LabelText = OnlineSettingsStrings.AutomaticallyDownload, Keywords = new[] { "spectator" }, Current = config.GetBindable(OsuSetting.AutomaticallyDownloadWhenSpectating), }, new SettingsCheckbox { - LabelText = "Show explicit content in search results", + LabelText = OnlineSettingsStrings.ShowExplicitContent, Keywords = new[] { "nsfw", "18+", "offensive" }, Current = config.GetBindable(OsuSetting.ShowOnlineExplicitContent), } diff --git a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs index 680d11f7da..8b523b90b9 100644 --- a/osu.Game/Overlays/Settings/Sections/OnlineSection.cs +++ b/osu.Game/Overlays/Settings/Sections/OnlineSection.cs @@ -3,13 +3,15 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.Online; namespace osu.Game.Overlays.Settings.Sections { public class OnlineSection : SettingsSection { - public override string Header => "Online"; + public override LocalisableString Header => OnlineSettingsStrings.OnlineSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { From ac52b891489afc591ee4d5b08c54547c5c43de52 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 12:26:42 +0800 Subject: [PATCH 11/83] Add Maintenance and Debug SettingsStrings --- osu.Game/Localisation/DebugSettingsStrings.cs | 49 ++++++++++++ .../MaintenanceSettingsStrings.cs | 74 +++++++++++++++++++ .../Sections/Debug/GeneralSettings.cs | 9 ++- .../Settings/Sections/Debug/MemorySettings.cs | 5 +- .../Settings/Sections/DebugSection.cs | 4 +- .../Maintenance/DirectorySelectScreen.cs | 3 +- .../Sections/Maintenance/GeneralSettings.cs | 21 +++--- .../Settings/Sections/MaintenanceSection.cs | 4 +- 8 files changed, 150 insertions(+), 19 deletions(-) create mode 100644 osu.Game/Localisation/DebugSettingsStrings.cs create mode 100644 osu.Game/Localisation/MaintenanceSettingsStrings.cs diff --git a/osu.Game/Localisation/DebugSettingsStrings.cs b/osu.Game/Localisation/DebugSettingsStrings.cs new file mode 100644 index 0000000000..dd21739096 --- /dev/null +++ b/osu.Game/Localisation/DebugSettingsStrings.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Localisation; + +namespace osu.Game.Localisation +{ + public static class DebugSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.DebugSettings"; + + /// + /// "Debug" + /// + public static LocalisableString DebugSectionHeader => new TranslatableString(getKey(@"debug_section_header"), @"Debug"); + + /// + /// "General" + /// + public static LocalisableString GeneralHeader => new TranslatableString(getKey(@"general_header"), @"General"); + + /// + /// "Show log overlay" + /// + public static LocalisableString ShowLogOverlay => new TranslatableString(getKey(@"show_log_overlay"), @"Show log overlay"); + + /// + /// "Bypass front-to-back render pass" + /// + public static LocalisableString BypassFrontToBackPass => new TranslatableString(getKey(@"bypass_front_to_back_pass"), @"Bypass front-to-back render pass"); + + /// + /// "Import files" + /// + public static LocalisableString ImportFiles => new TranslatableString(getKey(@"import_files"), @"Import files"); + + /// + /// "Memory" + /// + public static LocalisableString MemoryHeader => new TranslatableString(getKey(@"memory_header"), @"Memory"); + + /// + /// "Clear all caches" + /// + public static LocalisableString ClearAllCaches => new TranslatableString(getKey(@"clear_all_caches"), @"Clear all caches"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Localisation/MaintenanceSettingsStrings.cs b/osu.Game/Localisation/MaintenanceSettingsStrings.cs new file mode 100644 index 0000000000..a0e1a9ddab --- /dev/null +++ b/osu.Game/Localisation/MaintenanceSettingsStrings.cs @@ -0,0 +1,74 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class MaintenanceSettingsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.MaintenanceSettings"; + + /// + /// "Maintenance" + /// + public static LocalisableString MaintenanceSectionHeader => new TranslatableString(getKey(@"maintenance_section_header"), @"Maintenance"); + + /// + /// "Select directory" + /// + public static LocalisableString SelectDirectory => new TranslatableString(getKey(@"select_directory"), @"Select directory"); + + /// + /// "Import beatmaps from stable" + /// + public static LocalisableString ImportBeatmapsFromStable => new TranslatableString(getKey(@"import_beatmaps_from_stable"), @"Import beatmaps from stable"); + + /// + /// "Delete ALL beatmaps" + /// + public static LocalisableString DeleteAllBeatmaps => new TranslatableString(getKey(@"delete_all_beatmaps"), @"Delete ALL beatmaps"); + + /// + /// "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" + /// + public static LocalisableString DeleteAllCollections => new TranslatableString(getKey(@"delete_all_collections"), @"Delete ALL collections"); + + /// + /// "Restore all hidden difficulties" + /// + public static LocalisableString RestoreAllHiddenDifficulties => new TranslatableString(getKey(@"restore_all_hidden_difficulties"), @"Restore all hidden difficulties"); + + /// + /// "Restore all recently deleted beatmaps" + /// + public static LocalisableString RestoreAllRecentlyDeletedBeatmaps => new TranslatableString(getKey(@"restore_all_recently_deleted_beatmaps"), @"Restore all recently deleted beatmaps"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs index 2b868cab85..25e20911b8 100644 --- a/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Debug/GeneralSettings.cs @@ -6,13 +6,14 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Framework.Screens; +using osu.Game.Localisation; using osu.Game.Screens.Import; namespace osu.Game.Overlays.Settings.Sections.Debug { public class GeneralSettings : SettingsSubsection { - protected override LocalisableString Header => "General"; + protected override LocalisableString Header => DebugSettingsStrings.GeneralHeader; [BackgroundDependencyLoader(true)] private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig, OsuGame game) @@ -21,18 +22,18 @@ namespace osu.Game.Overlays.Settings.Sections.Debug { new SettingsCheckbox { - LabelText = "Show log overlay", + LabelText = DebugSettingsStrings.ShowLogOverlay, Current = frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay) }, new SettingsCheckbox { - LabelText = "Bypass front-to-back render pass", + LabelText = DebugSettingsStrings.BypassFrontToBackPass, Current = config.GetBindable(DebugSetting.BypassFrontToBackPass) } }; Add(new SettingsButton { - Text = "Import files", + Text = DebugSettingsStrings.ImportFiles, Action = () => game?.PerformFromScreen(menu => menu.Push(new FileImportScreen())) }); } diff --git a/osu.Game/Overlays/Settings/Sections/Debug/MemorySettings.cs b/osu.Game/Overlays/Settings/Sections/Debug/MemorySettings.cs index bf7fb351c0..07fb0aca5a 100644 --- a/osu.Game/Overlays/Settings/Sections/Debug/MemorySettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Debug/MemorySettings.cs @@ -6,12 +6,13 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Framework.Platform; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Debug { public class MemorySettings : SettingsSubsection { - protected override LocalisableString Header => "Memory"; + protected override LocalisableString Header => DebugSettingsStrings.MemoryHeader; [BackgroundDependencyLoader] private void load(FrameworkDebugConfigManager config, GameHost host) @@ -20,7 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections.Debug { new SettingsButton { - Text = "Clear all caches", + Text = DebugSettingsStrings.ClearAllCaches, Action = host.Collect }, }; diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index 44d4088972..aa85ec920c 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -3,13 +3,15 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.Debug; namespace osu.Game.Overlays.Settings.Sections { public class DebugSection : SettingsSection { - public override string Header => "Debug"; + public override LocalisableString Header => DebugSettingsStrings.DebugSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs index 5392ba5d93..e509cac2f1 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/DirectorySelectScreen.cs @@ -14,6 +14,7 @@ using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; using osu.Framework.Screens; using osu.Game.Graphics.Containers; +using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Maintenance { @@ -104,7 +105,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Origin = Anchor.Centre, Width = 300, Margin = new MarginPadding(10), - Text = "Select directory", + Text = MaintenanceSettingsStrings.SelectDirectory, Action = () => OnSelection(directorySelector.CurrentPath.Value) }, } diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs index b9a408b1f8..803c8332c1 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Collections; using osu.Game.Database; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Scoring; using osu.Game.Skinning; @@ -37,7 +38,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { Add(importBeatmapsButton = new SettingsButton { - Text = "Import beatmaps from stable", + Text = MaintenanceSettingsStrings.ImportBeatmapsFromStable, Action = () => { importBeatmapsButton.Enabled.Value = false; @@ -48,7 +49,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Add(deleteBeatmapsButton = new DangerousSettingsButton { - Text = "Delete ALL beatmaps", + Text = MaintenanceSettingsStrings.DeleteAllBeatmaps, Action = () => { dialogOverlay?.Push(new DeleteAllBeatmapsDialog(() => @@ -63,7 +64,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { Add(importScoresButton = new SettingsButton { - Text = "Import scores from stable", + Text = MaintenanceSettingsStrings.ImportScoresFromStable, Action = () => { importScoresButton.Enabled.Value = false; @@ -74,7 +75,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Add(deleteScoresButton = new DangerousSettingsButton { - Text = "Delete ALL scores", + Text = MaintenanceSettingsStrings.DeleteAllScores, Action = () => { dialogOverlay?.Push(new DeleteAllBeatmapsDialog(() => @@ -89,7 +90,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { Add(importSkinsButton = new SettingsButton { - Text = "Import skins from stable", + Text = MaintenanceSettingsStrings.ImportSkinsFromStable, Action = () => { importSkinsButton.Enabled.Value = false; @@ -100,7 +101,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Add(deleteSkinsButton = new DangerousSettingsButton { - Text = "Delete ALL skins", + Text = MaintenanceSettingsStrings.DeleteAllSkins, Action = () => { dialogOverlay?.Push(new DeleteAllBeatmapsDialog(() => @@ -117,7 +118,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { Add(importCollectionsButton = new SettingsButton { - Text = "Import collections from stable", + Text = MaintenanceSettingsStrings.ImportCollectionsFromStable, Action = () => { importCollectionsButton.Enabled.Value = false; @@ -128,7 +129,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Add(new DangerousSettingsButton { - Text = "Delete ALL collections", + Text = MaintenanceSettingsStrings.DeleteAllCollections, Action = () => { dialogOverlay?.Push(new DeleteAllBeatmapsDialog(collectionManager.DeleteAll)); @@ -140,7 +141,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { restoreButton = new SettingsButton { - Text = "Restore all hidden difficulties", + Text = MaintenanceSettingsStrings.RestoreAllHiddenDifficulties, Action = () => { restoreButton.Enabled.Value = false; @@ -153,7 +154,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance }, undeleteButton = new SettingsButton { - Text = "Restore all recently deleted beatmaps", + Text = MaintenanceSettingsStrings.RestoreAllRecentlyDeletedBeatmaps, Action = () => { undeleteButton.Enabled.Value = false; diff --git a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs index 73c88b8e71..fa0c06167b 100644 --- a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs +++ b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs @@ -3,6 +3,8 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.Maintenance; using osuTK; @@ -10,7 +12,7 @@ namespace osu.Game.Overlays.Settings.Sections { public class MaintenanceSection : SettingsSection { - public override string Header => "Maintenance"; + public override LocalisableString Header => MaintenanceSettingsStrings.MaintenanceSectionHeader; public override Drawable CreateIcon() => new SpriteIcon { From 3f434c8474f19be27afc46254461bd5bfceeadfe Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Thu, 12 Aug 2021 13:42:16 +0800 Subject: [PATCH 12/83] Resolve code quality issue --- osu.Game/Localisation/GameplaySettingsStrings.cs | 1 - osu.sln.DotSettings | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Localisation/GameplaySettingsStrings.cs b/osu.Game/Localisation/GameplaySettingsStrings.cs index 172387bbb8..4354272ab5 100644 --- a/osu.Game/Localisation/GameplaySettingsStrings.cs +++ b/osu.Game/Localisation/GameplaySettingsStrings.cs @@ -89,7 +89,6 @@ namespace osu.Game.Localisation /// public static LocalisableString IncreaseFirstObjectVisibility => new TranslatableString(getKey(@"increase_first_object_visibility"), @"Increase visibility of first object when visual impairment mods are enabled"); - private static string getKey(string key) => $"{prefix}:{key}"; } } diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 139ee02b96..d884ea31c5 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -304,6 +304,7 @@ AABB API BPM + FPS GC GL GLSL From 2b86416cb268e717633b8f6d65d9772bb1ea022b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 06:27:57 +0300 Subject: [PATCH 13/83] Hide player settings overlay on multi-spectator player loader --- .../Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs | 7 +++++++ osu.Game/Screens/Play/PlayerLoader.cs | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs index 5a1d28e9c4..52e4a6e012 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs @@ -3,6 +3,7 @@ using System; using JetBrains.Annotations; +using osu.Framework.Allocation; using osu.Game.Scoring; using osu.Game.Screens.Menu; using osu.Game.Screens.Play; @@ -19,6 +20,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { } + [BackgroundDependencyLoader] + private void load() + { + PlayerSettingsGroups.Alpha = 0f; + } + protected override void LogoArriving(OsuLogo logo, bool resuming) { } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 5f6b4ca2b0..1f8387ac67 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -48,6 +48,11 @@ namespace osu.Game.Screens.Play protected BeatmapMetadataDisplay MetadataInfo; + /// + /// A fill flow containing the player settings groups, exposed for the ability to hide it from inheritors of the player loader. + /// + protected FillFlowContainer PlayerSettingsGroups; + protected VisualSettings VisualSettings; protected Task LoadTask { get; private set; } @@ -140,7 +145,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - new FillFlowContainer + PlayerSettingsGroups = new FillFlowContainer { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, From c10320f23914fd8f15ff0c5ee30ca943a5de8519 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 06:28:07 +0300 Subject: [PATCH 14/83] Hide and disable player settings overlay on multi-spectator player --- .../Multiplayer/Spectate/MultiSpectatorPlayer.cs | 4 ++++ osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs | 2 +- osu.Game/Screens/Play/HUDOverlay.cs | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index 2c157b0564..71defa2e07 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -4,6 +4,7 @@ using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Scoring; @@ -34,6 +35,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate private void load() { spectatorPlayerClock.WaitingOnFrames.BindTo(waitingOnFrames); + + HUDOverlay.PlayerSettingsOverlay.State.Value = Visibility.Hidden; + HUDOverlay.PlayerSettingsOverlay.State.Disabled = true; } protected override void UpdateAfterChildren() diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index ffcbb06fb3..efd37194d3 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Play.HUD if (e.ControlPressed) { - if (e.Key == Key.H && ReplayLoaded) + if (e.Key == Key.H && ReplayLoaded && !State.Disabled) { ToggleVisibility(); return true; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 2cf2555b3e..919886cae7 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -240,13 +240,17 @@ namespace osu.Game.Screens.Play if (e.NewValue) { - PlayerSettingsOverlay.Show(); + if (!PlayerSettingsOverlay.State.Disabled) + PlayerSettingsOverlay.Show(); + ModDisplay.FadeIn(200); KeyCounter.Margin = new MarginPadding(10) { Bottom = 30 }; } else { - PlayerSettingsOverlay.Hide(); + if (!PlayerSettingsOverlay.State.Disabled) + PlayerSettingsOverlay.Hide(); + ModDisplay.Delay(2000).FadeOut(200); KeyCounter.Margin = new MarginPadding(10); } From 1892db7f37e0d916826fef0d4788da4d78ce2531 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 06:31:39 +0300 Subject: [PATCH 15/83] Add test coverage --- .../Multiplayer/TestSceneMultiSpectatorScreen.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index 65b1d6d53a..ad60582ace 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -6,6 +6,7 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; @@ -13,6 +14,8 @@ using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus; using osu.Game.Rulesets.UI; using osu.Game.Screens.OnlinePlay.Multiplayer.Spectate; using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD; +using osu.Game.Screens.Play.PlayerSettings; using osu.Game.Tests.Beatmaps.IO; using osu.Game.Users; @@ -80,6 +83,19 @@ namespace osu.Game.Tests.Visual.Multiplayer AddWaitStep("wait a bit", 20); } + [Test] + public void TestSpectatorPlayerSettingsHidden() + { + start(new[] { PLAYER_1_ID, PLAYER_2_ID }); + loadSpectateScreen(false); + + AddUntilStep("wait for player loaders", () => this.ChildrenOfType().Count() == 2); + AddAssert("all player loader settings hidden", () => this.ChildrenOfType().All(l => l.ChildrenOfType>().Single().Alpha == 0f)); + + AddUntilStep("wait for players to load", () => spectatorScreen.AllPlayersLoaded); + AddAssert("all player settings hidden", () => this.ChildrenOfType().All(p => p.ChildrenOfType().Single().State.Value == Visibility.Hidden)); + } + [Test] public void TestTeamDisplay() { From cbeecff347b350458f4858ab97722f39c875bccf Mon Sep 17 00:00:00 2001 From: LiangXiang Shen Date: Fri, 13 Aug 2021 12:17:38 +0800 Subject: [PATCH 16/83] Apply suggestions from code review Co-authored-by: Joseph Madamba --- osu.Game/Localisation/GraphicsSettingsStrings.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Localisation/GraphicsSettingsStrings.cs b/osu.Game/Localisation/GraphicsSettingsStrings.cs index 989eaf19b9..0e384f983f 100644 --- a/osu.Game/Localisation/GraphicsSettingsStrings.cs +++ b/osu.Game/Localisation/GraphicsSettingsStrings.cs @@ -55,14 +55,14 @@ namespace osu.Game.Localisation public static LocalisableString Resolution => new TranslatableString(getKey(@"resolution"), @"Resolution"); /// - /// "UI Scaling" + /// "UI scaling" /// - public static LocalisableString UIScaling => new TranslatableString(getKey(@"ui_scaling"), @"UI Scaling"); + public static LocalisableString UIScaling => new TranslatableString(getKey(@"ui_scaling"), @"UI scaling"); /// - /// "Screen Scaling" + /// "Screen scaling" /// - public static LocalisableString ScreenScaling => new TranslatableString(getKey(@"screen_scaling"), @"Screen Scaling"); + public static LocalisableString ScreenScaling => new TranslatableString(getKey(@"screen_scaling"), @"Screen scaling"); /// /// "Horizontal position" @@ -95,14 +95,14 @@ namespace osu.Game.Localisation public static LocalisableString DetailSettingsHeader => new TranslatableString(getKey(@"detail_settings_header"), @"Detail Settings"); /// - /// "Storyboard / Video" + /// "Storyboard / video" /// - public static LocalisableString StoryboardVideo => new TranslatableString(getKey(@"storyboard_video"), @"Storyboard / Video"); + public static LocalisableString StoryboardVideo => new TranslatableString(getKey(@"storyboard_video"), @"Storyboard / video"); /// - /// "Hit Lighting" + /// "Hit lighting" /// - public static LocalisableString HitLighting => new TranslatableString(getKey(@"hit_lighting"), @"Hit Lighting"); + public static LocalisableString HitLighting => new TranslatableString(getKey(@"hit_lighting"), @"Hit lighting"); /// /// "Screenshot format" From 8dc7a925e7e4a05de0f288fa9bee5dc684169f54 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 07:28:57 +0300 Subject: [PATCH 17/83] Expire instead of hiding and disabling visibility state Since it's a temporary change until the spectator interface gets improved, no need to add further logic. --- .../Multiplayer/Spectate/MultiSpectatorPlayer.cs | 4 +--- .../Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs | 2 +- osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs | 2 +- osu.Game/Screens/Play/HUDOverlay.cs | 8 ++------ 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index 71defa2e07..b0ea361dbb 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -4,7 +4,6 @@ using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Graphics.Containers; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Scoring; @@ -36,8 +35,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { spectatorPlayerClock.WaitingOnFrames.BindTo(waitingOnFrames); - HUDOverlay.PlayerSettingsOverlay.State.Value = Visibility.Hidden; - HUDOverlay.PlayerSettingsOverlay.State.Disabled = true; + HUDOverlay.PlayerSettingsOverlay.Expire(); } protected override void UpdateAfterChildren() diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs index 52e4a6e012..f28c2a1d48 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate [BackgroundDependencyLoader] private void load() { - PlayerSettingsGroups.Alpha = 0f; + PlayerSettingsGroups.Expire(); } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index efd37194d3..ffcbb06fb3 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Play.HUD if (e.ControlPressed) { - if (e.Key == Key.H && ReplayLoaded && !State.Disabled) + if (e.Key == Key.H && ReplayLoaded) { ToggleVisibility(); return true; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 919886cae7..2cf2555b3e 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -240,17 +240,13 @@ namespace osu.Game.Screens.Play if (e.NewValue) { - if (!PlayerSettingsOverlay.State.Disabled) - PlayerSettingsOverlay.Show(); - + PlayerSettingsOverlay.Show(); ModDisplay.FadeIn(200); KeyCounter.Margin = new MarginPadding(10) { Bottom = 30 }; } else { - if (!PlayerSettingsOverlay.State.Disabled) - PlayerSettingsOverlay.Hide(); - + PlayerSettingsOverlay.Hide(); ModDisplay.Delay(2000).FadeOut(200); KeyCounter.Margin = new MarginPadding(10); } From e7cf6b2d2337168ecfd0442e3518efa87d7d2c07 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 07:29:55 +0300 Subject: [PATCH 18/83] Expire hold-to-quit button on multi-spectator player --- .../OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index b0ea361dbb..20381e0c48 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -36,6 +36,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate spectatorPlayerClock.WaitingOnFrames.BindTo(waitingOnFrames); HUDOverlay.PlayerSettingsOverlay.Expire(); + HUDOverlay.HoldToQuit.Expire(); } protected override void UpdateAfterChildren() From 34c2b317e240821b5c7038fa0b3d1afb45ac3be5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 07:30:09 +0300 Subject: [PATCH 19/83] Hide song progress bar on multi-spectator player --- .../Multiplayer/Spectate/MultiSpectatorPlayer.cs | 2 ++ osu.Game/Screens/Play/Player.cs | 12 +++++++++++- osu.Game/Screens/Play/SongProgress.cs | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index 20381e0c48..1b1dee5ae2 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -35,6 +35,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { spectatorPlayerClock.WaitingOnFrames.BindTo(waitingOnFrames); + AllowUserSeekingState.Value = false; + AllowUserSeekingState.Disabled = true; HUDOverlay.PlayerSettingsOverlay.Expire(); HUDOverlay.HoldToQuit.Expire(); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 09eaf1c543..dc37464a61 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -77,6 +77,10 @@ namespace osu.Game.Screens.Play protected readonly Bindable LocalUserPlaying = new Bindable(); + protected readonly Bindable AllowUserSeekingState = new Bindable(); + + public IBindable AllowUserSeeking => AllowUserSeekingState; + public int RestartCount; [Resolved] @@ -269,7 +273,13 @@ namespace osu.Game.Screens.Play DrawableRuleset.FrameStableClock.IsCatchingUp.BindValueChanged(_ => updateSampleDisabledState()); - DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState()); + DrawableRuleset.HasReplayLoaded.BindValueChanged(r => + { + if (!AllowUserSeekingState.Disabled) + AllowUserSeekingState.Value = r.NewValue; + + updateGameplayState(); + }); // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index f28622f42e..8debe6243d 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Play if (drawableRuleset != null) { - AllowSeeking.BindTo(drawableRuleset.HasReplayLoaded); + ((IBindable)AllowSeeking).BindTo(player.AllowUserSeeking); referenceClock = drawableRuleset.FrameStableClock; Objects = drawableRuleset.Objects; From fc22e806f44abddf493ab87bbe15f91a14e7c8c2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 07:30:24 +0300 Subject: [PATCH 20/83] Cover newly hidden/expired elements in existing test --- .../Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index ad60582ace..a9004987df 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -90,10 +90,13 @@ namespace osu.Game.Tests.Visual.Multiplayer loadSpectateScreen(false); AddUntilStep("wait for player loaders", () => this.ChildrenOfType().Count() == 2); - AddAssert("all player loader settings hidden", () => this.ChildrenOfType().All(l => l.ChildrenOfType>().Single().Alpha == 0f)); + AddAssert("all player loader settings hidden", () => this.ChildrenOfType().All(l => !l.ChildrenOfType>().Any())); AddUntilStep("wait for players to load", () => spectatorScreen.AllPlayersLoaded); - AddAssert("all player settings hidden", () => this.ChildrenOfType().All(p => p.ChildrenOfType().Single().State.Value == Visibility.Hidden)); + AddUntilStep("all interactive elements removed", () => this.ChildrenOfType().All(p => + !p.ChildrenOfType().Any() && + !p.ChildrenOfType().Any() && + !p.ChildrenOfType().Single().ShowHandle)); } [Test] From 8910781bcdb4dac3a18e17c1962c6dd34421b550 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 17:39:09 +0900 Subject: [PATCH 21/83] Move listing polling component to LoungeSubScreen --- .../TestSceneLoungeRoomsContainer.cs | 2 +- .../TestSceneMultiplayerRoomManager.cs | 314 +++++++++--------- .../TestScenePlaylistsMatchSettingsOverlay.cs | 12 + osu.Game/Online/Rooms/Room.cs | 2 +- .../Components/ListingPollingComponent.cs | 23 +- .../OnlinePlay/Components/RoomManager.cs | 73 ++-- .../Components/RoomPollingComponent.cs | 15 +- .../Components/SelectionPollingComponent.cs | 14 +- osu.Game/Screens/OnlinePlay/IRoomManager.cs | 11 +- .../OnlinePlay/Lounge/LoungeSubScreen.cs | 53 ++- .../OnlinePlay/Multiplayer/Multiplayer.cs | 30 -- .../Multiplayer/MultiplayerLoungeSubScreen.cs | 33 ++ .../Multiplayer/MultiplayerMatchSubScreen.cs | 9 +- .../Multiplayer/MultiplayerRoomManager.cs | 73 ---- .../Screens/OnlinePlay/OnlinePlayScreen.cs | 22 +- .../Screens/OnlinePlay/Playlists/Playlists.cs | 39 --- .../Playlists/PlaylistsLoungeSubScreen.cs | 3 + .../Playlists/PlaylistsRoomManager.cs | 21 -- .../Visual/OnlinePlay/BasicTestRoomManager.cs | 10 +- 19 files changed, 308 insertions(+), 451 deletions(-) delete mode 100644 osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomManager.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index bcbdcd2a4f..f3d961a646 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -74,7 +74,7 @@ namespace osu.Game.Tests.Visual.Multiplayer var room = RoomManager.Rooms[1]; RoomManager.RemoveRoom(room); - RoomManager.AddRoom(room); + RoomManager.AddOrUpdateRoom(room); }); AddAssert("no selection", () => checkRoomSelected(null)); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs index b17427a30b..15e9112c47 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs @@ -1,157 +1,157 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using NUnit.Framework; -using osu.Framework.Testing; -using osu.Game.Online.Rooms; -using osu.Game.Screens.OnlinePlay.Components; -using osu.Game.Tests.Beatmaps; -using osu.Game.Tests.Visual.OnlinePlay; - -namespace osu.Game.Tests.Visual.Multiplayer -{ - [HeadlessTest] - public class TestSceneMultiplayerRoomManager : MultiplayerTestScene - { - protected override OnlinePlayTestSceneDependencies CreateOnlinePlayDependencies() => new TestDependencies(); - - public TestSceneMultiplayerRoomManager() - : base(false) - { - } - - [Test] - public void TestPollsInitially() - { - AddStep("create room manager with a few rooms", () => - { - RoomManager.CreateRoom(createRoom(r => r.Name.Value = "1")); - RoomManager.PartRoom(); - RoomManager.CreateRoom(createRoom(r => r.Name.Value = "2")); - RoomManager.PartRoom(); - RoomManager.ClearRooms(); - }); - - AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2); - AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value); - } - - [Test] - public void TestRoomsClearedOnDisconnection() - { - AddStep("create room manager with a few rooms", () => - { - RoomManager.CreateRoom(createRoom()); - RoomManager.PartRoom(); - RoomManager.CreateRoom(createRoom()); - RoomManager.PartRoom(); - }); - - AddStep("disconnect", () => Client.Disconnect()); - - AddAssert("rooms cleared", () => ((RoomManager)RoomManager).Rooms.Count == 0); - AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value); - } - - [Test] - public void TestRoomsPolledOnReconnect() - { - AddStep("create room manager with a few rooms", () => - { - RoomManager.CreateRoom(createRoom()); - RoomManager.PartRoom(); - RoomManager.CreateRoom(createRoom()); - RoomManager.PartRoom(); - }); - - AddStep("disconnect", () => Client.Disconnect()); - AddStep("connect", () => Client.Connect()); - - AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2); - AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value); - } - - [Test] - public void TestRoomsNotPolledWhenJoined() - { - AddStep("create room manager with a room", () => - { - RoomManager.CreateRoom(createRoom()); - RoomManager.ClearRooms(); - }); - - AddAssert("manager not polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 0); - AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value); - } - - [Test] - public void TestMultiplayerRoomJoinedWhenCreated() - { - AddStep("create room manager with a room", () => - { - RoomManager.CreateRoom(createRoom()); - }); - - AddUntilStep("multiplayer room joined", () => Client.Room != null); - } - - [Test] - public void TestMultiplayerRoomPartedWhenAPIRoomParted() - { - AddStep("create room manager with a room", () => - { - RoomManager.CreateRoom(createRoom()); - RoomManager.PartRoom(); - }); - - AddAssert("multiplayer room parted", () => Client.Room == null); - } - - [Test] - public void TestMultiplayerRoomJoinedWhenAPIRoomJoined() - { - AddStep("create room manager with a room", () => - { - var r = createRoom(); - RoomManager.CreateRoom(r); - RoomManager.PartRoom(); - RoomManager.JoinRoom(r); - }); - - AddUntilStep("multiplayer room joined", () => Client.Room != null); - } - - private Room createRoom(Action initFunc = null) - { - var room = new Room - { - Name = - { - Value = "test room" - }, - Playlist = - { - new PlaylistItem - { - Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo }, - Ruleset = { Value = Ruleset.Value } - } - } - }; - - initFunc?.Invoke(room); - return room; - } - - private class TestDependencies : MultiplayerTestSceneDependencies - { - public TestDependencies() - { - // Need to set these values as early as possible. - RoomManager.TimeBetweenListingPolls.Value = 1; - RoomManager.TimeBetweenSelectionPolls.Value = 1; - } - } - } -} +// // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// // See the LICENCE file in the repository root for full licence text. +// +// using System; +// using NUnit.Framework; +// using osu.Framework.Testing; +// using osu.Game.Online.Rooms; +// using osu.Game.Screens.OnlinePlay.Components; +// using osu.Game.Tests.Beatmaps; +// using osu.Game.Tests.Visual.OnlinePlay; +// +// namespace osu.Game.Tests.Visual.Multiplayer +// { +// [HeadlessTest] +// public class TestSceneMultiplayerRoomManager : MultiplayerTestScene +// { +// protected override OnlinePlayTestSceneDependencies CreateOnlinePlayDependencies() => new TestDependencies(); +// +// public TestSceneMultiplayerRoomManager() +// : base(false) +// { +// } +// +// [Test] +// public void TestPollsInitially() +// { +// AddStep("create room manager with a few rooms", () => +// { +// RoomManager.CreateRoom(createRoom(r => r.Name.Value = "1")); +// RoomManager.PartRoom(); +// RoomManager.CreateRoom(createRoom(r => r.Name.Value = "2")); +// RoomManager.PartRoom(); +// RoomManager.ClearRooms(); +// }); +// +// AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2); +// AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value); +// } +// +// [Test] +// public void TestRoomsClearedOnDisconnection() +// { +// AddStep("create room manager with a few rooms", () => +// { +// RoomManager.CreateRoom(createRoom()); +// RoomManager.PartRoom(); +// RoomManager.CreateRoom(createRoom()); +// RoomManager.PartRoom(); +// }); +// +// AddStep("disconnect", () => Client.Disconnect()); +// +// AddAssert("rooms cleared", () => ((RoomManager)RoomManager).Rooms.Count == 0); +// AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value); +// } +// +// [Test] +// public void TestRoomsPolledOnReconnect() +// { +// AddStep("create room manager with a few rooms", () => +// { +// RoomManager.CreateRoom(createRoom()); +// RoomManager.PartRoom(); +// RoomManager.CreateRoom(createRoom()); +// RoomManager.PartRoom(); +// }); +// +// AddStep("disconnect", () => Client.Disconnect()); +// AddStep("connect", () => Client.Connect()); +// +// AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2); +// AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value); +// } +// +// [Test] +// public void TestRoomsNotPolledWhenJoined() +// { +// AddStep("create room manager with a room", () => +// { +// RoomManager.CreateRoom(createRoom()); +// RoomManager.ClearRooms(); +// }); +// +// AddAssert("manager not polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 0); +// AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value); +// } +// +// [Test] +// public void TestMultiplayerRoomJoinedWhenCreated() +// { +// AddStep("create room manager with a room", () => +// { +// RoomManager.CreateRoom(createRoom()); +// }); +// +// AddUntilStep("multiplayer room joined", () => Client.Room != null); +// } +// +// [Test] +// public void TestMultiplayerRoomPartedWhenAPIRoomParted() +// { +// AddStep("create room manager with a room", () => +// { +// RoomManager.CreateRoom(createRoom()); +// RoomManager.PartRoom(); +// }); +// +// AddAssert("multiplayer room parted", () => Client.Room == null); +// } +// +// [Test] +// public void TestMultiplayerRoomJoinedWhenAPIRoomJoined() +// { +// AddStep("create room manager with a room", () => +// { +// var r = createRoom(); +// RoomManager.CreateRoom(r); +// RoomManager.PartRoom(); +// RoomManager.JoinRoom(r); +// }); +// +// AddUntilStep("multiplayer room joined", () => Client.Room != null); +// } +// +// private Room createRoom(Action initFunc = null) +// { +// var room = new Room +// { +// Name = +// { +// Value = "test room" +// }, +// Playlist = +// { +// new PlaylistItem +// { +// Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo }, +// Ruleset = { Value = Ruleset.Value } +// } +// } +// }; +// +// initFunc?.Invoke(room); +// return room; +// } +// +// private class TestDependencies : MultiplayerTestSceneDependencies +// { +// public TestDependencies() +// { +// // Need to set these values as early as possible. +// RoomManager.TimeBetweenListingPolls.Value = 1; +// RoomManager.TimeBetweenSelectionPolls.Value = 1; +// } +// } +// } +// } diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs index cdc655500d..79af2d3099 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs @@ -141,6 +141,18 @@ namespace osu.Game.Tests.Visual.Playlists public IBindableList Rooms => null; + public void AddOrUpdateRoom(Room room) + { + } + + public void RemoveRoom(Room room) + { + } + + public void ClearRooms() + { + } + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { if (CreateRequested == null) diff --git a/osu.Game/Online/Rooms/Room.cs b/osu.Game/Online/Rooms/Room.cs index 4bd5b1a788..364336783d 100644 --- a/osu.Game/Online/Rooms/Room.cs +++ b/osu.Game/Online/Rooms/Room.cs @@ -134,7 +134,7 @@ namespace osu.Game.Online.Rooms /// The position of this in the list. This is not read from or written to the API. /// [JsonIgnore] - public readonly Bindable Position = new Bindable(-1); + public readonly Bindable Position = new Bindable(-1); public Room() { diff --git a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs index e50784fcbe..f686326d08 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs @@ -1,6 +1,7 @@ // 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 System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -14,6 +15,9 @@ namespace osu.Game.Screens.OnlinePlay.Components /// public class ListingPollingComponent : RoomPollingComponent { + public IBindable HasPolledOnce => hasPolledOnce; + private readonly Bindable hasPolledOnce = new Bindable(); + [Resolved] private Bindable currentFilter { get; set; } @@ -25,7 +29,9 @@ namespace osu.Game.Screens.OnlinePlay.Components { currentFilter.BindValueChanged(_ => { - NotifyRoomsReceived(null); + RoomManager.ClearRooms(); + hasPolledOnce.Value = false; + if (IsLoaded) PollImmediately(); }); @@ -45,17 +51,16 @@ namespace osu.Game.Screens.OnlinePlay.Components pollReq.Success += result => { - for (int i = 0; i < result.Count; i++) + foreach (var existing in RoomManager.Rooms.ToArray()) { - if (result[i].RoomID.Value == selectedRoom.Value?.RoomID.Value) - { - // The listing request always has less information than the opened room, so don't include it. - result[i] = selectedRoom.Value; - break; - } + if (result.All(r => r.RoomID.Value != existing.RoomID.Value)) + RoomManager.RemoveRoom(existing); } - NotifyRoomsReceived(result); + foreach (var incoming in result) + RoomManager.AddOrUpdateRoom(incoming); + + hasPolledOnce.Value = true; tcs.SetResult(true); }; diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs index 422576648c..ab92adcac7 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs @@ -8,7 +8,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Online.API; @@ -17,15 +16,12 @@ using osu.Game.Rulesets; namespace osu.Game.Screens.OnlinePlay.Components { - public abstract class RoomManager : CompositeDrawable, IRoomManager + public class RoomManager : Component, IRoomManager { public event Action RoomsUpdated; private readonly BindableList rooms = new BindableList(); - public IBindable InitialRoomsReceived => initialRoomsReceived; - private readonly Bindable initialRoomsReceived = new Bindable(); - public IBindableList Rooms => rooms; protected IBindable JoinedRoom => joinedRoom; @@ -40,15 +36,9 @@ namespace osu.Game.Screens.OnlinePlay.Components [Resolved] private IAPIProvider api { get; set; } - protected RoomManager() + public RoomManager() { RelativeSizeAxes = Axes.Both; - - InternalChildren = CreatePollingComponents().Select(p => - { - p.RoomsReceived = onRoomsReceived; - return p; - }).ToList(); } protected override void Dispose(bool isDisposing) @@ -118,56 +108,41 @@ namespace osu.Game.Screens.OnlinePlay.Components private readonly HashSet ignoredRooms = new HashSet(); - private void onRoomsReceived(List received) + public void AddOrUpdateRoom(Room room) { - if (received == null) - { - ClearRooms(); + Debug.Assert(room.RoomID.Value != null); + + if (ignoredRooms.Contains(room.RoomID.Value.Value)) return; - } - // Remove past matches - foreach (var r in rooms.ToList()) + room.Position.Value = -room.RoomID.Value.Value; + + try { - if (received.All(e => e.RoomID.Value != r.RoomID.Value)) - rooms.Remove(r); + update(room, room); + addRoom(room); } - - for (int i = 0; i < received.Count; i++) + catch (Exception ex) { - var room = received[i]; + Logger.Error(ex, $"Failed to update room: {room.Name.Value}."); - Debug.Assert(room.RoomID.Value != null); - - if (ignoredRooms.Contains(room.RoomID.Value.Value)) - continue; - - room.Position.Value = i; - - try - { - update(room, room); - addRoom(room); - } - catch (Exception ex) - { - Logger.Error(ex, $"Failed to update room: {room.Name.Value}."); - - ignoredRooms.Add(room.RoomID.Value.Value); - rooms.Remove(room); - } + ignoredRooms.Add(room.RoomID.Value.Value); + rooms.Remove(room); } - RoomsUpdated?.Invoke(); - initialRoomsReceived.Value = true; + notifyRoomsUpdated(); } - protected void RemoveRoom(Room room) => rooms.Remove(room); + public void RemoveRoom(Room room) + { + rooms.Remove(room); + notifyRoomsUpdated(); + } - protected void ClearRooms() + public void ClearRooms() { rooms.Clear(); - initialRoomsReceived.Value = false; + notifyRoomsUpdated(); } /// @@ -196,6 +171,6 @@ namespace osu.Game.Screens.OnlinePlay.Components existing.CopyFrom(room); } - protected abstract IEnumerable CreatePollingComponents(); + private void notifyRoomsUpdated() => Scheduler.AddOnce(() => RoomsUpdated?.Invoke()); } } diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs index b2ea3a05d6..95b4c4284c 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs @@ -1,29 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Game.Online; using osu.Game.Online.API; -using osu.Game.Online.Rooms; namespace osu.Game.Screens.OnlinePlay.Components { public abstract class RoomPollingComponent : PollingComponent { - /// - /// Invoked when any s have been received from the API. - /// - /// Any s present locally but not returned by this event are to be removed from display. - /// If null, the display of local rooms is reset to an initial state. - /// - /// - public Action> RoomsReceived; - [Resolved] protected IAPIProvider API { get; private set; } - protected void NotifyRoomsReceived(List rooms) => RoomsReceived?.Invoke(rooms); + [Resolved] + protected IRoomManager RoomManager { get; set; } } } diff --git a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs index dcf3c94b76..88d9469f8c 100644 --- a/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/SelectionPollingComponent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -48,17 +46,7 @@ namespace osu.Game.Screens.OnlinePlay.Components pollReq.Success += result => { - // existing rooms need to be ordered by their position because the received of NotifyRoomsReceives expects to be able to sort them based on this order. - var rooms = new List(roomManager.Rooms.OrderBy(r => r.Position.Value)); - - int index = rooms.FindIndex(r => r.RoomID.Value == result.RoomID.Value); - - if (index < 0) - return; - - rooms[index] = result; - - NotifyRoomsReceived(rooms); + RoomManager.AddOrUpdateRoom(result); tcs.SetResult(true); }; diff --git a/osu.Game/Screens/OnlinePlay/IRoomManager.cs b/osu.Game/Screens/OnlinePlay/IRoomManager.cs index 34c1393ff1..baf84e25f9 100644 --- a/osu.Game/Screens/OnlinePlay/IRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/IRoomManager.cs @@ -18,16 +18,17 @@ namespace osu.Game.Screens.OnlinePlay /// event Action RoomsUpdated; - /// - /// Whether an initial listing of rooms has been received. - /// - IBindable InitialRoomsReceived { get; } - /// /// All the active s. /// IBindableList Rooms { get; } + void AddOrUpdateRoom(Room room); + + void RemoveRoom(Room room); + + void ClearRooms(); + /// /// Creates a new . /// diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 7249ccdd93..50f7baa44c 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -12,14 +12,17 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Framework.Logging; using osu.Framework.Screens; using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using osu.Game.Input; using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Rulesets; +using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Users; @@ -41,10 +44,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge AutoSizeAxes = Axes.Both }; - private readonly IBindable initialRoomsReceived = new Bindable(); - private readonly IBindable operationInProgress = new Bindable(); - - private LoadingLayer loadingLayer; + protected ListingPollingComponent ListingPollingComponent { get; private set; } [Resolved] private Bindable selectedRoom { get; set; } @@ -61,9 +61,15 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [Resolved] private IBindable ruleset { get; set; } + [Resolved(CanBeNull = true)] + private IdleTracker idleTracker { get; set; } + [CanBeNull] private IDisposable joiningRoomOperation { get; set; } + private readonly IBindable operationInProgress = new Bindable(); + private readonly IBindable isIdle = new BindableBool(); + private LoadingLayer loadingLayer; private RoomsContainer roomsContainer; private SearchTextBox searchTextBox; private Dropdown statusDropdown; @@ -77,6 +83,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge InternalChildren = new Drawable[] { + ListingPollingComponent = CreatePollingComponent(), new Container { RelativeSizeAxes = Axes.Both, @@ -176,8 +183,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced()); ruleset.BindValueChanged(_ => UpdateFilter()); - initialRoomsReceived.BindTo(RoomManager.InitialRoomsReceived); - initialRoomsReceived.BindValueChanged(_ => updateLoadingLayer()); + ListingPollingComponent.HasPolledOnce.BindValueChanged(_ => updateLoadingLayer()); + + if (idleTracker != null) + { + isIdle.BindTo(idleTracker.IsIdle); + isIdle.BindValueChanged(_ => updatePollingRate(), true); + } if (ongoingOperationTracker != null) { @@ -231,7 +243,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge public override void OnEntering(IScreen last) { base.OnEntering(last); - onReturning(); } @@ -266,11 +277,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void onReturning() { + updatePollingRate(); searchTextBox.HoldFocus = true; } private void onLeaving() { + updatePollingRate(); searchTextBox.HoldFocus = false; // ensure any password prompt is dismissed. @@ -316,6 +329,24 @@ namespace osu.Game.Screens.OnlinePlay.Lounge this.Push(CreateRoomSubScreen(room)); } + private void updateLoadingLayer() + { + if (operationInProgress.Value || !ListingPollingComponent.HasPolledOnce.Value) + loadingLayer.Show(); + else + loadingLayer.Hide(); + } + + private void updatePollingRate() + { + if (!this.IsCurrentScreen()) + ListingPollingComponent.TimeBetweenPolls.Value = 0; + else + ListingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000; + + Logger.Log($"Polling adjusted (listing: {ListingPollingComponent.TimeBetweenPolls.Value})"); + } + protected abstract OsuButton CreateNewRoomButton(); /// @@ -326,13 +357,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge protected abstract RoomSubScreen CreateRoomSubScreen(Room room); - private void updateLoadingLayer() - { - if (operationInProgress.Value || !initialRoomsReceived.Value) - loadingLayer.Show(); - else - loadingLayer.Hide(); - } + protected abstract ListingPollingComponent CreatePollingComponent(); private class LoungeSearchTextBox : SearchTextBox { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs index 45928505bb..58b5b7bbeb 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Multiplayer.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Logging; using osu.Framework.Screens; using osu.Game.Online.Multiplayer; using osu.Game.Screens.OnlinePlay.Components; @@ -23,35 +22,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer client.ChangeState(MultiplayerUserState.Idle); } - protected override void UpdatePollingRate(bool isIdle) - { - var multiplayerRoomManager = (MultiplayerRoomManager)RoomManager; - - if (!this.IsCurrentScreen()) - { - multiplayerRoomManager.TimeBetweenListingPolls.Value = 0; - multiplayerRoomManager.TimeBetweenSelectionPolls.Value = 0; - } - else - { - switch (CurrentSubScreen) - { - case LoungeSubScreen _: - multiplayerRoomManager.TimeBetweenListingPolls.Value = isIdle ? 120000 : 15000; - multiplayerRoomManager.TimeBetweenSelectionPolls.Value = isIdle ? 120000 : 15000; - break; - - // Don't poll inside the match or anywhere else. - default: - multiplayerRoomManager.TimeBetweenListingPolls.Value = 0; - multiplayerRoomManager.TimeBetweenSelectionPolls.Value = 0; - break; - } - } - - Logger.Log($"Polling adjusted (listing: {multiplayerRoomManager.TimeBetweenListingPolls.Value}, selection: {multiplayerRoomManager.TimeBetweenSelectionPolls.Value})"); - } - protected override string ScreenTitle => "Multiplayer"; protected override RoomManager CreateRoomManager() => new MultiplayerRoomManager(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index ad7882abc2..db6096e93b 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -1,12 +1,16 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Threading.Tasks; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Logging; +using osu.Framework.Screens; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Online.Rooms; +using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; @@ -21,6 +25,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient client { get; set; } + public override void OnResuming(IScreen last) + { + base.OnResuming(last); + ListingPollingComponent.PollImmediately(); + } + protected override FilterCriteria CreateFilterCriteria() { var criteria = base.CreateFilterCriteria(); @@ -39,6 +49,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer protected override RoomSubScreen CreateRoomSubScreen(Room room) => new MultiplayerMatchSubScreen(room); + protected override ListingPollingComponent CreatePollingComponent() => new MultiplayerListingPollingComponent(); + protected override void OpenNewRoom(Room room) { if (client?.IsConnected.Value != true) @@ -49,5 +61,26 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer base.OpenNewRoom(room); } + + private class MultiplayerListingPollingComponent : ListingPollingComponent + { + public readonly IBindable AllowPolling = new Bindable(); + + protected override void LoadComplete() + { + base.LoadComplete(); + + AllowPolling.BindValueChanged(allowPolling => + { + if (!allowPolling.NewValue) + return; + + if (IsLoaded) + PollImmediately(); + }); + } + + protected override Task Poll() => !AllowPolling.Value ? Task.CompletedTask : base.Poll(); + } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index a8e44dd56c..ec011634b1 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -49,9 +49,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private OngoingOperationTracker ongoingOperationTracker { get; set; } [Resolved] - private Bindable currentRoom { get; set; } - - private MultiplayerMatchSettingsOverlay settingsOverlay; + private Bindable currentRoom { get; set; } // Todo: This should not exist. private readonly IBindable isConnected = new Bindable(); @@ -59,6 +57,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private IDisposable readyClickOperation; private GridContainer mainContent; + private MultiplayerMatchSettingsOverlay settingsOverlay; public MultiplayerMatchSubScreen(Room room) { @@ -324,6 +323,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public override bool OnExiting(IScreen next) { + // We don't know whether we're the only participant in the room, and whether the room will close after we leave it as a result. + // To work around this, temporarily remove the room until the next listing poll retrieves it. + RoomManager?.RemoveRoom(currentRoom.Value); + // the room may not be left immediately after a disconnection due to async flow, // so checking the IsConnected status is also required. if (client.Room == null || !client.IsConnected.Value) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs index cbba4babe5..ae8c3113ff 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs @@ -2,9 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ExceptionExtensions; @@ -21,13 +19,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient multiplayerClient { get; set; } - public readonly Bindable TimeBetweenListingPolls = new Bindable(); - public readonly Bindable TimeBetweenSelectionPolls = new Bindable(); private readonly IBindable isConnected = new Bindable(); private readonly Bindable allowPolling = new Bindable(); - private ListingPollingComponent listingPollingComponent; - protected override void LoadComplete() { base.LoadComplete(); @@ -64,19 +58,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer if (JoinedRoom.Value == null) return; - var joinedRoom = JoinedRoom.Value; - base.PartRoom(); - multiplayerClient.LeaveRoom(); - - // Todo: This is not the way to do this. Basically when we're the only participant and the room closes, there's no way to know if this is actually the case. - // This is delayed one frame because upon exiting the match subscreen, multiplayer updates the polling rate and messes with polling. - Schedule(() => - { - RemoveRoom(joinedRoom); - listingPollingComponent.PollImmediately(); - }); } private void joinMultiplayerRoom(Room room, string password, Action onSuccess = null, Action onError = null) @@ -108,61 +91,5 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer // Don't poll when not connected or when a room has been joined. allowPolling.Value = isConnected.Value && JoinedRoom.Value == null; } - - protected override IEnumerable CreatePollingComponents() => new RoomPollingComponent[] - { - listingPollingComponent = new MultiplayerListingPollingComponent - { - TimeBetweenPolls = { BindTarget = TimeBetweenListingPolls }, - AllowPolling = { BindTarget = allowPolling } - }, - new MultiplayerSelectionPollingComponent - { - TimeBetweenPolls = { BindTarget = TimeBetweenSelectionPolls }, - AllowPolling = { BindTarget = allowPolling } - } - }; - - private class MultiplayerListingPollingComponent : ListingPollingComponent - { - public readonly IBindable AllowPolling = new Bindable(); - - protected override void LoadComplete() - { - base.LoadComplete(); - - AllowPolling.BindValueChanged(allowPolling => - { - if (!allowPolling.NewValue) - return; - - if (IsLoaded) - PollImmediately(); - }); - } - - protected override Task Poll() => !AllowPolling.Value ? Task.CompletedTask : base.Poll(); - } - - private class MultiplayerSelectionPollingComponent : SelectionPollingComponent - { - public readonly IBindable AllowPolling = new Bindable(); - - protected override void LoadComplete() - { - base.LoadComplete(); - - AllowPolling.BindValueChanged(allowPolling => - { - if (!allowPolling.NewValue) - return; - - if (IsLoaded) - PollImmediately(); - }); - } - - protected override Task Poll() => !AllowPolling.Value ? Task.CompletedTask : base.Poll(); - } } } diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index c2ad0285b1..cfb19ca3d7 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -13,7 +13,6 @@ using osu.Framework.Logging; using osu.Framework.Screens; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics.Containers; -using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Overlays; @@ -43,8 +42,6 @@ namespace osu.Game.Screens.OnlinePlay private LoungeSubScreen loungeSubScreen; private ScreenStack screenStack; - private readonly IBindable isIdle = new BindableBool(); - [Cached(Type = typeof(IRoomManager))] protected RoomManager RoomManager { get; private set; } @@ -66,9 +63,6 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] protected IAPIProvider API { get; private set; } - [Resolved(CanBeNull = true)] - private IdleTracker idleTracker { get; set; } - [Resolved(CanBeNull = true)] private OsuLogo logo { get; set; } @@ -151,12 +145,6 @@ namespace osu.Game.Screens.OnlinePlay apiState.BindTo(API.State); apiState.BindValueChanged(onlineStateChanged, true); - - if (idleTracker != null) - { - isIdle.BindTo(idleTracker.IsIdle); - isIdle.BindValueChanged(idle => UpdatePollingRate(idle.NewValue), true); - } } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) @@ -166,8 +154,6 @@ namespace osu.Game.Screens.OnlinePlay return dependencies; } - protected abstract void UpdatePollingRate(bool isIdle); - private void forcefullyExit() { // This is temporary since we don't currently have a way to force screens to be exited @@ -203,8 +189,6 @@ namespace osu.Game.Screens.OnlinePlay screenStack.CurrentScreen.OnResuming(last); base.OnResuming(last); - - UpdatePollingRate(isIdle.Value); } public override void OnSuspending(IScreen next) @@ -214,8 +198,6 @@ namespace osu.Game.Screens.OnlinePlay Debug.Assert(screenStack.CurrentScreen != null); screenStack.CurrentScreen.OnSuspending(next); - - UpdatePollingRate(isIdle.Value); } public override bool OnExiting(IScreen next) @@ -279,15 +261,13 @@ namespace osu.Game.Screens.OnlinePlay if (newScreen is IOsuScreen newOsuScreen) ((IBindable)Activity).BindTo(newOsuScreen.Activity); - - UpdatePollingRate(isIdle.Value); } protected IScreen CurrentSubScreen => screenStack.CurrentScreen; protected abstract string ScreenTitle { get; } - protected abstract RoomManager CreateRoomManager(); + protected virtual RoomManager CreateRoomManager() => new RoomManager(); protected abstract LoungeSubScreen CreateLounge(); diff --git a/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs b/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs index 6a78e24ba1..1edeef77df 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/Playlists.cs @@ -1,53 +1,14 @@ // 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.Logging; -using osu.Framework.Screens; -using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Lounge; -using osu.Game.Screens.OnlinePlay.Match; namespace osu.Game.Screens.OnlinePlay.Playlists { public class Playlists : OnlinePlayScreen { - protected override void UpdatePollingRate(bool isIdle) - { - var playlistsManager = (PlaylistsRoomManager)RoomManager; - - if (!this.IsCurrentScreen()) - { - playlistsManager.TimeBetweenListingPolls.Value = 0; - playlistsManager.TimeBetweenSelectionPolls.Value = 0; - } - else - { - switch (CurrentSubScreen) - { - case LoungeSubScreen _: - playlistsManager.TimeBetweenListingPolls.Value = isIdle ? 120000 : 15000; - playlistsManager.TimeBetweenSelectionPolls.Value = isIdle ? 120000 : 15000; - break; - - case RoomSubScreen _: - playlistsManager.TimeBetweenListingPolls.Value = 0; - playlistsManager.TimeBetweenSelectionPolls.Value = isIdle ? 30000 : 5000; - break; - - default: - playlistsManager.TimeBetweenListingPolls.Value = 0; - playlistsManager.TimeBetweenSelectionPolls.Value = 0; - break; - } - } - - Logger.Log($"Polling adjusted (listing: {playlistsManager.TimeBetweenListingPolls.Value}, selection: {playlistsManager.TimeBetweenSelectionPolls.Value})"); - } - protected override string ScreenTitle => "Playlists"; - protected override RoomManager CreateRoomManager() => new PlaylistsRoomManager(); - protected override LoungeSubScreen CreateLounge() => new PlaylistsLoungeSubScreen(); } } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs index eee4d4f407..dced9b8691 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.Rooms; +using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; @@ -66,6 +67,8 @@ namespace osu.Game.Screens.OnlinePlay.Playlists protected override RoomSubScreen CreateRoomSubScreen(Room room) => new PlaylistsRoomSubScreen(room); + protected override ListingPollingComponent CreatePollingComponent() => new ListingPollingComponent(); + private enum PlaylistsCategory { Any, diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomManager.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomManager.cs deleted file mode 100644 index c55d1c3e94..0000000000 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomManager.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Collections.Generic; -using osu.Framework.Bindables; -using osu.Game.Screens.OnlinePlay.Components; - -namespace osu.Game.Screens.OnlinePlay.Playlists -{ - public class PlaylistsRoomManager : RoomManager - { - public readonly Bindable TimeBetweenListingPolls = new Bindable(); - public readonly Bindable TimeBetweenSelectionPolls = new Bindable(); - - protected override IEnumerable CreatePollingComponents() => new RoomPollingComponent[] - { - new ListingPollingComponent { TimeBetweenPolls = { BindTarget = TimeBetweenListingPolls } }, - new SelectionPollingComponent { TimeBetweenPolls = { BindTarget = TimeBetweenSelectionPolls } } - }; - } -} diff --git a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs index d37a64fa4b..2e9c0d1d53 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs @@ -33,10 +33,10 @@ namespace osu.Game.Tests.Visual.OnlinePlay room.RoomID.Value ??= Rooms.Select(r => r.RoomID.Value).Where(id => id != null).Select(id => id.Value).DefaultIfEmpty().Max() + 1; onSuccess?.Invoke(room); - AddRoom(room); + AddOrUpdateRoom(room); } - public void AddRoom(Room room) + public void AddOrUpdateRoom(Room room) { Rooms.Add(room); RoomsUpdated?.Invoke(); @@ -48,6 +48,12 @@ namespace osu.Game.Tests.Visual.OnlinePlay RoomsUpdated?.Invoke(); } + public void ClearRooms() + { + Rooms.Clear(); + RoomsUpdated?.Invoke(); + } + public void JoinRoom(Room room, string password, Action onSuccess = null, Action onError = null) { JoinRoomRequested?.Invoke(room, password); From 7cbf4c48edc94af45f10468eb34ca24565d55e28 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 17:59:18 +0900 Subject: [PATCH 22/83] Fix multiplayer polling when not connected --- .../OnlinePlay/Lounge/LoungeSubScreen.cs | 15 ++++---- .../Multiplayer/MultiplayerLoungeSubScreen.cs | 37 ++++++++++++++----- .../Multiplayer/MultiplayerRoomManager.cs | 22 ----------- 3 files changed, 34 insertions(+), 40 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 50f7baa44c..4525599a52 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -44,8 +44,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge AutoSizeAxes = Axes.Both }; - protected ListingPollingComponent ListingPollingComponent { get; private set; } - [Resolved] private Bindable selectedRoom { get; set; } @@ -73,6 +71,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private RoomsContainer roomsContainer; private SearchTextBox searchTextBox; private Dropdown statusDropdown; + private ListingPollingComponent listingPollingComponent; [BackgroundDependencyLoader] private void load() @@ -83,7 +82,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge InternalChildren = new Drawable[] { - ListingPollingComponent = CreatePollingComponent(), + listingPollingComponent = CreatePollingComponent(), new Container { RelativeSizeAxes = Axes.Both, @@ -183,7 +182,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced()); ruleset.BindValueChanged(_ => UpdateFilter()); - ListingPollingComponent.HasPolledOnce.BindValueChanged(_ => updateLoadingLayer()); + listingPollingComponent.HasPolledOnce.BindValueChanged(_ => updateLoadingLayer()); if (idleTracker != null) { @@ -331,7 +330,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void updateLoadingLayer() { - if (operationInProgress.Value || !ListingPollingComponent.HasPolledOnce.Value) + if (operationInProgress.Value || !listingPollingComponent.HasPolledOnce.Value) loadingLayer.Show(); else loadingLayer.Hide(); @@ -340,11 +339,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void updatePollingRate() { if (!this.IsCurrentScreen()) - ListingPollingComponent.TimeBetweenPolls.Value = 0; + listingPollingComponent.TimeBetweenPolls.Value = 0; else - ListingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000; + listingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000; - Logger.Log($"Polling adjusted (listing: {ListingPollingComponent.TimeBetweenPolls.Value})"); + Logger.Log($"Polling adjusted (listing: {listingPollingComponent.TimeBetweenPolls.Value})"); } protected abstract OsuButton CreateNewRoomButton(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index db6096e93b..3f20202ec7 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -25,10 +25,23 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient client { get; set; } + private MultiplayerListingPollingComponent listingPollingComponent; + + private readonly IBindable isConnected = new Bindable(); + private readonly Bindable allowPolling = new Bindable(); + + protected override void LoadComplete() + { + base.LoadComplete(); + + isConnected.BindTo(client.IsConnected); + isConnected.BindValueChanged(c => Scheduler.AddOnce(() => listingPollingComponent.AllowPolling = c.NewValue)); + } + public override void OnResuming(IScreen last) { base.OnResuming(last); - ListingPollingComponent.PollImmediately(); + listingPollingComponent.PollImmediately(); } protected override FilterCriteria CreateFilterCriteria() @@ -49,7 +62,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer protected override RoomSubScreen CreateRoomSubScreen(Room room) => new MultiplayerMatchSubScreen(room); - protected override ListingPollingComponent CreatePollingComponent() => new MultiplayerListingPollingComponent(); + protected override ListingPollingComponent CreatePollingComponent() => listingPollingComponent = new MultiplayerListingPollingComponent(); protected override void OpenNewRoom(Room room) { @@ -64,23 +77,27 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private class MultiplayerListingPollingComponent : ListingPollingComponent { - public readonly IBindable AllowPolling = new Bindable(); + private bool allowPolling; - protected override void LoadComplete() + public bool AllowPolling { - base.LoadComplete(); - - AllowPolling.BindValueChanged(allowPolling => + get => allowPolling; + set { - if (!allowPolling.NewValue) + if (allowPolling == value) + return; + + allowPolling = value; + + if (!allowPolling) return; if (IsLoaded) PollImmediately(); - }); + } } - protected override Task Poll() => !AllowPolling.Value ? Task.CompletedTask : base.Poll(); + protected override Task Poll() => !AllowPolling ? Task.CompletedTask : base.Poll(); } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs index ae8c3113ff..2d94b2328d 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs @@ -4,7 +4,6 @@ using System; using System.Diagnostics; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Extensions.ExceptionExtensions; using osu.Framework.Logging; using osu.Game.Online.Multiplayer; @@ -19,18 +18,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient multiplayerClient { get; set; } - private readonly IBindable isConnected = new Bindable(); - private readonly Bindable allowPolling = new Bindable(); - - protected override void LoadComplete() - { - base.LoadComplete(); - - isConnected.BindTo(multiplayerClient.IsConnected); - isConnected.BindValueChanged(_ => Scheduler.AddOnce(updatePolling)); - JoinedRoom.BindValueChanged(_ => Scheduler.AddOnce(updatePolling), true); - } - public override void CreateRoom(Room room, Action onSuccess = null, Action onError = null) => base.CreateRoom(room, r => joinMultiplayerRoom(r, r.Password.Value, onSuccess, onError), onError); @@ -82,14 +69,5 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer } }); } - - private void updatePolling() - { - if (!isConnected.Value) - ClearRooms(); - - // Don't poll when not connected or when a room has been joined. - allowPolling.Value = isConnected.Value && JoinedRoom.Value == null; - } } } From 83935540caf400882750283724326934c556110b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 18:11:52 +0900 Subject: [PATCH 23/83] Add selection polling component to PlaylistsRoomSubScreen --- .../OnlinePlay/Lounge/LoungeSubScreen.cs | 16 +++++-------- .../Playlists/PlaylistsRoomSubScreen.cs | 24 +++++++++++++++---- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 4525599a52..06db462205 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -59,9 +59,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [Resolved] private IBindable ruleset { get; set; } - [Resolved(CanBeNull = true)] - private IdleTracker idleTracker { get; set; } - [CanBeNull] private IDisposable joiningRoomOperation { get; set; } @@ -73,9 +70,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private Dropdown statusDropdown; private ListingPollingComponent listingPollingComponent; - [BackgroundDependencyLoader] - private void load() + [BackgroundDependencyLoader(true)] + private void load([CanBeNull] IdleTracker idleTracker) { + if (idleTracker != null) + isIdle.BindTo(idleTracker.IsIdle); + filter ??= new Bindable(new FilterCriteria()); OsuScrollContainer scrollContainer; @@ -184,11 +184,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge listingPollingComponent.HasPolledOnce.BindValueChanged(_ => updateLoadingLayer()); - if (idleTracker != null) - { - isIdle.BindTo(idleTracker.IsIdle); - isIdle.BindValueChanged(_ => updatePollingRate(), true); - } + isIdle.BindValueChanged(_ => updatePollingRate(), true); if (ongoingOperationTracker != null) { diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 953c687087..682b055766 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -3,11 +3,14 @@ using System.Diagnostics; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Logging; using osu.Framework.Screens; +using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Components; @@ -33,12 +36,13 @@ namespace osu.Game.Screens.OnlinePlay.Playlists [Resolved(typeof(Room), nameof(Room.Playlist))] private BindableList playlist { get; set; } + private readonly IBindable isIdle = new BindableBool(); + private MatchSettingsOverlay settingsOverlay; private MatchLeaderboard leaderboard; - private OverlinedHeader participantsHeader; - private GridContainer mainContent; + private SelectionPollingComponent selectionPollingComponent; public PlaylistsRoomSubScreen(Room room) { @@ -46,11 +50,15 @@ namespace osu.Game.Screens.OnlinePlay.Playlists Activity.Value = new UserActivity.InLobby(room); } - [BackgroundDependencyLoader] - private void load() + [BackgroundDependencyLoader(true)] + private void load([CanBeNull] IdleTracker idleTracker) { + if (idleTracker != null) + isIdle.BindTo(idleTracker.IsIdle); + AddRangeInternal(new Drawable[] { + selectionPollingComponent = new SelectionPollingComponent(), mainContent = new GridContainer { RelativeSizeAxes = Axes.Both, @@ -260,6 +268,8 @@ namespace osu.Game.Screens.OnlinePlay.Playlists { base.LoadComplete(); + isIdle.BindValueChanged(_ => updatePollingRate(), true); + roomId.BindValueChanged(id => { if (id.NewValue == null) @@ -275,6 +285,12 @@ namespace osu.Game.Screens.OnlinePlay.Playlists }, true); } + private void updatePollingRate() + { + selectionPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 30000 : 5000; + Logger.Log($"Polling adjusted (selection: {selectionPollingComponent.TimeBetweenPolls.Value})"); + } + protected override Screen CreateGameplayScreen() => new PlayerLoader(() => new PlaylistsPlayer(SelectedItem.Value) { Exited = () => leaderboard.RefreshScores() From f5cea0cacd34535f58b43c216f03ed60b1bb31ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 12:12:20 +0300 Subject: [PATCH 24/83] Fix failing test and rename to match new behaviour --- .../Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index a9004987df..080a1502b0 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] - public void TestSpectatorPlayerSettingsHidden() + public void TestSpectatorPlayerInteractiveElementsHidden() { start(new[] { PLAYER_1_ID, PLAYER_2_ID }); loadSpectateScreen(false); @@ -96,7 +96,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("all interactive elements removed", () => this.ChildrenOfType().All(p => !p.ChildrenOfType().Any() && !p.ChildrenOfType().Any() && - !p.ChildrenOfType().Single().ShowHandle)); + p.ChildrenOfType().SingleOrDefault()?.ShowHandle == false)); } [Test] From 6a46105b5efe9b6a2fcaa95838f53d1793daeb90 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 18:12:32 +0900 Subject: [PATCH 25/83] Fix incorrect dependency --- osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs index 95b4c4284c..cd224a7347 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomPollingComponent.cs @@ -13,6 +13,6 @@ namespace osu.Game.Screens.OnlinePlay.Components protected IAPIProvider API { get; private set; } [Resolved] - protected IRoomManager RoomManager { get; set; } + protected IRoomManager RoomManager { get; private set; } } } From 1bae7173d3794d1cecca63fb31fecbc4a64ef3f9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 18:13:55 +0900 Subject: [PATCH 26/83] Fix initial multiplayer poll --- .../OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index 3f20202ec7..d36462f482 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -28,7 +28,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private MultiplayerListingPollingComponent listingPollingComponent; private readonly IBindable isConnected = new Bindable(); - private readonly Bindable allowPolling = new Bindable(); protected override void LoadComplete() { @@ -36,6 +35,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer isConnected.BindTo(client.IsConnected); isConnected.BindValueChanged(c => Scheduler.AddOnce(() => listingPollingComponent.AllowPolling = c.NewValue)); + listingPollingComponent.AllowPolling = isConnected.Value; } public override void OnResuming(IScreen last) From d527eb3d8b8f89bafa8870fe691f3ef6127fca67 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Fri, 13 Aug 2021 17:15:18 +0800 Subject: [PATCH 27/83] Apply suggestions from code review Co-authored-by: Dean Herbert --- osu.Game/Localisation/GameplaySettingsStrings.cs | 6 +++--- osu.Game/Localisation/GeneralSettingsStrings.cs | 2 +- .../Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 6 +++--- .../Overlays/Settings/Sections/General/LanguageSettings.cs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Localisation/GameplaySettingsStrings.cs b/osu.Game/Localisation/GameplaySettingsStrings.cs index 4354272ab5..c63fa5ddcc 100644 --- a/osu.Game/Localisation/GameplaySettingsStrings.cs +++ b/osu.Game/Localisation/GameplaySettingsStrings.cs @@ -22,12 +22,12 @@ namespace osu.Game.Localisation /// /// "Background dim" /// - public static LocalisableString Dim => new TranslatableString(getKey(@"dim"), @"Background dim"); + public static LocalisableString BackgroundDim => new TranslatableString(getKey(@"dim"), @"Background dim"); /// /// "Background blur" /// - public static LocalisableString Blur => new TranslatableString(getKey(@"blur"), @"Background blur"); + public static LocalisableString BackgroundBlur => new TranslatableString(getKey(@"blur"), @"Background blur"); /// /// "Lighten playfield during breaks" @@ -57,7 +57,7 @@ namespace osu.Game.Localisation /// /// "Always show key overlay" /// - public static LocalisableString KeyOverlay => new TranslatableString(getKey(@"key_overlay"), @"Always show key overlay"); + public static LocalisableString AlwaysShowKeyOverlay => new TranslatableString(getKey(@"key_overlay"), @"Always show key overlay"); /// /// "Positional hitsounds" diff --git a/osu.Game/Localisation/GeneralSettingsStrings.cs b/osu.Game/Localisation/GeneralSettingsStrings.cs index 19fb8de972..a60e4891f4 100644 --- a/osu.Game/Localisation/GeneralSettingsStrings.cs +++ b/osu.Game/Localisation/GeneralSettingsStrings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Localisation /// /// "Prefer metadata in original language" /// - public static LocalisableString PreferOriginal => new TranslatableString(getKey(@"prefer_original"), @"Prefer metadata in original language"); + public static LocalisableString PreferOriginalMetadataLanguage => new TranslatableString(getKey(@"prefer_original"), @"Prefer metadata in original language"); /// /// "Updates" diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index efb586fdca..04332fcdd3 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -22,14 +22,14 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { new SettingsSlider { - LabelText = GameplaySettingsStrings.Dim, + LabelText = GameplaySettingsStrings.BackgroundDim, Current = config.GetBindable(OsuSetting.DimLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true }, new SettingsSlider { - LabelText = GameplaySettingsStrings.Blur, + LabelText = GameplaySettingsStrings.BackgroundBlur, Current = config.GetBindable(OsuSetting.BlurLevel), KeyboardStep = 0.01f, DisplayAsPercentage = true @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsCheckbox { - LabelText = GameplaySettingsStrings.KeyOverlay, + LabelText = GameplaySettingsStrings.AlwaysShowKeyOverlay, Current = config.GetBindable(OsuSetting.KeyOverlay) }, new SettingsCheckbox diff --git a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs index ac95a713bf..200618c469 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LanguageSettings.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Settings.Sections.General }, new SettingsCheckbox { - LabelText = GeneralSettingsStrings.PreferOriginal, + LabelText = GeneralSettingsStrings.PreferOriginalMetadataLanguage, Current = frameworkConfig.GetBindable(FrameworkSetting.ShowUnicode) }, }; From 1f992e67f3b29f63a0f965eb6c4e3ed26a6699c8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 18:17:18 +0900 Subject: [PATCH 28/83] Fix listing polling rate when entering room --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 06db462205..abe06bae9e 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -184,7 +184,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge listingPollingComponent.HasPolledOnce.BindValueChanged(_ => updateLoadingLayer()); - isIdle.BindValueChanged(_ => updatePollingRate(), true); + isIdle.BindValueChanged(_ => updatePollingRate(this.IsCurrentScreen()), true); if (ongoingOperationTracker != null) { @@ -272,13 +272,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void onReturning() { - updatePollingRate(); + updatePollingRate(true); searchTextBox.HoldFocus = true; } private void onLeaving() { - updatePollingRate(); + updatePollingRate(false); searchTextBox.HoldFocus = false; // ensure any password prompt is dismissed. @@ -332,9 +332,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge loadingLayer.Hide(); } - private void updatePollingRate() + private void updatePollingRate(bool isCurrentScreen) { - if (!this.IsCurrentScreen()) + if (!isCurrentScreen) listingPollingComponent.TimeBetweenPolls.Value = 0; else listingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000; From c71a581106f1640a4303ead14755820cfc1c29d7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 18:24:19 +0900 Subject: [PATCH 29/83] Fix exception when leaving match --- .../OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs | 9 ++++++++- .../OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs | 8 ++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index d36462f482..0756c78211 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -41,7 +41,14 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public override void OnResuming(IScreen last) { base.OnResuming(last); - listingPollingComponent.PollImmediately(); + + // Upon having left a room, we don't know whether we were the only participant, and whether the room is now closed as a result of leaving it. + // To work around this, temporarily clear all rooms until the next listing poll. + if (last is MultiplayerMatchSubScreen match) + { + RoomManager.RemoveRoom(match.Room); + listingPollingComponent.PollImmediately(); + } } protected override FilterCriteria CreateFilterCriteria() diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index ec011634b1..72ba4d62fb 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -42,6 +42,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public override string ShortTitle => "room"; + public readonly Room Room; + [Resolved] private MultiplayerClient client { get; set; } @@ -61,6 +63,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public MultiplayerMatchSubScreen(Room room) { + Room = room; + Title = room.RoomID.Value == null ? "New room" : room.Name.Value; Activity.Value = new UserActivity.InLobby(room); } @@ -323,10 +327,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public override bool OnExiting(IScreen next) { - // We don't know whether we're the only participant in the room, and whether the room will close after we leave it as a result. - // To work around this, temporarily remove the room until the next listing poll retrieves it. - RoomManager?.RemoveRoom(currentRoom.Value); - // the room may not be left immediately after a disconnection due to async flow, // so checking the IsConnected status is also required. if (client.Room == null || !client.IsConnected.Value) From fbadc4897e211db035eb495d19cc797535e4fbc1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 18:28:20 +0900 Subject: [PATCH 30/83] Remove test scene --- .../TestSceneMultiplayerRoomManager.cs | 157 ------------------ 1 file changed, 157 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs deleted file mode 100644 index 15e9112c47..0000000000 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerRoomManager.cs +++ /dev/null @@ -1,157 +0,0 @@ -// // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// // See the LICENCE file in the repository root for full licence text. -// -// using System; -// using NUnit.Framework; -// using osu.Framework.Testing; -// using osu.Game.Online.Rooms; -// using osu.Game.Screens.OnlinePlay.Components; -// using osu.Game.Tests.Beatmaps; -// using osu.Game.Tests.Visual.OnlinePlay; -// -// namespace osu.Game.Tests.Visual.Multiplayer -// { -// [HeadlessTest] -// public class TestSceneMultiplayerRoomManager : MultiplayerTestScene -// { -// protected override OnlinePlayTestSceneDependencies CreateOnlinePlayDependencies() => new TestDependencies(); -// -// public TestSceneMultiplayerRoomManager() -// : base(false) -// { -// } -// -// [Test] -// public void TestPollsInitially() -// { -// AddStep("create room manager with a few rooms", () => -// { -// RoomManager.CreateRoom(createRoom(r => r.Name.Value = "1")); -// RoomManager.PartRoom(); -// RoomManager.CreateRoom(createRoom(r => r.Name.Value = "2")); -// RoomManager.PartRoom(); -// RoomManager.ClearRooms(); -// }); -// -// AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2); -// AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value); -// } -// -// [Test] -// public void TestRoomsClearedOnDisconnection() -// { -// AddStep("create room manager with a few rooms", () => -// { -// RoomManager.CreateRoom(createRoom()); -// RoomManager.PartRoom(); -// RoomManager.CreateRoom(createRoom()); -// RoomManager.PartRoom(); -// }); -// -// AddStep("disconnect", () => Client.Disconnect()); -// -// AddAssert("rooms cleared", () => ((RoomManager)RoomManager).Rooms.Count == 0); -// AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value); -// } -// -// [Test] -// public void TestRoomsPolledOnReconnect() -// { -// AddStep("create room manager with a few rooms", () => -// { -// RoomManager.CreateRoom(createRoom()); -// RoomManager.PartRoom(); -// RoomManager.CreateRoom(createRoom()); -// RoomManager.PartRoom(); -// }); -// -// AddStep("disconnect", () => Client.Disconnect()); -// AddStep("connect", () => Client.Connect()); -// -// AddAssert("manager polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 2); -// AddAssert("initial rooms received", () => RoomManager.InitialRoomsReceived.Value); -// } -// -// [Test] -// public void TestRoomsNotPolledWhenJoined() -// { -// AddStep("create room manager with a room", () => -// { -// RoomManager.CreateRoom(createRoom()); -// RoomManager.ClearRooms(); -// }); -// -// AddAssert("manager not polled for rooms", () => ((RoomManager)RoomManager).Rooms.Count == 0); -// AddAssert("initial rooms not received", () => !RoomManager.InitialRoomsReceived.Value); -// } -// -// [Test] -// public void TestMultiplayerRoomJoinedWhenCreated() -// { -// AddStep("create room manager with a room", () => -// { -// RoomManager.CreateRoom(createRoom()); -// }); -// -// AddUntilStep("multiplayer room joined", () => Client.Room != null); -// } -// -// [Test] -// public void TestMultiplayerRoomPartedWhenAPIRoomParted() -// { -// AddStep("create room manager with a room", () => -// { -// RoomManager.CreateRoom(createRoom()); -// RoomManager.PartRoom(); -// }); -// -// AddAssert("multiplayer room parted", () => Client.Room == null); -// } -// -// [Test] -// public void TestMultiplayerRoomJoinedWhenAPIRoomJoined() -// { -// AddStep("create room manager with a room", () => -// { -// var r = createRoom(); -// RoomManager.CreateRoom(r); -// RoomManager.PartRoom(); -// RoomManager.JoinRoom(r); -// }); -// -// AddUntilStep("multiplayer room joined", () => Client.Room != null); -// } -// -// private Room createRoom(Action initFunc = null) -// { -// var room = new Room -// { -// Name = -// { -// Value = "test room" -// }, -// Playlist = -// { -// new PlaylistItem -// { -// Beatmap = { Value = new TestBeatmap(Ruleset.Value).BeatmapInfo }, -// Ruleset = { Value = Ruleset.Value } -// } -// } -// }; -// -// initFunc?.Invoke(room); -// return room; -// } -// -// private class TestDependencies : MultiplayerTestSceneDependencies -// { -// public TestDependencies() -// { -// // Need to set these values as early as possible. -// RoomManager.TimeBetweenListingPolls.Value = 1; -// RoomManager.TimeBetweenSelectionPolls.Value = 1; -// } -// } -// } -// } From 7cf6b551d353ffd8393b3ed4d7489f5c6d23bca3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 13:01:17 +0300 Subject: [PATCH 31/83] Replace until step with wait step with explanatory comment --- .../Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index 080a1502b0..62a9b597ad 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -93,10 +93,15 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("all player loader settings hidden", () => this.ChildrenOfType().All(l => !l.ChildrenOfType>().Any())); AddUntilStep("wait for players to load", () => spectatorScreen.AllPlayersLoaded); - AddUntilStep("all interactive elements removed", () => this.ChildrenOfType().All(p => + + // components wrapped in skinnable target containers load asynchronously, potentially taking more than one frame to load. + // wait once to properly execute the assert. + AddWaitStep("wait for async load", 1); + + AddAssert("all interactive elements removed", () => this.ChildrenOfType().All(p => !p.ChildrenOfType().Any() && !p.ChildrenOfType().Any() && - p.ChildrenOfType().SingleOrDefault()?.ShowHandle == false)); + !p.ChildrenOfType().Single().ShowHandle)); } [Test] From c32ba9e38fe45f6200c8305fcc0938046cb792e6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 15:06:11 +0300 Subject: [PATCH 32/83] Remove arbitrarily-set wait step with until step instead, keeping the comment --- .../Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index 62a9b597ad..f1ddfefe33 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -95,10 +95,8 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("wait for players to load", () => spectatorScreen.AllPlayersLoaded); // components wrapped in skinnable target containers load asynchronously, potentially taking more than one frame to load. - // wait once to properly execute the assert. - AddWaitStep("wait for async load", 1); - - AddAssert("all interactive elements removed", () => this.ChildrenOfType().All(p => + // therefore use until step rather than direct assert to account for that. + AddUntilStep("all interactive elements removed", () => this.ChildrenOfType().All(p => !p.ChildrenOfType().Any() && !p.ChildrenOfType().Any() && !p.ChildrenOfType().Single().ShowHandle)); From 1fed9193f86c4052393c1a58ea09c0f8c2756272 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Aug 2021 15:24:10 +0300 Subject: [PATCH 33/83] Revert reverted segment to fix failure --- .../Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index f1ddfefe33..9bb9c24c6b 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -99,7 +99,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("all interactive elements removed", () => this.ChildrenOfType().All(p => !p.ChildrenOfType().Any() && !p.ChildrenOfType().Any() && - !p.ChildrenOfType().Single().ShowHandle)); + p.ChildrenOfType().SingleOrDefault()?.ShowHandle == false)); } [Test] From 1fcb1cdb108fb4049a8aa3f0d0de78408e50e187 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 22:01:47 +0900 Subject: [PATCH 34/83] Add todo --- osu.Game/Online/Rooms/Room.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Rooms/Room.cs b/osu.Game/Online/Rooms/Room.cs index 364336783d..d964060f10 100644 --- a/osu.Game/Online/Rooms/Room.cs +++ b/osu.Game/Online/Rooms/Room.cs @@ -134,7 +134,7 @@ namespace osu.Game.Online.Rooms /// The position of this in the list. This is not read from or written to the API. /// [JsonIgnore] - public readonly Bindable Position = new Bindable(-1); + public readonly Bindable Position = new Bindable(-1); // Todo: This does not need to exist. public Room() { From 155e9e16a5d08d2bcb52dfaeda81af6903e478f2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 22:08:34 +0900 Subject: [PATCH 35/83] Refactorings --- osu.Game/Screens/OnlinePlay/IRoomManager.cs | 12 ++++++++++++ .../Multiplayer/MultiplayerLoungeSubScreen.cs | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/IRoomManager.cs b/osu.Game/Screens/OnlinePlay/IRoomManager.cs index baf84e25f9..6e1ffbda74 100644 --- a/osu.Game/Screens/OnlinePlay/IRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/IRoomManager.cs @@ -23,10 +23,22 @@ namespace osu.Game.Screens.OnlinePlay /// IBindableList Rooms { get; } + /// + /// Adds a to this . + /// If already existing, the local room will be updated with the given one. + /// + /// The incoming . void AddOrUpdateRoom(Room room); + /// + /// Removes a from this . + /// + /// The to remove. void RemoveRoom(Room room); + /// + /// Removes all s from this . + /// void ClearRooms(); /// diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index 0756c78211..77db955f0a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -43,7 +43,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer base.OnResuming(last); // Upon having left a room, we don't know whether we were the only participant, and whether the room is now closed as a result of leaving it. - // To work around this, temporarily clear all rooms until the next listing poll. + // To work around this, temporarily remove the room and trigger an immediate listing poll. if (last is MultiplayerMatchSubScreen match) { RoomManager.RemoveRoom(match.Room); From 5cfb89f18ac02d26168569846255e73703dde9d2 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Sat, 14 Aug 2021 10:56:52 +0800 Subject: [PATCH 36/83] Apply suggestions from code review Co-authored-by: Joseph Madamba --- osu.Game/Localisation/UserInterfaceStrings.cs | 2 +- .../Settings/Sections/UserInterface/SongSelectSettings.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/UserInterfaceStrings.cs b/osu.Game/Localisation/UserInterfaceStrings.cs index 18a9257732..fcfaf661dc 100644 --- a/osu.Game/Localisation/UserInterfaceStrings.cs +++ b/osu.Game/Localisation/UserInterfaceStrings.cs @@ -77,7 +77,7 @@ namespace osu.Game.Localisation /// /// "Song Select" /// - public static LocalisableString SoneSelectHeader => new TranslatableString(getKey(@"song_select_header"), @"Song Select"); + public static LocalisableString SongSelectHeader => new TranslatableString(getKey(@"song_select_header"), @"Song Select"); /// /// "Right mouse drag to absolute scroll" diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs index 8596cecbb8..6290046987 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/SongSelectSettings.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface private Bindable minStars; private Bindable maxStars; - protected override LocalisableString Header => UserInterfaceStrings.SoneSelectHeader; + protected override LocalisableString Header => UserInterfaceStrings.SongSelectHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) From e26ccf786e6812a8aca382f061e346f3b5b64a76 Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Sat, 14 Aug 2021 11:04:38 +0800 Subject: [PATCH 37/83] code style format --- osu.Game/Localisation/OnlineSettingsStrings.cs | 4 ++-- osu.Game/Localisation/SkinSettingsStrings.cs | 2 +- .../Settings/Sections/Online/AlertsAndPrivacySettings.cs | 2 +- osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs | 2 +- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Localisation/OnlineSettingsStrings.cs b/osu.Game/Localisation/OnlineSettingsStrings.cs index 0ef98a720c..0173cc7cbb 100644 --- a/osu.Game/Localisation/OnlineSettingsStrings.cs +++ b/osu.Game/Localisation/OnlineSettingsStrings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Localisation /// /// "Show a notification when you receive a private message" /// - public static LocalisableString NotifyOnPM => new TranslatableString(getKey(@"notify_on_pm"), @"Show a notification when you receive a private message"); + public static LocalisableString NotifyOnPrivateMessage => new TranslatableString(getKey(@"notify_on_private_message"), @"Show a notification when you receive a private message"); /// /// "Integrations" @@ -57,7 +57,7 @@ namespace osu.Game.Localisation /// /// "Automatically download beatmaps when spectating" /// - public static LocalisableString AutomaticallyDownload => new TranslatableString(getKey(@"automatically_download"), @"Automatically download beatmaps when spectating"); + public static LocalisableString AutomaticallyDownloadWhenSpectating => new TranslatableString(getKey(@"automatically_download_when_spectating"), @"Automatically download beatmaps when spectating"); /// /// "Show explicit content in search results" diff --git a/osu.Game/Localisation/SkinSettingsStrings.cs b/osu.Game/Localisation/SkinSettingsStrings.cs index 848c01b93a..f22b4d6bf5 100644 --- a/osu.Game/Localisation/SkinSettingsStrings.cs +++ b/osu.Game/Localisation/SkinSettingsStrings.cs @@ -22,7 +22,7 @@ namespace osu.Game.Localisation /// /// "Gameplay cursor size" /// - public static LocalisableString CursorSize => new TranslatableString(getKey(@"cursor_size"), @"Gameplay cursor size"); + public static LocalisableString GameplayCursorSize => new TranslatableString(getKey(@"gameplay_cursor_size"), @"Gameplay cursor size"); /// /// "Adjust gameplay cursor size based on current beatmap" diff --git a/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs b/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs index 1728b565c2..351a32c72e 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/AlertsAndPrivacySettings.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Settings.Sections.Online }, new SettingsCheckbox { - LabelText = OnlineSettingsStrings.NotifyOnPM, + LabelText = OnlineSettingsStrings.NotifyOnPrivateMessage, Current = config.GetBindable(OsuSetting.NotifyOnPrivateMessage) }, }; diff --git a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs index 4200ddda3d..e864260cc6 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/WebSettings.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Settings.Sections.Online }, new SettingsCheckbox { - LabelText = OnlineSettingsStrings.AutomaticallyDownload, + LabelText = OnlineSettingsStrings.AutomaticallyDownloadWhenSpectating, Keywords = new[] { "spectator" }, Current = config.GetBindable(OsuSetting.AutomaticallyDownloadWhenSpectating), }, diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 007302c584..e0d8252930 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -76,7 +76,7 @@ namespace osu.Game.Overlays.Settings.Sections new ExportSkinButton(), new SettingsSlider { - LabelText = SkinSettingsStrings.CursorSize, + LabelText = SkinSettingsStrings.GameplayCursorSize, Current = config.GetBindable(OsuSetting.GameplayCursorSize), KeyboardStep = 0.01f }, From f87f86e671190c2836b95b801fee7be50aa52b1a Mon Sep 17 00:00:00 2001 From: kj415j45 Date: Sat, 14 Aug 2021 21:52:09 +0800 Subject: [PATCH 38/83] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Localisation/GameplaySettingsStrings.cs | 2 +- osu.Game/Localisation/OnlineSettingsStrings.cs | 2 +- osu.Game/Localisation/UserInterfaceStrings.cs | 2 +- .../Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 2 +- .../Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 2 +- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 2 +- .../Overlays/Settings/Sections/Online/IntegrationSettings.cs | 2 +- .../Settings/Sections/UserInterface/GeneralSettings.cs | 2 +- .../Settings/Sections/UserInterface/MainMenuSettings.cs | 2 +- osu.Game/Overlays/Settings/SettingsSubsection.cs | 5 +++++ 10 files changed, 14 insertions(+), 9 deletions(-) diff --git a/osu.Game/Localisation/GameplaySettingsStrings.cs b/osu.Game/Localisation/GameplaySettingsStrings.cs index c63fa5ddcc..868eb6b98a 100644 --- a/osu.Game/Localisation/GameplaySettingsStrings.cs +++ b/osu.Game/Localisation/GameplaySettingsStrings.cs @@ -42,7 +42,7 @@ namespace osu.Game.Localisation /// /// "Show difficulty graph on progress bar" /// - public static LocalisableString ShowProgressGraph => new TranslatableString(getKey(@"show_progress_graph"), @"Show difficulty graph on progress bar"); + public static LocalisableString ShowDifficultyGraph => new TranslatableString(getKey(@"show_progress_graph"), @"Show difficulty graph on progress bar"); /// /// "Show health display even when you can't fail" diff --git a/osu.Game/Localisation/OnlineSettingsStrings.cs b/osu.Game/Localisation/OnlineSettingsStrings.cs index 0173cc7cbb..6862f4ac2c 100644 --- a/osu.Game/Localisation/OnlineSettingsStrings.cs +++ b/osu.Game/Localisation/OnlineSettingsStrings.cs @@ -32,7 +32,7 @@ namespace osu.Game.Localisation /// /// "Integrations" /// - public static LocalisableString IntegrationHeader => new TranslatableString(getKey(@"integration_header"), @"Integrations"); + public static LocalisableString IntegrationsHeader => new TranslatableString(getKey(@"integrations_header"), @"Integrations"); /// /// "Discord Rich Presence" diff --git a/osu.Game/Localisation/UserInterfaceStrings.cs b/osu.Game/Localisation/UserInterfaceStrings.cs index fcfaf661dc..4be403edb4 100644 --- a/osu.Game/Localisation/UserInterfaceStrings.cs +++ b/osu.Game/Localisation/UserInterfaceStrings.cs @@ -37,7 +37,7 @@ namespace osu.Game.Localisation /// /// "Hold-to-confirm activation time" /// - public static LocalisableString HoldActivationDelay => new TranslatableString(getKey(@"hold_activation_delay"), @"Hold-to-confirm activation time"); + public static LocalisableString HoldToConfirmActivationTime => new TranslatableString(getKey(@"hold_to_confirm_activation_time"), @"Hold-to-confirm activation time"); /// /// "Main Menu" diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 04332fcdd3..3a0265e453 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsCheckbox { - LabelText = GameplaySettingsStrings.ShowProgressGraph, + LabelText = GameplaySettingsStrings.ShowDifficultyGraph, Current = config.GetBindable(OsuSetting.ShowProgressGraph) }, new SettingsCheckbox diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 50bd8184ee..124b3b804c 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -146,7 +146,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { updateResolutionDropdown(); - windowModeDropdown.WarningText = mode.NewValue != WindowMode.Fullscreen ? GraphicsSettingsStrings.NotFullscreenNote : string.Empty; + windowModeDropdown.WarningText = mode.NewValue != WindowMode.Fullscreen ? GraphicsSettingsStrings.NotFullscreenNote : default; }, true); windowModes.BindCollectionChanged((sender, args) => diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 9747f6b373..653f30a018 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics frameLimiterDropdown.Current.BindValueChanged(limit => { - frameLimiterDropdown.WarningText = limit.NewValue == FrameSync.Unlimited ? GraphicsSettingsStrings.UnlimitedFramesNote : string.Empty; + frameLimiterDropdown.WarningText = limit.NewValue == FrameSync.Unlimited ? GraphicsSettingsStrings.UnlimitedFramesNote : default; }, true); } } diff --git a/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs b/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs index f2a516feef..0207f2fd01 100644 --- a/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Online/IntegrationSettings.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Settings.Sections.Online { public class IntegrationSettings : SettingsSubsection { - protected override LocalisableString Header => OnlineSettingsStrings.IntegrationHeader; + protected override LocalisableString Header => OnlineSettingsStrings.IntegrationsHeader; [BackgroundDependencyLoader] private void load(OsuConfigManager config) diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs index b26363a9da..0afbed5df5 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/GeneralSettings.cs @@ -37,7 +37,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface }, new SettingsSlider { - LabelText = UserInterfaceStrings.HoldActivationDelay, + LabelText = UserInterfaceStrings.HoldToConfirmActivationTime, Current = config.GetBindable(OsuSetting.UIHoldActivationDelay), KeyboardStep = 50 }, diff --git a/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs b/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs index 976893bf0a..40485a070c 100644 --- a/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/UserInterface/MainMenuSettings.cs @@ -61,7 +61,7 @@ namespace osu.Game.Overlays.Settings.Sections.UserInterface user.BindValueChanged(u => { - backgroundSourceDropdown.WarningText = u.NewValue?.IsSupporter != true ? UserInterfaceStrings.NotSupporterNote : string.Empty; + backgroundSourceDropdown.WarningText = u.NewValue?.IsSupporter != true ? UserInterfaceStrings.NotSupporterNote : default; }, true); } } diff --git a/osu.Game/Overlays/Settings/SettingsSubsection.cs b/osu.Game/Overlays/Settings/SettingsSubsection.cs index df32424b67..4aa9360452 100644 --- a/osu.Game/Overlays/Settings/SettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/SettingsSubsection.cs @@ -24,6 +24,11 @@ namespace osu.Game.Overlays.Settings protected abstract LocalisableString Header { get; } public IEnumerable FilterableChildren => Children.OfType(); + + // FilterTerms should contains both original string and localised string for user to search. + // Since LocalisableString is unable to get original string at this time (2021-08-14), + // only call .ToString() to use localised one. + // TODO: Update here when FilterTerms accept LocalisableString. public virtual IEnumerable FilterTerms => new[] { Header.ToString() }; public bool MatchingFilter From 246a8882ce248f35ba238875db35d281473e12f6 Mon Sep 17 00:00:00 2001 From: LiangXiang Shen Date: Sun, 15 Aug 2021 00:23:14 +0800 Subject: [PATCH 39/83] Update translation key --- osu.Game/Localisation/GameplaySettingsStrings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Localisation/GameplaySettingsStrings.cs b/osu.Game/Localisation/GameplaySettingsStrings.cs index 868eb6b98a..6d6381b429 100644 --- a/osu.Game/Localisation/GameplaySettingsStrings.cs +++ b/osu.Game/Localisation/GameplaySettingsStrings.cs @@ -42,7 +42,7 @@ namespace osu.Game.Localisation /// /// "Show difficulty graph on progress bar" /// - public static LocalisableString ShowDifficultyGraph => new TranslatableString(getKey(@"show_progress_graph"), @"Show difficulty graph on progress bar"); + public static LocalisableString ShowDifficultyGraph => new TranslatableString(getKey(@"show_difficulty_graph"), @"Show difficulty graph on progress bar"); /// /// "Show health display even when you can't fail" From 2ddf28346aa2873bef9cb9edf313f8fe0b52e721 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 14 Aug 2021 19:58:20 +0300 Subject: [PATCH 40/83] PlayerSettingsGroups -> PlayerSettings --- .../Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs index f28c2a1d48..14bd8fa6dc 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayerLoader.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate [BackgroundDependencyLoader] private void load() { - PlayerSettingsGroups.Expire(); + PlayerSettings.Expire(); } protected override void LogoArriving(OsuLogo logo, bool resuming) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 1f8387ac67..a6592e4d24 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play /// /// A fill flow containing the player settings groups, exposed for the ability to hide it from inheritors of the player loader. /// - protected FillFlowContainer PlayerSettingsGroups; + protected FillFlowContainer PlayerSettings; protected VisualSettings VisualSettings; @@ -145,7 +145,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre, }, - PlayerSettingsGroups = new FillFlowContainer + PlayerSettings = new FillFlowContainer { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, From 95943fdb25c763a10849f9dff6dffb4fa7466919 Mon Sep 17 00:00:00 2001 From: Jacob Van Meter Date: Sat, 14 Aug 2021 20:00:26 -0400 Subject: [PATCH 41/83] Add glow to supporter promo on changelog Added glow to the supporter promo at the end of the changelog, as it is on the website. --- .../Changelog/ChangelogSupporterPromo.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index f617b4fc82..46fab30d5e 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -138,14 +138,28 @@ namespace osu.Game.Overlays.Changelog FillMode = FillMode.Fill, Texture = textures.Get(@"Online/supporter-pippi"), }, - new Sprite + new Container { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Width = 75, Height = 75, - Margin = new MarginPadding { Top = 70 }, - Texture = textures.Get(@"Online/supporter-heart"), + Margin = new MarginPadding { Top = 83 }, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Colour = Color4.HotPink.Opacity(0.88f), + Offset = new Vector2(0, 0), + Radius = 17, + Roundness = 39f, + }, + Child = new Sprite + { + Width = 75, + Height = 75, + Texture = textures.Get(@"Online/supporter-heart"), + }, }, }; } From 772860232cbbfad9ca85c68d413465405828279b Mon Sep 17 00:00:00 2001 From: Jacob Van Meter Date: Sat, 14 Aug 2021 20:32:38 -0400 Subject: [PATCH 42/83] Removed empty offset and corrected colour --- osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index 46fab30d5e..203a371f43 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -149,8 +149,7 @@ namespace osu.Game.Overlays.Changelog EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, - Colour = Color4.HotPink.Opacity(0.88f), - Offset = new Vector2(0, 0), + Colour = colour.Pink, Radius = 17, Roundness = 39f, }, From 71ccd38bb35e6276205152edb953daedc0affb34 Mon Sep 17 00:00:00 2001 From: Jacob Van Meter Date: Sat, 14 Aug 2021 20:36:43 -0400 Subject: [PATCH 43/83] Corrected pippi background and promo positioning --- osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index 203a371f43..f8613b101e 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -134,6 +134,7 @@ namespace osu.Game.Overlays.Changelog { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Margin = new MarginPadding { Bottom = 28 }, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fill, Texture = textures.Get(@"Online/supporter-pippi"), @@ -144,7 +145,7 @@ namespace osu.Game.Overlays.Changelog Origin = Anchor.TopCentre, Width = 75, Height = 75, - Margin = new MarginPadding { Top = 83 }, + Margin = new MarginPadding { Top = 70 }, Masking = true, EdgeEffect = new EdgeEffectParameters { From 6472d85aae3377c7f37bb233aace478cfad8ab06 Mon Sep 17 00:00:00 2001 From: Jacob Van Meter Date: Sat, 14 Aug 2021 21:48:57 -0400 Subject: [PATCH 44/83] Added heart_size constant and adjusted the glow radius value Added heart_size constant and adjusted the glow radius value to be more in line with the website --- .../Overlays/Changelog/ChangelogSupporterPromo.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index f8613b101e..c51f927f9f 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -24,6 +24,7 @@ namespace osu.Game.Overlays.Changelog public class ChangelogSupporterPromo : CompositeDrawable { private const float image_container_width = 164; + private const float heart_size = 75; private readonly FillFlowContainer textContainer; private readonly Container imageContainer; @@ -143,21 +144,21 @@ namespace osu.Game.Overlays.Changelog { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Width = 75, - Height = 75, + Width = heart_size, + Height = heart_size, Margin = new MarginPadding { Top = 70 }, Masking = true, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, Colour = colour.Pink, - Radius = 17, - Roundness = 39f, + Radius = 10, + Roundness = heart_size / 2, }, Child = new Sprite { - Width = 75, - Height = 75, + Width = heart_size, + Height = heart_size, Texture = textures.Get(@"Online/supporter-heart"), }, }, From 29a22bd11f4b82304a14a1501ec48a373d4c1651 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Sun, 15 Aug 2021 20:48:00 +0200 Subject: [PATCH 45/83] added rhythm multiplier for strain sections --- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 15 +++++++++++++++ .../Rulesets/Difficulty/Skills/StrainSkill.cs | 7 ++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index f0eb199e5f..b1373cd215 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -34,6 +34,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { } + private double calculateRhythmBonus(double time) + { + return 1.0; + } + + protected override double StrainValueOf(DifficultyHitObject current) { if (current.BaseObject is Spinner) @@ -66,5 +72,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills return (1 + (speedBonus - 1) * 0.75) * angleBonus * (0.95 + speedBonus * Math.Pow(distance / single_spacing_threshold, 3.5)) / osuCurrent.StrainTime; } + protected override double GetTotalCurrentStrain(DifficultyHitObject current) + { + return base.GetTotalCurrentStrain(current) * calculateRhythmBonus(current.StartTime); + } + + protected override double GetPeakStrain(double time) + { + return base.GetPeakStrain(time) * calculateRhythmBonus(time); + } } } diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs index d4fcefab9b..95b0fe43fc 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs @@ -71,7 +71,12 @@ namespace osu.Game.Rulesets.Difficulty.Skills CurrentStrain *= strainDecay(current.DeltaTime); CurrentStrain += StrainValueOf(current) * SkillMultiplier; - currentSectionPeak = Math.Max(CurrentStrain, currentSectionPeak); + currentSectionPeak = Math.Max(GetTotalCurrentStrain(current), currentSectionPeak); + } + + protected virtual double GetTotalCurrentStrain(DifficultyHitObject current) + { + return CurrentStrain; } /// From 76a8d4329fe570a10532d3cb87cd09210523abcf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Aug 2021 12:43:09 +0900 Subject: [PATCH 46/83] Make TestRoomManager update existing room --- osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs index 2e9c0d1d53..d7c5a0a0e4 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs @@ -38,7 +38,13 @@ namespace osu.Game.Tests.Visual.OnlinePlay public void AddOrUpdateRoom(Room room) { - Rooms.Add(room); + var existing = Rooms.FirstOrDefault(r => r.RoomID.Value != null && r.RoomID.Value == room.RoomID.Value); + + if (existing != null) + existing.CopyFrom(room); + else + Rooms.Add(room); + RoomsUpdated?.Invoke(); } From 3db0b69f9247ae4037a6c6621fa7bcb9b7078f6e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Aug 2021 12:44:12 +0900 Subject: [PATCH 47/83] Throw not implemented exceptions --- .../TestScenePlaylistsMatchSettingsOverlay.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs index 79af2d3099..98882b659c 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs @@ -141,17 +141,11 @@ namespace osu.Game.Tests.Visual.Playlists public IBindableList Rooms => null; - public void AddOrUpdateRoom(Room room) - { - } + public void AddOrUpdateRoom(Room room) => throw new NotImplementedException(); - public void RemoveRoom(Room room) - { - } + public void RemoveRoom(Room room) => throw new NotImplementedException(); - public void ClearRooms() - { - } + public void ClearRooms() => throw new NotImplementedException(); public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { From 81f94424713470101867c541b8e83d4dd719e15d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Aug 2021 13:04:06 +0900 Subject: [PATCH 48/83] Inline update/addRoom in usage sites --- .../OnlinePlay/Components/RoomManager.cs | 43 +++++-------------- 1 file changed, 11 insertions(+), 32 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs index ab92adcac7..43bf3a2ce5 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs @@ -57,11 +57,10 @@ namespace osu.Game.Screens.OnlinePlay.Components { joinedRoom.Value = room; - update(room, result); - addRoom(room); + AddOrUpdateRoom(result); + room.CopyFrom(result); // Also copy back to the source model, since this is likely to have been stored elsewhere. - RoomsUpdated?.Invoke(); - onSuccess?.Invoke(room); + onSuccess?.Invoke(result); }; req.Failure += exception => @@ -119,8 +118,14 @@ namespace osu.Game.Screens.OnlinePlay.Components try { - update(room, room); - addRoom(room); + foreach (var pi in room.Playlist) + pi.MapObjects(beatmaps, rulesets); + + var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value); + if (existing == null) + rooms.Add(room); + else + existing.CopyFrom(room); } catch (Exception ex) { @@ -145,32 +150,6 @@ namespace osu.Game.Screens.OnlinePlay.Components notifyRoomsUpdated(); } - /// - /// Updates a local with a remote copy. - /// - /// The local to update. - /// The remote to update with. - private void update(Room local, Room remote) - { - foreach (var pi in remote.Playlist) - pi.MapObjects(beatmaps, rulesets); - - local.CopyFrom(remote); - } - - /// - /// Adds a to the list of available rooms. - /// - /// The to add. - private void addRoom(Room room) - { - var existing = rooms.FirstOrDefault(e => e.RoomID.Value == room.RoomID.Value); - if (existing == null) - rooms.Add(room); - else - existing.CopyFrom(room); - } - private void notifyRoomsUpdated() => Scheduler.AddOnce(() => RoomsUpdated?.Invoke()); } } From b6a2020c59ebd7667d821277fcc25493f07ff4e2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Aug 2021 13:09:04 +0900 Subject: [PATCH 49/83] General refactorings from PR review --- .../Components/ListingPollingComponent.cs | 8 ++++---- .../Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 15 ++++++++------- .../Multiplayer/MultiplayerLoungeSubScreen.cs | 12 ++++++------ 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs index f686326d08..bc6480d05e 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs @@ -15,8 +15,8 @@ namespace osu.Game.Screens.OnlinePlay.Components /// public class ListingPollingComponent : RoomPollingComponent { - public IBindable HasPolledOnce => hasPolledOnce; - private readonly Bindable hasPolledOnce = new Bindable(); + public IBindable InitialRoomsReceived => initialRoomsReceived; + private readonly Bindable initialRoomsReceived = new Bindable(); [Resolved] private Bindable currentFilter { get; set; } @@ -30,7 +30,7 @@ namespace osu.Game.Screens.OnlinePlay.Components currentFilter.BindValueChanged(_ => { RoomManager.ClearRooms(); - hasPolledOnce.Value = false; + initialRoomsReceived.Value = false; if (IsLoaded) PollImmediately(); @@ -60,7 +60,7 @@ namespace osu.Game.Screens.OnlinePlay.Components foreach (var incoming in result) RoomManager.AddOrUpdateRoom(incoming); - hasPolledOnce.Value = true; + initialRoomsReceived.Value = true; tcs.SetResult(true); }; diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 4e3f37f814..bd2648791c 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -45,6 +45,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge AutoSizeAxes = Axes.Both }; + protected ListingPollingComponent ListingPollingComponent { get; private set; } + [Resolved] private Bindable selectedRoom { get; set; } @@ -72,7 +74,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private RoomsContainer roomsContainer; private SearchTextBox searchTextBox; private Dropdown statusDropdown; - private ListingPollingComponent listingPollingComponent; [BackgroundDependencyLoader(true)] private void load([CanBeNull] IdleTracker idleTracker) @@ -86,7 +87,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge InternalChildren = new Drawable[] { - listingPollingComponent = CreatePollingComponent(), + ListingPollingComponent = CreatePollingComponent(), loadingLayer = new LoadingLayer(true), new Container { @@ -186,7 +187,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced()); ruleset.BindValueChanged(_ => UpdateFilter()); - listingPollingComponent.HasPolledOnce.BindValueChanged(_ => updateLoadingLayer()); + ListingPollingComponent.InitialRoomsReceived.BindValueChanged(_ => updateLoadingLayer()); isIdle.BindValueChanged(_ => updatePollingRate(this.IsCurrentScreen()), true); @@ -337,7 +338,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void updateLoadingLayer() { - if (operationInProgress.Value || !listingPollingComponent.HasPolledOnce.Value) + if (operationInProgress.Value || !ListingPollingComponent.InitialRoomsReceived.Value) loadingLayer.Show(); else loadingLayer.Hide(); @@ -346,11 +347,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private void updatePollingRate(bool isCurrentScreen) { if (!isCurrentScreen) - listingPollingComponent.TimeBetweenPolls.Value = 0; + ListingPollingComponent.TimeBetweenPolls.Value = 0; else - listingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000; + ListingPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 120000 : 15000; - Logger.Log($"Polling adjusted (listing: {listingPollingComponent.TimeBetweenPolls.Value})"); + Logger.Log($"Polling adjusted (listing: {ListingPollingComponent.TimeBetweenPolls.Value})"); } protected abstract OsuButton CreateNewRoomButton(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index 77db955f0a..97fed2040d 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient client { get; set; } - private MultiplayerListingPollingComponent listingPollingComponent; + private MultiplayerListingPollingComponent multiplayerListingPollingComponent => (MultiplayerListingPollingComponent)ListingPollingComponent; private readonly IBindable isConnected = new Bindable(); @@ -34,8 +34,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer base.LoadComplete(); isConnected.BindTo(client.IsConnected); - isConnected.BindValueChanged(c => Scheduler.AddOnce(() => listingPollingComponent.AllowPolling = c.NewValue)); - listingPollingComponent.AllowPolling = isConnected.Value; + isConnected.BindValueChanged(c => Scheduler.AddOnce(() => multiplayerListingPollingComponent.AllowPolling = c.NewValue)); + multiplayerListingPollingComponent.AllowPolling = isConnected.Value; } public override void OnResuming(IScreen last) @@ -47,7 +47,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer if (last is MultiplayerMatchSubScreen match) { RoomManager.RemoveRoom(match.Room); - listingPollingComponent.PollImmediately(); + multiplayerListingPollingComponent.PollImmediately(); } } @@ -69,7 +69,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer protected override RoomSubScreen CreateRoomSubScreen(Room room) => new MultiplayerMatchSubScreen(room); - protected override ListingPollingComponent CreatePollingComponent() => listingPollingComponent = new MultiplayerListingPollingComponent(); + protected override ListingPollingComponent CreatePollingComponent() => new MultiplayerListingPollingComponent(); protected override void OpenNewRoom(Room room) { @@ -104,7 +104,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer } } - protected override Task Poll() => !AllowPolling ? Task.CompletedTask : base.Poll(); + protected override Task Poll() => AllowPolling ? base.Poll() : Task.CompletedTask; } } } From 53c3eccfb50bfc6bd3238fa84e2c371a83b4a388 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Aug 2021 07:21:37 +0300 Subject: [PATCH 50/83] Force HUD visibility mode to "Always" during testing --- .../Multiplayer/TestSceneMultiSpectatorScreen.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index 9bb9c24c6b..18e4a6c575 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.MatchTypes.TeamVersus; using osu.Game.Rulesets.UI; @@ -26,6 +27,9 @@ namespace osu.Game.Tests.Visual.Multiplayer [Resolved] private OsuGameBase game { get; set; } + [Resolved] + private OsuConfigManager config { get; set; } + [Resolved] private BeatmapManager beatmapManager { get; set; } @@ -86,6 +90,11 @@ namespace osu.Game.Tests.Visual.Multiplayer [Test] public void TestSpectatorPlayerInteractiveElementsHidden() { + HUDVisibilityMode originalConfigValue = default; + + AddStep("get original config hud visibility", () => originalConfigValue = config.Get(OsuSetting.HUDVisibilityMode)); + AddStep("set config hud visibility to always", () => config.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always)); + start(new[] { PLAYER_1_ID, PLAYER_2_ID }); loadSpectateScreen(false); @@ -100,6 +109,8 @@ namespace osu.Game.Tests.Visual.Multiplayer !p.ChildrenOfType().Any() && !p.ChildrenOfType().Any() && p.ChildrenOfType().SingleOrDefault()?.ShowHandle == false)); + + AddStep("restore config hud visibility", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue)); } [Test] From 81480ac4fc5ea2e14b7790284e8eec3528329bd5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 16:16:02 +0900 Subject: [PATCH 51/83] Use `PlayerConfiguration` to convey no-seek state --- .../Multiplayer/Spectate/MultiSpectatorPlayer.cs | 4 +--- osu.Game/Screens/Play/Player.cs | 8 ++++---- osu.Game/Screens/Play/PlayerConfiguration.cs | 5 +++++ osu.Game/Screens/Play/SpectatorPlayer.cs | 3 ++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index 1b1dee5ae2..feb1af770b 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// The score containing the player's replay. /// The clock controlling the gameplay running state. public MultiSpectatorPlayer([NotNull] Score score, [NotNull] ISpectatorPlayerClock spectatorPlayerClock) - : base(score) + : base(score, new PlayerConfiguration { AllowSeeking = false }) { this.spectatorPlayerClock = spectatorPlayerClock; } @@ -35,8 +35,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { spectatorPlayerClock.WaitingOnFrames.BindTo(waitingOnFrames); - AllowUserSeekingState.Value = false; - AllowUserSeekingState.Disabled = true; HUDOverlay.PlayerSettingsOverlay.Expire(); HUDOverlay.HoldToQuit.Expire(); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index dc37464a61..73bf3f9bda 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -77,9 +77,9 @@ namespace osu.Game.Screens.Play protected readonly Bindable LocalUserPlaying = new Bindable(); - protected readonly Bindable AllowUserSeekingState = new Bindable(); + private readonly Bindable allowUserSeeking = new Bindable(); - public IBindable AllowUserSeeking => AllowUserSeekingState; + public IBindable AllowUserSeeking => allowUserSeeking; public int RestartCount; @@ -275,8 +275,8 @@ namespace osu.Game.Screens.Play DrawableRuleset.HasReplayLoaded.BindValueChanged(r => { - if (!AllowUserSeekingState.Disabled) - AllowUserSeekingState.Value = r.NewValue; + if (Configuration.AllowSeeking) + allowUserSeeking.Value = r.NewValue; updateGameplayState(); }); diff --git a/osu.Game/Screens/Play/PlayerConfiguration.cs b/osu.Game/Screens/Play/PlayerConfiguration.cs index 18ee73374f..39c7a7568e 100644 --- a/osu.Game/Screens/Play/PlayerConfiguration.cs +++ b/osu.Game/Screens/Play/PlayerConfiguration.cs @@ -20,6 +20,11 @@ namespace osu.Game.Screens.Play /// public bool AllowRestart { get; set; } = true; + /// + /// Whether the player should be allowed to seek in a displayed replay. + /// + public bool AllowSeeking { get; set; } = true; + /// /// Whether the player should be allowed to skip intros/outros, advancing to the start of gameplay or the end of a storyboard. /// diff --git a/osu.Game/Screens/Play/SpectatorPlayer.cs b/osu.Game/Screens/Play/SpectatorPlayer.cs index f662a479ec..1dae28092a 100644 --- a/osu.Game/Screens/Play/SpectatorPlayer.cs +++ b/osu.Game/Screens/Play/SpectatorPlayer.cs @@ -23,7 +23,8 @@ namespace osu.Game.Screens.Play protected override bool CheckModsAllowFailure() => false; // todo: better support starting mid-way through beatmap - public SpectatorPlayer(Score score) + public SpectatorPlayer(Score score, PlayerConfiguration configuration = null) + : base(configuration) { this.score = score; } From 838bcc51b2922f6403a8e459aafe8d8ecde41a4a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 16:27:19 +0900 Subject: [PATCH 52/83] Avoid new bindable requirement --- osu.Game/Screens/Play/Player.cs | 20 ++++++++------------ osu.Game/Screens/Play/SongProgress.cs | 3 ++- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 73bf3f9bda..c43b701ebf 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -77,10 +77,6 @@ namespace osu.Game.Screens.Play protected readonly Bindable LocalUserPlaying = new Bindable(); - private readonly Bindable allowUserSeeking = new Bindable(); - - public IBindable AllowUserSeeking => allowUserSeeking; - public int RestartCount; [Resolved] @@ -273,13 +269,7 @@ namespace osu.Game.Screens.Play DrawableRuleset.FrameStableClock.IsCatchingUp.BindValueChanged(_ => updateSampleDisabledState()); - DrawableRuleset.HasReplayLoaded.BindValueChanged(r => - { - if (Configuration.AllowSeeking) - allowUserSeeking.Value = r.NewValue; - - updateGameplayState(); - }); + DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState()); // bind clock into components that require it DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused); @@ -592,7 +582,13 @@ namespace osu.Game.Screens.Play /// Seek to a specific time in gameplay. /// /// The destination time to seek to. - public void Seek(double time) => GameplayClockContainer.Seek(time); + public void Seek(double time) + { + if (!Configuration.AllowSeeking) + throw new InvalidOperationException($"Seeking has ben disabled by the current {nameof(Configuration)}."); + + GameplayClockContainer.Seek(time); + } private ScheduledDelegate frameStablePlaybackResetDelegate; diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 8debe6243d..3e30cf17b3 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -119,7 +119,8 @@ namespace osu.Game.Screens.Play if (drawableRuleset != null) { - ((IBindable)AllowSeeking).BindTo(player.AllowUserSeeking); + if (player?.Configuration.AllowSeeking == true) + ((IBindable)AllowSeeking).BindTo(drawableRuleset.HasReplayLoaded); referenceClock = drawableRuleset.FrameStableClock; Objects = drawableRuleset.Objects; From ae8a1adae838648807431fec10b41826abbd9849 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 16:47:57 +0900 Subject: [PATCH 53/83] Allow seeking via `Player.Seek` even if disabled --- osu.Game/Screens/Play/Player.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c43b701ebf..09eaf1c543 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -582,13 +582,7 @@ namespace osu.Game.Screens.Play /// Seek to a specific time in gameplay. /// /// The destination time to seek to. - public void Seek(double time) - { - if (!Configuration.AllowSeeking) - throw new InvalidOperationException($"Seeking has ben disabled by the current {nameof(Configuration)}."); - - GameplayClockContainer.Seek(time); - } + public void Seek(double time) => GameplayClockContainer.Seek(time); private ScheduledDelegate frameStablePlaybackResetDelegate; From 8d45f86bd3ded0bb0b7c901c3fb30e1b1f7fff93 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 16:48:40 +0900 Subject: [PATCH 54/83] Rename variable to better reflect its purpose --- .../OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs | 2 +- osu.Game/Screens/Play/PlayerConfiguration.cs | 4 ++-- osu.Game/Screens/Play/SongProgress.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs index feb1af770b..ececa1e497 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorPlayer.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate /// The score containing the player's replay. /// The clock controlling the gameplay running state. public MultiSpectatorPlayer([NotNull] Score score, [NotNull] ISpectatorPlayerClock spectatorPlayerClock) - : base(score, new PlayerConfiguration { AllowSeeking = false }) + : base(score, new PlayerConfiguration { AllowUserInteraction = false }) { this.spectatorPlayerClock = spectatorPlayerClock; } diff --git a/osu.Game/Screens/Play/PlayerConfiguration.cs b/osu.Game/Screens/Play/PlayerConfiguration.cs index 39c7a7568e..3aa424e5d5 100644 --- a/osu.Game/Screens/Play/PlayerConfiguration.cs +++ b/osu.Game/Screens/Play/PlayerConfiguration.cs @@ -21,9 +21,9 @@ namespace osu.Game.Screens.Play public bool AllowRestart { get; set; } = true; /// - /// Whether the player should be allowed to seek in a displayed replay. + /// Whether the player should be able to interact with this player instance. /// - public bool AllowSeeking { get; set; } = true; + public bool AllowUserInteraction { get; set; } = true; /// /// Whether the player should be allowed to skip intros/outros, advancing to the start of gameplay or the end of a storyboard. diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index 3e30cf17b3..b27a9c5f5d 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Play if (drawableRuleset != null) { - if (player?.Configuration.AllowSeeking == true) + if (player?.Configuration.AllowUserInteraction == true) ((IBindable)AllowSeeking).BindTo(drawableRuleset.HasReplayLoaded); referenceClock = drawableRuleset.FrameStableClock; From db1a0ebb55448903587ce59bbdf99c5ed90744a5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Aug 2021 18:46:44 +0900 Subject: [PATCH 55/83] Fix preview track crashes --- .../BeatmapListing/Panels/PlayButton.cs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/Panels/PlayButton.cs b/osu.Game/Overlays/BeatmapListing/Panels/PlayButton.cs index 4bbc3569fe..3aa9aa5ca5 100644 --- a/osu.Game/Overlays/BeatmapListing/Panels/PlayButton.cs +++ b/osu.Game/Overlays/BeatmapListing/Panels/PlayButton.cs @@ -139,19 +139,24 @@ namespace osu.Game.Overlays.BeatmapListing.Panels LoadComponentAsync(Preview = previewTrackManager.Get(beatmapSet), preview => { - // beatmapset may have changed. - if (Preview != preview) - return; + // Make sure that we schedule to after the next audio frame to fix crashes in single-threaded execution. + // See: https://github.com/ppy/osu-framework/issues/4692 + Schedule(() => + { + // beatmapset may have changed. + if (Preview != preview) + return; - AddInternal(preview); - loading = false; - // make sure that the update of value of Playing (and the ensuing value change callbacks) - // are marshaled back to the update thread. - preview.Stopped += () => Schedule(() => playing.Value = false); + AddInternal(preview); + loading = false; + // make sure that the update of value of Playing (and the ensuing value change callbacks) + // are marshaled back to the update thread. + preview.Stopped += () => Schedule(() => playing.Value = false); - // user may have changed their mind. - if (playing.Value) - attemptStart(); + // user may have changed their mind. + if (playing.Value) + attemptStart(); + }); }); } else From 855fff1486477eb490ed851a33a26be57b96c095 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Aug 2021 12:47:56 +0300 Subject: [PATCH 56/83] Fix `DifficultyAdjustSettingsControl.SliderControl` not following up with the current pattern This was causing any `ValueChanged` event bind (such as the one in `SettingsItem` to invoke `SettingsChanged`) to be overwritten when `Current` is set afterwards. --- osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs index 067657159b..186514e868 100644 --- a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs +++ b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs @@ -91,7 +91,13 @@ namespace osu.Game.Rulesets.Mods { // This is required as SettingsItem relies heavily on this bindable for internal use. // The actual update flow is done via the bindable provided in the constructor. - public Bindable Current { get; set; } = new Bindable(); + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public Bindable Current + { + get => current.Current; + set => current.Current = value; + } public SliderControl(BindableNumber currentNumber) { From 6653a78e659774213635568d5fd2bdcc7d693170 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Aug 2021 12:48:49 +0300 Subject: [PATCH 57/83] Add test coverage --- .../TestSceneModDifficultyAdjustSettings.cs | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs index e0d76b3e4a..f8652573f4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModDifficultyAdjustSettings.cs @@ -1,8 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -174,6 +176,60 @@ namespace osu.Game.Tests.Visual.UserInterface checkBindableAtValue("Circle Size", null); } + [Test] + public void TestModSettingChangeTracker() + { + ModSettingChangeTracker tracker = null; + Queue settingsChangedQueue = null; + + setBeatmapWithDifficultyParameters(5); + + AddStep("add mod settings change tracker", () => + { + settingsChangedQueue = new Queue(); + + tracker = new ModSettingChangeTracker(modDifficultyAdjust.Yield()) + { + SettingChanged = settingsChangedQueue.Enqueue + }; + }); + + AddAssert("no settings changed", () => settingsChangedQueue.Count == 0); + + setSliderValue("Circle Size", 3); + + settingsChangedFired(); + + setSliderValue("Circle Size", 5); + checkBindableAtValue("Circle Size", 5); + + settingsChangedFired(); + + AddStep("reset mod settings", () => modDifficultyAdjust.CircleSize.SetDefault()); + checkBindableAtValue("Circle Size", null); + + settingsChangedFired(); + + setExtendedLimits(true); + + settingsChangedFired(); + + AddStep("dispose tracker", () => + { + tracker.Dispose(); + tracker = null; + }); + + void settingsChangedFired() + { + AddAssert("setting changed event fired", () => + { + settingsChangedQueue.Dequeue(); + return settingsChangedQueue.Count == 0; + }); + } + } + private void resetToDefault(string name) { AddStep($"Reset {name} to default", () => From e39a295c5c417ec6d71ded0f07b1029849436c89 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Aug 2021 13:45:50 +0300 Subject: [PATCH 58/83] Hide tablet settings content when input handler is disabled --- .../Settings/Sections/Input/TabletSettings.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index c561b693d8..8303fee3ef 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -22,6 +22,8 @@ namespace osu.Game.Overlays.Settings.Sections.Input { private readonly ITabletHandler tabletHandler; + private readonly Bindable enabled = new BindableBool(true); + private readonly Bindable areaOffset = new Bindable(); private readonly Bindable areaSize = new Bindable(); private readonly IBindable tablet = new Bindable(); @@ -74,7 +76,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input LabelText = CommonStrings.Enabled, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Current = tabletHandler.Enabled + Current = enabled, }, noTabletMessage = new FillFlowContainer { @@ -194,6 +196,9 @@ namespace osu.Game.Overlays.Settings.Sections.Input { base.LoadComplete(); + enabled.BindTo(tabletHandler.Enabled); + enabled.BindValueChanged(_ => Scheduler.AddOnce(updateVisibility)); + rotation.BindTo(tabletHandler.Rotation); areaOffset.BindTo(tabletHandler.AreaOffset); @@ -239,7 +244,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input tablet.BindTo(tabletHandler.Tablet); tablet.BindValueChanged(val => { - Scheduler.AddOnce(toggleVisibility); + Scheduler.AddOnce(updateVisibility); var tab = val.NewValue; @@ -259,8 +264,15 @@ namespace osu.Game.Overlays.Settings.Sections.Input }, true); } - private void toggleVisibility() + private void updateVisibility() { + if (!tabletHandler.Enabled.Value) + { + mainSettings.Hide(); + noTabletMessage.Hide(); + return; + } + bool tabletFound = tablet.Value != null; if (!tabletFound) From e485728109869c1e3704056e1c2b9c98708c43d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 19:54:45 +0900 Subject: [PATCH 59/83] Add keywords to make finding audio offset adjustments easier in settings --- osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs index 7f2e377c83..eaa557bb37 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/OffsetSettings.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; @@ -13,6 +15,8 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { protected override LocalisableString Header => "Offset Adjustment"; + public override IEnumerable FilterTerms => base.FilterTerms.Concat(new[] { "universal", "uo", "timing" }); + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { From 568d027013a67ddcc3ff58525001301cf353da8a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 22:07:41 +0900 Subject: [PATCH 60/83] Simplify weird conditionals --- .../Settings/Sections/Input/TabletSettings.cs | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 8303fee3ef..b8b86d9069 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -266,24 +266,16 @@ namespace osu.Game.Overlays.Settings.Sections.Input private void updateVisibility() { - if (!tabletHandler.Enabled.Value) - { - mainSettings.Hide(); - noTabletMessage.Hide(); - return; - } - - bool tabletFound = tablet.Value != null; - - if (!tabletFound) - { - mainSettings.Hide(); - noTabletMessage.Show(); - return; - } - - mainSettings.Show(); + mainSettings.Hide(); noTabletMessage.Hide(); + + if (!tabletHandler.Enabled.Value) + return; + + if (tablet.Value != null) + mainSettings.Show(); + else + noTabletMessage.Show(); } private void applyAspectRatio(BindableNumber sizeChanged) From c3a86769323e11c637cd738393928be1e1499b47 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 23:38:13 +0900 Subject: [PATCH 61/83] Simplify size specifications --- osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs index c51f927f9f..508c8399b6 100644 --- a/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs +++ b/osu.Game/Overlays/Changelog/ChangelogSupporterPromo.cs @@ -144,8 +144,7 @@ namespace osu.Game.Overlays.Changelog { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Width = heart_size, - Height = heart_size, + Size = new Vector2(heart_size), Margin = new MarginPadding { Top = 70 }, Masking = true, EdgeEffect = new EdgeEffectParameters @@ -157,8 +156,7 @@ namespace osu.Game.Overlays.Changelog }, Child = new Sprite { - Width = heart_size, - Height = heart_size, + Size = new Vector2(heart_size), Texture = textures.Get(@"Online/supporter-heart"), }, }, From df6e4664e0aaa47788c1064be78126fe57fa1d75 Mon Sep 17 00:00:00 2001 From: emu1337 Date: Mon, 16 Aug 2021 16:42:07 +0200 Subject: [PATCH 62/83] changed history length in speed --- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index b1373cd215..5b8ec5103a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -29,6 +29,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private const double max_speed_bonus = 45; // ~330BPM private const double speed_balancing_factor = 40; + protected override int HistoryLength => 32; + public Speed(Mod[] mods) : base(mods) { From 19cdd5c3234ad368f81d2c3df8f66abf63fb51df Mon Sep 17 00:00:00 2001 From: Xexxar Date: Mon, 16 Aug 2021 15:25:35 +0000 Subject: [PATCH 63/83] recoded and added rhythm complexity calculator (untested) --- .../Difficulty/Skills/Speed.cs | 82 ++++++++++++++++++- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 5b8ec5103a..73704735d0 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private const double pi_over_4 = Math.PI / 4; private const double pi_over_2 = Math.PI / 2; + private const double rhythmMultiplier = 1.0; protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; protected override int ReducedSectionCount => 5; @@ -31,16 +32,91 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override int HistoryLength => 32; + private const int HistoryTimeMax = 4; // 4 seconds of calculatingRhythmBonus max. + public Speed(Mod[] mods) : base(mods) { } - private double calculateRhythmBonus(double time) + private bool isRatioEqual(double ratio, double a, double b) { - return 1.0; + return a + 15 > ratio * b && a - 15 < ratio * b; } + /// + /// Calculates a rhythm multiplier for the difficulty of the tap associated with historic data of the current . + /// + private double calculateRhythmBonus(double startTime) + { + // {doubles, triplets, quads, quints, 6-tuplets, 7 Tuplets, greater} + int previousIslandSize = -1; + double[] islandTimes = {0, 0, 0, 0, 0, 0, 0}; + int islandSize = 0; + + bool firstDeltaSwitch = false; + + for (int i = Previous.Count - 1; i < 0; i--) + { + double currDelta = ((OsuDifficultyHitObject)Previous[i - 1]).StrainTime; + double prevDelta = ((OsuDifficultyHitObject)Previous[i]).StrainTime; + double effectiveRatio = Math.Min(prevDelta, currDelta) / Math.Max(prevDelta, currDelta); + + double currHistoricalDecay = Math.Max(0, (HistoryTimeMax - (startTime - Previous[i - 1].StartTime))) / HistoryTimeMax; + + // if (historyTime > HistoryTimeMax) + // break; // not sure if this even does what I want.. + + if (firstDeltaSwitch) + { + if (isRatioEqual(1.0, prevDelta, currDelta)) + { + islandSize++; // island is still progressing, count size. + } + + else + { + if (islandSize > 6) + islandSize = 6; + + if (Previous[i - 1].BaseObject is Slider) // bpm change is into slider, this is easy acc window + effectiveRatio *= 0.5; + + if (Previous[i].BaseObject is Slider) // bpm change was from a slider, this is easier typically than circle -> circle + effectiveRatio *= 0.75; + + if (previousIslandSize == islandSize) // repeated island size (ex: triplet -> triplet) + effectiveRatio *= 0.5; + + islandTimes[islandSize] = islandTimes[islandSize] + effectiveRatio * currHistoricalDecay; + + previousIslandSize = islandSize; // log the last island size. + + if (prevDelta * 1.25 < currDelta) // we're slowing down, stop counting + firstDeltaSwitch = false; // if we're speeding up, this stays true and we keep counting island size. + + islandSize = 0; + } + } + else if (prevDelta > 1.25 * currDelta) // we want to be speeding up. + { + // Begin counting island until we change speed again. + firstDeltaSwitch = true; + islandSize = 0; + } + } + + double rhythmComplexitySum = 0.0; + + for (int i = 0; i < islandTimes.Length; i++) + { + rhythmComplexitySum += islandTimes[i]; // sum the total amount of rhythm variance + } + +Console.WriteLine(Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2); + + return Math.Min(1.5, Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2); + } protected override double StrainValueOf(DifficultyHitObject current) { @@ -81,7 +157,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double GetPeakStrain(double time) { - return base.GetPeakStrain(time) * calculateRhythmBonus(time); + return base.GetPeakStrain(time);// * calculateRhythmBonus(current.StartTime); } } } From 7d46b3f9c5fe9062afa5528d025908173c5ca812 Mon Sep 17 00:00:00 2001 From: Xexxar Date: Mon, 16 Aug 2021 16:06:50 +0000 Subject: [PATCH 64/83] initial testing and debugging --- .../Difficulty/Skills/Speed.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 73704735d0..433150a025 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -20,7 +20,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private const double pi_over_4 = Math.PI / 4; private const double pi_over_2 = Math.PI / 2; - private const double rhythmMultiplier = 1.0; + private const double rhythmMultiplier = 1.5; + protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; protected override int ReducedSectionCount => 5; @@ -32,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override int HistoryLength => 32; - private const int HistoryTimeMax = 4; // 4 seconds of calculatingRhythmBonus max. + private const int HistoryTimeMax = 3000; // 4 seconds of calculatingRhythmBonus max. public Speed(Mod[] mods) : base(mods) @@ -56,16 +57,16 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills bool firstDeltaSwitch = false; - for (int i = Previous.Count - 1; i < 0; i--) + for (int i = Previous.Count - 1; i > 0; i--) { double currDelta = ((OsuDifficultyHitObject)Previous[i - 1]).StrainTime; double prevDelta = ((OsuDifficultyHitObject)Previous[i]).StrainTime; double effectiveRatio = Math.Min(prevDelta, currDelta) / Math.Max(prevDelta, currDelta); - double currHistoricalDecay = Math.Max(0, (HistoryTimeMax - (startTime - Previous[i - 1].StartTime))) / HistoryTimeMax; + if (effectiveRatio > 0.5) + effectiveRatio = 0.5 + (effectiveRatio - 0.5) * 5; // extra buff for 1/3 -> 1/4 etc transitions. - // if (historyTime > HistoryTimeMax) - // break; // not sure if this even does what I want.. + double currHistoricalDecay = Math.Max(0, (HistoryTimeMax - (startTime - Previous[i - 1].StartTime))) / HistoryTimeMax; if (firstDeltaSwitch) { @@ -113,9 +114,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills rhythmComplexitySum += islandTimes[i]; // sum the total amount of rhythm variance } -Console.WriteLine(Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2); +// Console.WriteLine(Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2); - return Math.Min(1.5, Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2); + return Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2; } protected override double StrainValueOf(DifficultyHitObject current) From 176b3e75335476273ceb305a60c2b4a0fc9fa3f4 Mon Sep 17 00:00:00 2001 From: Xexxar Date: Mon, 16 Aug 2021 22:14:29 +0000 Subject: [PATCH 65/83] changed decay system to allow for customizing the currentStrain --- .../Difficulty/Skills/Movement.cs | 2 +- .../Difficulty/Skills/Strain.cs | 4 +- .../Difficulty/Skills/Aim.cs | 2 +- .../Difficulty/Skills/OsuStrainSkill.cs | 4 +- .../Difficulty/Skills/Speed.cs | 11 +--- .../Difficulty/Skills/Colour.cs | 2 +- .../Difficulty/Skills/Rhythm.cs | 2 +- .../Difficulty/Skills/Stamina.cs | 2 +- .../Difficulty/Skills/StrainDecaySkill.cs | 64 +++++++++++++++++++ .../Rulesets/Difficulty/Skills/StrainSkill.cs | 44 +++---------- 10 files changed, 83 insertions(+), 54 deletions(-) create mode 100644 osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs diff --git a/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs index 4372ed938c..cfb3fe40be 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs @@ -9,7 +9,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Catch.Difficulty.Skills { - public class Movement : StrainSkill + public class Movement : StrainDecaySkill { private const float absolute_player_positioning_error = 16f; private const float normalized_hitobject_radius = 41.0f; diff --git a/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs b/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs index 2ba2ee6b4a..01d930d585 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/Skills/Strain.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Mania.Difficulty.Skills { - public class Strain : StrainSkill + public class Strain : StrainDecaySkill { private const double individual_decay_base = 0.125; private const double overall_decay_base = 0.30; @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty.Skills return individualStrain + overallStrain - CurrentStrain; } - protected override double GetPeakStrain(double offset) + protected override double CalculateInitialStrain(double offset) => applyDecay(individualStrain, offset - Previous[0].StartTime, individual_decay_base) + applyDecay(overallStrain, offset - Previous[0].StartTime, overall_decay_base); diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 16a18cbcb9..f08c19af76 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances. /// - public class Aim : OsuStrainSkill + public class Aim : OsuStrainDecaySkill { private const double angle_bonus_begin = Math.PI / 3; private const double timing_threshold = 107; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index e47edc37cc..c1bee9b202 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -10,7 +10,7 @@ using osu.Framework.Utils; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { - public abstract class OsuStrainSkill : StrainSkill + public abstract class OsuStrainDecaySkill : StrainDecaySkill { /// /// The number of sections with the highest strains, which the peak strain reductions will apply to. @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// protected virtual double DifficultyMultiplier => 1.06; - protected OsuStrainSkill(Mod[] mods) + protected OsuStrainDecaySkill(Mod[] mods) : base(mods) { } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 433150a025..bb40ff657a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. /// - public class Speed : OsuStrainSkill + public class Speed : OsuStrainDecaySkill { private const double single_spacing_threshold = 125; @@ -151,14 +151,5 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills return (1 + (speedBonus - 1) * 0.75) * angleBonus * (0.95 + speedBonus * Math.Pow(distance / single_spacing_threshold, 3.5)) / osuCurrent.StrainTime; } - protected override double GetTotalCurrentStrain(DifficultyHitObject current) - { - return base.GetTotalCurrentStrain(current) * calculateRhythmBonus(current.StartTime); - } - - protected override double GetPeakStrain(double time) - { - return base.GetPeakStrain(time);// * calculateRhythmBonus(current.StartTime); - } } } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs index 769d021362..0c17ca66b9 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Colour.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills /// /// Calculates the colour coefficient of taiko difficulty. /// - public class Colour : StrainSkill + public class Colour : StrainDecaySkill { protected override double SkillMultiplier => 1; protected override double StrainDecayBase => 0.4; diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs index a32f6ebe0d..973e55f4b4 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Rhythm.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills /// /// Calculates the rhythm coefficient of taiko difficulty. /// - public class Rhythm : StrainSkill + public class Rhythm : StrainDecaySkill { protected override double SkillMultiplier => 10; protected override double StrainDecayBase => 0; diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs index 4cceadb23f..54cf233d69 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills /// /// The reference play style chosen uses two hands, with full alternating (the hand changes after every hit). /// - public class Stamina : StrainSkill + public class Stamina : StrainDecaySkill { protected override double SkillMultiplier => 1; protected override double StrainDecayBase => 0.4; diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs new file mode 100644 index 0000000000..dab1081abb --- /dev/null +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs @@ -0,0 +1,64 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.Linq; +using osu.Game.Rulesets.Difficulty.Preprocessing; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Difficulty.Skills +{ + /// + /// Used to processes strain values of s, keep track of strain levels caused by the processed objects + /// and to calculate a final difficulty value representing the difficulty of hitting all the processed objects. + /// + public abstract class StrainDecaySkill : StrainSkill + { + /// + /// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other. + /// + protected abstract double SkillMultiplier { get; } + + /// + /// Determines how quickly strain decays for the given skill. + /// For example a value of 0.15 indicates that strain decays to 15% of its original value in one second. + /// + protected abstract double StrainDecayBase { get; } + + /// + /// The current strain level. + /// + protected double CurrentStrain { get; private set; } = 1; + + protected StrainDecaySkill(Mod[] mods) + : base(mods) + { + } + + /// + /// Retrieves the peak strain at a point in time. + /// + /// The time to retrieve the peak strain at. + /// The peak strain. + protected override double CalculateInitialStrain(double time) => CurrentStrain * strainDecay(time - Previous[0].StartTime); + + /// + /// Returns the strain value of . This value is calculated with or without respect to previous objects. + /// + protected override double StrainValueAt(DifficultyHitObject current) + { + CurrentStrain *= strainDecay(current.DeltaTime); + CurrentStrain += StrainValueOf(current) * SkillMultiplier; + + return CurrentStrain; + } + + /// + /// Calculates the strain value of a . This value is affected by previously processed objects. + /// + protected abstract double StrainValueOf(DifficultyHitObject current); + + private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000); + } +} diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs index 95b0fe43fc..e8ae452506 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs @@ -15,27 +15,11 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// public abstract class StrainSkill : Skill { - /// - /// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other. - /// - protected abstract double SkillMultiplier { get; } - - /// - /// Determines how quickly strain decays for the given skill. - /// For example a value of 0.15 indicates that strain decays to 15% of its original value in one second. - /// - protected abstract double StrainDecayBase { get; } - /// /// The weight by which each strain value decays. /// protected virtual double DecayWeight => 0.9; - /// - /// The current strain level. - /// - protected double CurrentStrain { get; private set; } = 1; - /// /// The length of each strain section. /// @@ -52,6 +36,11 @@ namespace osu.Game.Rulesets.Difficulty.Skills { } + /// + /// Returns the strain value of . This value is calculated with or without respect to previous objects. + /// + protected abstract double StrainValueAt(DifficultyHitObject current); + /// /// Process a and update current strain values accordingly. /// @@ -68,15 +57,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills currentSectionEnd += SectionLength; } - CurrentStrain *= strainDecay(current.DeltaTime); - CurrentStrain += StrainValueOf(current) * SkillMultiplier; - - currentSectionPeak = Math.Max(GetTotalCurrentStrain(current), currentSectionPeak); - } - - protected virtual double GetTotalCurrentStrain(DifficultyHitObject current) - { - return CurrentStrain; + currentSectionPeak = Math.Max(StrainValueAt(current), currentSectionPeak); } /// @@ -93,9 +74,9 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// The beginning of the new section in milliseconds. private void startNewSectionFrom(double time) { - // The maximum strain of the new section is not zero by default, strain decays as usual regardless of section boundaries. + // The maximum strain of the new section is not zero by default // This means we need to capture the strain level at the beginning of the new section, and use that as the initial peak level. - currentSectionPeak = GetPeakStrain(time); + currentSectionPeak = CalculateInitialStrain(time); } /// @@ -103,7 +84,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills /// /// The time to retrieve the peak strain at. /// The peak strain. - protected virtual double GetPeakStrain(double time) => CurrentStrain * strainDecay(time - Previous[0].StartTime); + protected abstract double CalculateInitialStrain(double time); /// /// Returns a live enumerable of the peak strains for each section of the beatmap, @@ -129,12 +110,5 @@ namespace osu.Game.Rulesets.Difficulty.Skills return difficulty; } - - /// - /// Calculates the strain value of a . This value is affected by previously processed objects. - /// - protected abstract double StrainValueOf(DifficultyHitObject current); - - private double strainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000); } } From 5561e4852e838c226257d09088e3f51e42d6f2d2 Mon Sep 17 00:00:00 2001 From: Xexxar Date: Mon, 16 Aug 2021 22:23:40 +0000 Subject: [PATCH 66/83] removed stuff --- .../Difficulty/Skills/Speed.cs | 85 ------------------- 1 file changed, 85 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index bb40ff657a..78d1438923 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -20,8 +20,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private const double pi_over_4 = Math.PI / 4; private const double pi_over_2 = Math.PI / 2; - private const double rhythmMultiplier = 1.5; - protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; protected override int ReducedSectionCount => 5; @@ -31,94 +29,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private const double max_speed_bonus = 45; // ~330BPM private const double speed_balancing_factor = 40; - protected override int HistoryLength => 32; - - private const int HistoryTimeMax = 3000; // 4 seconds of calculatingRhythmBonus max. - public Speed(Mod[] mods) : base(mods) { } - private bool isRatioEqual(double ratio, double a, double b) - { - return a + 15 > ratio * b && a - 15 < ratio * b; - } - - /// - /// Calculates a rhythm multiplier for the difficulty of the tap associated with historic data of the current . - /// - private double calculateRhythmBonus(double startTime) - { - // {doubles, triplets, quads, quints, 6-tuplets, 7 Tuplets, greater} - int previousIslandSize = -1; - double[] islandTimes = {0, 0, 0, 0, 0, 0, 0}; - int islandSize = 0; - - bool firstDeltaSwitch = false; - - for (int i = Previous.Count - 1; i > 0; i--) - { - double currDelta = ((OsuDifficultyHitObject)Previous[i - 1]).StrainTime; - double prevDelta = ((OsuDifficultyHitObject)Previous[i]).StrainTime; - double effectiveRatio = Math.Min(prevDelta, currDelta) / Math.Max(prevDelta, currDelta); - - if (effectiveRatio > 0.5) - effectiveRatio = 0.5 + (effectiveRatio - 0.5) * 5; // extra buff for 1/3 -> 1/4 etc transitions. - - double currHistoricalDecay = Math.Max(0, (HistoryTimeMax - (startTime - Previous[i - 1].StartTime))) / HistoryTimeMax; - - if (firstDeltaSwitch) - { - if (isRatioEqual(1.0, prevDelta, currDelta)) - { - islandSize++; // island is still progressing, count size. - } - - else - { - if (islandSize > 6) - islandSize = 6; - - if (Previous[i - 1].BaseObject is Slider) // bpm change is into slider, this is easy acc window - effectiveRatio *= 0.5; - - if (Previous[i].BaseObject is Slider) // bpm change was from a slider, this is easier typically than circle -> circle - effectiveRatio *= 0.75; - - if (previousIslandSize == islandSize) // repeated island size (ex: triplet -> triplet) - effectiveRatio *= 0.5; - - islandTimes[islandSize] = islandTimes[islandSize] + effectiveRatio * currHistoricalDecay; - - previousIslandSize = islandSize; // log the last island size. - - if (prevDelta * 1.25 < currDelta) // we're slowing down, stop counting - firstDeltaSwitch = false; // if we're speeding up, this stays true and we keep counting island size. - - islandSize = 0; - } - } - else if (prevDelta > 1.25 * currDelta) // we want to be speeding up. - { - // Begin counting island until we change speed again. - firstDeltaSwitch = true; - islandSize = 0; - } - } - - double rhythmComplexitySum = 0.0; - - for (int i = 0; i < islandTimes.Length; i++) - { - rhythmComplexitySum += islandTimes[i]; // sum the total amount of rhythm variance - } - -// Console.WriteLine(Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2); - - return Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2; - } - protected override double StrainValueOf(DifficultyHitObject current) { if (current.BaseObject is Spinner) From 61045bd0876afac630c9611de1398c0c65677141 Mon Sep 17 00:00:00 2001 From: Xexxar Date: Mon, 16 Aug 2021 22:36:14 +0000 Subject: [PATCH 67/83] adjusted code comments --- osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs | 8 -------- osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs index dab1081abb..dbac132faf 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs @@ -36,16 +36,8 @@ namespace osu.Game.Rulesets.Difficulty.Skills { } - /// - /// Retrieves the peak strain at a point in time. - /// - /// The time to retrieve the peak strain at. - /// The peak strain. protected override double CalculateInitialStrain(double time) => CurrentStrain * strainDecay(time - Previous[0].StartTime); - /// - /// Returns the strain value of . This value is calculated with or without respect to previous objects. - /// protected override double StrainValueAt(DifficultyHitObject current) { CurrentStrain *= strainDecay(current.DeltaTime); diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs index e8ae452506..0880f1b08e 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainSkill.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills } /// - /// Returns the strain value of . This value is calculated with or without respect to previous objects. + /// Returns the strain value at . This value is calculated with or without respect to previous objects. /// protected abstract double StrainValueAt(DifficultyHitObject current); From 9b21016eed1aadc232c0023b23624d61775659c3 Mon Sep 17 00:00:00 2001 From: Xexxar Date: Mon, 16 Aug 2021 22:46:56 +0000 Subject: [PATCH 68/83] accidently renamed osuStrainSkill, fixed --- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 2 +- osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs | 4 ++-- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index f08c19af76..16a18cbcb9 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances. /// - public class Aim : OsuStrainDecaySkill + public class Aim : OsuStrainSkill { private const double angle_bonus_begin = Math.PI / 3; private const double timing_threshold = 107; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs index c1bee9b202..7bcd867a9c 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs @@ -10,7 +10,7 @@ using osu.Framework.Utils; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { - public abstract class OsuStrainDecaySkill : StrainDecaySkill + public abstract class OsuStrainSkill : StrainDecaySkill { /// /// The number of sections with the highest strains, which the peak strain reductions will apply to. @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// protected virtual double DifficultyMultiplier => 1.06; - protected OsuStrainDecaySkill(Mod[] mods) + protected OsuStrainSkill(Mod[] mods) : base(mods) { } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 78d1438923..f0eb199e5f 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. /// - public class Speed : OsuStrainDecaySkill + public class Speed : OsuStrainSkill { private const double single_spacing_threshold = 125; From 97d5b80834568d76ca423cf876aaf9955681a72f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 09:18:21 +0900 Subject: [PATCH 69/83] Fix joining with incorrect password --- .../Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs index 2d94b2328d..776307e20e 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private MultiplayerClient multiplayerClient { get; set; } public override void CreateRoom(Room room, Action onSuccess = null, Action onError = null) - => base.CreateRoom(room, r => joinMultiplayerRoom(r, r.Password.Value, onSuccess, onError), onError); + => base.CreateRoom(room, r => joinMultiplayerRoom(r, room.Password.Value, onSuccess, onError), onError); public override void JoinRoom(Room room, string password = null, Action onSuccess = null, Action onError = null) { From 352949069a4a3130c8db14ea8412ac11c93d57aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 09:36:43 +0900 Subject: [PATCH 70/83] Move filter to LoungeSubScreen --- .../TestSceneLoungeRoomsContainer.cs | 10 ++++----- .../Multiplayer/TestSceneMultiplayer.cs | 22 +++++++++++-------- .../Components/ListingPollingComponent.cs | 10 +++++---- .../Lounge/Components/RoomsContainer.cs | 9 ++++---- .../OnlinePlay/Lounge/LoungeSubScreen.cs | 15 ++++++------- .../Screens/OnlinePlay/OnlinePlayScreen.cs | 4 ---- ...stRequestHandlingMultiplayerRoomManager.cs | 5 ----- .../IOnlinePlayTestSceneDependencies.cs | 6 ----- .../Visual/OnlinePlay/OnlinePlayTestScene.cs | 2 -- .../OnlinePlayTestSceneDependencies.cs | 4 ---- 10 files changed, 35 insertions(+), 52 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index f3d961a646..7e822f898e 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -115,11 +115,11 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4); - AddStep("filter one room", () => container.Filter(new FilterCriteria { SearchString = "1" })); + AddStep("filter one room", () => container.Filter.Value = new FilterCriteria { SearchString = "1" }); AddUntilStep("1 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 1); - AddStep("remove filter", () => container.Filter(null)); + AddStep("remove filter", () => container.Filter.Value = null); AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4); } @@ -131,13 +131,13 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("add rooms", () => RoomManager.AddRooms(3, new CatchRuleset().RulesetInfo)); // Todo: What even is this case...? - AddStep("set empty filter criteria", () => container.Filter(null)); + AddStep("set empty filter criteria", () => container.Filter.Value = null); AddUntilStep("5 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 5); - AddStep("filter osu! rooms", () => container.Filter(new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo })); + AddStep("filter osu! rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo }); AddUntilStep("2 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 2); - AddStep("filter catch rooms", () => container.Filter(new FilterCriteria { Ruleset = new CatchRuleset().RulesetInfo })); + AddStep("filter catch rooms", () => container.Filter.Value = new FilterCriteria { Ruleset = new CatchRuleset().RulesetInfo }); AddUntilStep("3 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 3); } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 08b3fb98a8..cf2f2f259e 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -132,11 +132,9 @@ namespace osu.Game.Tests.Visual.Multiplayer [Test] public void TestExitMidJoin() { - Room room = null; - AddStep("create room", () => { - room = new Room + multiplayerScreen.RoomManager.AddRoom(new Room { Name = { Value = "Test Room" }, Playlist = @@ -147,14 +145,16 @@ namespace osu.Game.Tests.Visual.Multiplayer Ruleset = { Value = new OsuRuleset().RulesetInfo }, } } - }; + }); }); - AddStep("refresh rooms", () => multiplayerScreen.RoomManager.Filter.Value = new FilterCriteria()); + AddStep("refresh rooms", () => this.ChildrenOfType().Single().UpdateFilter()); + AddUntilStep("wait for room", () => this.ChildrenOfType().Any()); + AddStep("select room", () => InputManager.Key(Key.Down)); - AddStep("join room and immediately exit", () => + AddStep("join room and immediately exit select", () => { - multiplayerScreen.ChildrenOfType().Single().Open(room); + InputManager.Key(Key.Enter); Schedule(() => Stack.CurrentScreen.Exit()); }); } @@ -178,7 +178,9 @@ namespace osu.Game.Tests.Visual.Multiplayer }); }); - AddStep("refresh rooms", () => multiplayerScreen.RoomManager.Filter.Value = new FilterCriteria()); + AddStep("refresh rooms", () => this.ChildrenOfType().Single().UpdateFilter()); + AddUntilStep("wait for room", () => this.ChildrenOfType().Any()); + AddStep("select room", () => InputManager.Key(Key.Down)); AddStep("join room", () => InputManager.Key(Key.Enter)); @@ -226,7 +228,9 @@ namespace osu.Game.Tests.Visual.Multiplayer }); }); - AddStep("refresh rooms", () => multiplayerScreen.RoomManager.Filter.Value = new FilterCriteria()); + AddStep("refresh rooms", () => this.ChildrenOfType().Single().UpdateFilter()); + AddUntilStep("wait for room", () => this.ChildrenOfType().Any()); + AddStep("select room", () => InputManager.Key(Key.Down)); AddStep("join room", () => InputManager.Key(Key.Enter)); diff --git a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs index bc6480d05e..1387b5a671 100644 --- a/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs +++ b/osu.Game/Screens/OnlinePlay/Components/ListingPollingComponent.cs @@ -18,8 +18,7 @@ namespace osu.Game.Screens.OnlinePlay.Components public IBindable InitialRoomsReceived => initialRoomsReceived; private readonly Bindable initialRoomsReceived = new Bindable(); - [Resolved] - private Bindable currentFilter { get; set; } + public readonly Bindable Filter = new Bindable(); [Resolved] private Bindable selectedRoom { get; set; } @@ -27,7 +26,7 @@ namespace osu.Game.Screens.OnlinePlay.Components [BackgroundDependencyLoader] private void load() { - currentFilter.BindValueChanged(_ => + Filter.BindValueChanged(_ => { RoomManager.ClearRooms(); initialRoomsReceived.Value = false; @@ -44,10 +43,13 @@ namespace osu.Game.Screens.OnlinePlay.Components if (!API.IsLoggedIn) return base.Poll(); + if (Filter.Value == null) + return base.Poll(); + var tcs = new TaskCompletionSource(); pollReq?.Cancel(); - pollReq = new GetRoomsRequest(currentFilter.Value.Status, currentFilter.Value.Category); + pollReq = new GetRoomsRequest(Filter.Value.Status, Filter.Value.Category); pollReq.Success += result => { diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs index 46d9850fde..e243477a8c 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs @@ -30,8 +30,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components public IReadOnlyList Rooms => roomFlow.FlowingChildren.Cast().ToArray(); - [Resolved(CanBeNull = true)] - private Bindable filter { get; set; } + public readonly Bindable Filter = new Bindable(); [Resolved] private Bindable selectedRoom { get; set; } @@ -74,7 +73,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components rooms.BindTo(roomManager.Rooms); - filter?.BindValueChanged(criteria => Filter(criteria.NewValue)); + Filter?.BindValueChanged(criteria => applyFilterCriteria(criteria.NewValue), true); selectedRoom.BindValueChanged(selection => { @@ -85,7 +84,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components private void updateSelection() => roomFlow.Children.ForEach(r => r.State = r.Room == selectedRoom.Value ? SelectionState.Selected : SelectionState.NotSelected); - public void Filter(FilterCriteria criteria) + private void applyFilterCriteria(FilterCriteria criteria) { roomFlow.Children.ForEach(r => { @@ -126,7 +125,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components roomFlow.Add(new DrawableRoom(room)); } - Filter(filter?.Value); + applyFilterCriteria(Filter?.Value); updateSelection(); } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index bd2648791c..3e8d07d002 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -56,9 +56,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [Resolved(CanBeNull = true)] private OngoingOperationTracker ongoingOperationTracker { get; set; } - [Resolved(CanBeNull = true)] - private Bindable filter { get; set; } - [Resolved] private IBindable ruleset { get; set; } @@ -68,6 +65,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [CanBeNull] private LeasedBindable selectionLease; + private readonly Bindable filter = new Bindable(new FilterCriteria()); private readonly IBindable operationInProgress = new Bindable(); private readonly IBindable isIdle = new BindableBool(); private LoadingLayer loadingLayer; @@ -81,13 +79,11 @@ namespace osu.Game.Screens.OnlinePlay.Lounge if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle); - filter ??= new Bindable(new FilterCriteria()); - OsuScrollContainer scrollContainer; InternalChildren = new Drawable[] { - ListingPollingComponent = CreatePollingComponent(), + ListingPollingComponent = CreatePollingComponent().With(c => c.Filter.BindTarget = filter), loadingLayer = new LoadingLayer(true), new Container { @@ -161,7 +157,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { RelativeSizeAxes = Axes.Both, ScrollbarOverlapsContent = false, - Child = roomsContainer = new RoomsContainer() + Child = roomsContainer = new RoomsContainer + { + Filter = { BindTarget = filter } + } }, } }, @@ -202,7 +201,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge #region Filtering - protected void UpdateFilter() => Scheduler.AddOnce(updateFilter); + public void UpdateFilter() => Scheduler.AddOnce(updateFilter); private ScheduledDelegate scheduledFilterUpdate; diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 183b7e51f9..e5962db608 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -20,7 +20,6 @@ using osu.Game.Overlays; using osu.Game.Screens.Menu; using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Lounge; -using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Users; using osuTK; using osuTK.Graphics; @@ -49,9 +48,6 @@ namespace osu.Game.Screens.OnlinePlay [Cached] private readonly Bindable selectedRoom = new Bindable(); - [Cached] - private readonly Bindable currentFilter = new Bindable(new FilterCriteria()); - [Cached] private readonly OngoingOperationTracker ongoingOperationTracker = new OngoingOperationTracker(); diff --git a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs index 2e56c8a094..31b59be61e 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs @@ -5,14 +5,12 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Rooms; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using osu.Game.Screens.OnlinePlay.Components; -using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Multiplayer; namespace osu.Game.Tests.Visual.Multiplayer @@ -32,9 +30,6 @@ namespace osu.Game.Tests.Visual.Multiplayer [Resolved] private OsuGameBase game { get; set; } - [Cached] - public readonly Bindable Filter = new Bindable(new FilterCriteria()); - public new readonly List Rooms = new List(); private int currentRoomId; diff --git a/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs b/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs index 6e1e831d9b..71acefb158 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/IOnlinePlayTestSceneDependencies.cs @@ -4,7 +4,6 @@ using osu.Framework.Bindables; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay; -using osu.Game.Screens.OnlinePlay.Lounge.Components; namespace osu.Game.Tests.Visual.OnlinePlay { @@ -23,11 +22,6 @@ namespace osu.Game.Tests.Visual.OnlinePlay /// IRoomManager RoomManager { get; } - /// - /// The cached . - /// - Bindable Filter { get; } - /// /// The cached . /// diff --git a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs index 997c910dd4..8716646074 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestScene.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay; -using osu.Game.Screens.OnlinePlay.Lounge.Components; namespace osu.Game.Tests.Visual.OnlinePlay { @@ -20,7 +19,6 @@ namespace osu.Game.Tests.Visual.OnlinePlay { public Bindable SelectedRoom => OnlinePlayDependencies?.SelectedRoom; public IRoomManager RoomManager => OnlinePlayDependencies?.RoomManager; - public Bindable Filter => OnlinePlayDependencies?.Filter; public OngoingOperationTracker OngoingOperationTracker => OnlinePlayDependencies?.OngoingOperationTracker; public OnlinePlayBeatmapAvailabilityTracker AvailabilityTracker => OnlinePlayDependencies?.AvailabilityTracker; diff --git a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs index 05ba509a73..e39711b7ce 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics; using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Screens.OnlinePlay; -using osu.Game.Screens.OnlinePlay.Lounge.Components; namespace osu.Game.Tests.Visual.OnlinePlay { @@ -20,7 +19,6 @@ namespace osu.Game.Tests.Visual.OnlinePlay { public Bindable SelectedRoom { get; } public IRoomManager RoomManager { get; } - public Bindable Filter { get; } public OngoingOperationTracker OngoingOperationTracker { get; } public OnlinePlayBeatmapAvailabilityTracker AvailabilityTracker { get; } @@ -36,7 +34,6 @@ namespace osu.Game.Tests.Visual.OnlinePlay { SelectedRoom = new Bindable(); RoomManager = CreateRoomManager(); - Filter = new Bindable(new FilterCriteria()); OngoingOperationTracker = new OngoingOperationTracker(); AvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker(); @@ -44,7 +41,6 @@ namespace osu.Game.Tests.Visual.OnlinePlay CacheAs(SelectedRoom); CacheAs(RoomManager); - CacheAs(Filter); CacheAs(OngoingOperationTracker); CacheAs(AvailabilityTracker); CacheAs(new OverlayColourProvider(OverlayColourScheme.Plum)); From c4a42c4db007af794104c65c8c768506eb4f5b12 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 09:36:59 +0900 Subject: [PATCH 71/83] Fix BasicTestRoomManager overriding rooms --- .../Tests/Visual/OnlinePlay/BasicTestRoomManager.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs index d7c5a0a0e4..55fbb9f1a6 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs @@ -28,6 +28,8 @@ namespace osu.Game.Tests.Visual.OnlinePlay IBindableList IRoomManager.Rooms => Rooms; + private int currentRoomId; + public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) { room.RoomID.Value ??= Rooms.Select(r => r.RoomID.Value).Where(id => id != null).Select(id => id.Value).DefaultIfEmpty().Max() + 1; @@ -76,9 +78,9 @@ namespace osu.Game.Tests.Visual.OnlinePlay { var room = new Room { - RoomID = { Value = i }, - Position = { Value = i }, - Name = { Value = $"Room {i}" }, + RoomID = { Value = currentRoomId }, + Position = { Value = currentRoomId }, + Name = { Value = $"Room {currentRoomId}" }, Host = { Value = new User { Username = "Host" } }, EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) }, Category = { Value = i % 2 == 0 ? RoomCategory.Spotlight : RoomCategory.Normal }, @@ -101,6 +103,8 @@ namespace osu.Game.Tests.Visual.OnlinePlay } CreateRoom(room); + + currentRoomId++; } } } From 1e282432c90397d976164da3f9e03b99876199da Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 09:40:25 +0900 Subject: [PATCH 72/83] Fix password in a better way --- osu.Game/Screens/OnlinePlay/Components/RoomManager.cs | 3 ++- .../Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs index 43bf3a2ce5..3b6c1c8be0 100644 --- a/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Components/RoomManager.cs @@ -60,7 +60,8 @@ namespace osu.Game.Screens.OnlinePlay.Components AddOrUpdateRoom(result); room.CopyFrom(result); // Also copy back to the source model, since this is likely to have been stored elsewhere. - onSuccess?.Invoke(result); + // The server may not contain all properties (such as password), so invoke success with the given room. + onSuccess?.Invoke(room); }; req.Failure += exception => diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs index 776307e20e..2d94b2328d 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomManager.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private MultiplayerClient multiplayerClient { get; set; } public override void CreateRoom(Room room, Action onSuccess = null, Action onError = null) - => base.CreateRoom(room, r => joinMultiplayerRoom(r, room.Password.Value, onSuccess, onError), onError); + => base.CreateRoom(room, r => joinMultiplayerRoom(r, r.Password.Value, onSuccess, onError), onError); public override void JoinRoom(Room room, string password = null, Action onSuccess = null, Action onError = null) { From b672d4b9366d0a695b8085b649c91c037b59878f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 09:42:17 +0900 Subject: [PATCH 73/83] Refactor RequestHandlingMultiplayerRoomManager to avoid confusion --- .../Multiplayer/TestSceneMultiplayer.cs | 6 +++--- .../Multiplayer/TestMultiplayerClient.cs | 4 ++-- ...stRequestHandlingMultiplayerRoomManager.cs | 20 +++++++------------ 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index cf2f2f259e..8b96f5dc80 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -134,7 +134,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { AddStep("create room", () => { - multiplayerScreen.RoomManager.AddRoom(new Room + multiplayerScreen.RoomManager.AddServerSideRoom(new Room { Name = { Value = "Test Room" }, Playlist = @@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { AddStep("create room", () => { - multiplayerScreen.RoomManager.AddRoom(new Room + multiplayerScreen.RoomManager.AddServerSideRoom(new Room { Name = { Value = "Test Room" }, Playlist = @@ -213,7 +213,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { AddStep("create room", () => { - multiplayerScreen.RoomManager.AddRoom(new Room + multiplayerScreen.RoomManager.AddServerSideRoom(new Room { Name = { Value = "Test Room" }, Password = { Value = "password" }, diff --git a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs index f2da66d666..2c0ca0b872 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestMultiplayerClient.cs @@ -127,7 +127,7 @@ namespace osu.Game.Tests.Visual.Multiplayer protected override Task JoinRoom(long roomId, string? password = null) { - var apiRoom = roomManager.Rooms.Single(r => r.RoomID.Value == roomId); + var apiRoom = roomManager.ServerSideRooms.Single(r => r.RoomID.Value == roomId); if (password != apiRoom.Password.Value) throw new InvalidOperationException("Invalid password."); @@ -260,7 +260,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { Debug.Assert(Room != null); - var apiRoom = roomManager.Rooms.Single(r => r.RoomID.Value == Room.RoomID); + var apiRoom = roomManager.ServerSideRooms.Single(r => r.RoomID.Value == Room.RoomID); var set = apiRoom.Playlist.FirstOrDefault(p => p.BeatmapID == beatmapId)?.Beatmap.Value.BeatmapSet ?? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId)?.BeatmapSet; diff --git a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs index 31b59be61e..41102ae7b5 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual.Multiplayer [Resolved] private OsuGameBase game { get; set; } - public new readonly List Rooms = new List(); + public readonly List ServerSideRooms = new List(); private int currentRoomId; private int currentPlaylistItemId; @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Multiplayer apiRoom.HasPassword.Value = !string.IsNullOrEmpty(createRoomRequest.Room.Password.Value); apiRoom.Password.Value = createRoomRequest.Room.Password.Value; - AddRoom(apiRoom); + AddServerSideRoom(apiRoom); var responseRoom = new APICreatedRoom(); responseRoom.CopyFrom(createResponseRoom(apiRoom, false)); @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Multiplayer case JoinRoomRequest joinRoomRequest: { - var room = Rooms.Single(r => r.RoomID.Value == joinRoomRequest.Room.RoomID.Value); + var room = ServerSideRooms.Single(r => r.RoomID.Value == joinRoomRequest.Room.RoomID.Value); if (joinRoomRequest.Password != room.Password.Value) { @@ -84,14 +84,14 @@ namespace osu.Game.Tests.Visual.Multiplayer case GetRoomsRequest getRoomsRequest: var roomsWithoutParticipants = new List(); - foreach (var r in Rooms) + foreach (var r in ServerSideRooms) roomsWithoutParticipants.Add(createResponseRoom(r, false)); getRoomsRequest.TriggerSuccess(roomsWithoutParticipants); return true; case GetRoomRequest getRoomRequest: - getRoomRequest.TriggerSuccess(createResponseRoom(Rooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId), true)); + getRoomRequest.TriggerSuccess(createResponseRoom(ServerSideRooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId), true)); return true; case GetBeatmapSetRequest getBeatmapSetRequest: @@ -127,17 +127,15 @@ namespace osu.Game.Tests.Visual.Multiplayer }; } - public void AddRoom(Room room) + public void AddServerSideRoom(Room room) { room.RoomID.Value ??= currentRoomId++; for (int i = 0; i < room.Playlist.Count; i++) room.Playlist[i].ID = currentPlaylistItemId++; - Rooms.Add(room); + ServerSideRooms.Add(room); } - public new void RemoveRoom(Room room) => base.RemoveRoom(room); - private Room createResponseRoom(Room room, bool withParticipants) { var responseRoom = new Room(); @@ -147,9 +145,5 @@ namespace osu.Game.Tests.Visual.Multiplayer responseRoom.RecentParticipants.Clear(); return responseRoom; } - - public new void ClearRooms() => base.ClearRooms(); - - public new void Schedule(Action action) => base.Schedule(action); } } From 5214731dc1be8fdfe638143386319377ad839f54 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 09:45:10 +0900 Subject: [PATCH 74/83] Refactor test a bit --- .../Visual/Multiplayer/TestSceneMultiplayer.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 8b96f5dc80..e618b28f40 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -44,6 +44,8 @@ namespace osu.Game.Tests.Visual.Multiplayer private TestMultiplayer multiplayerScreen; private TestMultiplayerClient client; + private TestRequestHandlingMultiplayerRoomManager roomManager => multiplayerScreen.RoomManager; + [Cached(typeof(UserLookupCache))] private UserLookupCache lookupCache = new TestUserLookupCache(); @@ -68,7 +70,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("load dependencies", () => { - client = new TestMultiplayerClient(multiplayerScreen.RoomManager); + client = new TestMultiplayerClient(roomManager); // The screen gets suspended so it stops receiving updates. Child = client; @@ -134,7 +136,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { AddStep("create room", () => { - multiplayerScreen.RoomManager.AddServerSideRoom(new Room + roomManager.AddServerSideRoom(new Room { Name = { Value = "Test Room" }, Playlist = @@ -164,7 +166,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { AddStep("create room", () => { - multiplayerScreen.RoomManager.AddServerSideRoom(new Room + roomManager.AddServerSideRoom(new Room { Name = { Value = "Test Room" }, Playlist = @@ -213,7 +215,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { AddStep("create room", () => { - multiplayerScreen.RoomManager.AddServerSideRoom(new Room + roomManager.AddServerSideRoom(new Room { Name = { Value = "Test Room" }, Password = { Value = "password" }, From f2340c6dac64d6c7dda95e84699586e35d81b964 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 09:48:33 +0900 Subject: [PATCH 75/83] Privatise mutable list --- .../Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs index 41102ae7b5..c3a944f93c 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs @@ -30,7 +30,8 @@ namespace osu.Game.Tests.Visual.Multiplayer [Resolved] private OsuGameBase game { get; set; } - public readonly List ServerSideRooms = new List(); + public IReadOnlyList ServerSideRooms => serverSideRooms; + private readonly List serverSideRooms = new List(); private int currentRoomId; private int currentPlaylistItemId; @@ -133,7 +134,7 @@ namespace osu.Game.Tests.Visual.Multiplayer for (int i = 0; i < room.Playlist.Count; i++) room.Playlist[i].ID = currentPlaylistItemId++; - ServerSideRooms.Add(room); + serverSideRooms.Add(room); } private Room createResponseRoom(Room room, bool withParticipants) From 1e2c0031d7473302f2f39bee34f4e4d2d4088048 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 13:34:44 +0900 Subject: [PATCH 76/83] Remove unused usings --- osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs index dbac132faf..73bab31e82 100644 --- a/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs +++ b/osu.Game/Rulesets/Difficulty/Skills/StrainDecaySkill.cs @@ -2,8 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; -using System.Linq; using osu.Game.Rulesets.Difficulty.Preprocessing; using osu.Game.Rulesets.Mods; From 081524b6c862af923b6f1084e3182f0abd85f59f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 13:44:21 +0900 Subject: [PATCH 77/83] Privatise setters --- osu.Game/Screens/Play/PlayerLoader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index a6592e4d24..969527a758 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -46,14 +46,14 @@ namespace osu.Game.Screens.Play protected override bool PlayResumeSound => false; - protected BeatmapMetadataDisplay MetadataInfo; + protected BeatmapMetadataDisplay MetadataInfo { get; private set; } /// /// A fill flow containing the player settings groups, exposed for the ability to hide it from inheritors of the player loader. /// - protected FillFlowContainer PlayerSettings; + protected FillFlowContainer PlayerSettings { get; private set; } - protected VisualSettings VisualSettings; + protected VisualSettings VisualSettings { get; private set; } protected Task LoadTask { get; private set; } From 3a7b9bf096d1b3c259c8db8c7c44f9c99dc44ff5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 08:56:49 +0300 Subject: [PATCH 78/83] Fix `MatchSettingsOverlay` not resetting focus on hide properly --- .../Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs index 2676453a7e..62a968b508 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs @@ -41,11 +41,13 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components protected override void PopIn() { + base.PopIn(); Settings.MoveToY(0, TRANSITION_DURATION, Easing.OutQuint); } protected override void PopOut() { + base.PopOut(); Settings.MoveToY(-1, TRANSITION_DURATION, Easing.InSine); } From 82eddeffefe1a33035cd44a7a7435c650c316d00 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 16:13:45 +0900 Subject: [PATCH 79/83] Add `LocalUserPlayInfo` interface to convey common information about player status --- osu.Desktop/Windows/GameplayWinKeyBlocker.cs | 8 ++++---- osu.Game/Input/ConfineMouseTracker.cs | 5 +++-- osu.Game/OsuGame.cs | 4 +++- osu.Game/Performance/HighPerformanceSession.cs | 5 +++-- osu.Game/Screens/Play/ILocalUserPlayInfo.cs | 17 +++++++++++++++++ osu.Game/Screens/Play/Player.cs | 4 +++- 6 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 osu.Game/Screens/Play/ILocalUserPlayInfo.cs diff --git a/osu.Desktop/Windows/GameplayWinKeyBlocker.cs b/osu.Desktop/Windows/GameplayWinKeyBlocker.cs index efc3f21149..dbfd170ea1 100644 --- a/osu.Desktop/Windows/GameplayWinKeyBlocker.cs +++ b/osu.Desktop/Windows/GameplayWinKeyBlocker.cs @@ -5,23 +5,23 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Platform; -using osu.Game; using osu.Game.Configuration; +using osu.Game.Screens.Play; namespace osu.Desktop.Windows { public class GameplayWinKeyBlocker : Component { private Bindable disableWinKey; - private Bindable localUserPlaying; + private IBindable localUserPlaying; [Resolved] private GameHost host { get; set; } [BackgroundDependencyLoader] - private void load(OsuGame game, OsuConfigManager config) + private void load(ILocalUserPlayInfo localUserInfo, OsuConfigManager config) { - localUserPlaying = game.LocalUserPlaying.GetBoundCopy(); + localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy(); localUserPlaying.BindValueChanged(_ => updateBlocking()); disableWinKey = config.GetBindable(OsuSetting.GameplayDisableWinKey); diff --git a/osu.Game/Input/ConfineMouseTracker.cs b/osu.Game/Input/ConfineMouseTracker.cs index 75d9c8debb..d2bf953dbc 100644 --- a/osu.Game/Input/ConfineMouseTracker.cs +++ b/osu.Game/Input/ConfineMouseTracker.cs @@ -7,6 +7,7 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Game.Configuration; +using osu.Game.Screens.Play; namespace osu.Game.Input { @@ -24,14 +25,14 @@ namespace osu.Game.Input private IBindable localUserPlaying; [BackgroundDependencyLoader] - private void load(OsuGame game, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) + private void load(ILocalUserPlayInfo localUserInfo, FrameworkConfigManager frameworkConfigManager, OsuConfigManager osuConfigManager) { frameworkConfineMode = frameworkConfigManager.GetBindable(FrameworkSetting.ConfineMouseMode); frameworkWindowMode = frameworkConfigManager.GetBindable(FrameworkSetting.WindowMode); frameworkWindowMode.BindValueChanged(_ => updateConfineMode()); osuConfineMode = osuConfigManager.GetBindable(OsuSetting.ConfineMouseMode); - localUserPlaying = game.LocalUserPlaying.GetBoundCopy(); + localUserPlaying = localUserInfo.IsPlaying.GetBoundCopy(); osuConfineMode.ValueChanged += _ => updateConfineMode(); localUserPlaying.BindValueChanged(_ => updateConfineMode(), true); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fb682e0909..0db63df69b 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -62,7 +62,7 @@ namespace osu.Game /// The full osu! experience. Builds on top of to add menus and binding logic /// for initial components that are generally retrieved via DI. /// - public class OsuGame : OsuGameBase, IKeyBindingHandler + public class OsuGame : OsuGameBase, IKeyBindingHandler, ILocalUserPlayInfo { /// /// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications). @@ -1085,5 +1085,7 @@ namespace osu.Game if (newScreen == null) Exit(); } + + IBindable ILocalUserPlayInfo.IsPlaying => LocalUserPlaying; } } diff --git a/osu.Game/Performance/HighPerformanceSession.cs b/osu.Game/Performance/HighPerformanceSession.cs index 661c1046f1..3ef0e0bf93 100644 --- a/osu.Game/Performance/HighPerformanceSession.cs +++ b/osu.Game/Performance/HighPerformanceSession.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Screens.Play; namespace osu.Game.Performance { @@ -12,9 +13,9 @@ namespace osu.Game.Performance private readonly IBindable localUserPlaying = new Bindable(); [BackgroundDependencyLoader] - private void load(OsuGame game) + private void load(ILocalUserPlayInfo localUserInfo) { - localUserPlaying.BindTo(game.LocalUserPlaying); + localUserPlaying.BindTo(localUserInfo.IsPlaying); } protected override void LoadComplete() diff --git a/osu.Game/Screens/Play/ILocalUserPlayInfo.cs b/osu.Game/Screens/Play/ILocalUserPlayInfo.cs new file mode 100644 index 0000000000..64c3f97305 --- /dev/null +++ b/osu.Game/Screens/Play/ILocalUserPlayInfo.cs @@ -0,0 +1,17 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; + +namespace osu.Game.Screens.Play +{ + [Cached] + public interface ILocalUserPlayInfo + { + /// + /// Whether the local user is currently playing. + /// + public IBindable IsPlaying { get; } + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 09eaf1c543..5461c6ac6c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play { [Cached] [Cached(typeof(ISamplePlaybackDisabler))] - public abstract class Player : ScreenWithBeatmapBackground, ISamplePlaybackDisabler + public abstract class Player : ScreenWithBeatmapBackground, ISamplePlaybackDisabler, ILocalUserPlayInfo { /// /// The delay upon completion of the beatmap before displaying the results screen. @@ -1052,5 +1052,7 @@ namespace osu.Game.Screens.Play #endregion IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => samplePlaybackDisabled; + + IBindable ILocalUserPlayInfo.IsPlaying => LocalUserPlaying; } } From 6ee6a468941525b3b6d98369c4f3fdcdd30c58d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 16:22:12 +0900 Subject: [PATCH 80/83] Remove unnecessary `public` prefix in interface specification --- osu.Game/Screens/Play/ILocalUserPlayInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/ILocalUserPlayInfo.cs b/osu.Game/Screens/Play/ILocalUserPlayInfo.cs index 64c3f97305..9a2259b12f 100644 --- a/osu.Game/Screens/Play/ILocalUserPlayInfo.cs +++ b/osu.Game/Screens/Play/ILocalUserPlayInfo.cs @@ -12,6 +12,6 @@ namespace osu.Game.Screens.Play /// /// Whether the local user is currently playing. /// - public IBindable IsPlaying { get; } + IBindable IsPlaying { get; } } } From 8a1651e8308f1ee865d22cc81f9bc87192e962a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 17:04:32 +0900 Subject: [PATCH 81/83] Reorganise methods in `PollingComponent` --- osu.Game/Online/PollingComponent.cs | 73 ++++++++++++++--------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/osu.Game/Online/PollingComponent.cs b/osu.Game/Online/PollingComponent.cs index 806c0047e7..243be8da44 100644 --- a/osu.Game/Online/PollingComponent.cs +++ b/osu.Game/Online/PollingComponent.cs @@ -47,39 +47,13 @@ namespace osu.Game.Online pollIfNecessary(); } - private bool pollIfNecessary() + /// + /// Immediately performs a . + /// + public void PollImmediately() { - // we must be loaded so we have access to clock. - if (!IsLoaded) return false; - - // there's already a poll process running. - if (pollingActive) return false; - - // don't try polling if the time between polls hasn't been set. - if (TimeBetweenPolls.Value == 0) return false; - - if (!lastTimePolled.HasValue) - { - doPoll(); - return true; - } - - if (Time.Current - lastTimePolled.Value > TimeBetweenPolls.Value) - { - doPoll(); - return true; - } - - // not enough time has passed since the last poll. we do want to schedule a poll to happen, though. + lastTimePolled = Time.Current - TimeBetweenPolls.Value; scheduleNextPoll(); - return false; - } - - private void doPoll() - { - scheduledPoll = null; - pollingActive = true; - Poll().ContinueWith(_ => pollComplete()); } /// @@ -90,13 +64,11 @@ namespace osu.Game.Online return Task.CompletedTask; } - /// - /// Immediately performs a . - /// - public void PollImmediately() + private void doPoll() { - lastTimePolled = Time.Current - TimeBetweenPolls.Value; - scheduleNextPoll(); + scheduledPoll = null; + pollingActive = true; + Poll().ContinueWith(_ => pollComplete()); } /// @@ -111,6 +83,33 @@ namespace osu.Game.Online pollIfNecessary(); } + private void pollIfNecessary() + { + // we must be loaded so we have access to clock. + if (!IsLoaded) return; + + // there's already a poll process running. + if (pollingActive) return; + + // don't try polling if the time between polls hasn't been set. + if (TimeBetweenPolls.Value == 0) return; + + if (!lastTimePolled.HasValue) + { + doPoll(); + return; + } + + if (Time.Current - lastTimePolled.Value > TimeBetweenPolls.Value) + { + doPoll(); + return; + } + + // not enough time has passed since the last poll. we do want to schedule a poll to happen, though. + scheduleNextPoll(); + } + private void scheduleNextPoll() { scheduledPoll?.Cancel(); From 9eb16fa61de76cd0432cb199503ef9a4f31f6d2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 17:16:21 +0900 Subject: [PATCH 82/83] Move poll allowance logic based on signalr connection inside polling component --- .../Multiplayer/MultiplayerLoungeSubScreen.cs | 47 +++++++------------ 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index 97fed2040d..d152fc3913 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -25,19 +25,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient client { get; set; } - private MultiplayerListingPollingComponent multiplayerListingPollingComponent => (MultiplayerListingPollingComponent)ListingPollingComponent; - - private readonly IBindable isConnected = new Bindable(); - - protected override void LoadComplete() - { - base.LoadComplete(); - - isConnected.BindTo(client.IsConnected); - isConnected.BindValueChanged(c => Scheduler.AddOnce(() => multiplayerListingPollingComponent.AllowPolling = c.NewValue)); - multiplayerListingPollingComponent.AllowPolling = isConnected.Value; - } - public override void OnResuming(IScreen last) { base.OnResuming(last); @@ -47,7 +34,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer if (last is MultiplayerMatchSubScreen match) { RoomManager.RemoveRoom(match.Room); - multiplayerListingPollingComponent.PollImmediately(); + ListingPollingComponent.PollImmediately(); } } @@ -84,27 +71,29 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private class MultiplayerListingPollingComponent : ListingPollingComponent { - private bool allowPolling; + [Resolved] + private MultiplayerClient client { get; set; } - public bool AllowPolling + private readonly IBindable isConnected = new Bindable(); + + [BackgroundDependencyLoader] + private void load() { - get => allowPolling; - set + isConnected.BindTo(client.IsConnected); + isConnected.BindValueChanged(c => Scheduler.AddOnce(() => { - if (allowPolling == value) - return; - - allowPolling = value; - - if (!allowPolling) - return; - - if (IsLoaded) + if (isConnected.Value && IsLoaded) PollImmediately(); - } + }), true); } - protected override Task Poll() => AllowPolling ? base.Poll() : Task.CompletedTask; + protected override Task Poll() + { + if (!isConnected.Value) + return Task.CompletedTask; + + return base.Poll(); + } } } } From 3b5fc6d10ff17fb06f43cdd107036a6e7da0164a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 17:18:23 +0900 Subject: [PATCH 83/83] Ensure `updateLoadingLayer` is run at least once --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 3e8d07d002..8bed3d6049 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -186,16 +186,16 @@ namespace osu.Game.Screens.OnlinePlay.Lounge searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced()); ruleset.BindValueChanged(_ => UpdateFilter()); - ListingPollingComponent.InitialRoomsReceived.BindValueChanged(_ => updateLoadingLayer()); - isIdle.BindValueChanged(_ => updatePollingRate(this.IsCurrentScreen()), true); if (ongoingOperationTracker != null) { operationInProgress.BindTo(ongoingOperationTracker.InProgress); - operationInProgress.BindValueChanged(_ => updateLoadingLayer(), true); + operationInProgress.BindValueChanged(_ => updateLoadingLayer()); } + ListingPollingComponent.InitialRoomsReceived.BindValueChanged(_ => updateLoadingLayer(), true); + updateFilter(); }