After dd06dd0e699311494412e36bc3f37bb055a01477 the behaviour set up on
the mock in the test in question is no longer realistic. Online
metadata lookups will no longer fall back to online ID or filename.
Both online and offline using the cache.
The rationale behind this change is that in the current state of
affairs, `TestPartiallyMaliciousSet()` fails in a way that cannot be
reconciled without this sort of change.
The test exercises a scenario where the beatmap being imported has an
online ID in the `.osu` file, but its hash does not match the online
hash of the beatmap. This turns out to be a more frequent scenario than
envisioned because of users doing stupid things with manual file editing
rather than reporting issues properly.
The scenario is realistic only because the behaviour of the endpoint
responsible for looking up beatmaps is such that if multiple parameters
are given (e.g. all three of beatmap MD5, online ID, and filename), it
will try the three in succession:
f6b341813b/app/Http/Controllers/BeatmapsController.php (L260-L266)
and the local metadata cache implementation reflected this
implementation.
Because online ID and filename are inherently unreliable in this
scenario due to being directly manipulable by clueless or malicious
users, neither should not be used as a fallback.
Fixes the root client-side failure causing
https://github.com/ppy/osu/issues/30415.
Thread of breakage is as follows:
1. `SongSelect` loads the carousel.
At this point, the ruleset is what the ambient ruleset would have
been at the time of pushing song select, so most likely it will
match the current ruleset.
Notably, the carousel is loaded with `AllowSelection == false`.
2. `OnlinePlaySongSelect` sets the ruleset to the one taken from
the relevant playlist item in `LoadComplete()`.
3. At any point between the previous and the next step, the user
changes the ruleset manually.
4. `SongSelect.carouselBeatmapsLoaded()` is ran, which calls
`transferRulesetValue()`, which calls `FilterControl.FilterChanged`.
But at this stage `Carousel.AllowSelection` is still false, so
the filter is not executed, but `pendingFilterApplication` is set
instead.
Unfortunately, the pending filter never gets applied after that.
The only place that checks that flag is `OnEntering()`, which at
this point has already ran.
To fix, move the `pendingFilterApplication` check to `Update()`, which
seems like the most obvious and safe solution.
I don't know why this was ever a good idea, and would say that we want
this to fail *hard* not soft. If things ever get in this state, things
have gone *seriously* wrong elsewhere, and need to be fixed there.
More specifically, this fixes placement blueprints not beginning placement when using touch input while the cursor was previously outside compose area, due to the placement blueprint not existing (removed from the scene by `ComposeBlueprintContainer`).