Merge branch '2.0.2' into mcdf-background-creation

This commit is contained in:
2025-12-26 21:20:09 +00:00
10 changed files with 1009 additions and 724 deletions

View File

@@ -4,21 +4,22 @@ using Dalamud.Plugin;
using Dalamud.Plugin.Services;
using LightlessSync.LightlessConfiguration;
using LightlessSync.LightlessConfiguration.Models;
using LightlessSync.Services.LightFinder;
using LightlessSync.Services.Mediator;
using LightlessSync.UI;
using LightlessSync.UI.Services;
using LightlessSync.Utils;
using LightlessSync.WebAPI;
using Lumina.Excel.Sheets;
using LightlessSync.UI.Services;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using LightlessSync.UI;
using LightlessSync.Services.LightFinder;
namespace LightlessSync.Services;
internal class ContextMenuService : IHostedService
{
private readonly IContextMenu _contextMenu;
private readonly IChatGui _chatGui;
private readonly IDalamudPluginInterface _pluginInterface;
private readonly IDataManager _gameData;
private readonly ILogger<ContextMenuService> _logger;
@@ -29,6 +30,7 @@ internal class ContextMenuService : IHostedService
private readonly ApiController _apiController;
private readonly IObjectTable _objectTable;
private readonly LightlessConfigService _configService;
private readonly NotificationService _lightlessNotification;
private readonly LightFinderScannerService _broadcastScannerService;
private readonly LightFinderService _broadcastService;
private readonly LightlessProfileManager _lightlessProfileManager;
@@ -43,7 +45,7 @@ internal class ContextMenuService : IHostedService
ILogger<ContextMenuService> logger,
DalamudUtilService dalamudUtil,
ApiController apiController,
IObjectTable objectTable,
IObjectTable objectTable,
LightlessConfigService configService,
PairRequestService pairRequestService,
PairUiService pairUiService,
@@ -51,7 +53,9 @@ internal class ContextMenuService : IHostedService
LightFinderScannerService broadcastScannerService,
LightFinderService broadcastService,
LightlessProfileManager lightlessProfileManager,
LightlessMediator mediator)
LightlessMediator mediator,
IChatGui chatGui,
NotificationService lightlessNotification)
{
_contextMenu = contextMenu;
_pluginInterface = pluginInterface;
@@ -68,6 +72,8 @@ internal class ContextMenuService : IHostedService
_broadcastService = broadcastService;
_lightlessProfileManager = lightlessProfileManager;
_mediator = mediator;
_chatGui = chatGui;
_lightlessNotification = lightlessNotification;
}
public Task StartAsync(CancellationToken cancellationToken)
@@ -99,6 +105,12 @@ internal class ContextMenuService : IHostedService
if (!_pluginInterface.UiBuilder.ShouldModifyUi)
return;
if (!_configService.Current.EnableRightClickMenus)
{
_logger.LogTrace("Right-click menus are disabled in configuration.");
return;
}
if (args.AddonName != null)
{
var addonName = args.AddonName;
@@ -198,6 +210,18 @@ internal class ContextMenuService : IHostedService
.Where(p => p.IsVisible && p.PlayerCharacterId != uint.MaxValue)
.Select(p => (ulong)p.PlayerCharacterId)];
private void NotifyInChat(string message, NotificationType type = NotificationType.Info)
{
if (!_configService.Current.UseLightlessNotifications || (_configService.Current.LightlessPairRequestNotification == NotificationLocation.Chat || _configService.Current.LightlessPairRequestNotification == NotificationLocation.ChatAndLightlessUi))
{
var chatMsg = $"[Lightless] {message}";
if (type == NotificationType.Error)
_chatGui.PrintError(chatMsg);
else
_chatGui.Print(chatMsg);
}
}
private async Task HandleSelection(IMenuArgs args)
{
if (args.Target is not MenuTargetDefault target)
@@ -226,6 +250,9 @@ internal class ContextMenuService : IHostedService
{
_pairRequestService.RemoveRequest(receiverCid);
}
// Notify in chat when NotificationService is disabled
NotifyInChat($"Pair request sent to {target.TargetName}@{world.Name}.", NotificationType.Info);
}
catch (Exception ex)
{

View File

@@ -0,0 +1,71 @@
using LightlessSync.Interop.Ipc;
using LightlessSync.LightlessConfiguration;
using LightlessSync.Services.Mediator;
using Microsoft.Extensions.Logging;
namespace LightlessSync.Services;
public sealed class PenumbraTempCollectionJanitor : DisposableMediatorSubscriberBase
{
private readonly IpcManager _ipc;
private readonly LightlessConfigService _config;
private int _ran;
public PenumbraTempCollectionJanitor(
ILogger<PenumbraTempCollectionJanitor> logger,
LightlessMediator mediator,
IpcManager ipc,
LightlessConfigService config) : base(logger, mediator)
{
_ipc = ipc;
_config = config;
Mediator.Subscribe<PenumbraInitializedMessage>(this, _ => CleanupOrphansOnBoot());
}
public void Register(Guid id)
{
if (id == Guid.Empty) return;
if (_config.Current.OrphanableTempCollections.Add(id))
_config.Save();
}
public void Unregister(Guid id)
{
if (id == Guid.Empty) return;
if (_config.Current.OrphanableTempCollections.Remove(id))
_config.Save();
}
private void CleanupOrphansOnBoot()
{
if (Interlocked.Exchange(ref _ran, 1) == 1)
return;
if (!_ipc.Penumbra.APIAvailable)
return;
var ids = _config.Current.OrphanableTempCollections.ToArray();
if (ids.Length == 0)
return;
var appId = Guid.NewGuid();
Logger.LogInformation("Cleaning up {count} orphaned Lightless temp collections found in configuration", ids.Length);
foreach (var id in ids)
{
try
{
_ipc.Penumbra.RemoveTemporaryCollectionAsync(Logger, appId, id)
.GetAwaiter().GetResult();
}
catch (Exception ex)
{
Logger.LogDebug(ex, "Failed removing orphaned temp collection {id}", id);
}
}
_config.Current.OrphanableTempCollections.Clear();
_config.Save();
}
}