diff --git a/MareSynchronos/Factories/CharacterDataFactory.cs b/MareSynchronos/Factories/CharacterDataFactory.cs index 027ca27..f2e9ad2 100644 --- a/MareSynchronos/Factories/CharacterDataFactory.cs +++ b/MareSynchronos/Factories/CharacterDataFactory.cs @@ -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) diff --git a/MareSynchronos/Factories/FileReplacementFactory.cs b/MareSynchronos/Factories/FileReplacementFactory.cs deleted file mode 100644 index 9768f8f..0000000 --- a/MareSynchronos/Factories/FileReplacementFactory.cs +++ /dev/null @@ -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()!); - } - } -} diff --git a/MareSynchronos/Managers/CharacterCacheManager.cs b/MareSynchronos/Managers/CharacterCacheManager.cs index ad0620d..5349255 100644 --- a/MareSynchronos/Managers/CharacterCacheManager.cs +++ b/MareSynchronos/Managers/CharacterCacheManager.cs @@ -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 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 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; diff --git a/MareSynchronos/Managers/CharacterManager.cs b/MareSynchronos/Managers/CharacterManager.cs index 7ca62a1..e5b953c 100644 --- a/MareSynchronos/Managers/CharacterManager.cs +++ b/MareSynchronos/Managers/CharacterManager.cs @@ -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(); @@ -152,28 +155,21 @@ namespace MareSynchronos.Managers Logger.Debug("Watcher Player Changed"); Task.Run(() => { - try + // fix for redraw from anamnesis + while (!_dalamudUtil.IsPlayerPresent) { - // fix for redraw from anamnesis - while (!_dalamudUtil.IsPlayerPresent) - { - Logger.Debug("Waiting Until Player is Present"); - Thread.Sleep(100); - } - - if (actor.Name.ToString() == _dalamudUtil.PlayerName) - { - Logger.Debug("Watcher: PlayerChanged"); - PlayerChanged(actor.Name.ToString()); - } - else - { - Logger.Debug("PlayerChanged: " + actor.Name.ToString()); - } + Logger.Debug("Waiting Until Player is Present"); + Thread.Sleep(100); } - catch (Exception ex) + + if (actor.Name.ToString() == _dalamudUtil.PlayerName) { - PluginLog.Error(ex, "Actor was null or broken " + actor); + Logger.Debug("Watcher: PlayerChanged"); + PlayerChanged(actor.Name.ToString()); + } + else + { + Logger.Debug("PlayerChanged: " + actor.Name.ToString()); } }); } diff --git a/MareSynchronos/Managers/FileCacheManager.cs b/MareSynchronos/Managers/FileCacheManager.cs index e29bdbb..ecd6c61 100644 --- a/MareSynchronos/Managers/FileCacheManager.cs +++ b/MareSynchronos/Managers/FileCacheManager.cs @@ -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); diff --git a/MareSynchronos/Managers/IpcManager.cs b/MareSynchronos/Managers/IpcManager.cs index ef4630f..3e356eb 100644 --- a/MareSynchronos/Managers/IpcManager.cs +++ b/MareSynchronos/Managers/IpcManager.cs @@ -17,6 +17,7 @@ namespace MareSynchronos.Managers private readonly ICallGateSubscriber _penumbraCreateTemporaryCollection; private readonly ICallGateSubscriber _penumbraGetMetaManipulations; private readonly ICallGateSubscriber _penumbraInit; + private readonly ICallGateSubscriber _penumbraDispose; private readonly ICallGateSubscriber _penumbraObjectIsRedrawn; private readonly ICallGateSubscriber? _penumbraRedraw; private readonly ICallGateSubscriber _penumbraRemoveTemporaryCollection; @@ -30,6 +31,7 @@ namespace MareSynchronos.Managers Logger.Debug("Creating " + nameof(IpcManager)); _penumbraInit = pi.GetIpcSubscriber("Penumbra.Initialized"); + _penumbraDispose = pi.GetIpcSubscriber("Penumbra.Disposed"); _penumbraResolvePath = pi.GetIpcSubscriber("Penumbra.ResolveCharacterPath"); _penumbraResolveModDir = pi.GetIpcSubscriber("Penumbra.GetModDirectory"); _penumbraRedraw = pi.GetIpcSubscriber("Penumbra.RedrawObjectByName"); @@ -44,7 +46,8 @@ namespace MareSynchronos.Managers pi.GetIpcSubscriber("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("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); } } } diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index c706078..36f317f 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -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(); diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index 2a520ef..9eda827 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -31,6 +31,11 @@ namespace MareSynchronos.Utils public Dictionary GetLocalPlayers() { + if (!_clientState.IsLoggedIn) + { + return new Dictionary(); + } + Dictionary 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()); } } diff --git a/MareSynchronos/WebAPI/ApiController.cs b/MareSynchronos/WebAPI/ApiController.cs index c65a6e2..983601b 100644 --- a/MareSynchronos/WebAPI/ApiController.cs +++ b/MareSynchronos/WebAPI/ApiController.cs @@ -55,8 +55,8 @@ namespace MareSynchronos.WebAPI public ConcurrentDictionary CurrentDownloads { get; } = new(); public ConcurrentDictionary 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 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 DownloadFile(string hash) { - IsDownloading = true; var reader = await _fileHub!.StreamAsChannelAsync("DownloadFile", hash); List downloadedData = new(); int i = 0; @@ -108,12 +107,13 @@ namespace MareSynchronos.WebAPI } } - IsDownloading = false; return downloadedData.ToArray(); } public async Task DownloadFiles(List fileReplacementDto) { + IsDownloading = true; + foreach (var file in fileReplacementDto) { var fileSize = await _fileHub!.InvokeAsync("GetFileSize", file.Hash); @@ -149,6 +149,7 @@ namespace MareSynchronos.WebAPI } CurrentDownloads.Clear(); + IsDownloading = false; } public async Task GetCharacterData(Dictionary hashedCharacterNames)