Add GetGameObjectResourceTrees ipc method

This commit is contained in:
Asriel Camora 2023-11-28 10:28:37 -08:00
parent 43c6b52d0b
commit 73af509885
No known key found for this signature in database
GPG key ID: 92B8372B278DDE41
4 changed files with 48 additions and 1 deletions

@ -1 +1 @@
Subproject commit 80f9793ef2ddaa50246b7112fde4d9b2098d8823 Subproject commit 3f3af19d11ec4d7a83ee6c17810eb55ec4237675

View file

@ -1075,6 +1075,15 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return resDictionaries.AsReadOnly(); return resDictionaries.AsReadOnly();
} }
public IEnumerable<Ipc.ResourceNode>?[] GetGameObjectResourceTrees(bool withUIData, params ushort[] gameObjects)
{
var characters = gameObjects.Select(index => _dalamud.Objects[index]).OfType<Character>();
var resourceTrees = _resourceTreeFactory.FromCharacters(characters, withUIData ? ResourceTreeFactory.Flags.WithUiData : 0);
var resDictionary = ResourceTreeApiHelper.EncapsulateResourceTrees(resourceTrees);
return Array.ConvertAll(gameObjects, obj => resDictionary.TryGetValue(obj, out var nodes) ? nodes : null);
}
// TODO: cleanup when incrementing API // TODO: cleanup when incrementing API
public string GetMetaManipulations(string characterName) public string GetMetaManipulations(string characterName)

View file

@ -130,6 +130,8 @@ public class PenumbraIpcProviders : IDisposable
FuncProvider<ResourceType, bool, IReadOnlyDictionary<ushort, IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>>> FuncProvider<ResourceType, bool, IReadOnlyDictionary<ushort, IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>>>
GetPlayerResourcesOfType; GetPlayerResourcesOfType;
internal readonly FuncProvider<bool, ushort[], IEnumerable<Ipc.ResourceNode>?[]> GetGameObjectResourceTrees;
public PenumbraIpcProviders(DalamudServices dalamud, IPenumbraApi api, ModManager modManager, CollectionManager collections, public PenumbraIpcProviders(DalamudServices dalamud, IPenumbraApi api, ModManager modManager, CollectionManager collections,
TempModManager tempMods, TempCollectionManager tempCollections, SaveService saveService, Configuration config) TempModManager tempMods, TempCollectionManager tempCollections, SaveService saveService, Configuration config)
{ {
@ -254,6 +256,7 @@ public class PenumbraIpcProviders : IDisposable
GetPlayerResourcePaths = Ipc.GetPlayerResourcePaths.Provider(pi, Api.GetPlayerResourcePaths); GetPlayerResourcePaths = Ipc.GetPlayerResourcePaths.Provider(pi, Api.GetPlayerResourcePaths);
GetGameObjectResourcesOfType = Ipc.GetGameObjectResourcesOfType.Provider(pi, Api.GetGameObjectResourcesOfType); GetGameObjectResourcesOfType = Ipc.GetGameObjectResourcesOfType.Provider(pi, Api.GetGameObjectResourcesOfType);
GetPlayerResourcesOfType = Ipc.GetPlayerResourcesOfType.Provider(pi, Api.GetPlayerResourcesOfType); GetPlayerResourcesOfType = Ipc.GetPlayerResourcesOfType.Provider(pi, Api.GetPlayerResourcesOfType);
GetGameObjectResourceTrees = Ipc.GetGameObjectResourceTrees.Provider(pi, Api.GetGameObjectResourceTrees);
Tester = new IpcTester(config, dalamud, this, modManager, collections, tempMods, tempCollections, saveService); Tester = new IpcTester(config, dalamud, this, modManager, collections, tempMods, tempCollections, saveService);

View file

@ -1,5 +1,7 @@
using Dalamud.Game.ClientState.Objects.Types; using Dalamud.Game.ClientState.Objects.Types;
using Penumbra.Api;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.String.Classes;
using Penumbra.UI; using Penumbra.UI;
namespace Penumbra.Interop.ResourceTree; namespace Penumbra.Interop.ResourceTree;
@ -71,4 +73,37 @@ internal static class ResourceTreeApiHelper
return resDictionaries.ToDictionary(pair => pair.Key, return resDictionaries.ToDictionary(pair => pair.Key,
pair => (IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>)pair.Value.AsReadOnly()); pair => (IReadOnlyDictionary<nint, (string, string, ChangedItemIcon)>)pair.Value.AsReadOnly());
} }
public static Dictionary<ushort, IEnumerable<Ipc.ResourceNode>> EncapsulateResourceTrees(IEnumerable<(Character, ResourceTree)> resourceTrees)
{
static Ipc.ResourceNode GetIpcNode(ResourceNode[] tree, ResourceNode node) =>
new()
{
ChildrenIndices = node.Children.Select(c => Array.IndexOf(tree, c)).ToArray(),
Type = node.Type,
Icon = ChangedItemDrawer.ToApiIcon(node.Icon),
Name = node.Name,
GamePath = node.GamePath.Equals(Utf8GamePath.Empty) ? null : node.GamePath.ToString(),
ActualPath = node.FullPath.ToString(),
ObjectAddress = node.ObjectAddress,
ResourceHandle = node.ResourceHandle,
};
static IEnumerable<Ipc.ResourceNode> GetIpcNodes(ResourceTree tree)
{
var nodes = tree.FlatNodes.ToArray();
return nodes.Select(n => GetIpcNode(nodes, n)).ToArray();
}
var resDictionary = new Dictionary<ushort, IEnumerable<Ipc.ResourceNode>>(4);
foreach (var (gameObject, resourceTree) in resourceTrees)
{
if (resDictionary.ContainsKey(gameObject.ObjectIndex))
continue;
resDictionary.Add(gameObject.ObjectIndex, GetIpcNodes(resourceTree));
}
return resDictionary;
}
} }