diff --git a/Penumbra/Api/IPenumbraApi.cs b/Penumbra/Api/IPenumbraApi.cs index 1fa7b576..cc9c7e56 100644 --- a/Penumbra/Api/IPenumbraApi.cs +++ b/Penumbra/Api/IPenumbraApi.cs @@ -97,6 +97,10 @@ public interface IPenumbraApi : IPenumbraApiBase // Obtain a list of all installed mods. The first string is their directory name, the second string is their mod name. public IList< (string, string) > GetModList(); + // Obtain a base64 encoded, zipped json-string with a prepended version-byte of the current manipulations + // for the given collection associated with the character name, or the default collection. + public string GetMetaManipulations( string characterName ); + // ############## Mod Settings ################# diff --git a/Penumbra/Api/IpcTester.cs b/Penumbra/Api/IpcTester.cs index 30059913..9a9794b5 100644 --- a/Penumbra/Api/IpcTester.cs +++ b/Penumbra/Api/IpcTester.cs @@ -14,7 +14,6 @@ using OtterGui.Raii; using Penumbra.GameData.ByteString; using Penumbra.GameData.Enums; using Penumbra.Mods; -using Penumbra.Util; namespace Penumbra.Api; @@ -449,6 +448,14 @@ public class IpcTester : IDisposable ImGui.OpenPopup( "Ipc Data" ); } + DrawIntro(PenumbraIpc.LabelProviderGetMetaManipulations, "Meta Manipulations" ); + if( ImGui.Button( "Copy to Clipboard" ) ) + { + var base64 = _pi.GetIpcSubscriber< string, string >( PenumbraIpc.LabelProviderGetMetaManipulations ) + .InvokeFunc( _characterCollectionName ); + ImGui.SetClipboardText( base64 ); + } + ImGui.SetNextWindowSize( ImGuiHelpers.ScaledVector2( 500, 500 ) ); using var p = ImRaii.Popup( "Ipc Data" ); if( p ) diff --git a/Penumbra/Api/PenumbraApi.cs b/Penumbra/Api/PenumbraApi.cs index 2efeaaa9..e56f0b7a 100644 --- a/Penumbra/Api/PenumbraApi.cs +++ b/Penumbra/Api/PenumbraApi.cs @@ -443,6 +443,16 @@ public class PenumbraApi : IDisposable, IPenumbraApi }; } + public string GetMetaManipulations( string characterName ) + { + CheckInitialized(); + var collection = Penumbra.TempMods.Collections.TryGetValue( characterName, out var c ) + ? c + : Penumbra.CollectionManager.Character( characterName ); + var set = collection.MetaCache?.Manipulations ?? Array.Empty< MetaManipulation >(); + return Functions.ToCompressedBase64( set, MetaManipulation.CurrentVersion ); + } + internal bool HasTooltip => ChangedItemTooltip != null; diff --git a/Penumbra/Api/PenumbraIpc.cs b/Penumbra/Api/PenumbraIpc.cs index 600dcf9e..a60d63f4 100644 --- a/Penumbra/Api/PenumbraIpc.cs +++ b/Penumbra/Api/PenumbraIpc.cs @@ -326,12 +326,14 @@ public partial class PenumbraIpc public const string LabelProviderCurrentCollectionName = "Penumbra.GetCurrentCollectionName"; public const string LabelProviderDefaultCollectionName = "Penumbra.GetDefaultCollectionName"; public const string LabelProviderCharacterCollectionName = "Penumbra.GetCharacterCollectionName"; + public const string LabelProviderGetMetaManipulations = "Penumbra.GetMetaManipulations"; internal ICallGateProvider< IList< (string, string) > >? ProviderGetMods; internal ICallGateProvider< IList< string > >? ProviderGetCollections; internal ICallGateProvider< string >? ProviderCurrentCollectionName; internal ICallGateProvider< string >? ProviderDefaultCollectionName; internal ICallGateProvider< string, (string, bool) >? ProviderCharacterCollectionName; + internal ICallGateProvider< string, string >? ProviderGetMetaManipulations; private void InitializeDataProviders( DalamudPluginInterface pi ) { @@ -384,6 +386,16 @@ public partial class PenumbraIpc { PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); } + + try + { + ProviderGetMetaManipulations = pi.GetIpcProvider< string, string >( LabelProviderGetMetaManipulations ); + ProviderGetMetaManipulations.RegisterFunc( Api.GetMetaManipulations ); + } + catch( Exception e ) + { + PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" ); + } } private void DisposeDataProviders() @@ -393,6 +405,7 @@ public partial class PenumbraIpc ProviderCurrentCollectionName?.UnregisterFunc(); ProviderDefaultCollectionName?.UnregisterFunc(); ProviderCharacterCollectionName?.UnregisterFunc(); + ProviderGetMetaManipulations?.UnregisterFunc(); } } diff --git a/Penumbra/Meta/Manager/MetaManager.cs b/Penumbra/Meta/Manager/MetaManager.cs index a71e37b1..50404234 100644 --- a/Penumbra/Meta/Manager/MetaManager.cs +++ b/Penumbra/Meta/Manager/MetaManager.cs @@ -1,5 +1,6 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Runtime.CompilerServices; using Penumbra.Collections; using Penumbra.Meta.Files; @@ -30,7 +31,7 @@ public partial class MetaManager : IDisposable } } - public bool TryGetValue( MetaManipulation manip, [NotNullWhen(true)] out IMod? mod ) + public bool TryGetValue( MetaManipulation manip, [NotNullWhen( true )] out IMod? mod ) { mod = manip.ManipulationType switch { @@ -53,6 +54,15 @@ public partial class MetaManager : IDisposable + Est.Manipulations.Count + Eqp.Manipulations.Count; + public MetaManipulation[] Manipulations + => Imc.Manipulations.Keys.Select( m => ( MetaManipulation )m ) + .Concat( Eqdp.Manipulations.Keys.Select( m => ( MetaManipulation )m ) ) + .Concat( Cmp.Manipulations.Keys.Select( m => ( MetaManipulation )m ) ) + .Concat( Gmp.Manipulations.Keys.Select( m => ( MetaManipulation )m ) ) + .Concat( Est.Manipulations.Keys.Select( m => ( MetaManipulation )m ) ) + .Concat( Eqp.Manipulations.Keys.Select( m => ( MetaManipulation )m ) ) + .ToArray(); + public MetaManager( ModCollection collection ) => Imc = new MetaManagerImc( collection );