1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-23 17:33:09 +08:00

Fix multiplayer song select not correctly applying filter sometimes

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.
This commit is contained in:
Bartłomiej Dach 2024-10-25 15:51:26 +02:00
parent 36bcc5896c
commit b78e7d5d9a
No known key found for this signature in database

View File

@ -711,12 +711,6 @@ namespace osu.Game.Screens.Select
Carousel.AllowSelection = true;
if (pendingFilterApplication)
{
Carousel.Filter(FilterControl.CreateCriteria());
pendingFilterApplication = false;
}
BeatmapDetails.Refresh();
beginLooping();
@ -749,6 +743,17 @@ namespace osu.Game.Screens.Select
FilterControl.Activate();
}
protected override void Update()
{
base.Update();
if (Carousel.AllowSelection && pendingFilterApplication)
{
Carousel.Filter(FilterControl.CreateCriteria());
pendingFilterApplication = false;
}
}
public override void OnSuspending(ScreenTransitionEvent e)
{
// Handle the case where FinaliseSelection is never called (ie. when a screen is pushed externally).