diff --git a/MareSynchronos/Managers/CachedPlayersManager.cs b/MareSynchronos/Managers/CachedPlayersManager.cs index 4842c0d..b4dcc95 100644 --- a/MareSynchronos/Managers/CachedPlayersManager.cs +++ b/MareSynchronos/Managers/CachedPlayersManager.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Dalamud.Game; -using Dalamud.Game.ClientState; using MareSynchronos.Models; using MareSynchronos.Utils; using MareSynchronos.WebAPI; @@ -13,7 +12,6 @@ namespace MareSynchronos.Managers; public class CachedPlayersManager : IDisposable { private readonly ApiController _apiController; - private readonly ClientState _clientState; private readonly DalamudUtil _dalamudUtil; private readonly Framework _framework; private readonly IpcManager _ipcManager; @@ -21,20 +19,15 @@ public class CachedPlayersManager : IDisposable private readonly List _localVisiblePlayers = new(); private DateTime _lastPlayerObjectCheck = DateTime.Now; - public CachedPlayersManager(ClientState clientState, Framework framework, - ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager) + public CachedPlayersManager(Framework framework, ApiController apiController, DalamudUtil dalamudUtil, IpcManager ipcManager) { Logger.Debug("Creating " + nameof(CachedPlayersManager)); - _clientState = clientState; _framework = framework; _apiController = apiController; _dalamudUtil = dalamudUtil; _ipcManager = ipcManager; - _clientState.Login += ClientStateOnLogin; - _clientState.Logout += ClientStateOnLogout; - _apiController.PairedClientOnline += ApiControllerOnPairedClientOnline; _apiController.PairedClientOffline += ApiControllerOnPairedClientOffline; _apiController.PairedWithOther += ApiControllerOnPairedWithOther; @@ -43,12 +36,25 @@ public class CachedPlayersManager : IDisposable _ipcManager.PenumbraDisposed += IpcManagerOnPenumbraDisposed; - if (clientState.IsLoggedIn) + _dalamudUtil.LogIn += DalamudUtilOnLogIn; + _dalamudUtil.LogOut += DalamudUtilOnLogOut; + + if (_dalamudUtil.IsLoggedIn) { - ClientStateOnLogin(null, EventArgs.Empty); + DalamudUtilOnLogIn(); } } - + + private void DalamudUtilOnLogOut() + { + _framework.Update -= FrameworkOnUpdate; + } + + private void DalamudUtilOnLogIn() + { + _framework.Update += FrameworkOnUpdate; + } + private void IpcManagerOnPenumbraDisposed(object? sender, EventArgs e) { _onlineCachedPlayers.ForEach(p => p.DisposePlayer()); @@ -59,16 +65,6 @@ public class CachedPlayersManager : IDisposable 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) { _onlineCachedPlayers.Clear(); @@ -92,8 +88,8 @@ public class CachedPlayersManager : IDisposable _framework.Update -= FrameworkOnUpdate; - _clientState.Login -= ClientStateOnLogin; - _clientState.Logout -= ClientStateOnLogout; + _dalamudUtil.LogIn -= DalamudUtilOnLogIn; + _dalamudUtil.LogOut -= DalamudUtilOnLogOut; } private void RestoreAllCharacters() diff --git a/MareSynchronos/Managers/FileCacheManager.cs b/MareSynchronos/Managers/FileCacheManager.cs index 008db0a..4aa7d4d 100644 --- a/MareSynchronos/Managers/FileCacheManager.cs +++ b/MareSynchronos/Managers/FileCacheManager.cs @@ -73,6 +73,7 @@ namespace MareSynchronos.Managers _ipcManager.PenumbraDisposed -= IpcManagerOnPenumbraDisposed; _rescanTaskCancellationTokenSource?.Cancel(); _rescanTaskRunCancellationTokenSource?.Cancel(); + _scanCancellationTokenSource?.Cancel(); StopWatchersAndScan(); } diff --git a/MareSynchronos/Managers/IpcManager.cs b/MareSynchronos/Managers/IpcManager.cs index 843bc8a..585a9c5 100644 --- a/MareSynchronos/Managers/IpcManager.cs +++ b/MareSynchronos/Managers/IpcManager.cs @@ -198,7 +198,6 @@ namespace MareSynchronos.Managers Logger.Debug("Assigning temp mods for " + collectionName); var ret = _penumbraSetTemporaryMod.InvokeFunc("MareSynchronos", collectionName, modPaths, manipulationData, 0); - Logger.Debug("Penumbra Ret: " + ret.ToString()); } private void RedrawEvent(IntPtr objectAddress, int objectTableIndex) diff --git a/MareSynchronos/Managers/PlayerManager.cs b/MareSynchronos/Managers/PlayerManager.cs index 4c231d6..588258a 100644 --- a/MareSynchronos/Managers/PlayerManager.cs +++ b/MareSynchronos/Managers/PlayerManager.cs @@ -59,7 +59,7 @@ namespace MareSynchronos.Managers private void ApiController_Connected(object? sender, EventArgs args) { Logger.Debug("ApiController Connected"); - var apiTask = _apiController.SendCharacterName(_dalamudUtil.PlayerNameHashed); + var apiTask = _apiController.GetOnlineCharacters(); _lastSentHash = string.Empty; Task.WaitAll(apiTask); diff --git a/MareSynchronos/Models/CharacterData.cs b/MareSynchronos/Models/CharacterData.cs index 3515284..4e404d4 100644 --- a/MareSynchronos/Models/CharacterData.cs +++ b/MareSynchronos/Models/CharacterData.cs @@ -10,7 +10,15 @@ namespace MareSynchronos.Models public class CharacterData { [JsonProperty] - public List AllReplacements => FileReplacements.Where(f => f.HasFileReplacement).GroupBy(f => f.Hash).Select(g => g.First()).ToList(); + public List AllReplacements => FileReplacements.Where(f => f.HasFileReplacement).GroupBy(f => f.Hash).Select(g => + { + return new FileReplacement("") + { + ResolvedPath = g.First().ResolvedPath, + GamePaths = g.SelectMany(g => g.GamePaths).Distinct().ToList(), + Hash = g.First().Hash + }; + }).ToList(); [JsonProperty] public string CacheHash { get; set; } = string.Empty; diff --git a/MareSynchronos/Plugin.cs b/MareSynchronos/Plugin.cs index 4e5a74f..71f7bda 100644 --- a/MareSynchronos/Plugin.cs +++ b/MareSynchronos/Plugin.cs @@ -21,7 +21,6 @@ namespace MareSynchronos { private const string CommandName = "/mare"; private readonly ApiController _apiController; - private readonly ClientState _clientState; private readonly CommandManager _commandManager; private readonly Framework _framework; private readonly Configuration _configuration; @@ -29,7 +28,7 @@ namespace MareSynchronos private readonly IntroUi _introUi; private readonly IpcManager _ipcManager; public static DalamudPluginInterface PluginInterface { get; set; } - private readonly PluginUi _pluginUi; + private readonly MainUi _mainUi; private readonly WindowSystem _windowSystem; private PlayerManager? _playerManager; private readonly DalamudUtil _dalamudUtil; @@ -44,7 +43,6 @@ namespace MareSynchronos PluginInterface = pluginInterface; _commandManager = commandManager; _framework = framework; - _clientState = clientState; _configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration(); _configuration.Initialize(PluginInterface); _configuration.Migrate(); @@ -54,7 +52,9 @@ namespace MareSynchronos new FileCacheContext().Dispose(); // make sure db is initialized I guess // those can be initialized outside of game login - _apiController = new ApiController(_configuration); + _dalamudUtil = new DalamudUtil(clientState, objectTable, PlayerWatchFactory.Create(framework, clientState, objectTable)); + + _apiController = new ApiController(_configuration, _dalamudUtil); _ipcManager = new IpcManager(PluginInterface); _fileCacheManager = new FileCacheManager(_ipcManager, _configuration); @@ -62,31 +62,37 @@ namespace MareSynchronos var uiSharedComponent = new UiShared(_ipcManager, _apiController, _fileCacheManager, _fileDialogManager, _configuration); - _pluginUi = new PluginUi(_windowSystem, uiSharedComponent, _configuration, _apiController); + _mainUi = new MainUi(_windowSystem, uiSharedComponent, _configuration, _apiController); + _introUi = new IntroUi(_windowSystem, uiSharedComponent, _configuration, _fileCacheManager); - _introUi.FinishedRegistration += (_, _) => + _mainUi.SwitchFromMainUiToIntro += () => + { + _introUi.IsOpen = true; + _mainUi.IsOpen = false; + }; + _introUi.SwitchFromIntroToMainUi += () => { _introUi.IsOpen = false; - _pluginUi.IsOpen = true; + _mainUi.IsOpen = true; + _fileCacheManager.StartWatchers(); ReLaunchCharacterManager(); }; _downloadUi = new DownloadUi(_windowSystem, _configuration, _apiController); - _dalamudUtil = new DalamudUtil(_clientState, objectTable, PlayerWatchFactory.Create(framework, _clientState, objectTable)); - clientState.Login += ClientState_Login; - clientState.Logout += ClientState_Logout; + _dalamudUtil.LogIn += DalamudUtilOnLogIn; + _dalamudUtil.LogOut += DalamudUtilOnLogOut; _apiController.ChangingServers += ApiControllerOnChangingServers; - if (clientState.IsLoggedIn) + if (_dalamudUtil.IsLoggedIn) { - ClientState_Login(null, null!); + DalamudUtilOnLogIn(); } } private void ApiControllerOnChangingServers(object? sender, EventArgs e) { - _pluginUi.IsOpen = false; + _mainUi.IsOpen = false; _introUi.IsOpen = true; } @@ -98,10 +104,10 @@ namespace MareSynchronos _apiController?.Dispose(); _commandManager.RemoveHandler(CommandName); - _clientState.Login -= ClientState_Login; - _clientState.Logout -= ClientState_Logout; + _dalamudUtil.LogIn -= DalamudUtilOnLogIn; + _dalamudUtil.LogOut -= DalamudUtilOnLogOut; - _pluginUi?.Dispose(); + _mainUi?.Dispose(); _introUi?.Dispose(); _downloadUi?.Dispose(); @@ -113,7 +119,7 @@ namespace MareSynchronos } - private void ClientState_Login(object? sender, EventArgs e) + private void DalamudUtilOnLogIn() { Logger.Debug("Client login"); @@ -127,13 +133,15 @@ namespace MareSynchronos if (!_configuration.HasValidSetup()) { _introUi.IsOpen = true; + _configuration.FullPause = false; + _configuration.Save(); return; } ReLaunchCharacterManager(); } - private void ClientState_Logout(object? sender, EventArgs e) + private void DalamudUtilOnLogOut() { Logger.Debug("Client logout"); _characterCacheManager?.Dispose(); @@ -162,7 +170,7 @@ namespace MareSynchronos { var characterCacheFactory = new CharacterDataFactory(_dalamudUtil, _ipcManager); - _characterCacheManager = new CachedPlayersManager(_clientState, _framework, + _characterCacheManager = new CachedPlayersManager(_framework, _apiController, _dalamudUtil, _ipcManager); _playerManager = new PlayerManager(_apiController, _ipcManager, characterCacheFactory, _characterCacheManager, _dalamudUtil); @@ -183,14 +191,14 @@ namespace MareSynchronos { if (string.IsNullOrEmpty(args)) { - _pluginUi.Toggle(); + _mainUi.Toggle(); } } private void OpenConfigUi() { if (_configuration.HasValidSetup()) - _pluginUi.Toggle(); + _mainUi.Toggle(); else _introUi.Toggle(); } diff --git a/MareSynchronos/UI/IntroUI.cs b/MareSynchronos/UI/IntroUI.cs index a2871d4..140e5e4 100644 --- a/MareSynchronos/UI/IntroUI.cs +++ b/MareSynchronos/UI/IntroUI.cs @@ -16,7 +16,7 @@ namespace MareSynchronos.UI private readonly WindowSystem _windowSystem; private bool _readFirstPage = false; - public event EventHandler? FinishedRegistration; + public event SwitchUi? SwitchFromIntroToMainUi; public void Dispose() { @@ -157,7 +157,7 @@ namespace MareSynchronos.UI ImGui.Text("Service registration"); ImGui.SetWindowFontScale(1.0f); ImGui.Separator(); - if (_pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri)) + if (_pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri) && _uiShared.ShowClientSecret) { ImGui.Separator(); UiShared.TextWrapped(_pluginConfiguration.ClientSecret[_pluginConfiguration.ApiUri]); @@ -176,7 +176,7 @@ namespace MareSynchronos.UI ImGui.Separator(); if (ImGui.Button("Finish##finishIntro")) { - FinishedRegistration?.Invoke(null, EventArgs.Empty); + SwitchFromIntroToMainUi?.Invoke(); IsOpen = false; } } @@ -190,7 +190,7 @@ namespace MareSynchronos.UI "to verify who you are. It is directly tied to the UID you will be receiving. In case of loss, you will have to re-register an account."); UiShared.TextWrapped("Do not ever, under any circumstances, share your secret key to anyone! Likewise do not share your Mare Synchronos plugin configuration to anyone!"); ImGui.PopStyleColor(); - _uiShared.DrawServiceSelection(); + _uiShared.DrawServiceSelection(() => SwitchFromIntroToMainUi?.Invoke(), true); } } } diff --git a/MareSynchronos/UI/PluginUI.cs b/MareSynchronos/UI/MainUi.cs similarity index 91% rename from MareSynchronos/UI/PluginUI.cs rename to MareSynchronos/UI/MainUi.cs index 28f0f26..e24648a 100644 --- a/MareSynchronos/UI/PluginUI.cs +++ b/MareSynchronos/UI/MainUi.cs @@ -13,17 +13,19 @@ using MareSynchronos.Utils; namespace MareSynchronos.UI { - public class PluginUi : Window, IDisposable + public delegate void SwitchUi(); + public class MainUi : Window, IDisposable { private readonly Configuration _configuration; private readonly WindowSystem _windowSystem; private readonly ApiController _apiController; private readonly UiShared _uiShared; + public event SwitchUi? SwitchFromMainUiToIntro; - public PluginUi(WindowSystem windowSystem, + public MainUi(WindowSystem windowSystem, UiShared uiShared, Configuration configuration, ApiController apiController) : base("Mare Synchronos Settings", ImGuiWindowFlags.None) { - Logger.Debug("Creating " + nameof(PluginUi)); + Logger.Debug("Creating " + nameof(MainUi)); SizeConstraints = new WindowSizeConstraints() { @@ -40,7 +42,7 @@ namespace MareSynchronos.UI public void Dispose() { - Logger.Debug("Disposing " + nameof(PluginUi)); + Logger.Debug("Disposing " + nameof(MainUi)); _windowSystem.RemoveWindow(this); } @@ -79,9 +81,24 @@ namespace MareSynchronos.UI } else { - string error = _configuration.FullPause ? "Fully Paused" : "Service unavailable"; + string error = _configuration.FullPause ? "Fully Paused" : _apiController.ServerAlive ? "Unauthorized" : "Service unavailable"; ImGui.TextColored(ImGuiColors.DalamudRed, $"No UID ({error})"); ImGui.SetWindowFontScale(1.0f); + if (_apiController.ServerAlive && !_configuration.FullPause) + { + ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudRed); + UiShared.TextWrapped("Your account is not present on the service anymore or you are banned."); + ImGui.PopStyleColor(); + ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow); + UiShared.TextWrapped("If you think your secret key is just invalid, use the following button to reset the local secret key to be able to re-register. If you continue to see this message after registering, tough luck, asshole."); + ImGui.PopStyleColor(); + if (ImGui.Button("Reset Secret Key")) + { + _configuration.ClientSecret.Remove(_configuration.ApiUri); + _configuration.Save(); + SwitchFromMainUiToIntro?.Invoke(); + } + } } ImGui.Separator(); @@ -157,6 +174,7 @@ namespace MareSynchronos.UI Task.Run(() => _apiController.DeleteAccount()); ImGui.CloseCurrentPopup(); _deleteAccountPopupModalShown = false; + SwitchFromMainUiToIntro?.Invoke(); } ImGui.SameLine(); @@ -201,7 +219,7 @@ namespace MareSynchronos.UI if (marePaused) { - _uiShared.DrawServiceSelection(); + _uiShared.DrawServiceSelection(() => SwitchFromMainUiToIntro?.Invoke()); } diff --git a/MareSynchronos/UI/UIShared.cs b/MareSynchronos/UI/UIShared.cs index da5b28a..5d160c2 100644 --- a/MareSynchronos/UI/UIShared.cs +++ b/MareSynchronos/UI/UIShared.cs @@ -20,6 +20,7 @@ namespace MareSynchronos.UI private readonly FileDialogManager _fileDialogManager; private readonly Configuration _pluginConfiguration; public long FileCacheSize => _fileCacheManager.FileCacheSize; + public bool ShowClientSecret = true; public UiShared(IpcManager ipcManager, ApiController apiController, FileCacheManager fileCacheManager, FileDialogManager fileDialogManager, Configuration pluginConfiguration) { @@ -78,12 +79,12 @@ namespace MareSynchronos.UI } } - public void PrintServerState() + public void PrintServerState(bool isIntroUi = false) { var serverName = _apiController.ServerDictionary.ContainsKey(_pluginConfiguration.ApiUri) ? _apiController.ServerDictionary[_pluginConfiguration.ApiUri] : _pluginConfiguration.ApiUri; - ImGui.Text("Service status of \"" + serverName + "\":"); + ImGui.Text("Service " + serverName + ":"); ImGui.SameLine(); var color = _apiController.ServerAlive ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed; ImGui.TextColored(color, _apiController.ServerAlive ? "Available" : "Unavailable"); @@ -94,7 +95,7 @@ namespace MareSynchronos.UI ImGui.SameLine(); ImGui.TextColored(ImGuiColors.ParsedGreen, _apiController.OnlineUsers.ToString()); ImGui.SameLine(); - ImGui.Text("Users Online (server-wide)"); + ImGui.Text("Users Online" + (!isIntroUi ? " (server-wide)" : string.Empty)); ImGui.SameLine(); ImGui.Text(")"); } @@ -154,8 +155,9 @@ namespace MareSynchronos.UI private int _serverSelectionIndex = 0; private string _customServerName = ""; private string _customServerUri = ""; + private bool _enterSecretKey = false; - public void DrawServiceSelection() + public void DrawServiceSelection(Action? callBackOnExit = null, bool isIntroUi = false) { string[] comboEntries = _apiController.ServerDictionary.Values.ToArray(); _serverSelectionIndex = Array.IndexOf(_apiController.ServerDictionary.Keys.ToArray(), _pluginConfiguration.ApiUri); @@ -186,21 +188,50 @@ namespace MareSynchronos.UI if (ImGui.Button(FontAwesomeIcon.Trash.ToIconString() + "##deleteService")) { _pluginConfiguration.CustomServerList.Remove(_pluginConfiguration.ApiUri); - _pluginConfiguration.ApiUri = ApiController.MainServiceUri; + _pluginConfiguration.ApiUri = _apiController.ServerDictionary.First().Key; _pluginConfiguration.Save(); } ImGui.PopFont(); } - PrintServerState(); + if (ImGui.TreeNode("Add Custom Service")) + { + ImGui.SetNextItemWidth(250); + ImGui.InputText("Custom Service Name", ref _customServerName, 255); + ImGui.SetNextItemWidth(250); + ImGui.InputText("Custom Service Address", ref _customServerUri, 255); + if (ImGui.Button("Add Custom Service")) + { + if (!string.IsNullOrEmpty(_customServerUri) + && !string.IsNullOrEmpty(_customServerName) + && !_pluginConfiguration.CustomServerList.ContainsValue(_customServerName) + && !_pluginConfiguration.CustomServerList.ContainsKey(_customServerUri)) + { + _pluginConfiguration.CustomServerList[_customServerUri] = _customServerName; + _customServerUri = string.Empty; + _customServerName = string.Empty; + _pluginConfiguration.Save(); + } + } + ImGui.TreePop(); + } + + PrintServerState(isIntroUi); if (_apiController.ServerAlive && !_pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri)) { - if (ImGui.Button("Register")) + if (!_enterSecretKey) { - _pluginConfiguration.FullPause = false; - _pluginConfiguration.Save(); - Task.Run(_apiController.Register); + if (ImGui.Button("Register")) + { + _pluginConfiguration.FullPause = false; + _pluginConfiguration.Save(); + Task.Run(_apiController.Register); + ShowClientSecret = true; + callBackOnExit?.Invoke(); + } + + ImGui.SameLine(); } } else @@ -217,28 +248,31 @@ namespace MareSynchronos.UI } } - if (ImGui.TreeNode("Custom Service")) + string checkboxText = _pluginConfiguration.ClientSecret.ContainsKey(_pluginConfiguration.ApiUri) + ? "I want to switch accounts" + : "I already have an account"; + ImGui.Checkbox(checkboxText, ref _enterSecretKey); + + if (_enterSecretKey) { - ImGui.SetNextItemWidth(250); - ImGui.InputText("Custom Service Name", ref _customServerName, 255); - ImGui.SetNextItemWidth(250); - ImGui.InputText("Custom Service Address", ref _customServerUri, 255); - if (ImGui.Button("Add Custom Service")) + ImGui.SetNextItemWidth(400); + ImGui.InputText("Enter Secret Key", ref _secretKey, 255); + ImGui.SameLine(); + if (ImGui.Button("Save")) { - if (!string.IsNullOrEmpty(_customServerUri) - && !string.IsNullOrEmpty(_customServerName) - && !_pluginConfiguration.CustomServerList.ContainsValue(_customServerName)) - { - _pluginConfiguration.CustomServerList[_customServerUri] = _customServerName; - _customServerUri = string.Empty; - _customServerName = string.Empty; - _pluginConfiguration.Save(); - } + _pluginConfiguration.ClientSecret[_pluginConfiguration.ApiUri] = _secretKey; + _pluginConfiguration.Save(); + _secretKey = string.Empty; + Task.Run(_apiController.CreateConnections); + ShowClientSecret = false; + _enterSecretKey = false; + callBackOnExit?.Invoke(); } - ImGui.TreePop(); } } + private string _secretKey = ""; + public static void DrawHelpText(string helpText) { ImGui.SameLine(); diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index e8affad..176b706 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -13,12 +13,17 @@ namespace MareSynchronos.Utils { public delegate void PlayerChange(Character actor); + public delegate void LogIn(); + public delegate void LogOut(); + public class DalamudUtil : IDisposable { private readonly ClientState _clientState; private readonly ObjectTable _objectTable; private readonly IPlayerWatcher _watcher; public event PlayerChange? PlayerChanged; + public event LogIn? LogIn; + public event LogOut? LogOut; public DalamudUtil(ClientState clientState, ObjectTable objectTable, IPlayerWatcher watcher) { @@ -27,8 +32,26 @@ namespace MareSynchronos.Utils _watcher = watcher; _watcher.Enable(); _watcher.PlayerChanged += WatcherOnPlayerChanged; + _clientState.Login += ClientStateOnLogin; + _clientState.Logout += ClientStateOnLogout; + if (IsLoggedIn) + { + ClientStateOnLogin(null, EventArgs.Empty); + } } + private void ClientStateOnLogout(object? sender, EventArgs e) + { + LogOut?.Invoke(); + } + + private void ClientStateOnLogin(object? sender, EventArgs e) + { + LogIn?.Invoke(); + } + + public bool IsLoggedIn => _clientState.IsLoggedIn; + private void WatcherOnPlayerChanged(Character actor) { PlayerChanged?.Invoke(actor); diff --git a/MareSynchronos/WebAPI/ApiController.cs b/MareSynchronos/WebAPI/ApiController.cs index 34fa886..06e4086 100644 --- a/MareSynchronos/WebAPI/ApiController.cs +++ b/MareSynchronos/WebAPI/ApiController.cs @@ -27,6 +27,7 @@ namespace MareSynchronos.WebAPI #endif private readonly Configuration _pluginConfiguration; + private readonly DalamudUtil _dalamudUtil; private CancellationTokenSource _cts; @@ -38,16 +39,33 @@ namespace MareSynchronos.WebAPI private HubConnection? _userHub; - public ApiController(Configuration pluginConfiguration) + public ApiController(Configuration pluginConfiguration, DalamudUtil dalamudUtil) { Logger.Debug("Creating " + nameof(ApiController)); _pluginConfiguration = pluginConfiguration; + _dalamudUtil = dalamudUtil; _cts = new CancellationTokenSource(); + _dalamudUtil.LogIn += DalamudUtilOnLogIn; + _dalamudUtil.LogOut += DalamudUtilOnLogOut; + if (_dalamudUtil.IsLoggedIn) + { + DalamudUtilOnLogIn(); + } + } + + private void DalamudUtilOnLogOut() + { + Task.Run(async () => await StopAllConnections(_cts.Token)); + } + + private void DalamudUtilOnLogIn() + { Task.Run(CreateConnections); } + public event EventHandler? ChangingServers; public event EventHandler? CharacterReceived; @@ -153,6 +171,9 @@ namespace MareSynchronos.WebAPI { Logger.Debug("Disposing " + nameof(ApiController)); + _dalamudUtil.LogIn -= DalamudUtilOnLogIn; + _dalamudUtil.LogOut -= DalamudUtilOnLogOut; + Task.Run(async () => await StopAllConnections(_cts.Token)); _cts?.Cancel(); } @@ -165,6 +186,7 @@ namespace MareSynchronos.WebAPI if (!string.IsNullOrEmpty(SecretKey) && !_pluginConfiguration.FullPause) { options.Headers.Add("Authorization", SecretKey); + options.Headers.Add("CharacterNameHash", _dalamudUtil.PlayerNameHashed); } options.Transports = HttpTransportType.WebSockets; @@ -211,18 +233,21 @@ namespace MareSynchronos.WebAPI _heartbeatHub.Reconnected -= HeartbeatHubOnReconnected; _heartbeatHub.Reconnecting += HeartbeatHubOnReconnecting; await _heartbeatHub.DisposeAsync(); + _heartbeatHub = null; } if (_fileHub is { State: HubConnectionState.Connected or HubConnectionState.Connecting or HubConnectionState.Reconnecting }) { await _fileHub.StopAsync(token); await _fileHub.DisposeAsync(); + _fileHub = null; } if (_userHub is { State: HubConnectionState.Connected or HubConnectionState.Connecting or HubConnectionState.Reconnecting }) { await _userHub.StopAsync(token); await _userHub.DisposeAsync(); + _userHub = null; } } } @@ -242,6 +267,7 @@ namespace MareSynchronos.WebAPI public async Task DeleteAccount() { _pluginConfiguration.ClientSecret.Remove(ApiUri); + _pluginConfiguration.Save(); await _fileHub!.SendAsync("DeleteAllFiles"); await _userHub!.SendAsync("DeleteAccount"); await CreateConnections(); @@ -273,8 +299,8 @@ namespace MareSynchronos.WebAPI foreach (var file in fileReplacementDto) { - var fileSize = await _fileHub!.InvokeAsync("GetFileSize", file.Hash, ct); - CurrentDownloads[file.Hash] = (0, fileSize); + var downloadFileDto = await _fileHub!.InvokeAsync("GetFileSize", file.Hash, ct); + CurrentDownloads[file.Hash] = (0, downloadFileDto.Size); } List downloadedHashes = new(); @@ -361,23 +387,23 @@ namespace MareSynchronos.WebAPI var uploadToken = _uploadCancellationTokenSource.Token; Logger.Verbose("New Token Created"); - var filesToUpload = await _fileHub!.InvokeAsync>("SendFiles", character.FileReplacements.Select(c => c.Hash).Distinct(), uploadToken); + var filesToUpload = await _fileHub!.InvokeAsync>("SendFiles", character.FileReplacements.Select(c => c.Hash).Distinct(), uploadToken); IsUploading = true; - foreach (var file in filesToUpload) + foreach (var file in filesToUpload.Where(f => f.IsForbidden == false)) { await using var db = new FileCacheContext(); - CurrentUploads[file] = (0, new FileInfo(db.FileCaches.First(f => f.Hash == file).Filepath).Length); + CurrentUploads[file.Hash] = (0, new FileInfo(db.FileCaches.First(f => f.Hash == file.Hash).Filepath).Length); } Logger.Verbose("Compressing and uploading files"); foreach (var file in filesToUpload) { Logger.Verbose("Compressing and uploading " + file); - var data = await GetCompressedFileData(file, uploadToken); + var data = await GetCompressedFileData(file.Hash, uploadToken); CurrentUploads[data.Item1] = (0, data.Item2.Length); - _ = UploadFile(data.Item2, file, uploadToken); + _ = UploadFile(data.Item2, file.Hash, uploadToken); if (!uploadToken.IsCancellationRequested) continue; Logger.Warn("Cancel in filesToUpload loop detected"); CurrentUploads.Clear(); @@ -411,9 +437,9 @@ namespace MareSynchronos.WebAPI _uploadCancellationTokenSource = null; } - public async Task> SendCharacterName(string hashedName) + public async Task> GetOnlineCharacters() { - return await _userHub!.InvokeAsync>("SendCharacterNameHash", hashedName); + return await _userHub!.InvokeAsync>("GetOnlineCharacters"); } public async Task SendPairedClientAddition(string uid)