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.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs index 8818cef8eb..80bb82c769 100644 --- a/osu.Desktop/DiscordRichPresence.cs +++ b/osu.Desktop/DiscordRichPresence.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; +using System.Text; using DiscordRPC; using DiscordRPC.Message; using osu.Framework.Allocation; @@ -43,6 +45,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 => @@ -77,8 +83,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 { @@ -96,6 +102,27 @@ namespace osu.Desktop client.SetPresence(presence); } + private static readonly int ellipsis_length = Encoding.UTF8.GetByteCount(new[] { '…' }); + + private string truncate(string str) + { + if (Encoding.UTF8.GetByteCount(str) <= 128) + return str; + + ReadOnlyMemory strMem = str.AsMemory(); + + do + { + strMem = strMem[..^1]; + } while (Encoding.UTF8.GetByteCount(strMem.Span) + ellipsis_length > 128); + + return string.Create(strMem.Length + 1, strMem, (span, mem) => + { + mem.Span.CopyTo(span); + span[^1] = '…'; + }); + } + private string getDetails(UserActivity activity) { switch (activity) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 1cac4d76ab..f5b7bc3073 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -12,10 +12,12 @@ using osu.Framework.Input.Events; namespace osu.Game.Graphics.UserInterface { - public class OsuTextBox : TextBox + public class OsuTextBox : BasicTextBox { protected override float LeftRightPadding => 10; + protected override float CaretWidth => 3; + protected override SpriteText CreatePlaceholder() => new OsuSpriteText { Font = OsuFont.GetFont(italics: true), @@ -41,6 +43,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; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 231115d1e1..b28d572b5c 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(); } @@ -244,10 +247,18 @@ 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 exitDialog) + { + exitConfirmed = true; + exitDialog.Buttons.First().Click(); + } + else + { + dialogOverlay.Push(new ConfirmExitDialog(confirmAndExit, () => exitConfirmOverlay.Abort())); + return true; + } } buttons.State = ButtonSystemState.Exit; 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); 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 @@ - +