From c2e5499aef456fab9a2ba9ae13ab3a9d9a09eb03 Mon Sep 17 00:00:00 2001 From: Exter-N Date: Mon, 22 Jan 2024 01:51:42 +0100 Subject: [PATCH] ClientStructs-ify some stuff --- .../ResolveContext.PathResolution.cs | 13 ++-- .../Interop/ResourceTree/ResolveContext.cs | 8 +-- .../Interop/Structs/CharacterBaseUtility.cs | 62 ------------------- .../Structs/ModelResourceHandleUtility.cs | 19 ------ Penumbra/Interop/Structs/StructExtensions.cs | 57 ++++++++++++----- Penumbra/Penumbra.cs | 1 - Penumbra/Services/ServiceManagerA.cs | 3 +- 7 files changed, 53 insertions(+), 110 deletions(-) delete mode 100644 Penumbra/Interop/Structs/CharacterBaseUtility.cs delete mode 100644 Penumbra/Interop/Structs/ModelResourceHandleUtility.cs diff --git a/Penumbra/Interop/ResourceTree/ResolveContext.PathResolution.cs b/Penumbra/Interop/ResourceTree/ResolveContext.PathResolution.cs index 0ab1e0e3..66af5521 100644 --- a/Penumbra/Interop/ResourceTree/ResolveContext.PathResolution.cs +++ b/Penumbra/Interop/ResourceTree/ResolveContext.PathResolution.cs @@ -7,7 +7,7 @@ using Penumbra.Meta.Files; using Penumbra.Meta.Manipulations; using Penumbra.String; using Penumbra.String.Classes; -using static Penumbra.Interop.Structs.CharacterBaseUtility; +using static Penumbra.Interop.Structs.StructExtensions; using ModelType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase.ModelType; namespace Penumbra.Interop.ResourceTree; @@ -71,7 +71,7 @@ internal partial record ResolveContext private unsafe Utf8GamePath ResolveModelPathNative() { - var path = ResolveMdlPath(CharacterBase, SlotIndex); + var path = CharacterBase.Value->ResolveMdlPathAsByteString(SlotIndex); return Utf8GamePath.FromByteString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty; } @@ -139,8 +139,7 @@ internal partial record ResolveContext private unsafe Utf8GamePath ResolveMonsterMaterialPath(Utf8GamePath modelPath, ResourceHandle* imc, byte* mtrlFileName) { - // TODO: Submit this (Monster->Variant) to ClientStructs - var variant = ResolveMaterialVariant(imc, ((byte*)CharacterBase.Value)[0x8F4]); + var variant = ResolveMaterialVariant(imc, (byte)((Monster*)CharacterBase.Value)->Variant); var fileName = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(mtrlFileName); Span pathBuffer = stackalloc byte[260]; @@ -196,7 +195,7 @@ internal partial record ResolveContext ByteString? path; try { - path = ResolveMtrlPath(CharacterBase, SlotIndex, mtrlFileName); + path = CharacterBase.Value->ResolveMtrlPathAsByteString(SlotIndex, mtrlFileName); } catch (AccessViolationException) { @@ -277,7 +276,7 @@ internal partial record ResolveContext private unsafe Utf8GamePath ResolveSkeletonPathNative(uint partialSkeletonIndex) { - var path = ResolveSklbPath(CharacterBase, partialSkeletonIndex); + var path = CharacterBase.Value->ResolveSklbPathAsByteString(partialSkeletonIndex); return Utf8GamePath.FromByteString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty; } @@ -305,7 +304,7 @@ internal partial record ResolveContext private unsafe Utf8GamePath ResolveSkeletonParameterPathNative(uint partialSkeletonIndex) { - var path = ResolveSkpPath(CharacterBase, partialSkeletonIndex); + var path = CharacterBase.Value->ResolveSkpPathAsByteString(partialSkeletonIndex); return Utf8GamePath.FromByteString(path, out var gamePath) ? gamePath : Utf8GamePath.Empty; } } diff --git a/Penumbra/Interop/ResourceTree/ResolveContext.cs b/Penumbra/Interop/ResourceTree/ResolveContext.cs index 431f1ac0..7a31c9dd 100644 --- a/Penumbra/Interop/ResourceTree/ResolveContext.cs +++ b/Penumbra/Interop/ResourceTree/ResolveContext.cs @@ -13,8 +13,6 @@ using Penumbra.GameData.Structs; using Penumbra.String; using Penumbra.String.Classes; using Penumbra.UI; -using static Penumbra.Interop.Structs.CharacterBaseUtility; -using static Penumbra.Interop.Structs.ModelResourceHandleUtility; using static Penumbra.Interop.Structs.StructExtensions; using ModelType = FFXIVClientStructs.FFXIV.Client.Graphics.Scene.CharacterBase.ModelType; @@ -126,7 +124,7 @@ internal partial record ResolveContext( if (eid == null) return null; - if (!Utf8GamePath.FromByteString(ResolveEidPath(CharacterBase), out var path)) + if (!Utf8GamePath.FromByteString(CharacterBase.Value->ResolveEidPathAsByteString(), out var path)) return null; return GetOrCreateNode(ResourceType.Eid, 0, eid, path); @@ -137,7 +135,7 @@ internal partial record ResolveContext( if (imc == null) return null; - if (!Utf8GamePath.FromByteString(ResolveImcPath(CharacterBase, SlotIndex), out var path)) + if (!Utf8GamePath.FromByteString(CharacterBase.Value->ResolveImcPathAsByteString(SlotIndex), out var path)) return null; return GetOrCreateNode(ResourceType.Imc, 0, imc, path); @@ -174,7 +172,7 @@ internal partial record ResolveContext( if (mtrl == null) continue; - var mtrlFileName = GetMaterialFileNameBySlot(mdlResource, (uint)i); + var mtrlFileName = mdlResource->GetMaterialFileNameBySlot((uint)i); var mtrlNode = CreateNodeFromMaterial(mtrl, ResolveMaterialPath(path, imc, mtrlFileName)); if (mtrlNode != null) { diff --git a/Penumbra/Interop/Structs/CharacterBaseUtility.cs b/Penumbra/Interop/Structs/CharacterBaseUtility.cs deleted file mode 100644 index c29f44a3..00000000 --- a/Penumbra/Interop/Structs/CharacterBaseUtility.cs +++ /dev/null @@ -1,62 +0,0 @@ -using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; -using Penumbra.String; - -namespace Penumbra.Interop.Structs; - -// TODO submit these to ClientStructs -public static unsafe class CharacterBaseUtility -{ - private const int PathBufferSize = 260; - - private const uint ResolveSklbPathVf = 72; - private const uint ResolveMdlPathVf = 73; - private const uint ResolveSkpPathVf = 74; - private const uint ResolveImcPathVf = 81; - private const uint ResolveMtrlPathVf = 82; - private const uint ResolveEidPathVf = 85; - - private static void* GetVFunc(CharacterBase* characterBase, uint vfIndex) - => ((void**)characterBase->VTable)[vfIndex]; - - private static ByteString? ResolvePath(CharacterBase* characterBase, uint vfIndex) - { - var vFunc = (delegate* unmanaged)GetVFunc(characterBase, vfIndex); - var pathBuffer = stackalloc byte[PathBufferSize]; - var path = vFunc(characterBase, pathBuffer, PathBufferSize); - return path != null ? new ByteString(path).Clone() : null; - } - - private static ByteString? ResolvePath(CharacterBase* characterBase, uint vfIndex, uint slotIndex) - { - var vFunc = (delegate* unmanaged)GetVFunc(characterBase, vfIndex); - var pathBuffer = stackalloc byte[PathBufferSize]; - var path = vFunc(characterBase, pathBuffer, PathBufferSize, slotIndex); - return path != null ? new ByteString(path).Clone() : null; - } - - private static ByteString? ResolvePath(CharacterBase* characterBase, uint vfIndex, uint slotIndex, byte* name) - { - var vFunc = (delegate* unmanaged)GetVFunc(characterBase, vfIndex); - var pathBuffer = stackalloc byte[PathBufferSize]; - var path = vFunc(characterBase, pathBuffer, PathBufferSize, slotIndex, name); - return path != null ? new ByteString(path).Clone() : null; - } - - public static ByteString? ResolveEidPath(CharacterBase* characterBase) - => ResolvePath(characterBase, ResolveEidPathVf); - - public static ByteString? ResolveImcPath(CharacterBase* characterBase, uint slotIndex) - => ResolvePath(characterBase, ResolveImcPathVf, slotIndex); - - public static ByteString? ResolveMdlPath(CharacterBase* characterBase, uint slotIndex) - => ResolvePath(characterBase, ResolveMdlPathVf, slotIndex); - - public static ByteString? ResolveMtrlPath(CharacterBase* characterBase, uint slotIndex, byte* mtrlFileName) - => ResolvePath(characterBase, ResolveMtrlPathVf, slotIndex, mtrlFileName); - - public static ByteString? ResolveSklbPath(CharacterBase* characterBase, uint partialSkeletonIndex) - => ResolvePath(characterBase, ResolveSklbPathVf, partialSkeletonIndex); - - public static ByteString? ResolveSkpPath(CharacterBase* characterBase, uint partialSkeletonIndex) - => ResolvePath(characterBase, ResolveSkpPathVf, partialSkeletonIndex); -} diff --git a/Penumbra/Interop/Structs/ModelResourceHandleUtility.cs b/Penumbra/Interop/Structs/ModelResourceHandleUtility.cs deleted file mode 100644 index bcfa2fa2..00000000 --- a/Penumbra/Interop/Structs/ModelResourceHandleUtility.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Dalamud.Plugin.Services; -using Dalamud.Utility.Signatures; -using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle; -using Penumbra.GameData; - -namespace Penumbra.Interop.Structs; - -// TODO submit this to ClientStructs -public class ModelResourceHandleUtility -{ - public ModelResourceHandleUtility(IGameInteropProvider interop) - => interop.InitializeFromAttributes(this); - - [Signature(Sigs.GetMaterialFileNameBySlot)] - private static nint _getMaterialFileNameBySlot = nint.Zero; - - public static unsafe byte* GetMaterialFileNameBySlot(ModelResourceHandle* handle, uint slot) - => ((delegate* unmanaged)_getMaterialFileNameBySlot)(handle, slot); -} diff --git a/Penumbra/Interop/Structs/StructExtensions.cs b/Penumbra/Interop/Structs/StructExtensions.cs index d1a38ae4..3cd87424 100644 --- a/Penumbra/Interop/Structs/StructExtensions.cs +++ b/Penumbra/Interop/Structs/StructExtensions.cs @@ -1,3 +1,4 @@ +using FFXIVClientStructs.FFXIV.Client.Graphics.Scene; using FFXIVClientStructs.STD; using Penumbra.String; @@ -5,20 +6,48 @@ namespace Penumbra.Interop.Structs; internal static class StructExtensions { - // TODO submit this to ClientStructs - public static unsafe ReadOnlySpan AsSpan(in this StdString str) - { - if (str.Length < 16) - { - fixed (StdString* pStr = &str) - { - return new(pStr->Buffer, (int)str.Length); - } - } - else - return new(str.BufferPtr, (int)str.Length); - } - public static unsafe ByteString AsByteString(in this StdString str) => ByteString.FromSpanUnsafe(str.AsSpan(), true); + + public static ByteString ResolveEidPathAsByteString(in this CharacterBase character) + { + Span pathBuffer = stackalloc byte[CharacterBase.PathBufferSize]; + return ToOwnedByteString(character.ResolveEidPath(pathBuffer)); + } + + public static ByteString ResolveImcPathAsByteString(in this CharacterBase character, uint slotIndex) + { + Span pathBuffer = stackalloc byte[CharacterBase.PathBufferSize]; + return ToOwnedByteString(character.ResolveImcPath(pathBuffer, slotIndex)); + } + + public static ByteString ResolveMdlPathAsByteString(in this CharacterBase character, uint slotIndex) + { + Span pathBuffer = stackalloc byte[CharacterBase.PathBufferSize]; + return ToOwnedByteString(character.ResolveMdlPath(pathBuffer, slotIndex)); + } + + public static unsafe ByteString ResolveMtrlPathAsByteString(in this CharacterBase character, uint slotIndex, byte* mtrlFileName) + { + var pathBuffer = stackalloc byte[CharacterBase.PathBufferSize]; + return ToOwnedByteString(character.ResolveMtrlPath(pathBuffer, CharacterBase.PathBufferSize, slotIndex, mtrlFileName)); + } + + public static ByteString ResolveSklbPathAsByteString(in this CharacterBase character, uint partialSkeletonIndex) + { + Span pathBuffer = stackalloc byte[CharacterBase.PathBufferSize]; + return ToOwnedByteString(character.ResolveSklbPath(pathBuffer, partialSkeletonIndex)); + } + + public static ByteString ResolveSkpPathAsByteString(in this CharacterBase character, uint partialSkeletonIndex) + { + Span pathBuffer = stackalloc byte[CharacterBase.PathBufferSize]; + return ToOwnedByteString(character.ResolveSkpPath(pathBuffer, partialSkeletonIndex)); + } + + private static unsafe ByteString ToOwnedByteString(byte* str) + => str == null ? ByteString.Empty : new ByteString(str).Clone(); + + private static ByteString ToOwnedByteString(ReadOnlySpan str) + => str.Length == 0 ? ByteString.Empty : ByteString.FromSpanUnsafe(str, true).Clone(); } diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs index 9ecd2232..15b7ce56 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/Penumbra.cs @@ -76,7 +76,6 @@ public class Penumbra : IDalamudPlugin _communicatorService = _services.GetService(); _services.GetService(); // Initialize because not required anywhere else. _services.GetService(); // Initialize because not required anywhere else. - _services.GetService(); // Initialize because not required anywhere else. _collectionManager.Caches.CreateNecessaryCaches(); _services.GetService(); _services.GetService(); diff --git a/Penumbra/Services/ServiceManagerA.cs b/Penumbra/Services/ServiceManagerA.cs index 2b2bbf95..f25aac7c 100644 --- a/Penumbra/Services/ServiceManagerA.cs +++ b/Penumbra/Services/ServiceManagerA.cs @@ -99,8 +99,7 @@ public static class ServiceManagerA .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton() - .AddSingleton(); + .AddSingleton(); private static ServiceManager AddConfiguration(this ServiceManager services) => services.AddSingleton()