1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-03 13:04:19 +08:00

Add support for vote-to-skip in multiplayer

This commit is contained in:
Dan Balasescu
2025-10-30 19:56:12 +09:00
Unverified
parent a435dfe93e
commit 373162df02
5 changed files with 63 additions and 8 deletions
@@ -131,6 +131,9 @@ namespace osu.Game.Online.Multiplayer
public event Action<int, long>? MatchmakingItemDeselected;
public event Action<MatchRoomState>? MatchRoomStateChanged;
public event Action<int>? UserVotedToSkip;
public event Action? VoteToSkipPassed;
/// <summary>
/// Whether the <see cref="MultiplayerClient"/> is currently connected.
/// This is NOT thread safe and usage should be scheduled.
@@ -521,6 +524,12 @@ namespace osu.Game.Online.Multiplayer
break;
}
if (state == MultiplayerRoomState.Playing)
{
foreach (var user in Room.Users)
user.VotedToSkip = false;
}
RoomUpdated?.Invoke();
});
@@ -920,12 +929,33 @@ namespace osu.Game.Online.Multiplayer
Task IMultiplayerClient.UserVotedToSkip(int userId)
{
throw new NotImplementedException();
handleRoomRequest(() =>
{
Debug.Assert(Room != null);
var user = Room.Users.SingleOrDefault(u => u.UserID == userId);
// TODO: user should NEVER be null here, see https://github.com/ppy/osu/issues/17713.
if (user == null)
return;
user.VotedToSkip = true;
UserVotedToSkip?.Invoke(userId);
});
return Task.CompletedTask;
}
Task IMultiplayerClient.VoteToSkipPassed()
{
throw new NotImplementedException();
handleRoomRequest(() =>
{
Debug.Assert(Room != null);
VoteToSkipPassed?.Invoke();
});
return Task.CompletedTask;
}
/// <summary>
@@ -70,7 +70,8 @@ namespace osu.Game.Online.Multiplayer
connection.On<MultiplayerPlaylistItem>(nameof(IMultiplayerClient.PlaylistItemAdded), ((IMultiplayerClient)this).PlaylistItemAdded);
connection.On<long>(nameof(IMultiplayerClient.PlaylistItemRemoved), ((IMultiplayerClient)this).PlaylistItemRemoved);
connection.On<MultiplayerPlaylistItem>(nameof(IMultiplayerClient.PlaylistItemChanged), ((IMultiplayerClient)this).PlaylistItemChanged);
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMultiplayerClient)this).DisconnectRequested);
connection.On<int>(nameof(IMultiplayerClient.UserVotedToSkip), ((IMultiplayerClient)this).UserVotedToSkip);
connection.On(nameof(IMultiplayerClient.VoteToSkipPassed), ((IMultiplayerClient)this).VoteToSkipPassed);
connection.On(nameof(IMatchmakingClient.MatchmakingQueueJoined), ((IMatchmakingClient)this).MatchmakingQueueJoined);
connection.On(nameof(IMatchmakingClient.MatchmakingQueueLeft), ((IMatchmakingClient)this).MatchmakingQueueLeft);
@@ -80,6 +81,8 @@ namespace osu.Game.Online.Multiplayer
connection.On<MatchmakingQueueStatus>(nameof(IMatchmakingClient.MatchmakingQueueStatusChanged), ((IMatchmakingClient)this).MatchmakingQueueStatusChanged);
connection.On<int, long>(nameof(IMatchmakingClient.MatchmakingItemSelected), ((IMatchmakingClient)this).MatchmakingItemSelected);
connection.On<int, long>(nameof(IMatchmakingClient.MatchmakingItemDeselected), ((IMatchmakingClient)this).MatchmakingItemDeselected);
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMultiplayerClient)this).DisconnectRequested);
};
IsConnected.BindTo(connector.IsConnected);
@@ -314,7 +317,12 @@ namespace osu.Game.Online.Multiplayer
public override Task VoteToSkip()
{
throw new NotImplementedException();
if (!IsConnected.Value)
return Task.CompletedTask;
Debug.Assert(connection != null);
return connection.InvokeAsync(nameof(IMultiplayerServer.VoteToSkip));
}
public override Task DisconnectInternal()
@@ -56,7 +56,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{
AllowPause = false,
AllowRestart = false,
AllowSkipping = room.AutoSkip,
AutomaticallySkipIntro = room.AutoSkip,
ShowLeaderboard = true,
})
@@ -121,6 +120,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
client.GameplayStarted += onGameplayStarted;
client.ResultsReady += onResultsReady;
client.VoteToSkipPassed += onVoteToSkipPassed;
ScoreProcessor.HasCompleted.BindValueChanged(_ =>
{
@@ -219,6 +219,17 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
await Task.WhenAny(resultsReady.Task, Task.Delay(TimeSpan.FromSeconds(60))).ConfigureAwait(false);
}
protected override void RequestIntroSkip()
{
// No base call because we aren't skipping yet.
client.VoteToSkip();
}
private void onVoteToSkipPassed()
{
Schedule(PerformIntroSkip);
}
protected override ResultsScreen CreateResults(ScoreInfo score)
{
Debug.Assert(Room.RoomID != null);
@@ -242,6 +253,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
{
client.GameplayStarted -= onGameplayStarted;
client.ResultsReady -= onResultsReady;
client.VoteToSkipPassed -= onVoteToSkipPassed;
}
}
}
+7 -2
View File
@@ -502,7 +502,7 @@ namespace osu.Game.Screens.Play
DrawableRuleset.Cursor?.CreateProxy() ?? new Container(),
skipIntroOverlay = new SkipOverlay(DrawableRuleset.GameplayStartTime)
{
RequestSkip = performUserRequestedSkip
RequestSkip = RequestIntroSkip
},
skipOutroOverlay = new SkipOverlay(GameplayState.Storyboard.LatestEventTime ?? 0)
{
@@ -701,7 +701,12 @@ namespace osu.Game.Screens.Play
return true;
}
private void performUserRequestedSkip()
protected virtual void RequestIntroSkip()
{
PerformIntroSkip();
}
protected void PerformIntroSkip()
{
// user requested skip
// disable sample playback to stop currently playing samples and perform skip
@@ -563,7 +563,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
public override Task VoteToSkip()
{
throw new NotImplementedException();
return Task.CompletedTask;
}
protected override Task<MultiplayerRoom> CreateRoomInternal(MultiplayerRoom room)