Restore logic
This commit is contained in:
@@ -1,17 +1,16 @@
|
||||
using System;
|
||||
using LightlessSync.API.Data;
|
||||
using LightlessSync.API.Data.Comparer;
|
||||
using LightlessSync.PlayerData.Pairs;
|
||||
using LightlessSync.Utils;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using LightlessSync.Services;
|
||||
using LightlessSync.WebAPI;
|
||||
using LightlessSync.WebAPI.Files;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using LightlessSync.API.Data;
|
||||
using LightlessSync.API.Data.Comparer;
|
||||
using LightlessSync.Services;
|
||||
using LightlessSync.Services.Mediator;
|
||||
using LightlessSync.Utils;
|
||||
using LightlessSync.WebAPI;
|
||||
using LightlessSync.WebAPI.Files;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace LightlessSync.PlayerData.Pairs;
|
||||
|
||||
@@ -28,9 +27,6 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase
|
||||
private readonly HashSet<UserData> _usersToPushDataTo = new(UserDataComparer.Instance);
|
||||
private readonly SemaphoreSlim _pushDataSemaphore = new(1, 1);
|
||||
private readonly CancellationTokenSource _runtimeCts = new();
|
||||
private readonly Dictionary<string, string> _lastPushedHashes = new(StringComparer.Ordinal);
|
||||
private readonly object _pushSync = new();
|
||||
|
||||
|
||||
public VisibleUserDataDistributor(ILogger<VisibleUserDataDistributor> logger, ApiController apiController, DalamudUtilService dalamudUtil,
|
||||
PairLedger pairLedger, LightlessMediator mediator, FileUploadManager fileTransferManager) : base(logger, mediator)
|
||||
@@ -56,7 +52,14 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase
|
||||
});
|
||||
|
||||
Mediator.Subscribe<ConnectedMessage>(this, (_) => PushToAllVisibleUsers());
|
||||
Mediator.Subscribe<DisconnectedMessage>(this, (_) => HandleDisconnected());
|
||||
Mediator.Subscribe<DisconnectedMessage>(this, (_) =>
|
||||
{
|
||||
_fileTransferManager.CancelUpload();
|
||||
_previouslyVisiblePlayers.Clear();
|
||||
_usersToPushDataTo.Clear();
|
||||
_uploadingCharacterData = null;
|
||||
_fileUploadTask = null;
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
@@ -72,18 +75,15 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase
|
||||
|
||||
private void PushToAllVisibleUsers(bool forced = false)
|
||||
{
|
||||
lock (_pushSync)
|
||||
foreach (var user in GetVisibleUsers())
|
||||
{
|
||||
foreach (var user in GetVisibleUsers())
|
||||
{
|
||||
_usersToPushDataTo.Add(user);
|
||||
}
|
||||
_usersToPushDataTo.Add(user);
|
||||
}
|
||||
|
||||
if (_usersToPushDataTo.Count > 0)
|
||||
{
|
||||
Logger.LogDebug("Pushing data {hash} for {count} visible players", _lastCreatedData?.DataHash.Value ?? "UNKNOWN", _usersToPushDataTo.Count);
|
||||
PushCharacterData_internalLocked(forced);
|
||||
}
|
||||
if (_usersToPushDataTo.Count > 0)
|
||||
{
|
||||
Logger.LogDebug("Pushing data {hash} for {count} visible players", _lastCreatedData?.DataHash.Value ?? "UNKNOWN", _usersToPushDataTo.Count);
|
||||
PushCharacterData(forced);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,9 +92,7 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase
|
||||
if (!_dalamudUtil.GetIsPlayerPresent() || !_apiController.IsConnected) return;
|
||||
|
||||
var allVisibleUsers = GetVisibleUsers();
|
||||
var newVisibleUsers = allVisibleUsers
|
||||
.Except(_previouslyVisiblePlayers, UserDataComparer.Instance)
|
||||
.ToList();
|
||||
var newVisibleUsers = allVisibleUsers.Except(_previouslyVisiblePlayers, UserDataComparer.Instance).ToList();
|
||||
_previouslyVisiblePlayers.Clear();
|
||||
_previouslyVisiblePlayers.AddRange(allVisibleUsers);
|
||||
if (newVisibleUsers.Count == 0) return;
|
||||
@@ -102,115 +100,48 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase
|
||||
Logger.LogDebug("Scheduling character data push of {data} to {users}",
|
||||
_lastCreatedData?.DataHash.Value ?? string.Empty,
|
||||
string.Join(", ", newVisibleUsers.Select(k => k.AliasOrUID)));
|
||||
lock (_pushSync)
|
||||
foreach (var user in newVisibleUsers)
|
||||
{
|
||||
foreach (var user in newVisibleUsers)
|
||||
{
|
||||
_usersToPushDataTo.Add(user);
|
||||
}
|
||||
PushCharacterData_internalLocked();
|
||||
_usersToPushDataTo.Add(user);
|
||||
}
|
||||
PushCharacterData();
|
||||
}
|
||||
|
||||
private void PushCharacterData(bool forced = false)
|
||||
{
|
||||
lock (_pushSync)
|
||||
{
|
||||
PushCharacterData_internalLocked(forced);
|
||||
}
|
||||
}
|
||||
|
||||
private void PushCharacterData_internalLocked(bool forced = false)
|
||||
{
|
||||
if (_lastCreatedData == null || _usersToPushDataTo.Count == 0) return;
|
||||
if (!_apiController.IsConnected || !_fileTransferManager.IsReady)
|
||||
{
|
||||
Logger.LogTrace("Skipping character push. Connected: {connected}, UploadManagerReady: {ready}",
|
||||
_apiController.IsConnected, _fileTransferManager.IsReady);
|
||||
return;
|
||||
}
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Task<CharacterData>? uploadTask;
|
||||
bool forcedPush;
|
||||
lock (_pushSync)
|
||||
{
|
||||
if (_lastCreatedData == null || _usersToPushDataTo.Count == 0) return;
|
||||
forcedPush = forced | (_uploadingCharacterData?.DataHash != _lastCreatedData.DataHash);
|
||||
forced |= _uploadingCharacterData?.DataHash != _lastCreatedData.DataHash;
|
||||
|
||||
if (_fileUploadTask == null || (_fileUploadTask?.IsCompleted ?? false) || forcedPush)
|
||||
{
|
||||
_uploadingCharacterData = _lastCreatedData.DeepClone();
|
||||
Logger.LogDebug("Starting UploadTask for {hash}, Reason: TaskIsNull: {task}, TaskIsCompleted: {taskCpl}, Forced: {frc}",
|
||||
_lastCreatedData.DataHash, _fileUploadTask == null, _fileUploadTask?.IsCompleted ?? false, forcedPush);
|
||||
_fileUploadTask = _fileTransferManager.UploadFiles(_uploadingCharacterData, [.. _usersToPushDataTo]);
|
||||
}
|
||||
if (_fileUploadTask == null || (_fileUploadTask?.IsCompleted ?? false) || forced)
|
||||
{
|
||||
_uploadingCharacterData = _lastCreatedData.DeepClone();
|
||||
Logger.LogDebug("Starting UploadTask for {hash}, Reason: TaskIsNull: {task}, TaskIsCompleted: {taskCpl}, Forced: {frc}",
|
||||
_lastCreatedData.DataHash, _fileUploadTask == null, _fileUploadTask?.IsCompleted ?? false, forced);
|
||||
_fileUploadTask = _fileTransferManager.UploadFiles(_uploadingCharacterData, [.. _usersToPushDataTo]);
|
||||
}
|
||||
|
||||
uploadTask = _fileUploadTask;
|
||||
}
|
||||
|
||||
var dataToSend = await uploadTask.ConfigureAwait(false);
|
||||
var dataHash = dataToSend.DataHash.Value;
|
||||
if (_fileUploadTask != null)
|
||||
{
|
||||
var dataToSend = await _fileUploadTask.ConfigureAwait(false);
|
||||
await _pushDataSemaphore.WaitAsync(_runtimeCts.Token).ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
List<UserData> recipients;
|
||||
bool shouldSkip = false;
|
||||
lock (_pushSync)
|
||||
{
|
||||
if (_usersToPushDataTo.Count == 0) return;
|
||||
recipients = forcedPush
|
||||
? _usersToPushDataTo.ToList()
|
||||
: _usersToPushDataTo
|
||||
.Where(user => !_lastPushedHashes.TryGetValue(user.UID, out var sentHash) || !string.Equals(sentHash, dataHash, StringComparison.Ordinal))
|
||||
.ToList();
|
||||
|
||||
if (recipients.Count == 0 && !forcedPush)
|
||||
{
|
||||
Logger.LogTrace("All recipients already have character data hash {hash}, skipping push.", dataHash);
|
||||
_usersToPushDataTo.Clear();
|
||||
shouldSkip = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldSkip)
|
||||
return;
|
||||
|
||||
Logger.LogDebug("Pushing {data} to {users}", dataHash, string.Join(", ", recipients.Select(k => k.AliasOrUID)));
|
||||
await _apiController.PushCharacterData(dataToSend, recipients).ConfigureAwait(false);
|
||||
|
||||
lock (_pushSync)
|
||||
{
|
||||
foreach (var user in recipients)
|
||||
{
|
||||
_lastPushedHashes[user.UID] = dataHash;
|
||||
_usersToPushDataTo.Remove(user);
|
||||
}
|
||||
|
||||
if (!forcedPush && _usersToPushDataTo.Count > 0)
|
||||
{
|
||||
foreach (var satisfied in _usersToPushDataTo
|
||||
.Where(user => _lastPushedHashes.TryGetValue(user.UID, out var sentHash) && string.Equals(sentHash, dataHash, StringComparison.Ordinal))
|
||||
.ToList())
|
||||
{
|
||||
_usersToPushDataTo.Remove(satisfied);
|
||||
}
|
||||
}
|
||||
|
||||
if (forcedPush)
|
||||
{
|
||||
_usersToPushDataTo.Clear();
|
||||
}
|
||||
}
|
||||
if (_usersToPushDataTo.Count == 0) return;
|
||||
Logger.LogDebug("Pushing {data} to {users}", dataToSend.DataHash, string.Join(", ", _usersToPushDataTo.Select(k => k.AliasOrUID)));
|
||||
await _apiController.PushCharacterData(dataToSend, [.. _usersToPushDataTo]).ConfigureAwait(false);
|
||||
_usersToPushDataTo.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_pushDataSemaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) when (_runtimeCts.IsCancellationRequested)
|
||||
{
|
||||
Logger.LogDebug("PushCharacterData cancelled");
|
||||
@@ -222,20 +153,6 @@ public class VisibleUserDataDistributor : DisposableMediatorSubscriberBase
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleDisconnected()
|
||||
{
|
||||
_fileTransferManager.CancelUpload();
|
||||
_previouslyVisiblePlayers.Clear();
|
||||
|
||||
lock (_pushSync)
|
||||
{
|
||||
_usersToPushDataTo.Clear();
|
||||
_lastPushedHashes.Clear();
|
||||
_uploadingCharacterData = null;
|
||||
_fileUploadTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<UserData> GetVisibleUsers()
|
||||
{
|
||||
return _pairLedger.GetVisiblePairs()
|
||||
|
||||
Reference in New Issue
Block a user