Get rid off EQDP files

This commit is contained in:
Ottermandias 2024-06-16 01:02:42 +02:00
parent 9ecc4ab46d
commit 600fd2ecd3
23 changed files with 192 additions and 246 deletions

View file

@ -23,10 +23,11 @@ public sealed unsafe class CalculateHeight : FastHook<CalculateHeight.Delegate>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private ulong Detour(Character* character)
{
_metaState.RspCollection = _collectionResolver.IdentifyCollection((GameObject*)character, true);
var collection = _collectionResolver.IdentifyCollection((GameObject*)character, true);
_metaState.RspCollection.Push(collection);
var ret = Task.Result.Original.Invoke(character);
Penumbra.Log.Excessive($"[Calculate Height] Invoked on {(nint)character:X} -> {ret}.");
_metaState.RspCollection = ResolveData.Invalid;
_metaState.RspCollection.Pop();
return ret;
}
}

View file

@ -1,12 +1,12 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Structs;
using Penumbra.Interop.PathResolving;
namespace Penumbra.Interop.Hooks.Meta;
using Penumbra.GameData;
using Penumbra.GameData.Structs;
using Penumbra.Interop.PathResolving;
namespace Penumbra.Interop.Hooks.Meta;
public sealed unsafe class ChangeCustomize : FastHook<ChangeCustomize.Delegate>
{
private readonly CollectionResolver _collectionResolver;
@ -24,14 +24,15 @@ public sealed unsafe class ChangeCustomize : FastHook<ChangeCustomize.Delegate>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private bool Detour(Human* human, CustomizeArray* data, byte skipEquipment)
{
_metaState.CustomizeChangeCollection = _collectionResolver.IdentifyCollection((DrawObject*)human, true);
_metaState.RspCollection = _metaState.CustomizeChangeCollection;
var collection = _collectionResolver.IdentifyCollection((DrawObject*)human, true);
_metaState.CustomizeChangeCollection = collection;
_metaState.RspCollection.Push(collection);
using var decal1 = _metaState.ResolveDecal(_metaState.CustomizeChangeCollection, true);
using var decal2 = _metaState.ResolveDecal(_metaState.CustomizeChangeCollection, false);
var ret = Task.Result.Original.Invoke(human, data, skipEquipment);
Penumbra.Log.Excessive($"[Change Customize] Invoked on {(nint)human:X} with {(nint)data:X}, {skipEquipment} -> {ret}.");
_metaState.CustomizeChangeCollection = ResolveData.Invalid;
_metaState.RspCollection = ResolveData.Invalid;
_metaState.RspCollection.Pop();
return ret;
}
}
}

View file

@ -0,0 +1,33 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.Interop.PathResolving;
using Penumbra.Meta.Manipulations;
namespace Penumbra.Interop.Hooks.Meta;
public unsafe class EqdpAccessoryHook : FastHook<EqdpAccessoryHook.Delegate>
{
public delegate void Delegate(CharacterUtility* utility, EqdpEntry* entry, uint id, uint raceCode);
private readonly MetaState _metaState;
public EqdpAccessoryHook(HookManager hooks, MetaState metaState)
{
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("GetEqdpAccessoryEntry", "E8 ?? ?? ?? ?? 41 BF ?? ?? ?? ?? 83 FB", Detour, true);
}
private void Detour(CharacterUtility* utility, EqdpEntry* entry, uint setId, uint raceCode)
{
if (_metaState.EqdpCollection.TryPeek(out var collection)
&& collection is { Valid: true, ModCollection.MetaCache: { } cache }
&& cache.Eqdp.TryGetFullEntry(new PrimaryId((ushort)setId), (GenderRace)raceCode, true, out var newEntry))
*entry = newEntry;
else
Task.Result.Original(utility, entry, setId, raceCode);
Penumbra.Log.Information(
$"[GetEqdpAccessoryEntry] Invoked on 0x{(ulong)utility:X} with {setId}, {(GenderRace)raceCode}, returned {(ushort)*entry:B10}.");
}
}

View file

@ -0,0 +1,32 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.Interop.PathResolving;
namespace Penumbra.Interop.Hooks.Meta;
public unsafe class EqdpEquipHook : FastHook<EqdpEquipHook.Delegate>
{
public delegate void Delegate(CharacterUtility* utility, EqdpEntry* entry, uint id, uint raceCode);
private readonly MetaState _metaState;
public EqdpEquipHook(HookManager hooks, MetaState metaState)
{
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("GetEqdpEquipEntry", "E8 ?? ?? ?? ?? 85 DB 75 ?? F6 45", Detour, true);
}
private void Detour(CharacterUtility* utility, EqdpEntry* entry, uint setId, uint raceCode)
{
if (_metaState.EqdpCollection.TryPeek(out var collection)
&& collection is { Valid: true, ModCollection.MetaCache: { } cache }
&& cache.Eqdp.TryGetFullEntry(new PrimaryId((ushort)setId), (GenderRace)raceCode, false, out var newEntry))
*entry = newEntry;
else
Task.Result.Original(utility, entry, setId, raceCode);
Penumbra.Log.Information(
$"[GetEqdpEquipEntry] Invoked on 0x{(ulong)utility:X} with {setId}, {(GenderRace)raceCode}, returned {(ushort)*entry:B10}.");
}
}

View file

@ -19,7 +19,7 @@ public unsafe class EqpHook : FastHook<EqpHook.Delegate>
private void Detour(CharacterUtility* utility, EqpEntry* flags, CharacterArmor* armor)
{
if (_metaState.EqpCollection is { Valid: true, ModCollection.MetaCache: { } cache })
if (_metaState.EqpCollection.TryPeek(out var collection) && collection is { Valid: true, ModCollection.MetaCache: { } cache })
{
*flags = cache.Eqp.GetValues(armor);
*flags = cache.GlobalEqp.Apply(*flags, armor);

View file

@ -21,7 +21,7 @@ public class EstHook : FastHook<EstHook.Delegate>
private EstEntry Detour(uint genderRace, int estType, uint id)
{
EstEntry ret;
if (_metaState.EstCollection is { Valid: true, ModCollection.MetaCache: { } cache }
if (_metaState.EstCollection.TryPeek(out var collection) && collection is { Valid: true, ModCollection.MetaCache: { } cache }
&& cache.Est.TryGetValue(Convert(genderRace, estType, id), out var entry))
ret = entry.Entry;
else

View file

@ -29,8 +29,9 @@ public sealed unsafe class GetEqpIndirect : FastHook<GetEqpIndirect.Delegate>
return;
Penumbra.Log.Excessive($"[Get EQP Indirect] Invoked on {(nint)drawObject:X}.");
_metaState.EqpCollection = _collectionResolver.IdentifyCollection(drawObject, true);
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
_metaState.EqpCollection.Push(collection);
Task.Result.Original(drawObject);
_metaState.EqpCollection = ResolveData.Invalid;
_metaState.EqpCollection.Pop();
}
}

View file

@ -1,11 +1,11 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.Interop.PathResolving;
namespace Penumbra.Interop.Hooks.Meta;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.Interop.PathResolving;
namespace Penumbra.Interop.Hooks.Meta;
public sealed unsafe class GetEqpIndirect2 : FastHook<GetEqpIndirect2.Delegate>
{
private readonly CollectionResolver _collectionResolver;
@ -29,8 +29,9 @@ public sealed unsafe class GetEqpIndirect2 : FastHook<GetEqpIndirect2.Delegate>
return;
Penumbra.Log.Excessive($"[Get EQP Indirect 2] Invoked on {(nint)drawObject:X}.");
_metaState.EqpCollection = _collectionResolver.IdentifyCollection(drawObject, true);
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
_metaState.EqpCollection.Push(collection);
Task.Result.Original(drawObject);
_metaState.EqpCollection = ResolveData.Invalid;
_metaState.EqpCollection.Pop();
}
}
}

View file

@ -27,15 +27,15 @@ public unsafe class GmpHook : FastHook<GmpHook.Delegate>
private nint Detour(nint gmpResource, uint dividedHeadId)
{
nint ret;
if (_metaState.GmpCollection is { Valid: true, ModCollection.MetaCache: { } cache }
&& cache.Gmp.TryGetValue(new GmpIdentifier(_metaState.UndividedGmpId), out var entry))
if (_metaState.GmpCollection.TryPeek(out var collection) && collection.Collection is { Valid: true, ModCollection.MetaCache: { } cache }
&& cache.Gmp.TryGetValue(new GmpIdentifier(collection.Id), out var entry))
{
if (entry.Entry.Enabled)
{
*StablePointer.Pointer = entry.Entry.Value;
// This function already gets the original ID divided by the block size, so we can compute the modulo with a single multiplication and addition.
// We then go backwards from our pointer because this gets added by the calling functions.
ret = (nint)(StablePointer.Pointer - (_metaState.UndividedGmpId.Id - dividedHeadId * ExpandedEqpGmpBase.BlockSize));
ret = (nint)(StablePointer.Pointer - (collection.Id.Id - dividedHeadId * ExpandedEqpGmpBase.BlockSize));
}
else
{

View file

@ -23,10 +23,11 @@ public sealed unsafe class ModelLoadComplete : FastHook<ModelLoadComplete.Delega
private void Detour(DrawObject* drawObject)
{
Penumbra.Log.Excessive($"[Model Load Complete] Invoked on {(nint)drawObject:X}.");
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
using var eqdp = _metaState.ResolveEqdpData(collection.ModCollection, MetaState.GetDrawObjectGenderRace((nint)drawObject), true, true);
_metaState.EqpCollection = collection;
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
_metaState.EqpCollection.Push(collection);
_metaState.EqdpCollection.Push(collection);
Task.Result.Original(drawObject);
_metaState.EqpCollection = ResolveData.Invalid;
_metaState.EqpCollection.Pop();
_metaState.EqdpCollection.Pop();
}
}

View file

@ -33,7 +33,7 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>
}
var ret = storage;
if (bodyType < 2 && _metaState.RspCollection is { Valid: true, ModCollection.MetaCache: { } cache })
if (bodyType < 2 && _metaState.RspCollection.TryPeek(out var collection) && collection is { Valid: true, ModCollection.MetaCache: { } cache })
{
var bustScale = bustSize / 100f;
var clan = (SubRace)(((int)race - 1) * 2 + 1 + isSecondSubRace);

View file

@ -1,3 +1,4 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.GameData.Enums;
using Penumbra.Interop.PathResolving;
@ -24,7 +25,7 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>
private unsafe float Detour(nint cmpResource, Race race, byte gender, byte isSecondSubRace, byte bodyType, byte height)
{
float scale;
if (bodyType < 2 && _metaState.RspCollection is { Valid: true, ModCollection.MetaCache: { } cache })
if (bodyType < 2 && _metaState.RspCollection.TryPeek(out var collection) && collection is { Valid: true, ModCollection.MetaCache: { } cache })
{
var clan = (SubRace)(((int)race - 1) * 2 + 1 + isSecondSubRace);
var (minIdent, maxIdent) = gender == 0

View file

@ -31,8 +31,9 @@ public sealed unsafe class RspSetupCharacter : FastHook<RspSetupCharacter.Delega
return;
}
_metaState.RspCollection = _collectionResolver.IdentifyCollection(drawObject, true);
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
_metaState.RspCollection.Push(collection);
Task.Result.Original.Invoke(drawObject, unk2, unk3, unk4, unk5);
_metaState.RspCollection = ResolveData.Invalid;
_metaState.RspCollection.Pop();
}
}

View file

@ -24,7 +24,7 @@ public class RspTailHook : FastHook<RspTailHook.Delegate>
private unsafe float Detour(nint cmpResource, Race race, byte gender, byte isSecondSubRace, byte bodyType, byte tailLength)
{
float scale;
if (bodyType < 2 && _metaState.RspCollection is { Valid: true, ModCollection.MetaCache: { } cache })
if (bodyType < 2 && _metaState.RspCollection.TryPeek(out var collection) && collection is { Valid: true, ModCollection.MetaCache: { } cache })
{
var clan = (SubRace)(((int)race - 1) * 2 + 1 + isSecondSubRace);
var (minIdent, maxIdent) = gender == 0

View file

@ -27,11 +27,11 @@ public sealed unsafe class SetupVisor : FastHook<SetupVisor.Delegate>
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private byte Detour(DrawObject* drawObject, ushort modelId, byte visorState)
{
_metaState.GmpCollection = _collectionResolver.IdentifyCollection(drawObject, true);
_metaState.UndividedGmpId = modelId;
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
_metaState.GmpCollection.Push((collection, modelId));
var ret = Task.Result.Original.Invoke(drawObject, modelId, visorState);
Penumbra.Log.Excessive($"[Setup Visor] Invoked on {(nint)drawObject:X} with {modelId}, {visorState} -> {ret}.");
_metaState.GmpCollection = ResolveData.Invalid;
_metaState.GmpCollection.Pop();
return ret;
}
}

View file

@ -29,10 +29,11 @@ public sealed unsafe class UpdateModel : FastHook<UpdateModel.Delegate>
return;
Penumbra.Log.Excessive($"[Update Model] Invoked on {(nint)drawObject:X}.");
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
using var eqdp = _metaState.ResolveEqdpData(collection.ModCollection, MetaState.GetDrawObjectGenderRace((nint)drawObject), true, true);
_metaState.EqpCollection = collection;
var collection = _collectionResolver.IdentifyCollection(drawObject, true);
_metaState.EqpCollection.Push(collection);
_metaState.EqdpCollection.Push(collection);
Task.Result.Original(drawObject);
_metaState.EqpCollection = ResolveData.Invalid;
_metaState.EqpCollection.Pop();
_metaState.EqdpCollection.Pop();
}
}

View file

@ -1,11 +1,9 @@
using System.Text.Unicode;
using Dalamud.Hooking;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Classes;
using OtterGui.Services;
using Penumbra.Collections;
using Penumbra.Interop.PathResolving;
using Penumbra.Meta.Manipulations;
namespace Penumbra.Interop.Hooks.Resources;
@ -149,42 +147,51 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable
private nint ResolveMdlHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint slotIndex)
{
var data = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
using var eqdp = slotIndex > 9 || _parent.InInternalResolve
? DisposableContainer.Empty
: _parent.MetaState.ResolveEqdpData(data.ModCollection, MetaState.GetHumanGenderRace(drawObject), slotIndex < 5, slotIndex > 4);
return ResolvePath(data, _resolveMdlPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex));
var collection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
if (slotIndex < 10)
_parent.MetaState.EqdpCollection.Push(collection);
var ret = ResolvePath(collection, _resolveMdlPathHook.Original(drawObject, pathBuffer, pathBufferSize, slotIndex));
if (slotIndex < 10)
_parent.MetaState.EqdpCollection.Pop();
return ret;
}
private nint ResolvePapHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint unkAnimationIndex, nint animationName)
{
_parent.MetaState.EstCollection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
var ret = ResolvePath(_parent.MetaState.EstCollection, _resolvePapPathHook.Original(drawObject, pathBuffer, pathBufferSize, unkAnimationIndex, animationName));
_parent.MetaState.EstCollection = ResolveData.Invalid;
var collection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
_parent.MetaState.EstCollection.Push(collection);
var ret = ResolvePath(collection,
_resolvePapPathHook.Original(drawObject, pathBuffer, pathBufferSize, unkAnimationIndex, animationName));
_parent.MetaState.EstCollection.Pop();
return ret;
}
private nint ResolvePhybHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex)
{
_parent.MetaState.EstCollection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
var ret = ResolvePath(_parent.MetaState.EstCollection, _resolvePhybPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex));
_parent.MetaState.EstCollection = ResolveData.Invalid;
var collection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
_parent.MetaState.EstCollection.Push(collection);
var ret = ResolvePath(collection, _resolvePhybPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex));
_parent.MetaState.EstCollection.Pop();
return ret;
}
private nint ResolveSklbHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex)
{
_parent.MetaState.EstCollection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
var ret = ResolvePath(_parent.MetaState.EstCollection, _resolveSklbPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex));
_parent.MetaState.EstCollection = ResolveData.Invalid;
var collection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
_parent.MetaState.EstCollection.Push(collection);
var ret = ResolvePath(collection, _resolveSklbPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex));
_parent.MetaState.EstCollection.Pop();
return ret;
}
private nint ResolveSkpHuman(nint drawObject, nint pathBuffer, nint pathBufferSize, uint partialSkeletonIndex)
{
_parent.MetaState.EstCollection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
var ret = ResolvePath(_parent.MetaState.EstCollection, _resolveSkpPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex));
_parent.MetaState.EstCollection = ResolveData.Invalid;
var collection = _parent.CollectionResolver.IdentifyCollection((DrawObject*)drawObject, true);
_parent.MetaState.EstCollection.Push(collection);
var ret = ResolvePath(collection, _resolveSkpPathHook.Original(drawObject, pathBuffer, pathBufferSize, partialSkeletonIndex));
_parent.MetaState.EstCollection.Pop();
return ret;
}