From 5d29ff29cbe4464288b299dc2841664d7c970430 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 22 Dec 2019 20:52:00 +0800 Subject: [PATCH 01/14] Animate "Good bye" instead on exit --- osu.Game/Screens/Menu/MainMenu.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 231115d1e1..8437748d9d 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osuTK; using osuTK.Graphics; using osu.Framework.Allocation; @@ -132,6 +133,8 @@ namespace osu.Game.Screens.Menu private void confirmAndExit() { + if (exitConfirmed) return; + exitConfirmed = true; this.Exit(); } @@ -250,6 +253,12 @@ namespace osu.Game.Screens.Menu return true; } + if (dialogOverlay.CurrentDialog is ConfirmExitDialog) + { + exitConfirmed = true; + dialogOverlay.CurrentDialog.Buttons.First().Click(); + } + buttons.State = ButtonSystemState.Exit; this.FadeOut(3000); return base.OnExiting(next); From 1f41acc5b92648a2d3c51afcf775346cf9090404 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 22 Dec 2019 21:20:55 +0800 Subject: [PATCH 02/14] Integrate auto click into exit confirmed check --- osu.Game/Screens/Menu/MainMenu.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 8437748d9d..ee4d98bd89 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -247,14 +247,14 @@ namespace osu.Game.Screens.Menu public override bool OnExiting(IScreen next) { - if (!exitConfirmed && dialogOverlay != null && !(dialogOverlay.CurrentDialog is ConfirmExitDialog)) + if (!exitConfirmed && dialogOverlay != null) { - dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort())); - return true; - } + if (!(dialogOverlay.CurrentDialog is ConfirmExitDialog)) + { + dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort())); + return true; + } - if (dialogOverlay.CurrentDialog is ConfirmExitDialog) - { exitConfirmed = true; dialogOverlay.CurrentDialog.Buttons.First().Click(); } From 796223d3e0e3f62c640a7c4a64046c781b257d87 Mon Sep 17 00:00:00 2001 From: mcendu Date: Sun, 22 Dec 2019 21:39:25 +0800 Subject: [PATCH 03/14] Invert if --- osu.Game/Screens/Menu/MainMenu.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index ee4d98bd89..b28d572b5c 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -249,14 +249,16 @@ namespace osu.Game.Screens.Menu { if (!exitConfirmed && dialogOverlay != null) { - if (!(dialogOverlay.CurrentDialog is ConfirmExitDialog)) + if (dialogOverlay.CurrentDialog is ConfirmExitDialog exitDialog) + { + exitConfirmed = true; + exitDialog.Buttons.First().Click(); + } + else { dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort())); return true; } - - exitConfirmed = true; - dialogOverlay.CurrentDialog.Buttons.First().Click(); } buttons.State = ButtonSystemState.Exit; From e2b4e3580cc55caaa7a0a0941150ab5464d063f8 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sat, 21 Dec 2019 15:48:15 +0100 Subject: [PATCH 04/14] Truncate strings passed to the Discord RPC client to a maximum of 128 bytes --- osu.Desktop/DiscordRichPresence.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index b53ca6161b..45552f1906 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -1,7 +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.Linq; +using System.Text; using DiscordRPC; +using DiscordRPC.Helper; using DiscordRPC.Message; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -78,8 +81,8 @@ namespace osu.Desktop if (status.Value is UserStatusOnline && activity.Value != null) { - presence.State = activity.Value.Status; - presence.Details = getDetails(activity.Value); + presence.State = truncate(activity.Value.Status); + presence.Details = truncate(getDetails(activity.Value)); } else { @@ -97,6 +100,8 @@ namespace osu.Desktop client.SetPresence(presence); } + private string truncate(string str) => str.WithinLength(128) ? str : new string (str.TakeWhile((c, i) => Encoding.UTF8.GetByteCount(str.Substring(0, i + 1)) <= 125).ToArray()) + '…'; //the ellipsis char is 3 bytes long in UTF8 + private string getDetails(UserActivity activity) { switch (activity) From 125f4286ae75fec93c83a50c243536782a898aed Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 23 Dec 2019 10:55:44 +0100 Subject: [PATCH 05/14] Move truncate() to a method body --- osu.Desktop/DiscordRichPresence.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index 45552f1906..cd5fba533b 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -100,7 +100,13 @@ namespace osu.Desktop client.SetPresence(presence); } - private string truncate(string str) => str.WithinLength(128) ? str : new string (str.TakeWhile((c, i) => Encoding.UTF8.GetByteCount(str.Substring(0, i + 1)) <= 125).ToArray()) + '…'; //the ellipsis char is 3 bytes long in UTF8 + private string truncate(string str) + { + if (str.WithinLength(128)) + return str; + + return new string(str.TakeWhile((c, i) => Encoding.UTF8.GetByteCount(str.Substring(0, i + 1)) <= 125).ToArray()) + '…'; //the ellipsis char is 3 bytes long in UTF8 + } private string getDetails(UserActivity activity) { From c7936e40d5c2b02a37ef7821b5d9698146e68a88 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 23 Dec 2019 19:13:36 +0900 Subject: [PATCH 06/14] Protect against potential nullref --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 5dfdeb5ebc..8970f9ac88 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -562,7 +562,7 @@ namespace osu.Game.Screens.Play // GameplayClockContainer performs seeks / start / stop operations on the beatmap's track. // as we are no longer the current screen, we cannot guarantee the track is still usable. - GameplayClockContainer.StopUsingBeatmapClock(); + GameplayClockContainer?.StopUsingBeatmapClock(); fadeOut(); return base.OnExiting(next); From 43024122430816e425d69174bf554edfd2be4930 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 23 Dec 2019 19:34:12 +0900 Subject: [PATCH 07/14] Simplify implementation --- osu.Desktop/DiscordRichPresence.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index cd5fba533b..85e4b8db55 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; +using System; using System.Text; using DiscordRPC; -using DiscordRPC.Helper; using DiscordRPC.Message; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -100,12 +99,19 @@ namespace osu.Desktop client.SetPresence(presence); } - private string truncate(string str) + private string truncate(ReadOnlySpan str) { - if (str.WithinLength(128)) - return str; + if (Encoding.UTF8.GetByteCount(str) < 128) + return new string(str); - return new string(str.TakeWhile((c, i) => Encoding.UTF8.GetByteCount(str.Substring(0, i + 1)) <= 125).ToArray()) + '…'; //the ellipsis char is 3 bytes long in UTF8 + int ellipsisLength = Encoding.UTF8.GetByteCount(new[] { '…' }); + + do + { + str = str[..^1]; + } while (Encoding.UTF8.GetByteCount(str) + ellipsisLength > 128); + + return new string(str) + '…'; } private string getDetails(UserActivity activity) From b9bc1c954eae7513a1fbb31e90cc71ed43c2aabd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 23 Dec 2019 19:50:35 +0900 Subject: [PATCH 08/14] Disable automatic retry of failed discord RPC connections --- osu.Desktop/DiscordRichPresence.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index 8818cef8eb..71b73ec78e 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -43,6 +43,10 @@ namespace osu.Desktop }; client.OnReady += onReady; + + // safety measure for now, until we performance test / improve backoff for failed connections. + client.OnConnectionFailed += (_, __) => client.Deinitialize(); + client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network); (user = provider.LocalUser.GetBoundCopy()).BindValueChanged(u => From f1f9e1f658cca54a0888629a6cd9e5c761fe3115 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 23 Dec 2019 19:56:05 +0900 Subject: [PATCH 09/14] Don't truncate with exactly 128 bytes --- osu.Desktop/DiscordRichPresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index 9d2fad2e1a..ce878edda8 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -100,7 +100,7 @@ namespace osu.Desktop private string truncate(ReadOnlySpan str) { - if (Encoding.UTF8.GetByteCount(str) < 128) + if (Encoding.UTF8.GetByteCount(str) <= 128) return new string(str); int ellipsisLength = Encoding.UTF8.GetByteCount(new[] { '…' }); From 0bfd7579362d55a258163c70ba1a8640b1e11eff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 24 Dec 2019 14:21:16 +0900 Subject: [PATCH 10/14] Make OsuTextBox use BasicTextBox --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 1cac4d76ab..72fa135699 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -12,7 +12,7 @@ using osu.Framework.Input.Events; namespace osu.Game.Graphics.UserInterface { - public class OsuTextBox : TextBox + public class OsuTextBox : BasicTextBox { protected override float LeftRightPadding => 10; @@ -41,6 +41,8 @@ namespace osu.Game.Graphics.UserInterface BackgroundCommit = BorderColour = colour.Yellow; } + protected override Color4 SelectionColour => new Color4(249, 90, 255, 255); + protected override void OnFocus(FocusEvent e) { BorderThickness = 3; From e088a856620a584ba4dd8b639e9033b6df7f65f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Dec 2019 17:12:12 +0900 Subject: [PATCH 11/14] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index dd11804b90..d684b73d8d 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -54,6 +54,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 757e0e11fa..4c5f3e0f38 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 0dba92b975..ccfbee9a62 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From bc75bd34f6222c5fa3ccd5678d745700061e10a4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 24 Dec 2019 18:23:09 +0900 Subject: [PATCH 12/14] Fix caret width having changed --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 72fa135699..f5b7bc3073 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -16,6 +16,8 @@ namespace osu.Game.Graphics.UserInterface { protected override float LeftRightPadding => 10; + protected override float CaretWidth => 3; + protected override SpriteText CreatePlaceholder() => new OsuSpriteText { Font = OsuFont.GetFont(italics: true), From 36dd0e69980eb39c4df566a4ead1b5773dec737d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 25 Dec 2019 11:14:40 +0900 Subject: [PATCH 13/14] Make ellipsis length into a static --- osu.Desktop/DiscordRichPresence.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index ce878edda8..73c717b97c 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -98,17 +98,17 @@ namespace osu.Desktop client.SetPresence(presence); } + private static readonly int ellipsis_length = Encoding.UTF8.GetByteCount(new[] { '…' }); + private string truncate(ReadOnlySpan str) { if (Encoding.UTF8.GetByteCount(str) <= 128) return new string(str); - int ellipsisLength = Encoding.UTF8.GetByteCount(new[] { '…' }); - do { str = str[..^1]; - } while (Encoding.UTF8.GetByteCount(str) + ellipsisLength > 128); + } while (Encoding.UTF8.GetByteCount(str) + ellipsis_length > 128); return new string(str) + '…'; } From 1a7937bcf73f0fe3bc87666df542b6e1c0cd3ba6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 25 Dec 2019 12:04:28 +0900 Subject: [PATCH 14/14] Apply suggested optimisations --- osu.Desktop/DiscordRichPresence.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index 73c717b97c..05004cf76e 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.cs @@ -100,17 +100,23 @@ namespace osu.Desktop private static readonly int ellipsis_length = Encoding.UTF8.GetByteCount(new[] { '…' }); - private string truncate(ReadOnlySpan str) + private string truncate(string str) { if (Encoding.UTF8.GetByteCount(str) <= 128) - return new string(str); + return str; + + ReadOnlyMemory strMem = str.AsMemory(); do { - str = str[..^1]; - } while (Encoding.UTF8.GetByteCount(str) + ellipsis_length > 128); + strMem = strMem[..^1]; + } while (Encoding.UTF8.GetByteCount(strMem.Span) + ellipsis_length > 128); - return new string(str) + '…'; + return string.Create(strMem.Length + 1, strMem, (span, mem) => + { + mem.Span.CopyTo(span); + span[^1] = '…'; + }); } private string getDetails(UserActivity activity)