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
197 lines
5.0 KiB
C#
197 lines
5.0 KiB
C#
using Dalamud.Plugin;
|
|
using LightlessSync.Services.Mediator;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.Linq;
|
|
|
|
namespace LightlessSync.Interop.Ipc.Framework;
|
|
|
|
public enum IpcConnectionState
|
|
{
|
|
Unknown = 0,
|
|
MissingPlugin = 1,
|
|
VersionMismatch = 2,
|
|
PluginDisabled = 3,
|
|
NotReady = 4,
|
|
Available = 5,
|
|
Error = 6,
|
|
}
|
|
|
|
public sealed record IpcServiceDescriptor(string InternalName, string DisplayName, Version MinimumVersion)
|
|
{
|
|
public override string ToString()
|
|
=> $"{DisplayName} (>= {MinimumVersion})";
|
|
}
|
|
|
|
public interface IIpcService : IDisposable
|
|
{
|
|
IpcServiceDescriptor Descriptor { get; }
|
|
IpcConnectionState State { get; }
|
|
IDalamudPluginInterface PluginInterface { get; }
|
|
bool APIAvailable { get; }
|
|
void CheckAPI();
|
|
}
|
|
|
|
public interface IIpcInterop : IDisposable
|
|
{
|
|
string Name { get; }
|
|
void OnConnectionStateChanged(IpcConnectionState state);
|
|
}
|
|
|
|
public abstract class IpcInteropBase : IIpcInterop
|
|
{
|
|
protected IpcInteropBase(ILogger logger)
|
|
{
|
|
Logger = logger;
|
|
}
|
|
|
|
protected ILogger Logger { get; }
|
|
|
|
protected IpcConnectionState State { get; private set; } = IpcConnectionState.Unknown;
|
|
|
|
protected bool IsAvailable => State == IpcConnectionState.Available;
|
|
|
|
public abstract string Name { get; }
|
|
|
|
public void OnConnectionStateChanged(IpcConnectionState state)
|
|
{
|
|
if (State == state)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var previous = State;
|
|
State = state;
|
|
HandleStateChange(previous, state);
|
|
}
|
|
|
|
protected abstract void HandleStateChange(IpcConnectionState previous, IpcConnectionState current);
|
|
|
|
public virtual void Dispose()
|
|
{
|
|
}
|
|
}
|
|
|
|
public abstract class IpcServiceBase : DisposableMediatorSubscriberBase, IIpcService
|
|
{
|
|
private readonly List<IIpcInterop> _interops = new();
|
|
|
|
protected IpcServiceBase(
|
|
ILogger logger,
|
|
LightlessMediator mediator,
|
|
IDalamudPluginInterface pluginInterface,
|
|
IpcServiceDescriptor descriptor) : base(logger, mediator)
|
|
{
|
|
PluginInterface = pluginInterface;
|
|
Descriptor = descriptor;
|
|
}
|
|
|
|
protected IDalamudPluginInterface PluginInterface { get; }
|
|
|
|
IDalamudPluginInterface IIpcService.PluginInterface => PluginInterface;
|
|
|
|
protected IpcServiceDescriptor Descriptor { get; }
|
|
|
|
IpcServiceDescriptor IIpcService.Descriptor => Descriptor;
|
|
|
|
public IpcConnectionState State { get; private set; } = IpcConnectionState.Unknown;
|
|
|
|
public bool APIAvailable => State == IpcConnectionState.Available;
|
|
|
|
public virtual void CheckAPI()
|
|
{
|
|
var newState = EvaluateState();
|
|
UpdateState(newState);
|
|
}
|
|
|
|
protected virtual IpcConnectionState EvaluateState()
|
|
{
|
|
try
|
|
{
|
|
var plugin = PluginInterface.InstalledPlugins
|
|
.Where(p => string.Equals(p.InternalName, Descriptor.InternalName, StringComparison.OrdinalIgnoreCase))
|
|
.OrderByDescending(p => p.IsLoaded)
|
|
.FirstOrDefault();
|
|
|
|
if (plugin == null)
|
|
{
|
|
return IpcConnectionState.MissingPlugin;
|
|
}
|
|
|
|
if (plugin.Version < Descriptor.MinimumVersion)
|
|
{
|
|
return IpcConnectionState.VersionMismatch;
|
|
}
|
|
|
|
if (!IsPluginEnabled(plugin))
|
|
{
|
|
return IpcConnectionState.PluginDisabled;
|
|
}
|
|
|
|
if (!IsPluginReady())
|
|
{
|
|
return IpcConnectionState.NotReady;
|
|
}
|
|
|
|
return IpcConnectionState.Available;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogDebug(ex, "Failed to evaluate IPC state for {Service}", Descriptor.DisplayName);
|
|
return IpcConnectionState.Error;
|
|
}
|
|
}
|
|
|
|
protected virtual bool IsPluginEnabled(IExposedPlugin plugin)
|
|
=> plugin.IsLoaded;
|
|
|
|
protected virtual bool IsPluginReady()
|
|
=> true;
|
|
|
|
protected TInterop RegisterInterop<TInterop>(TInterop interop)
|
|
where TInterop : IIpcInterop
|
|
{
|
|
_interops.Add(interop);
|
|
interop.OnConnectionStateChanged(State);
|
|
return interop;
|
|
}
|
|
|
|
private void UpdateState(IpcConnectionState newState)
|
|
{
|
|
if (State == newState)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var previous = State;
|
|
State = newState;
|
|
OnConnectionStateChanged(previous, newState);
|
|
|
|
foreach (var interop in _interops)
|
|
{
|
|
interop.OnConnectionStateChanged(newState);
|
|
}
|
|
}
|
|
|
|
protected virtual void OnConnectionStateChanged(IpcConnectionState previous, IpcConnectionState current)
|
|
{
|
|
Logger.LogTrace("{Service} IPC state transitioned from {Previous} to {Current}", Descriptor.DisplayName, previous, current);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
base.Dispose(disposing);
|
|
|
|
if (!disposing)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (var i = _interops.Count - 1; i >= 0; --i)
|
|
{
|
|
_interops[i].Dispose();
|
|
}
|
|
|
|
_interops.Clear();
|
|
}
|
|
}
|