mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 04:52:57 +08:00
Merge pull request #24921 from Pasi4K5/diff-name-search
Add ability to search for difficulty names using square brackets
This commit is contained in:
commit
19be0055d5
@ -2,10 +2,12 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Filter;
|
using osu.Game.Rulesets.Filter;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
using osu.Game.Screens.Select.Carousel;
|
||||||
using osu.Game.Screens.Select.Filter;
|
using osu.Game.Screens.Select.Filter;
|
||||||
|
|
||||||
namespace osu.Game.Tests.NonVisual.Filtering
|
namespace osu.Game.Tests.NonVisual.Filtering
|
||||||
@ -382,6 +384,57 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
Assert.AreEqual("unrecognised=keyword", filterCriteria.SearchText.Trim());
|
Assert.AreEqual("unrecognised=keyword", filterCriteria.SearchText.Trim());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase("[1]", new[] { 0 })]
|
||||||
|
[TestCase("[1", new[] { 0 })]
|
||||||
|
[TestCase("My[Favourite", new[] { 2 })]
|
||||||
|
[TestCase("My[Favourite]", new[] { 2 })]
|
||||||
|
[TestCase("My[Favourite]Song", new[] { 2 })]
|
||||||
|
[TestCase("Favourite]", new[] { 2 })]
|
||||||
|
[TestCase("[Diff", new[] { 0, 1, 3, 4, 6 })]
|
||||||
|
[TestCase("[Diff]", new[] { 0, 1, 3, 4, 6 })]
|
||||||
|
[TestCase("[Favourite]", new[] { 3 })]
|
||||||
|
[TestCase("Title1 [Diff]", new[] { 0, 1 })]
|
||||||
|
[TestCase("Title1[Diff]", new int[] { })]
|
||||||
|
[TestCase("[diff ]with]", new[] { 4 })]
|
||||||
|
[TestCase("[diff ]with [[ brackets]]]]", new[] { 4 })]
|
||||||
|
[TestCase("[Diff in title]", new int[] { })]
|
||||||
|
[TestCase("[Diff in diff]", new[] { 6 })]
|
||||||
|
[TestCase("diff=Diff", new[] { 0, 1, 3, 4, 6 })]
|
||||||
|
[TestCase("diff=Diff1", new[] { 0 })]
|
||||||
|
[TestCase("diff=\"Diff\"", new[] { 3, 4, 6 })]
|
||||||
|
[TestCase("diff=!\"Diff\"", new int[] { })]
|
||||||
|
public void TestDifficultySearch(string query, int[] expectedBeatmapIndexes)
|
||||||
|
{
|
||||||
|
var carouselBeatmaps = (((string title, string difficultyName)[])new[]
|
||||||
|
{
|
||||||
|
("Title1", "Diff1"),
|
||||||
|
("Title1", "Diff2"),
|
||||||
|
("My[Favourite]Song", "Expert"),
|
||||||
|
("Title", "My Favourite Diff"),
|
||||||
|
("Another One", "diff ]with [[ brackets]]]"),
|
||||||
|
("Diff in title", "a"),
|
||||||
|
("a", "Diff in diff"),
|
||||||
|
}).Select(info => new CarouselBeatmap(new BeatmapInfo
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = info.title
|
||||||
|
},
|
||||||
|
DifficultyName = info.difficultyName
|
||||||
|
})).ToList();
|
||||||
|
|
||||||
|
var criteria = new FilterCriteria();
|
||||||
|
|
||||||
|
FilterQueryParser.ApplyQueries(criteria, query);
|
||||||
|
carouselBeatmaps.ForEach(b => b.Filter(criteria));
|
||||||
|
|
||||||
|
int[] visibleBeatmaps = carouselBeatmaps
|
||||||
|
.Where(b => !b.Filtered.Value)
|
||||||
|
.Select(b => carouselBeatmaps.IndexOf(b)).ToArray();
|
||||||
|
|
||||||
|
Assert.That(visibleBeatmaps, Is.EqualTo(expectedBeatmapIndexes));
|
||||||
|
}
|
||||||
|
|
||||||
private class CustomFilterCriteria : IRulesetFilterCriteria
|
private class CustomFilterCriteria : IRulesetFilterCriteria
|
||||||
{
|
{
|
||||||
public string? CustomValue { get; set; }
|
public string? CustomValue { get; set; }
|
||||||
|
@ -59,7 +59,7 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
criteria.Artist.Matches(BeatmapInfo.Metadata.ArtistUnicode);
|
criteria.Artist.Matches(BeatmapInfo.Metadata.ArtistUnicode);
|
||||||
match &= !criteria.Title.HasFilter || criteria.Title.Matches(BeatmapInfo.Metadata.Title) ||
|
match &= !criteria.Title.HasFilter || criteria.Title.Matches(BeatmapInfo.Metadata.Title) ||
|
||||||
criteria.Title.Matches(BeatmapInfo.Metadata.TitleUnicode);
|
criteria.Title.Matches(BeatmapInfo.Metadata.TitleUnicode);
|
||||||
|
match &= !criteria.DifficultyName.HasFilter || criteria.DifficultyName.Matches(BeatmapInfo.DifficultyName);
|
||||||
match &= !criteria.UserStarDifficulty.HasFilter || criteria.UserStarDifficulty.IsInRange(BeatmapInfo.StarRating);
|
match &= !criteria.UserStarDifficulty.HasFilter || criteria.UserStarDifficulty.IsInRange(BeatmapInfo.StarRating);
|
||||||
|
|
||||||
if (!match) return false;
|
if (!match) return false;
|
||||||
|
@ -38,6 +38,7 @@ namespace osu.Game.Screens.Select
|
|||||||
public OptionalTextFilter Creator;
|
public OptionalTextFilter Creator;
|
||||||
public OptionalTextFilter Artist;
|
public OptionalTextFilter Artist;
|
||||||
public OptionalTextFilter Title;
|
public OptionalTextFilter Title;
|
||||||
|
public OptionalTextFilter DifficultyName;
|
||||||
|
|
||||||
public OptionalRange<double> UserStarDifficulty = new OptionalRange<double>
|
public OptionalRange<double> UserStarDifficulty = new OptionalRange<double>
|
||||||
{
|
{
|
||||||
@ -68,8 +69,23 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
string remainingText = value;
|
string remainingText = value;
|
||||||
|
|
||||||
|
// Match either an open difficulty tag to the end of string,
|
||||||
|
// or match a closed one with a whitespace after it.
|
||||||
|
//
|
||||||
|
// To keep things simple, the closing ']' may be included in the match group,
|
||||||
|
// and is trimmed post-match.
|
||||||
|
foreach (Match quotedSegment in Regex.Matches(value, "(^|\\s)\\[(.*)(\\]\\s|$)"))
|
||||||
|
{
|
||||||
|
DifficultyName = new OptionalTextFilter
|
||||||
|
{
|
||||||
|
SearchTerm = quotedSegment.Groups[2].Value.Trim(']')
|
||||||
|
};
|
||||||
|
|
||||||
|
remainingText = remainingText.Replace(quotedSegment.Value, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
// First handle quoted segments to ensure we keep inline spaces in exact matches.
|
// First handle quoted segments to ensure we keep inline spaces in exact matches.
|
||||||
foreach (Match quotedSegment in Regex.Matches(searchText, "(\"[^\"]+\"[!]?)"))
|
foreach (Match quotedSegment in Regex.Matches(value, "(\"[^\"]+\"[!]?)"))
|
||||||
{
|
{
|
||||||
terms.Add(new OptionalTextFilter { SearchTerm = quotedSegment.Value });
|
terms.Add(new OptionalTextFilter { SearchTerm = quotedSegment.Value });
|
||||||
remainingText = remainingText.Replace(quotedSegment.Value, string.Empty);
|
remainingText = remainingText.Replace(quotedSegment.Value, string.Empty);
|
||||||
|
@ -76,6 +76,9 @@ namespace osu.Game.Screens.Select
|
|||||||
case "title":
|
case "title":
|
||||||
return TryUpdateCriteriaText(ref criteria.Title, op, value);
|
return TryUpdateCriteriaText(ref criteria.Title, op, value);
|
||||||
|
|
||||||
|
case "diff":
|
||||||
|
return TryUpdateCriteriaText(ref criteria.DifficultyName, op, value);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return criteria.RulesetCriteria?.TryParseCustomKeywordCriteria(key, op, value) ?? false;
|
return criteria.RulesetCriteria?.TryParseCustomKeywordCriteria(key, op, value) ?? false;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user