Refactoring Claims, add Server Side Messaging (#33)
* cache JWT by ApiUri, CharaIdent, SecretKey, refactor auth flow to new api * add server side message handling * update client to mainline api Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
2
MareAPI
2
MareAPI
Submodule MareAPI updated: 6645eaf63f...d361cfa3b9
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors></Authors>
|
<Authors></Authors>
|
||||||
<Company></Company>
|
<Company></Company>
|
||||||
<Version>0.5.21</Version>
|
<Version>0.5.22</Version>
|
||||||
<Description></Description>
|
<Description></Description>
|
||||||
<Copyright></Copyright>
|
<Copyright></Copyright>
|
||||||
<PackageProjectUrl>https://github.com/Penumbra-Sync/client</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/Penumbra-Sync/client</PackageProjectUrl>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ using MareSynchronos.UI;
|
|||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using MareSynchronos.FileCache;
|
using MareSynchronos.FileCache;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Game.Gui;
|
||||||
|
|
||||||
namespace MareSynchronos;
|
namespace MareSynchronos;
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
private const string CommandName = "/mare";
|
private const string CommandName = "/mare";
|
||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
private readonly CommandManager _commandManager;
|
private readonly CommandManager _commandManager;
|
||||||
|
private readonly ChatGui _chatGui;
|
||||||
private readonly Configuration _configuration;
|
private readonly Configuration _configuration;
|
||||||
private readonly PeriodicFileScanner _periodicFileScanner;
|
private readonly PeriodicFileScanner _periodicFileScanner;
|
||||||
private readonly IntroUi _introUi;
|
private readonly IntroUi _introUi;
|
||||||
@@ -44,7 +45,8 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
|
|
||||||
|
|
||||||
public Plugin(DalamudPluginInterface pluginInterface, CommandManager commandManager,
|
public Plugin(DalamudPluginInterface pluginInterface, CommandManager commandManager,
|
||||||
Framework framework, ObjectTable objectTable, ClientState clientState, Condition condition)
|
Framework framework, ObjectTable objectTable, ClientState clientState, Condition condition,
|
||||||
|
ChatGui chatGui)
|
||||||
{
|
{
|
||||||
Logger.Debug("Launching " + Name);
|
Logger.Debug("Launching " + Name);
|
||||||
_pluginInterface = pluginInterface;
|
_pluginInterface = pluginInterface;
|
||||||
@@ -59,7 +61,7 @@ public sealed class Plugin : IDalamudPlugin
|
|||||||
_windowSystem = new WindowSystem("MareSynchronos");
|
_windowSystem = new WindowSystem("MareSynchronos");
|
||||||
|
|
||||||
// those can be initialized outside of game login
|
// those can be initialized outside of game login
|
||||||
_dalamudUtil = new DalamudUtil(clientState, objectTable, framework, condition);
|
_dalamudUtil = new DalamudUtil(clientState, objectTable, framework, condition, chatGui);
|
||||||
|
|
||||||
_ipcManager = new IpcManager(_pluginInterface, _dalamudUtil);
|
_ipcManager = new IpcManager(_pluginInterface, _dalamudUtil);
|
||||||
_fileDialogManager = new FileDialogManager();
|
_fileDialogManager = new FileDialogManager();
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ public class CompactUi : Window, IDisposable
|
|||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed, "Not connected to any server");
|
ImGui.TextColored(ImGuiColors.DalamudRed, "Not connected to any server");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (printShard)
|
if (printShard)
|
||||||
{
|
{
|
||||||
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().ItemSpacing.Y);
|
ImGui.SetCursorPosY(ImGui.GetCursorPosY() - ImGui.GetStyle().ItemSpacing.Y);
|
||||||
@@ -631,7 +631,7 @@ public class CompactUi : Window, IDisposable
|
|||||||
return _apiController.ServerState switch
|
return _apiController.ServerState switch
|
||||||
{
|
{
|
||||||
ServerState.Disconnected => "You are currently disconnected from the Mare Synchronos server.",
|
ServerState.Disconnected => "You are currently disconnected from the Mare Synchronos server.",
|
||||||
ServerState.Unauthorized => "The account associated with your used secret key is not present on the server anymore or you are tempbanned. To check the latter disconnect and reconnect in 15 minutes.",
|
ServerState.Unauthorized => "Server Response: " + _apiController.AuthFailureMessage,
|
||||||
ServerState.Offline => "Your selected Mare Synchronos server is currently offline.",
|
ServerState.Offline => "Your selected Mare Synchronos server is currently offline.",
|
||||||
ServerState.VersionMisMatch =>
|
ServerState.VersionMisMatch =>
|
||||||
"Your plugin or the server you are connecting to is out of date. Please update your plugin now. If you already did so, contact the server provider to update their server to the latest version.",
|
"Your plugin or the server you are connecting to is out of date. Please update your plugin now. If you already did so, contact the server provider to update their server to the latest version.",
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dalamud.Game;
|
using Dalamud.Game;
|
||||||
@@ -9,6 +8,8 @@ using Dalamud.Game.ClientState;
|
|||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
|
using Dalamud.Game.Gui;
|
||||||
|
using Dalamud.Game.Text.SeStringHandling;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
|
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ public class DalamudUtil : IDisposable
|
|||||||
private readonly ObjectTable _objectTable;
|
private readonly ObjectTable _objectTable;
|
||||||
private readonly Framework _framework;
|
private readonly Framework _framework;
|
||||||
private readonly Condition _condition;
|
private readonly Condition _condition;
|
||||||
|
private readonly ChatGui _chatGui;
|
||||||
|
|
||||||
public event LogIn? LogIn;
|
public event LogIn? LogIn;
|
||||||
public event LogOut? LogOut;
|
public event LogOut? LogOut;
|
||||||
@@ -54,12 +56,13 @@ public class DalamudUtil : IDisposable
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DalamudUtil(ClientState clientState, ObjectTable objectTable, Framework framework, Condition condition)
|
public DalamudUtil(ClientState clientState, ObjectTable objectTable, Framework framework, Condition condition, ChatGui chatGui)
|
||||||
{
|
{
|
||||||
_clientState = clientState;
|
_clientState = clientState;
|
||||||
_objectTable = objectTable;
|
_objectTable = objectTable;
|
||||||
_framework = framework;
|
_framework = framework;
|
||||||
_condition = condition;
|
_condition = condition;
|
||||||
|
_chatGui = chatGui;
|
||||||
_clientState.Login += ClientStateOnLogin;
|
_clientState.Login += ClientStateOnLogin;
|
||||||
_clientState.Logout += ClientStateOnLogout;
|
_clientState.Logout += ClientStateOnLogout;
|
||||||
_framework.Update += FrameworkOnUpdate;
|
_framework.Update += FrameworkOnUpdate;
|
||||||
@@ -70,6 +73,24 @@ public class DalamudUtil : IDisposable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void PrintInfoChat(string message)
|
||||||
|
{
|
||||||
|
SeStringBuilder se = new SeStringBuilder().AddText("[Mare Synchronos] Info: ").AddItalics(message);
|
||||||
|
_chatGui.Print(se.BuiltString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrintWarnChat(string message)
|
||||||
|
{
|
||||||
|
SeStringBuilder se = new SeStringBuilder().AddText("[Mare Synchronos] ").AddUiForeground("Warning: " + message, 31).AddUiForegroundOff();
|
||||||
|
_chatGui.Print(se.BuiltString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PrintErrorChat(string message)
|
||||||
|
{
|
||||||
|
SeStringBuilder se = new SeStringBuilder().AddText("[Mare Synchronos] ").AddUiForeground("Error: ", 534).AddItalicsOn().AddUiForeground(message, 534).AddUiForegroundOff().AddItalicsOff();
|
||||||
|
_chatGui.Print(se.BuiltString);
|
||||||
|
}
|
||||||
|
|
||||||
private void FrameworkOnUpdate(Framework framework)
|
private void FrameworkOnUpdate(Framework framework)
|
||||||
{
|
{
|
||||||
if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51] || IsInGpose)
|
if (_condition[ConditionFlag.BetweenAreas] || _condition[ConditionFlag.BetweenAreas51] || IsInGpose)
|
||||||
|
|||||||
@@ -30,12 +30,24 @@ internal class Logger : ILogger
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Error(string msg, Exception ex)
|
||||||
|
{
|
||||||
|
var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown";
|
||||||
|
PluginLog.Error($"[{caller}] {msg} {Environment.NewLine} Exception: {ex.Message} {Environment.NewLine} {ex.StackTrace}");
|
||||||
|
}
|
||||||
|
|
||||||
public static void Warn(string msg, Exception ex)
|
public static void Warn(string msg, Exception ex)
|
||||||
{
|
{
|
||||||
var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown";
|
var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown";
|
||||||
PluginLog.Warning($"[{caller}] {msg} {Environment.NewLine} Exception: {ex.Message} {Environment.NewLine} {ex.StackTrace}");
|
PluginLog.Warning($"[{caller}] {msg} {Environment.NewLine} Exception: {ex.Message} {Environment.NewLine} {ex.StackTrace}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Error(string msg)
|
||||||
|
{
|
||||||
|
var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown";
|
||||||
|
PluginLog.Error($"[{caller}] {msg}");
|
||||||
|
}
|
||||||
|
|
||||||
public static void Warn(string warn)
|
public static void Warn(string warn)
|
||||||
{
|
{
|
||||||
var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown";
|
var caller = new StackTrace().GetFrame(1)?.GetMethod()?.ReflectedType?.Name ?? "Unknown";
|
||||||
|
|||||||
@@ -78,6 +78,12 @@ public partial class ApiController
|
|||||||
_mareHub!.On(nameof(Client_AdminUpdateOrAddForbiddenFile), act);
|
_mareHub!.On(nameof(Client_AdminUpdateOrAddForbiddenFile), act);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnReceiveServerMessage(Action<MessageSeverity, string> act)
|
||||||
|
{
|
||||||
|
if (_initialized) return;
|
||||||
|
_mareHub!.On(nameof(Client_ReceiveServerMessage), act);
|
||||||
|
}
|
||||||
|
|
||||||
public Task Client_UserUpdateClientPairs(ClientPairDto dto)
|
public Task Client_UserUpdateClientPairs(ClientPairDto dto)
|
||||||
{
|
{
|
||||||
var entry = PairedClients.SingleOrDefault(e => string.Equals(e.OtherUID, dto.OtherUID, System.StringComparison.Ordinal));
|
var entry = PairedClients.SingleOrDefault(e => string.Equals(e.OtherUID, dto.OtherUID, System.StringComparison.Ordinal));
|
||||||
@@ -213,4 +219,25 @@ public partial class ApiController
|
|||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task Client_ReceiveServerMessage(MessageSeverity severity, string message)
|
||||||
|
{
|
||||||
|
switch (severity)
|
||||||
|
{
|
||||||
|
case MessageSeverity.Error:
|
||||||
|
Logger.Error(message);
|
||||||
|
_dalamudUtil.PrintErrorChat(message);
|
||||||
|
break;
|
||||||
|
case MessageSeverity.Warning:
|
||||||
|
Logger.Warn(message);
|
||||||
|
_dalamudUtil.PrintWarnChat(message);
|
||||||
|
break;
|
||||||
|
case MessageSeverity.Information:
|
||||||
|
Logger.Info(message);
|
||||||
|
_dalamudUtil.PrintInfoChat(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ using MareSynchronos.FileCache;
|
|||||||
using MareSynchronos.Utils;
|
using MareSynchronos.Utils;
|
||||||
using MareSynchronos.WebAPI.Utils;
|
using MareSynchronos.WebAPI.Utils;
|
||||||
using Microsoft.AspNetCore.Http.Connections;
|
using Microsoft.AspNetCore.Http.Connections;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
|
||||||
using Microsoft.AspNetCore.SignalR.Client;
|
using Microsoft.AspNetCore.SignalR.Client;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -20,6 +19,8 @@ namespace MareSynchronos.WebAPI;
|
|||||||
|
|
||||||
public delegate void SimpleStringDelegate(string str);
|
public delegate void SimpleStringDelegate(string str);
|
||||||
|
|
||||||
|
public record JwtCache(string ApiUrl, string CharaIdent, string SecretKey);
|
||||||
|
|
||||||
public partial class ApiController : IDisposable, IMareHubClient
|
public partial class ApiController : IDisposable, IMareHubClient
|
||||||
{
|
{
|
||||||
public const string MainServer = "Lunae Crescere Incipientis (Central Server EU)";
|
public const string MainServer = "Lunae Crescere Incipientis (Central Server EU)";
|
||||||
@@ -31,8 +32,8 @@ public partial class ApiController : IDisposable, IMareHubClient
|
|||||||
private readonly DalamudUtil _dalamudUtil;
|
private readonly DalamudUtil _dalamudUtil;
|
||||||
private readonly FileCacheManager _fileDbManager;
|
private readonly FileCacheManager _fileDbManager;
|
||||||
private CancellationTokenSource _connectionCancellationTokenSource;
|
private CancellationTokenSource _connectionCancellationTokenSource;
|
||||||
private Dictionary<string, string> _jwtToken = new(StringComparer.Ordinal);
|
private Dictionary<JwtCache, string> _jwtToken = new();
|
||||||
private KeyValuePair<string, string> AuthorizationJwtHeader => new("Authorization", "Bearer " + _jwtToken[SecretKey]);
|
private KeyValuePair<string, string> AuthorizationJwtHeader => new("Authorization", "Bearer " + _jwtToken.GetValueOrDefault(new JwtCache(ApiUri, _dalamudUtil.PlayerNameHashed, SecretKey), string.Empty));
|
||||||
|
|
||||||
private HubConnection? _mareHub;
|
private HubConnection? _mareHub;
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ public partial class ApiController : IDisposable, IMareHubClient
|
|||||||
|
|
||||||
private ConnectionDto? _connectionDto;
|
private ConnectionDto? _connectionDto;
|
||||||
public ServerInfoDto ServerInfo => _connectionDto?.ServerInfo ?? new ServerInfoDto();
|
public ServerInfoDto ServerInfo => _connectionDto?.ServerInfo ?? new ServerInfoDto();
|
||||||
|
public string AuthFailureMessage { get; private set; } = string.Empty;
|
||||||
|
|
||||||
public SystemInfoDto SystemInfoDto { get; private set; } = new();
|
public SystemInfoDto SystemInfoDto { get; private set; } = new();
|
||||||
public bool IsModerator => (_connectionDto?.IsAdmin ?? false) || (_connectionDto?.IsModerator ?? false);
|
public bool IsModerator => (_connectionDto?.IsAdmin ?? false) || (_connectionDto?.IsModerator ?? false);
|
||||||
@@ -167,15 +169,17 @@ public partial class ApiController : IDisposable, IMareHubClient
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AuthFailureMessage = string.Empty;
|
||||||
|
|
||||||
await StopConnection(token).ConfigureAwait(false);
|
await StopConnection(token).ConfigureAwait(false);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Logger.Debug("Building connection");
|
Logger.Debug("Building connection");
|
||||||
|
|
||||||
if (!_jwtToken.TryGetValue(SecretKey, out var jwtToken) || forceGetToken)
|
if (!_jwtToken.TryGetValue(new JwtCache(ApiUri, _dalamudUtil.PlayerNameHashed, SecretKey), out var jwtToken) || forceGetToken)
|
||||||
{
|
{
|
||||||
Logger.Debug("Requesting new JWT token");
|
Logger.Debug("Requesting new JWT");
|
||||||
using HttpClient httpClient = new();
|
using HttpClient httpClient = new();
|
||||||
var postUri = new Uri(new Uri(ApiUri
|
var postUri = new Uri(new Uri(ApiUri
|
||||||
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
|
.Replace("wss://", "https://", StringComparison.OrdinalIgnoreCase)
|
||||||
@@ -184,11 +188,13 @@ public partial class ApiController : IDisposable, IMareHubClient
|
|||||||
var auth = BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes(SecretKey))).Replace("-", "", StringComparison.OrdinalIgnoreCase);
|
var auth = BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes(SecretKey))).Replace("-", "", StringComparison.OrdinalIgnoreCase);
|
||||||
var result = await httpClient.PostAsync(postUri, new FormUrlEncodedContent(new[]
|
var result = await httpClient.PostAsync(postUri, new FormUrlEncodedContent(new[]
|
||||||
{
|
{
|
||||||
new KeyValuePair<string, string>("auth", auth)
|
new KeyValuePair<string, string>("auth", auth),
|
||||||
|
new KeyValuePair<string, string>("charaIdent", _dalamudUtil.PlayerNameHashed)
|
||||||
})).ConfigureAwait(false);
|
})).ConfigureAwait(false);
|
||||||
|
AuthFailureMessage = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
result.EnsureSuccessStatusCode();
|
result.EnsureSuccessStatusCode();
|
||||||
_jwtToken[SecretKey] = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
|
_jwtToken[new JwtCache(ApiUri, _dalamudUtil.PlayerNameHashed, SecretKey)] = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
Logger.Debug("JWT Token Success");
|
Logger.Debug("JWT Success");
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!_dalamudUtil.IsPlayerPresent && !token.IsCancellationRequested)
|
while (!_dalamudUtil.IsPlayerPresent && !token.IsCancellationRequested)
|
||||||
@@ -203,9 +209,10 @@ public partial class ApiController : IDisposable, IMareHubClient
|
|||||||
|
|
||||||
await _mareHub.StartAsync(token).ConfigureAwait(false);
|
await _mareHub.StartAsync(token).ConfigureAwait(false);
|
||||||
|
|
||||||
|
OnReceiveServerMessage((sev, msg) => Client_ReceiveServerMessage(sev, msg));
|
||||||
OnUpdateSystemInfo((dto) => Client_UpdateSystemInfo(dto));
|
OnUpdateSystemInfo((dto) => Client_UpdateSystemInfo(dto));
|
||||||
|
|
||||||
_connectionDto = await Heartbeat(_dalamudUtil.PlayerNameHashed).ConfigureAwait(false);
|
_connectionDto = await GetConnectionDto().ConfigureAwait(false);
|
||||||
|
|
||||||
ServerState = ServerState.Connected;
|
ServerState = ServerState.Connected;
|
||||||
|
|
||||||
@@ -225,24 +232,6 @@ public partial class ApiController : IDisposable, IMareHubClient
|
|||||||
_mareHub.Reconnected += MareHubOnReconnected;
|
_mareHub.Reconnected += MareHubOnReconnected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (HubException ex)
|
|
||||||
{
|
|
||||||
if (ex.Message.Contains("unauthorized", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
Logger.Warn(ex.Message);
|
|
||||||
ServerState = ServerState.Unauthorized;
|
|
||||||
await StopConnection(token).ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Warn(ex.GetType().ToString());
|
|
||||||
Logger.Warn(ex.Message);
|
|
||||||
Logger.Warn(ex.StackTrace ?? string.Empty);
|
|
||||||
|
|
||||||
ServerState = ServerState.RateLimited;
|
|
||||||
await StopConnection(token).ConfigureAwait(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch (HttpRequestException ex)
|
catch (HttpRequestException ex)
|
||||||
{
|
{
|
||||||
Logger.Warn(ex.GetType().ToString());
|
Logger.Warn(ex.GetType().ToString());
|
||||||
@@ -423,6 +412,11 @@ public partial class ApiController : IDisposable, IMareHubClient
|
|||||||
return await _mareHub!.InvokeAsync<ConnectionDto>(nameof(Heartbeat), characterIdentification).ConfigureAwait(false);
|
return await _mareHub!.InvokeAsync<ConnectionDto>(nameof(Heartbeat), characterIdentification).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<ConnectionDto> GetConnectionDto()
|
||||||
|
{
|
||||||
|
return await _mareHub!.InvokeAsync<ConnectionDto>(nameof(GetConnectionDto)).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> CheckClientHealth()
|
public async Task<bool> CheckClientHealth()
|
||||||
{
|
{
|
||||||
return await _mareHub!.InvokeAsync<bool>(nameof(CheckClientHealth)).ConfigureAwait(false);
|
return await _mareHub!.InvokeAsync<bool>(nameof(CheckClientHealth)).ConfigureAwait(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user