diff --git a/MareSynchronos/UI/UIShared.cs b/MareSynchronos/UI/UIShared.cs index eda42d3..a141ada 100644 --- a/MareSynchronos/UI/UIShared.cs +++ b/MareSynchronos/UI/UIShared.cs @@ -96,7 +96,11 @@ namespace MareSynchronos.UI ImGui.SameLine(); ImGui.TextColored(ImGuiColors.ParsedGreen, _apiController.OnlineUsers.ToString()); ImGui.SameLine(); - ImGui.Text("Users Online" + (!isIntroUi ? " (server-wide)" : string.Empty)); + ImGui.Text("Users Online,"); + ImGui.SameLine(); + ColorText(_apiController.SystemInfoDto.CpuUsage.ToString("0.00") + "%", GetCpuLoadColor(_apiController.SystemInfoDto.CpuUsage)); + ImGui.SameLine(); + ImGui.Text("Load"); ImGui.SameLine(); ImGui.Text(")"); } @@ -123,6 +127,9 @@ namespace MareSynchronos.UI ImGui.PopTextWrapPos(); } + public static Vector4 GetCpuLoadColor(double input) => input < 50 ? ImGuiColors.ParsedGreen : + input < 90 ? ImGuiColors.DalamudYellow : ImGuiColors.DalamudRed; + public static Vector4 GetBoolColor(bool input) => input ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed; public static Vector4 UploadColor((long, long) data) => data.Item1 == 0 ? ImGuiColors.DalamudGrey : diff --git a/MareSynchronos/Utils/DalamudUtil.cs b/MareSynchronos/Utils/DalamudUtil.cs index 68e7b81..95dddc2 100644 --- a/MareSynchronos/Utils/DalamudUtil.cs +++ b/MareSynchronos/Utils/DalamudUtil.cs @@ -58,7 +58,7 @@ namespace MareSynchronos.Utils public bool IsLoggedIn => _clientState.IsLoggedIn; - public bool IsPlayerPresent => _clientState.LocalPlayer != null; + public bool IsPlayerPresent => _clientState.LocalPlayer != null && _clientState.LocalPlayer.IsValid(); public string PlayerName => _clientState.LocalPlayer?.Name.ToString() ?? "--"; diff --git a/MareSynchronos/WebAPI/ApiController.Connectivity.cs b/MareSynchronos/WebAPI/ApiController.Connectivity.cs index b6932e6..3531a3d 100644 --- a/MareSynchronos/WebAPI/ApiController.Connectivity.cs +++ b/MareSynchronos/WebAPI/ApiController.Connectivity.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using Dalamud.Logging; using MareSynchronos.API; using MareSynchronos.Utils; using MareSynchronos.WebAPI.Utils; @@ -38,7 +40,7 @@ namespace MareSynchronos.WebAPI private HubConnection? _fileHub; - private HubConnection? _heartbeatHub; + private HubConnection? _connectionHub; private HubConnection? _adminHub; @@ -46,6 +48,7 @@ namespace MareSynchronos.WebAPI private HubConnection? _userHub; private ConnectionDto? _connectionDto; + public SystemInfoDto SystemInfoDto { get; private set; } = new(); public bool IsModerator => (_connectionDto?.IsAdmin ?? false) || (_connectionDto?.IsModerator ?? false); public bool IsAdmin => _connectionDto?.IsAdmin ?? false; @@ -116,7 +119,7 @@ namespace MareSynchronos.WebAPI : "-"; public bool ServerAlive => - (_heartbeatHub?.State ?? HubConnectionState.Disconnected) == HubConnectionState.Connected; + (_connectionHub?.State ?? HubConnectionState.Disconnected) == HubConnectionState.Connected; public Dictionary ServerDictionary => new Dictionary() { { MainServiceUri, MainServer } } @@ -125,22 +128,25 @@ namespace MareSynchronos.WebAPI public string UID => _connectionDto?.UID ?? string.Empty; private string ApiUri => _pluginConfiguration.ApiUri; - public int OnlineUsers { get; private set; } + public int OnlineUsers => SystemInfoDto.OnlineUsers; public ServerState ServerState { get { + var supportedByServer = SupportedServerVersions.Contains(_connectionDto?.ServerVersion ?? 0); + bool hasUid = !string.IsNullOrEmpty(UID); if (_pluginConfiguration.FullPause) return ServerState.Disconnected; if (!ServerAlive) return ServerState.Offline; - if (ServerAlive && SupportedServerVersions.Contains(_connectionDto?.ServerVersion ?? 0) && string.IsNullOrEmpty(UID)) - return ServerState.Unauthorized; - if (ServerAlive && !SupportedServerVersions.Contains(_connectionDto?.ServerVersion ?? 0) && !string.IsNullOrEmpty(UID)) + if (!hasUid && _pluginConfiguration.ClientSecret.ContainsKey(ApiUri)) + return ServerState.Unauthorized; + if (!supportedByServer) return ServerState.VersionMisMatch; - if (ServerAlive && SupportedServerVersions.Contains(_connectionDto?.ServerVersion ?? 0) && !string.IsNullOrEmpty(UID)) + if (supportedByServer && hasUid) return ServerState.Connected; + return ServerState.NoAccount; } } @@ -154,25 +160,33 @@ namespace MareSynchronos.WebAPI _connectionCancellationTokenSource.Cancel(); _connectionCancellationTokenSource = new CancellationTokenSource(); var token = _connectionCancellationTokenSource.Token; - - while (!ServerAlive && !token.IsCancellationRequested) + while (ServerState is not ServerState.Connected && !token.IsCancellationRequested) { + await StopAllConnections(_connectionCancellationTokenSource.Token); + try { - if (_dalamudUtil.PlayerCharacter == null) throw new ArgumentException("Player not initialized"); Logger.Debug("Building connection"); - _heartbeatHub = BuildHubConnection(ConnectionHubAPI.Path); + + while (!_dalamudUtil.IsPlayerPresent && !token.IsCancellationRequested) + { + Logger.Debug("Player not loaded in yet, waiting"); + await Task.Delay(TimeSpan.FromSeconds(1), token); + } + + if (token.IsCancellationRequested) break; + + _connectionHub = BuildHubConnection(ConnectionHubAPI.Path); _userHub = BuildHubConnection(UserHubAPI.Path); _fileHub = BuildHubConnection(FilesHubAPI.Path); _adminHub = BuildHubConnection(AdminHubAPI.Path); - await _heartbeatHub.StartAsync(token); + await _connectionHub.StartAsync(token); await _userHub.StartAsync(token); await _fileHub.StartAsync(token); await _adminHub.StartAsync(token); - OnlineUsers = await _userHub.InvokeAsync(UserHubAPI.InvokeGetOnlineUsers, token); - _userHub.On(UserHubAPI.OnUsersOnline, (count) => OnlineUsers = count); + _connectionHub.On(ConnectionHubAPI.OnUpdateSystemInfo, (dto) => SystemInfoDto = dto); if (_pluginConfiguration.FullPause) { @@ -180,36 +194,51 @@ namespace MareSynchronos.WebAPI return; } - _connectionDto = await _heartbeatHub.InvokeAsync(ConnectionHubAPI.InvokeHeartbeat, token); + _connectionDto = + await _connectionHub.InvokeAsync(ConnectionHubAPI.InvokeHeartbeat, token); if (ServerState is ServerState.Connected) // user is authorized && server is legit { Logger.Debug("Initializing data"); - _userHub.On(UserHubAPI.OnUpdateClientPairs, UpdateLocalClientPairsCallback); - _userHub.On(UserHubAPI.OnReceiveCharacterData, ReceiveCharacterDataCallback); + _userHub.On(UserHubAPI.OnUpdateClientPairs, + UpdateLocalClientPairsCallback); + _userHub.On(UserHubAPI.OnReceiveCharacterData, + ReceiveCharacterDataCallback); _userHub.On(UserHubAPI.OnRemoveOnlinePairedPlayer, (s) => PairedClientOffline?.Invoke(s)); _userHub.On(UserHubAPI.OnAddOnlinePairedPlayer, (s) => PairedClientOnline?.Invoke(s)); _adminHub.On(AdminHubAPI.OnForcedReconnect, UserForcedReconnectCallback); - PairedClients = await _userHub!.InvokeAsync>(UserHubAPI.InvokeGetPairedClients, token); + PairedClients = + await _userHub!.InvokeAsync>(UserHubAPI.InvokeGetPairedClients, token); - _heartbeatHub.Closed += HeartbeatHubOnClosed; - _heartbeatHub.Reconnected += HeartbeatHubOnReconnected; - _heartbeatHub.Reconnecting += HeartbeatHubOnReconnecting; + _connectionHub.Closed += ConnectionHubOnClosed; + _connectionHub.Reconnected += ConnectionHubOnReconnected; + _connectionHub.Reconnecting += ConnectionHubOnReconnecting; if (IsModerator) { - AdminForbiddenFiles = await _adminHub.InvokeAsync>(AdminHubAPI.InvokeGetForbiddenFiles, token); - AdminBannedUsers = await _adminHub.InvokeAsync>(AdminHubAPI.InvokeGetBannedUsers, token); - _adminHub.On(AdminHubAPI.OnUpdateOrAddBannedUser, UpdateOrAddBannedUserCallback); + AdminForbiddenFiles = + await _adminHub.InvokeAsync>(AdminHubAPI.InvokeGetForbiddenFiles, + token); + AdminBannedUsers = + await _adminHub.InvokeAsync>(AdminHubAPI.InvokeGetBannedUsers, + token); + _adminHub.On(AdminHubAPI.OnUpdateOrAddBannedUser, + UpdateOrAddBannedUserCallback); _adminHub.On(AdminHubAPI.OnDeleteBannedUser, DeleteBannedUserCallback); - _adminHub.On(AdminHubAPI.OnUpdateOrAddForbiddenFile, UpdateOrAddForbiddenFileCallback); - _adminHub.On(AdminHubAPI.OnDeleteForbiddenFile, DeleteForbiddenFileCallback); + _adminHub.On(AdminHubAPI.OnUpdateOrAddForbiddenFile, + UpdateOrAddForbiddenFileCallback); + _adminHub.On(AdminHubAPI.OnDeleteForbiddenFile, + DeleteForbiddenFileCallback); } Connected?.Invoke(); } + else if (ServerState is ServerState.VersionMisMatch or ServerState.NoAccount or ServerState.Unauthorized) + { + break; + } } catch (Exception ex) { @@ -249,7 +278,7 @@ namespace MareSynchronos.WebAPI .Build(); } - private Task HeartbeatHubOnClosed(Exception? arg) + private Task ConnectionHubOnClosed(Exception? arg) { CurrentUploads.Clear(); CurrentDownloads.Clear(); @@ -259,16 +288,15 @@ namespace MareSynchronos.WebAPI return Task.CompletedTask; } - private Task HeartbeatHubOnReconnected(string? arg) + private Task ConnectionHubOnReconnected(string? arg) { Logger.Debug("Connection restored"); - OnlineUsers = _userHub!.InvokeAsync(UserHubAPI.InvokeGetOnlineUsers).Result; - _connectionDto = _heartbeatHub!.InvokeAsync(ConnectionHubAPI.InvokeHeartbeat).Result; + _connectionDto = _connectionHub!.InvokeAsync(ConnectionHubAPI.InvokeHeartbeat).Result; Connected?.Invoke(); return Task.CompletedTask; } - private Task HeartbeatHubOnReconnecting(Exception? arg) + private Task ConnectionHubOnReconnecting(Exception? arg) { CurrentUploads.Clear(); CurrentDownloads.Clear(); @@ -281,14 +309,14 @@ namespace MareSynchronos.WebAPI private async Task StopAllConnections(CancellationToken token) { Logger.Verbose("Stopping all connections"); - if (_heartbeatHub is not null) + if (_connectionHub is not null) { - await _heartbeatHub.StopAsync(token); - _heartbeatHub.Closed -= HeartbeatHubOnClosed; - _heartbeatHub.Reconnected -= HeartbeatHubOnReconnected; - _heartbeatHub.Reconnecting += HeartbeatHubOnReconnecting; - await _heartbeatHub.DisposeAsync(); - _heartbeatHub = null; + await _connectionHub.StopAsync(token); + _connectionHub.Closed -= ConnectionHubOnClosed; + _connectionHub.Reconnected -= ConnectionHubOnReconnected; + _connectionHub.Reconnecting += ConnectionHubOnReconnecting; + await _connectionHub.DisposeAsync(); + _connectionHub = null; } if (_fileHub is not null)