1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-21 07:09:53 +08:00

Fix selection being changed on re-entering song select when a converted beatmap is selected

Closes https://github.com/ppy/osu/issues/34062.

The root cause of the issue is that `OnEntering()` calls
`onArrivingAtScreen()`, which calls `ensureGlobalBeatmapValid()`, which
would call `checkBeatmapValidForSelection()` with a `FilterCriteria`
instance retrieved from the `FilterControl`.

The problem with that is at the time that this call chain is happening,
`FilterControl` is not yet loaded, which means in particular that it has
not bound itself to the config bindable, as that happens on
`LoadComplete()`:

	https://github.com/ppy/osu/blob/bff07010d1f9874125baf2918f02c5cf61a5ea60/osu.Game/Screens/SelectV2/FilterControl.cs#L198

To resolve this, retrieve the bindable in `SongSelect` itself, which
ensures it is valid for reading at the time the above call chain
happens.
This commit is contained in:
Bartłomiej Dach
2025-10-02 13:27:43 +02:00
Unverified
parent e7076b9582
commit 3d5dc60cfe
+10 -11
View File
@@ -155,6 +155,7 @@ namespace osu.Game.Screens.SelectV2
private readonly RealmPopulatingOnlineLookupSource onlineLookupSource = new RealmPopulatingOnlineLookupSource();
private Bindable<bool> configBackgroundBlur = null!;
private Bindable<bool> showConvertedBeatmaps = null!;
[BackgroundDependencyLoader]
private void load(AudioManager audio, OsuConfigManager config)
@@ -302,6 +303,8 @@ namespace osu.Game.Screens.SelectV2
updateBackgroundDim();
});
showConvertedBeatmaps = config.GetBindable<bool>(OsuSetting.ShowConvertedBeatmaps);
}
private void requestRecommendedSelection(IEnumerable<GroupedBeatmap> groupedBeatmaps)
@@ -522,7 +525,7 @@ namespace osu.Game.Screens.SelectV2
if (!this.IsCurrentScreen())
return;
if (!checkBeatmapValidForSelection(beatmap, carousel.Criteria))
if (!checkBeatmapValidForSelection(beatmap))
return;
// To ensure sanity, cancel any pending selection as we are about to force a selection.
@@ -573,7 +576,7 @@ namespace osu.Game.Screens.SelectV2
// Refetch to be confident that the current selection is still valid. It may have been deleted or hidden.
var currentBeatmap = beatmaps.GetWorkingBeatmap(Beatmap.Value.BeatmapInfo, true);
bool validSelection = checkBeatmapValidForSelection(currentBeatmap.BeatmapInfo, filterControl.CreateCriteria());
bool validSelection = checkBeatmapValidForSelection(currentBeatmap.BeatmapInfo);
if (validSelection)
{
@@ -594,9 +597,8 @@ namespace osu.Game.Screens.SelectV2
{
// In the case a difficulty was hidden or removed, prefer selecting another difficulty from the same set.
var activeSet = currentBeatmap.BeatmapSetInfo;
var criteria = filterControl.CreateCriteria();
var validBeatmaps = activeSet.Beatmaps.Where(b => checkBeatmapValidForSelection(b, criteria)).ToArray();
var validBeatmaps = activeSet.Beatmaps.Where(checkBeatmapValidForSelection).ToArray();
if (validBeatmaps.Any())
{
@@ -614,12 +616,9 @@ namespace osu.Game.Screens.SelectV2
return validSelection;
}
private bool checkBeatmapValidForSelection(BeatmapInfo beatmap, FilterCriteria? criteria)
private bool checkBeatmapValidForSelection(BeatmapInfo beatmap)
{
if (criteria == null)
return false;
if (!beatmap.AllowGameplayWithRuleset(Ruleset.Value, criteria.AllowConvertedBeatmaps))
if (!beatmap.AllowGameplayWithRuleset(Ruleset.Value, showConvertedBeatmaps.Value))
return false;
if (beatmap.Hidden)
@@ -777,7 +776,7 @@ namespace osu.Game.Screens.SelectV2
// This avoids a flicker of a placeholder or invalid beatmap before a proper selection.
//
// After the carousel finishes filtering, it will attempt a selection then call this method again.
if (!CarouselItemsPresented && !checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo, filterControl.CreateCriteria()))
if (!CarouselItemsPresented && !checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo))
return;
if (carousel.VisuallyFocusSelected)
@@ -834,7 +833,7 @@ namespace osu.Game.Screens.SelectV2
bool isFirstFilter = filterDebounce == null;
// Criteria change may have included a ruleset change which made the current selection invalid.
bool isSelectionValid = checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo, criteria);
bool isSelectionValid = checkBeatmapValidForSelection(Beatmap.Value.BeatmapInfo);
filterDebounce = Scheduler.AddDelayed(() => carousel.Filter(criteria, !isSelectionValid), isFirstFilter || !isSelectionValid ? 0 : filter_delay);
}