From e505e71d07ae4109ad66de2e6fee801bd217cc16 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 30 Jun 2023 21:40:00 +0200 Subject: [PATCH 01/12] Merge the two `app.manifest` files --- app.manifest | 1 + osu.Desktop/app.manifest | 21 --------------------- osu.Desktop/osu.Desktop.csproj | 1 - 3 files changed, 1 insertion(+), 22 deletions(-) delete mode 100644 osu.Desktop/app.manifest diff --git a/app.manifest b/app.manifest index 533c6ff208..b85df82c4d 100644 --- a/app.manifest +++ b/app.manifest @@ -1,6 +1,7 @@  + 1 diff --git a/osu.Desktop/app.manifest b/osu.Desktop/app.manifest deleted file mode 100644 index a11cee132c..0000000000 --- a/osu.Desktop/app.manifest +++ /dev/null @@ -1,21 +0,0 @@ - - - - 1 - - - - - - - - - - - - - - true - - - diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index f1b9c92429..16d6a81d40 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -8,7 +8,6 @@ osu! osu!(lazer) lazer.ico - app.manifest 0.0.0 0.0.0 From 909edefa2048f59ffb6cf623f8fce8d16f5ca2d2 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 30 Jun 2023 21:41:18 +0200 Subject: [PATCH 02/12] Remove unnecessary `` osu! was working fine without this. --- app.manifest | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app.manifest b/app.manifest index b85df82c4d..2e5ba1b18a 100644 --- a/app.manifest +++ b/app.manifest @@ -32,16 +32,4 @@ true - - - - - From bfa5bcb2a77de4b3416128b8d829e99fee06036d Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 30 Jun 2023 21:43:01 +0200 Subject: [PATCH 03/12] Update `` to match what osu! actually supports --- app.manifest | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app.manifest b/app.manifest index 2e5ba1b18a..69702111ce 100644 --- a/app.manifest +++ b/app.manifest @@ -15,15 +15,9 @@ - - - - - - - + From b0e716feab3f728e4bf59b3800a86fdaf1e030ee Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 30 Jun 2023 21:59:46 +0200 Subject: [PATCH 04/12] Use correct `perMonitorV2` `` Yes, `xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings"` is required else the game will exit with code 500 on startup. --- app.manifest | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app.manifest b/app.manifest index 69702111ce..ad8b5d005a 100644 --- a/app.manifest +++ b/app.manifest @@ -23,7 +23,8 @@ - true + per Monitor + perMonitorV2 From caba571263b6fca21fde60d25ac755a8308e21ec Mon Sep 17 00:00:00 2001 From: Susko3 Date: Sat, 1 Jul 2023 19:11:48 +0200 Subject: [PATCH 05/12] Remove manifest DPI awareness entires It'll be properly handled by osu!framework with https://github.com/ppy/osu/pull/24092 --- app.manifest | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app.manifest b/app.manifest index ad8b5d005a..088ad1dde7 100644 --- a/app.manifest +++ b/app.manifest @@ -21,10 +21,4 @@ - - - per Monitor - perMonitorV2 - - From 45194b2b4a4ebb26ce3f1fc2e948f4d21495f828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 9 Jul 2023 18:21:43 +0200 Subject: [PATCH 06/12] Fix pressing Ctrl-C in composer not copying timestamp to system clipboard --- .../Screens/Edit/Compose/ComposeScreen.cs | 25 +++++++++------- osu.Game/Screens/Edit/EditorScreen.cs | 29 +++++++------------ 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs index dc026f7eac..433fb5c8ee 100644 --- a/osu.Game/Screens/Edit/Compose/ComposeScreen.cs +++ b/osu.Game/Screens/Edit/Compose/ComposeScreen.cs @@ -101,26 +101,31 @@ namespace osu.Game.Screens.Edit.Compose #region Clipboard operations - protected override void PerformCut() + public override void Cut() { - base.PerformCut(); + if (!CanCut.Value) + return; Copy(); EditorBeatmap.RemoveRange(EditorBeatmap.SelectedHitObjects.ToArray()); } - protected override void PerformCopy() + public override void Copy() { - base.PerformCopy(); + // on stable, pressing Ctrl-C would copy the current timestamp to system clipboard + // regardless of whether anything was even selected at all. + // UX-wise this is generally strange and unexpected, but make it work anyways to preserve muscle memory. + // note that this means that `getTimestamp()` must handle no-selection case, too. + host.GetClipboard()?.SetText(getTimestamp()); - clipboard.Value = new ClipboardContent(EditorBeatmap).Serialize(); - - host.GetClipboard()?.SetText(formatSelectionAsString()); + if (CanCopy.Value) + clipboard.Value = new ClipboardContent(EditorBeatmap).Serialize(); } - protected override void PerformPaste() + public override void Paste() { - base.PerformPaste(); + if (!CanPaste.Value) + return; var objects = clipboard.Value.Deserialize().HitObjects; @@ -147,7 +152,7 @@ namespace osu.Game.Screens.Edit.Compose CanPaste.Value = composer.IsLoaded && !string.IsNullOrEmpty(clipboard.Value); } - private string formatSelectionAsString() + private string getTimestamp() { if (composer == null) return string.Empty; diff --git a/osu.Game/Screens/Edit/EditorScreen.cs b/osu.Game/Screens/Edit/EditorScreen.cs index b39c0cf5f3..3bc870b898 100644 --- a/osu.Game/Screens/Edit/EditorScreen.cs +++ b/osu.Game/Screens/Edit/EditorScreen.cs @@ -44,29 +44,23 @@ namespace osu.Game.Screens.Edit /// /// Performs a "cut to clipboard" operation appropriate for the given screen. /// - protected virtual void PerformCut() + /// + /// Implementors are responsible for checking themselves. + /// + public virtual void Cut() { } - public void Cut() - { - if (CanCut.Value) - PerformCut(); - } - public BindableBool CanCopy { get; } = new BindableBool(); /// /// Performs a "copy to clipboard" operation appropriate for the given screen. /// - protected virtual void PerformCopy() - { - } - + /// + /// Implementors are responsible for checking themselves. + /// public virtual void Copy() { - if (CanCopy.Value) - PerformCopy(); } public BindableBool CanPaste { get; } = new BindableBool(); @@ -74,14 +68,11 @@ namespace osu.Game.Screens.Edit /// /// Performs a "paste from clipboard" operation appropriate for the given screen. /// - protected virtual void PerformPaste() - { - } - + /// + /// Implementors are responsible for checking themselves. + /// public virtual void Paste() { - if (CanPaste.Value) - PerformPaste(); } #endregion From d135b3f6f57a6d3e67ec45b3a250bbf58451ae4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 9 Jul 2023 21:27:33 +0200 Subject: [PATCH 07/12] Add message length limit field to API response --- osu.Game/Online/Chat/Channel.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 761e8aba8d..3f43560f41 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -86,6 +86,9 @@ namespace osu.Game.Online.Chat [JsonProperty(@"last_read_id")] public long? LastReadId; + [JsonProperty(@"message_length_limit")] + public int MessageLengthLimit; + /// /// Signals if the current user joined this channel or not. Defaults to false. /// Note that this does not guarantee a join has completed. Check Id > 0 for confirmation. From 2af8c7bc24e3435dba1c7feb08bd1ee923bc9d36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 9 Jul 2023 21:35:24 +0200 Subject: [PATCH 08/12] Add failing test case for chat message length limit enforcement --- .../Visual/Online/TestSceneChatTextBox.cs | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs b/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs index 1e80acd56b..8c5475223c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatTextBox.cs @@ -3,11 +3,13 @@ #nullable disable +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.API.Requests.Responses; @@ -18,7 +20,7 @@ using osu.Game.Overlays.Chat; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public partial class TestSceneChatTextBox : OsuTestScene + public partial class TestSceneChatTextBox : OsuManualInputManagerTestScene { [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); @@ -30,6 +32,8 @@ namespace osu.Game.Tests.Visual.Online private OsuSpriteText searchText; private ChatTextBar bar; + private ChatTextBox textBox => bar.ChildrenOfType().Single(); + [SetUp] public void SetUp() { @@ -115,6 +119,36 @@ namespace osu.Game.Tests.Visual.Online AddStep("Chat Mode Search", () => bar.ShowSearch.Value = true); } + [Test] + public void TestLengthLimit() + { + var firstChannel = new Channel + { + Name = "#test1", + Type = ChannelType.Public, + Id = 4567, + MessageLengthLimit = 20 + }; + var secondChannel = new Channel + { + Name = "#test2", + Type = ChannelType.Public, + Id = 5678, + MessageLengthLimit = 5 + }; + + AddStep("switch to channel with 20 char length limit", () => currentChannel.Value = firstChannel); + AddStep("type a message", () => textBox.Current.Value = "abcdefgh"); + + AddStep("switch to channel with 5 char length limit", () => currentChannel.Value = secondChannel); + AddAssert("text box empty", () => textBox.Current.Value, () => Is.Empty); + AddStep("type too much", () => textBox.Current.Value = "123456"); + AddAssert("text box has 5 chars", () => textBox.Current.Value, () => Has.Length.EqualTo(5)); + + AddStep("switch back to channel with 20 char length limit", () => currentChannel.Value = firstChannel); + AddAssert("unsent message preserved without truncation", () => textBox.Current.Value, () => Is.EqualTo("abcdefgh")); + } + private static Channel createPublicChannel(string name) => new Channel { Name = name, Type = ChannelType.Public, Id = 1234 }; From 6453ab6049937e6e47d114ac5baa979771b369f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 9 Jul 2023 21:42:13 +0200 Subject: [PATCH 09/12] Set chat text box message length limit based on channel --- osu.Game/Overlays/Chat/ChatTextBar.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Overlays/Chat/ChatTextBar.cs b/osu.Game/Overlays/Chat/ChatTextBar.cs index 87e787fcb8..16a8d14b10 100644 --- a/osu.Game/Overlays/Chat/ChatTextBar.cs +++ b/osu.Game/Overlays/Chat/ChatTextBar.cs @@ -156,7 +156,11 @@ namespace osu.Game.Overlays.Chat chatTextBox.Current.UnbindFrom(change.OldValue.TextBoxMessage); if (newChannel != null) + { + // change length limit first before binding to avoid accidentally truncating pending message from new channel. + chatTextBox.LengthLimit = newChannel.MessageLengthLimit; chatTextBox.Current.BindTo(newChannel.TextBoxMessage); + } }, true); } From 91e286560ef53428cc6159e4df6b1c641e503c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 9 Jul 2023 21:49:50 +0200 Subject: [PATCH 10/12] Fix search being broken in channel listing "channel" --- osu.Game/Online/Chat/Channel.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index 3f43560f41..15ce926039 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -12,6 +12,7 @@ using osu.Framework.Bindables; using osu.Framework.Lists; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Chat; +using osu.Game.Overlays.Chat.Listing; namespace osu.Game.Online.Chat { @@ -86,8 +87,11 @@ namespace osu.Game.Online.Chat [JsonProperty(@"last_read_id")] public long? LastReadId; + /// + /// Purposefully nullable for the sake of . + /// [JsonProperty(@"message_length_limit")] - public int MessageLengthLimit; + public int? MessageLengthLimit; /// /// Signals if the current user joined this channel or not. Defaults to false. From 89b110e3aa318a16bab399df07408576ac9d9aae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 Jul 2023 21:26:20 +0900 Subject: [PATCH 11/12] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 270a0aa44b..759167829c 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -11,7 +11,7 @@ manifestmerger.jar - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 184a77a286..7968364243 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 51bcc36621..2e691da079 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -16,6 +16,6 @@ iossimulator-x64 - + From 82364b4f9f8ceb5fdc5512fb763067b84cf3696e Mon Sep 17 00:00:00 2001 From: Zyf Date: Tue, 11 Jul 2023 02:46:32 +0200 Subject: [PATCH 12/12] Use OsuScoreProcessor in the scoring test scene --- osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs index 2b378c8013..c722d67ac9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScoring.cs @@ -17,7 +17,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays.Settings; -using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Objects; @@ -125,8 +125,8 @@ namespace osu.Game.Tests.Visual.Gameplay graphs.Clear(); legend.Clear(); - runForProcessor("lazer-standardised", Color4.YellowGreen, new ScoreProcessor(new OsuRuleset()), ScoringMode.Standardised); - runForProcessor("lazer-classic", Color4.MediumPurple, new ScoreProcessor(new OsuRuleset()), ScoringMode.Classic); + runForProcessor("lazer-standardised", Color4.YellowGreen, new OsuScoreProcessor(), ScoringMode.Standardised); + runForProcessor("lazer-classic", Color4.MediumPurple, new OsuScoreProcessor(), ScoringMode.Classic); runScoreV1(); runScoreV2();