Files
LightlessClient/LightlessSync/PlayerData/Pairs/PairCoordinator.cs
defnotken 835a0a637d
All checks were successful
Tag and Release Lightless / tag-and-release (push) Successful in 2m27s
2.0.0 (#92)
2.0.0 Changes:

- Reworked shell finder UI with compact or list view with profile tags showing with the listing, allowing moderators to broadcast the syncshell as well to have it be used more.
- Reworked user list in syncshell admin screen to have filter visible and moved away from table to its own thing, allowing to copy uid/note/alias when clicking on the name.
- Reworked download bars and download box to make it look more modern, removed the jitter around, so it shouldn't vibrate around much.
- Chat has been added to the top menu, working in Zone or in Syncshells to be used there.
- Paired system has been revamped to make pausing and unpausing faster, and loading people should be faster as well.
- Moved to the internal object table to have faster load times for users; people should load in faster
- Compactor is running on a multi-threaded level instead of single-threaded; this should increase the speed of compacting files
- Nameplate Service has been reworked so it wouldn't use the nameplate handler anymore.
- Files can be resized when downloading to reduce load on users if they aren't compressed. (can be toggled to resize all).
- Penumbra Collections are now only made when people are visible, reducing the load on boot-up when having many syncshells in your list.
- Lightfinder plates have been moved away from using Nameplates, but will use an overlay.
- Main UI has been changed a bit with a gradient, and on hover will glow up now.
- Reworked Profile UI for Syncshell and Users to be more user-facing with more customizable items.
- Reworked Settings UI to look more modern.
- Performance should be better due to new systems that would dispose of the collections and better caching of items.

Co-authored-by: defnotken <itsdefnotken@gmail.com>
Co-authored-by: azyges <aaaaaa@aaa.aaa>
Co-authored-by: choco <choco@patat.nl>
Co-authored-by: cake <admin@cakeandbanana.nl>
Co-authored-by: Minmoose <KennethBohr@outlook.com>
Reviewed-on: #92
2025-12-21 17:19:34 +00:00

140 lines
4.7 KiB
C#

using System.Collections.Concurrent;
using LightlessSync.API.Dto.User;
using LightlessSync.LightlessConfiguration;
using LightlessSync.LightlessConfiguration.Models;
using LightlessSync.Services.Mediator;
using LightlessSync.Services.ServerConfiguration;
using Microsoft.Extensions.Logging;
namespace LightlessSync.PlayerData.Pairs;
/// <summary>
/// wires mediator events into the pair system
/// </summary>
public sealed partial class PairCoordinator : MediatorSubscriberBase
{
private readonly ILogger<PairCoordinator> _logger;
private readonly LightlessConfigService _configService;
private readonly LightlessMediator _mediator;
private readonly PairHandlerRegistry _handlerRegistry;
private readonly PairManager _pairManager;
private readonly PairLedger _pairLedger;
private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly PairPerformanceMetricsCache _metricsCache;
private readonly ConcurrentDictionary<string, OnlineUserCharaDataDto> _pendingCharacterData = new(StringComparer.Ordinal);
public PairCoordinator(
ILogger<PairCoordinator> logger,
LightlessConfigService configService,
LightlessMediator mediator,
PairHandlerRegistry handlerRegistry,
PairManager pairManager,
PairLedger pairLedger,
ServerConfigurationManager serverConfigurationManager,
PairPerformanceMetricsCache metricsCache)
: base(logger, mediator)
{
_logger = logger;
_configService = configService;
_mediator = mediator;
_handlerRegistry = handlerRegistry;
_pairManager = pairManager;
_pairLedger = pairLedger;
_serverConfigurationManager = serverConfigurationManager;
_metricsCache = metricsCache;
mediator.Subscribe<ActiveServerChangedMessage>(this, msg => HandleActiveServerChange(msg.ServerUrl));
mediator.Subscribe<DisconnectedMessage>(this, _ => HandleDisconnected());
}
internal PairLedger Ledger => _pairLedger;
private void PublishPairDataChanged(bool groupChanged = false)
{
_mediator.Publish(new RefreshUiMessage());
_mediator.Publish(new PairDataChangedMessage());
if (groupChanged)
{
_mediator.Publish(new GroupCollectionChangedMessage());
}
}
private void NotifyUserOnline(PairConnection? connection, bool sendNotification)
{
if (connection is null)
{
return;
}
var config = _configService.Current;
if (config.ShowOnlineNotifications && _logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug("Pair {Uid} marked online", connection.User.UID);
}
if (!sendNotification || !config.ShowOnlineNotifications)
{
return;
}
if (config.ShowOnlineNotificationsOnlyForIndividualPairs &&
(!connection.IsDirectlyPaired || connection.IsOneSided))
{
return;
}
var note = _serverConfigurationManager.GetNoteForUid(connection.User.UID);
if (config.ShowOnlineNotificationsOnlyForNamedPairs &&
string.IsNullOrEmpty(note))
{
return;
}
var message = !string.IsNullOrEmpty(note)
? $"{note} ({connection.User.AliasOrUID}) is now online"
: $"{connection.User.AliasOrUID} is now online";
_mediator.Publish(new NotificationMessage("User online", message, NotificationType.Info, TimeSpan.FromSeconds(5)));
}
private void ReapplyLastKnownData(string userId, string ident, bool forced = false)
{
var result = _handlerRegistry.ApplyLastReceivedData(new PairUniqueIdentifier(userId), ident, forced);
if (!result.Success && _logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug("Failed to reapply cached data for {Uid}: {Error}", userId, result.Error);
}
}
private void HandleActiveServerChange(string serverUrl)
{
if (_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug("Active server changed to {Server}", serverUrl);
}
ResetPairState();
}
private void HandleDisconnected()
{
if (_logger.IsEnabled(LogLevel.Debug))
{
_logger.LogDebug("Lightless disconnected, clearing pair state");
}
ResetPairState();
}
private void ResetPairState()
{
_handlerRegistry.ResetAllHandlers();
_pairManager.ClearAll();
_pendingCharacterData.Clear();
_metricsCache.ClearAll();
_mediator.Publish(new ClearProfileUserDataMessage());
_mediator.Publish(new ClearProfileGroupDataMessage());
PublishPairDataChanged(groupChanged: true);
}
}