- Move them to the correct class. They were exercising filter matching,
not parsing.
- Remove a bunch of unreadable tuple stuff that was mostly obfuscating
the readability without actually improving test coverage.
- Make tests fail everywhere rather than on CI only. They were failing
because they were written in a way that was implicitly dependent on
the local computer's timezone.
Other textual keyword filters also worked like that, wherein if you did
`artist=a artist=b` the second filter would overwrite the second, but in
those cases the query is against a single field, so attempting to put
multiple search criteria in conjunction on a single field is kind of
nonsensical, so it was sort of fine to do that.
Which is not the case for user tags, which are multi-valued.
Because of greedy matching, a filter of
tag="style/clean"! tag="song representation/simple"!
would not parse into 2 separate filters like
(tag, =, "style/clean"!)
(tag, =, "song representation/simple"!)
but rather a single one like
(tag, =, "style/clean"! tag="song representation/simple"!)
This sort of matches what web did in
https://github.com/ppy/osu-web/pull/12044, except web does some stuff
with quote escaping that I'd rather not, and also the search syntax
seems to slightly deviate because web seems to be using single quotes
and double quotes to open the value part of the filter. I'm not sure
what the difference is and I'd rather not go into all that right now.
As indicated in the inline comment this is very best effort, just to
make the HP bar not very obviously stuck in a very obviously incorrect
state after the replay is rewound from a failure. There's likely to be a
bunch of replay accuracy issues related to this, but I'm just making the
minimum effort to get this to work semi-acceptably for now.
This indicator allows the player to either rewind to an earlier part of
the replay, or to proceed to results. It also plays a shortened variant
of the failure animation SFX.
Before this commit, there was `AllowFailAnimation` (used by multiplayer)
and `OnFail()` (used by score submitting implementations of player to
ensure a failed play submits).
The former is replaced by `PerformFail()` which allows for arbitrary
operations on failure, which replay player shall leverage in subsequent
commits. The latter would ideally be replaced by nothing, but it's
placed in a very awkward place behind a schedule, so by force of
necessity to avoid code duplication it's replaced by
`ConcludeFailedScore()` which is overridden to submit the score in all
submitting players --- except for multiplayer, which is never supposed
to be calling it, so in that case it just throws an exception.