1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 09:07:52 +08:00

Add client/server models & operations for "daily challenge" feature

This commit is contained in:
Bartłomiej Dach 2024-05-17 10:32:39 +02:00
parent badda23dde
commit 61a415fed2
No known key found for this signature in database
7 changed files with 60 additions and 1 deletions

View File

@ -0,0 +1,16 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. 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 struct DailyChallengeInfo
{
[Key(0)]
public long RoomID { get; set; }
}
}

View File

@ -20,5 +20,11 @@ namespace osu.Game.Online.Metadata
/// Delivers an update of the <see cref="UserPresence"/> of the user with the supplied <paramref name="userId"/>. /// Delivers an update of the <see cref="UserPresence"/> of the user with the supplied <paramref name="userId"/>.
/// </summary> /// </summary>
Task UserPresenceUpdated(int userId, UserPresence? status); Task UserPresenceUpdated(int userId, UserPresence? status);
/// <summary>
/// Delivers an update of the current "daily challenge" status.
/// Null value means there is no "daily challenge" currently active.
/// </summary>
Task DailyChallengeUpdated(DailyChallengeInfo? info);
} }
} }

View File

@ -7,7 +7,12 @@ using osu.Game.Users;
namespace osu.Game.Online.Metadata namespace osu.Game.Online.Metadata
{ {
/// <summary> /// <summary>
/// Metadata server is responsible for keeping the osu! client up-to-date with any changes. /// Metadata server is responsible for keeping the osu! client up-to-date with various real-time happenings, such as:
/// <list type="bullet">
/// <item>beatmap updates via BSS,</item>
/// <item>online user activity/status updates,</item>
/// <item>other real-time happenings, such as current "daily challenge" status.</item>
/// </list>
/// </summary> /// </summary>
public interface IMetadataServer public interface IMetadataServer
{ {

View File

@ -59,6 +59,15 @@ namespace osu.Game.Online.Metadata
#endregion #endregion
#region Daily Challenge
public abstract IBindable<DailyChallengeInfo?> DailyChallengeInfo { get; }
/// <inheritdoc/>
public abstract Task DailyChallengeUpdated(DailyChallengeInfo? info);
#endregion
#region Disconnection handling #region Disconnection handling
public event Action? Disconnecting; public event Action? Disconnecting;

View File

@ -26,6 +26,9 @@ namespace osu.Game.Online.Metadata
public override IBindableDictionary<int, UserPresence> UserStates => userStates; public override IBindableDictionary<int, UserPresence> UserStates => userStates;
private readonly BindableDictionary<int, UserPresence> userStates = new BindableDictionary<int, UserPresence>(); private readonly BindableDictionary<int, UserPresence> userStates = new BindableDictionary<int, UserPresence>();
public override IBindable<DailyChallengeInfo?> DailyChallengeInfo => dailyChallengeInfo;
private readonly Bindable<DailyChallengeInfo?> dailyChallengeInfo = new Bindable<DailyChallengeInfo?>();
private readonly string endpoint; private readonly string endpoint;
private IHubClientConnector? connector; private IHubClientConnector? connector;
@ -58,6 +61,7 @@ namespace osu.Game.Online.Metadata
// https://github.com/dotnet/aspnetcore/issues/15198 // https://github.com/dotnet/aspnetcore/issues/15198
connection.On<BeatmapUpdates>(nameof(IMetadataClient.BeatmapSetsUpdated), ((IMetadataClient)this).BeatmapSetsUpdated); connection.On<BeatmapUpdates>(nameof(IMetadataClient.BeatmapSetsUpdated), ((IMetadataClient)this).BeatmapSetsUpdated);
connection.On<int, UserPresence?>(nameof(IMetadataClient.UserPresenceUpdated), ((IMetadataClient)this).UserPresenceUpdated); connection.On<int, UserPresence?>(nameof(IMetadataClient.UserPresenceUpdated), ((IMetadataClient)this).UserPresenceUpdated);
connection.On<DailyChallengeInfo?>(nameof(IMetadataClient.DailyChallengeUpdated), ((IMetadataClient)this).DailyChallengeUpdated);
connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMetadataClient)this).DisconnectRequested); connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMetadataClient)this).DisconnectRequested);
}; };
@ -101,6 +105,7 @@ namespace osu.Game.Online.Metadata
{ {
isWatchingUserPresence.Value = false; isWatchingUserPresence.Value = false;
userStates.Clear(); userStates.Clear();
dailyChallengeInfo.Value = null;
}); });
return; return;
} }
@ -229,6 +234,12 @@ namespace osu.Game.Online.Metadata
} }
} }
public override Task DailyChallengeUpdated(DailyChallengeInfo? info)
{
Schedule(() => dailyChallengeInfo.Value = info);
return Task.CompletedTask;
}
public override async Task DisconnectRequested() public override async Task DisconnectRequested()
{ {
await base.DisconnectRequested().ConfigureAwait(false); await base.DisconnectRequested().ConfigureAwait(false);

View File

@ -13,5 +13,8 @@ namespace osu.Game.Online.Rooms
[Description("Featured Artist")] [Description("Featured Artist")]
FeaturedArtist, FeaturedArtist,
[Description("Daily Challenge")]
DailyChallenge,
} }
} }

View File

@ -21,6 +21,9 @@ namespace osu.Game.Tests.Visual.Metadata
public override IBindableDictionary<int, UserPresence> UserStates => userStates; public override IBindableDictionary<int, UserPresence> UserStates => userStates;
private readonly BindableDictionary<int, UserPresence> userStates = new BindableDictionary<int, UserPresence>(); private readonly BindableDictionary<int, UserPresence> userStates = new BindableDictionary<int, UserPresence>();
public override IBindable<DailyChallengeInfo?> DailyChallengeInfo => dailyChallengeInfo;
private readonly Bindable<DailyChallengeInfo?> dailyChallengeInfo = new Bindable<DailyChallengeInfo?>();
[Resolved] [Resolved]
private IAPIProvider api { get; set; } = null!; private IAPIProvider api { get; set; } = null!;
@ -77,5 +80,11 @@ namespace osu.Game.Tests.Visual.Metadata
=> Task.FromResult(new BeatmapUpdates(Array.Empty<int>(), queueId)); => Task.FromResult(new BeatmapUpdates(Array.Empty<int>(), queueId));
public override Task BeatmapSetsUpdated(BeatmapUpdates updates) => Task.CompletedTask; public override Task BeatmapSetsUpdated(BeatmapUpdates updates) => Task.CompletedTask;
public override Task DailyChallengeUpdated(DailyChallengeInfo? info)
{
dailyChallengeInfo.Value = info;
return Task.CompletedTask;
}
} }
} }