push character data through the server without using the database
This commit is contained in:
@@ -78,7 +78,7 @@ namespace MareSynchronos.Factories
|
|||||||
var cache = new CharacterData
|
var cache = new CharacterData
|
||||||
{
|
{
|
||||||
JobId = _dalamudUtil.PlayerJobId,
|
JobId = _dalamudUtil.PlayerJobId,
|
||||||
GlamourerString = _ipcManager.GlamourerGetCharacterCustomization(_dalamudUtil.PlayerName),
|
GlamourerString = _ipcManager.GlamourerGetCharacterCustomization(_dalamudUtil.PlayerCharacter),
|
||||||
ManipulationString = _ipcManager.PenumbraGetMetaManipulations(_dalamudUtil.PlayerName)
|
ManipulationString = _ipcManager.PenumbraGetMetaManipulations(_dalamudUtil.PlayerName)
|
||||||
};
|
};
|
||||||
var model = (CharacterBase*)((Character*)_dalamudUtil.PlayerPointer)->GameObject.GetDrawObject();
|
var model = (CharacterBase*)((Character*)_dalamudUtil.PlayerPointer)->GameObject.GetDrawObject();
|
||||||
|
|||||||
@@ -60,6 +60,26 @@ public class CachedPlayer
|
|||||||
|
|
||||||
private CharacterEquipment? _currentCharacterEquipment;
|
private CharacterEquipment? _currentCharacterEquipment;
|
||||||
|
|
||||||
|
public void ApplyCharacterData(CharacterCacheDto characterData)
|
||||||
|
{
|
||||||
|
Logger.Debug("Received data for " + this);
|
||||||
|
|
||||||
|
Logger.Debug("Checking for files to download for player " + PlayerName);
|
||||||
|
Logger.Debug("Hash for data is " + characterData.Hash);
|
||||||
|
if (!_cache.ContainsKey(characterData.Hash))
|
||||||
|
{
|
||||||
|
Logger.Debug("Received total " + characterData.FileReplacements.Count + " file replacement data");
|
||||||
|
_cache[characterData.Hash] = characterData;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Debug("Had valid local cache for " + PlayerName);
|
||||||
|
}
|
||||||
|
_lastAppliedEquipmentHash = characterData.Hash;
|
||||||
|
|
||||||
|
DownloadAndApplyCharacter();
|
||||||
|
}
|
||||||
|
|
||||||
private void ApiControllerOnCharacterReceived(object? sender, CharacterReceivedEventArgs e)
|
private void ApiControllerOnCharacterReceived(object? sender, CharacterReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(PlayerName) || e.CharacterNameHash != PlayerNameHash) return;
|
if (string.IsNullOrEmpty(PlayerName) || e.CharacterNameHash != PlayerNameHash) return;
|
||||||
@@ -147,7 +167,7 @@ public class CachedPlayer
|
|||||||
Logger.Debug(
|
Logger.Debug(
|
||||||
$"Request Redraw for {PlayerName}");
|
$"Request Redraw for {PlayerName}");
|
||||||
_ipcManager.PenumbraSetTemporaryMods(tempCollection, moddedPaths, cache.ManipulationData);
|
_ipcManager.PenumbraSetTemporaryMods(tempCollection, moddedPaths, cache.ManipulationData);
|
||||||
_ipcManager.GlamourerApplyAll(cache.GlamourerData, PlayerName!);
|
_ipcManager.GlamourerApplyAll(cache.GlamourerData, PlayerCharacter!);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisposePlayer()
|
public void DisposePlayer()
|
||||||
@@ -166,8 +186,8 @@ public class CachedPlayer
|
|||||||
_ipcManager.PenumbraRemoveTemporaryCollection(PlayerName);
|
_ipcManager.PenumbraRemoveTemporaryCollection(PlayerName);
|
||||||
if (PlayerCharacter != null)
|
if (PlayerCharacter != null)
|
||||||
{
|
{
|
||||||
_ipcManager.GlamourerApplyOnlyCustomization(_originalGlamourerData, PlayerName);
|
_ipcManager.GlamourerApplyOnlyCustomization(_originalGlamourerData, PlayerCharacter);
|
||||||
_ipcManager.GlamourerApplyOnlyEquipment(_lastGlamourerData, PlayerName);
|
_ipcManager.GlamourerApplyOnlyEquipment(_lastGlamourerData, PlayerCharacter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -182,7 +202,7 @@ public class CachedPlayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InitializePlayer(PlayerCharacter character)
|
public void InitializePlayer(PlayerCharacter character, CharacterCacheDto? cache)
|
||||||
{
|
{
|
||||||
IsVisible = true;
|
IsVisible = true;
|
||||||
PlayerName = character.Name.ToString();
|
PlayerName = character.Name.ToString();
|
||||||
@@ -190,10 +210,12 @@ public class CachedPlayer
|
|||||||
Logger.Debug("Initializing Player " + this);
|
Logger.Debug("Initializing Player " + this);
|
||||||
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
||||||
_ipcManager.PenumbraRedrawEvent += IpcManagerOnPenumbraRedrawEvent;
|
_ipcManager.PenumbraRedrawEvent += IpcManagerOnPenumbraRedrawEvent;
|
||||||
_apiController.CharacterReceived += ApiControllerOnCharacterReceived;
|
_originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter);
|
||||||
_originalGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerName);
|
|
||||||
_currentCharacterEquipment = new CharacterEquipment(PlayerCharacter);
|
_currentCharacterEquipment = new CharacterEquipment(PlayerCharacter);
|
||||||
_lastPlayerObjectCheck = DateTime.Now;
|
if (cache != null)
|
||||||
|
{
|
||||||
|
ApplyCharacterData(cache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DalamudUtilOnFrameworkUpdate()
|
private void DalamudUtilOnFrameworkUpdate()
|
||||||
@@ -250,11 +272,10 @@ public class CachedPlayer
|
|||||||
private void OnPlayerChanged()
|
private void OnPlayerChanged()
|
||||||
{
|
{
|
||||||
Logger.Debug($"Player {PlayerName} changed, PenumbraRedraw is {RequestedPenumbraRedraw}");
|
Logger.Debug($"Player {PlayerName} changed, PenumbraRedraw is {RequestedPenumbraRedraw}");
|
||||||
PlayerCharacter = _dalamudUtil.GetPlayerCharacterFromObjectTableByName(PlayerName!);
|
|
||||||
if (!RequestedPenumbraRedraw && PlayerCharacter is not null)
|
if (!RequestedPenumbraRedraw && PlayerCharacter is not null)
|
||||||
{
|
{
|
||||||
Logger.Debug($"Saving new Glamourer data");
|
Logger.Debug($"Saving new Glamourer data");
|
||||||
_lastGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerName!);
|
_lastGlamourerData = _ipcManager.GlamourerGetCharacterCustomization(PlayerCharacter!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ using Dalamud.Plugin.Ipc;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
|
|
||||||
namespace MareSynchronos.Managers
|
namespace MareSynchronos.Managers
|
||||||
@@ -11,11 +12,11 @@ namespace MareSynchronos.Managers
|
|||||||
public class IpcManager : IDisposable
|
public class IpcManager : IDisposable
|
||||||
{
|
{
|
||||||
private readonly ICallGateSubscriber<int> _glamourerApiVersion;
|
private readonly ICallGateSubscriber<int> _glamourerApiVersion;
|
||||||
private readonly ICallGateSubscriber<string, string, object>? _glamourerApplyAll;
|
private readonly ICallGateSubscriber<string, GameObject?, object>? _glamourerApplyAll;
|
||||||
private readonly ICallGateSubscriber<string, string>? _glamourerGetAllCustomization;
|
private readonly ICallGateSubscriber<GameObject?, string>? _glamourerGetAllCustomization;
|
||||||
private readonly ICallGateSubscriber<string, object> _glamourerRevertCustomization;
|
private readonly ICallGateSubscriber<GameObject?, object> _glamourerRevertCustomization;
|
||||||
private readonly ICallGateSubscriber<string, string, object>? _glamourerApplyOnlyEquipment;
|
private readonly ICallGateSubscriber<string, GameObject?, object>? _glamourerApplyOnlyEquipment;
|
||||||
private readonly ICallGateSubscriber<string, string, object>? _glamourerApplyOnlyCustomization;
|
private readonly ICallGateSubscriber<string, GameObject?, object>? _glamourerApplyOnlyCustomization;
|
||||||
private readonly ICallGateSubscriber<int> _penumbraApiVersion;
|
private readonly ICallGateSubscriber<int> _penumbraApiVersion;
|
||||||
private readonly ICallGateSubscriber<string, string, bool, (int, string)> _penumbraCreateTemporaryCollection;
|
private readonly ICallGateSubscriber<string, string, bool, (int, string)> _penumbraCreateTemporaryCollection;
|
||||||
private readonly ICallGateSubscriber<string, string> _penumbraGetMetaManipulations;
|
private readonly ICallGateSubscriber<string, string> _penumbraGetMetaManipulations;
|
||||||
@@ -45,11 +46,11 @@ namespace MareSynchronos.Managers
|
|||||||
pi.GetIpcSubscriber<string, string>("Penumbra.GetMetaManipulations");
|
pi.GetIpcSubscriber<string, string>("Penumbra.GetMetaManipulations");
|
||||||
|
|
||||||
_glamourerApiVersion = pi.GetIpcSubscriber<int>("Glamourer.ApiVersion");
|
_glamourerApiVersion = pi.GetIpcSubscriber<int>("Glamourer.ApiVersion");
|
||||||
_glamourerGetAllCustomization = pi.GetIpcSubscriber<string, string>("Glamourer.GetAllCustomization");
|
_glamourerGetAllCustomization = pi.GetIpcSubscriber<GameObject?, string>("Glamourer.GetAllCustomizationFromCharacter");
|
||||||
_glamourerApplyAll = pi.GetIpcSubscriber<string, string, object>("Glamourer.ApplyAll");
|
_glamourerApplyAll = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyAllToCharacter");
|
||||||
_glamourerApplyOnlyCustomization = pi.GetIpcSubscriber<string, string, object>("Glamourer.ApplyOnlyCustomization");
|
_glamourerApplyOnlyCustomization = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyCustomizationToCharacter");
|
||||||
_glamourerApplyOnlyEquipment = pi.GetIpcSubscriber<string, string, object>("Glamourer.ApplyOnlyEquipment");
|
_glamourerApplyOnlyEquipment = pi.GetIpcSubscriber<string, GameObject?, object>("Glamourer.ApplyOnlyEquipmentToCharacter");
|
||||||
_glamourerRevertCustomization = pi.GetIpcSubscriber<string, object>("Glamourer.Revert");
|
_glamourerRevertCustomization = pi.GetIpcSubscriber<GameObject?, object>("Glamourer.RevertCharacter");
|
||||||
|
|
||||||
_penumbraObjectIsRedrawn.Subscribe(RedrawEvent);
|
_penumbraObjectIsRedrawn.Subscribe(RedrawEvent);
|
||||||
_penumbraInit.Subscribe(PenumbraInit);
|
_penumbraInit.Subscribe(PenumbraInit);
|
||||||
@@ -110,37 +111,37 @@ namespace MareSynchronos.Managers
|
|||||||
Logger.Debug("IPC Manager disposed");
|
Logger.Debug("IPC Manager disposed");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlamourerApplyAll(string customization, string characterName)
|
public void GlamourerApplyAll(string customization, GameObject character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi()) return;
|
if (!CheckGlamourerApi()) return;
|
||||||
Logger.Debug("Glamourer apply all to " + characterName);
|
Logger.Debug("Glamourer apply all to " + character);
|
||||||
_glamourerApplyAll!.InvokeAction(customization, characterName);
|
_glamourerApplyAll!.InvokeAction(customization, character);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlamourerApplyOnlyEquipment(string customization, string characterName)
|
public void GlamourerApplyOnlyEquipment(string customization, GameObject character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
||||||
Logger.Debug("Glamourer apply only equipment to " + characterName);
|
Logger.Debug("Glamourer apply only equipment to " + character);
|
||||||
_glamourerApplyOnlyEquipment!.InvokeAction(customization, characterName);
|
_glamourerApplyOnlyEquipment!.InvokeAction(customization, character);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlamourerApplyOnlyCustomization(string customization, string characterName)
|
public void GlamourerApplyOnlyCustomization(string customization, GameObject character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
if (!CheckGlamourerApi() || string.IsNullOrEmpty(customization)) return;
|
||||||
Logger.Debug("Glamourer apply only customization to " + characterName);
|
Logger.Debug("Glamourer apply only customization to " + character);
|
||||||
_glamourerApplyOnlyCustomization!.InvokeAction(customization, characterName);
|
_glamourerApplyOnlyCustomization!.InvokeAction(customization, character);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GlamourerGetCharacterCustomization(string characterName)
|
public string GlamourerGetCharacterCustomization(GameObject character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi()) return string.Empty;
|
if (!CheckGlamourerApi()) return string.Empty;
|
||||||
return _glamourerGetAllCustomization!.InvokeFunc(characterName);
|
return _glamourerGetAllCustomization!.InvokeFunc(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GlamourerRevertCharacterCustomization(string characterName)
|
public void GlamourerRevertCharacterCustomization(GameObject character)
|
||||||
{
|
{
|
||||||
if (!CheckGlamourerApi()) return;
|
if (!CheckGlamourerApi()) return;
|
||||||
_glamourerRevertCustomization!.InvokeAction(characterName);
|
_glamourerRevertCustomization!.InvokeAction(character);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string PenumbraCreateTemporaryCollection(string characterName)
|
public string PenumbraCreateTemporaryCollection(string characterName)
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
|
using MareSynchronos.API;
|
||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
using MareSynchronos.WebAPI;
|
using MareSynchronos.WebAPI;
|
||||||
|
using MareSynchronos.WebAPI.Utils;
|
||||||
|
|
||||||
namespace MareSynchronos.Managers;
|
namespace MareSynchronos.Managers;
|
||||||
|
|
||||||
@@ -14,10 +16,15 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
private readonly Framework _framework;
|
private readonly Framework _framework;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
|
private readonly PlayerManager _playerManager;
|
||||||
private readonly List<CachedPlayer> _onlineCachedPlayers = new();
|
private readonly List<CachedPlayer> _onlineCachedPlayers = new();
|
||||||
|
private readonly Dictionary<string, CharacterCacheDto> _temporaryStoredCharacterCache = new();
|
||||||
|
|
||||||
|
private List<string> OnlineVisiblePlayerHashes => _onlineCachedPlayers.Where(p => p.PlayerCharacter != null)
|
||||||
|
.Select(p => p.PlayerNameHash).ToList();
|
||||||
private DateTime _lastPlayerObjectCheck = DateTime.Now;
|
private DateTime _lastPlayerObjectCheck = DateTime.Now;
|
||||||
|
|
||||||
public OnlinePlayerManager(Framework framework, ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager)
|
public OnlinePlayerManager(Framework framework, ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager, PlayerManager playerManager)
|
||||||
{
|
{
|
||||||
Logger.Debug("Creating " + nameof(OnlinePlayerManager));
|
Logger.Debug("Creating " + nameof(OnlinePlayerManager));
|
||||||
|
|
||||||
@@ -25,12 +32,15 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
_ipcManager = ipcManager;
|
_ipcManager = ipcManager;
|
||||||
|
_playerManager = playerManager;
|
||||||
|
|
||||||
_apiController.PairedClientOnline += ApiControllerOnPairedClientOnline;
|
_apiController.PairedClientOnline += ApiControllerOnPairedClientOnline;
|
||||||
_apiController.PairedClientOffline += ApiControllerOnPairedClientOffline;
|
_apiController.PairedClientOffline += ApiControllerOnPairedClientOffline;
|
||||||
_apiController.PairedWithOther += ApiControllerOnPairedWithOther;
|
_apiController.PairedWithOther += ApiControllerOnPairedWithOther;
|
||||||
_apiController.UnpairedFromOther += ApiControllerOnUnpairedFromOther;
|
_apiController.UnpairedFromOther += ApiControllerOnUnpairedFromOther;
|
||||||
|
_apiController.Connected += ApiControllerOnConnected;
|
||||||
_apiController.Disconnected += ApiControllerOnDisconnected;
|
_apiController.Disconnected += ApiControllerOnDisconnected;
|
||||||
|
_apiController.CharacterReceived += ApiControllerOnCharacterReceived;
|
||||||
|
|
||||||
_ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed;
|
_ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed;
|
||||||
|
|
||||||
@@ -43,6 +53,37 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ApiControllerOnCharacterReceived(object? sender, CharacterReceivedEventArgs e)
|
||||||
|
{
|
||||||
|
var visiblePlayer = _onlineCachedPlayers.SingleOrDefault(c => c.IsVisible && c.PlayerNameHash == e.CharacterNameHash);
|
||||||
|
if (visiblePlayer != null)
|
||||||
|
{
|
||||||
|
Logger.Debug("Received data and applying to " + e.CharacterNameHash);
|
||||||
|
visiblePlayer.ApplyCharacterData(e.CharacterData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Debug("Received data but no fitting character visible for " + e.CharacterNameHash);
|
||||||
|
_temporaryStoredCharacterCache[e.CharacterNameHash] = e.CharacterData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PlayerManagerOnPlayerHasChanged(CharacterCacheDto characterCache)
|
||||||
|
{
|
||||||
|
_ = _apiController.PushCharacterData(characterCache, OnlineVisiblePlayerHashes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApiControllerOnConnected(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var apiTask = _apiController.GetOnlineCharacters();
|
||||||
|
|
||||||
|
Task.WaitAll(apiTask);
|
||||||
|
|
||||||
|
AddInitialPairs(apiTask.Result);
|
||||||
|
|
||||||
|
_playerManager.PlayerHasChanged += PlayerManagerOnPlayerHasChanged;
|
||||||
|
}
|
||||||
|
|
||||||
private void DalamudUtilOnLogOut()
|
private void DalamudUtilOnLogOut()
|
||||||
{
|
{
|
||||||
_framework.Update -= FrameworkOnUpdate;
|
_framework.Update -= FrameworkOnUpdate;
|
||||||
@@ -61,6 +102,7 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
private void ApiControllerOnDisconnected(object? sender, EventArgs e)
|
private void ApiControllerOnDisconnected(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
RestoreAllCharacters();
|
RestoreAllCharacters();
|
||||||
|
_playerManager.PlayerHasChanged -= PlayerManagerOnPlayerHasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddInitialPairs(List<string> apiTaskResult)
|
public void AddInitialPairs(List<string> apiTaskResult)
|
||||||
@@ -163,12 +205,24 @@ public class OnlinePlayerManager : IDisposable
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
_onlineCachedPlayers.SingleOrDefault(p => p.PlayerNameHash == hashedName)?.InitializePlayer(pChar);
|
if (_temporaryStoredCharacterCache.TryGetValue(hashedName, out var cache))
|
||||||
|
{
|
||||||
|
_temporaryStoredCharacterCache.Remove(hashedName);
|
||||||
|
}
|
||||||
|
_onlineCachedPlayers.SingleOrDefault(p => p.PlayerNameHash == hashedName)?.InitializePlayer(pChar, cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.Run(async () => await UpdatePlayersFromService(_onlineCachedPlayers
|
var newlyVisiblePlayers = _onlineCachedPlayers
|
||||||
.Where(p => p.PlayerCharacter != null && p.IsVisible && !p.WasVisible)
|
.Where(p => p.PlayerCharacter != null && p.IsVisible && !p.WasVisible).Select(p => p.PlayerNameHash)
|
||||||
.ToDictionary(k => k.PlayerNameHash, k => (int)k.PlayerCharacter!.ClassJob.Id)));
|
.ToList();
|
||||||
|
if (newlyVisiblePlayers.Any() && _playerManager.LastSentCharacterData != null)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await _apiController.PushCharacterData(_playerManager.LastSentCharacterData.ToCharacterCacheDto(),
|
||||||
|
newlyVisiblePlayers);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_lastPlayerObjectCheck = DateTime.Now;
|
_lastPlayerObjectCheck = DateTime.Now;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,41 @@
|
|||||||
using Dalamud.Logging;
|
using MareSynchronos.Factories;
|
||||||
using MareSynchronos.Factories;
|
|
||||||
using MareSynchronos.Models;
|
using MareSynchronos.Models;
|
||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
using MareSynchronos.WebAPI;
|
using MareSynchronos.WebAPI;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using MareSynchronos.API;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace MareSynchronos.Managers
|
namespace MareSynchronos.Managers
|
||||||
{
|
{
|
||||||
|
public delegate void PlayerHasChanged(CharacterCacheDto characterCache);
|
||||||
|
|
||||||
public class PlayerManager : IDisposable
|
public class PlayerManager : IDisposable
|
||||||
{
|
{
|
||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
private readonly OnlinePlayerManager _onlinePlayerManager;
|
|
||||||
private readonly CharacterDataFactory _characterDataFactory;
|
private readonly CharacterDataFactory _characterDataFactory;
|
||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
private string _lastSentHash = string.Empty;
|
public event PlayerHasChanged? PlayerHasChanged;
|
||||||
|
public bool SendingData { get; private set; }
|
||||||
|
public CharacterData? LastSentCharacterData { get; private set; }
|
||||||
|
|
||||||
private CancellationTokenSource? _playerChangedCts;
|
private CancellationTokenSource? _playerChangedCts;
|
||||||
private DateTime _lastPlayerObjectCheck;
|
private DateTime _lastPlayerObjectCheck;
|
||||||
private CharacterEquipment _currentCharacterEquipment;
|
private CharacterEquipment? _currentCharacterEquipment;
|
||||||
|
|
||||||
public PlayerManager(ApiController apiController, IpcManager ipcManager,
|
public PlayerManager(ApiController apiController, IpcManager ipcManager,
|
||||||
CharacterDataFactory characterDataFactory, OnlinePlayerManager onlinePlayerManager, DalamudUtil dalamudUtil)
|
CharacterDataFactory characterDataFactory, DalamudUtil dalamudUtil)
|
||||||
{
|
{
|
||||||
Logger.Debug("Creating " + nameof(PlayerManager));
|
Logger.Debug("Creating " + nameof(PlayerManager));
|
||||||
|
|
||||||
_apiController = apiController;
|
_apiController = apiController;
|
||||||
_ipcManager = ipcManager;
|
_ipcManager = ipcManager;
|
||||||
_characterDataFactory = characterDataFactory;
|
_characterDataFactory = characterDataFactory;
|
||||||
_onlinePlayerManager = onlinePlayerManager;
|
|
||||||
_dalamudUtil = dalamudUtil;
|
_dalamudUtil = dalamudUtil;
|
||||||
|
|
||||||
_apiController.Connected += ApiController_Connected;
|
_apiController.Connected += ApiController_Connected;
|
||||||
@@ -75,12 +76,6 @@ namespace MareSynchronos.Managers
|
|||||||
private void ApiController_Connected(object? sender, EventArgs args)
|
private void ApiController_Connected(object? sender, EventArgs args)
|
||||||
{
|
{
|
||||||
Logger.Debug("ApiController Connected");
|
Logger.Debug("ApiController Connected");
|
||||||
var apiTask = _apiController.GetOnlineCharacters();
|
|
||||||
_lastSentHash = string.Empty;
|
|
||||||
|
|
||||||
Task.WaitAll(apiTask);
|
|
||||||
|
|
||||||
_onlinePlayerManager.AddInitialPairs(apiTask.Result);
|
|
||||||
|
|
||||||
_ipcManager.PenumbraRedrawEvent += IpcManager_PenumbraRedrawEvent;
|
_ipcManager.PenumbraRedrawEvent += IpcManager_PenumbraRedrawEvent;
|
||||||
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
_dalamudUtil.FrameworkUpdate += DalamudUtilOnFrameworkUpdate;
|
||||||
@@ -154,6 +149,7 @@ namespace MareSynchronos.Managers
|
|||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
|
SendingData = true;
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
while (!_apiController.IsConnected && attempts < 10 && !token.IsCancellationRequested)
|
while (!_apiController.IsConnected && attempts < 10 && !token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
@@ -167,11 +163,11 @@ namespace MareSynchronos.Managers
|
|||||||
Stopwatch st = Stopwatch.StartNew();
|
Stopwatch st = Stopwatch.StartNew();
|
||||||
_dalamudUtil.WaitWhileSelfIsDrawing(token);
|
_dalamudUtil.WaitWhileSelfIsDrawing(token);
|
||||||
|
|
||||||
var characterCacheTask = await CreateFullCharacterCache(token);
|
var characterCache = await CreateFullCharacterCache(token);
|
||||||
|
|
||||||
if (token.IsCancellationRequested) return;
|
if (token.IsCancellationRequested) return;
|
||||||
|
|
||||||
var cacheDto = characterCacheTask.ToCharacterCacheDto();
|
var cacheDto = characterCache.ToCharacterCacheDto();
|
||||||
st.Stop();
|
st.Stop();
|
||||||
|
|
||||||
if (token.IsCancellationRequested)
|
if (token.IsCancellationRequested)
|
||||||
@@ -180,13 +176,16 @@ namespace MareSynchronos.Managers
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger.Debug("Elapsed time PlayerChangedTask: " + st.Elapsed);
|
Logger.Debug("Elapsed time PlayerChangedTask: " + st.Elapsed);
|
||||||
if (cacheDto.Hash == _lastSentHash)
|
if (cacheDto.Hash == (LastSentCharacterData?.CacheHash ?? "-"))
|
||||||
{
|
{
|
||||||
Logger.Debug("Not sending data, already sent");
|
Logger.Debug("Not sending data, already sent");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ = _apiController.SendCharacterData(cacheDto, _dalamudUtil.GetLocalPlayers().Select(d => d.Key).ToList());
|
|
||||||
_lastSentHash = cacheDto.Hash;
|
LastSentCharacterData = characterCache;
|
||||||
|
PlayerHasChanged?.Invoke(cacheDto);
|
||||||
|
SendingData = false;
|
||||||
|
|
||||||
}, token);
|
}, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -168,10 +168,10 @@ namespace MareSynchronos
|
|||||||
{
|
{
|
||||||
var characterCacheFactory =
|
var characterCacheFactory =
|
||||||
new CharacterDataFactory(_dalamudUtil, _ipcManager);
|
new CharacterDataFactory(_dalamudUtil, _ipcManager);
|
||||||
_characterCacheManager = new OnlinePlayerManager(_framework,
|
|
||||||
_apiController, _dalamudUtil, _ipcManager);
|
|
||||||
_playerManager = new PlayerManager(_apiController, _ipcManager,
|
_playerManager = new PlayerManager(_apiController, _ipcManager,
|
||||||
characterCacheFactory, _characterCacheManager, _dalamudUtil);
|
characterCacheFactory, _dalamudUtil);
|
||||||
|
_characterCacheManager = new OnlinePlayerManager(_framework,
|
||||||
|
_apiController, _dalamudUtil, _ipcManager, _playerManager);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,23 +56,6 @@ namespace MareSynchronos.WebAPI
|
|||||||
foreach (var file in fileReplacementDto)
|
foreach (var file in fileReplacementDto)
|
||||||
{
|
{
|
||||||
downloadFiles.Add(await _fileHub!.InvokeAsync<DownloadFileDto>("GetFileSize", file.Hash, ct));
|
downloadFiles.Add(await _fileHub!.InvokeAsync<DownloadFileDto>("GetFileSize", file.Hash, ct));
|
||||||
/*var downloadFileDto = ;
|
|
||||||
var downloadFileTransfer = new DownloadFileTransfer(downloadFileDto);
|
|
||||||
if (CurrentDownloads.Any(f => f.Hash == downloadFileTransfer.Hash))
|
|
||||||
{
|
|
||||||
if (fileTransferList.All(f => f.Hash != downloadFileTransfer.Hash))
|
|
||||||
{
|
|
||||||
fileTransferList.Add(downloadFileTransfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileTransferList.All(f => f.Hash != downloadFileTransfer.Hash))
|
|
||||||
{
|
|
||||||
fileTransferList.Add(downloadFileTransfer);
|
|
||||||
}
|
|
||||||
CurrentDownloads.Add(new DownloadFileTransfer(downloadFileDto));*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadFiles = downloadFiles.Distinct().ToList();
|
downloadFiles = downloadFiles.Distinct().ToList();
|
||||||
@@ -140,7 +123,7 @@ namespace MareSynchronos.WebAPI
|
|||||||
CurrentDownloads.RemoveAll(d => d.Transferred == d.Total);
|
CurrentDownloads.RemoveAll(d => d.Transferred == d.Total);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SendCharacterData(CharacterCacheDto character, List<string> visibleCharacterIds)
|
public async Task PushCharacterData(CharacterCacheDto character, List<string> visibleCharacterIds)
|
||||||
{
|
{
|
||||||
if (!IsConnected || SecretKey == "-") return;
|
if (!IsConnected || SecretKey == "-") return;
|
||||||
Logger.Debug("Sending Character data to service " + ApiUri);
|
Logger.Debug("Sending Character data to service " + ApiUri);
|
||||||
@@ -155,10 +138,19 @@ namespace MareSynchronos.WebAPI
|
|||||||
foreach (var file in filesToUpload.Where(f => !f.IsForbidden))
|
foreach (var file in filesToUpload.Where(f => !f.IsForbidden))
|
||||||
{
|
{
|
||||||
await using var db = new FileCacheContext();
|
await using var db = new FileCacheContext();
|
||||||
CurrentUploads.Add(new UploadFileTransfer(file)
|
try
|
||||||
{
|
{
|
||||||
Total = new FileInfo(db.FileCaches.First(f => f.Hash == file.Hash).Filepath).Length
|
CurrentUploads.Add(new UploadFileTransfer(file)
|
||||||
});
|
{
|
||||||
|
Total = new FileInfo(db.FileCaches.FirstOrDefault(f => f.Hash.ToLower() == file.Hash.ToLower())
|
||||||
|
?.Filepath ?? string.Empty).Length
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Warn("Tried to request file " + file.Hash + " but file was not present");
|
||||||
|
Logger.Warn(ex.StackTrace!);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var file in CurrentUploads.Where(c => c.IsForbidden))
|
foreach (var file in CurrentUploads.Where(c => c.IsForbidden))
|
||||||
@@ -197,7 +189,7 @@ namespace MareSynchronos.WebAPI
|
|||||||
if (!uploadToken.IsCancellationRequested)
|
if (!uploadToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
Logger.Verbose("=== Pushing character data ===");
|
Logger.Verbose("=== Pushing character data ===");
|
||||||
await _userHub!.InvokeAsync("PushCharacterData", character, visibleCharacterIds, uploadToken);
|
await _userHub!.InvokeAsync("PushCharacterDataToVisibleClients", character, visibleCharacterIds, uploadToken);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user