refactor + add resiliency against penumbra/api shutdowns
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
@@ -15,18 +16,31 @@ namespace MareSynchronos.Factories
|
||||
{
|
||||
private readonly DalamudUtil _dalamudUtil;
|
||||
private readonly IpcManager _ipcManager;
|
||||
private readonly FileReplacementFactory _factory;
|
||||
|
||||
public CharacterDataFactory(DalamudUtil dalamudUtil, IpcManager ipcManager, FileReplacementFactory factory)
|
||||
public CharacterDataFactory(DalamudUtil dalamudUtil, IpcManager ipcManager)
|
||||
{
|
||||
Logger.Debug("Creating " + nameof(CharacterDataFactory));
|
||||
|
||||
_dalamudUtil = dalamudUtil;
|
||||
_ipcManager = ipcManager;
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public unsafe CharacterData BuildCharacterData()
|
||||
private FileReplacement CreateBaseFileReplacement()
|
||||
{
|
||||
return new FileReplacement(_ipcManager.PenumbraModDirectory()!);
|
||||
}
|
||||
|
||||
public CharacterData BuildCharacterData()
|
||||
{
|
||||
if (!_dalamudUtil.IsPlayerPresent || !_ipcManager.Initialized)
|
||||
{
|
||||
throw new ArgumentException("Player is not present or Penumbra is not connected");
|
||||
}
|
||||
|
||||
return CreateCharacterData();
|
||||
}
|
||||
|
||||
private unsafe CharacterData CreateCharacterData()
|
||||
{
|
||||
Stopwatch st = Stopwatch.StartNew();
|
||||
var cache = new CharacterData();
|
||||
@@ -47,7 +61,7 @@ namespace MareSynchronos.Factories
|
||||
|
||||
var mdlPath = new Utf8String(mdl->ResourceHandle->FileName()).ToString();
|
||||
|
||||
FileReplacement cachedMdlResource = _factory.Create();
|
||||
FileReplacement cachedMdlResource = CreateBaseFileReplacement();
|
||||
cachedMdlResource.GamePaths = _ipcManager.PenumbraReverseResolvePath(mdlPath, _dalamudUtil.PlayerName);
|
||||
cachedMdlResource.SetResolvedPath(mdlPath);
|
||||
//PluginLog.Verbose("Resolving for model " + mdlPath);
|
||||
@@ -59,10 +73,10 @@ namespace MareSynchronos.Factories
|
||||
var mtrl = (Material*)mdl->Materials[mtrlIdx];
|
||||
if (mtrl == null) continue;
|
||||
|
||||
//var mtrlFileResource = factory.Create();
|
||||
//var mtrlFileResource = factory.CreateBaseFileReplacement();
|
||||
var mtrlPath = new Utf8String(mtrl->ResourceHandle->FileName()).ToString().Split("|")[2];
|
||||
//PluginLog.Verbose("Resolving for material " + mtrlPath);
|
||||
var cachedMtrlResource = _factory.Create();
|
||||
var cachedMtrlResource = CreateBaseFileReplacement();
|
||||
cachedMtrlResource.GamePaths = _ipcManager.PenumbraReverseResolvePath(mtrlPath, _dalamudUtil.PlayerName);
|
||||
cachedMtrlResource.SetResolvedPath(mtrlPath);
|
||||
cache.AddAssociatedResource(cachedMtrlResource, cachedMdlResource, null!);
|
||||
@@ -74,7 +88,7 @@ namespace MareSynchronos.Factories
|
||||
|
||||
if (string.IsNullOrEmpty(texPath.ToString())) continue;
|
||||
|
||||
var cachedTexResource = _factory.Create();
|
||||
var cachedTexResource = CreateBaseFileReplacement();
|
||||
cachedTexResource.GamePaths = new[] { texPath };
|
||||
cachedTexResource.SetResolvedPath(_ipcManager.PenumbraResolvePath(texPath, _dalamudUtil.PlayerName)!);
|
||||
if (!cachedTexResource.HasFileReplacement)
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
using MareSynchronos.Managers;
|
||||
using MareSynchronos.Models;
|
||||
using MareSynchronos.Utils;
|
||||
|
||||
namespace MareSynchronos.Factories
|
||||
{
|
||||
public class FileReplacementFactory
|
||||
{
|
||||
private readonly IpcManager _ipcManager;
|
||||
|
||||
public FileReplacementFactory(IpcManager ipcManager)
|
||||
{
|
||||
Logger.Debug("Creating " + nameof(FileReplacementFactory));
|
||||
|
||||
this._ipcManager = ipcManager;
|
||||
}
|
||||
|
||||
public FileReplacement Create()
|
||||
{
|
||||
if (!_ipcManager.CheckPenumbraApi())
|
||||
{
|
||||
throw new System.Exception();
|
||||
}
|
||||
|
||||
return new FileReplacement(_ipcManager.PenumbraModDirectory()!);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,46 @@ public class CharacterCacheManager : IDisposable
|
||||
_apiController = apiController;
|
||||
_dalamudUtil = dalamudUtil;
|
||||
_ipcManager = ipcManager;
|
||||
|
||||
_clientState.Login += ClientStateOnLogin;
|
||||
_clientState.Logout += ClientStateOnLogout;
|
||||
|
||||
_apiController.CharacterReceived += ApiControllerOnCharacterReceived;
|
||||
_apiController.PairedClientOnline += ApiControllerOnPairedClientOnline;
|
||||
_apiController.PairedClientOffline += ApiControllerOnPairedClientOffline;
|
||||
_apiController.PairedWithOther += ApiControllerOnPairedWithOther;
|
||||
_apiController.UnpairedFromOther += ApiControllerOnUnpairedFromOther;
|
||||
_apiController.Disconnected += ApiControllerOnDisconnected;
|
||||
_ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed;
|
||||
|
||||
if (clientState.IsLoggedIn)
|
||||
{
|
||||
ClientStateOnLogin(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void IpcManagerOnPenumbraDisposed(object? sender, EventArgs e)
|
||||
{
|
||||
foreach (var character in _onlineCachedPlayers.ToList())
|
||||
{
|
||||
RestoreCharacter(character);
|
||||
character.IsVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void ApiControllerOnDisconnected(object? sender, EventArgs e)
|
||||
{
|
||||
RestoreAllCharacters();
|
||||
}
|
||||
|
||||
private void ClientStateOnLogin(object? sender, EventArgs e)
|
||||
{
|
||||
_framework.Update += FrameworkOnUpdate;
|
||||
}
|
||||
|
||||
private void ClientStateOnLogout(object? sender, EventArgs e)
|
||||
{
|
||||
_framework.Update -= FrameworkOnUpdate;
|
||||
}
|
||||
|
||||
public void AddInitialPairs(List<string> apiTaskResult)
|
||||
@@ -55,8 +95,15 @@ public class CharacterCacheManager : IDisposable
|
||||
_apiController.PairedClientOffline -= ApiControllerOnPairedClientOffline;
|
||||
_apiController.PairedWithOther -= ApiControllerOnPairedWithOther;
|
||||
_apiController.UnpairedFromOther -= ApiControllerOnUnpairedFromOther;
|
||||
_ipcManager.PenumbraDisposed -= ApiControllerOnDisconnected;
|
||||
_framework.Update -= FrameworkOnUpdate;
|
||||
_clientState.Login -= ClientStateOnLogin;
|
||||
_clientState.Logout -= ClientStateOnLogout;
|
||||
RestoreAllCharacters();
|
||||
}
|
||||
|
||||
private void RestoreAllCharacters()
|
||||
{
|
||||
foreach (var character in _onlineCachedPlayers.ToList())
|
||||
{
|
||||
RestoreCharacter(character);
|
||||
@@ -65,18 +112,6 @@ public class CharacterCacheManager : IDisposable
|
||||
_onlineCachedPlayers.Clear();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
_onlineCachedPlayers.Clear();
|
||||
|
||||
_apiController.CharacterReceived += ApiControllerOnCharacterReceived;
|
||||
_apiController.PairedClientOnline += ApiControllerOnPairedClientOnline;
|
||||
_apiController.PairedClientOffline += ApiControllerOnPairedClientOffline;
|
||||
_apiController.PairedWithOther += ApiControllerOnPairedWithOther;
|
||||
_apiController.UnpairedFromOther += ApiControllerOnUnpairedFromOther;
|
||||
_framework.Update += FrameworkOnUpdate;
|
||||
}
|
||||
|
||||
public async Task UpdatePlayersFromService(Dictionary<string, int> playerJobIds)
|
||||
{
|
||||
await _apiController.GetCharacterData(playerJobIds);
|
||||
@@ -190,6 +225,7 @@ public class CharacterCacheManager : IDisposable
|
||||
if (DateTime.Now < _lastPlayerObjectCheck.AddSeconds(2)) return;
|
||||
|
||||
_localVisiblePlayers.Clear();
|
||||
if (!_ipcManager.Initialized) return;
|
||||
foreach (var obj in _objectTable)
|
||||
{
|
||||
if (obj.ObjectKind != Dalamud.Game.ClientState.Objects.Enums.ObjectKind.Player) continue;
|
||||
|
||||
@@ -70,7 +70,6 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
var apiTask = _apiController.SendCharacterName(_dalamudUtil.PlayerNameHashed);
|
||||
_lastSentHash = string.Empty;
|
||||
_characterCacheManager.Initialize();
|
||||
|
||||
Task.WaitAll(apiTask);
|
||||
|
||||
@@ -81,8 +80,6 @@ namespace MareSynchronos.Managers
|
||||
|
||||
private void ApiController_Disconnected(object? sender, EventArgs args)
|
||||
{
|
||||
_characterCacheManager.Dispose();
|
||||
|
||||
Logger.Debug(nameof(ApiController_Disconnected));
|
||||
|
||||
_ipcManager.PenumbraRedrawEvent -= IpcManager_PenumbraRedrawEvent;
|
||||
@@ -126,6 +123,12 @@ namespace MareSynchronos.Managers
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_ipcManager.Initialized)
|
||||
{
|
||||
PluginLog.Warning("Penumbra not active, doing nothing.");
|
||||
return;
|
||||
}
|
||||
|
||||
_playerChangedTask = Task.Run(async () =>
|
||||
{
|
||||
Stopwatch st = Stopwatch.StartNew();
|
||||
@@ -151,8 +154,6 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
Logger.Debug("Watcher Player Changed");
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// fix for redraw from anamnesis
|
||||
while (!_dalamudUtil.IsPlayerPresent)
|
||||
@@ -170,11 +171,6 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
Logger.Debug("PlayerChanged: " + actor.Name.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PluginLog.Error(ex, "Actor was null or broken " + actor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -26,17 +26,32 @@ namespace MareSynchronos.Managers
|
||||
_ipcManager = ipcManager;
|
||||
_pluginConfiguration = pluginConfiguration;
|
||||
|
||||
if (_ipcManager.CheckPenumbraApi()
|
||||
&& _pluginConfiguration.AcceptedAgreement
|
||||
&& !string.IsNullOrEmpty(_pluginConfiguration.CacheFolder)
|
||||
&& _pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri)
|
||||
&& !string.IsNullOrEmpty(_ipcManager.PenumbraModDirectory()))
|
||||
StartWatchersAndScan();
|
||||
|
||||
_ipcManager.PenumbraInitialized += IpcManagerOnPenumbraInitialized;
|
||||
_ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed;
|
||||
}
|
||||
|
||||
private void StartWatchersAndScan()
|
||||
{
|
||||
if (_ipcManager.Initialized && _pluginConfiguration.HasValidSetup)
|
||||
{
|
||||
Logger.Debug("Penumbra is active, configuration is valid, starting watchers and scan");
|
||||
StartWatchers();
|
||||
StartInitialScan();
|
||||
}
|
||||
}
|
||||
|
||||
private void IpcManagerOnPenumbraInitialized(object? sender, EventArgs e)
|
||||
{
|
||||
StartWatchersAndScan();
|
||||
}
|
||||
|
||||
private void IpcManagerOnPenumbraDisposed(object? sender, EventArgs e)
|
||||
{
|
||||
StopWatchersAndScan();
|
||||
}
|
||||
|
||||
public long CurrentFileProgress { get; private set; }
|
||||
public long FileCacheSize { get; set; }
|
||||
public bool IsScanRunning => !_scanTask?.IsCompleted ?? false;
|
||||
@@ -68,6 +83,14 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
Logger.Debug("Disposing " + nameof(FileCacheManager));
|
||||
|
||||
_ipcManager.PenumbraInitialized -= IpcManagerOnPenumbraInitialized;
|
||||
_ipcManager.PenumbraDisposed -= IpcManagerOnPenumbraDisposed;
|
||||
|
||||
StopWatchersAndScan();
|
||||
}
|
||||
|
||||
private void StopWatchersAndScan()
|
||||
{
|
||||
_cacheDirWatcher?.Dispose();
|
||||
_penumbraDirWatcher?.Dispose();
|
||||
_scanCancellationTokenSource?.Cancel();
|
||||
@@ -81,6 +104,7 @@ namespace MareSynchronos.Managers
|
||||
|
||||
public void StartWatchers()
|
||||
{
|
||||
if (!_ipcManager.Initialized || !_pluginConfiguration.HasValidSetup) return;
|
||||
Logger.Debug("Starting File System Watchers");
|
||||
_penumbraDirWatcher?.Dispose();
|
||||
_cacheDirWatcher?.Dispose();
|
||||
@@ -91,7 +115,6 @@ namespace MareSynchronos.Managers
|
||||
InternalBufferSize = 65536
|
||||
};
|
||||
_penumbraDirWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
|
||||
//_penumbraDirWatcher.Created += OnCreated;
|
||||
_penumbraDirWatcher.Deleted += OnDeleted;
|
||||
_penumbraDirWatcher.Changed += OnModified;
|
||||
_penumbraDirWatcher.Filters.Add("*.mtrl");
|
||||
@@ -107,7 +130,6 @@ namespace MareSynchronos.Managers
|
||||
InternalBufferSize = 65536
|
||||
};
|
||||
_cacheDirWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size;
|
||||
//_cacheDirWatcher.Created += OnCreated;
|
||||
_cacheDirWatcher.Deleted += OnDeleted;
|
||||
_cacheDirWatcher.Changed += OnModified;
|
||||
_cacheDirWatcher.Filters.Add("*.mtrl");
|
||||
@@ -134,49 +156,6 @@ namespace MareSynchronos.Managers
|
||||
return false;
|
||||
}
|
||||
|
||||
private void OnCreated(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
var fi = new FileInfo(e.FullPath);
|
||||
using var db = new FileCacheContext();
|
||||
var ext = fi.Extension.ToLower();
|
||||
if (ext is ".mdl" or ".tex" or ".mtrl")
|
||||
{
|
||||
Logger.Debug("File created: " + e.FullPath);
|
||||
try
|
||||
{
|
||||
var createdFileCache = Create(fi.FullName.ToLower());
|
||||
db.Add(createdFileCache);
|
||||
}
|
||||
catch (FileLoadException)
|
||||
{
|
||||
Logger.Debug("File was still being written to.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Directory.Exists(e.FullPath))
|
||||
{
|
||||
Logger.Debug("Folder added: " + e.FullPath);
|
||||
var newFiles = Directory.EnumerateFiles(e.FullPath, "*.*", SearchOption.AllDirectories)
|
||||
.Where(f => f.EndsWith(".tex", StringComparison.OrdinalIgnoreCase) ||
|
||||
f.EndsWith(".mdl", StringComparison.OrdinalIgnoreCase) ||
|
||||
f.EndsWith(".mtrl", StringComparison.OrdinalIgnoreCase)).ToList();
|
||||
foreach (var file in newFiles)
|
||||
{
|
||||
Logger.Debug("Adding " + file);
|
||||
db.Add(Create(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
db.SaveChanges();
|
||||
|
||||
if (e.FullPath.Contains(_pluginConfiguration.CacheFolder, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Task.Run(RecalculateFileCacheSize);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDeleted(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
var fi = new FileInfo(e.FullPath);
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace MareSynchronos.Managers
|
||||
private readonly ICallGateSubscriber<string, string, bool, (int, string)> _penumbraCreateTemporaryCollection;
|
||||
private readonly ICallGateSubscriber<string, string> _penumbraGetMetaManipulations;
|
||||
private readonly ICallGateSubscriber<object> _penumbraInit;
|
||||
private readonly ICallGateSubscriber<object> _penumbraDispose;
|
||||
private readonly ICallGateSubscriber<IntPtr, int, object?> _penumbraObjectIsRedrawn;
|
||||
private readonly ICallGateSubscriber<string, int, object>? _penumbraRedraw;
|
||||
private readonly ICallGateSubscriber<string, int> _penumbraRemoveTemporaryCollection;
|
||||
@@ -30,6 +31,7 @@ namespace MareSynchronos.Managers
|
||||
Logger.Debug("Creating " + nameof(IpcManager));
|
||||
|
||||
_penumbraInit = pi.GetIpcSubscriber<object>("Penumbra.Initialized");
|
||||
_penumbraDispose = pi.GetIpcSubscriber<object>("Penumbra.Disposed");
|
||||
_penumbraResolvePath = pi.GetIpcSubscriber<string, string, string>("Penumbra.ResolveCharacterPath");
|
||||
_penumbraResolveModDir = pi.GetIpcSubscriber<string>("Penumbra.GetModDirectory");
|
||||
_penumbraRedraw = pi.GetIpcSubscriber<string, int, object>("Penumbra.RedrawObjectByName");
|
||||
@@ -44,7 +46,8 @@ namespace MareSynchronos.Managers
|
||||
pi.GetIpcSubscriber<string, string>("Penumbra.GetMetaManipulations");
|
||||
|
||||
_penumbraObjectIsRedrawn.Subscribe(RedrawEvent);
|
||||
_penumbraInit.Subscribe(RedrawSelf);
|
||||
_penumbraInit.Subscribe(PenumbraInit);
|
||||
_penumbraDispose.Subscribe(PenumbraDispose);
|
||||
|
||||
_penumbraSetTemporaryMod =
|
||||
pi
|
||||
@@ -56,12 +59,17 @@ namespace MareSynchronos.Managers
|
||||
_penumbraRemoveTemporaryCollection =
|
||||
pi.GetIpcSubscriber<string, int>("Penumbra.RemoveTemporaryCollection");
|
||||
|
||||
Initialized = true;
|
||||
if (Initialized)
|
||||
{
|
||||
PenumbraInitialized?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler? PenumbraInitialized;
|
||||
public event EventHandler? PenumbraDisposed;
|
||||
public event EventHandler? PenumbraRedrawEvent;
|
||||
|
||||
public bool Initialized { get; private set; } = false;
|
||||
public bool Initialized => CheckPenumbraApi();
|
||||
public bool CheckGlamourerApi()
|
||||
{
|
||||
try
|
||||
@@ -78,18 +86,22 @@ namespace MareSynchronos.Managers
|
||||
{
|
||||
try
|
||||
{
|
||||
return _penumbraApiVersion.InvokeFunc() >= 4;
|
||||
return _penumbraApiVersion.InvokeFunc() >= 5;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Logger.Debug("Disposing " + nameof(IpcManager));
|
||||
|
||||
Uninitialize();
|
||||
_penumbraDispose.Unsubscribe(PenumbraDispose);
|
||||
_penumbraInit.Unsubscribe(PenumbraInit);
|
||||
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
||||
Logger.Debug("IPC Manager disposed");
|
||||
}
|
||||
|
||||
public void GlamourerApplyCharacterCustomization(string customization, string characterName)
|
||||
@@ -174,17 +186,15 @@ namespace MareSynchronos.Managers
|
||||
PenumbraRedrawEvent?.Invoke(objectTableIndex, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void RedrawSelf()
|
||||
private void PenumbraInit()
|
||||
{
|
||||
PenumbraInitialized?.Invoke(null, EventArgs.Empty);
|
||||
_penumbraRedraw!.InvokeAction("self", 0);
|
||||
}
|
||||
|
||||
private void Uninitialize()
|
||||
private void PenumbraDispose()
|
||||
{
|
||||
_penumbraInit.Unsubscribe(RedrawSelf);
|
||||
_penumbraObjectIsRedrawn.Unsubscribe(RedrawEvent);
|
||||
Initialized = false;
|
||||
Logger.Debug("IPC Manager disposed");
|
||||
PenumbraDisposed?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace MareSynchronos
|
||||
private readonly ApiController _apiController;
|
||||
private readonly ClientState _clientState;
|
||||
private readonly CommandManager _commandManager;
|
||||
private readonly Framework _framework;
|
||||
private readonly Configuration _configuration;
|
||||
private readonly FileCacheManager _fileCacheManager;
|
||||
private readonly IntroUi _introUi;
|
||||
@@ -32,7 +33,7 @@ namespace MareSynchronos
|
||||
private readonly WindowSystem _windowSystem;
|
||||
private CharacterManager? _characterManager;
|
||||
private readonly DalamudUtil _dalamudUtil;
|
||||
private readonly CharacterCacheManager _characterCacheManager;
|
||||
private CharacterCacheManager? _characterCacheManager;
|
||||
private readonly IPlayerWatcher _playerWatcher;
|
||||
private readonly DownloadUi _downloadUi;
|
||||
|
||||
@@ -42,6 +43,7 @@ namespace MareSynchronos
|
||||
Logger.Debug("Launching " + Name);
|
||||
_pluginInterface = pluginInterface;
|
||||
_commandManager = commandManager;
|
||||
_framework = framework;
|
||||
_objectTable = objectTable;
|
||||
_clientState = clientState;
|
||||
_configuration = _pluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
@@ -49,18 +51,16 @@ namespace MareSynchronos
|
||||
|
||||
_windowSystem = new WindowSystem("MareSynchronos");
|
||||
|
||||
new FileCacheContext().Dispose(); // make sure db is initialized I guess
|
||||
|
||||
// those can be initialized outside of game login
|
||||
_apiController = new ApiController(_configuration);
|
||||
_ipcManager = new IpcManager(_pluginInterface);
|
||||
|
||||
_fileCacheManager = new FileCacheManager(_ipcManager, _configuration);
|
||||
_dalamudUtil = new DalamudUtil(_clientState, _objectTable);
|
||||
_characterCacheManager = new CharacterCacheManager(_clientState, framework, _objectTable, _apiController,
|
||||
_dalamudUtil, _ipcManager);
|
||||
_playerWatcher = PlayerWatchFactory.Create(framework, _clientState, _objectTable);
|
||||
_playerWatcher.Enable();
|
||||
|
||||
var uiSharedComponent =
|
||||
new UiShared(_ipcManager, _apiController, _fileCacheManager, _configuration);
|
||||
|
||||
_pluginUi = new PluginUi(_windowSystem, uiSharedComponent, _configuration, _apiController);
|
||||
_introUi = new IntroUi(_windowSystem, uiSharedComponent, _configuration, _fileCacheManager);
|
||||
_introUi.FinishedRegistration += (_, _) =>
|
||||
@@ -71,7 +71,9 @@ namespace MareSynchronos
|
||||
};
|
||||
_downloadUi = new DownloadUi(_windowSystem, _configuration, _apiController);
|
||||
|
||||
new FileCacheContext().Dispose(); // make sure db is initialized I guess
|
||||
_dalamudUtil = new DalamudUtil(_clientState, _objectTable);
|
||||
_playerWatcher = PlayerWatchFactory.Create(framework, _clientState, _objectTable);
|
||||
_playerWatcher.Enable();
|
||||
|
||||
clientState.Login += ClientState_Login;
|
||||
clientState.Logout += ClientState_Logout;
|
||||
@@ -87,8 +89,8 @@ namespace MareSynchronos
|
||||
{
|
||||
_pluginUi.IsOpen = false;
|
||||
_introUi.IsOpen = true;
|
||||
_characterCacheManager.Dispose();
|
||||
_characterManager!.Dispose();
|
||||
_characterCacheManager?.Dispose();
|
||||
_characterManager?.Dispose();
|
||||
}
|
||||
|
||||
public string Name => "Mare Synchronos";
|
||||
@@ -102,7 +104,6 @@ namespace MareSynchronos
|
||||
_clientState.Login -= ClientState_Login;
|
||||
_clientState.Logout -= ClientState_Logout;
|
||||
|
||||
|
||||
_pluginUi?.Dispose();
|
||||
_introUi?.Dispose();
|
||||
_downloadUi?.Dispose();
|
||||
@@ -110,7 +111,7 @@ namespace MareSynchronos
|
||||
_fileCacheManager?.Dispose();
|
||||
_ipcManager?.Dispose();
|
||||
_characterManager?.Dispose();
|
||||
_characterCacheManager.Dispose();
|
||||
_characterCacheManager?.Dispose();
|
||||
_playerWatcher.Disable();
|
||||
_playerWatcher.Dispose();
|
||||
}
|
||||
@@ -139,6 +140,7 @@ namespace MareSynchronos
|
||||
private void ClientState_Logout(object? sender, EventArgs e)
|
||||
{
|
||||
Logger.Debug("Client logout");
|
||||
_characterCacheManager?.Dispose();
|
||||
_characterManager?.Dispose();
|
||||
_pluginInterface.UiBuilder.Draw -= Draw;
|
||||
_pluginInterface.UiBuilder.OpenConfigUi -= OpenConfigUi;
|
||||
@@ -159,7 +161,9 @@ namespace MareSynchronos
|
||||
try
|
||||
{
|
||||
var characterCacheFactory =
|
||||
new CharacterDataFactory(_dalamudUtil, _ipcManager, new FileReplacementFactory(_ipcManager));
|
||||
new CharacterDataFactory(_dalamudUtil, _ipcManager);
|
||||
_characterCacheManager = new CharacterCacheManager(_clientState, _framework, _objectTable,
|
||||
_apiController, _dalamudUtil, _ipcManager);
|
||||
_characterManager = new CharacterManager(_apiController, _objectTable, _ipcManager,
|
||||
characterCacheFactory, _characterCacheManager, _dalamudUtil, _playerWatcher);
|
||||
_characterManager.StartWatchingPlayer();
|
||||
|
||||
@@ -31,6 +31,11 @@ namespace MareSynchronos.Utils
|
||||
|
||||
public Dictionary<string, PlayerCharacter> GetLocalPlayers()
|
||||
{
|
||||
if (!_clientState.IsLoggedIn)
|
||||
{
|
||||
return new Dictionary<string, PlayerCharacter>();
|
||||
}
|
||||
|
||||
Dictionary<string, PlayerCharacter> allLocalPlayers = new();
|
||||
foreach (var obj in _objectTable)
|
||||
{
|
||||
@@ -46,6 +51,8 @@ namespace MareSynchronos.Utils
|
||||
|
||||
public unsafe void WaitWhileCharacterIsDrawing(IntPtr characterAddress)
|
||||
{
|
||||
if (!_clientState.IsLoggedIn) return;
|
||||
|
||||
var obj = (GameObject*)characterAddress;
|
||||
|
||||
// ReSharper disable once LoopVariableIsNeverChangedInsideLoop
|
||||
@@ -59,6 +66,6 @@ namespace MareSynchronos.Utils
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
public void WaitWhileSelfIsDrawing() => WaitWhileCharacterIsDrawing(_clientState.LocalPlayer!.Address);
|
||||
public void WaitWhileSelfIsDrawing() => WaitWhileCharacterIsDrawing(_clientState.LocalPlayer?.Address ?? new IntPtr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,8 +55,8 @@ namespace MareSynchronos.WebAPI
|
||||
public ConcurrentDictionary<string, (long, long)> CurrentDownloads { get; } = new();
|
||||
public ConcurrentDictionary<string, (long, long)> CurrentUploads { get; } = new();
|
||||
public bool IsConnected => !string.IsNullOrEmpty(UID);
|
||||
public bool IsDownloading { get; private set; } = false;
|
||||
public bool IsUploading { get; private set; } = false;
|
||||
public bool IsDownloading { get; private set; }
|
||||
public bool IsUploading { get; private set; }
|
||||
public List<ClientPairDto> PairedClients { get; set; } = new();
|
||||
public string SecretKey => _pluginConfiguration.ClientSecret.ContainsKey(ApiUri) ? _pluginConfiguration.ClientSecret[ApiUri] : "-";
|
||||
public bool ServerAlive =>
|
||||
@@ -95,7 +95,6 @@ namespace MareSynchronos.WebAPI
|
||||
|
||||
public async Task<byte[]> DownloadFile(string hash)
|
||||
{
|
||||
IsDownloading = true;
|
||||
var reader = await _fileHub!.StreamAsChannelAsync<byte[]>("DownloadFile", hash);
|
||||
List<byte> downloadedData = new();
|
||||
int i = 0;
|
||||
@@ -108,12 +107,13 @@ namespace MareSynchronos.WebAPI
|
||||
}
|
||||
}
|
||||
|
||||
IsDownloading = false;
|
||||
return downloadedData.ToArray();
|
||||
}
|
||||
|
||||
public async Task DownloadFiles(List<FileReplacementDto> fileReplacementDto)
|
||||
{
|
||||
IsDownloading = true;
|
||||
|
||||
foreach (var file in fileReplacementDto)
|
||||
{
|
||||
var fileSize = await _fileHub!.InvokeAsync<long>("GetFileSize", file.Hash);
|
||||
@@ -149,6 +149,7 @@ namespace MareSynchronos.WebAPI
|
||||
}
|
||||
|
||||
CurrentDownloads.Clear();
|
||||
IsDownloading = false;
|
||||
}
|
||||
|
||||
public async Task GetCharacterData(Dictionary<string, int> hashedCharacterNames)
|
||||
|
||||
Reference in New Issue
Block a user