mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 16:12:57 +08:00
Merge pull request #11738 from peppy/fix-multiplayer-mod-propagation-race
Make server authoritative in which mods the client should be using when gameplay starts
This commit is contained in:
commit
d757dfa05c
@ -78,7 +78,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
managerUpdated = beatmapManager.ItemUpdated.GetBoundCopy();
|
||||
managerUpdated.BindValueChanged(beatmapUpdated);
|
||||
|
||||
UserMods.BindValueChanged(_ => updateMods());
|
||||
UserMods.BindValueChanged(_ => Scheduler.AddOnce(UpdateMods));
|
||||
}
|
||||
|
||||
public override void OnEntering(IScreen last)
|
||||
@ -97,7 +97,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
{
|
||||
base.OnResuming(last);
|
||||
beginHandlingTrack();
|
||||
updateMods();
|
||||
Scheduler.AddOnce(UpdateMods);
|
||||
}
|
||||
|
||||
public override bool OnExiting(IScreen next)
|
||||
@ -128,7 +128,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
.Where(m => SelectedItem.Value.AllowedMods.Any(a => m.GetType() == a.GetType()))
|
||||
.ToList();
|
||||
|
||||
updateMods();
|
||||
UpdateMods();
|
||||
|
||||
Ruleset.Value = SelectedItem.Value.Ruleset.Value;
|
||||
}
|
||||
@ -145,7 +145,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
|
||||
Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap);
|
||||
}
|
||||
|
||||
private void updateMods()
|
||||
protected virtual void UpdateMods()
|
||||
{
|
||||
if (SelectedItem.Value == null)
|
||||
return;
|
||||
|
@ -274,6 +274,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
UserMods.BindValueChanged(onUserModsChanged);
|
||||
|
||||
client.LoadRequested += onLoadRequested;
|
||||
client.RoomUpdated += onRoomUpdated;
|
||||
|
||||
isConnected = client.IsConnected.GetBoundCopy();
|
||||
isConnected.BindValueChanged(connected =>
|
||||
@ -283,6 +284,17 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
}, true);
|
||||
}
|
||||
|
||||
protected override void UpdateMods()
|
||||
{
|
||||
if (SelectedItem.Value == null || client.LocalUser == null)
|
||||
return;
|
||||
|
||||
// update local mods based on room's reported status for the local user (omitting the base call implementation).
|
||||
// this makes the server authoritative, and avoids the local user potentially setting mods that the server is not aware of (ie. if the match was started during the selection being changed).
|
||||
var ruleset = Ruleset.Value.CreateInstance();
|
||||
Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList();
|
||||
}
|
||||
|
||||
public override bool OnBackButton()
|
||||
{
|
||||
if (client.Room != null && settingsOverlay.State.Value == Visibility.Visible)
|
||||
@ -391,6 +403,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
}
|
||||
}
|
||||
|
||||
private void onRoomUpdated()
|
||||
{
|
||||
// user mods may have changed.
|
||||
Scheduler.AddOnce(UpdateMods);
|
||||
}
|
||||
|
||||
private void onLoadRequested()
|
||||
{
|
||||
Debug.Assert(client.Room != null);
|
||||
@ -408,7 +426,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (client != null)
|
||||
{
|
||||
client.RoomUpdated -= onRoomUpdated;
|
||||
client.LoadRequested -= onLoadRequested;
|
||||
}
|
||||
|
||||
modSettingChangeTracker?.Dispose();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user