8 Commits

Author SHA1 Message Date
f0cef81b5e Merge pull request #17 from ProfessorFartsalot/main
Some checks are pending
.NET Build and Publish to Gitea / build (push) Waiting to run
Fix health check, reconnect automatically on error
2025-09-05 06:12:43 +01:00
d8160effd0 Fix up client reconnect code
Simplified the reconnect code so that redis is made aware that we have a new connection.

Made the reconnect fire immediately on error rather than waiting for subsequent errors.
2025-09-04 21:50:47 -04:00
18da07763c Add in extra check to see if hub server DC'd 2025-09-04 18:41:44 -04:00
3c448f2290 Fix health check, reconnect automatically on error
+ Made health check actually do something instead of just logging connection health issues.

+ Requires server code change to enable the health check so it's not just returning false all the time.

+ Forcibly reconnects the client when they've had connection issues.
2025-09-04 17:18:26 -04:00
cadc7e223f minor fixes 2025-09-04 14:26:15 +01:00
e1baca7940 Version bump
Some checks failed
.NET Build and Publish to Gitea / build (push) Has been cancelled
2025-09-03 16:11:51 +01:00
c2e0cf65a8 Packages update 2025-09-03 16:07:00 +01:00
a3d0408d6f More sensible VRAM sorting thing
Some checks failed
.NET Build and Publish to Gitea / build (push) Has been cancelled
2025-09-03 16:01:51 +01:00
5 changed files with 63 additions and 26 deletions

View File

@@ -2,8 +2,8 @@
<Project Sdk="Dalamud.NET.Sdk/13.0.0">
<PropertyGroup>
<AssemblyName>Snowcloak</AssemblyName>
<Version>0.2.1</Version>
<PackageProjectUrl>https://github.com/Eauldane/SnowcloakClient/</PackageProjectUrl>
<Version>0.2.2</Version>
<PackageProjectUrl>https://git.snowcloak-sync.com/Eauldane/SnowcloakClient/</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>

View File

@@ -235,11 +235,17 @@ public class Pair : DisposableMediatorSubscriberBase
{
string? noteOrName = GetNoteOrName();
if (noteOrName != null)
if (_mareConfig.Current.SortSyncshellsByVRAM)
{
return($"0{LastAppliedApproximateVRAMBytes}");
}
else if (noteOrName != null) {
return $"0{noteOrName}";
else
}
else {
return $"9{UserData.AliasOrUID}";
}
}
}
public string GetPlayerNameHash()
{

View File

@@ -20,7 +20,7 @@ public class DrawGroupPair : DrawPairBase
private readonly GroupPairFullInfoDto _fullInfoDto;
private readonly GroupFullInfoDto _group;
private readonly CharaDataManager _charaDataManager;
public long VramUsage { get; set; }
public long VRAMUsage { get; set; }
public DrawGroupPair(string id, Pair entry, ApiController apiController,
MareMediator mareMediator, GroupFullInfoDto group, GroupPairFullInfoDto fullInfoDto,
@@ -87,7 +87,6 @@ public class DrawGroupPair : DrawPairBase
presenceText += "Files Size: " + UiSharedService.ByteToString(_pair.LastAppliedDataBytes, true);
if (_pair.LastAppliedApproximateVRAMBytes >= 0)
{
VramUsage = _pair.LastAppliedApproximateVRAMBytes;
presenceText += Environment.NewLine + "Approx. VRAM Usage: " + UiSharedService.ByteToString(_pair.LastAppliedApproximateVRAMBytes, true);
}
if (_pair.LastAppliedDataTris >= 0)
@@ -130,7 +129,7 @@ public class DrawGroupPair : DrawPairBase
protected override float DrawRightSide(float textPosY, float originalY)
{
var pauseIcon = _fullInfoDto.GroupUserPermissions.IsPaused() ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
var pauseIcon = _pair.IsPaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;
var pauseIconSize = _uiSharedService.GetIconButtonSize(pauseIcon);
var spacingX = ImGui.GetStyle().ItemSpacing.X;
var entryUID = _fullInfoDto.UserAliasOrUID;
@@ -297,9 +296,10 @@ public class DrawGroupPair : DrawPairBase
if (_uiSharedService.IconButton(pauseIcon))
{
var perm = _fullInfoDto.GroupUserPermissions;
var newPaused = !perm.IsPaused();
perm.SetPaused(newPaused);
var perm = _pair.UserPair!.OwnPermissions;
perm.SetPaused(!perm.IsPaused());
_ = _apiController.UserSetPairPermissions(new(_pair.UserData, perm));
}
UiSharedService.AttachToolTip(!_fullInfoDto.GroupUserPermissions.IsPaused()

View File

@@ -428,6 +428,7 @@ internal sealed class GroupPanel
var onlineUsers = new List<DrawGroupPair>();
var offlineUsers = new List<DrawGroupPair>();
foreach (var pair in sortedPairs)
{
var drawPair = new DrawGroupPair(
@@ -452,16 +453,9 @@ internal sealed class GroupPanel
{
ImGui.TextUnformatted("Visible");
ImGui.Separator();
if (_mareConfig.Current.SortSyncshellsByVRAM)
{
List<DrawGroupPair> sortedVisibleUsers = visibleUsers.OrderBy(o=>o.VramUsage).ToList();
_uidDisplayHandler.RenderPairList(sortedVisibleUsers);
}
else
{
_uidDisplayHandler.RenderPairList(visibleUsers);
_uidDisplayHandler.RenderPairList(visibleUsers);
}
}
if (onlineUsers.Count > 0)

View File

@@ -183,6 +183,8 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
_connectionDto = await GetConnectionDto().ConfigureAwait(false);
await CheckClientHealth().ConfigureAwait(false);
ServerState = ServerState.Connected;
var currentClientVer = Assembly.GetExecutingAssembly().GetName().Version!;
@@ -308,14 +310,24 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
_ = Task.Run(async () => await StopConnection(ServerState.Disconnected).ConfigureAwait(false));
_connectionCancellationTokenSource?.Cancel();
}
private int _unhealthy = 0;
private async Task ClientHealthCheck(CancellationToken ct)
{
while (!ct.IsCancellationRequested && _mareHub != null)
{
await Task.Delay(TimeSpan.FromSeconds(30), ct).ConfigureAwait(false);
Logger.LogDebug("Checking Client Health State");
_ = await CheckClientHealth().ConfigureAwait(false);
var healthy = await CheckClientHealth().ConfigureAwait(false);
if (!healthy || _mareHub.State != HubConnectionState.Connected)
{
_unhealthy++;
if (_unhealthy > 0)
{
Logger.LogWarning("Health check failed, forcing reconnect. ClientHealth: {0} HubConnected: {1}", healthy, _mareHub.State != HubConnectionState.Connected);
await ForceResetConnection().ConfigureAwait(false);
_unhealthy = 0;
}
}
else _unhealthy = 0;
}
}
@@ -391,7 +403,7 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
{
var users = await GroupsGetUsersInGroup(group).ConfigureAwait(false);
foreach (var user in users)
{
{
Logger.LogDebug("Group Pair: {user}", user);
_pairManager.AddGroupPair(user);
}
@@ -478,5 +490,30 @@ public sealed partial class ApiController : DisposableMediatorSubscriberBase, IM
ServerState = state;
}
//Because this plugin really likes to bug out with connections, lets "fix" it....
public async Task ForceResetConnection()
{
if (!_initialized) return;
Logger.LogInformation("ForceReconnect called");
try
{
await StopConnection(ServerState.Disconnected).ConfigureAwait(false);
// Cancel any ongoing health checks to prevent conflicts
_healthCheckTokenSource?.Cancel();
_healthCheckTokenSource?.Dispose();
_healthCheckTokenSource = null;
await CreateConnections().ConfigureAwait(false);
Logger.LogInformation("ForceReconnect completed successfully");
}
catch (Exception ex)
{
Logger.LogError(ex, "Failure during ForceReconnect, disconnecting");
await StopConnection(ServerState.Disconnected).ConfigureAwait(false);
}
}
}
#pragma warning restore MA0040