diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs index af7cc003a5..c793535255 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatLink.cs @@ -60,7 +60,11 @@ 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($"{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)] 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; diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 9a194dba47..f055633d64 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); @@ -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 otherIndex, int otherLength) => Index < otherIndex + otherLength && otherIndex < Index + Length; public int CompareTo(Link? otherLink) => Index > otherLink?.Index ? 1 : -1; }