All checks were successful
Tag and Release Lightless / tag-and-release (push) Successful in 2m27s
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
127 lines
4.1 KiB
C#
127 lines
4.1 KiB
C#
using System;
|
|
using Dalamud.Game.ClientState.Objects.Types;
|
|
using Dalamud.Plugin;
|
|
using Dalamud.Plugin.Ipc;
|
|
using LightlessSync.PlayerData.Handlers;
|
|
using LightlessSync.Services;
|
|
using LightlessSync.Services.Mediator;
|
|
using Microsoft.Extensions.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace LightlessSync.Interop.Ipc;
|
|
|
|
public class IpcProvider : IHostedService, IMediatorSubscriber
|
|
{
|
|
private readonly ILogger<IpcProvider> _logger;
|
|
private readonly IDalamudPluginInterface _pi;
|
|
private readonly CharaDataManager _charaDataManager;
|
|
private readonly List<IpcRegister> _ipcRegisters = [];
|
|
private readonly List<GameObjectHandler> _activeGameObjectHandlers = [];
|
|
|
|
public LightlessMediator Mediator { get; init; }
|
|
|
|
public IpcProvider(ILogger<IpcProvider> logger, IDalamudPluginInterface pi,
|
|
CharaDataManager charaDataManager, LightlessMediator lightlessMediator)
|
|
{
|
|
_logger = logger;
|
|
_pi = pi;
|
|
_charaDataManager = charaDataManager;
|
|
Mediator = lightlessMediator;
|
|
|
|
Mediator.Subscribe<GameObjectHandlerCreatedMessage>(this, (msg) =>
|
|
{
|
|
if (msg.OwnedObject) return;
|
|
_activeGameObjectHandlers.Add(msg.GameObjectHandler);
|
|
});
|
|
Mediator.Subscribe<GameObjectHandlerDestroyedMessage>(this, (msg) =>
|
|
{
|
|
if (msg.OwnedObject) return;
|
|
_activeGameObjectHandlers.Remove(msg.GameObjectHandler);
|
|
});
|
|
}
|
|
|
|
public Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogInformation("Starting IpcProviderService");
|
|
_ipcRegisters.Add(RegisterFunc<string, IGameObject, bool>("LightlessSync.LoadMcdf", LoadMcdf));
|
|
_ipcRegisters.Add(RegisterFunc<string, IGameObject, Task<bool>>("LightlessSync.LoadMcdfAsync", LoadMcdfAsync));
|
|
_ipcRegisters.Add(RegisterFunc("LightlessSync.GetHandledAddresses", GetHandledAddresses));
|
|
_logger.LogInformation("Started IpcProviderService");
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken)
|
|
{
|
|
_logger.LogDebug("Stopping IpcProvider Service");
|
|
foreach (var register in _ipcRegisters)
|
|
{
|
|
register.Dispose();
|
|
}
|
|
_ipcRegisters.Clear();
|
|
Mediator.UnsubscribeAll(this);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private async Task<bool> LoadMcdfAsync(string path, IGameObject target)
|
|
{
|
|
await ApplyFileAsync(path, target).ConfigureAwait(false);
|
|
|
|
return true;
|
|
}
|
|
|
|
private bool LoadMcdf(string path, IGameObject target)
|
|
{
|
|
_ = Task.Run(async () => await ApplyFileAsync(path, target).ConfigureAwait(false)).ConfigureAwait(false);
|
|
|
|
return true;
|
|
}
|
|
|
|
private async Task ApplyFileAsync(string path, IGameObject target)
|
|
{
|
|
_charaDataManager.LoadMcdf(path);
|
|
await (_charaDataManager.LoadedMcdfHeader ?? Task.CompletedTask).ConfigureAwait(false);
|
|
_charaDataManager.McdfApplyToTarget(target.Name.TextValue);
|
|
}
|
|
|
|
private List<nint> GetHandledAddresses()
|
|
{
|
|
return _activeGameObjectHandlers.Where(g => g.Address != nint.Zero).Select(g => g.Address).Distinct().ToList();
|
|
}
|
|
|
|
private IpcRegister RegisterFunc(string label, Func<List<nint>> handler)
|
|
{
|
|
var provider = _pi.GetIpcProvider<List<nint>>(label);
|
|
provider.RegisterFunc(handler);
|
|
return new IpcRegister(provider.UnregisterFunc);
|
|
}
|
|
|
|
private IpcRegister RegisterFunc<T1, T2, TRet>(string label, Func<T1, T2, TRet> handler)
|
|
{
|
|
var provider = _pi.GetIpcProvider<T1, T2, TRet>(label);
|
|
provider.RegisterFunc(handler);
|
|
return new IpcRegister(provider.UnregisterFunc);
|
|
}
|
|
|
|
private sealed class IpcRegister : IDisposable
|
|
{
|
|
private readonly Action _unregister;
|
|
private bool _disposed;
|
|
|
|
public IpcRegister(Action unregister)
|
|
{
|
|
_unregister = unregister;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
if (_disposed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_unregister();
|
|
_disposed = true;
|
|
}
|
|
}
|
|
}
|