From 8c9f816e6dbb2d2250c6a1de6567d197d76d11a9 Mon Sep 17 00:00:00 2001 From: Stanley Dimant Date: Sat, 25 Jun 2022 19:37:26 +0200 Subject: [PATCH] several fixes for file cache handling, add account deletion --- .../Managers/CharacterCacheManager.cs | 2 + MareSynchronos/Managers/FileCacheManager.cs | 10 ++- MareSynchronos/Plugin.cs | 11 ++++ MareSynchronos/UI/PluginUI.cs | 61 ++++++++++++++++++- MareSynchronos/WebAPI/ApiController.cs | 19 +++++- 5 files changed, 98 insertions(+), 5 deletions(-) diff --git a/MareSynchronos/Managers/CharacterCacheManager.cs b/MareSynchronos/Managers/CharacterCacheManager.cs index 817673a..ad0620d 100644 --- a/MareSynchronos/Managers/CharacterCacheManager.cs +++ b/MareSynchronos/Managers/CharacterCacheManager.cs @@ -41,6 +41,7 @@ public class CharacterCacheManager : IDisposable public void AddInitialPairs(List apiTaskResult) { + _onlineCachedPlayers.Clear(); _onlineCachedPlayers.AddRange(apiTaskResult.Select(a => new CachedPlayer(a))); Logger.Debug("Online and paired users: " + string.Join(",", _onlineCachedPlayers)); } @@ -159,6 +160,7 @@ public class CharacterCacheManager : IDisposable private void ApiControllerOnPairedClientOnline(object? sender, EventArgs e) { Logger.Debug("Player online: " + sender!); + if (_onlineCachedPlayers.Any(c => c.PlayerNameHash == (string)sender!)) return; _onlineCachedPlayers.Add(new CachedPlayer((string)sender!)); } diff --git a/MareSynchronos/Managers/FileCacheManager.cs b/MareSynchronos/Managers/FileCacheManager.cs index fd0685a..e29bdbb 100644 --- a/MareSynchronos/Managers/FileCacheManager.cs +++ b/MareSynchronos/Managers/FileCacheManager.cs @@ -317,9 +317,15 @@ namespace MareSynchronos.Managers Logger.Debug("Found " + fileCachesToAdd.Count + " additions and " + fileCachesToDelete.Count + " deletions"); try { - db.FileCaches.RemoveRange(fileCachesToDelete); + foreach (var deletion in fileCachesToDelete) + { + var entry = db.FileCaches.SingleOrDefault(f => + f.Hash == deletion.Hash && f.Filepath == deletion.Filepath); + if (entry != null) + db.FileCaches.Remove(entry); + } db.FileCaches.AddRange(fileCachesToAdd); - db.SaveChanges(); + await db.SaveChangesAsync(ct); } catch (Exception ex) { diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index 4749f3d..c706078 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -75,6 +75,7 @@ namespace MareSynchronos clientState.Login += ClientState_Login; clientState.Logout += ClientState_Logout; + _apiController.AccountDeleted += ApiControllerOnAccountDeleted; if (clientState.IsLoggedIn) { @@ -82,16 +83,26 @@ namespace MareSynchronos } } + private void ApiControllerOnAccountDeleted(object? sender, EventArgs e) + { + _pluginUi.IsOpen = false; + _introUi.IsOpen = true; + _characterCacheManager.Dispose(); + _characterManager!.Dispose(); + } + public string Name => "Mare Synchronos"; public void Dispose() { Logger.Debug("Disposing " + Name); + _apiController.AccountDeleted -= ApiControllerOnAccountDeleted; _apiController?.Dispose(); _commandManager.RemoveHandler(CommandName); _clientState.Login -= ClientState_Login; _clientState.Logout -= ClientState_Logout; + _pluginUi?.Dispose(); _introUi?.Dispose(); _downloadUi?.Dispose(); diff --git a/MareSynchronos/UI/PluginUI.cs b/MareSynchronos/UI/PluginUI.cs index 5053cab..7f19351 100644 --- a/MareSynchronos/UI/PluginUI.cs +++ b/MareSynchronos/UI/PluginUI.cs @@ -6,6 +6,7 @@ using MareSynchronos.WebAPI; using System; using System.IO; using System.Linq; +using System.Numerics; using System.Threading.Tasks; using MareSynchronos.Utils; @@ -97,6 +98,9 @@ namespace MareSynchronos.UI } } + private bool _deleteFilesPopupModalShown = false; + private bool _deleteAccountPopupModalShown = false; + private void DrawAdministration() { if (ImGui.TreeNode( @@ -104,8 +108,63 @@ namespace MareSynchronos.UI { if (ImGui.Button("Delete all my files")) { - Task.Run(() => _apiController.DeleteAllMyFiles()); + _deleteFilesPopupModalShown = true; + ImGui.OpenPopup("Delete all your files?"); } + + if (ImGui.BeginPopupModal("Delete all your files?", ref _deleteFilesPopupModalShown, ImGuiWindowFlags.AlwaysAutoResize)) + { + UiShared.TextWrapped("All your own uploaded files on the service will be deleted.\nThis operation cannot be undone."); + ImGui.Text("Are you sure you want to continue?"); + ImGui.Separator(); + if (ImGui.Button("Delete everything", new Vector2(150, 0))) + { + Task.Run(() => _apiController.DeleteAllMyFiles()); + ImGui.CloseCurrentPopup(); + _deleteFilesPopupModalShown = false; + } + + ImGui.SameLine(); + + if (ImGui.Button("Cancel##cancelDelete", new Vector2(150, 0))) + { + ImGui.CloseCurrentPopup(); + _deleteFilesPopupModalShown = false; + } + + ImGui.EndPopup(); + } + + if (ImGui.Button("Delete account")) + { + _deleteAccountPopupModalShown = true; + ImGui.OpenPopup("Delete your account?"); + } + + if (ImGui.BeginPopupModal("Delete your account?", ref _deleteAccountPopupModalShown, ImGuiWindowFlags.AlwaysAutoResize)) + { + UiShared.TextWrapped("Your account and all associated files and data on the service will be deleted."); + UiShared.TextWrapped("Your UID will be removed from all pairing lists."); + ImGui.Text("Are you sure you want to continue?"); + ImGui.Separator(); + if (ImGui.Button("Delete account", new Vector2(150, 0))) + { + Task.Run(() => _apiController.DeleteAccount()); + ImGui.CloseCurrentPopup(); + _deleteAccountPopupModalShown = false; + } + + ImGui.SameLine(); + + if (ImGui.Button("Cancel##cancelDelete", new Vector2(150, 0))) + { + ImGui.CloseCurrentPopup(); + _deleteAccountPopupModalShown = false; + } + + ImGui.EndPopup(); + } + ImGui.TreePop(); } } diff --git a/MareSynchronos/WebAPI/ApiController.cs b/MareSynchronos/WebAPI/ApiController.cs index 1f28a4b..c65a6e2 100644 --- a/MareSynchronos/WebAPI/ApiController.cs +++ b/MareSynchronos/WebAPI/ApiController.cs @@ -50,6 +50,7 @@ namespace MareSynchronos.WebAPI public event EventHandler? PairedWithOther; public event EventHandler? UnpairedFromOther; + public event EventHandler? AccountDeleted; public ConcurrentDictionary CurrentDownloads { get; } = new(); public ConcurrentDictionary CurrentUploads { get; } = new(); @@ -97,13 +98,13 @@ namespace MareSynchronos.WebAPI IsDownloading = true; var reader = await _fileHub!.StreamAsChannelAsync("DownloadFile", hash); List downloadedData = new(); + int i = 0; while (await reader.WaitToReadAsync()) { while (reader.TryRead(out var data)) { CurrentDownloads[hash] = (CurrentDownloads[hash].Item1 + data.Length, CurrentDownloads[hash].Item2); downloadedData.AddRange(data); - //await Task.Delay(25); } } @@ -122,7 +123,10 @@ namespace MareSynchronos.WebAPI List downloadedHashes = new(); foreach (var file in fileReplacementDto.Where(f => CurrentDownloads[f.Hash].Item2 > 0)) { - if (downloadedHashes.Contains(file.Hash)) continue; + if (downloadedHashes.Contains(file.Hash)) + { + continue; + } var hash = file.Hash; var data = await DownloadFile(hash); var extractedFile = LZ4Codec.Unwrap(data); @@ -330,6 +334,15 @@ namespace MareSynchronos.WebAPI await _fileHub!.SendAsync("DeleteAllFiles"); } + public async Task DeleteAccount() + { + _pluginConfiguration.ClientSecret.Remove(ApiUri); + await _fileHub!.SendAsync("DeleteAllFiles"); + await _userHub!.SendAsync("DeleteAccount"); + _ = OnHeartbeatHubOnClosed(null); + AccountDeleted?.Invoke(null, EventArgs.Empty); + } + private async Task DisposeHubConnections() { if (_fileHub != null) @@ -406,6 +419,7 @@ namespace MareSynchronos.WebAPI var pairedClients = await _userHub!.InvokeAsync>("GetPairedClients"); PairedClients = pairedClients.ToList(); } + private Task OnHeartbeatHubOnClosed(Exception? exception) { Logger.Debug("Connection closed: " + ApiUri); @@ -419,6 +433,7 @@ namespace MareSynchronos.WebAPI Logger.Debug("Reconnected: " + ApiUri); UID = await _heartbeatHub!.InvokeAsync("Heartbeat"); } + private void UpdateLocalClientPairs(ClientPairDto dto, string characterIdentifier) { var entry = PairedClients.SingleOrDefault(e => e.OtherUID == dto.OtherUID);