Delta-v/Content.Server/_DV/AccountLinking/LinkAccountManager.cs

121 lines
3.7 KiB
C#

using System.Threading;
using System.Threading.Tasks;
using Content.Server.Database;
using Content.Shared._DV.AccountLinking;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Timing;
namespace Content.Server._DV.AccountLinking;
public sealed class LinkAccountManager : IPostInjectInit
{
[Dependency] private readonly IServerDbManager _db = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly UserDbDataManager _userDb = default!;
private readonly Dictionary<NetUserId, TimeSpan> _lastRequest = new();
private readonly TimeSpan _minimumWait = TimeSpan.FromSeconds(0.5);
private readonly Dictionary<NetUserId, SharedPatronFull> _connected = new();
private readonly List<SharedPatron> _allPatrons = [];
private async Task LoadData(ICommonSession player, CancellationToken cancel)
{
var patron = await _db.GetPatron(player.UserId, cancel);
var linked = await _db.HasLinkedAccount(player.UserId, cancel);
cancel.ThrowIfCancellationRequested();
var tier = patron?.Tier;
var sharedTier = tier == null
? null
: new SharedPatronTier(
tier.ShowOnCredits,
tier.Name
);
_connected[player.UserId] = new SharedPatronFull(sharedTier, linked);
}
private void FinishLoad(ICommonSession player)
{
SendPatronStatus(player);
}
private void ClientDisconnected(ICommonSession player)
{
_connected.Remove(player.UserId);
}
private void SendPatronStatus(ICommonSession player)
{
var connected = _connected.GetValueOrDefault(player.UserId);
var msg = new LinkAccountStatusMsg { Patron = connected, };
_net.ServerSendMessage(msg, player.Channel);
SendPatrons(player);
}
private void OnRequest(LinkAccountRequestMsg message)
{
var user = message.MsgChannel.UserId;
var time = _timing.RealTime;
if (_lastRequest.TryGetValue(user, out var last) &&
last + _minimumWait > time)
{
return;
}
_lastRequest[user] = time;
var code = Guid.NewGuid();
_db.SetLinkingCode(user, code);
var response = new LinkAccountCodeMsg { Code = code };
_net.ServerSendMessage(response, message.MsgChannel);
}
public async Task RefreshAllPatrons()
{
var patrons = await _db.GetAllPatrons();
_allPatrons.Clear();
foreach (var patron in patrons)
{
_allPatrons.Add(new SharedPatron(patron.Player.LastSeenUserName, patron.Tier.Name));
}
}
public void SendPatronsToAll()
{
var msg = new PatronListMsg { Patrons = _allPatrons };
_net.ServerSendToAll(msg);
}
public void SendPatrons(ICommonSession player)
{
var msg = new PatronListMsg { Patrons = _allPatrons };
_net.ServerSendMessage(msg, player.Channel);
}
public SharedPatronFull? GetPatron(ICommonSession player)
{
return GetPatron(player.UserId);
}
public SharedPatronFull? GetPatron(NetUserId userId)
{
return _connected.GetValueOrDefault(userId);
}
void IPostInjectInit.PostInject()
{
_net.RegisterNetMessage<LinkAccountRequestMsg>(OnRequest);
_net.RegisterNetMessage<LinkAccountCodeMsg>();
_net.RegisterNetMessage<LinkAccountStatusMsg>();
_net.RegisterNetMessage<PatronListMsg>();
_userDb.AddOnLoadPlayer(LoadData);
_userDb.AddOnFinishLoad(FinishLoad);
_userDb.AddOnPlayerDisconnect(ClientDisconnected);
}
}