Some updates.

This commit is contained in:
Ottermandias 2024-07-02 17:08:27 +02:00
parent c2e74ed382
commit 221b18751d
121 changed files with 338 additions and 328 deletions

@ -1 +1 @@
Subproject commit 6fafc03b34971be7c0e74fd9a638d1ed642ea19a
Subproject commit 437ef65c6464c54c8f40196dd2428da901d73aab

@ -1 +1 @@
Subproject commit f1e4e520daaa8f23e5c8b71d55e5992b8f6768e2
Subproject commit 43b0b47f2d019af0fe4681dfc578f9232e3ba90c

@ -1 +1 @@
Subproject commit 4b55c05c72eb194bec0d28c52cf076962010424b
Subproject commit 3a97e5aeee3b7375b333c1add5305d0ce80cbf83

@ -1 +1 @@
Subproject commit caa58c5c92710e69ce07b9d736ebe2d228cb4488
Subproject commit f04abbabedf5e757c5cbb970f3e513fef23e53cf

View file

@ -13,7 +13,7 @@ public class RedrawApi(RedrawService redrawService) : IPenumbraApiRedraw, IApiSe
public void RedrawObject(string name, RedrawType setting)
=> redrawService.RedrawObject(name, setting);
public void RedrawObject(GameObject? gameObject, RedrawType setting)
public void RedrawObject(IGameObject? gameObject, RedrawType setting)
=> redrawService.RedrawObject(gameObject, setting);
public void RedrawAll(RedrawType setting)

View file

@ -12,7 +12,7 @@ public class ResourceTreeApi(ResourceTreeFactory resourceTreeFactory, ObjectMana
{
public Dictionary<string, HashSet<string>>?[] GetGameObjectResourcePaths(params ushort[] gameObjects)
{
var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType<Character>();
var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType<ICharacter>();
var resourceTrees = resourceTreeFactory.FromCharacters(characters, 0);
var pathDictionaries = ResourceTreeApiHelper.GetResourcePathDictionaries(resourceTrees);
@ -28,7 +28,7 @@ public class ResourceTreeApi(ResourceTreeFactory resourceTreeFactory, ObjectMana
public GameResourceDict?[] GetGameObjectResourcesOfType(ResourceType type, bool withUiData,
params ushort[] gameObjects)
{
var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType<Character>();
var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType<ICharacter>();
var resourceTrees = resourceTreeFactory.FromCharacters(characters, withUiData ? ResourceTreeFactory.Flags.WithUiData : 0);
var resDictionaries = ResourceTreeApiHelper.GetResourcesOfType(resourceTrees, type);
@ -45,7 +45,7 @@ public class ResourceTreeApi(ResourceTreeFactory resourceTreeFactory, ObjectMana
public JObject?[] GetGameObjectResourceTrees(bool withUiData, params ushort[] gameObjects)
{
var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType<Character>();
var characters = gameObjects.Select(index => objects.GetDalamudObject((int)index)).OfType<ICharacter>();
var resourceTrees = resourceTreeFactory.FromCharacters(characters, withUiData ? ResourceTreeFactory.Flags.WithUiData : 0);
var resDictionary = ResourceTreeApiHelper.EncapsulateResourceTrees(resourceTrees);

View file

@ -12,7 +12,7 @@ public sealed class IpcProviders : IDisposable, IApiService
private readonly EventProvider _disposedProvider;
private readonly EventProvider _initializedProvider;
public IpcProviders(DalamudPluginInterface pi, IPenumbraApi api)
public IpcProviders(IDalamudPluginInterface pi, IPenumbraApi api)
{
_disposedProvider = IpcSubscribers.Disposed.Provider(pi);
_initializedProvider = IpcSubscribers.Initialized.Provider(pi);

View file

@ -13,7 +13,7 @@ using ImGuiClip = OtterGui.ImGuiClip;
namespace Penumbra.Api.IpcTester;
public class CollectionsIpcTester(DalamudPluginInterface pi) : IUiService
public class CollectionsIpcTester(IDalamudPluginInterface pi) : IUiService
{
private int _objectIdx;
private string _collectionIdString = string.Empty;

View file

@ -8,7 +8,7 @@ using Penumbra.Api.IpcSubscribers;
namespace Penumbra.Api.IpcTester;
public class EditingIpcTester(DalamudPluginInterface pi) : IUiService
public class EditingIpcTester(IDalamudPluginInterface pi) : IUiService
{
private string _inputPath = string.Empty;
private string _inputPath2 = string.Empty;

View file

@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
public class GameStateIpcTester : IUiService, IDisposable
{
private readonly DalamudPluginInterface _pi;
private readonly IDalamudPluginInterface _pi;
public readonly EventSubscriber<nint, Guid, nint, nint, nint> CharacterBaseCreating;
public readonly EventSubscriber<nint, Guid, nint> CharacterBaseCreated;
public readonly EventSubscriber<nint, string, string> GameObjectResourcePathResolved;
@ -30,7 +30,7 @@ public class GameStateIpcTester : IUiService, IDisposable
private int _currentCutsceneParent;
private PenumbraApiEc _cutsceneError = PenumbraApiEc.Success;
public GameStateIpcTester(DalamudPluginInterface pi)
public GameStateIpcTester(IDalamudPluginInterface pi)
{
_pi = pi;
CharacterBaseCreating = IpcSubscribers.CreatingCharacterBase.Subscriber(pi, UpdateLastCreated);
@ -134,7 +134,6 @@ public class GameStateIpcTester : IUiService, IDisposable
private static unsafe string GetObjectName(nint gameObject)
{
var obj = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)gameObject;
var name = obj != null ? obj->Name : null;
return name != null && *name != 0 ? new ByteString(name).ToString() : "Unknown";
return obj != null && obj->Name[0] != 0 ? new ByteString(obj->Name).ToString() : "Unknown";
}
}

View file

@ -6,7 +6,7 @@ using Penumbra.Api.IpcSubscribers;
namespace Penumbra.Api.IpcTester;
public class MetaIpcTester(DalamudPluginInterface pi) : IUiService
public class MetaIpcTester(IDalamudPluginInterface pi) : IUiService
{
private int _gameObjectIndex;

View file

@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
public class ModSettingsIpcTester : IUiService, IDisposable
{
private readonly DalamudPluginInterface _pi;
private readonly IDalamudPluginInterface _pi;
public readonly EventSubscriber<ModSettingChange, Guid, string, bool> SettingChanged;
private PenumbraApiEc _lastSettingsError = PenumbraApiEc.Success;
@ -33,7 +33,7 @@ public class ModSettingsIpcTester : IUiService, IDisposable
private IReadOnlyDictionary<string, (string[], GroupType)>? _availableSettings;
private Dictionary<string, List<string>>? _currentSettings;
public ModSettingsIpcTester(DalamudPluginInterface pi)
public ModSettingsIpcTester(IDalamudPluginInterface pi)
{
_pi = pi;
SettingChanged = ModSettingChanged.Subscriber(pi, UpdateLastModSetting);

View file

@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
public class ModsIpcTester : IUiService, IDisposable
{
private readonly DalamudPluginInterface _pi;
private readonly IDalamudPluginInterface _pi;
private string _modDirectory = string.Empty;
private string _modName = string.Empty;
@ -38,7 +38,7 @@ public class ModsIpcTester : IUiService, IDisposable
private string _lastMovedModFrom = string.Empty;
private string _lastMovedModTo = string.Empty;
public ModsIpcTester(DalamudPluginInterface pi)
public ModsIpcTester(IDalamudPluginInterface pi)
{
_pi = pi;
DeleteSubscriber = ModDeleted.Subscriber(pi, s =>

View file

@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
public class PluginStateIpcTester : IUiService, IDisposable
{
private readonly DalamudPluginInterface _pi;
private readonly IDalamudPluginInterface _pi;
public readonly EventSubscriber<string, bool> ModDirectoryChanged;
public readonly EventSubscriber Initialized;
public readonly EventSubscriber Disposed;
@ -29,7 +29,7 @@ public class PluginStateIpcTester : IUiService, IDisposable
private DateTimeOffset _lastEnabledChange = DateTimeOffset.UnixEpoch;
private bool? _lastEnabledValue;
public PluginStateIpcTester(DalamudPluginInterface pi)
public PluginStateIpcTester(IDalamudPluginInterface pi)
{
_pi = pi;
ModDirectoryChanged = IpcSubscribers.ModDirectoryChanged.Subscriber(pi, UpdateModDirectoryChanged);

View file

@ -13,14 +13,14 @@ namespace Penumbra.Api.IpcTester;
public class RedrawingIpcTester : IUiService, IDisposable
{
private readonly DalamudPluginInterface _pi;
private readonly IDalamudPluginInterface _pi;
private readonly ObjectManager _objects;
public readonly EventSubscriber<nint, int> Redrawn;
private int _redrawIndex;
private string _lastRedrawnString = "None";
public RedrawingIpcTester(DalamudPluginInterface pi, ObjectManager objects)
public RedrawingIpcTester(IDalamudPluginInterface pi, ObjectManager objects)
{
_pi = pi;
_objects = objects;

View file

@ -7,7 +7,7 @@ using Penumbra.String.Classes;
namespace Penumbra.Api.IpcTester;
public class ResolveIpcTester(DalamudPluginInterface pi) : IUiService
public class ResolveIpcTester(IDalamudPluginInterface pi) : IUiService
{
private string _currentResolvePath = string.Empty;
private string _currentReversePath = string.Empty;

View file

@ -15,7 +15,7 @@ using Penumbra.GameData.Structs;
namespace Penumbra.Api.IpcTester;
public class ResourceTreeIpcTester(DalamudPluginInterface pi, ObjectManager objects) : IUiService
public class ResourceTreeIpcTester(IDalamudPluginInterface pi, ObjectManager objects) : IUiService
{
private readonly Stopwatch _stopwatch = new();

View file

@ -17,7 +17,7 @@ using Penumbra.Services;
namespace Penumbra.Api.IpcTester;
public class TemporaryIpcTester(
DalamudPluginInterface pi,
IDalamudPluginInterface pi,
ModManager modManager,
CollectionManager collections,
TempModManager tempMods,

View file

@ -10,7 +10,7 @@ namespace Penumbra.Api.IpcTester;
public class UiIpcTester : IUiService, IDisposable
{
private readonly DalamudPluginInterface _pi;
private readonly IDalamudPluginInterface _pi;
public readonly EventSubscriber<string, float, float> PreSettingsTabBar;
public readonly EventSubscriber<string> PreSettingsPanel;
public readonly EventSubscriber<string> PostEnabled;
@ -28,7 +28,7 @@ public class UiIpcTester : IUiService, IDisposable
private string _modName = string.Empty;
private PenumbraApiEc _ec = PenumbraApiEc.Success;
public UiIpcTester(DalamudPluginInterface pi)
public UiIpcTester(IDalamudPluginInterface pi)
{
_pi = pi;
PreSettingsTabBar = IpcSubscribers.PreSettingsTabBarDraw.Subscriber(pi, UpdateLastDrawnMod);

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui.Classes;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Services;

View file

@ -127,7 +127,7 @@ public sealed partial class IndividualCollections : IReadOnlyList<(string Displa
}
}
public bool TryGetCollection(GameObject? gameObject, out ModCollection? collection)
public bool TryGetCollection(IGameObject? gameObject, out ModCollection? collection)
=> TryGetCollection(_actors.FromObject(gameObject, true, false, false), out collection);
public unsafe bool TryGetCollection(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection)

View file

@ -1,5 +1,5 @@
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json.Linq;
using OtterGui.Classes;
using Penumbra.GameData.Actors;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Filesystem;

View file

@ -1,5 +1,5 @@
using Dalamud.Configuration;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json;
using OtterGui;
using OtterGui.Classes;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json;
using OtterGui.Classes;
using OtterGui.Services;

View file

@ -1,4 +1,7 @@
using FFXIVClientStructs.Havok;
using FFXIVClientStructs.Havok.Common.Base.System.IO.OStream;
using FFXIVClientStructs.Havok.Common.Base.Types;
using FFXIVClientStructs.Havok.Common.Serialize.Resource;
using FFXIVClientStructs.Havok.Common.Serialize.Util;
namespace Penumbra.Import.Models;

View file

@ -103,7 +103,7 @@ public readonly struct BaseImage : IDisposable
{
null => 0,
ScratchImage s => s.Meta.MipLevels,
TexFile t => t.Header.MipLevelsCount,
TexFile t => t.Header.MipCount,
_ => 1,
};
}

View file

@ -79,8 +79,8 @@ public static class TexFileParser
w.Write(header.Width);
w.Write(header.Height);
w.Write(header.Depth);
w.Write(header.MipLevelsCount);
w.Write((byte)0); // TODO Lumina Update
w.Write(header.MipCount);
w.Write(header.MipUnknownFlag); // TODO Lumina Update
unsafe
{
w.Write(header.LodOffset[0]);
@ -96,11 +96,11 @@ public static class TexFileParser
var meta = scratch.Meta;
var ret = new TexFile.TexHeader()
{
Height = (ushort)meta.Height,
Width = (ushort)meta.Width,
Depth = (ushort)Math.Max(meta.Depth, 1),
MipLevelsCount = (byte)Math.Min(meta.MipLevels, 13),
Format = meta.Format.ToTexFormat(),
Height = (ushort)meta.Height,
Width = (ushort)meta.Width,
Depth = (ushort)Math.Max(meta.Depth, 1),
MipCount = (byte)Math.Min(meta.MipLevels, 13),
Format = meta.Format.ToTexFormat(),
Type = meta.Dimension switch
{
_ when meta.IsCubeMap => TexFile.Attribute.TextureTypeCube,
@ -143,7 +143,7 @@ public static class TexFileParser
Height = header.Height,
Width = header.Width,
Depth = Math.Max(header.Depth, (ushort)1),
MipLevels = header.MipLevelsCount,
MipLevels = header.MipCount,
ArraySize = 1,
Format = header.Format.ToDXGI(),
Dimension = header.Type.ToDimension(),

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures.TextureWraps;
using OtterTex;
namespace Penumbra.Import.Textures;

View file

@ -105,7 +105,7 @@ public static class TextureDrawer
ImGuiUtil.DrawTableColumn("Format");
ImGuiUtil.DrawTableColumn(t.Header.Format.ToString());
ImGuiUtil.DrawTableColumn("Mip Levels");
ImGuiUtil.DrawTableColumn(t.Header.MipLevelsCount.ToString());
ImGuiUtil.DrawTableColumn(t.Header.MipCount.ToString());
ImGuiUtil.DrawTableColumn("Data Size");
ImGuiUtil.DrawTableColumn($"{Functions.HumanReadableSize(t.ImageData.Length)} ({t.ImageData.Length} Bytes)");
break;

View file

@ -1,5 +1,5 @@
using Dalamud.Interface;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Textures;
using Dalamud.Interface.Textures.TextureWraps;
using Dalamud.Plugin.Services;
using Lumina.Data.Files;
using OtterGui.Log;
@ -13,7 +13,7 @@ using Image = SixLabors.ImageSharp.Image;
namespace Penumbra.Import.Textures;
public sealed class TextureManager(UiBuilder uiBuilder, IDataManager gameData, Logger logger)
public sealed class TextureManager(IDataManager gameData, Logger logger, ITextureProvider textureProvider)
: SingleTaskQueue, IDisposable, IService
{
private readonly Logger _logger = logger;
@ -211,7 +211,7 @@ public sealed class TextureManager(UiBuilder uiBuilder, IDataManager gameData, L
/// <summary> Load a texture wrap for a given image. </summary>
public IDalamudTextureWrap LoadTextureWrap(byte[] rgba, int width, int height)
=> uiBuilder.LoadImageRaw(rgba, width, height, 4);
=> textureProvider.CreateFromRaw(RawImageSpecification.Rgba32(width, height), rgba, "Penumbra.Texture");
/// <summary> Load any supported file from game data or drive depending on extension and if the path is rooted. </summary>
public (BaseImage, TextureType) Load(string path)

View file

@ -21,7 +21,7 @@ public sealed unsafe class ApricotListenerSoundPlay : FastHook<ApricotListenerSo
_state = state;
_collectionResolver = collectionResolver;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Apricot Listener Sound Play", Sigs.ApricotListenerSoundPlay, Detour, true);
Task = hooks.CreateHook<Delegate>("Apricot Listener Sound Play", Sigs.ApricotListenerSoundPlay, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate nint Delegate(nint a1, nint a2, nint a3, nint a4, nint a5, nint a6);

View file

@ -26,7 +26,7 @@ public sealed unsafe class CharacterBaseLoadAnimation : FastHook<CharacterBaseLo
_collectionResolver = collectionResolver;
_drawObjectState = drawObjectState;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("CharacterBase Load Animation", Sigs.CharacterBaseLoadAnimation, Detour, true);
Task = hooks.CreateHook<Delegate>("CharacterBase Load Animation", Sigs.CharacterBaseLoadAnimation, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(DrawObject* drawBase);

View file

@ -15,7 +15,7 @@ public sealed unsafe class Dismount : FastHook<Dismount.Delegate>
{
_state = state;
_collectionResolver = collectionResolver;
Task = hooks.CreateHook<Delegate>("Dismount", Sigs.Dismount, Detour, true);
Task = hooks.CreateHook<Delegate>("Dismount", Sigs.Dismount, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(nint a1, nint a2);

View file

@ -20,7 +20,7 @@ public sealed unsafe class LoadAreaVfx : FastHook<LoadAreaVfx.Delegate>
_state = state;
_collectionResolver = collectionResolver;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Load Area VFX", Sigs.LoadAreaVfx, Detour, true);
Task = hooks.CreateHook<Delegate>("Load Area VFX", Sigs.LoadAreaVfx, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate nint Delegate(uint vfxId, float* pos, GameObject* caster, float unk1, float unk2, byte unk3);

View file

@ -1,3 +1,4 @@
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using OtterGui.Services;
using Penumbra.CrashHandler.Buffers;
@ -15,12 +16,10 @@ public sealed unsafe class LoadCharacterSound : FastHook<LoadCharacterSound.Dele
public LoadCharacterSound(HookManager hooks, GameState state, CollectionResolver collectionResolver, CrashHandlerService crashHandler)
{
_state = state;
_state = state;
_collectionResolver = collectionResolver;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Load Character Sound",
(nint)FFXIVClientStructs.FFXIV.Client.Game.Character.Character.VfxContainer.MemberFunctionPointers.LoadCharacterSound, Detour,
true);
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Load Character Sound", (nint)VfxContainer.MemberFunctionPointers.LoadCharacterSound, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate nint Delegate(nint container, int unk1, int unk2, nint unk3, ulong unk4, int unk5, int unk6, ulong unk7);

View file

@ -26,7 +26,7 @@ public sealed unsafe class LoadCharacterVfx : FastHook<LoadCharacterVfx.Delegate
_collectionResolver = collectionResolver;
_objects = objects;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Load Character VFX", Sigs.LoadCharacterVfx, Detour, true);
Task = hooks.CreateHook<Delegate>("Load Character VFX", Sigs.LoadCharacterVfx, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate nint Delegate(byte* vfxPath, VfxParams* vfxParams, byte unk1, byte unk2, float unk3, int unk4);

View file

@ -30,7 +30,7 @@ public sealed unsafe class LoadTimelineResources : FastHook<LoadTimelineResource
_conditions = conditions;
_objects = objects;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Load Timeline Resources", Sigs.LoadTimelineResources, Detour, true);
Task = hooks.CreateHook<Delegate>("Load Timeline Resources", Sigs.LoadTimelineResources, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate ulong Delegate(nint timeline);

View file

@ -14,7 +14,7 @@ public sealed unsafe class PlayFootstep : FastHook<PlayFootstep.Delegate>
{
_state = state;
_collectionResolver = collectionResolver;
Task = hooks.CreateHook<Delegate>("Play Footstep", Sigs.FootStepSound, Detour, true);
Task = hooks.CreateHook<Delegate>("Play Footstep", Sigs.FootStepSound, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(GameObject* gameObject, int id, int unk);

View file

@ -23,7 +23,7 @@ public sealed unsafe class ScheduleClipUpdate : FastHook<ScheduleClipUpdate.Dele
_collectionResolver = collectionResolver;
_objects = objects;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Schedule Clip Update", Sigs.ScheduleClipUpdate, Detour, true);
Task = hooks.CreateHook<Delegate>("Schedule Clip Update", Sigs.ScheduleClipUpdate, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(ClipScheduler* x);

View file

@ -1,4 +1,4 @@
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using OtterGui.Services;
using Penumbra.CrashHandler.Buffers;
@ -20,15 +20,15 @@ public sealed unsafe class SomeActionLoad : FastHook<SomeActionLoad.Delegate>
_state = state;
_collectionResolver = collectionResolver;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Some Action Load", Sigs.LoadSomeAction, Detour, true);
Task = hooks.CreateHook<Delegate>("Some Action Load", Sigs.LoadSomeAction, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(ActionTimelineManager* timelineManager);
public delegate void Delegate(TimelineContainer* timelineManager);
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private void Detour(ActionTimelineManager* timelineManager)
private void Detour(TimelineContainer* timelineManager)
{
var newData = _collectionResolver.IdentifyCollection((GameObject*)timelineManager->Parent, true);
var newData = _collectionResolver.IdentifyCollection((GameObject*)timelineManager->OwnerObject, true);
var last = _state.SetAnimationData(newData);
Penumbra.Log.Excessive($"[Some Action Load] Invoked on 0x{(nint)timelineManager:X}.");
_crashHandler.LogAnimation(newData.AssociatedGameObject, newData.ModCollection, AnimationInvocationType.ActionLoad);

View file

@ -15,7 +15,7 @@ public sealed unsafe class SomeMountAnimation : FastHook<SomeMountAnimation.Dele
{
_state = state;
_collectionResolver = collectionResolver;
Task = hooks.CreateHook<Delegate>("Some Mount Animation", Sigs.UnkMountAnimation, Detour, true);
Task = hooks.CreateHook<Delegate>("Some Mount Animation", Sigs.UnkMountAnimation, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(DrawObject* drawObject, uint unk1, byte unk2, uint unk3);

View file

@ -22,7 +22,7 @@ public sealed unsafe class SomePapLoad : FastHook<SomePapLoad.Delegate>
_collectionResolver = collectionResolver;
_objects = objects;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Some PAP Load", Sigs.LoadSomePap, Detour, true);
Task = hooks.CreateHook<Delegate>("Some PAP Load", Sigs.LoadSomePap, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(nint a1, int a2, nint a3, int a4);

View file

@ -15,7 +15,7 @@ public sealed unsafe class SomeParasolAnimation : FastHook<SomeParasolAnimation.
{
_state = state;
_collectionResolver = collectionResolver;
Task = hooks.CreateHook<Delegate>("Some Parasol Animation", Sigs.UnkParasolAnimation, Detour, true);
Task = hooks.CreateHook<Delegate>("Some Parasol Animation", Sigs.UnkParasolAnimation, Detour, HookSettings.VfxIdentificationHooks);
}
public delegate void Delegate(DrawObject* drawObject, int unk1);

View file

@ -0,0 +1,8 @@
namespace Penumbra.Interop.Hooks;
public static class HookSettings
{
public const bool MetaEntryHooks = false;
public const bool MetaParentHooks = false;
public const bool VfxIdentificationHooks = false;
}

View file

@ -1,6 +1,5 @@
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using OtterGui.Services;
using Penumbra.Collections;
using Penumbra.Interop.PathResolving;
using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character;
@ -15,7 +14,7 @@ public sealed unsafe class CalculateHeight : FastHook<CalculateHeight.Delegate>
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("Calculate Height", (nint)Character.MemberFunctionPointers.CalculateHeight, Detour, true);
Task = hooks.CreateHook<Delegate>("Calculate Height", (nint)Character.MemberFunctionPointers.CalculateHeight, Detour, HookSettings.MetaParentHooks);
}
public delegate ulong Delegate(Character* character);

View file

@ -16,7 +16,7 @@ public sealed unsafe class ChangeCustomize : FastHook<ChangeCustomize.Delegate>
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("Change Customize", Sigs.ChangeCustomize, Detour, true);
Task = hooks.CreateHook<Delegate>("Change Customize", Sigs.ChangeCustomize, Detour, HookSettings.MetaParentHooks);
}
public delegate bool Delegate(Human* human, CustomizeArray* data, byte skipEquipment);

View file

@ -16,7 +16,7 @@ public unsafe class EqdpAccessoryHook : FastHook<EqdpAccessoryHook.Delegate>, ID
public EqdpAccessoryHook(HookManager hooks, MetaState metaState)
{
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("GetEqdpAccessoryEntry", Sigs.GetEqdpAccessoryEntry, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetEqdpAccessoryEntry", Sigs.GetEqdpAccessoryEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -16,7 +16,7 @@ public unsafe class EqdpEquipHook : FastHook<EqdpEquipHook.Delegate>, IDisposabl
public EqdpEquipHook(HookManager hooks, MetaState metaState)
{
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("GetEqdpEquipEntry", Sigs.GetEqdpEquipEntry, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetEqdpEquipEntry", Sigs.GetEqdpEquipEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -15,7 +15,7 @@ public unsafe class EqpHook : FastHook<EqpHook.Delegate>, IDisposable
public EqpHook(HookManager hooks, MetaState metaState)
{
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("GetEqpFlags", Sigs.GetEqpEntry, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetEqpFlags", Sigs.GetEqpEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -16,7 +16,7 @@ public class EstHook : FastHook<EstHook.Delegate>, IDisposable
public EstHook(HookManager hooks, MetaState metaState)
{
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("GetEstEntry", Sigs.GetEstEntry, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetEstEntry", Sigs.GetEstEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -15,7 +15,7 @@ public sealed unsafe class GetEqpIndirect : FastHook<GetEqpIndirect.Delegate>
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("Get EQP Indirect", Sigs.GetEqpIndirect, Detour, true);
Task = hooks.CreateHook<Delegate>("Get EQP Indirect", Sigs.GetEqpIndirect, Detour, HookSettings.MetaParentHooks);
}
public delegate void Delegate(DrawObject* drawObject);

View file

@ -15,7 +15,7 @@ public sealed unsafe class GetEqpIndirect2 : FastHook<GetEqpIndirect2.Delegate>
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("Get EQP Indirect 2", Sigs.GetEqpIndirect2, Detour, true);
Task = hooks.CreateHook<Delegate>("Get EQP Indirect 2", Sigs.GetEqpIndirect2, Detour, HookSettings.MetaParentHooks);
}
public delegate void Delegate(DrawObject* drawObject);

View file

@ -17,7 +17,7 @@ public unsafe class GmpHook : FastHook<GmpHook.Delegate>, IDisposable
public GmpHook(HookManager hooks, MetaState metaState)
{
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("GetGmpEntry", Sigs.GetGmpEntry, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetGmpEntry", Sigs.GetGmpEntry, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -1,6 +1,5 @@
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Services;
using Penumbra.Collections;
using Penumbra.Interop.PathResolving;
namespace Penumbra.Interop.Hooks.Meta;
@ -14,7 +13,7 @@ public sealed unsafe class ModelLoadComplete : FastHook<ModelLoadComplete.Delega
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("Model Load Complete", vtables.HumanVTable[58], Detour, true);
Task = hooks.CreateHook<Delegate>("Model Load Complete", vtables.HumanVTable[58], Detour, HookSettings.MetaParentHooks);
}
public delegate void Delegate(DrawObject* drawObject);

View file

@ -20,7 +20,7 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>, IDisposable
{
_metaState = metaState;
_metaFileManager = metaFileManager;
Task = hooks.CreateHook<Delegate>("GetRspBust", Sigs.GetRspBust, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetRspBust", Sigs.GetRspBust, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -19,7 +19,7 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>, IDisposable
{
_metaState = metaState;
_metaFileManager = metaFileManager;
Task = hooks.CreateHook<Delegate>("GetRspHeight", Sigs.GetRspHeight, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetRspHeight", Sigs.GetRspHeight, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -15,7 +15,7 @@ public sealed unsafe class RspSetupCharacter : FastHook<RspSetupCharacter.Delega
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("RSP Setup Character", Sigs.RspSetupCharacter, Detour, true);
Task = hooks.CreateHook<Delegate>("RSP Setup Character", Sigs.RspSetupCharacter, Detour, HookSettings.MetaParentHooks);
}
public delegate void Delegate(DrawObject* drawObject, nint unk2, float unk3, nint unk4, byte unk5);

View file

@ -19,7 +19,7 @@ public class RspTailHook : FastHook<RspTailHook.Delegate>, IDisposable
{
_metaState = metaState;
_metaFileManager = metaFileManager;
Task = hooks.CreateHook<Delegate>("GetRspTail", Sigs.GetRspTail, Detour, metaState.Config.EnableMods);
Task = hooks.CreateHook<Delegate>("GetRspTail", Sigs.GetRspTail, Detour, metaState.Config.EnableMods && HookSettings.MetaEntryHooks);
_metaState.Config.ModsEnabled += Toggle;
}

View file

@ -19,7 +19,7 @@ public sealed unsafe class SetupVisor : FastHook<SetupVisor.Delegate>
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("Setup Visor", Sigs.SetupVisor, Detour, true);
Task = hooks.CreateHook<Delegate>("Setup Visor", Sigs.SetupVisor, Detour, HookSettings.MetaParentHooks);
}
public delegate byte Delegate(DrawObject* drawObject, ushort modelId, byte visorState);

View file

@ -15,7 +15,7 @@ public sealed unsafe class UpdateModel : FastHook<UpdateModel.Delegate>
{
_collectionResolver = collectionResolver;
_metaState = metaState;
Task = hooks.CreateHook<Delegate>("Update Model", Sigs.UpdateModel, Detour, true);
Task = hooks.CreateHook<Delegate>("Update Model", Sigs.UpdateModel, Detour, HookSettings.MetaParentHooks);
}
public delegate void Delegate(DrawObject* drawObject);

View file

@ -20,7 +20,7 @@ public sealed unsafe class CopyCharacter : EventWrapperPtr<Character, Character,
private readonly Task<Hook<Delegate>> _task;
public nint Address
=> (nint)CharacterSetup.MemberFunctionPointers.CopyFromCharacter;
=> (nint)CharacterSetupContainer.MemberFunctionPointers.CopyFromCharacter;
public void Enable()
=> _task.Result.Enable();
@ -34,9 +34,9 @@ public sealed unsafe class CopyCharacter : EventWrapperPtr<Character, Character,
public bool Finished
=> _task.IsCompletedSuccessfully;
private delegate ulong Delegate(CharacterSetup* target, Character* source, uint unk);
private delegate ulong Delegate(CharacterSetupContainer* target, Character* source, uint unk);
private ulong Detour(CharacterSetup* target, Character* source, uint unk)
private ulong Detour(CharacterSetupContainer* target, Character* source, uint unk)
{
// TODO: update when CS updated.
var character = ((Character**)target)[1];

View file

@ -39,7 +39,7 @@ public sealed unsafe class WeaponReload : EventWrapperPtr<DrawDataContainer, Cha
private void Detour(DrawDataContainer* drawData, uint slot, ulong weapon, byte d, byte e, byte f, byte g)
{
var gameObject = drawData->Parent;
var gameObject = drawData->OwnerObject;
Penumbra.Log.Verbose($"[{Name}] Triggered with drawData: 0x{(nint)drawData:X}, {slot}, {weapon}, {d}, {e}, {f}, {g}.");
Invoke(drawData, gameObject, (CharacterWeapon*)(&weapon));
_task.Result.Original(drawData, slot, weapon, d, e, f, g);

View file

@ -44,18 +44,20 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable
{
_parent = parent;
// @formatter:off
_resolveDecalPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveDecal)}", hooks, vTable[83], ResolveDecal);
_resolveEidPathHook = Create<SingleResolveDelegate>( $"{name}.{nameof(ResolveEid)}", hooks, vTable[85], ResolveEid);
_resolveImcPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveImc)}", hooks, vTable[81], ResolveImc);
_resolveMPapPathHook = Create<MPapResolveDelegate>( $"{name}.{nameof(ResolveMPap)}", hooks, vTable[79], ResolveMPap);
_resolveMdlPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveMdl)}", hooks, vTable[73], type, ResolveMdl, ResolveMdlHuman);
_resolveMtrlPathHook = Create<NamedResolveDelegate>( $"{name}.{nameof(ResolveMtrl)}", hooks, vTable[82], ResolveMtrl);
_resolvePapPathHook = Create<NamedResolveDelegate>( $"{name}.{nameof(ResolvePap)}", hooks, vTable[76], type, ResolvePap, ResolvePapHuman);
_resolvePhybPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolvePhyb)}", hooks, vTable[75], type, ResolvePhyb, ResolvePhybHuman);
_resolveSklbPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSklb)}", hooks, vTable[72], type, ResolveSklb, ResolveSklbHuman);
_resolveSkpPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSkp)}", hooks, vTable[74], type, ResolveSkp, ResolveSkpHuman);
_resolveTmbPathHook = Create<TmbResolveDelegate>( $"{name}.{nameof(ResolveTmb)}", hooks, vTable[77], ResolveTmb);
_resolveVfxPathHook = Create<VfxResolveDelegate>( $"{name}.{nameof(ResolveVfx)}", hooks, vTable[84], type, ResolveVfx, ResolveVfxHuman);
_resolveSklbPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSklb)}", hooks, vTable[76], type, ResolveSklb, ResolveSklbHuman);
_resolveMdlPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveMdl)}", hooks, vTable[77], type, ResolveMdl, ResolveMdlHuman);
_resolveSkpPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSkp)}", hooks, vTable[78], type, ResolveSkp, ResolveSkpHuman);
_resolvePhybPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolvePhyb)}", hooks, vTable[79], type, ResolvePhyb, ResolvePhybHuman);
_resolvePapPathHook = Create<NamedResolveDelegate>( $"{name}.{nameof(ResolvePap)}", hooks, vTable[84], type, ResolvePap, ResolvePapHuman);
_resolveTmbPathHook = Create<TmbResolveDelegate>( $"{name}.{nameof(ResolveTmb)}", hooks, vTable[85], ResolveTmb);
_resolveMPapPathHook = Create<MPapResolveDelegate>( $"{name}.{nameof(ResolveMPap)}", hooks, vTable[87], ResolveMPap);
_resolveImcPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveImc)}", hooks, vTable[89], ResolveImc);
_resolveMtrlPathHook = Create<NamedResolveDelegate>( $"{name}.{nameof(ResolveMtrl)}", hooks, vTable[90], ResolveMtrl);
_resolveDecalPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveDecal)}", hooks, vTable[92], ResolveDecal);
_resolveVfxPathHook = Create<VfxResolveDelegate>( $"{name}.{nameof(ResolveVfx)}", hooks, vTable[93], type, ResolveVfx, ResolveVfxHuman);
_resolveEidPathHook = Create<SingleResolveDelegate>( $"{name}.{nameof(ResolveEid)}", hooks, vTable[94], ResolveEid);
// @formatter:on
Enable();
}

View file

@ -120,7 +120,7 @@ public sealed unsafe class CollectionResolver(
var lobby = AgentLobby.Instance();
if (lobby != null)
{
var span = lobby->LobbyData.CharaSelectEntries.Span;
var span = lobby->LobbyData.CharaSelectEntries.AsSpan();
// The lobby uses the first 8 cutscene actors.
var idx = gameObject->ObjectIndex - ObjectIndex.CutsceneStart.Index;
if (idx >= 0 && idx < span.Length && span[idx].Value != null)
@ -148,7 +148,7 @@ public sealed unsafe class CollectionResolver(
/// <summary> Used if at the aesthetician. The relevant actor is yourself, so use player collection when possible. </summary>
private bool Aesthetician(GameObject* gameObject, out ResolveData ret)
{
if (gameGui.GetAddonByName("ScreenLog") != IntPtr.Zero)
if (gameGui.GetAddonByName("ScreenLog") != nint.Zero)
{
ret = ResolveData.Invalid;
return false;

View file

@ -1,3 +1,4 @@
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using OtterGui.Services;
@ -19,7 +20,7 @@ public sealed class CutsceneService : IRequiredService, IDisposable
private readonly CharacterDestructor _characterDestructor;
private readonly short[] _copiedCharacters = Enumerable.Repeat((short)-1, CutsceneSlots).ToArray();
public IEnumerable<KeyValuePair<int, Dalamud.Game.ClientState.Objects.Types.GameObject>> Actors
public IEnumerable<KeyValuePair<int, IGameObject>> Actors
=> Enumerable.Range(CutsceneStartIdx, CutsceneSlots)
.Where(i => _objects[i].Valid)
.Select(i => KeyValuePair.Create(i, this[i] ?? _objects.GetDalamudObject(i)!));
@ -42,7 +43,7 @@ public sealed class CutsceneService : IRequiredService, IDisposable
/// Does not check for valid input index.
/// Returns null if no connected actor is set or the actor does not exist anymore.
/// </summary>
private Dalamud.Game.ClientState.Objects.Types.GameObject? this[int idx]
private IGameObject? this[int idx]
{
get
{

View file

@ -63,7 +63,7 @@ public unsafe class FileReadService : IDisposable, IRequiredService
byte? ret = null;
_lastFileThreadResourceManager.Value = resourceManager;
ReadSqPack?.Invoke(fileDescriptor, ref priority, ref isSync, ref ret);
_lastFileThreadResourceManager.Value = IntPtr.Zero;
_lastFileThreadResourceManager.Value = nint.Zero;
return ret ?? _readSqPackHook.Original(resourceManager, fileDescriptor, priority, isSync);
}
@ -82,7 +82,7 @@ public unsafe class FileReadService : IDisposable, IRequiredService
/// So we keep track of them per thread and use them.
/// </summary>
private nint GetResourceManager()
=> !_lastFileThreadResourceManager.IsValueCreated || _lastFileThreadResourceManager.Value == IntPtr.Zero
=> !_lastFileThreadResourceManager.IsValueCreated || _lastFileThreadResourceManager.Value == nint.Zero
? (nint)_resourceManager.ResourceManager
: _lastFileThreadResourceManager.Value;
}

View file

@ -25,8 +25,8 @@ public unsafe class ResourceManagerService : IRequiredService
ref var manager = ref *ResourceManager;
var catIdx = (uint)cat >> 0x18;
cat = (ResourceCategory)(ushort)cat;
ref var category = ref manager.ResourceGraph->ContainerArraySpan[(int)cat];
var extMap = FindInMap(category.CategoryMapsSpan[(int)catIdx].Value, (uint)ext);
ref var category = ref manager.ResourceGraph->Containers[(int)cat];
var extMap = FindInMap(category.CategoryMaps[(int)catIdx].Value, (uint)ext);
if (extMap == null)
return null;
@ -44,10 +44,10 @@ public unsafe class ResourceManagerService : IRequiredService
ref var manager = ref *ResourceManager;
foreach (var resourceType in Enum.GetValues<ResourceCategory>().SkipLast(1))
{
ref var graph = ref manager.ResourceGraph->ContainerArraySpan[(int)resourceType];
ref var graph = ref manager.ResourceGraph->Containers[(int)resourceType];
for (var i = 0; i < 20; ++i)
{
var map = graph.CategoryMapsSpan[i];
var map = graph.CategoryMaps[i];
if (map.Value != null)
action(resourceType, map, i);
}
@ -79,25 +79,10 @@ public unsafe class ResourceManagerService : IRequiredService
where TKey : unmanaged, IComparable<TKey>
where TValue : unmanaged
{
if (map == null || map->Count == 0)
if (map == null)
return null;
var node = map->Head->Parent;
while (!node->IsNil)
{
switch (key.CompareTo(node->KeyValuePair.Item1))
{
case 0: return &node->KeyValuePair.Item2;
case < 0:
node = node->Left;
break;
default:
node = node->Right;
break;
}
}
return null;
return map->TryGetValuePointer(key, out var val) ? val : null;
}
// Iterate in tree-order through a map, applying action to each KeyValuePair.
@ -105,10 +90,10 @@ public unsafe class ResourceManagerService : IRequiredService
where TKey : unmanaged
where TValue : unmanaged
{
if (map == null || map->Count == 0)
if (map == null)
return;
for (var node = map->SmallestValue; !node->IsNil; node = node->Next())
action(node->KeyValuePair.Item1, node->KeyValuePair.Item2);
foreach (var (key, value) in *map)
action(key, value);
}
}

View file

@ -127,7 +127,7 @@ public unsafe class ResourceService : IDisposable, IRequiredService
#endregion
private delegate IntPtr ResourceHandlePrototype(ResourceHandle* handle);
private delegate nint ResourceHandlePrototype(ResourceHandle* handle);
#region IncRef

View file

@ -1,6 +1,7 @@
using Dalamud.Hooking;
using Dalamud.Plugin.Services;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.LayoutEngine;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using OtterGui.Services;
using Penumbra.Api.Enums;
@ -12,7 +13,7 @@ namespace Penumbra.Interop.ResourceLoading;
public unsafe class TexMdlService : IDisposable, IRequiredService
{
/// <summary> Custom ulong flag to signal our files as opposed to SE files. </summary>
public static readonly IntPtr CustomFileFlag = new(0xDEADBEEF);
public static readonly nint CustomFileFlag = new(0xDEADBEEF);
/// <summary>
/// We need to keep a list of all CRC64 hash values of our replaced Mdl and Tex files,
@ -24,9 +25,9 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
public TexMdlService(IGameInteropProvider interop)
{
interop.InitializeFromAttributes(this);
_checkFileStateHook.Enable();
_loadTexFileExternHook.Enable();
_loadMdlFileExternHook.Enable();
//_checkFileStateHook.Enable();
//_loadTexFileExternHook.Enable();
//_loadMdlFileExternHook.Enable();
}
/// <summary> Add CRC64 if the given file is a model or texture file and has an associated path. </summary>
@ -42,14 +43,14 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
public void Dispose()
{
_checkFileStateHook.Dispose();
_loadTexFileExternHook.Dispose();
_loadMdlFileExternHook.Dispose();
//_checkFileStateHook.Dispose();
//_loadTexFileExternHook.Dispose();
//_loadMdlFileExternHook.Dispose();
}
private readonly HashSet<ulong> _customFileCrc = new();
private delegate IntPtr CheckFileStatePrototype(IntPtr unk1, ulong crc64);
private delegate nint CheckFileStatePrototype(nint unk1, ulong crc64);
[Signature(Sigs.CheckFileState, DetourName = nameof(CheckFileStateDetour))]
private readonly Hook<CheckFileStatePrototype> _checkFileStateHook = null!;
@ -58,42 +59,53 @@ public unsafe class TexMdlService : IDisposable, IRequiredService
/// The function that checks a files CRC64 to determine whether it is 'protected'.
/// We use it to check against our stored CRC64s and if it corresponds, we return the custom flag.
/// </summary>
private IntPtr CheckFileStateDetour(IntPtr ptr, ulong crc64)
private nint CheckFileStateDetour(nint ptr, ulong crc64)
=> _customFileCrc.Contains(crc64) ? CustomFileFlag : _checkFileStateHook.Original(ptr, crc64);
private delegate byte LoadTexFileLocalDelegate(ResourceHandle* handle, int unk1, IntPtr unk2, bool unk3);
private delegate byte LoadTexFileLocalDelegate(ResourceHandle* handle, int unk1, nint unk2, bool unk3);
/// <summary> We use the local functions for our own files in the extern hook. </summary>
[Signature(Sigs.LoadTexFileLocal)]
private readonly LoadTexFileLocalDelegate _loadTexFileLocal = null!;
private delegate byte LoadMdlFileLocalPrototype(ResourceHandle* handle, IntPtr unk1, bool unk2);
private delegate byte LoadMdlFileLocalPrototype(ResourceHandle* handle, nint unk1, bool unk2);
/// <summary> We use the local functions for our own files in the extern hook. </summary>
[Signature(Sigs.LoadMdlFileLocal)]
private readonly LoadMdlFileLocalPrototype _loadMdlFileLocal = null!;
private delegate byte LoadTexFileExternPrototype(ResourceHandle* handle, int unk1, IntPtr unk2, bool unk3, IntPtr unk4);
private delegate byte LoadTexFileExternPrototype(ResourceHandle* handle, int unk1, nint unk2, bool unk3, nint unk4);
[Signature(Sigs.LoadTexFileExtern, DetourName = nameof(LoadTexFileExternDetour))]
private readonly Hook<LoadTexFileExternPrototype> _loadTexFileExternHook = null!;
private delegate byte TexResourceHandleVf32Prototype(ResourceHandle* handle, nint unk1, byte unk2);
//[Signature("40 53 55 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B D9", DetourName = nameof(Vf32Detour))]
//private readonly Hook<TexResourceHandleVf32Prototype> _vf32Hook = null!;
//
//private byte Vf32Detour(ResourceHandle* handle, nint unk1, byte unk2)
//{
// var ret = _vf32Hook.Original(handle, unk1, unk2);
// return _loadTexFileLocal()
//}
//[Signature(Sigs.LoadTexFileExtern, DetourName = nameof(LoadTexFileExternDetour))]
//private readonly Hook<LoadTexFileExternPrototype> _loadTexFileExternHook = null!;
/// <summary> We hook the extern functions to just return the local one if given the custom flag as last argument. </summary>
private byte LoadTexFileExternDetour(ResourceHandle* resourceHandle, int unk1, IntPtr unk2, bool unk3, IntPtr ptr)
=> ptr.Equals(CustomFileFlag)
? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3)
: _loadTexFileExternHook.Original(resourceHandle, unk1, unk2, unk3, ptr);
//private byte LoadTexFileExternDetour(ResourceHandle* resourceHandle, int unk1, nint unk2, bool unk3, nint ptr)
// => ptr.Equals(CustomFileFlag)
// ? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3)
// : _loadTexFileExternHook.Original(resourceHandle, unk1, unk2, unk3, ptr);
public delegate byte LoadMdlFileExternPrototype(ResourceHandle* handle, IntPtr unk1, bool unk2, IntPtr unk3);
public delegate byte LoadMdlFileExternPrototype(ResourceHandle* handle, nint unk1, bool unk2, nint unk3);
[Signature(Sigs.LoadMdlFileExtern, DetourName = nameof(LoadMdlFileExternDetour))]
private readonly Hook<LoadMdlFileExternPrototype> _loadMdlFileExternHook = null!;
/// <summary> We hook the extern functions to just return the local one if given the custom flag as last argument. </summary>
private byte LoadMdlFileExternDetour(ResourceHandle* resourceHandle, IntPtr unk1, bool unk2, IntPtr ptr)
private byte LoadMdlFileExternDetour(ResourceHandle* resourceHandle, nint unk1, bool unk2, nint ptr)
=> ptr.Equals(CustomFileFlag)
? _loadMdlFileLocal.Invoke(resourceHandle, unk1, unk2)
: _loadMdlFileExternHook.Original(resourceHandle, unk1, unk2, ptr);

View file

@ -111,7 +111,7 @@ internal unsafe partial record ResolveContext(
if (resourceHandle == null)
throw new ArgumentNullException(nameof(resourceHandle));
var fileName = resourceHandle->FileName.AsSpan();
var fileName = (ReadOnlySpan<byte>) resourceHandle->FileName.AsSpan();
var additionalData = ByteString.Empty;
if (PathDataHandler.Split(fileName, out fileName, out var data))
additionalData = ByteString.FromSpanUnsafe(data, false).Clone();

View file

@ -62,7 +62,7 @@ public class ResourceTree
var equipment = modelType switch
{
CharacterBase.ModelType.Human => new ReadOnlySpan<CharacterArmor>(&human->Head, 10),
CharacterBase.ModelType.DemiHuman => new ReadOnlySpan<CharacterArmor>(&character->DrawData.Head, 10),
CharacterBase.ModelType.DemiHuman => new ReadOnlySpan<CharacterArmor>(Unsafe.AsPointer(ref character->DrawData.EquipmentModelIds[0]), 10),
_ => ReadOnlySpan<CharacterArmor>.Empty,
};
ModelId = character->CharacterData.ModelCharaId;

View file

@ -10,7 +10,7 @@ namespace Penumbra.Interop.ResourceTree;
internal static class ResourceTreeApiHelper
{
public static Dictionary<ushort, Dictionary<string, HashSet<string>>> GetResourcePathDictionaries(
IEnumerable<(Character, ResourceTree)> resourceTrees)
IEnumerable<(ICharacter, ResourceTree)> resourceTrees)
{
var pathDictionaries = new Dictionary<ushort, Dictionary<string, HashSet<string>>>(4);
@ -47,7 +47,7 @@ internal static class ResourceTreeApiHelper
}
}
public static Dictionary<ushort, GameResourceDict> GetResourcesOfType(IEnumerable<(Character, ResourceTree)> resourceTrees,
public static Dictionary<ushort, GameResourceDict> GetResourcesOfType(IEnumerable<(ICharacter, ResourceTree)> resourceTrees,
ResourceType type)
{
var resDictionaries = new Dictionary<ushort, GameResourceDict>(4);
@ -74,7 +74,7 @@ internal static class ResourceTreeApiHelper
return resDictionaries;
}
public static Dictionary<ushort, JObject> EncapsulateResourceTrees(IEnumerable<(Character, ResourceTree)> resourceTrees)
public static Dictionary<ushort, JObject> EncapsulateResourceTrees(IEnumerable<(ICharacter, ResourceTree)> resourceTrees)
{
var resDictionary = new Dictionary<ushort, JObject>(4);
foreach (var (gameObject, resourceTree) in resourceTrees)

View file

@ -1,3 +1,4 @@
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using OtterGui.Services;
@ -23,13 +24,13 @@ public class ResourceTreeFactory(
private TreeBuildCache CreateTreeBuildCache()
=> new(objects, gameData, actors);
public IEnumerable<Dalamud.Game.ClientState.Objects.Types.Character> GetLocalPlayerRelatedCharacters()
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
{
var cache = CreateTreeBuildCache();
return cache.GetLocalPlayerRelatedCharacters();
}
public IEnumerable<(Dalamud.Game.ClientState.Objects.Types.Character Character, ResourceTree ResourceTree)> FromObjectTable(
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromObjectTable(
Flags flags)
{
var cache = CreateTreeBuildCache();
@ -43,8 +44,8 @@ public class ResourceTreeFactory(
}
}
public IEnumerable<(Dalamud.Game.ClientState.Objects.Types.Character Character, ResourceTree ResourceTree)> FromCharacters(
IEnumerable<Dalamud.Game.ClientState.Objects.Types.Character> characters, Flags flags)
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromCharacters(
IEnumerable<ICharacter> characters, Flags flags)
{
var cache = CreateTreeBuildCache();
foreach (var character in characters)
@ -55,10 +56,10 @@ public class ResourceTreeFactory(
}
}
public ResourceTree? FromCharacter(Dalamud.Game.ClientState.Objects.Types.Character character, Flags flags)
public ResourceTree? FromCharacter(ICharacter character, Flags flags)
=> FromCharacter(character, CreateTreeBuildCache(), flags);
private unsafe ResourceTree? FromCharacter(Dalamud.Game.ClientState.Objects.Types.Character character, TreeBuildCache cache, Flags flags)
private unsafe ResourceTree? FromCharacter(ICharacter character, TreeBuildCache cache, Flags flags)
{
if (!character.IsValid())
return null;
@ -74,7 +75,7 @@ public class ResourceTreeFactory(
var localPlayerRelated = cache.IsLocalPlayerRelated(character);
var (name, anonymizedName, related) = GetCharacterName(character);
var networked = character.ObjectId != Dalamud.Game.ClientState.Objects.Types.GameObject.InvalidGameObjectId;
var networked = character.EntityId != 0xE0000000;
var tree = new ResourceTree(name, anonymizedName, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related,
networked, collectionResolveData.ModCollection.Name, collectionResolveData.ModCollection.AnonymizedName);
var globalContext = new GlobalResolveContext(identifier, collectionResolveData.ModCollection,
@ -155,14 +156,14 @@ public class ResourceTreeFactory(
}
}
private unsafe (string Name, string AnonymizedName, bool PlayerRelated) GetCharacterName(Dalamud.Game.ClientState.Objects.Types.Character character)
private unsafe (string Name, string AnonymizedName, bool PlayerRelated) GetCharacterName(ICharacter character)
{
var identifier = actors.FromObject((GameObject*)character.Address, out var owner, true, false, false);
var identifierStr = identifier.ToString();
return (identifierStr, identifier.Incognito(identifierStr), IsPlayerRelated(identifier, owner));
}
private unsafe bool IsPlayerRelated(Dalamud.Game.ClientState.Objects.Types.Character? character)
private unsafe bool IsPlayerRelated(ICharacter? character)
{
if (character == null)
return false;
@ -175,7 +176,7 @@ public class ResourceTreeFactory(
=> identifier.Type switch
{
IdentifierType.Player => true,
IdentifierType.Owned => IsPlayerRelated(objects.Objects.CreateObjectReference(owner) as Dalamud.Game.ClientState.Objects.Types.Character),
IdentifierType.Owned => IsPlayerRelated(objects.Objects.CreateObjectReference(owner) as ICharacter),
_ => false,
};

View file

@ -13,7 +13,7 @@ internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager data
{
private readonly Dictionary<FullPath, ShpkFile?> _shaderPackages = [];
public unsafe bool IsLocalPlayerRelated(Character character)
public unsafe bool IsLocalPlayerRelated(ICharacter character)
{
var player = objects.GetDalamudObject(0);
if (player == null)
@ -25,36 +25,36 @@ internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager data
return actualIndex switch
{
< 2 => true,
< (int)ScreenActor.CutsceneStart => gameObject->OwnerID == player.ObjectId,
< (int)ScreenActor.CutsceneStart => gameObject->OwnerId == player.EntityId,
_ => false,
};
}
public IEnumerable<Character> GetCharacters()
=> objects.Objects.OfType<Character>();
public IEnumerable<ICharacter> GetCharacters()
=> objects.Objects.OfType<ICharacter>();
public IEnumerable<Character> GetLocalPlayerRelatedCharacters()
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
{
var player = objects.GetDalamudObject(0);
if (player == null)
yield break;
yield return (Character)player;
yield return (ICharacter)player;
var minion = objects.GetDalamudObject(1);
if (minion != null)
yield return (Character)minion;
yield return (ICharacter)minion;
var playerId = player.ObjectId;
var playerId = player.EntityId;
for (var i = 2; i < ObjectIndex.CutsceneStart.Index; i += 2)
{
if (objects.GetDalamudObject(i) is Character owned && owned.OwnerId == playerId)
if (objects.GetDalamudObject(i) is ICharacter owned && owned.OwnerId == playerId)
yield return owned;
}
for (var i = ObjectIndex.CutsceneStart.Index; i < ObjectIndex.CharacterScreen.Index; ++i)
{
var character = objects.GetDalamudObject((int) i) as Character;
var character = objects.GetDalamudObject((int) i) as ICharacter;
if (character == null)
continue;

View file

@ -34,7 +34,7 @@ public unsafe class FontReloader : IService
if (framework == null)
return;
var uiModule = framework->GetUiModule();
var uiModule = framework->GetUIModule();
if (uiModule == null)
return;
@ -43,7 +43,7 @@ public unsafe class FontReloader : IService
return;
_atkModule = &atkModule->AtkModule;
_reloadFontsFunc = ((delegate* unmanaged<AtkModule*, bool, bool, void>*)_atkModule->vtbl)[Offsets.ReloadFontsVfunc];
_reloadFontsFunc = ((delegate* unmanaged<AtkModule*, bool, bool, void>*)_atkModule->VirtualTable)[Offsets.ReloadFontsVfunc];
});
}
}

View file

@ -4,8 +4,8 @@ using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Objects.SubKinds;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game.Housing;
using FFXIVClientStructs.Interop;
using FFXIVClientStructs.FFXIV.Client.Game;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using OtterGui.Services;
using Penumbra.Api;
using Penumbra.Api.Enums;
@ -37,11 +37,11 @@ public unsafe partial class RedrawService : IService
=> _clientState.IsGPosing;
// VFuncs that disable and enable draw, used only for GPose actors.
private static void DisableDraw(GameObject actor)
=> ((delegate* unmanaged< IntPtr, void >**)actor.Address)[0][Offsets.DisableDrawVfunc](actor.Address);
private static void DisableDraw(IGameObject actor)
=> ((delegate* unmanaged<nint, void >**)actor.Address)[0][Offsets.DisableDrawVfunc](actor.Address);
private static void EnableDraw(GameObject actor)
=> ((delegate* unmanaged< IntPtr, void >**)actor.Address)[0][Offsets.EnableDrawVfunc](actor.Address);
private static void EnableDraw(IGameObject actor)
=> ((delegate* unmanaged<nint, void >**)actor.Address)[0][Offsets.EnableDrawVfunc](actor.Address);
// Check whether we currently are in GPose.
// Also clear the name list.
@ -57,7 +57,7 @@ public unsafe partial class RedrawService : IService
// obj will be the object itself (or null) and false will be returned.
// If we are in GPose and a game object with the same name as the original actor is found,
// this will be in obj and true will be returned.
private bool FindCorrectActor(int idx, out GameObject? obj)
private bool FindCorrectActor(int idx, out IGameObject? obj)
{
obj = _objects.GetDalamudObject(idx);
if (!InGPose || obj == null || IsGPoseActor(idx))
@ -91,11 +91,11 @@ public unsafe partial class RedrawService : IService
}
}
return obj;
return false;
}
// Do not ever redraw any of the five UI Window actors.
private static bool BadRedrawIndices(GameObject? actor, out int tableIndex)
private static bool BadRedrawIndices(IGameObject? actor, out int tableIndex)
{
if (actor == null)
{
@ -155,13 +155,13 @@ public sealed unsafe partial class RedrawService : IDisposable
_communicator.ModFileChanged.Unsubscribe(OnModFileChanged);
}
public static DrawState* ActorDrawState(GameObject actor)
public static DrawState* ActorDrawState(IGameObject actor)
=> (DrawState*)(&((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actor.Address)->RenderFlags);
private static int ObjectTableIndex(GameObject actor)
private static int ObjectTableIndex(IGameObject actor)
=> ((FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)actor.Address)->ObjectIndex;
private void WriteInvisible(GameObject? actor)
private void WriteInvisible(IGameObject? actor)
{
if (BadRedrawIndices(actor, out var tableIndex))
return;
@ -172,7 +172,7 @@ public sealed unsafe partial class RedrawService : IDisposable
if (gPose)
DisableDraw(actor!);
if (actor is PlayerCharacter
if (actor is IPlayerCharacter
&& _objects.GetDalamudObject(tableIndex + 1) is { ObjectKind: ObjectKind.MountType or ObjectKind.Ornament } mountOrOrnament)
{
*ActorDrawState(mountOrOrnament) |= DrawState.Invisibility;
@ -181,7 +181,7 @@ public sealed unsafe partial class RedrawService : IDisposable
}
}
private void WriteVisible(GameObject? actor)
private void WriteVisible(IGameObject? actor)
{
if (BadRedrawIndices(actor, out var tableIndex))
return;
@ -192,7 +192,7 @@ public sealed unsafe partial class RedrawService : IDisposable
if (gPose)
EnableDraw(actor!);
if (actor is PlayerCharacter
if (actor is IPlayerCharacter
&& _objects.GetDalamudObject(tableIndex + 1) is { ObjectKind: ObjectKind.MountType or ObjectKind.Ornament } mountOrOrnament)
{
*ActorDrawState(mountOrOrnament) &= ~DrawState.Invisibility;
@ -203,7 +203,7 @@ public sealed unsafe partial class RedrawService : IDisposable
GameObjectRedrawn?.Invoke(actor!.Address, tableIndex);
}
private void ReloadActor(GameObject? actor)
private void ReloadActor(IGameObject? actor)
{
if (BadRedrawIndices(actor, out var tableIndex))
return;
@ -214,7 +214,7 @@ public sealed unsafe partial class RedrawService : IDisposable
_queue.Add(~tableIndex);
}
private void ReloadActorAfterGPose(GameObject? actor)
private void ReloadActorAfterGPose(IGameObject? actor)
{
if (_objects[GPosePlayerIdx].Valid)
{
@ -284,21 +284,21 @@ public sealed unsafe partial class RedrawService : IDisposable
_queue.RemoveRange(numKept, _queue.Count - numKept);
}
private static uint GetCurrentAnimationId(GameObject obj)
private static uint GetCurrentAnimationId(IGameObject obj)
{
var gameObj = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)obj.Address;
if (gameObj == null || !gameObj->IsCharacter())
return 0;
var chara = (Character*)gameObj;
var ptr = (byte*)&chara->ActionTimelineManager + 0xF0;
var ptr = (byte*)&chara->Timeline + 0xF0;
return *(uint*)ptr;
}
private static bool DelayRedraw(GameObject obj)
private static bool DelayRedraw(IGameObject obj)
=> ((Character*)obj.Address)->Mode switch
{
(Character.CharacterModes)6 => // fishing
(CharacterModes)6 => // fishing
GetCurrentAnimationId(obj) switch
{
278 => true, // line out.
@ -345,7 +345,7 @@ public sealed unsafe partial class RedrawService : IDisposable
HandleTarget();
}
public void RedrawObject(GameObject? actor, RedrawType settings)
public void RedrawObject(IGameObject? actor, RedrawType settings)
{
switch (settings)
{
@ -359,13 +359,13 @@ public sealed unsafe partial class RedrawService : IDisposable
}
}
private GameObject? GetLocalPlayer()
private IGameObject? GetLocalPlayer()
{
var gPosePlayer = _objects.GetDalamudObject(GPosePlayerIdx);
return gPosePlayer ?? _objects.GetDalamudObject(0);
}
public bool GetName(string lowerName, out GameObject? actor)
public bool GetName(string lowerName, out IGameObject? actor)
{
(actor, var ret) = lowerName switch
{
@ -419,15 +419,14 @@ public sealed unsafe partial class RedrawService : IDisposable
if (housingManager == null)
return;
var currentTerritory = housingManager->CurrentTerritory;
if (currentTerritory == null)
return;
if (!housingManager->IsInside())
var currentTerritory = (OutdoorTerritory*) housingManager->CurrentTerritory;
if (currentTerritory == null || currentTerritory->GetTerritoryType() is not HousingTerritoryType.Outdoor)
return;
foreach (var f in currentTerritory->FurnitureSpan.PointerEnumerator())
foreach (ref var f in currentTerritory->Furniture)
{
var gameObject = f->Index >= 0 ? currentTerritory->HousingObjectManager.ObjectsSpan[f->Index].Value : null;
var gameObject = f.Index >= 0 ? currentTerritory->HousingObjectManager.Objects[f.Index].Value : null;
if (gameObject == null)
continue;

View file

@ -4,8 +4,8 @@ namespace Penumbra.Interop.Structs;
public unsafe struct ClipScheduler
{
[FieldOffset(0)]
public IntPtr* VTable;
public nint* VTable;
[FieldOffset(0x38)]
public IntPtr SchedulerTimeline;
public nint SchedulerTimeline;
}

View file

@ -83,12 +83,12 @@ public unsafe struct ResourceHandle
[FieldOffset(0xB8)]
public uint DataLength;
public (IntPtr Data, int Length) GetData()
public (nint Data, int Length) GetData()
=> Data != null
? ((IntPtr)Data->DataPtr, (int)Data->DataLength)
: (IntPtr.Zero, 0);
? ((nint)Data->DataPtr, (int)Data->DataLength)
: (nint.Zero, 0);
public bool SetData(IntPtr data, int length)
public bool SetData(nint data, int length)
{
if (Data == null)
return false;

View file

@ -71,7 +71,7 @@ public unsafe class MetaBaseFile(MetaFileManager manager, IFileAllocator alloc,
public int Length { get; private set; }
public CharacterUtility.InternalIndex Index { get; } = CharacterUtility.ReverseIndices[(int)idx];
protected (IntPtr Data, int Length) DefaultData
protected (nint Data, int Length) DefaultData
=> Manager.CharacterUtility.DefaultResource(Index);
/// <summary> Reset to default values. </summary>

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Utility;
using OtterGui;
using OtterGui.Classes;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Services;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui;

View file

@ -1,10 +1,9 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui;
using OtterGui.Classes;
using Penumbra.Api.Enums;
using Penumbra.GameData;
using Penumbra.GameData.Data;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods.Settings;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using OtterGui.Classes;
using OtterGui.Services;
using Penumbra.Import;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using OtterGui.Classes;
using OtterGui.Filesystem;
using OtterGui.Services;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui;

View file

@ -48,7 +48,7 @@ public class Penumbra : IDalamudPlugin
private readonly ServiceManager _services;
public Penumbra(DalamudPluginInterface pluginInterface)
public Penumbra(IDalamudPluginInterface pluginInterface)
{
try
{
@ -182,7 +182,7 @@ public class Penumbra : IDalamudPlugin
[
"Glamourer", "MareSynchronos", "CustomizePlus", "SimpleHeels", "VfxEditor", "heliosphere-plugin", "Ktisis", "Brio", "DynamicBridge",
];
var plugins = _services.GetService<DalamudPluginInterface>().InstalledPlugins
var plugins = _services.GetService<IDalamudPluginInterface>().InstalledPlugins
.GroupBy(p => p.InternalName)
.ToDictionary(g => g.Key, g =>
{

View file

@ -37,6 +37,7 @@
<PropertyGroup>
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
<DalamudLibPath>H:\Projects\FFPlugins\Dalamud\bin\Release\</DalamudLibPath>
</PropertyGroup>
<ItemGroup>

View file

@ -8,7 +8,7 @@
"RepoUrl": "https://github.com/xivdev/Penumbra",
"ApplicableVersion": "any",
"Tags": [ "modding" ],
"DalamudApiLevel": 9,
"DalamudApiLevel": 10,
"LoadPriority": 69420,
"LoadState": 2,
"LoadSync": true,

View file

@ -10,9 +10,9 @@ public class DalamudConfigService : IService
try
{
var serviceType =
typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "Service`1" && t.IsGenericType);
var configType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudConfiguration");
var interfaceType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudInterface");
typeof(IDalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "Service`1" && t.IsGenericType);
var configType = typeof(IDalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudConfiguration");
var interfaceType = typeof(IDalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudInterface");
if (serviceType == null || configType == null || interfaceType == null)
return;

View file

@ -5,7 +5,7 @@ using Penumbra.Mods;
namespace Penumbra.Services;
public class FilenameService(DalamudPluginInterface pi) : IService
public class FilenameService(IDalamudPluginInterface pi) : IService
{
public readonly string ConfigDirectory = pi.ConfigDirectory.FullName;
public readonly string CollectionDirectory = Path.Combine(pi.ConfigDirectory.FullName, "collections");

View file

@ -9,8 +9,8 @@ using OtterGui.Services;
namespace Penumbra.Services;
public class MessageService(Logger log, UiBuilder uiBuilder, IChatGui chat, INotificationManager notificationManager)
: OtterGui.Classes.MessageService(log, uiBuilder, chat, notificationManager), IService
public class MessageService(Logger log, IUiBuilder builder, IChatGui chat, INotificationManager notificationManager)
: OtterGui.Classes.MessageService(log, builder, chat, notificationManager), IService
{
public void LinkItem(Item item)
{

View file

@ -19,7 +19,7 @@ namespace Penumbra.Services;
public static class StaticServiceManager
{
public static ServiceManager CreateProvider(Penumbra penumbra, DalamudPluginInterface pi, Logger log)
public static ServiceManager CreateProvider(Penumbra penumbra, IDalamudPluginInterface pi, Logger log)
{
var services = new ServiceManager(log)
.AddDalamudServices(pi)
@ -40,7 +40,7 @@ public static class StaticServiceManager
return services;
}
private static ServiceManager AddDalamudServices(this ServiceManager services, DalamudPluginInterface pi)
private static ServiceManager AddDalamudServices(this ServiceManager services, IDalamudPluginInterface pi)
=> services.AddExistingService(pi)
.AddExistingService(pi.UiBuilder)
.AddDalamudService<ICommandManager>(pi)

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin;
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using OtterGui.Classes;
@ -27,11 +27,11 @@ public class ValidityChecker : IService
get
{
var framework = Framework.Instance();
return framework == null ? string.Empty : framework->GameVersion[0];
return framework == null ? string.Empty : framework->GameVersionString;
}
}
public ValidityChecker(DalamudPluginInterface pi)
public ValidityChecker(IDalamudPluginInterface pi)
{
DevPenumbraExists = CheckDevPluginPenumbra(pi);
IsNotInstalledPenumbra = CheckIsNotInstalled(pi);
@ -50,7 +50,7 @@ public class ValidityChecker : IService
}
// Because remnants of penumbra in devPlugins cause issues, we check for them to warn users to remove them.
private static bool CheckDevPluginPenumbra(DalamudPluginInterface pi)
private static bool CheckDevPluginPenumbra(IDalamudPluginInterface pi)
{
#if !DEBUG
var path = Path.Combine(pi.DalamudAssetDirectory.Parent?.FullName ?? "INVALIDPATH", "devPlugins", "Penumbra");
@ -71,7 +71,7 @@ public class ValidityChecker : IService
}
// Check if the loaded version of Penumbra itself is in devPlugins.
private static bool CheckIsNotInstalled(DalamudPluginInterface pi)
private static bool CheckIsNotInstalled(IDalamudPluginInterface pi)
{
#if !DEBUG
var checkedDirectory = pi.AssemblyLocation.Directory?.Parent?.Parent?.Name;
@ -86,7 +86,7 @@ public class ValidityChecker : IService
}
// Check if the loaded version of Penumbra is installed from a valid source repo.
private static bool CheckSourceRepo(DalamudPluginInterface pi)
private static bool CheckSourceRepo(IDalamudPluginInterface pi)
{
#if !DEBUG
return pi.SourceRepository?.Trim().ToLowerInvariant() switch

View file

@ -1,5 +1,5 @@
using Dalamud.Interface;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Plugin.Services;
using ImGuiNET;
using OtterGui;

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using ImGuiNET;
using OtterGui;
using OtterGui.Classes;

View file

@ -1,5 +1,5 @@
using Dalamud.Interface;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Interface.ImGuiNotification;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using ImGuiNET;
using Newtonsoft.Json.Linq;

Some files were not shown because too many files have changed in this diff Show more