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
220 lines
8.3 KiB
C#
220 lines
8.3 KiB
C#
using Dalamud.Plugin;
|
|
using LightlessSync.Interop.Ipc.Framework;
|
|
using LightlessSync.Interop.Ipc.Penumbra;
|
|
using LightlessSync.LightlessConfiguration.Models;
|
|
using LightlessSync.PlayerData.Handlers;
|
|
using LightlessSync.Services;
|
|
using LightlessSync.Services.ActorTracking;
|
|
using LightlessSync.Services.Mediator;
|
|
using Microsoft.Extensions.Logging;
|
|
using Penumbra.Api.Enums;
|
|
using Penumbra.Api.Helpers;
|
|
using Penumbra.Api.IpcSubscribers;
|
|
|
|
namespace LightlessSync.Interop.Ipc;
|
|
|
|
public sealed class IpcCallerPenumbra : IpcServiceBase
|
|
{
|
|
private static readonly IpcServiceDescriptor PenumbraDescriptor = new("Penumbra", "Penumbra", new Version(1, 2, 0, 22));
|
|
|
|
private readonly PenumbraCollections _collections;
|
|
private readonly PenumbraResource _resources;
|
|
private readonly PenumbraRedraw _redraw;
|
|
private readonly PenumbraTexture _textures;
|
|
|
|
private readonly GetEnabledState _penumbraEnabled;
|
|
private readonly GetModDirectory _penumbraGetModDirectory;
|
|
private readonly EventSubscriber _penumbraInit;
|
|
private readonly EventSubscriber _penumbraDispose;
|
|
private readonly EventSubscriber<ModSettingChange, Guid, string, bool> _penumbraModSettingChanged;
|
|
|
|
private bool _shownPenumbraUnavailable;
|
|
private string? _modDirectory;
|
|
|
|
public IpcCallerPenumbra(
|
|
ILogger<IpcCallerPenumbra> logger,
|
|
IDalamudPluginInterface pluginInterface,
|
|
DalamudUtilService dalamudUtil,
|
|
LightlessMediator mediator,
|
|
RedrawManager redrawManager,
|
|
ActorObjectService actorObjectService) : base(logger, mediator, pluginInterface, PenumbraDescriptor)
|
|
{
|
|
_penumbraEnabled = new GetEnabledState(pluginInterface);
|
|
_penumbraGetModDirectory = new GetModDirectory(pluginInterface);
|
|
_penumbraInit = Initialized.Subscriber(pluginInterface, HandlePenumbraInitialized);
|
|
_penumbraDispose = Disposed.Subscriber(pluginInterface, HandlePenumbraDisposed);
|
|
_penumbraModSettingChanged = ModSettingChanged.Subscriber(pluginInterface, HandlePenumbraModSettingChanged);
|
|
|
|
_collections = RegisterInterop(new PenumbraCollections(logger, pluginInterface, dalamudUtil, mediator));
|
|
_resources = RegisterInterop(new PenumbraResource(logger, pluginInterface, dalamudUtil, mediator, actorObjectService));
|
|
_redraw = RegisterInterop(new PenumbraRedraw(logger, pluginInterface, dalamudUtil, mediator, redrawManager));
|
|
_textures = RegisterInterop(new PenumbraTexture(logger, pluginInterface, dalamudUtil, mediator, _redraw));
|
|
|
|
SubscribeMediatorEvents();
|
|
|
|
CheckAPI();
|
|
CheckModDirectory();
|
|
}
|
|
|
|
public string? ModDirectory
|
|
{
|
|
get => _modDirectory;
|
|
private set
|
|
{
|
|
if (string.Equals(_modDirectory, value, StringComparison.Ordinal))
|
|
{
|
|
return;
|
|
}
|
|
|
|
_modDirectory = value;
|
|
Mediator.Publish(new PenumbraDirectoryChangedMessage(_modDirectory));
|
|
}
|
|
}
|
|
|
|
public Task AssignTemporaryCollectionAsync(ILogger logger, Guid collectionId, int objectIndex)
|
|
=> _collections.AssignTemporaryCollectionAsync(logger, collectionId, objectIndex);
|
|
|
|
public Task<Guid> CreateTemporaryCollectionAsync(ILogger logger, string uid)
|
|
=> _collections.CreateTemporaryCollectionAsync(logger, uid);
|
|
|
|
public Task RemoveTemporaryCollectionAsync(ILogger logger, Guid applicationId, Guid collectionId)
|
|
=> _collections.RemoveTemporaryCollectionAsync(logger, applicationId, collectionId);
|
|
|
|
public Task SetTemporaryModsAsync(ILogger logger, Guid applicationId, Guid collectionId, Dictionary<string, string> modPaths)
|
|
=> _collections.SetTemporaryModsAsync(logger, applicationId, collectionId, modPaths);
|
|
|
|
public Task SetManipulationDataAsync(ILogger logger, Guid applicationId, Guid collectionId, string manipulationData)
|
|
=> _collections.SetManipulationDataAsync(logger, applicationId, collectionId, manipulationData);
|
|
|
|
public Task<Dictionary<string, HashSet<string>>?> GetCharacterData(ILogger logger, GameObjectHandler handler)
|
|
=> _resources.GetCharacterDataAsync(logger, handler);
|
|
|
|
public string GetMetaManipulations()
|
|
=> _resources.GetMetaManipulations();
|
|
|
|
public Task<(string[] forward, string[][] reverse)> ResolvePathsAsync(string[] forward, string[] reverse)
|
|
=> _resources.ResolvePathsAsync(forward, reverse);
|
|
|
|
public Task RedrawAsync(ILogger logger, GameObjectHandler handler, Guid applicationId, CancellationToken token)
|
|
=> _redraw.RedrawAsync(logger, handler, applicationId, token);
|
|
|
|
public Task ConvertTextureFiles(ILogger logger, IReadOnlyList<TextureConversionJob> jobs, IProgress<TextureConversionProgress>? progress, CancellationToken token)
|
|
=> _textures.ConvertTextureFilesAsync(logger, jobs, progress, token);
|
|
|
|
public Task ConvertTextureFileDirectAsync(TextureConversionJob job, CancellationToken token)
|
|
=> _textures.ConvertTextureFileDirectAsync(job, token);
|
|
|
|
public void CheckModDirectory()
|
|
{
|
|
if (!APIAvailable)
|
|
{
|
|
ModDirectory = string.Empty;
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
ModDirectory = _penumbraGetModDirectory.Invoke().ToLowerInvariant();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogWarning(ex, "Failed to resolve Penumbra mod directory");
|
|
}
|
|
}
|
|
|
|
protected override bool IsPluginEnabled(IExposedPlugin plugin)
|
|
{
|
|
try
|
|
{
|
|
return _penumbraEnabled.Invoke();
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
protected override void OnConnectionStateChanged(IpcConnectionState previous, IpcConnectionState current)
|
|
{
|
|
base.OnConnectionStateChanged(previous, current);
|
|
|
|
if (current == IpcConnectionState.Available)
|
|
{
|
|
_shownPenumbraUnavailable = false;
|
|
if (string.IsNullOrEmpty(ModDirectory))
|
|
{
|
|
CheckModDirectory();
|
|
}
|
|
return;
|
|
}
|
|
|
|
ModDirectory = string.Empty;
|
|
_redraw.CancelPendingRedraws();
|
|
|
|
if (_shownPenumbraUnavailable || current == IpcConnectionState.Unknown)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_shownPenumbraUnavailable = true;
|
|
Mediator.Publish(new NotificationMessage(
|
|
"Penumbra inactive",
|
|
"Your Penumbra installation is not active or out of date. Update Penumbra and/or the Enable Mods setting in Penumbra to continue to use Lightless. If you just updated Penumbra, ignore this message.",
|
|
NotificationType.Error));
|
|
}
|
|
|
|
private void SubscribeMediatorEvents()
|
|
{
|
|
Mediator.Subscribe<PenumbraRedrawCharacterMessage>(this, msg =>
|
|
{
|
|
_redraw.RequestImmediateRedraw(msg.Character.ObjectIndex, RedrawType.AfterGPose);
|
|
});
|
|
|
|
Mediator.Subscribe<DalamudLoginMessage>(this, _ => _shownPenumbraUnavailable = false);
|
|
|
|
Mediator.Subscribe<ActorTrackedMessage>(this, msg => _resources.TrackActor(msg.Descriptor.Address));
|
|
Mediator.Subscribe<ActorUntrackedMessage>(this, msg => _resources.UntrackActor(msg.Descriptor.Address));
|
|
Mediator.Subscribe<GameObjectHandlerCreatedMessage>(this, msg => _resources.TrackActor(msg.GameObjectHandler.Address));
|
|
Mediator.Subscribe<GameObjectHandlerDestroyedMessage>(this, msg => _resources.UntrackActor(msg.GameObjectHandler.Address));
|
|
}
|
|
|
|
private void HandlePenumbraInitialized()
|
|
{
|
|
Mediator.Publish(new PenumbraInitializedMessage());
|
|
CheckModDirectory();
|
|
_redraw.RequestImmediateRedraw(0, RedrawType.Redraw);
|
|
CheckAPI();
|
|
}
|
|
|
|
private void HandlePenumbraDisposed()
|
|
{
|
|
_redraw.CancelPendingRedraws();
|
|
ModDirectory = string.Empty;
|
|
Mediator.Publish(new PenumbraDisposedMessage());
|
|
CheckAPI();
|
|
}
|
|
|
|
private void HandlePenumbraModSettingChanged(ModSettingChange change, Guid _, string __, bool ___)
|
|
{
|
|
if (change == ModSettingChange.EnableState)
|
|
{
|
|
Mediator.Publish(new PenumbraModSettingChangedMessage());
|
|
CheckAPI();
|
|
}
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
base.Dispose(disposing);
|
|
|
|
if (!disposing)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_penumbraModSettingChanged.Dispose();
|
|
_penumbraDispose.Dispose();
|
|
_penumbraInit.Dispose();
|
|
}
|
|
}
|