Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use room watching functionality to receive realtime daily challenge updates #28659

Merged
merged 2 commits into from
Jul 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Screens.OnlinePlay.DailyChallenge;
using osu.Game.Tests.Resources;
using osu.Game.Screens.OnlinePlay.DailyChallenge.Events;

namespace osu.Game.Tests.Visual.DailyChallenge
{
Expand Down Expand Up @@ -129,19 +130,27 @@ public void TestIntegration()
});
AddStep("add normal score", () =>
{
var testScore = TestResources.CreateTestScoreInfo();
testScore.TotalScore = RNG.Next(1_000_000);
var ev = new NewScoreEvent(1, new APIUser
{
Id = 2,
Username = "peppy",
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}, RNG.Next(1_000_000), null);

feed.AddNewScore(new DailyChallengeEventFeed.NewScoreEvent(testScore, null));
breakdown.AddNewScore(testScore);
feed.AddNewScore(ev);
breakdown.AddNewScore(ev);
});
AddStep("add new user best", () =>
{
var testScore = TestResources.CreateTestScoreInfo();
testScore.TotalScore = RNG.Next(1_000_000);
var ev = new NewScoreEvent(1, new APIUser
{
Id = 2,
Username = "peppy",
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}, RNG.Next(1_000_000), RNG.Next(1, 1000));

feed.AddNewScore(new DailyChallengeEventFeed.NewScoreEvent(testScore, RNG.Next(1, 1000)));
breakdown.AddNewScore(testScore);
feed.AddNewScore(ev);
breakdown.AddNewScore(ev);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Screens.OnlinePlay.DailyChallenge;
using osu.Game.Screens.OnlinePlay.DailyChallenge.Events;
using osu.Game.Tests.Resources;

namespace osu.Game.Tests.Visual.DailyChallenge
Expand Down Expand Up @@ -50,26 +52,41 @@ public void TestBasicAppearance()

AddStep("add normal score", () =>
{
var testScore = TestResources.CreateTestScoreInfo();
testScore.TotalScore = RNG.Next(1_000_000);
var ev = new NewScoreEvent(1, new APIUser
{
Id = 2,
Username = "peppy",
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}, RNG.Next(1_000_000), null);

feed.AddNewScore(new DailyChallengeEventFeed.NewScoreEvent(testScore, null));
feed.AddNewScore(ev);
});

AddStep("add new user best", () =>
{
var ev = new NewScoreEvent(1, new APIUser
{
Id = 2,
Username = "peppy",
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}, RNG.Next(1_000_000), RNG.Next(11, 1000));

var testScore = TestResources.CreateTestScoreInfo();
testScore.TotalScore = RNG.Next(1_000_000);

feed.AddNewScore(new DailyChallengeEventFeed.NewScoreEvent(testScore, RNG.Next(1, 1000)));
feed.AddNewScore(ev);
});

AddStep("add top 10 score", () =>
{
var testScore = TestResources.CreateTestScoreInfo();
testScore.TotalScore = RNG.Next(1_000_000);
var ev = new NewScoreEvent(1, new APIUser
{
Id = 2,
Username = "peppy",
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}, RNG.Next(1_000_000), RNG.Next(1, 10));

feed.AddNewScore(new DailyChallengeEventFeed.NewScoreEvent(testScore, RNG.Next(1, 10)));
feed.AddNewScore(ev);
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
using osu.Game.Screens.OnlinePlay.DailyChallenge;
using osu.Game.Tests.Resources;
using osu.Game.Screens.OnlinePlay.DailyChallenge.Events;

namespace osu.Game.Tests.Visual.DailyChallenge
{
Expand Down Expand Up @@ -51,10 +52,14 @@ public void TestBasicAppearance()
AddStep("set initial data", () => breakdown.SetInitialCounts([1, 4, 9, 16, 25, 36, 49, 36, 25, 16, 9, 4, 1]));
AddStep("add new score", () =>
{
var testScore = TestResources.CreateTestScoreInfo();
testScore.TotalScore = RNG.Next(1_000_000);
var ev = new NewScoreEvent(1, new APIUser
{
Id = 2,
Username = "peppy",
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}, RNG.Next(1_000_000), null);

breakdown.AddNewScore(testScore);
breakdown.AddNewScore(ev);
});
}
}
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Online/Metadata/OnlineMetadataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public override async Task EndWatchingMultiplayerRoom(long id)
throw new OperationCanceledException();

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

public override async Task DisconnectRequested()
Expand Down
100 changes: 99 additions & 1 deletion osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,29 @@
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Logging;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Localisation;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Metadata;
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.OnlinePlay.Components;
using osu.Game.Screens.OnlinePlay.DailyChallenge.Events;
using osu.Game.Screens.OnlinePlay.Match;
using osu.Game.Screens.OnlinePlay.Match.Components;
using osu.Game.Screens.OnlinePlay.Playlists;
Expand All @@ -47,6 +55,9 @@ public partial class DailyChallenge : OsuScreen
private Sample? sampleStart;
private IDisposable? userModsSelectOverlayRegistration;

private DailyChallengeScoreBreakdown breakdown = null!;
private DailyChallengeEventFeed feed = null!;

[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Plum);

Expand All @@ -68,6 +79,12 @@ public partial class DailyChallenge : OsuScreen
[Resolved]
private IOverlayManager? overlayManager { get; set; }

[Resolved]
private MetadataClient metadataClient { get; set; } = null!;

[Resolved]
private UserLookupCache userLookupCache { get; set; } = null!;

public override bool DisallowExternalBeatmapRulesetChanges => true;

public DailyChallenge(Room room)
Expand Down Expand Up @@ -162,9 +179,39 @@ private void load(AudioManager audio)
{
new Drawable?[]
{
new DailyChallengeTimeRemainingRing
new GridContainer
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RowDimensions =
[
new Dimension(),
new Dimension()
],
Content = new[]
{
new Drawable[]
{
new DailyChallengeCarousel
{
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Children = new Drawable[]
{
new DailyChallengeTimeRemainingRing(),
breakdown = new DailyChallengeScoreBreakdown(),
}
}
},
[
feed = new DailyChallengeEventFeed
{
RelativeSizeAxes = Axes.Both,
}
],
},
},
null,
// Middle column (leaderboard)
Expand Down Expand Up @@ -275,6 +322,33 @@ [new MatchChatDisplay(room) { RelativeSizeAxes = Axes.Both }]
var allowedMods = playlistItem.AllowedMods.Select(m => m.ToMod(rulesetInstance));
userModsSelectOverlay.IsValidMod = m => allowedMods.Any(a => a.GetType() == m.GetType());
}

metadataClient.MultiplayerRoomScoreSet += onRoomScoreSet;
}

private void onRoomScoreSet(MultiplayerRoomScoreSetEvent e)
{
if (e.RoomID != room.RoomID.Value || e.PlaylistItemID != playlistItem.ID)
return;

userLookupCache.GetUserAsync(e.UserID).ContinueWith(t =>
{
if (t.Exception != null)
{
Logger.Log($@"Could not display room score set event: {t.Exception}", LoggingTarget.Network);
return;
}

APIUser? user = t.GetResultSafely();
if (user == null) return;

var ev = new NewScoreEvent(e.ScoreID, user, e.TotalScore, e.NewRank);
Schedule(() =>
{
breakdown.AddNewScore(ev);
feed.AddNewScore(ev);
});
});
}

protected override void LoadComplete()
Expand All @@ -294,6 +368,7 @@ private void trySetDailyChallengeBeatmap()
var beatmap = beatmapManager.QueryBeatmap(b => b.OnlineID == playlistItem.Beatmap.OnlineID);
Beatmap.Value = beatmapManager.GetWorkingBeatmap(beatmap); // this will gracefully fall back to dummy beatmap if missing locally.
Ruleset.Value = rulesets.GetRuleset(playlistItem.RulesetID);
applyLoopingToTrack();
}

public override void OnEntering(ScreenTransitionEvent e)
Expand All @@ -303,6 +378,25 @@ public override void OnEntering(ScreenTransitionEvent e)
waves.Show();
roomManager.JoinRoom(room);
applyLoopingToTrack();

metadataClient.BeginWatchingMultiplayerRoom(room.RoomID.Value!.Value).ContinueWith(t =>
{
if (t.Exception != null)
{
Logger.Error(t.Exception, @"Failed to subscribe to room updates", LoggingTarget.Network);
return;
}

MultiplayerPlaylistItemStats[] stats = t.GetResultSafely();
var itemStats = stats.SingleOrDefault(item => item.PlaylistItemID == playlistItem.ID);
if (itemStats == null) return;

Schedule(() => breakdown.SetInitialCounts(itemStats.TotalScoreDistribution));
});

beatmapAvailabilityTracker.SelectedItem.Value = playlistItem;
beatmapAvailabilityTracker.Availability.BindValueChanged(_ => trySetDailyChallengeBeatmap(), true);
userModsSelectOverlay.SelectedItem.Value = playlistItem;
}

public override void OnResuming(ScreenTransitionEvent e)
Expand All @@ -327,6 +421,7 @@ public override bool OnExiting(ScreenExitEvent e)
this.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut();

roomManager.PartRoom();
metadataClient.EndWatchingMultiplayerRoom(room.RoomID.Value!.Value).FireAndForget();

return base.OnExiting(e);
}
Expand Down Expand Up @@ -375,6 +470,9 @@ protected override void Dispose(bool isDisposing)
base.Dispose(isDisposing);

userModsSelectOverlayRegistration?.Dispose();

if (metadataClient.IsNotNull())
metadataClient.MultiplayerRoomScoreSet -= onRoomScoreSet;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Scoring;
using osu.Game.Screens.OnlinePlay.DailyChallenge.Events;
using osu.Game.Users.Drawables;
using osuTK;

Expand Down Expand Up @@ -70,8 +69,6 @@ protected override void Update()
}
}

public record NewScoreEvent(IScoreInfo Score, int? NewRank);

private partial class DailyChallengeEventFeedFlow : FillFlowContainer
{
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.Reverse();
Expand All @@ -98,8 +95,7 @@ private void load(OsuColour colours)

InternalChildren = new Drawable[]
{
// TODO: cast is temporary, will be removed later
new ClickableAvatar((APIUser)newScore.Score.User)
new ClickableAvatar(newScore.User)
{
Size = new Vector2(16),
Masking = true,
Expand All @@ -117,9 +113,9 @@ private void load(OsuColour colours)
}
};

text.AddUserLink(newScore.Score.User);
text.AddUserLink(newScore.User);
text.AddText(" got ");
text.AddLink($"{newScore.Score.TotalScore:N0} points", () => { }); // TODO: present the score here
text.AddLink($"{newScore.TotalScore:N0} points", () => { }); // TODO: present the score here

if (newScore.NewRank != null)
text.AddText($" and achieved rank #{newScore.NewRank.Value:N0}");
Expand Down
Loading
Loading