Skip to content

Commit

Permalink
Merge pull request #28636 from bdach/daily-challenge/watch-room
Browse files Browse the repository at this point in the history
Add client/server models for allowing clients to receive realtime playlist updates
  • Loading branch information
peppy authored Jun 28, 2024
2 parents 007bd39 + d6e7781 commit 4bb8a45
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 1 deletion.
6 changes: 6 additions & 0 deletions osu.Game/Online/Metadata/IMetadataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,11 @@ public interface IMetadataClient : IStatefulUserHubClient
/// Null value means there is no "daily challenge" currently active.
/// </summary>
Task DailyChallengeUpdated(DailyChallengeInfo? info);

/// <summary>
/// Delivers information that a multiplayer score was set in a watched room.
/// To receive these, the client must call <see cref="IMetadataServer.BeginWatchingMultiplayerRoom"/> for a given room first.
/// </summary>
Task MultiplayerRoomScoreSet(MultiplayerRoomScoreSetEvent roomScoreSetEvent);
}
}
10 changes: 10 additions & 0 deletions osu.Game/Online/Metadata/IMetadataServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,15 @@ public interface IMetadataServer
/// Signals to the server that the current user would like to stop receiving updates on other users' online presence.
/// </summary>
Task EndWatchingUserPresence();

/// <summary>
/// Signals to the server that the current user would like to begin receiving updates about the state of the multiplayer room with the given <paramref name="id"/>.
/// </summary>
Task<MultiplayerPlaylistItemStats[]> BeginWatchingMultiplayerRoom(long id);

/// <summary>
/// Signals to the server that the current user would like to stop receiving updates about the state of the multiplayer room with the given <paramref name="id"/>.
/// </summary>
Task EndWatchingMultiplayerRoom(long id);
}
}
18 changes: 18 additions & 0 deletions osu.Game/Online/Metadata/MetadataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ protected Task ProcessChanges(int[] beatmapSetIDs)

#endregion

#region Multiplayer room watching

public abstract Task<MultiplayerPlaylistItemStats[]> BeginWatchingMultiplayerRoom(long id);

public abstract Task EndWatchingMultiplayerRoom(long id);

public event Action<MultiplayerRoomScoreSetEvent>? MultiplayerRoomScoreSet;

Task IMetadataClient.MultiplayerRoomScoreSet(MultiplayerRoomScoreSetEvent roomScoreSetEvent)
{
if (MultiplayerRoomScoreSet != null)
Schedule(MultiplayerRoomScoreSet, roomScoreSetEvent);

return Task.CompletedTask;
}

#endregion

#region Disconnection handling

public event Action? Disconnecting;
Expand Down
29 changes: 29 additions & 0 deletions osu.Game/Online/Metadata/MultiplayerPlaylistItemStats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using MessagePack;

namespace osu.Game.Online.Metadata
{
[MessagePackObject]
[Serializable]
public class MultiplayerPlaylistItemStats
{
public const int TOTAL_SCORE_DISTRIBUTION_BINS = 13;

/// <summary>
/// The ID of the playlist item which these stats pertain to.
/// </summary>
[Key(0)]
public long PlaylistItemID { get; set; }

/// <summary>
/// The count of scores with given total ranges in the room.
/// The ranges are bracketed into <see cref="TOTAL_SCORE_DISTRIBUTION_BINS"/> bins, each of 100,000 score width.
/// The last bin will contain count of all scores with total of 1,200,000 or larger.
/// </summary>
[Key(1)]
public long[] TotalScoreDistribution { get; set; } = new long[TOTAL_SCORE_DISTRIBUTION_BINS];
}
}
50 changes: 50 additions & 0 deletions osu.Game/Online/Metadata/MultiplayerRoomScoreSetEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System;
using MessagePack;

namespace osu.Game.Online.Metadata
{
[Serializable]
[MessagePackObject]
public class MultiplayerRoomScoreSetEvent
{
/// <summary>
/// The ID of the room in which the score was set.
/// </summary>
[Key(0)]
public long RoomID { get; set; }

/// <summary>
/// The ID of the playlist item on which the score was set.
/// </summary>
[Key(1)]
public long PlaylistItemID { get; set; }

/// <summary>
/// The ID of the score set.
/// </summary>
[Key(2)]
public long ScoreID { get; set; }

/// <summary>
/// The ID of the user who set the score.
/// </summary>
[Key(3)]
public int UserID { get; set; }

/// <summary>
/// The total score set by the player.
/// </summary>
[Key(4)]
public long TotalScore { get; set; }

/// <summary>
/// If the set score is the user's new best on a playlist item, this member will contain the user's new rank in the room overall.
/// Otherwise, it will contain <see langword="null"/>.
/// </summary>
[Key(5)]
public int? NewRank { get; set; }
}
}
19 changes: 19 additions & 0 deletions osu.Game/Online/Metadata/OnlineMetadataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ private void load(IAPIProvider api, OsuConfigManager config)
connection.On<BeatmapUpdates>(nameof(IMetadataClient.BeatmapSetsUpdated), ((IMetadataClient)this).BeatmapSetsUpdated);
connection.On<int, UserPresence?>(nameof(IMetadataClient.UserPresenceUpdated), ((IMetadataClient)this).UserPresenceUpdated);
connection.On<DailyChallengeInfo?>(nameof(IMetadataClient.DailyChallengeUpdated), ((IMetadataClient)this).DailyChallengeUpdated);
connection.On<MultiplayerRoomScoreSetEvent>(nameof(IMetadataClient.MultiplayerRoomScoreSet), ((IMetadataClient)this).MultiplayerRoomScoreSet);
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMetadataClient)this).DisconnectRequested);
};

Expand Down Expand Up @@ -240,6 +241,24 @@ public override Task DailyChallengeUpdated(DailyChallengeInfo? info)
return Task.CompletedTask;
}

public override async Task<MultiplayerPlaylistItemStats[]> BeginWatchingMultiplayerRoom(long id)
{
if (connector?.IsConnected.Value != true)
throw new OperationCanceledException();

Debug.Assert(connection != null);
return await connection.InvokeAsync<MultiplayerPlaylistItemStats[]>(nameof(IMetadataServer.BeginWatchingMultiplayerRoom), id).ConfigureAwait(false);
}

public override async Task EndWatchingMultiplayerRoom(long id)
{
if (connector?.IsConnected.Value != true)
throw new OperationCanceledException();

Debug.Assert(connection != null);
await connection.InvokeAsync(nameof(IMetadataServer.EndWatchingMultiplayerRoom)).ConfigureAwait(false);
}

public override async Task DisconnectRequested()
{
await base.DisconnectRequested().ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.Metadata;
using osu.Game.Overlays;
using osu.Game.Scoring;
using osuTK;
Expand All @@ -21,7 +22,7 @@ public partial class DailyChallengeScoreBreakdown : CompositeDrawable
{
private FillFlowContainer<Bar> barsContainer = null!;

private const int bin_count = 13;
private const int bin_count = MultiplayerPlaylistItemStats.TOTAL_SCORE_DISTRIBUTION_BINS;
private long[] bins = new long[bin_count];

[BackgroundDependencyLoader]
Expand Down
5 changes: 5 additions & 0 deletions osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,10 @@ public override Task DailyChallengeUpdated(DailyChallengeInfo? info)
dailyChallengeInfo.Value = info;
return Task.CompletedTask;
}

public override Task<MultiplayerPlaylistItemStats[]> BeginWatchingMultiplayerRoom(long id)
=> Task.FromResult(new MultiplayerPlaylistItemStats[MultiplayerPlaylistItemStats.TOTAL_SCORE_DISTRIBUTION_BINS]);

public override Task EndWatchingMultiplayerRoom(long id) => Task.CompletedTask;
}
}

0 comments on commit 4bb8a45

Please sign in to comment.