mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Some cleanup, slight changes.
This commit is contained in:
parent
bcd62cbe69
commit
3c5cff1418
6 changed files with 74 additions and 62 deletions
|
|
@ -20,6 +20,7 @@ public interface IPenumbraApiBase
|
|||
|
||||
public delegate void ChangedItemHover( object? item );
|
||||
public delegate void ChangedItemClick( MouseButton button, object? item );
|
||||
public delegate void GameObjectRedrawn( IntPtr objectPtr, int objectTableIndex );
|
||||
|
||||
public enum PenumbraApiEc
|
||||
{
|
||||
|
|
@ -51,7 +52,7 @@ public interface IPenumbraApi : IPenumbraApiBase
|
|||
|
||||
// Triggered when the user clicks a listed changed object in a mod tab.
|
||||
public event ChangedItemClick? ChangedItemClicked;
|
||||
event EventHandler? ObjectIsRedrawn;
|
||||
public event GameObjectRedrawn? GameObjectRedrawn;
|
||||
|
||||
// Queue redrawing of all actors of the given name with the given RedrawType.
|
||||
public void RedrawObject( string name, RedrawType setting );
|
||||
|
|
@ -74,7 +75,7 @@ public interface IPenumbraApi : IPenumbraApiBase
|
|||
public string ResolvePath( string gamePath, string characterName );
|
||||
|
||||
// Reverse resolves a given modded local path into its replacement in form of all applicable game path for given character
|
||||
public string[] ReverseResolvePath( string moddedPath, string characterName );
|
||||
public IList<string> ReverseResolvePath( string moddedPath, string characterName );
|
||||
|
||||
// Try to load a given gamePath with the resolved path from Penumbra.
|
||||
public T? GetFile< T >( string gamePath ) where T : FileResource;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
public int ApiVersion { get; } = 4;
|
||||
private Penumbra? _penumbra;
|
||||
private Lumina.GameData? _lumina;
|
||||
public event EventHandler? ObjectIsRedrawn;
|
||||
public event GameObjectRedrawn? GameObjectRedrawn;
|
||||
|
||||
public bool Valid
|
||||
=> _penumbra != null;
|
||||
|
|
@ -29,21 +29,16 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
{
|
||||
_penumbra = penumbra;
|
||||
_lumina = ( Lumina.GameData? )Dalamud.GameData.GetType()
|
||||
.GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||
?.GetValue( Dalamud.GameData );
|
||||
_penumbra.ObjectReloader.ObjectIsRedrawn += ObjectReloader_ObjectIsRedrawn;
|
||||
}
|
||||
|
||||
private void ObjectReloader_ObjectIsRedrawn( object? sender, EventArgs e )
|
||||
{
|
||||
ObjectIsRedrawn?.Invoke( sender, e );
|
||||
.GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||
?.GetValue( Dalamud.GameData );
|
||||
_penumbra.ObjectReloader.GameObjectRedrawn += OnGameObjectRedrawn;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_penumbra!.ObjectReloader.ObjectIsRedrawn -= ObjectReloader_ObjectIsRedrawn;
|
||||
_penumbra = null;
|
||||
_lumina = null;
|
||||
_penumbra!.ObjectReloader.GameObjectRedrawn -= OnGameObjectRedrawn;
|
||||
_penumbra = null;
|
||||
_lumina = null;
|
||||
}
|
||||
|
||||
public event ChangedItemClick? ChangedItemClicked;
|
||||
|
|
@ -98,13 +93,18 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
_penumbra!.ObjectReloader.RedrawObject( gameObject, setting );
|
||||
}
|
||||
|
||||
private void OnGameObjectRedrawn( IntPtr objectAddress, int objectTableIndex )
|
||||
{
|
||||
GameObjectRedrawn?.Invoke( objectAddress, objectTableIndex );
|
||||
}
|
||||
|
||||
public void RedrawAll( RedrawType setting )
|
||||
{
|
||||
CheckInitialized();
|
||||
_penumbra!.ObjectReloader.RedrawAll( setting );
|
||||
}
|
||||
|
||||
private static string ResolvePath( string path, Mods.Mod.Manager _, ModCollection collection )
|
||||
private static string ResolvePath( string path, Mod.Manager _, ModCollection collection )
|
||||
{
|
||||
if( !Penumbra.Config.EnableMods )
|
||||
{
|
||||
|
|
@ -129,7 +129,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
Penumbra.CollectionManager.Character( characterName ) );
|
||||
}
|
||||
|
||||
public string[] ReverseResolvePath( string path, string characterName )
|
||||
public IList< string > ReverseResolvePath( string path, string characterName )
|
||||
{
|
||||
CheckInitialized();
|
||||
if( !Penumbra.Config.EnableMods )
|
||||
|
|
@ -137,11 +137,8 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return new[] { path };
|
||||
}
|
||||
|
||||
var gamePath = Utf8GamePath.FromString( path, out var p, true ) ? p : Utf8GamePath.Empty;
|
||||
var ret = Penumbra.CollectionManager.Character( characterName ).ResolveReversePath( new FullPath( path ) ) ??
|
||||
new List< Utf8GamePath >();
|
||||
if( ret.Count == 0 ) ret.Add( gamePath );
|
||||
return ret.Select( r => r.ToString() ).ToArray();
|
||||
var ret = Penumbra.CollectionManager.Character( characterName ).ReverseResolvePath( new FullPath( path ) );
|
||||
return ret.Select( r => r.ToString() ).ToList();
|
||||
}
|
||||
|
||||
private T? GetFileIntern< T >( string resolvedPath ) where T : FileResource
|
||||
|
|
@ -233,10 +230,11 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return Penumbra.ModManager.Select( m => ( m.ModPath.Name, m.Name.Text ) ).ToArray();
|
||||
}
|
||||
|
||||
public IDictionary< string, (IList<string>, SelectType) >? GetAvailableModSettings( string modDirectory, string modName )
|
||||
public IDictionary< string, (IList< string >, SelectType) >? GetAvailableModSettings( string modDirectory, string modName )
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public (PenumbraApiEc, (bool, int, IDictionary< string, IList<string> >, bool)?) GetCurrentModSettings( string collectionName, string modDirectory, string modName,
|
||||
public (PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)?) GetCurrentModSettings( string collectionName,
|
||||
string modDirectory, string modName,
|
||||
bool allowInheritance )
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
|
|
@ -252,7 +250,8 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName, string option )
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName, IReadOnlyList<string> options )
|
||||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName,
|
||||
IReadOnlyList< string > options )
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public PenumbraApiEc CreateTemporaryCollection( string collectionName, string? character, bool forceOverwriteCharacter )
|
||||
|
|
|
|||
|
|
@ -111,17 +111,17 @@ public partial class PenumbraIpc
|
|||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderRedrawName = "Penumbra.RedrawObjectByName";
|
||||
public const string LabelProviderRedrawIndex = "Penumbra.RedrawObjectByIndex";
|
||||
public const string LabelProviderRedrawObject = "Penumbra.RedrawObject";
|
||||
public const string LabelProviderRedrawAll = "Penumbra.RedrawAll";
|
||||
public const string LabelProviderObjectIsRedrawn = "Penumbra.ObjectIsRedrawn";
|
||||
public const string LabelProviderRedrawName = "Penumbra.RedrawObjectByName";
|
||||
public const string LabelProviderRedrawIndex = "Penumbra.RedrawObjectByIndex";
|
||||
public const string LabelProviderRedrawObject = "Penumbra.RedrawObject";
|
||||
public const string LabelProviderRedrawAll = "Penumbra.RedrawAll";
|
||||
public const string LabelProviderGameObjectRedrawn = "Penumbra.GameObjectRedrawn";
|
||||
|
||||
internal ICallGateProvider< string, int, object >? ProviderRedrawName;
|
||||
internal ICallGateProvider< int, int, object >? ProviderRedrawIndex;
|
||||
internal ICallGateProvider< GameObject, int, object >? ProviderRedrawObject;
|
||||
internal ICallGateProvider< int, object >? ProviderRedrawAll;
|
||||
internal ICallGateProvider< string, string >? ProviderObjectIsRedrawn;
|
||||
internal ICallGateProvider< IntPtr, int, object? >? ProviderGameObjectRedrawn;
|
||||
|
||||
private static RedrawType CheckRedrawType( int value )
|
||||
{
|
||||
|
|
@ -178,19 +178,17 @@ public partial class PenumbraIpc
|
|||
|
||||
try
|
||||
{
|
||||
ProviderObjectIsRedrawn = pi.GetIpcProvider< string, string >( LabelProviderObjectIsRedrawn );
|
||||
Api.ObjectIsRedrawn += Api_ObjectIsRedrawn;
|
||||
ProviderGameObjectRedrawn = pi.GetIpcProvider< IntPtr, int, object? >( LabelProviderGameObjectRedrawn );
|
||||
Api.GameObjectRedrawn += OnGameObjectRedrawn;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Error registering IPC provider for {LabelProviderObjectIsRedrawn}:\n{e}" );
|
||||
PluginLog.Error( $"Error registering IPC provider for {LabelProviderGameObjectRedrawn}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void Api_ObjectIsRedrawn( object? sender, EventArgs e )
|
||||
{
|
||||
ProviderObjectIsRedrawn?.SendMessage( ( ( GameObject? )sender )?.Name.ToString() ?? "" );
|
||||
}
|
||||
private void OnGameObjectRedrawn( IntPtr objectAddress, int objectTableIndex )
|
||||
=> ProviderGameObjectRedrawn?.SendMessage( objectAddress, objectTableIndex );
|
||||
|
||||
private void DisposeRedrawProviders()
|
||||
{
|
||||
|
|
@ -198,7 +196,7 @@ public partial class PenumbraIpc
|
|||
ProviderRedrawIndex?.UnregisterAction();
|
||||
ProviderRedrawObject?.UnregisterAction();
|
||||
ProviderRedrawAll?.UnregisterAction();
|
||||
Api.ObjectIsRedrawn -= Api_ObjectIsRedrawn;
|
||||
Api.GameObjectRedrawn -= OnGameObjectRedrawn;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,10 +207,10 @@ public partial class PenumbraIpc
|
|||
public const string LabelProviderGetDrawObjectInfo = "Penumbra.GetDrawObjectInfo";
|
||||
public const string LabelProviderReverseResolvePath = "Penumbra.ReverseResolvePath";
|
||||
|
||||
internal ICallGateProvider< string, string >? ProviderResolveDefault;
|
||||
internal ICallGateProvider< string, string, string >? ProviderResolveCharacter;
|
||||
internal ICallGateProvider< IntPtr, (IntPtr, string) >? ProviderGetDrawObjectInfo;
|
||||
internal ICallGateProvider< string, string, string[] >? ProviderReverseResolvePath;
|
||||
internal ICallGateProvider< string, string >? ProviderResolveDefault;
|
||||
internal ICallGateProvider< string, string, string >? ProviderResolveCharacter;
|
||||
internal ICallGateProvider< IntPtr, (IntPtr, string) >? ProviderGetDrawObjectInfo;
|
||||
internal ICallGateProvider< string, string, IList< string > >? ProviderReverseResolvePath;
|
||||
|
||||
private void InitializeResolveProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
|
|
@ -248,7 +246,7 @@ public partial class PenumbraIpc
|
|||
|
||||
try
|
||||
{
|
||||
ProviderReverseResolvePath = pi.GetIpcProvider< string, string, string[] >( LabelProviderReverseResolvePath );
|
||||
ProviderReverseResolvePath = pi.GetIpcProvider< string, string, IList< string > >( LabelProviderReverseResolvePath );
|
||||
ProviderReverseResolvePath.RegisterFunc( Api.ReverseResolvePath );
|
||||
}
|
||||
catch( Exception e )
|
||||
|
|
@ -262,6 +260,7 @@ public partial class PenumbraIpc
|
|||
ProviderGetDrawObjectInfo?.UnregisterFunc();
|
||||
ProviderResolveDefault?.UnregisterFunc();
|
||||
ProviderResolveCharacter?.UnregisterFunc();
|
||||
ProviderReverseResolvePath?.UnregisterFunc();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,8 @@ public partial class ModCollection
|
|||
PluginLog.Verbose( "Cleared cache of collection {Name:l}.", Name );
|
||||
}
|
||||
|
||||
public List<Utf8GamePath>? ResolveReversePath( FullPath path ) => _cache?.ReverseResolvePath( path );
|
||||
public IEnumerable< Utf8GamePath > ReverseResolvePath( FullPath path )
|
||||
=> _cache?.ReverseResolvePath( path ) ?? Array.Empty< Utf8GamePath >();
|
||||
|
||||
public FullPath? ResolvePath( Utf8GamePath path )
|
||||
=> _cache?.ResolvePath( path );
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ using Penumbra.Util;
|
|||
namespace Penumbra.Collections;
|
||||
|
||||
public record struct ModPath( Mod Mod, FullPath Path );
|
||||
|
||||
public record ModConflicts( Mod Mod2, List< object > Conflicts, bool HasPriority, bool Solved );
|
||||
|
||||
public partial class ModCollection
|
||||
|
|
@ -72,7 +71,7 @@ public partial class ModCollection
|
|||
}
|
||||
|
||||
if( candidate.Path.InternalName.Length > Utf8GamePath.MaxGamePathLength
|
||||
|| candidate.Path.IsRooted && !candidate.Path.Exists )
|
||||
|| candidate.Path.IsRooted && !candidate.Path.Exists )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
@ -80,11 +79,26 @@ public partial class ModCollection
|
|||
return candidate.Path;
|
||||
}
|
||||
|
||||
public List< Utf8GamePath > ReverseResolvePath( FullPath localFilePath )
|
||||
// For a given full path, find all game paths that currently use this file.
|
||||
public IEnumerable< Utf8GamePath > ReverseResolvePath( FullPath localFilePath )
|
||||
{
|
||||
string strToSearchFor = localFilePath.FullName.Replace( '/', '\\' ).ToLower();
|
||||
return ResolvedFiles.Where( f => f.Value.Path.FullName.ToLower() == strToSearchFor )
|
||||
.Select( kvp => kvp.Key ).ToList();
|
||||
var needle = localFilePath.FullName.ToLower();
|
||||
if( localFilePath.IsRooted )
|
||||
{
|
||||
needle = needle.Replace( '/', '\\' );
|
||||
}
|
||||
|
||||
var iterator = ResolvedFiles
|
||||
.Where( f => string.Equals( f.Value.Path.FullName, needle, StringComparison.InvariantCultureIgnoreCase ) )
|
||||
.Select( kvp => kvp.Key );
|
||||
|
||||
// For files that are not rooted, try to add themselves.
|
||||
if( !localFilePath.IsRooted && Utf8GamePath.FromString( localFilePath.FullName, out var utf8 ) )
|
||||
{
|
||||
iterator = iterator.Prepend( utf8 );
|
||||
}
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
private void OnModSettingChange( ModSettingChange type, int modIdx, int oldValue, int groupIdx, bool _ )
|
||||
|
|
@ -253,8 +267,8 @@ public partial class ModCollection
|
|||
case SelectType.Multi:
|
||||
{
|
||||
foreach( var (option, _) in group.WithIndex()
|
||||
.OrderByDescending( p => group.OptionPriority( p.Item2 ) )
|
||||
.Where( p => ( ( 1 << p.Item2 ) & config ) != 0 ) )
|
||||
.OrderByDescending( p => group.OptionPriority( p.Item2 ) )
|
||||
.Where( p => ( ( 1 << p.Item2 ) & config ) != 0 ) )
|
||||
{
|
||||
AddSubMod( option, mod );
|
||||
}
|
||||
|
|
@ -360,7 +374,7 @@ public partial class ModCollection
|
|||
// Returns if the added mod takes priority before the existing mod.
|
||||
private bool AddConflict( object data, Mod addedMod, Mod existingMod )
|
||||
{
|
||||
var addedPriority = addedMod.Index >= 0 ? _collection[ addedMod.Index ].Settings!.Priority : int.MaxValue;
|
||||
var addedPriority = addedMod.Index >= 0 ? _collection[ addedMod.Index ].Settings!.Priority : int.MaxValue;
|
||||
var existingPriority = existingMod.Index >= 0 ? _collection[ existingMod.Index ].Settings!.Priority : int.MaxValue;
|
||||
|
||||
if( existingPriority < addedPriority )
|
||||
|
|
@ -368,9 +382,8 @@ public partial class ModCollection
|
|||
var tmpConflicts = Conflicts( existingMod );
|
||||
foreach( var conflict in tmpConflicts )
|
||||
{
|
||||
if( data is Utf8GamePath path && conflict.Conflicts.RemoveAll( p => p is Utf8GamePath x && x.Equals( path ) ) > 0
|
||||
|| data is MetaManipulation meta &&
|
||||
conflict.Conflicts.RemoveAll( m => m is MetaManipulation x && x.Equals( meta ) ) > 0 )
|
||||
if( data is Utf8GamePath path && conflict.Conflicts.RemoveAll( p => p is Utf8GamePath x && x.Equals( path ) ) > 0
|
||||
|| data is MetaManipulation meta && conflict.Conflicts.RemoveAll( m => m is MetaManipulation x && x.Equals( meta ) ) > 0 )
|
||||
{
|
||||
AddConflict( data, addedMod, conflict.Mod2 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@ public unsafe partial class ObjectReloader
|
|||
private static void EnableDraw( GameObject actor )
|
||||
=> ( ( delegate* unmanaged< IntPtr, void >** )actor.Address )[ 0 ][ 16 ]( actor.Address );
|
||||
|
||||
public event EventHandler? ObjectIsRedrawn;
|
||||
|
||||
// Check whether we currently are in GPose.
|
||||
// Also clear the name list.
|
||||
private void SetGPose()
|
||||
|
|
@ -107,6 +105,8 @@ public sealed unsafe partial class ObjectReloader : IDisposable
|
|||
private readonly List< int > _afterGPoseQueue = new(GPoseSlots);
|
||||
private int _target = -1;
|
||||
|
||||
public event Action< IntPtr, int >? GameObjectRedrawn;
|
||||
|
||||
public ObjectReloader()
|
||||
=> Dalamud.Framework.Update += OnUpdateEvent;
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
private static void WriteVisible( GameObject? actor )
|
||||
private void WriteVisible( GameObject? actor )
|
||||
{
|
||||
if( BadRedrawIndices( actor, out var tableIndex ) )
|
||||
{
|
||||
|
|
@ -142,11 +142,12 @@ public sealed unsafe partial class ObjectReloader : IDisposable
|
|||
}
|
||||
|
||||
*ActorDrawState( actor! ) &= ~DrawState.Invisibility;
|
||||
|
||||
if( IsGPoseActor( tableIndex ) )
|
||||
{
|
||||
EnableDraw( actor! );
|
||||
}
|
||||
|
||||
GameObjectRedrawn?.Invoke( actor!.Address, tableIndex );
|
||||
}
|
||||
|
||||
private void ReloadActor( GameObject? actor )
|
||||
|
|
@ -282,8 +283,6 @@ public sealed unsafe partial class ObjectReloader : IDisposable
|
|||
break;
|
||||
default: throw new ArgumentOutOfRangeException( nameof( settings ), settings, null );
|
||||
}
|
||||
|
||||
ObjectIsRedrawn?.Invoke( actor, new EventArgs() );
|
||||
}
|
||||
|
||||
private static GameObject? GetLocalPlayer()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue