mirror of
https://github.com/ppy/osu.git
synced 2026-05-17 00:23:24 +08:00
156 lines
5.5 KiB
C#
156 lines
5.5 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.Linq;
|
|
using osu.Framework.Bindables;
|
|
using osu.Framework.Graphics;
|
|
using osu.Game.Configuration;
|
|
using osu.Game.Online.API.Requests;
|
|
using osu.Game.Online.API.Requests.Responses;
|
|
using osu.Game.Users;
|
|
|
|
namespace osu.Game.Online.API
|
|
{
|
|
public partial class LocalUserState : Component, ILocalUserState
|
|
{
|
|
public IBindable<APIUser> User => localUser;
|
|
public IBindableList<APIRelation> Friends => friends;
|
|
public IBindableList<APIRelation> Blocks => blocks;
|
|
public IBindableList<int> FavouriteBeatmapSets => favouriteBeatmapSets;
|
|
|
|
private readonly IAPIProvider api;
|
|
|
|
private readonly Bindable<APIUser> localUser = new Bindable<APIUser>(createGuestUser());
|
|
private readonly BindableList<APIRelation> friends = new BindableList<APIRelation>();
|
|
private readonly BindableList<APIRelation> blocks = new BindableList<APIRelation>();
|
|
private readonly BindableList<int> favouriteBeatmapSets = new BindableList<int>();
|
|
|
|
private readonly Bindable<UserStatus> configStatus = new Bindable<UserStatus>();
|
|
private readonly Bindable<bool> configSupporter = new Bindable<bool>();
|
|
|
|
public LocalUserState(IAPIProvider api, OsuConfigManager config)
|
|
{
|
|
this.api = api;
|
|
|
|
config.BindWith(OsuSetting.UserOnlineStatus, configStatus);
|
|
config.BindWith(OsuSetting.WasSupporter, configSupporter);
|
|
}
|
|
|
|
#region Logging in / out
|
|
|
|
private static APIUser createGuestUser() => new GuestUser();
|
|
|
|
/// <summary>
|
|
/// Show a placeholder user if saved credentials are available.
|
|
/// This is useful for storing local scores and showing a placeholder username after starting the game,
|
|
/// until a valid connection has been established.
|
|
/// </summary>
|
|
public void SetPlaceholderLocalUser(string username)
|
|
{
|
|
if (!localUser.IsDefault)
|
|
return;
|
|
|
|
localUser.Value = new APIUser
|
|
{
|
|
Username = username,
|
|
IsSupporter = configSupporter.Value,
|
|
};
|
|
}
|
|
|
|
public void SetLocalUser(APIMe me)
|
|
{
|
|
localUser.Value = me;
|
|
configSupporter.Value = me.IsSupporter;
|
|
|
|
// `last_visit` is assumed to be `null` if and only if the web-side "hide online presence toggle" is enabled
|
|
if (me.LastVisit == null)
|
|
configStatus.Value = UserStatus.Offline;
|
|
|
|
UpdateFriends();
|
|
UpdateBlocks();
|
|
UpdateFavouriteBeatmapSets();
|
|
}
|
|
|
|
public void ClearLocalUser()
|
|
{
|
|
// Reset the status to be broadcast on the next login, in case multiple players share the same system.
|
|
configStatus.Value = UserStatus.Online;
|
|
|
|
// Scheduled prior to state change such that the state changed event is invoked with the correct user and their friends present
|
|
Schedule(() =>
|
|
{
|
|
localUser.Value = createGuestUser();
|
|
configSupporter.Value = false;
|
|
friends.Clear();
|
|
blocks.Clear();
|
|
favouriteBeatmapSets.Clear();
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void UpdateFriends()
|
|
{
|
|
if (!api.IsLoggedIn)
|
|
return;
|
|
|
|
var friendsReq = new GetFriendsRequest();
|
|
friendsReq.Success += res =>
|
|
{
|
|
var existingFriends = friends.Select(f => f.TargetID).ToHashSet();
|
|
var updatedFriends = res.Select(f => f.TargetID).ToHashSet();
|
|
|
|
// Add new friends into local list.
|
|
friends.AddRange(res.Where(r => !existingFriends.Contains(r.TargetID)));
|
|
|
|
// Remove non-friends from local list.
|
|
friends.RemoveAll(f => !updatedFriends.Contains(f.TargetID));
|
|
};
|
|
|
|
api.Queue(friendsReq);
|
|
}
|
|
|
|
public void UpdateBlocks()
|
|
{
|
|
if (!api.IsLoggedIn)
|
|
return;
|
|
|
|
var blocksReq = new GetBlocksRequest();
|
|
blocksReq.Success += res =>
|
|
{
|
|
var existingBlocks = blocks.Select(f => f.TargetID).ToHashSet();
|
|
var updatedBlocks = res.Select(f => f.TargetID).ToHashSet();
|
|
|
|
// Add new blocked users to local list.
|
|
blocks.AddRange(res.Where(r => !existingBlocks.Contains(r.TargetID)));
|
|
|
|
// Remove non-blocked users from local list.
|
|
blocks.RemoveAll(b => !updatedBlocks.Contains(b.TargetID));
|
|
|
|
// Remove friends who got blocked since last check.
|
|
friends.RemoveAll(f => updatedBlocks.Contains(f.TargetID));
|
|
};
|
|
|
|
api.Queue(blocksReq);
|
|
}
|
|
|
|
public void UpdateFavouriteBeatmapSets()
|
|
{
|
|
if (!api.IsLoggedIn)
|
|
return;
|
|
|
|
var favouritesReq = new GetMyFavouriteBeatmapSetsRequest();
|
|
favouritesReq.Success += res =>
|
|
{
|
|
var existingBeatmapSets = favouriteBeatmapSets.ToHashSet();
|
|
var updatedBeatmapSets = res.BeatmapSetIds.ToHashSet();
|
|
|
|
favouriteBeatmapSets.AddRange(updatedBeatmapSets.Except(existingBeatmapSets));
|
|
favouriteBeatmapSets.RemoveAll(b => !updatedBeatmapSets.Contains(b));
|
|
};
|
|
|
|
api.Queue(favouritesReq);
|
|
}
|
|
}
|
|
}
|