mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add object-specific IPC for resolving paths and meta.
This commit is contained in:
parent
f1b495dff4
commit
ca51c3b107
6 changed files with 103 additions and 16 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 1a3f9d501ad44e020500eb7d0a79f91a04e46c93
|
||||
Subproject commit 891eb195c29904824004c45f84b92a9e1dd98ddf
|
||||
|
|
@ -13,7 +13,6 @@ using Penumbra.Api.Enums;
|
|||
using Penumbra.Api.Helpers;
|
||||
using Penumbra.String;
|
||||
using Penumbra.String.Classes;
|
||||
using Swan;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
|
@ -582,6 +581,7 @@ public class IpcTester : IDisposable
|
|||
private string _currentResolvePath = string.Empty;
|
||||
private string _currentResolveCharacter = string.Empty;
|
||||
private string _currentReversePath = string.Empty;
|
||||
private int _currentReverseIdx = 0;
|
||||
|
||||
public Resolve( DalamudPluginInterface pi )
|
||||
=> _pi = pi;
|
||||
|
|
@ -598,6 +598,7 @@ public class IpcTester : IDisposable
|
|||
ImGui.InputTextWithHint( "##resolveCharacter", "Character Name (leave blank for default)...", ref _currentResolveCharacter, 32 );
|
||||
ImGui.InputTextWithHint( "##resolveInversePath", "Reverse-resolve this path...", ref _currentReversePath,
|
||||
Utf8GamePath.MaxGamePathLength );
|
||||
ImGui.InputInt( "##resolveIdx", ref _currentReverseIdx, 0, 0 );
|
||||
using var table = ImRaii.Table( string.Empty, 3, ImGuiTableFlags.SizingFixedFit );
|
||||
if( !table )
|
||||
{
|
||||
|
|
@ -628,6 +629,12 @@ public class IpcTester : IDisposable
|
|||
ImGui.TextUnformatted( Ipc.ResolveCharacterPath.Subscriber( _pi ).Invoke( _currentResolvePath, _currentResolveCharacter ) );
|
||||
}
|
||||
|
||||
DrawIntro( Ipc.ResolveGameObjectPath.Label, "Game Object Collection Resolve" );
|
||||
if( _currentResolvePath.Length != 0 )
|
||||
{
|
||||
ImGui.TextUnformatted( Ipc.ResolveGameObjectPath.Subscriber( _pi ).Invoke( _currentResolvePath, _currentReverseIdx ) );
|
||||
}
|
||||
|
||||
DrawIntro( Ipc.ReverseResolvePath.Label, "Reversed Game Paths" );
|
||||
if( _currentReversePath.Length > 0 )
|
||||
{
|
||||
|
|
@ -655,6 +662,20 @@ public class IpcTester : IDisposable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
DrawIntro( Ipc.ReverseResolveGameObjectPath.Label, "Reversed Game Paths (Game Object)" );
|
||||
if( _currentReversePath.Length > 0 )
|
||||
{
|
||||
var list = Ipc.ReverseResolveGameObjectPath.Subscriber( _pi ).Invoke( _currentReversePath, _currentReverseIdx );
|
||||
if( list.Length > 0 )
|
||||
{
|
||||
ImGui.TextUnformatted( list[ 0 ] );
|
||||
if( list.Length > 1 && ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip( string.Join( "\n", list.Skip( 1 ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -763,7 +784,8 @@ public class IpcTester : IDisposable
|
|||
{
|
||||
private readonly DalamudPluginInterface _pi;
|
||||
|
||||
private string _characterName = string.Empty;
|
||||
private string _characterName = string.Empty;
|
||||
private int _gameObjectIndex = 0;
|
||||
|
||||
public Meta( DalamudPluginInterface pi )
|
||||
=> _pi = pi;
|
||||
|
|
@ -777,6 +799,7 @@ public class IpcTester : IDisposable
|
|||
}
|
||||
|
||||
ImGui.InputTextWithHint( "##characterName", "Character Name...", ref _characterName, 64 );
|
||||
ImGui.InputInt( "##metaIdx", ref _gameObjectIndex, 0, 0 );
|
||||
using var table = ImRaii.Table( string.Empty, 3, ImGuiTableFlags.SizingFixedFit );
|
||||
if( !table )
|
||||
{
|
||||
|
|
@ -796,6 +819,13 @@ public class IpcTester : IDisposable
|
|||
var base64 = Ipc.GetPlayerMetaManipulations.Subscriber( _pi ).Invoke();
|
||||
ImGui.SetClipboardText( base64 );
|
||||
}
|
||||
|
||||
DrawIntro( Ipc.GetGameObjectMetaManipulations.Label, "Game Object Manipulations" );
|
||||
if( ImGui.Button( "Copy to Clipboard##GameObject" ) )
|
||||
{
|
||||
var base64 = Ipc.GetGameObjectMetaManipulations.Subscriber( _pi ).Invoke( _gameObjectIndex );
|
||||
ImGui.SetClipboardText( base64 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace Penumbra.Api;
|
|||
public class PenumbraApi : IDisposable, IPenumbraApi
|
||||
{
|
||||
public (int, int) ApiVersion
|
||||
=> ( 4, 16 );
|
||||
=> ( 4, 17 );
|
||||
|
||||
private Penumbra? _penumbra;
|
||||
private Lumina.GameData? _lumina;
|
||||
|
|
@ -216,6 +216,13 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
public string ResolvePath( string path, string characterName )
|
||||
=> ResolvePath( path, characterName, ushort.MaxValue );
|
||||
|
||||
public string ResolveGameObjectPath( string path, int gameObjectIdx )
|
||||
{
|
||||
CheckInitialized();
|
||||
AssociatedCollection( gameObjectIdx, out var collection );
|
||||
return ResolvePath( path, Penumbra.ModManager, collection );
|
||||
}
|
||||
|
||||
public string ResolvePath( string path, string characterName, ushort worldId )
|
||||
{
|
||||
CheckInitialized();
|
||||
|
|
@ -239,6 +246,19 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return ret.Select( r => r.ToString() ).ToArray();
|
||||
}
|
||||
|
||||
public string[] ReverseResolveGameObjectPath( string path, int gameObjectIdx )
|
||||
{
|
||||
CheckInitialized();
|
||||
if( !Penumbra.Config.EnableMods )
|
||||
{
|
||||
return new[] { path };
|
||||
}
|
||||
|
||||
AssociatedCollection( gameObjectIdx, out var collection );
|
||||
var ret = collection.ReverseResolvePath( new FullPath( path ) );
|
||||
return ret.Select( r => r.ToString() ).ToArray();
|
||||
}
|
||||
|
||||
public string[] ReverseResolvePlayerPath( string path )
|
||||
{
|
||||
CheckInitialized();
|
||||
|
|
@ -794,6 +814,14 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return Functions.ToCompressedBase64( set, MetaManipulation.CurrentVersion );
|
||||
}
|
||||
|
||||
public string GetGameObjectMetaManipulations( int gameObjectIdx )
|
||||
{
|
||||
CheckInitialized();
|
||||
AssociatedCollection( gameObjectIdx, out var collection );
|
||||
var set = collection.MetaCache?.Manipulations.ToArray() ?? Array.Empty< MetaManipulation >();
|
||||
return Functions.ToCompressedBase64( set, MetaManipulation.CurrentVersion );
|
||||
}
|
||||
|
||||
internal bool HasTooltip
|
||||
=> ChangedItemTooltip != null;
|
||||
|
||||
|
|
@ -812,6 +840,26 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
}
|
||||
}
|
||||
|
||||
// Return the collection associated to a current game object. If it does not exist, return the default collection.
|
||||
// If the index is invalid, returns false and the default collection.
|
||||
private unsafe bool AssociatedCollection( int gameObjectIdx, out ModCollection collection )
|
||||
{
|
||||
collection = Penumbra.CollectionManager.Default;
|
||||
if( gameObjectIdx < 0 || gameObjectIdx >= Dalamud.Objects.Length )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var ptr = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )Dalamud.Objects.GetObjectAddress( gameObjectIdx );
|
||||
var data = PathResolver.IdentifyCollection( ptr, false );
|
||||
if( data.Valid )
|
||||
{
|
||||
collection = data.ModCollection;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve a path given by string for a specific collection.
|
||||
private static string ResolvePath( string path, Mod.Manager _, ModCollection collection )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,9 +52,11 @@ public class PenumbraIpcProviders : IDisposable
|
|||
internal readonly FuncProvider< string, string > ResolveDefaultPath;
|
||||
internal readonly FuncProvider< string, string > ResolveInterfacePath;
|
||||
internal readonly FuncProvider< string, string > ResolvePlayerPath;
|
||||
internal readonly FuncProvider< string, int, string > ResolveGameObjectPath;
|
||||
internal readonly FuncProvider< string, string, string > ResolveCharacterPath;
|
||||
internal readonly FuncProvider< string, string, string[] > ReverseResolvePath;
|
||||
internal readonly FuncProvider< string, string[] > ReverseResolvePathPlayer;
|
||||
internal readonly FuncProvider< string, int, string[] > ReverseResolveGameObjectPath;
|
||||
internal readonly FuncProvider< string, string[] > ReverseResolvePlayerPath;
|
||||
|
||||
// Collections
|
||||
internal readonly FuncProvider< IList< string > > GetCollections;
|
||||
|
|
@ -67,6 +69,7 @@ public class PenumbraIpcProviders : IDisposable
|
|||
// Meta
|
||||
internal readonly FuncProvider< string > GetPlayerMetaManipulations;
|
||||
internal readonly FuncProvider< string, string > GetMetaManipulations;
|
||||
internal readonly FuncProvider< int, string > GetGameObjectMetaManipulations;
|
||||
|
||||
// Mods
|
||||
internal readonly FuncProvider< IList< (string, string) > > GetMods;
|
||||
|
|
@ -144,12 +147,14 @@ public class PenumbraIpcProviders : IDisposable
|
|||
() => Api.GameObjectResourceResolved -= GameObjectResourceResolvedEvent );
|
||||
|
||||
// Resolve
|
||||
ResolveDefaultPath = Ipc.ResolveDefaultPath.Provider( pi, Api.ResolveDefaultPath );
|
||||
ResolveInterfacePath = Ipc.ResolveInterfacePath.Provider( pi, Api.ResolveInterfacePath );
|
||||
ResolvePlayerPath = Ipc.ResolvePlayerPath.Provider( pi, Api.ResolvePlayerPath );
|
||||
ResolveCharacterPath = Ipc.ResolveCharacterPath.Provider( pi, Api.ResolvePath );
|
||||
ReverseResolvePath = Ipc.ReverseResolvePath.Provider( pi, Api.ReverseResolvePath );
|
||||
ReverseResolvePathPlayer = Ipc.ReverseResolvePlayerPath.Provider( pi, Api.ReverseResolvePlayerPath );
|
||||
ResolveDefaultPath = Ipc.ResolveDefaultPath.Provider( pi, Api.ResolveDefaultPath );
|
||||
ResolveInterfacePath = Ipc.ResolveInterfacePath.Provider( pi, Api.ResolveInterfacePath );
|
||||
ResolvePlayerPath = Ipc.ResolvePlayerPath.Provider( pi, Api.ResolvePlayerPath );
|
||||
ResolveGameObjectPath = Ipc.ResolveGameObjectPath.Provider( pi, Api.ResolveGameObjectPath );
|
||||
ResolveCharacterPath = Ipc.ResolveCharacterPath.Provider( pi, Api.ResolvePath );
|
||||
ReverseResolvePath = Ipc.ReverseResolvePath.Provider( pi, Api.ReverseResolvePath );
|
||||
ReverseResolveGameObjectPath = Ipc.ReverseResolveGameObjectPath.Provider( pi, Api.ReverseResolveGameObjectPath );
|
||||
ReverseResolvePlayerPath = Ipc.ReverseResolvePlayerPath.Provider( pi, Api.ReverseResolvePlayerPath );
|
||||
|
||||
// Collections
|
||||
GetCollections = Ipc.GetCollections.Provider( pi, Api.GetCollections );
|
||||
|
|
@ -160,8 +165,9 @@ public class PenumbraIpcProviders : IDisposable
|
|||
GetChangedItems = Ipc.GetChangedItems.Provider( pi, Api.GetChangedItemsForCollection );
|
||||
|
||||
// Meta
|
||||
GetPlayerMetaManipulations = Ipc.GetPlayerMetaManipulations.Provider( pi, Api.GetPlayerMetaManipulations );
|
||||
GetMetaManipulations = Ipc.GetMetaManipulations.Provider( pi, Api.GetMetaManipulations );
|
||||
GetPlayerMetaManipulations = Ipc.GetPlayerMetaManipulations.Provider( pi, Api.GetPlayerMetaManipulations );
|
||||
GetMetaManipulations = Ipc.GetMetaManipulations.Provider( pi, Api.GetMetaManipulations );
|
||||
GetGameObjectMetaManipulations = Ipc.GetGameObjectMetaManipulations.Provider( pi, Api.GetGameObjectMetaManipulations );
|
||||
|
||||
// Mods
|
||||
GetMods = Ipc.GetMods.Provider( pi, Api.GetModList );
|
||||
|
|
@ -242,9 +248,11 @@ public class PenumbraIpcProviders : IDisposable
|
|||
ResolveDefaultPath.Dispose();
|
||||
ResolveInterfacePath.Dispose();
|
||||
ResolvePlayerPath.Dispose();
|
||||
ResolveGameObjectPath.Dispose();
|
||||
ResolveCharacterPath.Dispose();
|
||||
ReverseResolvePath.Dispose();
|
||||
ReverseResolvePathPlayer.Dispose();
|
||||
ReverseResolveGameObjectPath.Dispose();
|
||||
ReverseResolvePlayerPath.Dispose();
|
||||
|
||||
// Collections
|
||||
GetCollections.Dispose();
|
||||
|
|
@ -257,6 +265,7 @@ public class PenumbraIpcProviders : IDisposable
|
|||
// Meta
|
||||
GetPlayerMetaManipulations.Dispose();
|
||||
GetMetaManipulations.Dispose();
|
||||
GetGameObjectMetaManipulations.Dispose();
|
||||
|
||||
// Mods
|
||||
GetMods.Dispose();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Penumbra.Interop.Resolver;
|
|||
public unsafe partial class PathResolver
|
||||
{
|
||||
// Identify the correct collection for a GameObject by index and name.
|
||||
private static ResolveData IdentifyCollection( GameObject* gameObject, bool useCache )
|
||||
public static ResolveData IdentifyCollection( GameObject* gameObject, bool useCache )
|
||||
{
|
||||
if( gameObject == null )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
"penumbra.gamedata": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Penumbra.Api": "[1.0.0, )",
|
||||
"Penumbra.Api": "[1.0.3, )",
|
||||
"Penumbra.String": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue