From 7f9ae55f5eab245e2051d0a85744031289424ad4 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 1 Dec 2023 00:45:35 +0100 Subject: [PATCH 1/6] Add passing tests --- osu.Game.Tests/Visual/Online/TestSceneChatLink.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index 8d4ff82303..2dde1447e4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -60,7 +60,9 @@ namespace osu.Game.Tests.Visual.Online [TestCase("http://dev.ppy.sh!", LinkAction.External)] [TestCase("forgothttps://dev.ppy.sh!", LinkAction.External)] [TestCase("forgothttp://dev.ppy.sh!", LinkAction.External)] + [TestCase("00:12:345 - Test?", LinkAction.OpenEditorTimestamp)] [TestCase("00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)] + [TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 - Test?", LinkAction.OpenEditorTimestamp)] [TestCase("Wiki link for tasty [[Performance Points]]", LinkAction.OpenWiki)] [TestCase("(osu forums)[https://dev.ppy.sh/forum] (old link format)", LinkAction.External)] [TestCase("[https://dev.ppy.sh/home New site] (new link format)", LinkAction.External)] From c395ae2460fbbc7e8329060732fa132f1df7ca01 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 1 Dec 2023 00:49:21 +0100 Subject: [PATCH 2/6] Add failing tests They throws `ArgumentOutOfRangeException` on the first drawable Update() --- osu.Game.Tests/Visual/Online/TestSceneChatLink.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index 2dde1447e4..e77ff5c1cd 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -63,6 +63,8 @@ namespace osu.Game.Tests.Visual.Online [TestCase("00:12:345 - Test?", LinkAction.OpenEditorTimestamp)] [TestCase("00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)] [TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 - Test?", LinkAction.OpenEditorTimestamp)] + [TestCase($"{OsuGameBase.OSU_PROTOCOL}edit/00:12:345 (1,2) - Test?", LinkAction.OpenEditorTimestamp)] + [TestCase($"{OsuGameBase.OSU_PROTOCOL}00:12:345 - not an editor timestamp", LinkAction.External)] [TestCase("Wiki link for tasty [[Performance Points]]", LinkAction.OpenWiki)] [TestCase("(osu forums)[https://dev.ppy.sh/forum] (old link format)", LinkAction.External)] [TestCase("[https://dev.ppy.sh/home New site] (new link format)", LinkAction.External)] From 152c7e513ea98e0e25f3e3461c81307b6bd61376 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Thu, 30 Nov 2023 22:59:02 +0100 Subject: [PATCH 3/6] Ignore overlapping links instead of crashing --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 40e883f8ac..aa72996fff 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; +using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Online; using osu.Game.Users; @@ -47,9 +48,16 @@ namespace osu.Game.Graphics.Containers foreach (var link in links) { + string displayText = text.Substring(link.Index, link.Length); + + if (previousLinkEnd > link.Index) + { + Logger.Log($@"Link ""{link.Url}"" with text ""{displayText}"" overlaps previous link, ignoring."); + continue; + } + AddText(text[previousLinkEnd..link.Index]); - string displayText = text.Substring(link.Index, link.Length); object linkArgument = link.Argument; string tooltip = displayText == link.Url ? null : link.Url; From 30bdd2d4c0eaa6922ced5f44c589df93d50c9518 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 1 Dec 2023 01:07:23 +0100 Subject: [PATCH 4/6] Extract `Overlaps()` logic to accept generic index and length --- osu.Game/Online/Chat/MessageFormatter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 9a194dba47..078af667d1 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -364,7 +364,9 @@ namespace osu.Game.Online.Chat Argument = argument; } - public bool Overlaps(Link otherLink) => Index < otherLink.Index + otherLink.Length && otherLink.Index < Index + Length; + public bool Overlaps(Link otherLink) => Overlaps(otherLink.Index, otherLink.Length); + + public bool Overlaps(int index, int length) => Index < index + length && index < Index + Length; public int CompareTo(Link? otherLink) => Index > otherLink?.Index ? 1 : -1; } From d3517998cff60db3d80d38a9fc71460ce1707258 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 1 Dec 2023 01:08:22 +0100 Subject: [PATCH 5/6] Use common `Overlaps()` logic This actually fixes the problem and makes the tests pass --- osu.Game/Online/Chat/MessageFormatter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 078af667d1..c5256c3c74 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -85,8 +85,8 @@ namespace osu.Game.Online.Chat if (escapeChars != null) displayText = escapeChars.Aggregate(displayText, (current, c) => current.Replace($"\\{c}", c.ToString())); - // Check for encapsulated links - if (result.Links.Find(l => (l.Index <= index && l.Index + l.Length >= index + m.Length) || (index <= l.Index && index + m.Length >= l.Index + l.Length)) == null) + // Check for overlapping links + if (!result.Links.Exists(l => l.Overlaps(index, m.Length))) { result.Text = result.Text.Remove(index, m.Length).Insert(index, displayText); From abb4c943a7f36a5e8fb4ada240cfb66ed433a9e0 Mon Sep 17 00:00:00 2001 From: Susko3 Date: Fri, 1 Dec 2023 18:35:57 +0100 Subject: [PATCH 6/6] Rename to more readable names --- osu.Game/Online/Chat/MessageFormatter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index c5256c3c74..f055633d64 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -366,7 +366,7 @@ namespace osu.Game.Online.Chat public bool Overlaps(Link otherLink) => Overlaps(otherLink.Index, otherLink.Length); - public bool Overlaps(int index, int length) => Index < index + length && index < Index + Length; + public bool Overlaps(int otherIndex, int otherLength) => Index < otherIndex + otherLength && otherIndex < Index + Length; public int CompareTo(Link? otherLink) => Index > otherLink?.Index ? 1 : -1; }