mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-14 04:34:19 +01:00
Add compatible IPC for now.
This commit is contained in:
parent
1aba34f34a
commit
63e82d19dc
9 changed files with 392 additions and 305 deletions
27
Glamourer/Api/GlamourerIpc.ApiVersions.cs
Normal file
27
Glamourer/Api/GlamourerIpc.ApiVersions.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Penumbra.Api.Helpers;
|
||||||
|
|
||||||
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
|
public partial class GlamourerIpc
|
||||||
|
{
|
||||||
|
public const string LabelApiVersion = "Glamourer.ApiVersion";
|
||||||
|
public const string LabelApiVersions = "Glamourer.ApiVersions";
|
||||||
|
|
||||||
|
private readonly FuncProvider<int> _apiVersionProvider;
|
||||||
|
private readonly FuncProvider<(int Major, int Minor)> _apiVersionsProvider;
|
||||||
|
|
||||||
|
public static FuncSubscriber<int> ApiVersionSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApiVersion);
|
||||||
|
|
||||||
|
public static FuncSubscriber<(int Major, int Minor)> ApiVersionsSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApiVersions);
|
||||||
|
|
||||||
|
[Obsolete($"This call is obsolete, please use {nameof(ApiVersions)} instead.")]
|
||||||
|
public int ApiVersion()
|
||||||
|
=> CurrentApiVersionMajor;
|
||||||
|
|
||||||
|
public (int Major, int Minor) ApiVersions()
|
||||||
|
=> (CurrentApiVersionMajor, CurrentApiVersionMinor);
|
||||||
|
}
|
||||||
112
Glamourer/Api/GlamourerIpc.Apply.cs
Normal file
112
Glamourer/Api/GlamourerIpc.Apply.cs
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Glamourer.Designs;
|
||||||
|
using Glamourer.Interop.Structs;
|
||||||
|
using Penumbra.Api.Helpers;
|
||||||
|
using Penumbra.GameData.Actors;
|
||||||
|
|
||||||
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
|
public partial class GlamourerIpc
|
||||||
|
{
|
||||||
|
public const string LabelApplyAll = "Glamourer.ApplyAll";
|
||||||
|
public const string LabelApplyAllToCharacter = "Glamourer.ApplyAllToCharacter";
|
||||||
|
public const string LabelApplyOnlyEquipment = "Glamourer.ApplyOnlyEquipment";
|
||||||
|
public const string LabelApplyOnlyEquipmentToCharacter = "Glamourer.ApplyOnlyEquipmentToCharacter";
|
||||||
|
public const string LabelApplyOnlyCustomization = "Glamourer.ApplyOnlyCustomization";
|
||||||
|
public const string LabelApplyOnlyCustomizationToCharacter = "Glamourer.ApplyOnlyCustomizationToCharacter";
|
||||||
|
|
||||||
|
private readonly ActionProvider<string, string> _applyAllProvider;
|
||||||
|
private readonly ActionProvider<string, Character?> _applyAllToCharacterProvider;
|
||||||
|
private readonly ActionProvider<string, string> _applyOnlyEquipmentProvider;
|
||||||
|
private readonly ActionProvider<string, Character?> _applyOnlyEquipmentToCharacterProvider;
|
||||||
|
private readonly ActionProvider<string, string> _applyOnlyCustomizationProvider;
|
||||||
|
private readonly ActionProvider<string, Character?> _applyOnlyCustomizationToCharacterProvider;
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, string> ApplyAllSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyAll);
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, Character?> ApplyAllToCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyAllToCharacter);
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, string> ApplyOnlyEquipmentSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyOnlyEquipment);
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, Character?> ApplyOnlyEquipmentToCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyOnlyEquipmentToCharacter);
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, string> ApplyOnlyCustomizationSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyOnlyCustomization);
|
||||||
|
|
||||||
|
public static ActionSubscriber<string, Character?> ApplyOnlyCustomizationToCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelApplyOnlyCustomizationToCharacter);
|
||||||
|
|
||||||
|
|
||||||
|
public void ApplyAll(string base64, string characterName)
|
||||||
|
=> ApplyDesign(CreateTemporaryFromBase64(base64, true, true), FindActors(characterName));
|
||||||
|
|
||||||
|
public void ApplyAllToCharacter(string base64, Character? character)
|
||||||
|
=> ApplyDesign(CreateTemporaryFromBase64(base64, true, true), FindActors(character));
|
||||||
|
|
||||||
|
public void ApplyOnlyEquipment(string base64, string characterName)
|
||||||
|
=> ApplyDesign(CreateTemporaryFromBase64(base64, false, true), FindActors(characterName));
|
||||||
|
|
||||||
|
public void ApplyOnlyEquipmentToCharacter(string base64, Character? character)
|
||||||
|
=> ApplyDesign(CreateTemporaryFromBase64(base64, false, true), FindActors(character));
|
||||||
|
|
||||||
|
public void ApplyOnlyCustomization(string base64, string characterName)
|
||||||
|
=> ApplyDesign(CreateTemporaryFromBase64(base64, true, false), FindActors(characterName));
|
||||||
|
|
||||||
|
public void ApplyOnlyCustomizationToCharacter(string base64, Character? character)
|
||||||
|
=> ApplyDesign(CreateTemporaryFromBase64(base64, true, false), FindActors(character));
|
||||||
|
|
||||||
|
private void ApplyDesign(Design? design, IEnumerable<ActorIdentifier> actors)
|
||||||
|
{
|
||||||
|
if (design == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_objects.Update();
|
||||||
|
foreach (var id in actors)
|
||||||
|
{
|
||||||
|
if (!_stateManager.TryGetValue(id, out var state))
|
||||||
|
{
|
||||||
|
var data = _objects.TryGetValue(id, out var d) ? d : ActorData.Invalid;
|
||||||
|
if (!data.Valid || !_stateManager.GetOrCreate(id, data.Objects[0], out state))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stateManager.ApplyDesign(design, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Design? CreateTemporaryFromBase64(string base64, bool customize, bool equip)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ret = new Design(_items);
|
||||||
|
ret.MigrateBase64(_items, base64);
|
||||||
|
if (!customize)
|
||||||
|
{
|
||||||
|
ret.ApplyCustomize = 0;
|
||||||
|
ret.SetApplyWetness(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!equip)
|
||||||
|
{
|
||||||
|
ret.ApplyEquip = 0;
|
||||||
|
ret.SetApplyHatVisible(false);
|
||||||
|
ret.SetApplyWeaponVisible(false);
|
||||||
|
ret.SetApplyVisorToggle(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Glamourer.Log.Error($"[IPC] Could not parse base64 string [{base64}]:\n{ex}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
Glamourer/Api/GlamourerIpc.GetCustomization.cs
Normal file
51
Glamourer/Api/GlamourerIpc.GetCustomization.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Glamourer.Customization;
|
||||||
|
using Glamourer.Designs;
|
||||||
|
using Glamourer.Structs;
|
||||||
|
using Penumbra.Api.Helpers;
|
||||||
|
using Penumbra.GameData.Actors;
|
||||||
|
|
||||||
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
|
public partial class GlamourerIpc
|
||||||
|
{
|
||||||
|
public const string LabelGetAllCustomization = "Glamourer.GetAllCustomization";
|
||||||
|
public const string LabelGetAllCustomizationFromCharacter = "Glamourer.GetAllCustomizationFromCharacter";
|
||||||
|
|
||||||
|
private readonly FuncProvider<string, string?> _getAllCustomizationProvider;
|
||||||
|
private readonly FuncProvider<Character?, string?> _getAllCustomizationFromCharacterProvider;
|
||||||
|
|
||||||
|
public static FuncSubscriber<string, string?> GetAllCustomizationSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelGetAllCustomization);
|
||||||
|
|
||||||
|
public static FuncSubscriber<Character?, string?> GetAllCustomizationFromCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelGetAllCustomizationFromCharacter);
|
||||||
|
|
||||||
|
public string? GetAllCustomization(string characterName)
|
||||||
|
=> GetCustomization(FindActors(characterName));
|
||||||
|
|
||||||
|
public string? GetAllCustomizationFromCharacter(Character? character)
|
||||||
|
=> GetCustomization(FindActors(character));
|
||||||
|
|
||||||
|
private string? GetCustomization(IEnumerable<ActorIdentifier> actors)
|
||||||
|
{
|
||||||
|
var actor = actors.FirstOrDefault(ActorIdentifier.Invalid);
|
||||||
|
if (!actor.IsValid)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!_stateManager.TryGetValue(actor, out var state))
|
||||||
|
{
|
||||||
|
_objects.Update();
|
||||||
|
if (!_objects.TryGetValue(actor, out var data) || !data.Valid)
|
||||||
|
return null;
|
||||||
|
if (!_stateManager.GetOrCreate(actor, data.Objects[0], out state))
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DesignBase64Migration.CreateOldBase64(state.ModelData, EquipFlagExtensions.All, CustomizeFlagExtensions.All, true, true,
|
||||||
|
true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
37
Glamourer/Api/GlamourerIpc.Revert.cs
Normal file
37
Glamourer/Api/GlamourerIpc.Revert.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Penumbra.Api.Helpers;
|
||||||
|
using Penumbra.GameData.Actors;
|
||||||
|
|
||||||
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
|
public partial class GlamourerIpc
|
||||||
|
{
|
||||||
|
public const string LabelRevert = "Glamourer.Revert";
|
||||||
|
public const string LabelRevertCharacter = "Glamourer.RevertCharacter";
|
||||||
|
|
||||||
|
private readonly ActionProvider<string> _revertProvider;
|
||||||
|
private readonly ActionProvider<Character?> _revertCharacterProvider;
|
||||||
|
|
||||||
|
public static ActionSubscriber<string> RevertSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelRevert);
|
||||||
|
|
||||||
|
public static ActionSubscriber<Character?> RevertCharacterSubscriber(DalamudPluginInterface pi)
|
||||||
|
=> new(pi, LabelRevertCharacter);
|
||||||
|
|
||||||
|
public void Revert(string characterName)
|
||||||
|
=> Revert(FindActors(characterName));
|
||||||
|
|
||||||
|
public void RevertCharacter(Character? character)
|
||||||
|
=> Revert(FindActors(character));
|
||||||
|
|
||||||
|
private void Revert(IEnumerable<ActorIdentifier> actors)
|
||||||
|
{
|
||||||
|
foreach (var id in actors)
|
||||||
|
{
|
||||||
|
if (_stateManager.TryGetValue(id, out var state))
|
||||||
|
_stateManager.ResetState(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,318 +1,87 @@
|
||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Game.ClientState.Objects;
|
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
|
||||||
using Dalamud.Logging;
|
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Dalamud.Plugin.Ipc;
|
|
||||||
using System;
|
using System;
|
||||||
using Glamourer.Api;
|
using System.Collections.Generic;
|
||||||
using Glamourer.Designs;
|
using System.Linq;
|
||||||
|
using Glamourer.Interop;
|
||||||
using Glamourer.Services;
|
using Glamourer.Services;
|
||||||
using Glamourer.State;
|
using Glamourer.State;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Helpers;
|
||||||
|
using Penumbra.GameData.Actors;
|
||||||
|
using Penumbra.String;
|
||||||
|
|
||||||
namespace Glamourer;
|
namespace Glamourer.Api;
|
||||||
|
|
||||||
public partial class Glamourer
|
public partial class GlamourerIpc : IDisposable
|
||||||
{
|
{
|
||||||
public class GlamourerIpc : IDisposable
|
public const int CurrentApiVersionMajor = 0;
|
||||||
|
public const int CurrentApiVersionMinor = 1;
|
||||||
|
|
||||||
|
private readonly StateManager _stateManager;
|
||||||
|
private readonly ObjectManager _objects;
|
||||||
|
private readonly ActorService _actors;
|
||||||
|
private readonly ItemManager _items;
|
||||||
|
|
||||||
|
public GlamourerIpc(DalamudPluginInterface pi, StateManager stateManager, ObjectManager objects, ActorService actors, ItemManager items)
|
||||||
{
|
{
|
||||||
public const int CurrentApiVersion = 0;
|
_stateManager = stateManager;
|
||||||
public const string LabelProviderApiVersion = "Glamourer.ApiVersion";
|
_objects = objects;
|
||||||
public const string LabelProviderGetAllCustomization = "Glamourer.GetAllCustomization";
|
_actors = actors;
|
||||||
public const string LabelProviderGetAllCustomizationFromCharacter = "Glamourer.GetAllCustomizationFromCharacter";
|
_items = items;
|
||||||
public const string LabelProviderApplyAll = "Glamourer.ApplyAll";
|
_apiVersionProvider = new FuncProvider<int>(pi, LabelApiVersion, ApiVersion);
|
||||||
public const string LabelProviderApplyAllToCharacter = "Glamourer.ApplyAllToCharacter";
|
_apiVersionsProvider = new FuncProvider<(int Major, int Minor)>(pi, LabelApiVersions, ApiVersions);
|
||||||
public const string LabelProviderApplyOnlyEquipment = "Glamourer.ApplyOnlyEquipment";
|
|
||||||
public const string LabelProviderApplyOnlyEquipmentToCharacter = "Glamourer.ApplyOnlyEquipmentToCharacter";
|
|
||||||
public const string LabelProviderApplyOnlyCustomization = "Glamourer.ApplyOnlyCustomization";
|
|
||||||
public const string LabelProviderApplyOnlyCustomizationToCharacter = "Glamourer.ApplyOnlyCustomizationToCharacter";
|
|
||||||
public const string LabelProviderRevert = "Glamourer.Revert";
|
|
||||||
public const string LabelProviderRevertCharacter = "Glamourer.RevertCharacter";
|
|
||||||
|
|
||||||
private readonly ObjectTable _objectTable;
|
_getAllCustomizationProvider = new FuncProvider<string, string?>(pi, LabelGetAllCustomization, GetAllCustomization);
|
||||||
private readonly DalamudPluginInterface _pluginInterface;
|
_getAllCustomizationFromCharacterProvider =
|
||||||
private readonly ActiveDesign.Manager _stateManager;
|
new FuncProvider<Character?, string?>(pi, LabelGetAllCustomizationFromCharacter, GetAllCustomizationFromCharacter);
|
||||||
private readonly ItemManager _items;
|
|
||||||
private readonly PenumbraAttach _penumbra;
|
|
||||||
private readonly ActorService _actors;
|
|
||||||
|
|
||||||
internal ICallGateProvider<string, string?>? ProviderGetAllCustomization;
|
_applyAllProvider = new ActionProvider<string, string>(pi, LabelApplyAll, ApplyAll);
|
||||||
internal ICallGateProvider<Character?, string?>? ProviderGetAllCustomizationFromCharacter;
|
_applyAllToCharacterProvider = new ActionProvider<string, Character?>(pi, LabelApplyAllToCharacter, ApplyAllToCharacter);
|
||||||
internal ICallGateProvider<string, string, object>? ProviderApplyAll;
|
_applyOnlyEquipmentProvider = new ActionProvider<string, string>(pi, LabelApplyOnlyEquipment, ApplyOnlyEquipment);
|
||||||
internal ICallGateProvider<string, Character?, object>? ProviderApplyAllToCharacter;
|
_applyOnlyEquipmentToCharacterProvider =
|
||||||
internal ICallGateProvider<string, string, object>? ProviderApplyOnlyCustomization;
|
new ActionProvider<string, Character?>(pi, LabelApplyOnlyEquipmentToCharacter, ApplyOnlyEquipmentToCharacter);
|
||||||
internal ICallGateProvider<string, Character?, object>? ProviderApplyOnlyCustomizationToCharacter;
|
_applyOnlyCustomizationProvider = new ActionProvider<string, string>(pi, LabelApplyOnlyCustomization, ApplyOnlyCustomization);
|
||||||
internal ICallGateProvider<string, string, object>? ProviderApplyOnlyEquipment;
|
_applyOnlyCustomizationToCharacterProvider =
|
||||||
internal ICallGateProvider<string, Character?, object>? ProviderApplyOnlyEquipmentToCharacter;
|
new ActionProvider<string, Character?>(pi, LabelApplyOnlyCustomizationToCharacter, ApplyOnlyCustomizationToCharacter);
|
||||||
internal ICallGateProvider<string, object>? ProviderRevert;
|
|
||||||
internal ICallGateProvider<Character?, object>? ProviderRevertCharacter;
|
|
||||||
internal ICallGateProvider<int>? ProviderGetApiVersion;
|
|
||||||
|
|
||||||
public GlamourerIpc(ObjectTable objectTable, DalamudPluginInterface pluginInterface, ActiveDesign.Manager stateManager,
|
_revertProvider = new ActionProvider<string>(pi, LabelRevert, Revert);
|
||||||
ItemManager items, PenumbraAttach penumbra, ActorService actors)
|
_revertCharacterProvider = new ActionProvider<Character?>(pi, LabelRevertCharacter, RevertCharacter);
|
||||||
{
|
}
|
||||||
_objectTable = objectTable;
|
|
||||||
_pluginInterface = pluginInterface;
|
|
||||||
_stateManager = stateManager;
|
|
||||||
_items = items;
|
|
||||||
_penumbra = penumbra;
|
|
||||||
_actors = actors;
|
|
||||||
|
|
||||||
InitializeProviders();
|
public void Dispose()
|
||||||
}
|
{
|
||||||
|
_apiVersionProvider.Dispose();
|
||||||
|
_apiVersionsProvider.Dispose();
|
||||||
|
|
||||||
public void Dispose()
|
_getAllCustomizationProvider.Dispose();
|
||||||
=> DisposeProviders();
|
_getAllCustomizationFromCharacterProvider.Dispose();
|
||||||
|
|
||||||
private void DisposeProviders()
|
_applyAllProvider.Dispose();
|
||||||
{
|
_applyAllToCharacterProvider.Dispose();
|
||||||
ProviderGetAllCustomization?.UnregisterFunc();
|
_applyOnlyEquipmentProvider.Dispose();
|
||||||
ProviderGetAllCustomizationFromCharacter?.UnregisterFunc();
|
_applyOnlyEquipmentToCharacterProvider.Dispose();
|
||||||
ProviderApplyAll?.UnregisterAction();
|
_applyOnlyCustomizationProvider.Dispose();
|
||||||
ProviderApplyAllToCharacter?.UnregisterAction();
|
_applyOnlyCustomizationToCharacterProvider.Dispose();
|
||||||
ProviderApplyOnlyCustomization?.UnregisterAction();
|
_revertProvider.Dispose();
|
||||||
ProviderApplyOnlyCustomizationToCharacter?.UnregisterAction();
|
_revertCharacterProvider.Dispose();
|
||||||
ProviderApplyOnlyEquipment?.UnregisterAction();
|
}
|
||||||
ProviderApplyOnlyEquipmentToCharacter?.UnregisterAction();
|
|
||||||
ProviderRevert?.UnregisterAction();
|
|
||||||
ProviderRevertCharacter?.UnregisterAction();
|
|
||||||
ProviderGetApiVersion?.UnregisterFunc();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeProviders()
|
private IEnumerable<ActorIdentifier> FindActors(string actorName)
|
||||||
{
|
{
|
||||||
try
|
if (actorName.Length == 0 || !ByteString.FromString(actorName, out var byteString))
|
||||||
{
|
return Array.Empty<ActorIdentifier>();
|
||||||
ProviderGetApiVersion = _pluginInterface.GetIpcProvider<int>(LabelProviderApiVersion);
|
|
||||||
ProviderGetApiVersion.RegisterFunc(GetApiVersion);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApiVersion}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
_objects.Update();
|
||||||
{
|
return _objects.Where(i => i.Key is { IsValid: true, Type: IdentifierType.Player } && i.Key.PlayerName == byteString)
|
||||||
ProviderGetAllCustomization = _pluginInterface.GetIpcProvider<string, string?>(LabelProviderGetAllCustomization);
|
.Select(i => i.Key);
|
||||||
ProviderGetAllCustomization.RegisterFunc(GetAllCustomization);
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApplyOnlyEquipment}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
private IEnumerable<ActorIdentifier> FindActors(Character? character)
|
||||||
{
|
{
|
||||||
ProviderGetAllCustomizationFromCharacter =
|
var id = _actors.AwaitedService.FromObject(character, true, true, false);
|
||||||
_pluginInterface.GetIpcProvider<Character?, string?>(LabelProviderGetAllCustomizationFromCharacter);
|
if (!id.IsValid)
|
||||||
ProviderGetAllCustomizationFromCharacter.RegisterFunc(GetAllCustomization);
|
yield break;
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderGetAllCustomizationFromCharacter}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
yield return id;
|
||||||
{
|
|
||||||
ProviderApplyAll =
|
|
||||||
_pluginInterface.GetIpcProvider<string, string, object>(LabelProviderApplyAll);
|
|
||||||
ProviderApplyAll.RegisterAction(ApplyAll);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApplyAll}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProviderApplyAllToCharacter =
|
|
||||||
_pluginInterface.GetIpcProvider<string, Character?, object>(LabelProviderApplyAllToCharacter);
|
|
||||||
ProviderApplyAllToCharacter.RegisterAction(ApplyAll);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApplyAll}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProviderApplyOnlyCustomization =
|
|
||||||
_pluginInterface.GetIpcProvider<string, string, object>(LabelProviderApplyOnlyCustomization);
|
|
||||||
ProviderApplyOnlyCustomization.RegisterAction(ApplyOnlyCustomization);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApplyOnlyCustomization}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProviderApplyOnlyCustomizationToCharacter =
|
|
||||||
_pluginInterface.GetIpcProvider<string, Character?, object>(LabelProviderApplyOnlyCustomizationToCharacter);
|
|
||||||
ProviderApplyOnlyCustomizationToCharacter.RegisterAction(ApplyOnlyCustomization);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApplyOnlyCustomization}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProviderApplyOnlyEquipment =
|
|
||||||
_pluginInterface.GetIpcProvider<string, string, object>(LabelProviderApplyOnlyEquipment);
|
|
||||||
ProviderApplyOnlyEquipment.RegisterAction(ApplyOnlyEquipment);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApplyOnlyEquipment}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProviderApplyOnlyEquipmentToCharacter =
|
|
||||||
_pluginInterface.GetIpcProvider<string, Character?, object>(LabelProviderApplyOnlyEquipmentToCharacter);
|
|
||||||
ProviderApplyOnlyEquipmentToCharacter.RegisterAction(ApplyOnlyEquipment);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderApplyOnlyEquipment}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProviderRevert =
|
|
||||||
_pluginInterface.GetIpcProvider<string, object>(LabelProviderRevert);
|
|
||||||
ProviderRevert.RegisterAction(Revert);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderRevert}.");
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ProviderRevertCharacter =
|
|
||||||
_pluginInterface.GetIpcProvider<Character?, object>(LabelProviderRevertCharacter);
|
|
||||||
ProviderRevertCharacter.RegisterAction(Revert);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
PluginLog.Error(ex, $"Error registering IPC provider for {LabelProviderRevert}.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int GetApiVersion()
|
|
||||||
=> CurrentApiVersion;
|
|
||||||
|
|
||||||
private void ApplyAll(string customization, string characterName)
|
|
||||||
{
|
|
||||||
foreach (var gameObject in _objectTable)
|
|
||||||
{
|
|
||||||
if (gameObject.Name.ToString() == characterName)
|
|
||||||
{
|
|
||||||
ApplyAll(customization, gameObject as Character);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyAll(string customization, Character? character)
|
|
||||||
{
|
|
||||||
if (character == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var design = Design.CreateTemporaryFromBase64(_items, customization, true, true);
|
|
||||||
var active = _stateManager.GetOrCreateSave(character.Address);
|
|
||||||
_stateManager.ApplyDesign(active, design, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyOnlyCustomization(string customization, string characterName)
|
|
||||||
{
|
|
||||||
foreach (var gameObject in _objectTable)
|
|
||||||
{
|
|
||||||
if (gameObject.Name.ToString() == characterName)
|
|
||||||
{
|
|
||||||
ApplyOnlyCustomization(customization, gameObject as Character);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyOnlyCustomization(string customization, Character? character)
|
|
||||||
{
|
|
||||||
if (character == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var design = Design.CreateTemporaryFromBase64(_items, customization, true, false);
|
|
||||||
var active = _stateManager.GetOrCreateSave(character.Address);
|
|
||||||
_stateManager.ApplyDesign(active, design, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyOnlyEquipment(string customization, string characterName)
|
|
||||||
{
|
|
||||||
foreach (var gameObject in _objectTable)
|
|
||||||
{
|
|
||||||
if (gameObject.Name.ToString() != characterName)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ApplyOnlyEquipment(customization, gameObject as Character);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ApplyOnlyEquipment(string customization, Character? character)
|
|
||||||
{
|
|
||||||
if (character == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var design = Design.CreateTemporaryFromBase64(_items, customization, false, true);
|
|
||||||
var active = _stateManager.GetOrCreateSave(character.Address);
|
|
||||||
_stateManager.ApplyDesign(active, design, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Revert(string characterName)
|
|
||||||
{
|
|
||||||
foreach (var gameObject in _objectTable)
|
|
||||||
{
|
|
||||||
if (gameObject.Name.ToString() != characterName)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Revert(gameObject as Character);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Revert(Character? character)
|
|
||||||
{
|
|
||||||
if (character == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ident = _actors.AwaitedService.FromObject(character, true, false, false);
|
|
||||||
_stateManager.DeleteSave(ident);
|
|
||||||
_penumbra.RedrawObject(character.Address, RedrawType.Redraw);
|
|
||||||
}
|
|
||||||
|
|
||||||
private string? GetAllCustomization(Character? character)
|
|
||||||
{
|
|
||||||
if (character == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var ident = _actors.AwaitedService.FromObject(character, true, false, false);
|
|
||||||
if (!_stateManager.TryGetValue(ident, out var design))
|
|
||||||
design = new ActiveDesign(_items, ident, character.Address);
|
|
||||||
|
|
||||||
return design.CreateOldBase64();
|
|
||||||
}
|
|
||||||
|
|
||||||
private string? GetAllCustomization(string characterName)
|
|
||||||
{
|
|
||||||
foreach (var gameObject in _objectTable)
|
|
||||||
{
|
|
||||||
if (gameObject.Name.ToString() == characterName)
|
|
||||||
return GetAllCustomization(gameObject as Character);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ public static class DesignBase64Migration
|
||||||
data.SetItem(EquipSlot.MainHand, main);
|
data.SetItem(EquipSlot.MainHand, main);
|
||||||
data.SetStain(EquipSlot.MainHand, cur[0].Stain);
|
data.SetStain(EquipSlot.MainHand, cur[0].Stain);
|
||||||
var off = items.Identify(EquipSlot.OffHand, cur[1].Set, cur[1].Type, (byte)cur[1].Variant, main.Type);
|
var off = items.Identify(EquipSlot.OffHand, cur[1].Set, cur[1].Type, (byte)cur[1].Variant, main.Type);
|
||||||
if (!off.Valid)
|
if (main.Type.Offhand() != FullEquipType.Unknown && !off.Valid)
|
||||||
throw new Exception($"Base64 string invalid, weapon could not be identified.");
|
throw new Exception($"Base64 string invalid, weapon could not be identified.");
|
||||||
|
|
||||||
data.SetItem(EquipSlot.OffHand, off);
|
data.SetItem(EquipSlot.OffHand, off);
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,12 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Dalamud.Game.ClientState.Objects;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
|
using Dalamud.Plugin;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
|
using Glamourer.Api;
|
||||||
using Glamourer.Customization;
|
using Glamourer.Customization;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
|
|
@ -27,6 +29,7 @@ namespace Glamourer.Gui.Tabs;
|
||||||
|
|
||||||
public unsafe class DebugTab : ITab
|
public unsafe class DebugTab : ITab
|
||||||
{
|
{
|
||||||
|
private readonly DalamudPluginInterface _pluginInterface;
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly VisorService _visorService;
|
private readonly VisorService _visorService;
|
||||||
private readonly ChangeCustomizeService _changeCustomizeService;
|
private readonly ChangeCustomizeService _changeCustomizeService;
|
||||||
|
|
@ -36,6 +39,7 @@ public unsafe class DebugTab : ITab
|
||||||
private readonly PenumbraService _penumbra;
|
private readonly PenumbraService _penumbra;
|
||||||
private readonly ObjectTable _objects;
|
private readonly ObjectTable _objects;
|
||||||
private readonly ObjectManager _objectManager;
|
private readonly ObjectManager _objectManager;
|
||||||
|
private readonly GlamourerIpc _ipc;
|
||||||
|
|
||||||
private readonly ItemManager _items;
|
private readonly ItemManager _items;
|
||||||
private readonly ActorService _actors;
|
private readonly ActorService _actors;
|
||||||
|
|
@ -57,7 +61,7 @@ public unsafe class DebugTab : ITab
|
||||||
UpdateSlotService updateSlotService, WeaponService weaponService, PenumbraService penumbra,
|
UpdateSlotService updateSlotService, WeaponService weaponService, PenumbraService penumbra,
|
||||||
ActorService actors, ItemManager items, CustomizationService customization, ObjectManager objectManager,
|
ActorService actors, ItemManager items, CustomizationService customization, ObjectManager objectManager,
|
||||||
DesignFileSystem designFileSystem, DesignManager designManager, StateManager state, Configuration config,
|
DesignFileSystem designFileSystem, DesignManager designManager, StateManager state, Configuration config,
|
||||||
PenumbraChangedItemTooltip penumbraTooltip, MetaService metaService)
|
PenumbraChangedItemTooltip penumbraTooltip, MetaService metaService, GlamourerIpc ipc, DalamudPluginInterface pluginInterface)
|
||||||
{
|
{
|
||||||
_changeCustomizeService = changeCustomizeService;
|
_changeCustomizeService = changeCustomizeService;
|
||||||
_visorService = visorService;
|
_visorService = visorService;
|
||||||
|
|
@ -74,7 +78,9 @@ public unsafe class DebugTab : ITab
|
||||||
_state = state;
|
_state = state;
|
||||||
_config = config;
|
_config = config;
|
||||||
_penumbraTooltip = penumbraTooltip;
|
_penumbraTooltip = penumbraTooltip;
|
||||||
_metaService = metaService;
|
_metaService = metaService;
|
||||||
|
_ipc = ipc;
|
||||||
|
_pluginInterface = pluginInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlySpan<byte> Label
|
public ReadOnlySpan<byte> Label
|
||||||
|
|
@ -91,6 +97,7 @@ public unsafe class DebugTab : ITab
|
||||||
DrawPenumbraHeader();
|
DrawPenumbraHeader();
|
||||||
DrawDesigns();
|
DrawDesigns();
|
||||||
DrawState();
|
DrawState();
|
||||||
|
DrawIpc();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Interop
|
#region Interop
|
||||||
|
|
@ -778,7 +785,7 @@ public unsafe class DebugTab : ITab
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGui.SetNextItemWidth(-1);
|
ImGui.SetNextItemWidth(-1);
|
||||||
ImGui.InputTextWithHint("##base64", "Base 64 input...", ref _base64, 2048);
|
ImGui.InputTextWithHint("##base64", "Base 64 input...", ref _base64, 2047);
|
||||||
if (ImGui.IsItemDeactivatedAfterEdit())
|
if (ImGui.IsItemDeactivatedAfterEdit())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -1108,4 +1115,86 @@ public unsafe class DebugTab : ITab
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region IPC
|
||||||
|
|
||||||
|
private string _gameObjectName = string.Empty;
|
||||||
|
private string _base64Apply = string.Empty;
|
||||||
|
|
||||||
|
private void DrawIpc()
|
||||||
|
{
|
||||||
|
if (!ImGui.CollapsingHeader("IPC Tester"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui.InputInt("Game Object Index", ref _gameObjectIndex, 0, 0);
|
||||||
|
ImGui.InputTextWithHint("##gameObject", "Character Name...", ref _gameObjectName, 64);
|
||||||
|
ImGui.InputTextWithHint("##base64", "Design Base64...", ref _base64Apply, 2047);
|
||||||
|
using var table = ImRaii.Table("##ipc", 2, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg);
|
||||||
|
if (!table)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApiVersions);
|
||||||
|
var (major, minor) = GlamourerIpc.ApiVersionsSubscriber(_pluginInterface).Invoke();
|
||||||
|
ImGuiUtil.DrawTableColumn($"({major}, {minor})");
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelGetAllCustomization);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var base64 = GlamourerIpc.GetAllCustomizationSubscriber(_pluginInterface).Invoke(_gameObjectName);
|
||||||
|
if (base64 != null)
|
||||||
|
ImGuiUtil.CopyOnClickSelectable(base64);
|
||||||
|
else
|
||||||
|
ImGui.TextUnformatted("Error");
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelGetAllCustomizationFromCharacter);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
base64 = GlamourerIpc.GetAllCustomizationFromCharacterSubscriber(_pluginInterface).Invoke(_objects[_gameObjectIndex] as Character);
|
||||||
|
if (base64 != null)
|
||||||
|
ImGuiUtil.CopyOnClickSelectable(base64);
|
||||||
|
else
|
||||||
|
ImGui.TextUnformatted("Error");
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelRevert);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Revert##Name"))
|
||||||
|
GlamourerIpc.RevertSubscriber(_pluginInterface).Invoke(_gameObjectName);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelRevertCharacter);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Revert##Character"))
|
||||||
|
GlamourerIpc.RevertCharacterSubscriber(_pluginInterface).Invoke(_objects[_gameObjectIndex] as Character);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAll);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply##AllName"))
|
||||||
|
GlamourerIpc.ApplyAllSubscriber(_pluginInterface).Invoke(_base64Apply, _gameObjectName);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyAllToCharacter);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply##AllCharacter"))
|
||||||
|
GlamourerIpc.ApplyAllToCharacterSubscriber(_pluginInterface).Invoke(_base64Apply, _objects[_gameObjectIndex] as Character);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyEquipment);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply##EquipName"))
|
||||||
|
GlamourerIpc.ApplyOnlyEquipmentSubscriber(_pluginInterface).Invoke(_base64Apply, _gameObjectName);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyEquipmentToCharacter);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply##EquipCharacter"))
|
||||||
|
GlamourerIpc.ApplyOnlyEquipmentToCharacterSubscriber(_pluginInterface)
|
||||||
|
.Invoke(_base64Apply, _objects[_gameObjectIndex] as Character);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyCustomization);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply##CustomizeName"))
|
||||||
|
GlamourerIpc.ApplyOnlyCustomizationSubscriber(_pluginInterface).Invoke(_base64Apply, _gameObjectName);
|
||||||
|
|
||||||
|
ImGuiUtil.DrawTableColumn(GlamourerIpc.LabelApplyOnlyCustomizationToCharacter);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (ImGui.Button("Apply##CustomizeCharacter"))
|
||||||
|
GlamourerIpc.ApplyOnlyCustomizationToCharacterSubscriber(_pluginInterface)
|
||||||
|
.Invoke(_base64Apply, _objects[_gameObjectIndex] as Character);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ public class ItemManager : IDisposable
|
||||||
public bool IsOffhandValid(FullEquipType offType, uint offId, out EquipItem off)
|
public bool IsOffhandValid(FullEquipType offType, uint offId, out EquipItem off)
|
||||||
{
|
{
|
||||||
off = Resolve(offType, offId);
|
off = Resolve(offType, offId);
|
||||||
return off.Valid;
|
return offType == FullEquipType.Unknown || off.Valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Returns whether an offhand is valid given mainhand. </summary>
|
/// <summary> Returns whether an offhand is valid given mainhand. </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
|
using Glamourer.Api;
|
||||||
using Glamourer.Designs;
|
using Glamourer.Designs;
|
||||||
using Glamourer.Events;
|
using Glamourer.Events;
|
||||||
using Glamourer.Gui;
|
using Glamourer.Gui;
|
||||||
|
|
@ -99,5 +100,6 @@ public static class ServiceManager
|
||||||
.AddSingleton<PenumbraChangedItemTooltip>();
|
.AddSingleton<PenumbraChangedItemTooltip>();
|
||||||
|
|
||||||
private static IServiceCollection AddApi(this IServiceCollection services)
|
private static IServiceCollection AddApi(this IServiceCollection services)
|
||||||
=> services.AddSingleton<CommandService>();
|
=> services.AddSingleton<CommandService>()
|
||||||
|
.AddSingleton<GlamourerIpc>();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue