This commit is contained in:
CakeAndBanana
2025-09-25 22:01:22 +02:00
5 changed files with 43 additions and 27 deletions

View File

@@ -4,9 +4,7 @@ using LightlessSync.LightlessConfiguration;
using LightlessSync.Services.Mediator; using LightlessSync.Services.Mediator;
using LightlessSync.Utils; using LightlessSync.Utils;
using LightlessSync.WebAPI; using LightlessSync.WebAPI;
using LightlessSync.WebAPI.SignalR;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -16,7 +14,6 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
private readonly ILogger<BroadcastService> _logger; private readonly ILogger<BroadcastService> _logger;
private readonly ApiController _apiController; private readonly ApiController _apiController;
private readonly LightlessMediator _mediator; private readonly LightlessMediator _mediator;
private readonly HubFactory _hubFactory;
private readonly LightlessConfigService _config; private readonly LightlessConfigService _config;
private readonly DalamudUtilService _dalamudUtil; private readonly DalamudUtilService _dalamudUtil;
public LightlessMediator Mediator => _mediator; public LightlessMediator Mediator => _mediator;
@@ -29,35 +26,37 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
private TimeSpan? _remainingTtl = null; private TimeSpan? _remainingTtl = null;
private DateTime _lastTtlCheck = DateTime.MinValue; private DateTime _lastTtlCheck = DateTime.MinValue;
private DateTime _lastForcedDisableTime = DateTime.MinValue; private DateTime _lastForcedDisableTime = DateTime.MinValue;
private static readonly TimeSpan DisableCooldown = TimeSpan.FromSeconds(5); private static readonly TimeSpan _disableCooldown = TimeSpan.FromSeconds(5);
public TimeSpan? RemainingTtl => _remainingTtl; public TimeSpan? RemainingTtl => _remainingTtl;
public TimeSpan? RemainingCooldown public TimeSpan? RemainingCooldown
{ {
get get
{ {
var elapsed = DateTime.UtcNow - _lastForcedDisableTime; var elapsed = DateTime.UtcNow - _lastForcedDisableTime;
if (elapsed >= DisableCooldown) return null; if (elapsed >= _disableCooldown) return null;
return DisableCooldown - elapsed; return _disableCooldown - elapsed;
} }
} }
public BroadcastService(ILogger<BroadcastService> logger, LightlessMediator mediator, HubFactory hubFactory, LightlessConfigService config, DalamudUtilService dalamudUtil, ApiController apiController)
public BroadcastService(ILogger<BroadcastService> logger, LightlessMediator mediator, LightlessConfigService config, DalamudUtilService dalamudUtil, ApiController apiController)
{ {
_logger = logger; _logger = logger;
_mediator = mediator; _mediator = mediator;
_hubFactory = hubFactory;
_config = config; _config = config;
_dalamudUtil = dalamudUtil; _dalamudUtil = dalamudUtil;
_apiController = apiController; _apiController = apiController;
} }
private async Task RequireConnectionAsync(string context, Func<Task> action) private async Task RequireConnectionAsync(string context, Func<Task> action)
{ {
if (!_apiController.IsConnected) if (!_apiController.IsConnected)
{ {
_logger.LogDebug($"{context} skipped, not connected"); _logger.LogDebug(context + " skipped, not connected");
return; return;
} }
await action().ConfigureAwait(false); await action().ConfigureAwait(false);
} }
public async Task StartAsync(CancellationToken cancellationToken) public async Task StartAsync(CancellationToken cancellationToken)
{ {
_mediator.Subscribe<EnableBroadcastMessage>(this, OnEnableBroadcast); _mediator.Subscribe<EnableBroadcastMessage>(this, OnEnableBroadcast);
@@ -65,7 +64,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
_mediator.Subscribe<PriorityFrameworkUpdateMessage>(this, OnTick); _mediator.Subscribe<PriorityFrameworkUpdateMessage>(this, OnTick);
_apiController.OnConnected += () => _ = CheckLightfinderSupportAsync(cancellationToken); _apiController.OnConnected += () => _ = CheckLightfinderSupportAsync(cancellationToken);
_ = CheckLightfinderSupportAsync(cancellationToken); //_ = CheckLightfinderSupportAsync(cancellationToken);
} }
public Task StopAsync(CancellationToken cancellationToken) public Task StopAsync(CancellationToken cancellationToken)
@@ -86,13 +85,12 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)
return; return;
var hub = _hubFactory.GetOrCreate(CancellationToken.None);
var dummy = "0".PadLeft(64, '0'); var dummy = "0".PadLeft(64, '0');
await hub.InvokeAsync<BroadcastStatusInfoDto?>("IsUserBroadcasting", dummy, cancellationToken); await _apiController.IsUserBroadcasting(dummy).ConfigureAwait(false);
await hub.InvokeAsync("SetBroadcastStatus", dummy, true, null, cancellationToken); await _apiController.SetBroadcastStatus(dummy, true, null).ConfigureAwait(false);
await hub.InvokeAsync<TimeSpan?>("GetBroadcastTtl", dummy, cancellationToken); await _apiController.GetBroadcastTtl(dummy).ConfigureAwait(false);
await hub.InvokeAsync<Dictionary<string, BroadcastStatusInfoDto?>>("AreUsersBroadcasting", new[] { dummy }, cancellationToken); await _apiController.AreUsersBroadcasting([dummy]).ConfigureAwait(false);
IsLightFinderAvailable = true; IsLightFinderAvailable = true;
_logger.LogInformation("Lightfinder is available."); _logger.LogInformation("Lightfinder is available.");
@@ -119,6 +117,7 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
_config.Current.BroadcastEnabled = false; _config.Current.BroadcastEnabled = false;
_config.Current.BroadcastTtl = DateTime.MinValue; _config.Current.BroadcastTtl = DateTime.MinValue;
_config.Save(); _config.Save();
_mediator.Publish(new BroadcastStatusChangedMessage(false, null)); _mediator.Publish(new BroadcastStatusChangedMessage(false, null));
} }
} }
@@ -151,13 +150,13 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
_config.Save(); _config.Save();
_mediator.Publish(new BroadcastStatusChangedMessage(false, null)); _mediator.Publish(new BroadcastStatusChangedMessage(false, null));
Mediator.Publish(new EventMessage(new Services.Events.Event(nameof(BroadcastService), Services.Events.EventSeverity.Informational,$"Disabled Lightfinder for Player: {msg.HashedCid}"))); Mediator.Publish(new EventMessage(new Services.Events.Event(nameof(BroadcastService), Services.Events.EventSeverity.Informational, $"Disabled Lightfinder for Player: {msg.HashedCid}")));
return; return;
} }
_waitingForTtlFetch = true; _waitingForTtlFetch = true;
var ttl = await GetBroadcastTtlAsync(msg.HashedCid).ConfigureAwait(false); TimeSpan? ttl = await GetBroadcastTtlAsync(msg.HashedCid).ConfigureAwait(false);
if (ttl is { } remaining && remaining > TimeSpan.Zero) if (ttl is { } remaining && remaining > TimeSpan.Zero)
{ {
@@ -325,8 +324,8 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
_syncedOnStartup = true; _syncedOnStartup = true;
try try
{ {
var hashedCid = (await _dalamudUtil.GetCIDAsync().ConfigureAwait(false)).ToString().GetHash256(); string hashedCid = (await _dalamudUtil.GetCIDAsync().ConfigureAwait(false)).ToString().GetHash256();
var ttl = await GetBroadcastTtlAsync(hashedCid).ConfigureAwait(false); TimeSpan? ttl = await GetBroadcastTtlAsync(hashedCid).ConfigureAwait(false);
if (ttl is { } if (ttl is { }
remaining && remaining > TimeSpan.Zero) remaining && remaining > TimeSpan.Zero)
{ {
@@ -357,8 +356,8 @@ public class BroadcastService : IHostedService, IMediatorSubscriber
return; return;
} }
var expiry = _config.Current.BroadcastTtl; DateTime expiry = _config.Current.BroadcastTtl;
var remaining = expiry - DateTime.UtcNow; TimeSpan remaining = expiry - DateTime.UtcNow;
_remainingTtl = remaining > TimeSpan.Zero ? remaining : null; _remainingTtl = remaining > TimeSpan.Zero ? remaining : null;
if (_remainingTtl == null) if (_remainingTtl == null)
{ {

View File

@@ -336,7 +336,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
} }
ImGui.Separator(); ImGui.Separator();
if (_uiSharedService.MediumTreeNode("Mass Cleanup", UIColors.Get("LightlessPurple"))) if (_uiSharedService.MediumTreeNode("Mass Cleanup", UIColors.Get("DimRed")))
{ {
using (ImRaii.Disabled(!UiSharedService.CtrlPressed())) using (ImRaii.Disabled(!UiSharedService.CtrlPressed()))
{ {
@@ -348,6 +348,18 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
UiSharedService.AttachToolTip("This will remove all non-pinned, non-moderator users from the Syncshell." UiSharedService.AttachToolTip("This will remove all non-pinned, non-moderator users from the Syncshell."
+ UiSharedService.TooltipSeparator + "Hold CTRL to enable this button"); + UiSharedService.TooltipSeparator + "Hold CTRL to enable this button");
ImGui.SameLine();
using (ImRaii.Disabled(!UiSharedService.CtrlPressed()))
{
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Brush, "Clear Lightfinder Users"))
{
_ = _apiController.GroupClearFinder(new(GroupFullInfo.Group));
}
}
UiSharedService.AttachToolTip("This will remove all users that joined through Lightfinder from the Syncshell."
+ UiSharedService.TooltipSeparator + "Hold CTRL to enable this button");
ImGuiHelpers.ScaledDummy(2f); ImGuiHelpers.ScaledDummy(2f);
ImGui.Separator(); ImGui.Separator();
ImGuiHelpers.ScaledDummy(2f); ImGuiHelpers.ScaledDummy(2f);
@@ -410,12 +422,12 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
UiSharedService.TextWrapped($"Syncshell was pruned and {_pruneTask.Result} inactive user(s) have been removed."); UiSharedService.TextWrapped($"Syncshell was pruned and {_pruneTask.Result} inactive user(s) have been removed.");
} }
} }
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f); _uiSharedService.ColoredSeparator(UIColors.Get("DimRed"), 1.5f);
ImGui.TreePop(); ImGui.TreePop();
} }
ImGui.Separator(); ImGui.Separator();
if (_uiSharedService.MediumTreeNode("User Bans", UIColors.Get("LightlessPurple"))) if (_uiSharedService.MediumTreeNode("User Bans", UIColors.Get("LightlessYellow")))
{ {
if (_uiSharedService.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server")) if (_uiSharedService.IconTextButton(FontAwesomeIcon.Retweet, "Refresh Banlist from Server"))
{ {
@@ -456,7 +468,7 @@ public class SyncshellAdminUI : WindowMediatorSubscriberBase
} }
ImGui.EndTable(); ImGui.EndTable();
} }
_uiSharedService.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f); _uiSharedService.ColoredSeparator(UIColors.Get("LightlessYellow"), 1.5f);
ImGui.TreePop(); ImGui.TreePop();
} }
ImGui.Separator(); ImGui.Separator();

View File

@@ -189,7 +189,7 @@ public class SyncshellFinderUI : WindowMediatorSubscriberBase
finalPermissions.SetDisableAnimations(_ownPermissions.DisableGroupAnimations); finalPermissions.SetDisableAnimations(_ownPermissions.DisableGroupAnimations);
finalPermissions.SetDisableVFX(_ownPermissions.DisableGroupVFX); finalPermissions.SetDisableVFX(_ownPermissions.DisableGroupVFX);
_ = _apiController.GroupJoinFinalize(new GroupJoinDto(_joinDto.Group, _joinDto.Password, finalPermissions, true)); _ = _apiController.GroupJoinFinalize(new GroupJoinDto(_joinDto.Group, _joinDto.Password, finalPermissions));
_joinDto = null; _joinDto = null;
_joinInfo = null; _joinInfo = null;
} }

View File

@@ -45,6 +45,11 @@ public partial class ApiController
CheckConnection(); CheckConnection();
await _lightlessHub!.SendAsync(nameof(GroupClear), group).ConfigureAwait(false); await _lightlessHub!.SendAsync(nameof(GroupClear), group).ConfigureAwait(false);
} }
public async Task GroupClearFinder(GroupDto group)
{
CheckConnection();
await _lightlessHub!.SendAsync(nameof(GroupClearFinder), group).ConfigureAwait(false);
}
public async Task<GroupJoinDto> GroupCreate() public async Task<GroupJoinDto> GroupCreate()
{ {