mirror of
https://github.com/ppy/osu.git
synced 2025-01-30 06:12:58 +08:00
Add ability to search for difficulty names
This commit is contained in:
parent
81130eacd1
commit
793d1bf970
@ -64,6 +64,8 @@ namespace osu.Game.Screens.Select.Carousel
|
|||||||
|
|
||||||
if (!match) return false;
|
if (!match) return false;
|
||||||
|
|
||||||
|
match &= criteria.DifficultySearchTerms.All(term => term.Matches(BeatmapInfo.DifficultyName));
|
||||||
|
|
||||||
if (criteria.SearchTerms.Length > 0)
|
if (criteria.SearchTerms.Length > 0)
|
||||||
{
|
{
|
||||||
var searchableTerms = BeatmapInfo.GetSearchableTerms();
|
var searchableTerms = BeatmapInfo.GetSearchableTerms();
|
||||||
|
@ -46,6 +46,7 @@ namespace osu.Game.Screens.Select
|
|||||||
};
|
};
|
||||||
|
|
||||||
public OptionalTextFilter[] SearchTerms = Array.Empty<OptionalTextFilter>();
|
public OptionalTextFilter[] SearchTerms = Array.Empty<OptionalTextFilter>();
|
||||||
|
public OptionalTextFilter[] DifficultySearchTerms = Array.Empty<OptionalTextFilter>();
|
||||||
|
|
||||||
public RulesetInfo? Ruleset;
|
public RulesetInfo? Ruleset;
|
||||||
public bool AllowConvertedBeatmaps;
|
public bool AllowConvertedBeatmaps;
|
||||||
@ -64,24 +65,7 @@ namespace osu.Game.Screens.Select
|
|||||||
{
|
{
|
||||||
searchText = value;
|
searchText = value;
|
||||||
|
|
||||||
List<OptionalTextFilter> terms = new List<OptionalTextFilter>();
|
SearchTerms = getTermsFromSearchText(value);
|
||||||
|
|
||||||
string remainingText = value;
|
|
||||||
|
|
||||||
// First handle quoted segments to ensure we keep inline spaces in exact matches.
|
|
||||||
foreach (Match quotedSegment in Regex.Matches(searchText, "(\"[^\"]+\"[!]?)"))
|
|
||||||
{
|
|
||||||
terms.Add(new OptionalTextFilter { SearchTerm = quotedSegment.Value });
|
|
||||||
remainingText = remainingText.Replace(quotedSegment.Value, string.Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Then handle the rest splitting on any spaces.
|
|
||||||
terms.AddRange(remainingText.Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(s => new OptionalTextFilter
|
|
||||||
{
|
|
||||||
SearchTerm = s
|
|
||||||
}));
|
|
||||||
|
|
||||||
SearchTerms = terms.ToArray();
|
|
||||||
|
|
||||||
SearchNumber = null;
|
SearchNumber = null;
|
||||||
|
|
||||||
@ -90,6 +74,11 @@ namespace osu.Game.Screens.Select
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string DifficultySearchText
|
||||||
|
{
|
||||||
|
set => DifficultySearchTerms = getTermsFromSearchText(value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Hashes from the <see cref="BeatmapCollection"/> to filter to.
|
/// Hashes from the <see cref="BeatmapCollection"/> to filter to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -97,6 +86,28 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
public IRulesetFilterCriteria? RulesetCriteria { get; set; }
|
public IRulesetFilterCriteria? RulesetCriteria { get; set; }
|
||||||
|
|
||||||
|
private static OptionalTextFilter[] getTermsFromSearchText(string searchText)
|
||||||
|
{
|
||||||
|
List<OptionalTextFilter> terms = new List<OptionalTextFilter>();
|
||||||
|
|
||||||
|
string remainingText = searchText;
|
||||||
|
|
||||||
|
// First handle quoted segments to ensure we keep inline spaces in exact matches.
|
||||||
|
foreach (Match quotedSegment in Regex.Matches(searchText, "(\"[^\"]+\"[!]?)"))
|
||||||
|
{
|
||||||
|
terms.Add(new OptionalTextFilter { SearchTerm = quotedSegment.Value });
|
||||||
|
remainingText = remainingText.Replace(quotedSegment.Value, string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then handle the rest splitting on any spaces.
|
||||||
|
terms.AddRange(remainingText.Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(s => new OptionalTextFilter
|
||||||
|
{
|
||||||
|
SearchTerm = s
|
||||||
|
}));
|
||||||
|
|
||||||
|
return terms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
public struct OptionalRange<T> : IEquatable<OptionalRange<T>>
|
public struct OptionalRange<T> : IEquatable<OptionalRange<T>>
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
|
@ -19,8 +19,27 @@ namespace osu.Game.Screens.Select
|
|||||||
@"\b(?<key>\w+)(?<op>(:|=|(>|<)(:|=)?))(?<value>("".*""[!]?)|(\S*))",
|
@"\b(?<key>\w+)(?<op>(:|=|(>|<)(:|=)?))(?<value>("".*""[!]?)|(\S*))",
|
||||||
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
private static readonly Regex difficulty_query_syntax_regex = new Regex(
|
||||||
|
@"(\s|^)((\[(?>\[(?<level>)|[^[\]]+|\](?<-level>))*(?(level)(?!))\](\s|$))|(\[.*))",
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
|
||||||
internal static void ApplyQueries(FilterCriteria criteria, string query)
|
internal static void ApplyQueries(FilterCriteria criteria, string query)
|
||||||
{
|
{
|
||||||
|
foreach (Match match in difficulty_query_syntax_regex.Matches(query))
|
||||||
|
{
|
||||||
|
// Trim the first character because it's always '[' (ignoring spaces)
|
||||||
|
string cleanDifficultyQuery = match.Value.Trim(' ')[1..];
|
||||||
|
|
||||||
|
if (cleanDifficultyQuery.EndsWith(']'))
|
||||||
|
cleanDifficultyQuery = cleanDifficultyQuery[..^1];
|
||||||
|
|
||||||
|
criteria.DifficultySearchText = cleanDifficultyQuery;
|
||||||
|
|
||||||
|
// Insert whitespace if necessary so that the words before and after the difficulty query aren't joined together.
|
||||||
|
bool insertWhitespace = match.Value.StartsWith(' ') && match.Value.EndsWith(' ');
|
||||||
|
query = query.Replace(match.Value, insertWhitespace ? " " : "");
|
||||||
|
}
|
||||||
|
|
||||||
foreach (Match match in query_syntax_regex.Matches(query))
|
foreach (Match match in query_syntax_regex.Matches(query))
|
||||||
{
|
{
|
||||||
string key = match.Groups["key"].Value.ToLowerInvariant();
|
string key = match.Groups["key"].Value.ToLowerInvariant();
|
||||||
|
Loading…
Reference in New Issue
Block a user