mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 20:24:17 +01:00
Add some API
This commit is contained in:
parent
653e21e237
commit
99eb08958c
8 changed files with 112 additions and 50 deletions
|
|
@ -18,6 +18,8 @@ public delegate void ChangedItemHover( object? item );
|
||||||
public delegate void ChangedItemClick( MouseButton button, object? item );
|
public delegate void ChangedItemClick( MouseButton button, object? item );
|
||||||
public delegate void GameObjectRedrawn( IntPtr objectPtr, int objectTableIndex );
|
public delegate void GameObjectRedrawn( IntPtr objectPtr, int objectTableIndex );
|
||||||
public delegate void ModSettingChanged( ModSettingChange type, string collectionName, string modDirectory, bool inherited );
|
public delegate void ModSettingChanged( ModSettingChange type, string collectionName, string modDirectory, bool inherited );
|
||||||
|
public delegate void CreatingCharacterBaseDelegate( IntPtr gameObject, ModCollection collection, IntPtr customize, IntPtr equipData );
|
||||||
|
|
||||||
public enum PenumbraApiEc
|
public enum PenumbraApiEc
|
||||||
{
|
{
|
||||||
Success = 0,
|
Success = 0,
|
||||||
|
|
@ -50,13 +52,17 @@ public interface IPenumbraApi : IPenumbraApiBase
|
||||||
|
|
||||||
// Events that are fired before and after the content of a mod settings panel are drawn.
|
// Events that are fired before and after the content of a mod settings panel are drawn.
|
||||||
// Both are fired inside the child window of the settings panel itself.
|
// Both are fired inside the child window of the settings panel itself.
|
||||||
public event Action<string>? PreSettingsPanelDraw;
|
public event Action< string >? PreSettingsPanelDraw;
|
||||||
public event Action<string>? PostSettingsPanelDraw;
|
public event Action< string >? PostSettingsPanelDraw;
|
||||||
|
|
||||||
// Triggered when the user clicks a listed changed object in a mod tab.
|
// Triggered when the user clicks a listed changed object in a mod tab.
|
||||||
public event ChangedItemClick? ChangedItemClicked;
|
public event ChangedItemClick? ChangedItemClicked;
|
||||||
public event GameObjectRedrawn? GameObjectRedrawn;
|
public event GameObjectRedrawn? GameObjectRedrawn;
|
||||||
|
|
||||||
|
// Triggered when a character base is created and a corresponding gameObject could be found,
|
||||||
|
// before the Draw Object is actually created, so customize and equipdata can be manipulated beforehand.
|
||||||
|
public event CreatingCharacterBaseDelegate? CreatingCharacterBase;
|
||||||
|
|
||||||
// Queue redrawing of all actors of the given name with the given RedrawType.
|
// Queue redrawing of all actors of the given name with the given RedrawType.
|
||||||
public void RedrawObject( string name, RedrawType setting );
|
public void RedrawObject( string name, RedrawType setting );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -31,6 +30,7 @@ public class IpcTester : IDisposable
|
||||||
private readonly ICallGateSubscriber< string, object? > _postSettingsDraw;
|
private readonly ICallGateSubscriber< string, object? > _postSettingsDraw;
|
||||||
private readonly ICallGateSubscriber< IntPtr, int, object? > _redrawn;
|
private readonly ICallGateSubscriber< IntPtr, int, object? > _redrawn;
|
||||||
private readonly ICallGateSubscriber< ModSettingChange, string, string, bool, object? > _settingChanged;
|
private readonly ICallGateSubscriber< ModSettingChange, string, string, bool, object? > _settingChanged;
|
||||||
|
private readonly ICallGateSubscriber< IntPtr, string, IntPtr, IntPtr, object? > _characterBaseCreated;
|
||||||
|
|
||||||
private readonly List< DateTimeOffset > _initializedList = new();
|
private readonly List< DateTimeOffset > _initializedList = new();
|
||||||
private readonly List< DateTimeOffset > _disposedList = new();
|
private readonly List< DateTimeOffset > _disposedList = new();
|
||||||
|
|
@ -45,12 +45,15 @@ public class IpcTester : IDisposable
|
||||||
_preSettingsDraw = _pi.GetIpcSubscriber< string, object? >( PenumbraIpc.LabelProviderPreSettingsDraw );
|
_preSettingsDraw = _pi.GetIpcSubscriber< string, object? >( PenumbraIpc.LabelProviderPreSettingsDraw );
|
||||||
_postSettingsDraw = _pi.GetIpcSubscriber< string, object? >( PenumbraIpc.LabelProviderPostSettingsDraw );
|
_postSettingsDraw = _pi.GetIpcSubscriber< string, object? >( PenumbraIpc.LabelProviderPostSettingsDraw );
|
||||||
_settingChanged = _pi.GetIpcSubscriber< ModSettingChange, string, string, bool, object? >( PenumbraIpc.LabelProviderModSettingChanged );
|
_settingChanged = _pi.GetIpcSubscriber< ModSettingChange, string, string, bool, object? >( PenumbraIpc.LabelProviderModSettingChanged );
|
||||||
|
_characterBaseCreated =
|
||||||
|
_pi.GetIpcSubscriber< IntPtr, string, IntPtr, IntPtr, object? >( PenumbraIpc.LabelProviderCreatingCharacterBase );
|
||||||
_initialized.Subscribe( AddInitialized );
|
_initialized.Subscribe( AddInitialized );
|
||||||
_disposed.Subscribe( AddDisposed );
|
_disposed.Subscribe( AddDisposed );
|
||||||
_redrawn.Subscribe( SetLastRedrawn );
|
_redrawn.Subscribe( SetLastRedrawn );
|
||||||
_preSettingsDraw.Subscribe( UpdateLastDrawnMod );
|
_preSettingsDraw.Subscribe( UpdateLastDrawnMod );
|
||||||
_postSettingsDraw.Subscribe( UpdateLastDrawnMod );
|
_postSettingsDraw.Subscribe( UpdateLastDrawnMod );
|
||||||
_settingChanged.Subscribe( UpdateLastModSetting );
|
_settingChanged.Subscribe( UpdateLastModSetting );
|
||||||
|
_characterBaseCreated.Subscribe( UpdateLastCreated );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
@ -63,6 +66,7 @@ public class IpcTester : IDisposable
|
||||||
_preSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
|
_preSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
|
||||||
_postSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
|
_postSettingsDraw.Unsubscribe( UpdateLastDrawnMod );
|
||||||
_settingChanged.Unsubscribe( UpdateLastModSetting );
|
_settingChanged.Unsubscribe( UpdateLastModSetting );
|
||||||
|
_characterBaseCreated.Unsubscribe( UpdateLastCreated );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddInitialized()
|
private void AddInitialized()
|
||||||
|
|
@ -165,7 +169,8 @@ public class IpcTester : IDisposable
|
||||||
DrawIntro( PenumbraIpc.LabelProviderPostSettingsDraw, "Last Drawn Mod" );
|
DrawIntro( PenumbraIpc.LabelProviderPostSettingsDraw, "Last Drawn Mod" );
|
||||||
ImGui.TextUnformatted( _lastDrawnMod.Length > 0 ? $"{_lastDrawnMod} at {_lastDrawnModTime}" : "None" );
|
ImGui.TextUnformatted( _lastDrawnMod.Length > 0 ? $"{_lastDrawnMod} at {_lastDrawnModTime}" : "None" );
|
||||||
DrawIntro( PenumbraIpc.LabelProviderApiVersion, "Current Version" );
|
DrawIntro( PenumbraIpc.LabelProviderApiVersion, "Current Version" );
|
||||||
ImGui.TextUnformatted( _pi.GetIpcSubscriber< int >( PenumbraIpc.LabelProviderApiVersion ).InvokeFunc().ToString() );
|
var (breaking, features) = _pi.GetIpcSubscriber< (int, int) >( PenumbraIpc.LabelProviderApiVersion ).InvokeFunc();
|
||||||
|
ImGui.TextUnformatted( $"{breaking}.{features:D4}" );
|
||||||
DrawIntro( PenumbraIpc.LabelProviderGetModDirectory, "Current Mod Directory" );
|
DrawIntro( PenumbraIpc.LabelProviderGetModDirectory, "Current Mod Directory" );
|
||||||
ImGui.TextUnformatted( _pi.GetIpcSubscriber< string >( PenumbraIpc.LabelProviderGetModDirectory ).InvokeFunc() );
|
ImGui.TextUnformatted( _pi.GetIpcSubscriber< string >( PenumbraIpc.LabelProviderGetModDirectory ).InvokeFunc() );
|
||||||
DrawIntro( PenumbraIpc.LabelProviderGetConfiguration, "Configuration" );
|
DrawIntro( PenumbraIpc.LabelProviderGetConfiguration, "Configuration" );
|
||||||
|
|
@ -196,6 +201,15 @@ public class IpcTester : IDisposable
|
||||||
private string _currentDrawObjectString = string.Empty;
|
private string _currentDrawObjectString = string.Empty;
|
||||||
private string _currentReversePath = string.Empty;
|
private string _currentReversePath = string.Empty;
|
||||||
private IntPtr _currentDrawObject = IntPtr.Zero;
|
private IntPtr _currentDrawObject = IntPtr.Zero;
|
||||||
|
private string _lastCreatedGameObjectName = string.Empty;
|
||||||
|
private DateTimeOffset _lastCreatedGameObjectTime = DateTimeOffset.MaxValue;
|
||||||
|
|
||||||
|
private unsafe void UpdateLastCreated( IntPtr gameObject, string _, IntPtr _2, IntPtr _3 )
|
||||||
|
{
|
||||||
|
var obj = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )gameObject;
|
||||||
|
_lastCreatedGameObjectName = new Utf8String( obj->GetName() ).ToString();
|
||||||
|
_lastCreatedGameObjectTime = DateTimeOffset.Now;
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawResolve()
|
private void DrawResolve()
|
||||||
{
|
{
|
||||||
|
|
@ -263,6 +277,12 @@ public class IpcTester : IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawIntro( PenumbraIpc.LabelProviderCreatingCharacterBase, "Last Drawobject created" );
|
||||||
|
if( _lastCreatedGameObjectTime < DateTimeOffset.Now )
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted( $"for <{_lastCreatedGameObjectName}> at {_lastCreatedGameObjectTime}" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string _redrawName = string.Empty;
|
private string _redrawName = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,23 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
|
|
||||||
private readonly Dictionary< ModCollection, ModCollection.ModSettingChangeDelegate > _delegates = new();
|
private readonly Dictionary< ModCollection, ModCollection.ModSettingChangeDelegate > _delegates = new();
|
||||||
|
|
||||||
public event Action<string>? PreSettingsPanelDraw;
|
public event Action< string >? PreSettingsPanelDraw;
|
||||||
public event Action<string>? PostSettingsPanelDraw;
|
public event Action< string >? PostSettingsPanelDraw;
|
||||||
public event GameObjectRedrawn? GameObjectRedrawn;
|
|
||||||
|
public event GameObjectRedrawn? GameObjectRedrawn
|
||||||
|
{
|
||||||
|
add => _penumbra!.ObjectReloader.GameObjectRedrawn += value;
|
||||||
|
remove => _penumbra!.ObjectReloader.GameObjectRedrawn -= value;
|
||||||
|
}
|
||||||
|
|
||||||
public event ModSettingChanged? ModSettingChanged;
|
public event ModSettingChanged? ModSettingChanged;
|
||||||
|
|
||||||
|
public event CreatingCharacterBaseDelegate? CreatingCharacterBase
|
||||||
|
{
|
||||||
|
add => _penumbra!.PathResolver.CreatingCharacterBase += value;
|
||||||
|
remove => _penumbra!.PathResolver.CreatingCharacterBase -= value;
|
||||||
|
}
|
||||||
|
|
||||||
public bool Valid
|
public bool Valid
|
||||||
=> _penumbra != null;
|
=> _penumbra != null;
|
||||||
|
|
||||||
|
|
@ -42,7 +54,6 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
_lumina = ( Lumina.GameData? )Dalamud.GameData.GetType()
|
_lumina = ( Lumina.GameData? )Dalamud.GameData.GetType()
|
||||||
.GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( Dalamud.GameData );
|
?.GetValue( Dalamud.GameData );
|
||||||
_penumbra.ObjectReloader.GameObjectRedrawn += OnGameObjectRedrawn;
|
|
||||||
foreach( var collection in Penumbra.CollectionManager )
|
foreach( var collection in Penumbra.CollectionManager )
|
||||||
{
|
{
|
||||||
SubscribeToCollection( collection );
|
SubscribeToCollection( collection );
|
||||||
|
|
@ -54,7 +65,6 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Penumbra.CollectionManager.CollectionChanged -= SubscribeToNewCollections;
|
Penumbra.CollectionManager.CollectionChanged -= SubscribeToNewCollections;
|
||||||
_penumbra!.ObjectReloader.GameObjectRedrawn -= OnGameObjectRedrawn;
|
|
||||||
_penumbra = null;
|
_penumbra = null;
|
||||||
_lumina = null;
|
_lumina = null;
|
||||||
foreach( var collection in Penumbra.CollectionManager )
|
foreach( var collection in Penumbra.CollectionManager )
|
||||||
|
|
@ -249,9 +259,11 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
public PenumbraApiEc AddMod( string modDirectory )
|
public PenumbraApiEc AddMod( string modDirectory )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
var dir = new DirectoryInfo( Path.Combine(Penumbra.ModManager.BasePath.FullName, modDirectory) );
|
var dir = new DirectoryInfo( Path.Combine( Penumbra.ModManager.BasePath.FullName, modDirectory ) );
|
||||||
if( !dir.Exists )
|
if( !dir.Exists )
|
||||||
|
{
|
||||||
return PenumbraApiEc.FileMissing;
|
return PenumbraApiEc.FileMissing;
|
||||||
|
}
|
||||||
|
|
||||||
Penumbra.ModManager.AddMod( dir );
|
Penumbra.ModManager.AddMod( dir );
|
||||||
return PenumbraApiEc.Success;
|
return PenumbraApiEc.Success;
|
||||||
|
|
@ -521,11 +533,6 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGameObjectRedrawn( IntPtr objectAddress, int objectTableIndex )
|
|
||||||
{
|
|
||||||
GameObjectRedrawn?.Invoke( objectAddress, objectTableIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve a path given by string for a specific collection.
|
// Resolve a path given by string for a specific collection.
|
||||||
private static string ResolvePath( string path, Mod.Manager _, ModCollection collection )
|
private static string ResolvePath( string path, Mod.Manager _, ModCollection collection )
|
||||||
{
|
{
|
||||||
|
|
@ -645,9 +652,9 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InvokePreSettingsPanel(string modDirectory)
|
public void InvokePreSettingsPanel( string modDirectory )
|
||||||
=> PreSettingsPanelDraw?.Invoke(modDirectory);
|
=> PreSettingsPanelDraw?.Invoke( modDirectory );
|
||||||
|
|
||||||
public void InvokePostSettingsPanel(string modDirectory)
|
public void InvokePostSettingsPanel( string modDirectory )
|
||||||
=> PostSettingsPanelDraw?.Invoke(modDirectory);
|
=> PostSettingsPanelDraw?.Invoke( modDirectory );
|
||||||
}
|
}
|
||||||
|
|
@ -57,8 +57,8 @@ public partial class PenumbraIpc
|
||||||
internal ICallGateProvider< int >? ProviderApiVersion;
|
internal ICallGateProvider< int >? ProviderApiVersion;
|
||||||
internal ICallGateProvider< string >? ProviderGetModDirectory;
|
internal ICallGateProvider< string >? ProviderGetModDirectory;
|
||||||
internal ICallGateProvider< string >? ProviderGetConfiguration;
|
internal ICallGateProvider< string >? ProviderGetConfiguration;
|
||||||
internal ICallGateProvider<string, object?>? ProviderPreSettingsDraw;
|
internal ICallGateProvider< string, object? >? ProviderPreSettingsDraw;
|
||||||
internal ICallGateProvider<string, object?>? ProviderPostSettingsDraw;
|
internal ICallGateProvider< string, object? >? ProviderPostSettingsDraw;
|
||||||
|
|
||||||
private void InitializeGeneralProviders( DalamudPluginInterface pi )
|
private void InitializeGeneralProviders( DalamudPluginInterface pi )
|
||||||
{
|
{
|
||||||
|
|
@ -82,7 +82,7 @@ public partial class PenumbraIpc
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProviderApiVersion = pi.GetIpcProvider< int >( LabelProviderApiVersion );
|
ProviderApiVersion = pi.GetIpcProvider< (int Breaking, int Features) >( LabelProviderApiVersion );
|
||||||
ProviderApiVersion.RegisterFunc( () => Api.ApiVersion );
|
ProviderApiVersion.RegisterFunc( () => Api.ApiVersion );
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
|
|
@ -112,7 +112,7 @@ public partial class PenumbraIpc
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProviderPreSettingsDraw = pi.GetIpcProvider<string, object?>( LabelProviderPreSettingsDraw );
|
ProviderPreSettingsDraw = pi.GetIpcProvider< string, object? >( LabelProviderPreSettingsDraw );
|
||||||
Api.PreSettingsPanelDraw += InvokeSettingsPreDraw;
|
Api.PreSettingsPanelDraw += InvokeSettingsPreDraw;
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
|
|
@ -122,7 +122,7 @@ public partial class PenumbraIpc
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ProviderPostSettingsDraw = pi.GetIpcProvider<string, object?>( LabelProviderPostSettingsDraw );
|
ProviderPostSettingsDraw = pi.GetIpcProvider< string, object? >( LabelProviderPostSettingsDraw );
|
||||||
Api.PostSettingsPanelDraw += InvokeSettingsPostDraw;
|
Api.PostSettingsPanelDraw += InvokeSettingsPostDraw;
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
|
|
@ -136,6 +136,8 @@ public partial class PenumbraIpc
|
||||||
ProviderGetConfiguration?.UnregisterFunc();
|
ProviderGetConfiguration?.UnregisterFunc();
|
||||||
ProviderGetModDirectory?.UnregisterFunc();
|
ProviderGetModDirectory?.UnregisterFunc();
|
||||||
ProviderApiVersion?.UnregisterFunc();
|
ProviderApiVersion?.UnregisterFunc();
|
||||||
|
Api.PreSettingsPanelDraw -= InvokeSettingsPreDraw;
|
||||||
|
Api.PostSettingsPanelDraw -= InvokeSettingsPostDraw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,11 +244,13 @@ public partial class PenumbraIpc
|
||||||
public const string LabelProviderResolveCharacter = "Penumbra.ResolveCharacterPath";
|
public const string LabelProviderResolveCharacter = "Penumbra.ResolveCharacterPath";
|
||||||
public const string LabelProviderGetDrawObjectInfo = "Penumbra.GetDrawObjectInfo";
|
public const string LabelProviderGetDrawObjectInfo = "Penumbra.GetDrawObjectInfo";
|
||||||
public const string LabelProviderReverseResolvePath = "Penumbra.ReverseResolvePath";
|
public const string LabelProviderReverseResolvePath = "Penumbra.ReverseResolvePath";
|
||||||
|
public const string LabelProviderCreatingCharacterBase = "Penumbra.CreatingCharacterBase";
|
||||||
|
|
||||||
internal ICallGateProvider< string, string >? ProviderResolveDefault;
|
internal ICallGateProvider< string, string >? ProviderResolveDefault;
|
||||||
internal ICallGateProvider< string, string, string >? ProviderResolveCharacter;
|
internal ICallGateProvider< string, string, string >? ProviderResolveCharacter;
|
||||||
internal ICallGateProvider< IntPtr, (IntPtr, string) >? ProviderGetDrawObjectInfo;
|
internal ICallGateProvider< IntPtr, (IntPtr, string) >? ProviderGetDrawObjectInfo;
|
||||||
internal ICallGateProvider< string, string, IList< string > >? ProviderReverseResolvePath;
|
internal ICallGateProvider< string, string, IList< string > >? ProviderReverseResolvePath;
|
||||||
|
internal ICallGateProvider< IntPtr, string, IntPtr, IntPtr, object? >? ProviderCreatingCharacterBase;
|
||||||
|
|
||||||
private void InitializeResolveProviders( DalamudPluginInterface pi )
|
private void InitializeResolveProviders( DalamudPluginInterface pi )
|
||||||
{
|
{
|
||||||
|
|
@ -289,6 +293,16 @@ public partial class PenumbraIpc
|
||||||
{
|
{
|
||||||
PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetDrawObjectInfo}:\n{e}" );
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderGetDrawObjectInfo}:\n{e}" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderCreatingCharacterBase = pi.GetIpcProvider< IntPtr, string, IntPtr, IntPtr, object? >( LabelProviderCreatingCharacterBase );
|
||||||
|
Api.CreatingCharacterBase += CreatingCharacterBaseEvent;
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderCreatingCharacterBase}:\n{e}" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisposeResolveProviders()
|
private void DisposeResolveProviders()
|
||||||
|
|
@ -297,6 +311,12 @@ public partial class PenumbraIpc
|
||||||
ProviderResolveDefault?.UnregisterFunc();
|
ProviderResolveDefault?.UnregisterFunc();
|
||||||
ProviderResolveCharacter?.UnregisterFunc();
|
ProviderResolveCharacter?.UnregisterFunc();
|
||||||
ProviderReverseResolvePath?.UnregisterFunc();
|
ProviderReverseResolvePath?.UnregisterFunc();
|
||||||
|
Api.CreatingCharacterBase -= CreatingCharacterBaseEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreatingCharacterBaseEvent( IntPtr gameObject, ModCollection collection, IntPtr customize, IntPtr equipData )
|
||||||
|
{
|
||||||
|
ProviderCreatingCharacterBase?.SendMessage( gameObject, collection.Name, customize, equipData );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ using Dalamud.Utility.Signatures;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||||
using Penumbra.GameData.ByteString;
|
using Penumbra.GameData.ByteString;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Util;
|
|
||||||
using Penumbra.Interop.Structs;
|
using Penumbra.Interop.Structs;
|
||||||
using FileMode = Penumbra.Interop.Structs.FileMode;
|
using FileMode = Penumbra.Interop.Structs.FileMode;
|
||||||
using ResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle;
|
using ResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle;
|
||||||
|
|
@ -114,7 +113,7 @@ public unsafe partial class ResourceLoader
|
||||||
// Try all resolve path subscribers or use the default replacer.
|
// Try all resolve path subscribers or use the default replacer.
|
||||||
private (FullPath?, object?) ResolvePath( Utf8GamePath path, ResourceCategory category, ResourceType resourceType, int resourceHash )
|
private (FullPath?, object?) ResolvePath( Utf8GamePath path, ResourceCategory category, ResourceType resourceType, int resourceHash )
|
||||||
{
|
{
|
||||||
if( !DoReplacements || IsInIncRef )
|
if( !DoReplacements || IsInIncRef > 0 )
|
||||||
{
|
{
|
||||||
return ( null, null );
|
return ( null, null );
|
||||||
}
|
}
|
||||||
|
|
@ -270,15 +269,14 @@ public unsafe partial class ResourceLoader
|
||||||
// This means, that if the path determined from that is different than the resources path,
|
// This means, that if the path determined from that is different than the resources path,
|
||||||
// a different resource gets loaded or incremented, while the IncRef'd resource stays at 0.
|
// a different resource gets loaded or incremented, while the IncRef'd resource stays at 0.
|
||||||
// This causes some problems and is hopefully prevented with this.
|
// This causes some problems and is hopefully prevented with this.
|
||||||
public bool IsInIncRef { get; private set; } = false;
|
public int IsInIncRef { get; private set; } = 0;
|
||||||
private readonly Hook< ResourceHandleDestructor > _incRefHook;
|
private readonly Hook< ResourceHandleDestructor > _incRefHook;
|
||||||
|
|
||||||
private IntPtr ResourceHandleIncRefDetour( ResourceHandle* handle )
|
private IntPtr ResourceHandleIncRefDetour( ResourceHandle* handle )
|
||||||
{
|
{
|
||||||
var tmp = IsInIncRef;
|
++IsInIncRef;
|
||||||
IsInIncRef = true;
|
|
||||||
var ret = _incRefHook.Original( handle );
|
var ret = _incRefHook.Original( handle );
|
||||||
IsInIncRef = tmp;
|
--IsInIncRef;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Game.ClientState.Conditions;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Penumbra.Api;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Interop.Structs;
|
using Penumbra.Interop.Structs;
|
||||||
|
|
||||||
|
|
@ -105,7 +106,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
|
||||||
private readonly List< int > _afterGPoseQueue = new(GPoseSlots);
|
private readonly List< int > _afterGPoseQueue = new(GPoseSlots);
|
||||||
private int _target = -1;
|
private int _target = -1;
|
||||||
|
|
||||||
public event Action< IntPtr, int >? GameObjectRedrawn;
|
public event GameObjectRedrawn? GameObjectRedrawn;
|
||||||
|
|
||||||
public ObjectReloader()
|
public ObjectReloader()
|
||||||
=> Dalamud.Framework.Update += OnUpdateEvent;
|
=> Dalamud.Framework.Update += OnUpdateEvent;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
||||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||||
using FFXIVClientStructs.FFXIV.Client.UI;
|
using FFXIVClientStructs.FFXIV.Client.UI;
|
||||||
using FFXIVClientStructs.FFXIV.Component.GUI;
|
using FFXIVClientStructs.FFXIV.Component.GUI;
|
||||||
|
using Penumbra.Api;
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.GameData.ByteString;
|
using Penumbra.GameData.ByteString;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
@ -28,10 +29,18 @@ public unsafe partial class PathResolver
|
||||||
public Hook< CharacterBaseCreateDelegate >? CharacterBaseCreateHook;
|
public Hook< CharacterBaseCreateDelegate >? CharacterBaseCreateHook;
|
||||||
|
|
||||||
private ModCollection? _lastCreatedCollection;
|
private ModCollection? _lastCreatedCollection;
|
||||||
|
public event CreatingCharacterBaseDelegate? CreatingCharacterBase;
|
||||||
|
|
||||||
|
|
||||||
private IntPtr CharacterBaseCreateDetour( uint a, IntPtr b, IntPtr c, byte d )
|
private IntPtr CharacterBaseCreateDetour( uint a, IntPtr b, IntPtr c, byte d )
|
||||||
{
|
{
|
||||||
using var cmp = MetaChanger.ChangeCmp( this, out _lastCreatedCollection );
|
using var cmp = MetaChanger.ChangeCmp( this, out _lastCreatedCollection );
|
||||||
|
|
||||||
|
if( LastGameObject != null )
|
||||||
|
{
|
||||||
|
CreatingCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!, b, c );
|
||||||
|
}
|
||||||
|
|
||||||
var ret = CharacterBaseCreateHook!.Original( a, b, c, d );
|
var ret = CharacterBaseCreateHook!.Original( a, b, c, d );
|
||||||
if( LastGameObject != null )
|
if( LastGameObject != null )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,7 @@ public partial class ConfigWindow
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.TextUnformatted( $"In Increment RefCounter Mode: {Penumbra.ResourceLoader.IsInIncRef}" );
|
||||||
using var drawTree = ImRaii.TreeNode( "Draw Object to Object" );
|
using var drawTree = ImRaii.TreeNode( "Draw Object to Object" );
|
||||||
if( drawTree )
|
if( drawTree )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue