mirror of
https://github.com/ppy/osu.git
synced 2025-01-19 17:03:02 +08:00
4a628287e2
This also throws away the logic of updating `API.LocalUser.Value.Statistics`. Components should rely on `LocalUserStatisticsProvider` instead for proper behaviour and ability to update on statistics updates.
99 lines
3.4 KiB
C#
99 lines
3.4 KiB
C#
// 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.Collections.Generic;
|
|
using osu.Framework.Allocation;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Extensions.ObjectExtensions;
|
|
using osu.Framework.Graphics;
|
|
using osu.Game.Extensions;
|
|
using osu.Game.Online.API;
|
|
using osu.Game.Online.Spectator;
|
|
using osu.Game.Scoring;
|
|
|
|
namespace osu.Game.Online
|
|
{
|
|
/// <summary>
|
|
/// A persistent component that binds to the spectator server and API in order to deliver updates about the logged in user's gameplay statistics.
|
|
/// </summary>
|
|
public partial class UserStatisticsWatcher : Component
|
|
{
|
|
private readonly LocalUserStatisticsProvider statisticsProvider;
|
|
|
|
public IBindable<ScoreBasedUserStatisticsUpdate?> LatestUpdate => latestUpdate;
|
|
private readonly Bindable<ScoreBasedUserStatisticsUpdate?> latestUpdate = new Bindable<ScoreBasedUserStatisticsUpdate?>();
|
|
|
|
private ScoreInfo? scorePendingUpdate;
|
|
|
|
[Resolved]
|
|
private SpectatorClient spectatorClient { get; set; } = null!;
|
|
|
|
[Resolved]
|
|
private IAPIProvider api { get; set; } = null!;
|
|
|
|
private readonly Dictionary<long, ScoreInfo> watchedScores = new Dictionary<long, ScoreInfo>();
|
|
|
|
public UserStatisticsWatcher(LocalUserStatisticsProvider statisticsProvider)
|
|
{
|
|
this.statisticsProvider = statisticsProvider;
|
|
}
|
|
|
|
protected override void LoadComplete()
|
|
{
|
|
base.LoadComplete();
|
|
|
|
spectatorClient.OnUserScoreProcessed += userScoreProcessed;
|
|
statisticsProvider.StatisticsUpdate.ValueChanged += onStatisticsUpdated;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registers for a user statistics update after the given <paramref name="score"/> has been processed server-side.
|
|
/// </summary>
|
|
/// <param name="score">The score to listen for the statistics update for.</param>
|
|
public void RegisterForStatisticsUpdateAfter(ScoreInfo score)
|
|
{
|
|
Schedule(() =>
|
|
{
|
|
if (!api.IsLoggedIn)
|
|
return;
|
|
|
|
if (!score.Ruleset.IsLegacyRuleset() || score.OnlineID <= 0)
|
|
return;
|
|
|
|
watchedScores.Add(score.OnlineID, score);
|
|
});
|
|
}
|
|
|
|
private void userScoreProcessed(int userId, long scoreId)
|
|
{
|
|
if (userId != api.LocalUser.Value?.OnlineID)
|
|
return;
|
|
|
|
if (!watchedScores.Remove(scoreId, out var scoreInfo))
|
|
return;
|
|
|
|
scorePendingUpdate = scoreInfo;
|
|
statisticsProvider.RefetchStatistics(scoreInfo.Ruleset);
|
|
}
|
|
|
|
private void onStatisticsUpdated(ValueChangedEvent<UserStatisticsUpdate> update) => Schedule(() =>
|
|
{
|
|
if (scorePendingUpdate == null || !update.NewValue.Ruleset.Equals(scorePendingUpdate.Ruleset))
|
|
return;
|
|
|
|
if (update.NewValue.OldStatistics != null)
|
|
latestUpdate.Value = new ScoreBasedUserStatisticsUpdate(scorePendingUpdate, update.NewValue.OldStatistics, update.NewValue.NewStatistics);
|
|
|
|
scorePendingUpdate = null;
|
|
});
|
|
|
|
protected override void Dispose(bool isDisposing)
|
|
{
|
|
if (spectatorClient.IsNotNull())
|
|
spectatorClient.OnUserScoreProcessed -= userScoreProcessed;
|
|
|
|
base.Dispose(isDisposing);
|
|
}
|
|
}
|
|
}
|