mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Some updates.
This commit is contained in:
parent
c2e74ed382
commit
221b18751d
121 changed files with 338 additions and 328 deletions
2
OtterGui
2
OtterGui
|
|
@ -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
|
||||||
|
|
@ -13,7 +13,7 @@ public class RedrawApi(RedrawService redrawService) : IPenumbraApiRedraw, IApiSe
|
||||||
public void RedrawObject(string name, RedrawType setting)
|
public void RedrawObject(string name, RedrawType setting)
|
||||||
=> redrawService.RedrawObject(name, setting);
|
=> redrawService.RedrawObject(name, setting);
|
||||||
|
|
||||||
public void RedrawObject(GameObject? gameObject, RedrawType setting)
|
public void RedrawObject(IGameObject? gameObject, RedrawType setting)
|
||||||
=> redrawService.RedrawObject(gameObject, setting);
|
=> redrawService.RedrawObject(gameObject, setting);
|
||||||
|
|
||||||
public void RedrawAll(RedrawType setting)
|
public void RedrawAll(RedrawType setting)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ public class ResourceTreeApi(ResourceTreeFactory resourceTreeFactory, ObjectMana
|
||||||
{
|
{
|
||||||
public Dictionary<string, HashSet<string>>?[] GetGameObjectResourcePaths(params ushort[] gameObjects)
|
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 resourceTrees = resourceTreeFactory.FromCharacters(characters, 0);
|
||||||
var pathDictionaries = ResourceTreeApiHelper.GetResourcePathDictionaries(resourceTrees);
|
var pathDictionaries = ResourceTreeApiHelper.GetResourcePathDictionaries(resourceTrees);
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ public class ResourceTreeApi(ResourceTreeFactory resourceTreeFactory, ObjectMana
|
||||||
public GameResourceDict?[] GetGameObjectResourcesOfType(ResourceType type, bool withUiData,
|
public GameResourceDict?[] GetGameObjectResourcesOfType(ResourceType type, bool withUiData,
|
||||||
params ushort[] gameObjects)
|
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 resourceTrees = resourceTreeFactory.FromCharacters(characters, withUiData ? ResourceTreeFactory.Flags.WithUiData : 0);
|
||||||
var resDictionaries = ResourceTreeApiHelper.GetResourcesOfType(resourceTrees, type);
|
var resDictionaries = ResourceTreeApiHelper.GetResourcesOfType(resourceTrees, type);
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ public class ResourceTreeApi(ResourceTreeFactory resourceTreeFactory, ObjectMana
|
||||||
|
|
||||||
public JObject?[] GetGameObjectResourceTrees(bool withUiData, params ushort[] gameObjects)
|
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 resourceTrees = resourceTreeFactory.FromCharacters(characters, withUiData ? ResourceTreeFactory.Flags.WithUiData : 0);
|
||||||
var resDictionary = ResourceTreeApiHelper.EncapsulateResourceTrees(resourceTrees);
|
var resDictionary = ResourceTreeApiHelper.EncapsulateResourceTrees(resourceTrees);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ public sealed class IpcProviders : IDisposable, IApiService
|
||||||
private readonly EventProvider _disposedProvider;
|
private readonly EventProvider _disposedProvider;
|
||||||
private readonly EventProvider _initializedProvider;
|
private readonly EventProvider _initializedProvider;
|
||||||
|
|
||||||
public IpcProviders(DalamudPluginInterface pi, IPenumbraApi api)
|
public IpcProviders(IDalamudPluginInterface pi, IPenumbraApi api)
|
||||||
{
|
{
|
||||||
_disposedProvider = IpcSubscribers.Disposed.Provider(pi);
|
_disposedProvider = IpcSubscribers.Disposed.Provider(pi);
|
||||||
_initializedProvider = IpcSubscribers.Initialized.Provider(pi);
|
_initializedProvider = IpcSubscribers.Initialized.Provider(pi);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ using ImGuiClip = OtterGui.ImGuiClip;
|
||||||
|
|
||||||
namespace Penumbra.Api.IpcTester;
|
namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class CollectionsIpcTester(DalamudPluginInterface pi) : IUiService
|
public class CollectionsIpcTester(IDalamudPluginInterface pi) : IUiService
|
||||||
{
|
{
|
||||||
private int _objectIdx;
|
private int _objectIdx;
|
||||||
private string _collectionIdString = string.Empty;
|
private string _collectionIdString = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using Penumbra.Api.IpcSubscribers;
|
||||||
|
|
||||||
namespace Penumbra.Api.IpcTester;
|
namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class EditingIpcTester(DalamudPluginInterface pi) : IUiService
|
public class EditingIpcTester(IDalamudPluginInterface pi) : IUiService
|
||||||
{
|
{
|
||||||
private string _inputPath = string.Empty;
|
private string _inputPath = string.Empty;
|
||||||
private string _inputPath2 = string.Empty;
|
private string _inputPath2 = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class GameStateIpcTester : IUiService, IDisposable
|
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, nint, nint> CharacterBaseCreating;
|
||||||
public readonly EventSubscriber<nint, Guid, nint> CharacterBaseCreated;
|
public readonly EventSubscriber<nint, Guid, nint> CharacterBaseCreated;
|
||||||
public readonly EventSubscriber<nint, string, string> GameObjectResourcePathResolved;
|
public readonly EventSubscriber<nint, string, string> GameObjectResourcePathResolved;
|
||||||
|
|
@ -30,7 +30,7 @@ public class GameStateIpcTester : IUiService, IDisposable
|
||||||
private int _currentCutsceneParent;
|
private int _currentCutsceneParent;
|
||||||
private PenumbraApiEc _cutsceneError = PenumbraApiEc.Success;
|
private PenumbraApiEc _cutsceneError = PenumbraApiEc.Success;
|
||||||
|
|
||||||
public GameStateIpcTester(DalamudPluginInterface pi)
|
public GameStateIpcTester(IDalamudPluginInterface pi)
|
||||||
{
|
{
|
||||||
_pi = pi;
|
_pi = pi;
|
||||||
CharacterBaseCreating = IpcSubscribers.CreatingCharacterBase.Subscriber(pi, UpdateLastCreated);
|
CharacterBaseCreating = IpcSubscribers.CreatingCharacterBase.Subscriber(pi, UpdateLastCreated);
|
||||||
|
|
@ -134,7 +134,6 @@ public class GameStateIpcTester : IUiService, IDisposable
|
||||||
private static unsafe string GetObjectName(nint gameObject)
|
private static unsafe string GetObjectName(nint gameObject)
|
||||||
{
|
{
|
||||||
var obj = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)gameObject;
|
var obj = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)gameObject;
|
||||||
var name = obj != null ? obj->Name : null;
|
return obj != null && obj->Name[0] != 0 ? new ByteString(obj->Name).ToString() : "Unknown";
|
||||||
return name != null && *name != 0 ? new ByteString(name).ToString() : "Unknown";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ using Penumbra.Api.IpcSubscribers;
|
||||||
|
|
||||||
namespace Penumbra.Api.IpcTester;
|
namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class MetaIpcTester(DalamudPluginInterface pi) : IUiService
|
public class MetaIpcTester(IDalamudPluginInterface pi) : IUiService
|
||||||
{
|
{
|
||||||
private int _gameObjectIndex;
|
private int _gameObjectIndex;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class ModSettingsIpcTester : IUiService, IDisposable
|
public class ModSettingsIpcTester : IUiService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly IDalamudPluginInterface _pi;
|
||||||
public readonly EventSubscriber<ModSettingChange, Guid, string, bool> SettingChanged;
|
public readonly EventSubscriber<ModSettingChange, Guid, string, bool> SettingChanged;
|
||||||
|
|
||||||
private PenumbraApiEc _lastSettingsError = PenumbraApiEc.Success;
|
private PenumbraApiEc _lastSettingsError = PenumbraApiEc.Success;
|
||||||
|
|
@ -33,7 +33,7 @@ public class ModSettingsIpcTester : IUiService, IDisposable
|
||||||
private IReadOnlyDictionary<string, (string[], GroupType)>? _availableSettings;
|
private IReadOnlyDictionary<string, (string[], GroupType)>? _availableSettings;
|
||||||
private Dictionary<string, List<string>>? _currentSettings;
|
private Dictionary<string, List<string>>? _currentSettings;
|
||||||
|
|
||||||
public ModSettingsIpcTester(DalamudPluginInterface pi)
|
public ModSettingsIpcTester(IDalamudPluginInterface pi)
|
||||||
{
|
{
|
||||||
_pi = pi;
|
_pi = pi;
|
||||||
SettingChanged = ModSettingChanged.Subscriber(pi, UpdateLastModSetting);
|
SettingChanged = ModSettingChanged.Subscriber(pi, UpdateLastModSetting);
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class ModsIpcTester : IUiService, IDisposable
|
public class ModsIpcTester : IUiService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly IDalamudPluginInterface _pi;
|
||||||
|
|
||||||
private string _modDirectory = string.Empty;
|
private string _modDirectory = string.Empty;
|
||||||
private string _modName = string.Empty;
|
private string _modName = string.Empty;
|
||||||
|
|
@ -38,7 +38,7 @@ public class ModsIpcTester : IUiService, IDisposable
|
||||||
private string _lastMovedModFrom = string.Empty;
|
private string _lastMovedModFrom = string.Empty;
|
||||||
private string _lastMovedModTo = string.Empty;
|
private string _lastMovedModTo = string.Empty;
|
||||||
|
|
||||||
public ModsIpcTester(DalamudPluginInterface pi)
|
public ModsIpcTester(IDalamudPluginInterface pi)
|
||||||
{
|
{
|
||||||
_pi = pi;
|
_pi = pi;
|
||||||
DeleteSubscriber = ModDeleted.Subscriber(pi, s =>
|
DeleteSubscriber = ModDeleted.Subscriber(pi, s =>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class PluginStateIpcTester : IUiService, IDisposable
|
public class PluginStateIpcTester : IUiService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly IDalamudPluginInterface _pi;
|
||||||
public readonly EventSubscriber<string, bool> ModDirectoryChanged;
|
public readonly EventSubscriber<string, bool> ModDirectoryChanged;
|
||||||
public readonly EventSubscriber Initialized;
|
public readonly EventSubscriber Initialized;
|
||||||
public readonly EventSubscriber Disposed;
|
public readonly EventSubscriber Disposed;
|
||||||
|
|
@ -29,7 +29,7 @@ public class PluginStateIpcTester : IUiService, IDisposable
|
||||||
private DateTimeOffset _lastEnabledChange = DateTimeOffset.UnixEpoch;
|
private DateTimeOffset _lastEnabledChange = DateTimeOffset.UnixEpoch;
|
||||||
private bool? _lastEnabledValue;
|
private bool? _lastEnabledValue;
|
||||||
|
|
||||||
public PluginStateIpcTester(DalamudPluginInterface pi)
|
public PluginStateIpcTester(IDalamudPluginInterface pi)
|
||||||
{
|
{
|
||||||
_pi = pi;
|
_pi = pi;
|
||||||
ModDirectoryChanged = IpcSubscribers.ModDirectoryChanged.Subscriber(pi, UpdateModDirectoryChanged);
|
ModDirectoryChanged = IpcSubscribers.ModDirectoryChanged.Subscriber(pi, UpdateModDirectoryChanged);
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class RedrawingIpcTester : IUiService, IDisposable
|
public class RedrawingIpcTester : IUiService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly IDalamudPluginInterface _pi;
|
||||||
private readonly ObjectManager _objects;
|
private readonly ObjectManager _objects;
|
||||||
public readonly EventSubscriber<nint, int> Redrawn;
|
public readonly EventSubscriber<nint, int> Redrawn;
|
||||||
|
|
||||||
private int _redrawIndex;
|
private int _redrawIndex;
|
||||||
private string _lastRedrawnString = "None";
|
private string _lastRedrawnString = "None";
|
||||||
|
|
||||||
public RedrawingIpcTester(DalamudPluginInterface pi, ObjectManager objects)
|
public RedrawingIpcTester(IDalamudPluginInterface pi, ObjectManager objects)
|
||||||
{
|
{
|
||||||
_pi = pi;
|
_pi = pi;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Api.IpcTester;
|
namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class ResolveIpcTester(DalamudPluginInterface pi) : IUiService
|
public class ResolveIpcTester(IDalamudPluginInterface pi) : IUiService
|
||||||
{
|
{
|
||||||
private string _currentResolvePath = string.Empty;
|
private string _currentResolvePath = string.Empty;
|
||||||
private string _currentReversePath = string.Empty;
|
private string _currentReversePath = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Penumbra.Api.IpcTester;
|
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();
|
private readonly Stopwatch _stopwatch = new();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ using Penumbra.Services;
|
||||||
namespace Penumbra.Api.IpcTester;
|
namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class TemporaryIpcTester(
|
public class TemporaryIpcTester(
|
||||||
DalamudPluginInterface pi,
|
IDalamudPluginInterface pi,
|
||||||
ModManager modManager,
|
ModManager modManager,
|
||||||
CollectionManager collections,
|
CollectionManager collections,
|
||||||
TempModManager tempMods,
|
TempModManager tempMods,
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Penumbra.Api.IpcTester;
|
||||||
|
|
||||||
public class UiIpcTester : IUiService, IDisposable
|
public class UiIpcTester : IUiService, IDisposable
|
||||||
{
|
{
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly IDalamudPluginInterface _pi;
|
||||||
public readonly EventSubscriber<string, float, float> PreSettingsTabBar;
|
public readonly EventSubscriber<string, float, float> PreSettingsTabBar;
|
||||||
public readonly EventSubscriber<string> PreSettingsPanel;
|
public readonly EventSubscriber<string> PreSettingsPanel;
|
||||||
public readonly EventSubscriber<string> PostEnabled;
|
public readonly EventSubscriber<string> PostEnabled;
|
||||||
|
|
@ -28,7 +28,7 @@ public class UiIpcTester : IUiService, IDisposable
|
||||||
private string _modName = string.Empty;
|
private string _modName = string.Empty;
|
||||||
private PenumbraApiEc _ec = PenumbraApiEc.Success;
|
private PenumbraApiEc _ec = PenumbraApiEc.Success;
|
||||||
|
|
||||||
public UiIpcTester(DalamudPluginInterface pi)
|
public UiIpcTester(IDalamudPluginInterface pi)
|
||||||
{
|
{
|
||||||
_pi = pi;
|
_pi = pi;
|
||||||
PreSettingsTabBar = IpcSubscribers.PreSettingsTabBarDraw.Subscriber(pi, UpdateLastDrawnMod);
|
PreSettingsTabBar = IpcSubscribers.PreSettingsTabBarDraw.Subscriber(pi, UpdateLastDrawnMod);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
=> TryGetCollection(_actors.FromObject(gameObject, true, false, false), out collection);
|
||||||
|
|
||||||
public unsafe bool TryGetCollection(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection)
|
public unsafe bool TryGetCollection(FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* gameObject, out ModCollection? collection)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Game.ClientState.Objects.Enums;
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using Penumbra.GameData.Actors;
|
using Penumbra.GameData.Actors;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Configuration;
|
using Dalamud.Configuration;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
namespace Penumbra.Import.Models;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ public readonly struct BaseImage : IDisposable
|
||||||
{
|
{
|
||||||
null => 0,
|
null => 0,
|
||||||
ScratchImage s => s.Meta.MipLevels,
|
ScratchImage s => s.Meta.MipLevels,
|
||||||
TexFile t => t.Header.MipLevelsCount,
|
TexFile t => t.Header.MipCount,
|
||||||
_ => 1,
|
_ => 1,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@ public static class TexFileParser
|
||||||
w.Write(header.Width);
|
w.Write(header.Width);
|
||||||
w.Write(header.Height);
|
w.Write(header.Height);
|
||||||
w.Write(header.Depth);
|
w.Write(header.Depth);
|
||||||
w.Write(header.MipLevelsCount);
|
w.Write(header.MipCount);
|
||||||
w.Write((byte)0); // TODO Lumina Update
|
w.Write(header.MipUnknownFlag); // TODO Lumina Update
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
w.Write(header.LodOffset[0]);
|
w.Write(header.LodOffset[0]);
|
||||||
|
|
@ -96,11 +96,11 @@ public static class TexFileParser
|
||||||
var meta = scratch.Meta;
|
var meta = scratch.Meta;
|
||||||
var ret = new TexFile.TexHeader()
|
var ret = new TexFile.TexHeader()
|
||||||
{
|
{
|
||||||
Height = (ushort)meta.Height,
|
Height = (ushort)meta.Height,
|
||||||
Width = (ushort)meta.Width,
|
Width = (ushort)meta.Width,
|
||||||
Depth = (ushort)Math.Max(meta.Depth, 1),
|
Depth = (ushort)Math.Max(meta.Depth, 1),
|
||||||
MipLevelsCount = (byte)Math.Min(meta.MipLevels, 13),
|
MipCount = (byte)Math.Min(meta.MipLevels, 13),
|
||||||
Format = meta.Format.ToTexFormat(),
|
Format = meta.Format.ToTexFormat(),
|
||||||
Type = meta.Dimension switch
|
Type = meta.Dimension switch
|
||||||
{
|
{
|
||||||
_ when meta.IsCubeMap => TexFile.Attribute.TextureTypeCube,
|
_ when meta.IsCubeMap => TexFile.Attribute.TextureTypeCube,
|
||||||
|
|
@ -143,7 +143,7 @@ public static class TexFileParser
|
||||||
Height = header.Height,
|
Height = header.Height,
|
||||||
Width = header.Width,
|
Width = header.Width,
|
||||||
Depth = Math.Max(header.Depth, (ushort)1),
|
Depth = Math.Max(header.Depth, (ushort)1),
|
||||||
MipLevels = header.MipLevelsCount,
|
MipLevels = header.MipCount,
|
||||||
ArraySize = 1,
|
ArraySize = 1,
|
||||||
Format = header.Format.ToDXGI(),
|
Format = header.Format.ToDXGI(),
|
||||||
Dimension = header.Type.ToDimension(),
|
Dimension = header.Type.ToDimension(),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal;
|
using Dalamud.Interface.Textures.TextureWraps;
|
||||||
using OtterTex;
|
using OtterTex;
|
||||||
|
|
||||||
namespace Penumbra.Import.Textures;
|
namespace Penumbra.Import.Textures;
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ public static class TextureDrawer
|
||||||
ImGuiUtil.DrawTableColumn("Format");
|
ImGuiUtil.DrawTableColumn("Format");
|
||||||
ImGuiUtil.DrawTableColumn(t.Header.Format.ToString());
|
ImGuiUtil.DrawTableColumn(t.Header.Format.ToString());
|
||||||
ImGuiUtil.DrawTableColumn("Mip Levels");
|
ImGuiUtil.DrawTableColumn("Mip Levels");
|
||||||
ImGuiUtil.DrawTableColumn(t.Header.MipLevelsCount.ToString());
|
ImGuiUtil.DrawTableColumn(t.Header.MipCount.ToString());
|
||||||
ImGuiUtil.DrawTableColumn("Data Size");
|
ImGuiUtil.DrawTableColumn("Data Size");
|
||||||
ImGuiUtil.DrawTableColumn($"{Functions.HumanReadableSize(t.ImageData.Length)} ({t.ImageData.Length} Bytes)");
|
ImGuiUtil.DrawTableColumn($"{Functions.HumanReadableSize(t.ImageData.Length)} ({t.ImageData.Length} Bytes)");
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface.Textures;
|
||||||
using Dalamud.Interface.Internal;
|
using Dalamud.Interface.Textures.TextureWraps;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
|
|
@ -13,7 +13,7 @@ using Image = SixLabors.ImageSharp.Image;
|
||||||
|
|
||||||
namespace Penumbra.Import.Textures;
|
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
|
: SingleTaskQueue, IDisposable, IService
|
||||||
{
|
{
|
||||||
private readonly Logger _logger = logger;
|
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>
|
/// <summary> Load a texture wrap for a given image. </summary>
|
||||||
public IDalamudTextureWrap LoadTextureWrap(byte[] rgba, int width, int height)
|
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>
|
/// <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)
|
public (BaseImage, TextureType) Load(string path)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ public sealed unsafe class ApricotListenerSoundPlay : FastHook<ApricotListenerSo
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_crashHandler = crashHandler;
|
_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);
|
public delegate nint Delegate(nint a1, nint a2, nint a3, nint a4, nint a5, nint a6);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ public sealed unsafe class CharacterBaseLoadAnimation : FastHook<CharacterBaseLo
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_drawObjectState = drawObjectState;
|
_drawObjectState = drawObjectState;
|
||||||
_crashHandler = crashHandler;
|
_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);
|
public delegate void Delegate(DrawObject* drawBase);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class Dismount : FastHook<Dismount.Delegate>
|
||||||
{
|
{
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_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);
|
public delegate void Delegate(nint a1, nint a2);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public sealed unsafe class LoadAreaVfx : FastHook<LoadAreaVfx.Delegate>
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_crashHandler = crashHandler;
|
_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);
|
public delegate nint Delegate(uint vfxId, float* pos, GameObject* caster, float unk1, float unk2, byte unk3);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.CrashHandler.Buffers;
|
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)
|
public LoadCharacterSound(HookManager hooks, GameState state, CollectionResolver collectionResolver, CrashHandlerService crashHandler)
|
||||||
{
|
{
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_crashHandler = crashHandler;
|
_crashHandler = crashHandler;
|
||||||
Task = hooks.CreateHook<Delegate>("Load Character Sound",
|
Task = hooks.CreateHook<Delegate>("Load Character Sound", (nint)VfxContainer.MemberFunctionPointers.LoadCharacterSound, Detour, HookSettings.VfxIdentificationHooks);
|
||||||
(nint)FFXIVClientStructs.FFXIV.Client.Game.Character.Character.VfxContainer.MemberFunctionPointers.LoadCharacterSound, Detour,
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public delegate nint Delegate(nint container, int unk1, int unk2, nint unk3, ulong unk4, int unk5, int unk6, ulong unk7);
|
public delegate nint Delegate(nint container, int unk1, int unk2, nint unk3, ulong unk4, int unk5, int unk6, ulong unk7);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ public sealed unsafe class LoadCharacterVfx : FastHook<LoadCharacterVfx.Delegate
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_crashHandler = crashHandler;
|
_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);
|
public delegate nint Delegate(byte* vfxPath, VfxParams* vfxParams, byte unk1, byte unk2, float unk3, int unk4);
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ public sealed unsafe class LoadTimelineResources : FastHook<LoadTimelineResource
|
||||||
_conditions = conditions;
|
_conditions = conditions;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_crashHandler = crashHandler;
|
_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);
|
public delegate ulong Delegate(nint timeline);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ public sealed unsafe class PlayFootstep : FastHook<PlayFootstep.Delegate>
|
||||||
{
|
{
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_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);
|
public delegate void Delegate(GameObject* gameObject, int id, int unk);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public sealed unsafe class ScheduleClipUpdate : FastHook<ScheduleClipUpdate.Dele
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_crashHandler = crashHandler;
|
_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);
|
public delegate void Delegate(ClipScheduler* x);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.CrashHandler.Buffers;
|
using Penumbra.CrashHandler.Buffers;
|
||||||
|
|
@ -20,15 +20,15 @@ public sealed unsafe class SomeActionLoad : FastHook<SomeActionLoad.Delegate>
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_crashHandler = crashHandler;
|
_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)]
|
[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);
|
var last = _state.SetAnimationData(newData);
|
||||||
Penumbra.Log.Excessive($"[Some Action Load] Invoked on 0x{(nint)timelineManager:X}.");
|
Penumbra.Log.Excessive($"[Some Action Load] Invoked on 0x{(nint)timelineManager:X}.");
|
||||||
_crashHandler.LogAnimation(newData.AssociatedGameObject, newData.ModCollection, AnimationInvocationType.ActionLoad);
|
_crashHandler.LogAnimation(newData.AssociatedGameObject, newData.ModCollection, AnimationInvocationType.ActionLoad);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class SomeMountAnimation : FastHook<SomeMountAnimation.Dele
|
||||||
{
|
{
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_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);
|
public delegate void Delegate(DrawObject* drawObject, uint unk1, byte unk2, uint unk3);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public sealed unsafe class SomePapLoad : FastHook<SomePapLoad.Delegate>
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_objects = objects;
|
_objects = objects;
|
||||||
_crashHandler = crashHandler;
|
_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);
|
public delegate void Delegate(nint a1, int a2, nint a3, int a4);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class SomeParasolAnimation : FastHook<SomeParasolAnimation.
|
||||||
{
|
{
|
||||||
_state = state;
|
_state = state;
|
||||||
_collectionResolver = collectionResolver;
|
_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);
|
public delegate void Delegate(DrawObject* drawObject, int unk1);
|
||||||
|
|
|
||||||
8
Penumbra/Interop/Hooks/HookSettings.cs
Normal file
8
Penumbra/Interop/Hooks/HookSettings.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.Collections;
|
|
||||||
using Penumbra.Interop.PathResolving;
|
using Penumbra.Interop.PathResolving;
|
||||||
using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character;
|
using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character;
|
||||||
|
|
||||||
|
|
@ -15,7 +14,7 @@ public sealed unsafe class CalculateHeight : FastHook<CalculateHeight.Delegate>
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate ulong Delegate(Character* character);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public sealed unsafe class ChangeCustomize : FastHook<ChangeCustomize.Delegate>
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate bool Delegate(Human* human, CustomizeArray* data, byte skipEquipment);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public unsafe class EqdpAccessoryHook : FastHook<EqdpAccessoryHook.Delegate>, ID
|
||||||
public EqdpAccessoryHook(HookManager hooks, MetaState metaState)
|
public EqdpAccessoryHook(HookManager hooks, MetaState metaState)
|
||||||
{
|
{
|
||||||
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public unsafe class EqdpEquipHook : FastHook<EqdpEquipHook.Delegate>, IDisposabl
|
||||||
public EqdpEquipHook(HookManager hooks, MetaState metaState)
|
public EqdpEquipHook(HookManager hooks, MetaState metaState)
|
||||||
{
|
{
|
||||||
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public unsafe class EqpHook : FastHook<EqpHook.Delegate>, IDisposable
|
||||||
public EqpHook(HookManager hooks, MetaState metaState)
|
public EqpHook(HookManager hooks, MetaState metaState)
|
||||||
{
|
{
|
||||||
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ public class EstHook : FastHook<EstHook.Delegate>, IDisposable
|
||||||
public EstHook(HookManager hooks, MetaState metaState)
|
public EstHook(HookManager hooks, MetaState metaState)
|
||||||
{
|
{
|
||||||
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class GetEqpIndirect : FastHook<GetEqpIndirect.Delegate>
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate void Delegate(DrawObject* drawObject);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class GetEqpIndirect2 : FastHook<GetEqpIndirect2.Delegate>
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate void Delegate(DrawObject* drawObject);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ public unsafe class GmpHook : FastHook<GmpHook.Delegate>, IDisposable
|
||||||
public GmpHook(HookManager hooks, MetaState metaState)
|
public GmpHook(HookManager hooks, MetaState metaState)
|
||||||
{
|
{
|
||||||
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.Collections;
|
|
||||||
using Penumbra.Interop.PathResolving;
|
using Penumbra.Interop.PathResolving;
|
||||||
|
|
||||||
namespace Penumbra.Interop.Hooks.Meta;
|
namespace Penumbra.Interop.Hooks.Meta;
|
||||||
|
|
@ -14,7 +13,7 @@ public sealed unsafe class ModelLoadComplete : FastHook<ModelLoadComplete.Delega
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate void Delegate(DrawObject* drawObject);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public unsafe class RspBustHook : FastHook<RspBustHook.Delegate>, IDisposable
|
||||||
{
|
{
|
||||||
_metaState = metaState;
|
_metaState = metaState;
|
||||||
_metaFileManager = metaFileManager;
|
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public class RspHeightHook : FastHook<RspHeightHook.Delegate>, IDisposable
|
||||||
{
|
{
|
||||||
_metaState = metaState;
|
_metaState = metaState;
|
||||||
_metaFileManager = metaFileManager;
|
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class RspSetupCharacter : FastHook<RspSetupCharacter.Delega
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate void Delegate(DrawObject* drawObject, nint unk2, float unk3, nint unk4, byte unk5);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public class RspTailHook : FastHook<RspTailHook.Delegate>, IDisposable
|
||||||
{
|
{
|
||||||
_metaState = metaState;
|
_metaState = metaState;
|
||||||
_metaFileManager = metaFileManager;
|
_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;
|
_metaState.Config.ModsEnabled += Toggle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public sealed unsafe class SetupVisor : FastHook<SetupVisor.Delegate>
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate byte Delegate(DrawObject* drawObject, ushort modelId, byte visorState);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public sealed unsafe class UpdateModel : FastHook<UpdateModel.Delegate>
|
||||||
{
|
{
|
||||||
_collectionResolver = collectionResolver;
|
_collectionResolver = collectionResolver;
|
||||||
_metaState = metaState;
|
_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);
|
public delegate void Delegate(DrawObject* drawObject);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ public sealed unsafe class CopyCharacter : EventWrapperPtr<Character, Character,
|
||||||
private readonly Task<Hook<Delegate>> _task;
|
private readonly Task<Hook<Delegate>> _task;
|
||||||
|
|
||||||
public nint Address
|
public nint Address
|
||||||
=> (nint)CharacterSetup.MemberFunctionPointers.CopyFromCharacter;
|
=> (nint)CharacterSetupContainer.MemberFunctionPointers.CopyFromCharacter;
|
||||||
|
|
||||||
public void Enable()
|
public void Enable()
|
||||||
=> _task.Result.Enable();
|
=> _task.Result.Enable();
|
||||||
|
|
@ -34,9 +34,9 @@ public sealed unsafe class CopyCharacter : EventWrapperPtr<Character, Character,
|
||||||
public bool Finished
|
public bool Finished
|
||||||
=> _task.IsCompletedSuccessfully;
|
=> _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.
|
// TODO: update when CS updated.
|
||||||
var character = ((Character**)target)[1];
|
var character = ((Character**)target)[1];
|
||||||
|
|
|
||||||
|
|
@ -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)
|
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}.");
|
Penumbra.Log.Verbose($"[{Name}] Triggered with drawData: 0x{(nint)drawData:X}, {slot}, {weapon}, {d}, {e}, {f}, {g}.");
|
||||||
Invoke(drawData, gameObject, (CharacterWeapon*)(&weapon));
|
Invoke(drawData, gameObject, (CharacterWeapon*)(&weapon));
|
||||||
_task.Result.Original(drawData, slot, weapon, d, e, f, g);
|
_task.Result.Original(drawData, slot, weapon, d, e, f, g);
|
||||||
|
|
|
||||||
|
|
@ -44,18 +44,20 @@ public sealed unsafe class ResolvePathHooksBase : IDisposable
|
||||||
{
|
{
|
||||||
_parent = parent;
|
_parent = parent;
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
_resolveDecalPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveDecal)}", hooks, vTable[83], ResolveDecal);
|
_resolveSklbPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSklb)}", hooks, vTable[76], type, ResolveSklb, ResolveSklbHuman);
|
||||||
_resolveEidPathHook = Create<SingleResolveDelegate>( $"{name}.{nameof(ResolveEid)}", hooks, vTable[85], ResolveEid);
|
_resolveMdlPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveMdl)}", hooks, vTable[77], type, ResolveMdl, ResolveMdlHuman);
|
||||||
_resolveImcPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveImc)}", hooks, vTable[81], ResolveImc);
|
_resolveSkpPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSkp)}", hooks, vTable[78], type, ResolveSkp, ResolveSkpHuman);
|
||||||
_resolveMPapPathHook = Create<MPapResolveDelegate>( $"{name}.{nameof(ResolveMPap)}", hooks, vTable[79], ResolveMPap);
|
_resolvePhybPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolvePhyb)}", hooks, vTable[79], type, ResolvePhyb, ResolvePhybHuman);
|
||||||
_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);
|
_resolvePapPathHook = Create<NamedResolveDelegate>( $"{name}.{nameof(ResolvePap)}", hooks, vTable[84], type, ResolvePap, ResolvePapHuman);
|
||||||
_resolvePhybPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolvePhyb)}", hooks, vTable[75], type, ResolvePhyb, ResolvePhybHuman);
|
_resolveTmbPathHook = Create<TmbResolveDelegate>( $"{name}.{nameof(ResolveTmb)}", hooks, vTable[85], ResolveTmb);
|
||||||
_resolveSklbPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSklb)}", hooks, vTable[72], type, ResolveSklb, ResolveSklbHuman);
|
_resolveMPapPathHook = Create<MPapResolveDelegate>( $"{name}.{nameof(ResolveMPap)}", hooks, vTable[87], ResolveMPap);
|
||||||
_resolveSkpPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveSkp)}", hooks, vTable[74], type, ResolveSkp, ResolveSkpHuman);
|
_resolveImcPathHook = Create<PerSlotResolveDelegate>($"{name}.{nameof(ResolveImc)}", hooks, vTable[89], ResolveImc);
|
||||||
_resolveTmbPathHook = Create<TmbResolveDelegate>( $"{name}.{nameof(ResolveTmb)}", hooks, vTable[77], ResolveTmb);
|
_resolveMtrlPathHook = Create<NamedResolveDelegate>( $"{name}.{nameof(ResolveMtrl)}", hooks, vTable[90], ResolveMtrl);
|
||||||
_resolveVfxPathHook = Create<VfxResolveDelegate>( $"{name}.{nameof(ResolveVfx)}", hooks, vTable[84], type, ResolveVfx, ResolveVfxHuman);
|
_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
|
// @formatter:on
|
||||||
Enable();
|
Enable();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ public sealed unsafe class CollectionResolver(
|
||||||
var lobby = AgentLobby.Instance();
|
var lobby = AgentLobby.Instance();
|
||||||
if (lobby != null)
|
if (lobby != null)
|
||||||
{
|
{
|
||||||
var span = lobby->LobbyData.CharaSelectEntries.Span;
|
var span = lobby->LobbyData.CharaSelectEntries.AsSpan();
|
||||||
// The lobby uses the first 8 cutscene actors.
|
// The lobby uses the first 8 cutscene actors.
|
||||||
var idx = gameObject->ObjectIndex - ObjectIndex.CutsceneStart.Index;
|
var idx = gameObject->ObjectIndex - ObjectIndex.CutsceneStart.Index;
|
||||||
if (idx >= 0 && idx < span.Length && span[idx].Value != null)
|
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>
|
/// <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)
|
private bool Aesthetician(GameObject* gameObject, out ResolveData ret)
|
||||||
{
|
{
|
||||||
if (gameGui.GetAddonByName("ScreenLog") != IntPtr.Zero)
|
if (gameGui.GetAddonByName("ScreenLog") != nint.Zero)
|
||||||
{
|
{
|
||||||
ret = ResolveData.Invalid;
|
ret = ResolveData.Invalid;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
@ -19,7 +20,7 @@ public sealed class CutsceneService : IRequiredService, IDisposable
|
||||||
private readonly CharacterDestructor _characterDestructor;
|
private readonly CharacterDestructor _characterDestructor;
|
||||||
private readonly short[] _copiedCharacters = Enumerable.Repeat((short)-1, CutsceneSlots).ToArray();
|
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)
|
=> Enumerable.Range(CutsceneStartIdx, CutsceneSlots)
|
||||||
.Where(i => _objects[i].Valid)
|
.Where(i => _objects[i].Valid)
|
||||||
.Select(i => KeyValuePair.Create(i, this[i] ?? _objects.GetDalamudObject(i)!));
|
.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.
|
/// Does not check for valid input index.
|
||||||
/// Returns null if no connected actor is set or the actor does not exist anymore.
|
/// Returns null if no connected actor is set or the actor does not exist anymore.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dalamud.Game.ClientState.Objects.Types.GameObject? this[int idx]
|
private IGameObject? this[int idx]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ public unsafe class FileReadService : IDisposable, IRequiredService
|
||||||
byte? ret = null;
|
byte? ret = null;
|
||||||
_lastFileThreadResourceManager.Value = resourceManager;
|
_lastFileThreadResourceManager.Value = resourceManager;
|
||||||
ReadSqPack?.Invoke(fileDescriptor, ref priority, ref isSync, ref ret);
|
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);
|
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.
|
/// So we keep track of them per thread and use them.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private nint GetResourceManager()
|
private nint GetResourceManager()
|
||||||
=> !_lastFileThreadResourceManager.IsValueCreated || _lastFileThreadResourceManager.Value == IntPtr.Zero
|
=> !_lastFileThreadResourceManager.IsValueCreated || _lastFileThreadResourceManager.Value == nint.Zero
|
||||||
? (nint)_resourceManager.ResourceManager
|
? (nint)_resourceManager.ResourceManager
|
||||||
: _lastFileThreadResourceManager.Value;
|
: _lastFileThreadResourceManager.Value;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ public unsafe class ResourceManagerService : IRequiredService
|
||||||
ref var manager = ref *ResourceManager;
|
ref var manager = ref *ResourceManager;
|
||||||
var catIdx = (uint)cat >> 0x18;
|
var catIdx = (uint)cat >> 0x18;
|
||||||
cat = (ResourceCategory)(ushort)cat;
|
cat = (ResourceCategory)(ushort)cat;
|
||||||
ref var category = ref manager.ResourceGraph->ContainerArraySpan[(int)cat];
|
ref var category = ref manager.ResourceGraph->Containers[(int)cat];
|
||||||
var extMap = FindInMap(category.CategoryMapsSpan[(int)catIdx].Value, (uint)ext);
|
var extMap = FindInMap(category.CategoryMaps[(int)catIdx].Value, (uint)ext);
|
||||||
if (extMap == null)
|
if (extMap == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
|
@ -44,10 +44,10 @@ public unsafe class ResourceManagerService : IRequiredService
|
||||||
ref var manager = ref *ResourceManager;
|
ref var manager = ref *ResourceManager;
|
||||||
foreach (var resourceType in Enum.GetValues<ResourceCategory>().SkipLast(1))
|
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)
|
for (var i = 0; i < 20; ++i)
|
||||||
{
|
{
|
||||||
var map = graph.CategoryMapsSpan[i];
|
var map = graph.CategoryMaps[i];
|
||||||
if (map.Value != null)
|
if (map.Value != null)
|
||||||
action(resourceType, map, i);
|
action(resourceType, map, i);
|
||||||
}
|
}
|
||||||
|
|
@ -79,25 +79,10 @@ public unsafe class ResourceManagerService : IRequiredService
|
||||||
where TKey : unmanaged, IComparable<TKey>
|
where TKey : unmanaged, IComparable<TKey>
|
||||||
where TValue : unmanaged
|
where TValue : unmanaged
|
||||||
{
|
{
|
||||||
if (map == null || map->Count == 0)
|
if (map == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var node = map->Head->Parent;
|
return map->TryGetValuePointer(key, out var val) ? val : null;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate in tree-order through a map, applying action to each KeyValuePair.
|
// 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 TKey : unmanaged
|
||||||
where TValue : unmanaged
|
where TValue : unmanaged
|
||||||
{
|
{
|
||||||
if (map == null || map->Count == 0)
|
if (map == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (var node = map->SmallestValue; !node->IsNil; node = node->Next())
|
foreach (var (key, value) in *map)
|
||||||
action(node->KeyValuePair.Item1, node->KeyValuePair.Item2);
|
action(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ public unsafe class ResourceService : IDisposable, IRequiredService
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private delegate IntPtr ResourceHandlePrototype(ResourceHandle* handle);
|
private delegate nint ResourceHandlePrototype(ResourceHandle* handle);
|
||||||
|
|
||||||
#region IncRef
|
#region IncRef
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Dalamud.Hooking;
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
|
using FFXIVClientStructs.FFXIV.Client.LayoutEngine;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
|
@ -12,7 +13,7 @@ namespace Penumbra.Interop.ResourceLoading;
|
||||||
public unsafe class TexMdlService : IDisposable, IRequiredService
|
public unsafe class TexMdlService : IDisposable, IRequiredService
|
||||||
{
|
{
|
||||||
/// <summary> Custom ulong flag to signal our files as opposed to SE files. </summary>
|
/// <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>
|
/// <summary>
|
||||||
/// We need to keep a list of all CRC64 hash values of our replaced Mdl and Tex files,
|
/// 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)
|
public TexMdlService(IGameInteropProvider interop)
|
||||||
{
|
{
|
||||||
interop.InitializeFromAttributes(this);
|
interop.InitializeFromAttributes(this);
|
||||||
_checkFileStateHook.Enable();
|
//_checkFileStateHook.Enable();
|
||||||
_loadTexFileExternHook.Enable();
|
//_loadTexFileExternHook.Enable();
|
||||||
_loadMdlFileExternHook.Enable();
|
//_loadMdlFileExternHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Add CRC64 if the given file is a model or texture file and has an associated path. </summary>
|
/// <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()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_checkFileStateHook.Dispose();
|
//_checkFileStateHook.Dispose();
|
||||||
_loadTexFileExternHook.Dispose();
|
//_loadTexFileExternHook.Dispose();
|
||||||
_loadMdlFileExternHook.Dispose();
|
//_loadMdlFileExternHook.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly HashSet<ulong> _customFileCrc = new();
|
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))]
|
[Signature(Sigs.CheckFileState, DetourName = nameof(CheckFileStateDetour))]
|
||||||
private readonly Hook<CheckFileStatePrototype> _checkFileStateHook = null!;
|
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'.
|
/// 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.
|
/// We use it to check against our stored CRC64s and if it corresponds, we return the custom flag.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private IntPtr CheckFileStateDetour(IntPtr ptr, ulong crc64)
|
private nint CheckFileStateDetour(nint ptr, ulong crc64)
|
||||||
=> _customFileCrc.Contains(crc64) ? CustomFileFlag : _checkFileStateHook.Original(ptr, 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>
|
/// <summary> We use the local functions for our own files in the extern hook. </summary>
|
||||||
[Signature(Sigs.LoadTexFileLocal)]
|
[Signature(Sigs.LoadTexFileLocal)]
|
||||||
private readonly LoadTexFileLocalDelegate _loadTexFileLocal = null!;
|
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>
|
/// <summary> We use the local functions for our own files in the extern hook. </summary>
|
||||||
[Signature(Sigs.LoadMdlFileLocal)]
|
[Signature(Sigs.LoadMdlFileLocal)]
|
||||||
private readonly LoadMdlFileLocalPrototype _loadMdlFileLocal = null!;
|
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 delegate byte TexResourceHandleVf32Prototype(ResourceHandle* handle, nint unk1, byte unk2);
|
||||||
private readonly Hook<LoadTexFileExternPrototype> _loadTexFileExternHook = null!;
|
|
||||||
|
//[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>
|
/// <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)
|
//private byte LoadTexFileExternDetour(ResourceHandle* resourceHandle, int unk1, nint unk2, bool unk3, nint ptr)
|
||||||
=> ptr.Equals(CustomFileFlag)
|
// => ptr.Equals(CustomFileFlag)
|
||||||
? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3)
|
// ? _loadTexFileLocal.Invoke(resourceHandle, unk1, unk2, unk3)
|
||||||
: _loadTexFileExternHook.Original(resourceHandle, unk1, unk2, unk3, ptr);
|
// : _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))]
|
[Signature(Sigs.LoadMdlFileExtern, DetourName = nameof(LoadMdlFileExternDetour))]
|
||||||
private readonly Hook<LoadMdlFileExternPrototype> _loadMdlFileExternHook = null!;
|
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>
|
/// <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)
|
=> ptr.Equals(CustomFileFlag)
|
||||||
? _loadMdlFileLocal.Invoke(resourceHandle, unk1, unk2)
|
? _loadMdlFileLocal.Invoke(resourceHandle, unk1, unk2)
|
||||||
: _loadMdlFileExternHook.Original(resourceHandle, unk1, unk2, ptr);
|
: _loadMdlFileExternHook.Original(resourceHandle, unk1, unk2, ptr);
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ internal unsafe partial record ResolveContext(
|
||||||
if (resourceHandle == null)
|
if (resourceHandle == null)
|
||||||
throw new ArgumentNullException(nameof(resourceHandle));
|
throw new ArgumentNullException(nameof(resourceHandle));
|
||||||
|
|
||||||
var fileName = resourceHandle->FileName.AsSpan();
|
var fileName = (ReadOnlySpan<byte>) resourceHandle->FileName.AsSpan();
|
||||||
var additionalData = ByteString.Empty;
|
var additionalData = ByteString.Empty;
|
||||||
if (PathDataHandler.Split(fileName, out fileName, out var data))
|
if (PathDataHandler.Split(fileName, out fileName, out var data))
|
||||||
additionalData = ByteString.FromSpanUnsafe(data, false).Clone();
|
additionalData = ByteString.FromSpanUnsafe(data, false).Clone();
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public class ResourceTree
|
||||||
var equipment = modelType switch
|
var equipment = modelType switch
|
||||||
{
|
{
|
||||||
CharacterBase.ModelType.Human => new ReadOnlySpan<CharacterArmor>(&human->Head, 10),
|
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,
|
_ => ReadOnlySpan<CharacterArmor>.Empty,
|
||||||
};
|
};
|
||||||
ModelId = character->CharacterData.ModelCharaId;
|
ModelId = character->CharacterData.ModelCharaId;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ namespace Penumbra.Interop.ResourceTree;
|
||||||
internal static class ResourceTreeApiHelper
|
internal static class ResourceTreeApiHelper
|
||||||
{
|
{
|
||||||
public static Dictionary<ushort, Dictionary<string, HashSet<string>>> GetResourcePathDictionaries(
|
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);
|
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)
|
ResourceType type)
|
||||||
{
|
{
|
||||||
var resDictionaries = new Dictionary<ushort, GameResourceDict>(4);
|
var resDictionaries = new Dictionary<ushort, GameResourceDict>(4);
|
||||||
|
|
@ -74,7 +74,7 @@ internal static class ResourceTreeApiHelper
|
||||||
return resDictionaries;
|
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);
|
var resDictionary = new Dictionary<ushort, JObject>(4);
|
||||||
foreach (var (gameObject, resourceTree) in resourceTrees)
|
foreach (var (gameObject, resourceTree) in resourceTrees)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
@ -23,13 +24,13 @@ public class ResourceTreeFactory(
|
||||||
private TreeBuildCache CreateTreeBuildCache()
|
private TreeBuildCache CreateTreeBuildCache()
|
||||||
=> new(objects, gameData, actors);
|
=> new(objects, gameData, actors);
|
||||||
|
|
||||||
public IEnumerable<Dalamud.Game.ClientState.Objects.Types.Character> GetLocalPlayerRelatedCharacters()
|
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
|
||||||
{
|
{
|
||||||
var cache = CreateTreeBuildCache();
|
var cache = CreateTreeBuildCache();
|
||||||
return cache.GetLocalPlayerRelatedCharacters();
|
return cache.GetLocalPlayerRelatedCharacters();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<(Dalamud.Game.ClientState.Objects.Types.Character Character, ResourceTree ResourceTree)> FromObjectTable(
|
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromObjectTable(
|
||||||
Flags flags)
|
Flags flags)
|
||||||
{
|
{
|
||||||
var cache = CreateTreeBuildCache();
|
var cache = CreateTreeBuildCache();
|
||||||
|
|
@ -43,8 +44,8 @@ public class ResourceTreeFactory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<(Dalamud.Game.ClientState.Objects.Types.Character Character, ResourceTree ResourceTree)> FromCharacters(
|
public IEnumerable<(ICharacter Character, ResourceTree ResourceTree)> FromCharacters(
|
||||||
IEnumerable<Dalamud.Game.ClientState.Objects.Types.Character> characters, Flags flags)
|
IEnumerable<ICharacter> characters, Flags flags)
|
||||||
{
|
{
|
||||||
var cache = CreateTreeBuildCache();
|
var cache = CreateTreeBuildCache();
|
||||||
foreach (var character in characters)
|
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);
|
=> 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())
|
if (!character.IsValid())
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -74,7 +75,7 @@ public class ResourceTreeFactory(
|
||||||
|
|
||||||
var localPlayerRelated = cache.IsLocalPlayerRelated(character);
|
var localPlayerRelated = cache.IsLocalPlayerRelated(character);
|
||||||
var (name, anonymizedName, related) = GetCharacterName(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,
|
var tree = new ResourceTree(name, anonymizedName, character.ObjectIndex, (nint)gameObjStruct, (nint)drawObjStruct, localPlayerRelated, related,
|
||||||
networked, collectionResolveData.ModCollection.Name, collectionResolveData.ModCollection.AnonymizedName);
|
networked, collectionResolveData.ModCollection.Name, collectionResolveData.ModCollection.AnonymizedName);
|
||||||
var globalContext = new GlobalResolveContext(identifier, collectionResolveData.ModCollection,
|
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 identifier = actors.FromObject((GameObject*)character.Address, out var owner, true, false, false);
|
||||||
var identifierStr = identifier.ToString();
|
var identifierStr = identifier.ToString();
|
||||||
return (identifierStr, identifier.Incognito(identifierStr), IsPlayerRelated(identifier, owner));
|
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)
|
if (character == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -175,7 +176,7 @@ public class ResourceTreeFactory(
|
||||||
=> identifier.Type switch
|
=> identifier.Type switch
|
||||||
{
|
{
|
||||||
IdentifierType.Player => true,
|
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,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager data
|
||||||
{
|
{
|
||||||
private readonly Dictionary<FullPath, ShpkFile?> _shaderPackages = [];
|
private readonly Dictionary<FullPath, ShpkFile?> _shaderPackages = [];
|
||||||
|
|
||||||
public unsafe bool IsLocalPlayerRelated(Character character)
|
public unsafe bool IsLocalPlayerRelated(ICharacter character)
|
||||||
{
|
{
|
||||||
var player = objects.GetDalamudObject(0);
|
var player = objects.GetDalamudObject(0);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
|
|
@ -25,36 +25,36 @@ internal readonly struct TreeBuildCache(ObjectManager objects, IDataManager data
|
||||||
return actualIndex switch
|
return actualIndex switch
|
||||||
{
|
{
|
||||||
< 2 => true,
|
< 2 => true,
|
||||||
< (int)ScreenActor.CutsceneStart => gameObject->OwnerID == player.ObjectId,
|
< (int)ScreenActor.CutsceneStart => gameObject->OwnerId == player.EntityId,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Character> GetCharacters()
|
public IEnumerable<ICharacter> GetCharacters()
|
||||||
=> objects.Objects.OfType<Character>();
|
=> objects.Objects.OfType<ICharacter>();
|
||||||
|
|
||||||
public IEnumerable<Character> GetLocalPlayerRelatedCharacters()
|
public IEnumerable<ICharacter> GetLocalPlayerRelatedCharacters()
|
||||||
{
|
{
|
||||||
var player = objects.GetDalamudObject(0);
|
var player = objects.GetDalamudObject(0);
|
||||||
if (player == null)
|
if (player == null)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
yield return (Character)player;
|
yield return (ICharacter)player;
|
||||||
|
|
||||||
var minion = objects.GetDalamudObject(1);
|
var minion = objects.GetDalamudObject(1);
|
||||||
if (minion != null)
|
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)
|
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;
|
yield return owned;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = ObjectIndex.CutsceneStart.Index; i < ObjectIndex.CharacterScreen.Index; ++i)
|
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)
|
if (character == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public unsafe class FontReloader : IService
|
||||||
if (framework == null)
|
if (framework == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var uiModule = framework->GetUiModule();
|
var uiModule = framework->GetUIModule();
|
||||||
if (uiModule == null)
|
if (uiModule == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ public unsafe class FontReloader : IService
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_atkModule = &atkModule->AtkModule;
|
_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];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Game.Housing;
|
using FFXIVClientStructs.FFXIV.Client.Game;
|
||||||
using FFXIVClientStructs.Interop;
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.Api;
|
using Penumbra.Api;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
|
|
@ -37,11 +37,11 @@ public unsafe partial class RedrawService : IService
|
||||||
=> _clientState.IsGPosing;
|
=> _clientState.IsGPosing;
|
||||||
|
|
||||||
// VFuncs that disable and enable draw, used only for GPose actors.
|
// VFuncs that disable and enable draw, used only for GPose actors.
|
||||||
private static void DisableDraw(GameObject actor)
|
private static void DisableDraw(IGameObject actor)
|
||||||
=> ((delegate* unmanaged< IntPtr, void >**)actor.Address)[0][Offsets.DisableDrawVfunc](actor.Address);
|
=> ((delegate* unmanaged<nint, void >**)actor.Address)[0][Offsets.DisableDrawVfunc](actor.Address);
|
||||||
|
|
||||||
private static void EnableDraw(GameObject actor)
|
private static void EnableDraw(IGameObject actor)
|
||||||
=> ((delegate* unmanaged< IntPtr, void >**)actor.Address)[0][Offsets.EnableDrawVfunc](actor.Address);
|
=> ((delegate* unmanaged<nint, void >**)actor.Address)[0][Offsets.EnableDrawVfunc](actor.Address);
|
||||||
|
|
||||||
// Check whether we currently are in GPose.
|
// Check whether we currently are in GPose.
|
||||||
// Also clear the name list.
|
// 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.
|
// 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,
|
// 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.
|
// 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);
|
obj = _objects.GetDalamudObject(idx);
|
||||||
if (!InGPose || obj == null || IsGPoseActor(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.
|
// 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)
|
if (actor == null)
|
||||||
{
|
{
|
||||||
|
|
@ -155,13 +155,13 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
_communicator.ModFileChanged.Unsubscribe(OnModFileChanged);
|
_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);
|
=> (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;
|
=> ((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))
|
if (BadRedrawIndices(actor, out var tableIndex))
|
||||||
return;
|
return;
|
||||||
|
|
@ -172,7 +172,7 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
if (gPose)
|
if (gPose)
|
||||||
DisableDraw(actor!);
|
DisableDraw(actor!);
|
||||||
|
|
||||||
if (actor is PlayerCharacter
|
if (actor is IPlayerCharacter
|
||||||
&& _objects.GetDalamudObject(tableIndex + 1) is { ObjectKind: ObjectKind.MountType or ObjectKind.Ornament } mountOrOrnament)
|
&& _objects.GetDalamudObject(tableIndex + 1) is { ObjectKind: ObjectKind.MountType or ObjectKind.Ornament } mountOrOrnament)
|
||||||
{
|
{
|
||||||
*ActorDrawState(mountOrOrnament) |= DrawState.Invisibility;
|
*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))
|
if (BadRedrawIndices(actor, out var tableIndex))
|
||||||
return;
|
return;
|
||||||
|
|
@ -192,7 +192,7 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
if (gPose)
|
if (gPose)
|
||||||
EnableDraw(actor!);
|
EnableDraw(actor!);
|
||||||
|
|
||||||
if (actor is PlayerCharacter
|
if (actor is IPlayerCharacter
|
||||||
&& _objects.GetDalamudObject(tableIndex + 1) is { ObjectKind: ObjectKind.MountType or ObjectKind.Ornament } mountOrOrnament)
|
&& _objects.GetDalamudObject(tableIndex + 1) is { ObjectKind: ObjectKind.MountType or ObjectKind.Ornament } mountOrOrnament)
|
||||||
{
|
{
|
||||||
*ActorDrawState(mountOrOrnament) &= ~DrawState.Invisibility;
|
*ActorDrawState(mountOrOrnament) &= ~DrawState.Invisibility;
|
||||||
|
|
@ -203,7 +203,7 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
GameObjectRedrawn?.Invoke(actor!.Address, tableIndex);
|
GameObjectRedrawn?.Invoke(actor!.Address, tableIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReloadActor(GameObject? actor)
|
private void ReloadActor(IGameObject? actor)
|
||||||
{
|
{
|
||||||
if (BadRedrawIndices(actor, out var tableIndex))
|
if (BadRedrawIndices(actor, out var tableIndex))
|
||||||
return;
|
return;
|
||||||
|
|
@ -214,7 +214,7 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
_queue.Add(~tableIndex);
|
_queue.Add(~tableIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ReloadActorAfterGPose(GameObject? actor)
|
private void ReloadActorAfterGPose(IGameObject? actor)
|
||||||
{
|
{
|
||||||
if (_objects[GPosePlayerIdx].Valid)
|
if (_objects[GPosePlayerIdx].Valid)
|
||||||
{
|
{
|
||||||
|
|
@ -284,21 +284,21 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
_queue.RemoveRange(numKept, _queue.Count - numKept);
|
_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;
|
var gameObj = (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)obj.Address;
|
||||||
if (gameObj == null || !gameObj->IsCharacter())
|
if (gameObj == null || !gameObj->IsCharacter())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
var chara = (Character*)gameObj;
|
var chara = (Character*)gameObj;
|
||||||
var ptr = (byte*)&chara->ActionTimelineManager + 0xF0;
|
var ptr = (byte*)&chara->Timeline + 0xF0;
|
||||||
return *(uint*)ptr;
|
return *(uint*)ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool DelayRedraw(GameObject obj)
|
private static bool DelayRedraw(IGameObject obj)
|
||||||
=> ((Character*)obj.Address)->Mode switch
|
=> ((Character*)obj.Address)->Mode switch
|
||||||
{
|
{
|
||||||
(Character.CharacterModes)6 => // fishing
|
(CharacterModes)6 => // fishing
|
||||||
GetCurrentAnimationId(obj) switch
|
GetCurrentAnimationId(obj) switch
|
||||||
{
|
{
|
||||||
278 => true, // line out.
|
278 => true, // line out.
|
||||||
|
|
@ -345,7 +345,7 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
HandleTarget();
|
HandleTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RedrawObject(GameObject? actor, RedrawType settings)
|
public void RedrawObject(IGameObject? actor, RedrawType settings)
|
||||||
{
|
{
|
||||||
switch (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);
|
var gPosePlayer = _objects.GetDalamudObject(GPosePlayerIdx);
|
||||||
return gPosePlayer ?? _objects.GetDalamudObject(0);
|
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
|
(actor, var ret) = lowerName switch
|
||||||
{
|
{
|
||||||
|
|
@ -419,15 +419,14 @@ public sealed unsafe partial class RedrawService : IDisposable
|
||||||
if (housingManager == null)
|
if (housingManager == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var currentTerritory = housingManager->CurrentTerritory;
|
var currentTerritory = (OutdoorTerritory*) housingManager->CurrentTerritory;
|
||||||
if (currentTerritory == null)
|
if (currentTerritory == null || currentTerritory->GetTerritoryType() is not HousingTerritoryType.Outdoor)
|
||||||
return;
|
|
||||||
if (!housingManager->IsInside())
|
|
||||||
return;
|
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)
|
if (gameObject == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ namespace Penumbra.Interop.Structs;
|
||||||
public unsafe struct ClipScheduler
|
public unsafe struct ClipScheduler
|
||||||
{
|
{
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public IntPtr* VTable;
|
public nint* VTable;
|
||||||
|
|
||||||
[FieldOffset(0x38)]
|
[FieldOffset(0x38)]
|
||||||
public IntPtr SchedulerTimeline;
|
public nint SchedulerTimeline;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,12 @@ public unsafe struct ResourceHandle
|
||||||
[FieldOffset(0xB8)]
|
[FieldOffset(0xB8)]
|
||||||
public uint DataLength;
|
public uint DataLength;
|
||||||
|
|
||||||
public (IntPtr Data, int Length) GetData()
|
public (nint Data, int Length) GetData()
|
||||||
=> Data != null
|
=> Data != null
|
||||||
? ((IntPtr)Data->DataPtr, (int)Data->DataLength)
|
? ((nint)Data->DataPtr, (int)Data->DataLength)
|
||||||
: (IntPtr.Zero, 0);
|
: (nint.Zero, 0);
|
||||||
|
|
||||||
public bool SetData(IntPtr data, int length)
|
public bool SetData(nint data, int length)
|
||||||
{
|
{
|
||||||
if (Data == null)
|
if (Data == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ public unsafe class MetaBaseFile(MetaFileManager manager, IFileAllocator alloc,
|
||||||
public int Length { get; private set; }
|
public int Length { get; private set; }
|
||||||
public CharacterUtility.InternalIndex Index { get; } = CharacterUtility.ReverseIndices[(int)idx];
|
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);
|
=> Manager.CharacterUtility.DefaultResource(Index);
|
||||||
|
|
||||||
/// <summary> Reset to default values. </summary>
|
/// <summary> Reset to default values. </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using Penumbra.Api.Enums;
|
using Penumbra.Api.Enums;
|
||||||
using Penumbra.GameData;
|
|
||||||
using Penumbra.GameData.Data;
|
using Penumbra.GameData.Data;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods.Settings;
|
using Penumbra.Mods.Settings;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
using Penumbra.Import;
|
using Penumbra.Import;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
using OtterGui.Filesystem;
|
using OtterGui.Filesystem;
|
||||||
using OtterGui.Services;
|
using OtterGui.Services;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ public class Penumbra : IDalamudPlugin
|
||||||
|
|
||||||
private readonly ServiceManager _services;
|
private readonly ServiceManager _services;
|
||||||
|
|
||||||
public Penumbra(DalamudPluginInterface pluginInterface)
|
public Penumbra(IDalamudPluginInterface pluginInterface)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -182,7 +182,7 @@ public class Penumbra : IDalamudPlugin
|
||||||
[
|
[
|
||||||
"Glamourer", "MareSynchronos", "CustomizePlus", "SimpleHeels", "VfxEditor", "heliosphere-plugin", "Ktisis", "Brio", "DynamicBridge",
|
"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)
|
.GroupBy(p => p.InternalName)
|
||||||
.ToDictionary(g => g.Key, g =>
|
.ToDictionary(g => g.Key, g =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
|
<DalamudLibPath>$(AppData)\XIVLauncher\addon\Hooks\dev\</DalamudLibPath>
|
||||||
|
<DalamudLibPath>H:\Projects\FFPlugins\Dalamud\bin\Release\</DalamudLibPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"RepoUrl": "https://github.com/xivdev/Penumbra",
|
"RepoUrl": "https://github.com/xivdev/Penumbra",
|
||||||
"ApplicableVersion": "any",
|
"ApplicableVersion": "any",
|
||||||
"Tags": [ "modding" ],
|
"Tags": [ "modding" ],
|
||||||
"DalamudApiLevel": 9,
|
"DalamudApiLevel": 10,
|
||||||
"LoadPriority": 69420,
|
"LoadPriority": 69420,
|
||||||
"LoadState": 2,
|
"LoadState": 2,
|
||||||
"LoadSync": true,
|
"LoadSync": true,
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ public class DalamudConfigService : IService
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var serviceType =
|
var serviceType =
|
||||||
typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "Service`1" && t.IsGenericType);
|
typeof(IDalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "Service`1" && t.IsGenericType);
|
||||||
var configType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudConfiguration");
|
var configType = typeof(IDalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudConfiguration");
|
||||||
var interfaceType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudInterface");
|
var interfaceType = typeof(IDalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudInterface");
|
||||||
if (serviceType == null || configType == null || interfaceType == null)
|
if (serviceType == null || configType == null || interfaceType == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using Penumbra.Mods;
|
||||||
|
|
||||||
namespace Penumbra.Services;
|
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 ConfigDirectory = pi.ConfigDirectory.FullName;
|
||||||
public readonly string CollectionDirectory = Path.Combine(pi.ConfigDirectory.FullName, "collections");
|
public readonly string CollectionDirectory = Path.Combine(pi.ConfigDirectory.FullName, "collections");
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ using OtterGui.Services;
|
||||||
|
|
||||||
namespace Penumbra.Services;
|
namespace Penumbra.Services;
|
||||||
|
|
||||||
public class MessageService(Logger log, UiBuilder uiBuilder, IChatGui chat, INotificationManager notificationManager)
|
public class MessageService(Logger log, IUiBuilder builder, IChatGui chat, INotificationManager notificationManager)
|
||||||
: OtterGui.Classes.MessageService(log, uiBuilder, chat, notificationManager), IService
|
: OtterGui.Classes.MessageService(log, builder, chat, notificationManager), IService
|
||||||
{
|
{
|
||||||
public void LinkItem(Item item)
|
public void LinkItem(Item item)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ namespace Penumbra.Services;
|
||||||
|
|
||||||
public static class StaticServiceManager
|
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)
|
var services = new ServiceManager(log)
|
||||||
.AddDalamudServices(pi)
|
.AddDalamudServices(pi)
|
||||||
|
|
@ -40,7 +40,7 @@ public static class StaticServiceManager
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServiceManager AddDalamudServices(this ServiceManager services, DalamudPluginInterface pi)
|
private static ServiceManager AddDalamudServices(this ServiceManager services, IDalamudPluginInterface pi)
|
||||||
=> services.AddExistingService(pi)
|
=> services.AddExistingService(pi)
|
||||||
.AddExistingService(pi.UiBuilder)
|
.AddExistingService(pi.UiBuilder)
|
||||||
.AddDalamudService<ICommandManager>(pi)
|
.AddDalamudService<ICommandManager>(pi)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
using FFXIVClientStructs.FFXIV.Client.System.Framework;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
|
@ -27,11 +27,11 @@ public class ValidityChecker : IService
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var framework = Framework.Instance();
|
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);
|
DevPenumbraExists = CheckDevPluginPenumbra(pi);
|
||||||
IsNotInstalledPenumbra = CheckIsNotInstalled(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.
|
// 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
|
#if !DEBUG
|
||||||
var path = Path.Combine(pi.DalamudAssetDirectory.Parent?.FullName ?? "INVALIDPATH", "devPlugins", "Penumbra");
|
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.
|
// 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
|
#if !DEBUG
|
||||||
var checkedDirectory = pi.AssemblyLocation.Directory?.Parent?.Parent?.Name;
|
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.
|
// 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
|
#if !DEBUG
|
||||||
return pi.SourceRepository?.Trim().ToLowerInvariant() switch
|
return pi.SourceRepository?.Trim().ToLowerInvariant() switch
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.ImGuiNotification;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue