mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-02-23 00:07:53 +01:00
Use external library for API interface and IPC.
This commit is contained in:
parent
b3f048bfe6
commit
918d5db6a6
69 changed files with 4026 additions and 1873 deletions
|
|
@ -1,236 +0,0 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Lumina.Data;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Mods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
public interface IPenumbraApiBase
|
||||
{
|
||||
// The API version is staggered in two parts.
|
||||
// The major/Breaking version only increments if there are changes breaking backwards compatibility.
|
||||
// The minor/Feature version increments any time there is something added
|
||||
// and resets when Breaking is incremented.
|
||||
public (int Breaking, int Feature) ApiVersion { get; }
|
||||
public bool Valid { get; }
|
||||
}
|
||||
|
||||
public delegate void ChangedItemHover( object? item );
|
||||
public delegate void ChangedItemClick( MouseButton button, object? item );
|
||||
public delegate void GameObjectRedrawn( IntPtr objectPtr, int objectTableIndex );
|
||||
public delegate void ModSettingChanged( ModSettingChange type, string collectionName, string modDirectory, bool inherited );
|
||||
|
||||
public delegate void CreatingCharacterBaseDelegate( IntPtr gameObject, ModCollection collection, IntPtr modelId, IntPtr customize,
|
||||
IntPtr equipData );
|
||||
|
||||
public delegate void CreatedCharacterBaseDelegate( IntPtr gameObject, ModCollection collection, IntPtr drawObject );
|
||||
public delegate void GameObjectResourceResolvedDelegate( IntPtr gameObject, string gamePath, string localPath );
|
||||
|
||||
public enum PenumbraApiEc
|
||||
{
|
||||
Success = 0,
|
||||
NothingChanged = 1,
|
||||
CollectionMissing = 2,
|
||||
ModMissing = 3,
|
||||
OptionGroupMissing = 4,
|
||||
OptionMissing = 5,
|
||||
|
||||
CharacterCollectionExists = 6,
|
||||
LowerPriority = 7,
|
||||
InvalidGamePath = 8,
|
||||
FileMissing = 9,
|
||||
InvalidManipulation = 10,
|
||||
InvalidArgument = 11,
|
||||
UnknownError = 255,
|
||||
}
|
||||
|
||||
public interface IPenumbraApi : IPenumbraApiBase
|
||||
{
|
||||
// Obtain the currently set mod directory from the configuration.
|
||||
public string GetModDirectory();
|
||||
|
||||
// Fired whenever a mod directory change is finished.
|
||||
// Gives the full path of the mod directory and whether Penumbra treats it as valid.
|
||||
public event Action< string, bool >? ModDirectoryChanged;
|
||||
|
||||
// Obtain the entire current penumbra configuration as a json encoded string.
|
||||
public string GetConfiguration();
|
||||
|
||||
// Triggered when the user hovers over a listed changed object in a mod tab.
|
||||
// Can be used to append tooltips.
|
||||
public event ChangedItemHover? ChangedItemTooltip;
|
||||
|
||||
// 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.
|
||||
public event Action< string >? PreSettingsPanelDraw;
|
||||
public event Action< string >? PostSettingsPanelDraw;
|
||||
|
||||
// Triggered when the user clicks a listed changed object in a mod tab.
|
||||
public event ChangedItemClick? ChangedItemClicked;
|
||||
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;
|
||||
|
||||
// Triggered after a character base was created if a corresponding gameObject could be found,
|
||||
// so you can apply flag changes after finishing.
|
||||
public event CreatedCharacterBaseDelegate? CreatedCharacterBase;
|
||||
|
||||
// Triggered whenever a resource is redirected by Penumbra for a specific, identified game object.
|
||||
// Does not trigger if the resource is not requested for a known game object.
|
||||
public event GameObjectResourceResolvedDelegate? GameObjectResourceResolved;
|
||||
|
||||
// Queue redrawing of all actors of the given name with the given RedrawType.
|
||||
public void RedrawObject( string name, RedrawType setting );
|
||||
|
||||
// Queue redrawing of the specific actor with the given RedrawType. Should only be used when the actor is sure to be valid.
|
||||
public void RedrawObject( GameObject gameObject, RedrawType setting );
|
||||
|
||||
// Queue redrawing of the actor with the given object table index, if it exists, with the given RedrawType.
|
||||
public void RedrawObject( int tableIndex, RedrawType setting );
|
||||
|
||||
// Queue redrawing of all currently available actors with the given RedrawType.
|
||||
public void RedrawAll( RedrawType setting );
|
||||
|
||||
// Resolve a given gamePath via Penumbra using the Default collection.
|
||||
// Returns the given gamePath if penumbra would not manipulate it.
|
||||
public string ResolveDefaultPath( string gamePath );
|
||||
|
||||
// Resolve a given gamePath via Penumbra using the Interface collection.
|
||||
// Returns the given gamePath if penumbra would not manipulate it.
|
||||
public string ResolveInterfacePath( string gamePath );
|
||||
|
||||
// Resolve a given gamePath via Penumbra using the character collection for the given name (if it exists) and the Forced collections.
|
||||
// Returns the given gamePath if penumbra would not manipulate it.
|
||||
public string ResolvePath( string gamePath, string characterName );
|
||||
|
||||
// Resolve a given gamePath via Penumbra using any applicable character collections for the current character.
|
||||
// Returns the given gamePath if penumbra would not manipulate it.
|
||||
public string ResolvePlayerPath( string gamePath );
|
||||
|
||||
// Reverse resolves a given modded local path into its replacement in form of all applicable game paths for given character collection.
|
||||
public string[] ReverseResolvePath( string moddedPath, string characterName );
|
||||
|
||||
// Reverse resolves a given modded local path into its replacement in form of all applicable game paths
|
||||
// using the collection applying to the player character.
|
||||
public string[] ReverseResolvePlayerPath( string moddedPath );
|
||||
|
||||
// Try to load a given gamePath with the resolved path from Penumbra.
|
||||
public T? GetFile< T >( string gamePath ) where T : FileResource;
|
||||
|
||||
// Try to load a given gamePath with the resolved path from Penumbra.
|
||||
public T? GetFile< T >( string gamePath, string characterName ) where T : FileResource;
|
||||
|
||||
// Gets a dictionary of effected items from a collection
|
||||
public IReadOnlyDictionary< string, object? > GetChangedItemsForCollection( string collectionName );
|
||||
|
||||
// Obtain a list of the names of all currently installed collections.
|
||||
public IList< string > GetCollections();
|
||||
|
||||
// Obtain the name of the currently selected collection.
|
||||
public string GetCurrentCollection();
|
||||
|
||||
// Obtain the name of the default collection.
|
||||
public string GetDefaultCollection();
|
||||
|
||||
// Obtain the name of the interface collection.
|
||||
public string GetInterfaceCollection();
|
||||
|
||||
// Obtain the name of the collection associated with characterName and whether it is configured or inferred from default.
|
||||
public (string, bool) GetCharacterCollection( string characterName );
|
||||
|
||||
// Obtain the game object associated with a given draw object and the name of the collection associated with this game object.
|
||||
public (IntPtr, string) GetDrawObjectInfo( IntPtr drawObject );
|
||||
|
||||
// Obtain the parent game object index for an unnamed cutscene actor by its index.
|
||||
public int GetCutsceneParentIndex( int actor );
|
||||
|
||||
// Obtain a list of all installed mods. The first string is their directory name, the second string is their mod name.
|
||||
public IList< (string, string) > GetModList();
|
||||
|
||||
// Try to reload an existing mod by its directory name or mod name.
|
||||
// Can return ModMissing or success.
|
||||
// Reload is the same as if triggered by button press and might delete the mod if it is not valid anymore.
|
||||
public PenumbraApiEc ReloadMod( string modDirectory, string modName );
|
||||
|
||||
// Try to add a new mod inside the mod root directory (modDirectory should only be the name, not the full name).
|
||||
// Returns FileMissing if the directory does not exist or success otherwise.
|
||||
// Note that success does only imply a successful call, not a successful mod load.
|
||||
public PenumbraApiEc AddMod( string modDirectory );
|
||||
|
||||
// Obtain a base64 encoded, zipped json-string with a prepended version-byte of the current manipulations
|
||||
// for the collection currently associated with the player.
|
||||
public string GetPlayerMetaManipulations();
|
||||
|
||||
// Obtain a base64 encoded, zipped json-string with a prepended version-byte of the current manipulations
|
||||
// for the given collection associated with the character name, or the default collection.
|
||||
public string GetMetaManipulations( string characterName );
|
||||
|
||||
|
||||
// ############## Mod Settings #################
|
||||
|
||||
// Obtain the potential settings of a mod specified by its directory name first or mod name second.
|
||||
// Returns null if the mod could not be found.
|
||||
public IDictionary< string, (IList< string >, SelectType) >? GetAvailableModSettings( string modDirectory, string modName );
|
||||
|
||||
// Obtain the enabled state, the priority, the settings of a mod specified by its directory name first or mod name second,
|
||||
// and whether these settings are inherited, or null if the collection does not set them at all.
|
||||
// If allowInheritance is false, only the collection itself will be checked.
|
||||
public (PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)?) GetCurrentModSettings( string collectionName,
|
||||
string modDirectory, string modName, bool allowInheritance );
|
||||
|
||||
// Try to set the inheritance state in the given collection of a mod specified by its directory name first or mod name second.
|
||||
// Returns Okay, NothingChanged, CollectionMissing or ModMissing.
|
||||
public PenumbraApiEc TryInheritMod( string collectionName, string modDirectory, string modName, bool inherit );
|
||||
|
||||
// Try to set the enabled state in the given collection of a mod specified by its directory name first or mod name second. Also removes inheritance.
|
||||
// Returns Okay, NothingChanged, CollectionMissing or ModMissing.
|
||||
public PenumbraApiEc TrySetMod( string collectionName, string modDirectory, string modName, bool enabled );
|
||||
|
||||
// Try to set the priority in the given collection of a mod specified by its directory name first or mod name second. Also removes inheritance.
|
||||
// Returns Okay, NothingChanged, CollectionMissing or ModMissing.
|
||||
public PenumbraApiEc TrySetModPriority( string collectionName, string modDirectory, string modName, int priority );
|
||||
|
||||
// Try to set a specific option group in the given collection of a mod specified by its directory name first or mod name second. Also removes inheritance.
|
||||
// If the group is a Single Selection group, options should be a single string, otherwise the array of enabled options.
|
||||
// Returns Okay, NothingChanged, CollectionMissing or ModMissing, OptionGroupMissing or SettingMissing.
|
||||
// If any setting can not be found, it will not change anything.
|
||||
public PenumbraApiEc TrySetModSetting( string collectionName, string modDirectory, string modName, string optionGroupName, string option );
|
||||
|
||||
public PenumbraApiEc TrySetModSettings( string collectionName, string modDirectory, string modName, string optionGroupName,
|
||||
IReadOnlyList< string > options );
|
||||
|
||||
// This event gets fired when any setting in any collection changes.
|
||||
public event ModSettingChanged? ModSettingChanged;
|
||||
|
||||
// Create a temporary collection without actual settings but with a cache.
|
||||
// If no character collection for this character exists or forceOverwriteCharacter is true,
|
||||
// associate this collection to a specific character.
|
||||
// Can return Okay, CharacterCollectionExists or NothingChanged, as well as the name of the new temporary collection on success.
|
||||
public (PenumbraApiEc, string) CreateTemporaryCollection( string tag, string character, bool forceOverwriteCharacter );
|
||||
|
||||
// Remove the temporary collection associated with characterName if it exists.
|
||||
// Can return Okay or NothingChanged.
|
||||
public PenumbraApiEc RemoveTemporaryCollection( string characterName );
|
||||
|
||||
// Set a temporary mod with the given paths, manipulations and priority and the name tag to all collections.
|
||||
// Can return Okay, InvalidGamePath, or InvalidManipulation.
|
||||
public PenumbraApiEc AddTemporaryModAll( string tag, Dictionary< string, string > paths, string manipString, int priority );
|
||||
|
||||
// Set a temporary mod with the given paths, manipulations and priority and the name tag to the collection with the given name, which can be temporary.
|
||||
// Can return Okay, MissingCollection InvalidGamePath, or InvalidManipulation.
|
||||
public PenumbraApiEc AddTemporaryMod( string tag, string collectionName, Dictionary< string, string > paths, string manipString,
|
||||
int priority );
|
||||
|
||||
// Remove the temporary mod with the given tag and priority from the temporary mods applying to all collections, if it exists.
|
||||
// Can return Okay or NothingDone.
|
||||
public PenumbraApiEc RemoveTemporaryModAll( string tag, int priority );
|
||||
|
||||
// Remove the temporary mod with the given tag and priority from the temporary mods applying to the collection of the given name, which can be temporary.
|
||||
// Can return Okay or NothingDone.
|
||||
public PenumbraApiEc RemoveTemporaryMod( string tag, string collectionName, int priority );
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -4,7 +4,6 @@ using Newtonsoft.Json;
|
|||
using OtterGui;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.Resolver;
|
||||
using Penumbra.Interop.Structs;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
|
@ -15,6 +14,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ 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 >, GroupType) >? GetAvailableModSettings( string modDirectory, string modName )
|
||||
{
|
||||
CheckInitialized();
|
||||
return Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod )
|
||||
|
|
@ -330,6 +330,56 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return PenumbraApiEc.Success;
|
||||
}
|
||||
|
||||
public PenumbraApiEc DeleteMod( string modDirectory, string modName )
|
||||
{
|
||||
CheckInitialized();
|
||||
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod ) )
|
||||
return PenumbraApiEc.NothingChanged;
|
||||
|
||||
Penumbra.ModManager.DeleteMod( mod.Index );
|
||||
return PenumbraApiEc.Success;
|
||||
}
|
||||
|
||||
|
||||
public (PenumbraApiEc, string, bool) GetModPath( string modDirectory, string modName )
|
||||
{
|
||||
CheckInitialized();
|
||||
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod )
|
||||
|| !_penumbra!.ModFileSystem.FindLeaf( mod, out var leaf ) )
|
||||
{
|
||||
return ( PenumbraApiEc.ModMissing, string.Empty, false );
|
||||
}
|
||||
|
||||
var fullPath = leaf.FullName();
|
||||
|
||||
return ( PenumbraApiEc.Success, fullPath, !ModFileSystem.ModHasDefaultPath( mod, fullPath ) );
|
||||
}
|
||||
|
||||
public PenumbraApiEc SetModPath( string modDirectory, string modName, string newPath )
|
||||
{
|
||||
CheckInitialized();
|
||||
if( newPath.Length == 0 )
|
||||
{
|
||||
return PenumbraApiEc.InvalidArgument;
|
||||
}
|
||||
|
||||
if( !Penumbra.ModManager.TryGetMod( modDirectory, modName, out var mod )
|
||||
|| !_penumbra!.ModFileSystem.FindLeaf( mod, out var leaf ) )
|
||||
{
|
||||
return PenumbraApiEc.ModMissing;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_penumbra.ModFileSystem.RenameAndMove( leaf, newPath );
|
||||
return PenumbraApiEc.Success;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return PenumbraApiEc.PathRenameFailed;
|
||||
}
|
||||
}
|
||||
|
||||
public PenumbraApiEc TryInheritMod( string collectionName, string modDirectory, string modName, bool inherit )
|
||||
{
|
||||
CheckInitialized();
|
||||
|
|
@ -405,7 +455,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
return PenumbraApiEc.OptionMissing;
|
||||
}
|
||||
|
||||
var setting = mod.Groups[ groupIdx ].Type == SelectType.Multi ? 1u << optionIdx : ( uint )optionIdx;
|
||||
var setting = mod.Groups[ groupIdx ].Type == GroupType.Multi ? 1u << optionIdx : ( uint )optionIdx;
|
||||
|
||||
return collection.SetModSetting( mod.Index, groupIdx, setting ) ? PenumbraApiEc.Success : PenumbraApiEc.NothingChanged;
|
||||
}
|
||||
|
|
@ -433,7 +483,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
|
|||
var group = mod.Groups[ groupIdx ];
|
||||
|
||||
uint setting = 0;
|
||||
if( group.Type == SelectType.Single )
|
||||
if( group.Type == GroupType.Single )
|
||||
{
|
||||
var optionIdx = optionNames.Count == 0 ? -1 : group.IndexOf( o => o.Name == optionNames[ ^1 ] );
|
||||
if( optionIdx < 0 )
|
||||
|
|
|
|||
|
|
@ -1,878 +0,0 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Plugin;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
public partial class PenumbraIpc : IDisposable
|
||||
{
|
||||
internal readonly IPenumbraApi Api;
|
||||
internal readonly IpcTester Tester;
|
||||
|
||||
public PenumbraIpc( DalamudPluginInterface pi, IPenumbraApi api )
|
||||
{
|
||||
Api = api;
|
||||
Tester = new IpcTester( pi, this );
|
||||
InitializeGeneralProviders( pi );
|
||||
InitializeResolveProviders( pi );
|
||||
InitializeRedrawProviders( pi );
|
||||
InitializeChangedItemProviders( pi );
|
||||
InitializeDataProviders( pi );
|
||||
InitializeSettingProviders( pi );
|
||||
InitializeTempProviders( pi );
|
||||
ProviderInitialized?.SendMessage();
|
||||
InvokeModDirectoryChanged( Penumbra.ModManager.BasePath.FullName, Penumbra.ModManager.Valid );
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DisposeDataProviders();
|
||||
DisposeChangedItemProviders();
|
||||
DisposeRedrawProviders();
|
||||
DisposeResolveProviders();
|
||||
DisposeGeneralProviders();
|
||||
DisposeSettingProviders();
|
||||
DisposeTempProviders();
|
||||
ProviderDisposed?.SendMessage();
|
||||
Tester.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderInitialized = "Penumbra.Initialized";
|
||||
public const string LabelProviderDisposed = "Penumbra.Disposed";
|
||||
public const string LabelProviderApiVersion = "Penumbra.ApiVersion";
|
||||
public const string LabelProviderApiVersions = "Penumbra.ApiVersions";
|
||||
public const string LabelProviderGetModDirectory = "Penumbra.GetModDirectory";
|
||||
public const string LabelProviderModDirectoryChanged = "Penumbra.ModDirectoryChanged";
|
||||
public const string LabelProviderGetConfiguration = "Penumbra.GetConfiguration";
|
||||
public const string LabelProviderPreSettingsDraw = "Penumbra.PreSettingsDraw";
|
||||
public const string LabelProviderPostSettingsDraw = "Penumbra.PostSettingsDraw";
|
||||
|
||||
internal ICallGateProvider< object? >? ProviderInitialized;
|
||||
internal ICallGateProvider< object? >? ProviderDisposed;
|
||||
internal ICallGateProvider< int >? ProviderApiVersion;
|
||||
internal ICallGateProvider< (int Breaking, int Features) >? ProviderApiVersions;
|
||||
internal ICallGateProvider< string >? ProviderGetModDirectory;
|
||||
internal ICallGateProvider< string, bool, object? >? ProviderModDirectoryChanged;
|
||||
internal ICallGateProvider< string >? ProviderGetConfiguration;
|
||||
internal ICallGateProvider< string, object? >? ProviderPreSettingsDraw;
|
||||
internal ICallGateProvider< string, object? >? ProviderPostSettingsDraw;
|
||||
|
||||
private void InitializeGeneralProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProviderInitialized = pi.GetIpcProvider< object? >( LabelProviderInitialized );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderInitialized}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderDisposed = pi.GetIpcProvider< object? >( LabelProviderDisposed );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderDisposed}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderApiVersion = pi.GetIpcProvider< int >( LabelProviderApiVersion );
|
||||
ProviderApiVersion.RegisterFunc( () =>
|
||||
{
|
||||
Penumbra.Log.Warning( $"{LabelProviderApiVersion} is outdated. Please use {LabelProviderApiVersions} instead." );
|
||||
return Api.ApiVersion.Breaking;
|
||||
} );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderApiVersion}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderApiVersions = pi.GetIpcProvider< ( int, int ) >( LabelProviderApiVersions );
|
||||
ProviderApiVersions.RegisterFunc( () => Api.ApiVersion );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderApiVersions}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetModDirectory = pi.GetIpcProvider< string >( LabelProviderGetModDirectory );
|
||||
ProviderGetModDirectory.RegisterFunc( Api.GetModDirectory );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetModDirectory}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderModDirectoryChanged = pi.GetIpcProvider< string, bool, object? >( LabelProviderModDirectoryChanged );
|
||||
Api.ModDirectoryChanged += InvokeModDirectoryChanged;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderModDirectoryChanged}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetConfiguration = pi.GetIpcProvider< string >( LabelProviderGetConfiguration );
|
||||
ProviderGetConfiguration.RegisterFunc( Api.GetConfiguration );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetConfiguration}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderPreSettingsDraw = pi.GetIpcProvider< string, object? >( LabelProviderPreSettingsDraw );
|
||||
Api.PreSettingsPanelDraw += InvokeSettingsPreDraw;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderPreSettingsDraw}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderPostSettingsDraw = pi.GetIpcProvider< string, object? >( LabelProviderPostSettingsDraw );
|
||||
Api.PostSettingsPanelDraw += InvokeSettingsPostDraw;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderPostSettingsDraw}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeGeneralProviders()
|
||||
{
|
||||
ProviderGetConfiguration?.UnregisterFunc();
|
||||
ProviderGetModDirectory?.UnregisterFunc();
|
||||
ProviderApiVersion?.UnregisterFunc();
|
||||
ProviderApiVersions?.UnregisterFunc();
|
||||
Api.PreSettingsPanelDraw -= InvokeSettingsPreDraw;
|
||||
Api.PostSettingsPanelDraw -= InvokeSettingsPostDraw;
|
||||
Api.ModDirectoryChanged -= InvokeModDirectoryChanged;
|
||||
}
|
||||
|
||||
private void InvokeSettingsPreDraw( string modDirectory )
|
||||
=> ProviderPreSettingsDraw!.SendMessage( modDirectory );
|
||||
|
||||
private void InvokeSettingsPostDraw( string modDirectory )
|
||||
=> ProviderPostSettingsDraw!.SendMessage( modDirectory );
|
||||
|
||||
private void InvokeModDirectoryChanged( string modDirectory, bool valid )
|
||||
=> ProviderModDirectoryChanged?.SendMessage( modDirectory, valid );
|
||||
}
|
||||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderRedrawObject = "Penumbra.RedrawObject";
|
||||
public const string LabelProviderRedrawName = "Penumbra.RedrawObjectByName";
|
||||
public const string LabelProviderRedrawIndex = "Penumbra.RedrawObjectByIndex";
|
||||
public const string LabelProviderRedrawAll = "Penumbra.RedrawAll";
|
||||
public const string LabelProviderGameObjectRedrawn = "Penumbra.GameObjectRedrawn";
|
||||
|
||||
internal ICallGateProvider< string, int, object? >? ProviderRedrawName;
|
||||
internal ICallGateProvider< GameObject, int, object? >? ProviderRedrawObject;
|
||||
internal ICallGateProvider< int, int, object? >? ProviderRedrawIndex;
|
||||
internal ICallGateProvider< int, object? >? ProviderRedrawAll;
|
||||
internal ICallGateProvider< IntPtr, int, object? >? ProviderGameObjectRedrawn;
|
||||
|
||||
private static RedrawType CheckRedrawType( int value )
|
||||
{
|
||||
var type = ( RedrawType )value;
|
||||
if( Enum.IsDefined( type ) )
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
throw new Exception( "The integer provided for a Redraw Function was not a valid RedrawType." );
|
||||
}
|
||||
|
||||
private void InitializeRedrawProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProviderRedrawName = pi.GetIpcProvider< string, int, object? >( LabelProviderRedrawName );
|
||||
ProviderRedrawName.RegisterAction( ( s, i ) => Api.RedrawObject( s, CheckRedrawType( i ) ) );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderRedrawObject = pi.GetIpcProvider< GameObject, int, object? >( LabelProviderRedrawObject );
|
||||
ProviderRedrawObject.RegisterAction( ( s, i ) => Api.RedrawObject( s, CheckRedrawType( i ) ) );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawObject}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderRedrawIndex = pi.GetIpcProvider< int, int, object? >( LabelProviderRedrawIndex );
|
||||
ProviderRedrawIndex.RegisterAction( ( idx, i ) => Api.RedrawObject( idx, CheckRedrawType( i ) ) );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderRedrawAll = pi.GetIpcProvider< int, object? >( LabelProviderRedrawAll );
|
||||
ProviderRedrawAll.RegisterAction( i => Api.RedrawAll( CheckRedrawType( i ) ) );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRedrawAll}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGameObjectRedrawn = pi.GetIpcProvider< IntPtr, int, object? >( LabelProviderGameObjectRedrawn );
|
||||
Api.GameObjectRedrawn += OnGameObjectRedrawn;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGameObjectRedrawn}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGameObjectRedrawn( IntPtr objectAddress, int objectTableIndex )
|
||||
=> ProviderGameObjectRedrawn?.SendMessage( objectAddress, objectTableIndex );
|
||||
|
||||
private void DisposeRedrawProviders()
|
||||
{
|
||||
ProviderRedrawName?.UnregisterAction();
|
||||
ProviderRedrawObject?.UnregisterAction();
|
||||
ProviderRedrawIndex?.UnregisterAction();
|
||||
ProviderRedrawAll?.UnregisterAction();
|
||||
Api.GameObjectRedrawn -= OnGameObjectRedrawn;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderResolveDefault = "Penumbra.ResolveDefaultPath";
|
||||
public const string LabelProviderResolveInterface = "Penumbra.ResolveInterfacePath";
|
||||
public const string LabelProviderResolveCharacter = "Penumbra.ResolveCharacterPath";
|
||||
public const string LabelProviderResolvePlayer = "Penumbra.ResolvePlayerPath";
|
||||
public const string LabelProviderGetDrawObjectInfo = "Penumbra.GetDrawObjectInfo";
|
||||
public const string LabelProviderGetCutsceneParentIndex = "Penumbra.GetCutsceneParentIndex";
|
||||
public const string LabelProviderReverseResolvePath = "Penumbra.ReverseResolvePath";
|
||||
public const string LabelProviderReverseResolvePlayerPath = "Penumbra.ReverseResolvePlayerPath";
|
||||
public const string LabelProviderCreatingCharacterBase = "Penumbra.CreatingCharacterBase";
|
||||
public const string LabelProviderCreatedCharacterBase = "Penumbra.CreatedCharacterBase";
|
||||
public const string LabelProviderGameObjectResourcePathResolved = "Penumbra.GameObjectResourcePathResolved";
|
||||
|
||||
internal ICallGateProvider< string, string >? ProviderResolveDefault;
|
||||
internal ICallGateProvider< string, string >? ProviderResolveInterface;
|
||||
internal ICallGateProvider< string, string, string >? ProviderResolveCharacter;
|
||||
internal ICallGateProvider< string, string >? ProviderResolvePlayer;
|
||||
internal ICallGateProvider< IntPtr, (IntPtr, string) >? ProviderGetDrawObjectInfo;
|
||||
internal ICallGateProvider< int, int >? ProviderGetCutsceneParentIndex;
|
||||
internal ICallGateProvider< string, string, string[] >? ProviderReverseResolvePath;
|
||||
internal ICallGateProvider< string, string[] >? ProviderReverseResolvePathPlayer;
|
||||
internal ICallGateProvider< IntPtr, string, IntPtr, IntPtr, IntPtr, object? >? ProviderCreatingCharacterBase;
|
||||
internal ICallGateProvider< IntPtr, string, IntPtr, object? >? ProviderCreatedCharacterBase;
|
||||
internal ICallGateProvider< IntPtr, string, string, object? >? ProviderGameObjectResourcePathResolved;
|
||||
|
||||
private void InitializeResolveProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProviderResolveDefault = pi.GetIpcProvider< string, string >( LabelProviderResolveDefault );
|
||||
ProviderResolveDefault.RegisterFunc( Api.ResolveDefaultPath );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderResolveDefault}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderResolveInterface = pi.GetIpcProvider< string, string >( LabelProviderResolveInterface );
|
||||
ProviderResolveInterface.RegisterFunc( Api.ResolveInterfacePath );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderResolveInterface}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderResolveCharacter = pi.GetIpcProvider< string, string, string >( LabelProviderResolveCharacter );
|
||||
ProviderResolveCharacter.RegisterFunc( Api.ResolvePath );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderResolveCharacter}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderResolvePlayer = pi.GetIpcProvider< string, string >( LabelProviderResolvePlayer );
|
||||
ProviderResolvePlayer.RegisterFunc( Api.ResolvePlayerPath );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderResolveCharacter}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetDrawObjectInfo = pi.GetIpcProvider< IntPtr, (IntPtr, string) >( LabelProviderGetDrawObjectInfo );
|
||||
ProviderGetDrawObjectInfo.RegisterFunc( Api.GetDrawObjectInfo );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetDrawObjectInfo}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetCutsceneParentIndex = pi.GetIpcProvider< int, int >( LabelProviderGetCutsceneParentIndex );
|
||||
ProviderGetCutsceneParentIndex.RegisterFunc( Api.GetCutsceneParentIndex );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetCutsceneParentIndex}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderReverseResolvePath = pi.GetIpcProvider< string, string, string[] >( LabelProviderReverseResolvePath );
|
||||
ProviderReverseResolvePath.RegisterFunc( Api.ReverseResolvePath );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderReverseResolvePath}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderReverseResolvePathPlayer = pi.GetIpcProvider< string, string[] >( LabelProviderReverseResolvePlayerPath );
|
||||
ProviderReverseResolvePathPlayer.RegisterFunc( Api.ReverseResolvePlayerPath );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderReverseResolvePlayerPath}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderCreatingCharacterBase =
|
||||
pi.GetIpcProvider< IntPtr, string, IntPtr, IntPtr, IntPtr, object? >( LabelProviderCreatingCharacterBase );
|
||||
Api.CreatingCharacterBase += CreatingCharacterBaseEvent;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCreatingCharacterBase}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderCreatedCharacterBase =
|
||||
pi.GetIpcProvider< IntPtr, string, IntPtr, object? >( LabelProviderCreatedCharacterBase );
|
||||
Api.CreatedCharacterBase += CreatedCharacterBaseEvent;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCreatedCharacterBase}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGameObjectResourcePathResolved =
|
||||
pi.GetIpcProvider< IntPtr, string, string, object? >( LabelProviderGameObjectResourcePathResolved );
|
||||
Api.GameObjectResourceResolved += GameObjectResourceResolvedEvent;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGameObjectResourcePathResolved}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void GameObjectResourceResolvedEvent( IntPtr gameObject, string gamePath, string localPath )
|
||||
{
|
||||
ProviderGameObjectResourcePathResolved?.SendMessage( gameObject, gamePath, localPath );
|
||||
}
|
||||
|
||||
private void DisposeResolveProviders()
|
||||
{
|
||||
ProviderGetDrawObjectInfo?.UnregisterFunc();
|
||||
ProviderGetCutsceneParentIndex?.UnregisterFunc();
|
||||
ProviderResolveDefault?.UnregisterFunc();
|
||||
ProviderResolveInterface?.UnregisterFunc();
|
||||
ProviderResolveCharacter?.UnregisterFunc();
|
||||
ProviderReverseResolvePath?.UnregisterFunc();
|
||||
ProviderReverseResolvePathPlayer?.UnregisterFunc();
|
||||
Api.CreatingCharacterBase -= CreatingCharacterBaseEvent;
|
||||
Api.CreatedCharacterBase -= CreatedCharacterBaseEvent;
|
||||
Api.GameObjectResourceResolved -= GameObjectResourceResolvedEvent;
|
||||
}
|
||||
|
||||
private void CreatingCharacterBaseEvent( IntPtr gameObject, ModCollection collection, IntPtr modelId, IntPtr customize, IntPtr equipData )
|
||||
{
|
||||
ProviderCreatingCharacterBase?.SendMessage( gameObject, collection.Name, modelId, customize, equipData );
|
||||
}
|
||||
|
||||
private void CreatedCharacterBaseEvent( IntPtr gameObject, ModCollection collection, IntPtr drawObject )
|
||||
{
|
||||
ProviderCreatedCharacterBase?.SendMessage( gameObject, collection.Name, drawObject );
|
||||
}
|
||||
}
|
||||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderChangedItemTooltip = "Penumbra.ChangedItemTooltip";
|
||||
public const string LabelProviderChangedItemClick = "Penumbra.ChangedItemClick";
|
||||
public const string LabelProviderGetChangedItems = "Penumbra.GetChangedItems";
|
||||
|
||||
internal ICallGateProvider< ChangedItemType, uint, object? >? ProviderChangedItemTooltip;
|
||||
internal ICallGateProvider< MouseButton, ChangedItemType, uint, object? >? ProviderChangedItemClick;
|
||||
internal ICallGateProvider< string, IReadOnlyDictionary< string, object? > >? ProviderGetChangedItems;
|
||||
|
||||
private void OnClick( MouseButton click, object? item )
|
||||
{
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId( item );
|
||||
ProviderChangedItemClick?.SendMessage( click, type, id );
|
||||
}
|
||||
|
||||
private void OnTooltip( object? item )
|
||||
{
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId( item );
|
||||
ProviderChangedItemTooltip?.SendMessage( type, id );
|
||||
}
|
||||
|
||||
private void InitializeChangedItemProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProviderChangedItemTooltip = pi.GetIpcProvider< ChangedItemType, uint, object? >( LabelProviderChangedItemTooltip );
|
||||
Api.ChangedItemTooltip += OnTooltip;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemTooltip}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderChangedItemClick = pi.GetIpcProvider< MouseButton, ChangedItemType, uint, object? >( LabelProviderChangedItemClick );
|
||||
Api.ChangedItemClicked += OnClick;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetChangedItems = pi.GetIpcProvider< string, IReadOnlyDictionary< string, object? > >( LabelProviderGetChangedItems );
|
||||
ProviderGetChangedItems.RegisterFunc( Api.GetChangedItemsForCollection );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeChangedItemProviders()
|
||||
{
|
||||
ProviderGetChangedItems?.UnregisterFunc();
|
||||
Api.ChangedItemClicked -= OnClick;
|
||||
Api.ChangedItemTooltip -= OnTooltip;
|
||||
}
|
||||
}
|
||||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderGetMods = "Penumbra.GetMods";
|
||||
public const string LabelProviderGetCollections = "Penumbra.GetCollections";
|
||||
public const string LabelProviderCurrentCollectionName = "Penumbra.GetCurrentCollectionName";
|
||||
public const string LabelProviderDefaultCollectionName = "Penumbra.GetDefaultCollectionName";
|
||||
public const string LabelProviderInterfaceCollectionName = "Penumbra.GetInterfaceCollectionName";
|
||||
public const string LabelProviderCharacterCollectionName = "Penumbra.GetCharacterCollectionName";
|
||||
public const string LabelProviderGetPlayerMetaManipulations = "Penumbra.GetPlayerMetaManipulations";
|
||||
public const string LabelProviderGetMetaManipulations = "Penumbra.GetMetaManipulations";
|
||||
|
||||
internal ICallGateProvider< IList< (string, string) > >? ProviderGetMods;
|
||||
internal ICallGateProvider< IList< string > >? ProviderGetCollections;
|
||||
internal ICallGateProvider< string >? ProviderCurrentCollectionName;
|
||||
internal ICallGateProvider< string >? ProviderDefaultCollectionName;
|
||||
internal ICallGateProvider< string >? ProviderInterfaceCollectionName;
|
||||
internal ICallGateProvider< string, (string, bool) >? ProviderCharacterCollectionName;
|
||||
internal ICallGateProvider< string >? ProviderGetPlayerMetaManipulations;
|
||||
internal ICallGateProvider< string, string >? ProviderGetMetaManipulations;
|
||||
|
||||
private void InitializeDataProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProviderGetMods = pi.GetIpcProvider< IList< (string, string) > >( LabelProviderGetMods );
|
||||
ProviderGetMods.RegisterFunc( Api.GetModList );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetMods}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetCollections = pi.GetIpcProvider< IList< string > >( LabelProviderGetCollections );
|
||||
ProviderGetCollections.RegisterFunc( Api.GetCollections );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetCollections}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderCurrentCollectionName = pi.GetIpcProvider< string >( LabelProviderCurrentCollectionName );
|
||||
ProviderCurrentCollectionName.RegisterFunc( Api.GetCurrentCollection );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCurrentCollectionName}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderDefaultCollectionName = pi.GetIpcProvider< string >( LabelProviderDefaultCollectionName );
|
||||
ProviderDefaultCollectionName.RegisterFunc( Api.GetDefaultCollection );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderDefaultCollectionName}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderInterfaceCollectionName = pi.GetIpcProvider<string>( LabelProviderInterfaceCollectionName );
|
||||
ProviderInterfaceCollectionName.RegisterFunc( Api.GetInterfaceCollection );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderInterfaceCollectionName}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderCharacterCollectionName = pi.GetIpcProvider< string, (string, bool) >( LabelProviderCharacterCollectionName );
|
||||
ProviderCharacterCollectionName.RegisterFunc( Api.GetCharacterCollection );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCharacterCollectionName}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetPlayerMetaManipulations = pi.GetIpcProvider< string >( LabelProviderGetPlayerMetaManipulations );
|
||||
ProviderGetPlayerMetaManipulations.RegisterFunc( Api.GetPlayerMetaManipulations );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetPlayerMetaManipulations}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetMetaManipulations = pi.GetIpcProvider< string, string >( LabelProviderGetMetaManipulations );
|
||||
ProviderGetMetaManipulations.RegisterFunc( Api.GetMetaManipulations );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetMetaManipulations}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeDataProviders()
|
||||
{
|
||||
ProviderGetMods?.UnregisterFunc();
|
||||
ProviderGetCollections?.UnregisterFunc();
|
||||
ProviderCurrentCollectionName?.UnregisterFunc();
|
||||
ProviderDefaultCollectionName?.UnregisterFunc();
|
||||
ProviderInterfaceCollectionName?.UnregisterFunc();
|
||||
ProviderCharacterCollectionName?.UnregisterFunc();
|
||||
ProviderGetMetaManipulations?.UnregisterFunc();
|
||||
}
|
||||
}
|
||||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderGetAvailableModSettings = "Penumbra.GetAvailableModSettings";
|
||||
public const string LabelProviderReloadMod = "Penumbra.ReloadMod";
|
||||
public const string LabelProviderAddMod = "Penumbra.AddMod";
|
||||
public const string LabelProviderGetCurrentModSettings = "Penumbra.GetCurrentModSettings";
|
||||
public const string LabelProviderTryInheritMod = "Penumbra.TryInheritMod";
|
||||
public const string LabelProviderTrySetMod = "Penumbra.TrySetMod";
|
||||
public const string LabelProviderTrySetModPriority = "Penumbra.TrySetModPriority";
|
||||
public const string LabelProviderTrySetModSetting = "Penumbra.TrySetModSetting";
|
||||
public const string LabelProviderTrySetModSettings = "Penumbra.TrySetModSettings";
|
||||
public const string LabelProviderModSettingChanged = "Penumbra.ModSettingChanged";
|
||||
|
||||
internal ICallGateProvider< ModSettingChange, string, string, bool, object? >? ProviderModSettingChanged;
|
||||
|
||||
internal ICallGateProvider< string, string, IDictionary< string, (IList< string >, Mods.SelectType) >? >? ProviderGetAvailableModSettings;
|
||||
internal ICallGateProvider< string, string, PenumbraApiEc >? ProviderReloadMod;
|
||||
internal ICallGateProvider< string, PenumbraApiEc >? ProviderAddMod;
|
||||
|
||||
internal ICallGateProvider< string, string, string, bool, (PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)?) >?
|
||||
ProviderGetCurrentModSettings;
|
||||
|
||||
internal ICallGateProvider< string, string, string, bool, PenumbraApiEc >? ProviderTryInheritMod;
|
||||
internal ICallGateProvider< string, string, string, bool, PenumbraApiEc >? ProviderTrySetMod;
|
||||
internal ICallGateProvider< string, string, string, int, PenumbraApiEc >? ProviderTrySetModPriority;
|
||||
internal ICallGateProvider< string, string, string, string, string, PenumbraApiEc >? ProviderTrySetModSetting;
|
||||
internal ICallGateProvider< string, string, string, string, IReadOnlyList< string >, PenumbraApiEc >? ProviderTrySetModSettings;
|
||||
|
||||
private void InitializeSettingProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProviderModSettingChanged = pi.GetIpcProvider< ModSettingChange, string, string, bool, object? >( LabelProviderModSettingChanged );
|
||||
Api.ModSettingChanged += InvokeModSettingChanged;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderModSettingChanged}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetAvailableModSettings =
|
||||
pi.GetIpcProvider< string, string, IDictionary< string, (IList< string >, Mods.SelectType) >? >(
|
||||
LabelProviderGetAvailableModSettings );
|
||||
ProviderGetAvailableModSettings.RegisterFunc( Api.GetAvailableModSettings );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetAvailableModSettings}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderReloadMod = pi.GetIpcProvider< string, string, PenumbraApiEc >( LabelProviderReloadMod );
|
||||
ProviderReloadMod.RegisterFunc( Api.ReloadMod );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderReloadMod}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderAddMod = pi.GetIpcProvider< string, PenumbraApiEc >( LabelProviderAddMod );
|
||||
ProviderAddMod.RegisterFunc( Api.AddMod );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderGetCurrentModSettings =
|
||||
pi.GetIpcProvider< string, string, string, bool, (PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)?) >(
|
||||
LabelProviderGetCurrentModSettings );
|
||||
ProviderGetCurrentModSettings.RegisterFunc( Api.GetCurrentModSettings );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderGetCurrentModSettings}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderTryInheritMod = pi.GetIpcProvider< string, string, string, bool, PenumbraApiEc >( LabelProviderTryInheritMod );
|
||||
ProviderTryInheritMod.RegisterFunc( Api.TryInheritMod );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTryInheritMod}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderTrySetMod = pi.GetIpcProvider< string, string, string, bool, PenumbraApiEc >( LabelProviderTrySetMod );
|
||||
ProviderTrySetMod.RegisterFunc( Api.TrySetMod );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetMod}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderTrySetModPriority = pi.GetIpcProvider< string, string, string, int, PenumbraApiEc >( LabelProviderTrySetModPriority );
|
||||
ProviderTrySetModPriority.RegisterFunc( Api.TrySetModPriority );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetModPriority}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderTrySetModSetting =
|
||||
pi.GetIpcProvider< string, string, string, string, string, PenumbraApiEc >( LabelProviderTrySetModSetting );
|
||||
ProviderTrySetModSetting.RegisterFunc( Api.TrySetModSetting );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetModSetting}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderTrySetModSettings =
|
||||
pi.GetIpcProvider< string, string, string, string, IReadOnlyList< string >, PenumbraApiEc >( LabelProviderTrySetModSettings );
|
||||
ProviderTrySetModSettings.RegisterFunc( Api.TrySetModSettings );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderTrySetModSettings}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeSettingProviders()
|
||||
{
|
||||
Api.ModSettingChanged -= InvokeModSettingChanged;
|
||||
ProviderGetAvailableModSettings?.UnregisterFunc();
|
||||
ProviderReloadMod?.UnregisterFunc();
|
||||
ProviderAddMod?.UnregisterFunc();
|
||||
ProviderGetCurrentModSettings?.UnregisterFunc();
|
||||
ProviderTryInheritMod?.UnregisterFunc();
|
||||
ProviderTrySetMod?.UnregisterFunc();
|
||||
ProviderTrySetModPriority?.UnregisterFunc();
|
||||
ProviderTrySetModSetting?.UnregisterFunc();
|
||||
ProviderTrySetModSettings?.UnregisterFunc();
|
||||
}
|
||||
|
||||
private void InvokeModSettingChanged( ModSettingChange type, string collection, string mod, bool inherited )
|
||||
=> ProviderModSettingChanged?.SendMessage( type, collection, mod, inherited );
|
||||
}
|
||||
|
||||
public partial class PenumbraIpc
|
||||
{
|
||||
public const string LabelProviderCreateTemporaryCollection = "Penumbra.CreateTemporaryCollection";
|
||||
public const string LabelProviderRemoveTemporaryCollection = "Penumbra.RemoveTemporaryCollection";
|
||||
public const string LabelProviderAddTemporaryModAll = "Penumbra.AddTemporaryModAll";
|
||||
public const string LabelProviderAddTemporaryMod = "Penumbra.AddTemporaryMod";
|
||||
public const string LabelProviderRemoveTemporaryModAll = "Penumbra.RemoveTemporaryModAll";
|
||||
public const string LabelProviderRemoveTemporaryMod = "Penumbra.RemoveTemporaryMod";
|
||||
|
||||
internal ICallGateProvider< string, string, bool, (PenumbraApiEc, string) >? ProviderCreateTemporaryCollection;
|
||||
internal ICallGateProvider< string, PenumbraApiEc >? ProviderRemoveTemporaryCollection;
|
||||
|
||||
internal ICallGateProvider< string, Dictionary< string, string >, string, int, PenumbraApiEc >?
|
||||
ProviderAddTemporaryModAll;
|
||||
|
||||
internal ICallGateProvider< string, string, Dictionary< string, string >, string, int, PenumbraApiEc >?
|
||||
ProviderAddTemporaryMod;
|
||||
|
||||
internal ICallGateProvider< string, int, PenumbraApiEc >? ProviderRemoveTemporaryModAll;
|
||||
internal ICallGateProvider< string, string, int, PenumbraApiEc >? ProviderRemoveTemporaryMod;
|
||||
|
||||
private void InitializeTempProviders( DalamudPluginInterface pi )
|
||||
{
|
||||
try
|
||||
{
|
||||
ProviderCreateTemporaryCollection =
|
||||
pi.GetIpcProvider< string, string, bool, (PenumbraApiEc, string) >( LabelProviderCreateTemporaryCollection );
|
||||
ProviderCreateTemporaryCollection.RegisterFunc( Api.CreateTemporaryCollection );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderCreateTemporaryCollection}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderRemoveTemporaryCollection =
|
||||
pi.GetIpcProvider< string, PenumbraApiEc >( LabelProviderRemoveTemporaryCollection );
|
||||
ProviderRemoveTemporaryCollection.RegisterFunc( Api.RemoveTemporaryCollection );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryCollection}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderAddTemporaryModAll =
|
||||
pi.GetIpcProvider< string, Dictionary< string, string >, string, int, PenumbraApiEc >(
|
||||
LabelProviderAddTemporaryModAll );
|
||||
ProviderAddTemporaryModAll.RegisterFunc( Api.AddTemporaryModAll );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderAddTemporaryModAll}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderAddTemporaryMod =
|
||||
pi.GetIpcProvider< string, string, Dictionary< string, string >, string, int, PenumbraApiEc >(
|
||||
LabelProviderAddTemporaryMod );
|
||||
ProviderAddTemporaryMod.RegisterFunc( Api.AddTemporaryMod );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderAddTemporaryMod}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderRemoveTemporaryModAll = pi.GetIpcProvider< string, int, PenumbraApiEc >( LabelProviderRemoveTemporaryModAll );
|
||||
ProviderRemoveTemporaryModAll.RegisterFunc( Api.RemoveTemporaryModAll );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryModAll}:\n{e}" );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ProviderRemoveTemporaryMod = pi.GetIpcProvider< string, string, int, PenumbraApiEc >( LabelProviderRemoveTemporaryMod );
|
||||
ProviderRemoveTemporaryMod.RegisterFunc( Api.RemoveTemporaryMod );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Error registering IPC provider for {LabelProviderRemoveTemporaryMod}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
private void DisposeTempProviders()
|
||||
{
|
||||
ProviderCreateTemporaryCollection?.UnregisterFunc();
|
||||
ProviderRemoveTemporaryCollection?.UnregisterFunc();
|
||||
ProviderAddTemporaryModAll?.UnregisterFunc();
|
||||
ProviderAddTemporaryMod?.UnregisterFunc();
|
||||
ProviderRemoveTemporaryModAll?.UnregisterFunc();
|
||||
ProviderRemoveTemporaryMod?.UnregisterFunc();
|
||||
}
|
||||
}
|
||||
307
Penumbra/Api/PenumbraIpcProviders.cs
Normal file
307
Penumbra/Api/PenumbraIpcProviders.cs
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Dalamud.Plugin;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Api.Helpers;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
using CurrentSettings = ValueTuple< PenumbraApiEc, (bool, int, IDictionary< string, IList< string > >, bool)? >;
|
||||
|
||||
public class PenumbraIpcProviders : IDisposable
|
||||
{
|
||||
internal readonly IPenumbraApi Api;
|
||||
internal readonly IpcTester Tester;
|
||||
|
||||
// Plugin State
|
||||
internal readonly EventProvider Initialized;
|
||||
internal readonly EventProvider Disposed;
|
||||
internal readonly FuncProvider< int > ApiVersion;
|
||||
internal readonly FuncProvider< (int Breaking, int Features) > ApiVersions;
|
||||
|
||||
// Configuration
|
||||
internal readonly FuncProvider< string > GetModDirectory;
|
||||
internal readonly FuncProvider< string > GetConfiguration;
|
||||
internal readonly EventProvider< string, bool > ModDirectoryChanged;
|
||||
|
||||
// UI
|
||||
internal readonly EventProvider< string > PreSettingsDraw;
|
||||
internal readonly EventProvider< string > PostSettingsDraw;
|
||||
internal readonly EventProvider< ChangedItemType, uint > ChangedItemTooltip;
|
||||
internal readonly EventProvider< MouseButton, ChangedItemType, uint > ChangedItemClick;
|
||||
|
||||
// Redrawing
|
||||
internal readonly ActionProvider< RedrawType > RedrawAll;
|
||||
internal readonly ActionProvider< GameObject, RedrawType > RedrawObject;
|
||||
internal readonly ActionProvider< int, RedrawType > RedrawObjectByIndex;
|
||||
internal readonly ActionProvider< string, RedrawType > RedrawObjectByName;
|
||||
internal readonly EventProvider< nint, int > GameObjectRedrawn;
|
||||
|
||||
// Game State
|
||||
internal readonly FuncProvider< nint, (nint, string) > GetDrawObjectInfo;
|
||||
internal readonly FuncProvider< int, int > GetCutsceneParentIndex;
|
||||
internal readonly EventProvider< nint, string, nint, nint, nint > CreatingCharacterBase;
|
||||
internal readonly EventProvider< nint, string, nint > CreatedCharacterBase;
|
||||
internal readonly EventProvider< nint, string, string > GameObjectResourcePathResolved;
|
||||
|
||||
// Resolve
|
||||
internal readonly FuncProvider< string, string > ResolveDefaultPath;
|
||||
internal readonly FuncProvider< string, string > ResolveInterfacePath;
|
||||
internal readonly FuncProvider< string, string > ResolvePlayerPath;
|
||||
internal readonly FuncProvider< string, string, string > ResolveCharacterPath;
|
||||
internal readonly FuncProvider< string, string, string[] > ReverseResolvePath;
|
||||
internal readonly FuncProvider< string, string[] > ReverseResolvePathPlayer;
|
||||
|
||||
// Collections
|
||||
internal readonly FuncProvider< IList< string > > GetCollections;
|
||||
internal readonly FuncProvider< string > GetCurrentCollectionName;
|
||||
internal readonly FuncProvider< string > GetDefaultCollectionName;
|
||||
internal readonly FuncProvider< string > GetInterfaceCollectionName;
|
||||
internal readonly FuncProvider< string, (string, bool) > GetCharacterCollectionName;
|
||||
internal readonly FuncProvider< string, IReadOnlyDictionary< string, object? > > GetChangedItems;
|
||||
|
||||
// Meta
|
||||
internal readonly FuncProvider< string > GetPlayerMetaManipulations;
|
||||
internal readonly FuncProvider< string, string > GetMetaManipulations;
|
||||
|
||||
// Mods
|
||||
internal readonly FuncProvider< IList< (string, string) > > GetMods;
|
||||
internal readonly FuncProvider< string, string, PenumbraApiEc > ReloadMod;
|
||||
internal readonly FuncProvider< string, PenumbraApiEc > AddMod;
|
||||
internal readonly FuncProvider< string, string, PenumbraApiEc > DeleteMod;
|
||||
internal readonly FuncProvider< string, string, (PenumbraApiEc, string, bool) > GetModPath;
|
||||
internal readonly FuncProvider< string, string, string, PenumbraApiEc > SetModPath;
|
||||
|
||||
// ModSettings
|
||||
internal readonly FuncProvider< string, string, IDictionary< string, (IList< string >, GroupType) >? > GetAvailableModSettings;
|
||||
internal readonly FuncProvider< string, string, string, bool, CurrentSettings > GetCurrentModSettings;
|
||||
internal readonly FuncProvider< string, string, string, bool, PenumbraApiEc > TryInheritMod;
|
||||
internal readonly FuncProvider< string, string, string, bool, PenumbraApiEc > TrySetMod;
|
||||
internal readonly FuncProvider< string, string, string, int, PenumbraApiEc > TrySetModPriority;
|
||||
internal readonly FuncProvider< string, string, string, string, string, PenumbraApiEc > TrySetModSetting;
|
||||
internal readonly FuncProvider< string, string, string, string, IReadOnlyList< string >, PenumbraApiEc > TrySetModSettings;
|
||||
internal readonly EventProvider< ModSettingChange, string, string, bool > ModSettingChanged;
|
||||
|
||||
// Temporary
|
||||
internal readonly FuncProvider< string, string, bool, (PenumbraApiEc, string) > CreateTemporaryCollection;
|
||||
internal readonly FuncProvider< string, PenumbraApiEc > RemoveTemporaryCollection;
|
||||
internal readonly FuncProvider< string, Dictionary< string, string >, string, int, PenumbraApiEc > AddTemporaryModAll;
|
||||
internal readonly FuncProvider< string, string, Dictionary< string, string >, string, int, PenumbraApiEc > AddTemporaryMod;
|
||||
internal readonly FuncProvider< string, int, PenumbraApiEc > RemoveTemporaryModAll;
|
||||
internal readonly FuncProvider< string, string, int, PenumbraApiEc > RemoveTemporaryMod;
|
||||
|
||||
public PenumbraIpcProviders( DalamudPluginInterface pi, IPenumbraApi api )
|
||||
{
|
||||
Api = api;
|
||||
|
||||
// Plugin State
|
||||
Initialized = Ipc.Initialized.Provider( pi );
|
||||
Disposed = Ipc.Disposed.Provider( pi );
|
||||
ApiVersion = Ipc.ApiVersion.Provider( pi, DeprecatedVersion );
|
||||
ApiVersions = Ipc.ApiVersions.Provider( pi, () => Api.ApiVersion );
|
||||
|
||||
// Configuration
|
||||
GetModDirectory = Ipc.GetModDirectory.Provider( pi, Api.GetModDirectory );
|
||||
GetConfiguration = Ipc.GetConfiguration.Provider( pi, Api.GetConfiguration );
|
||||
ModDirectoryChanged = Ipc.ModDirectoryChanged.Provider( pi, a => Api.ModDirectoryChanged += a, a => Api.ModDirectoryChanged -= a );
|
||||
|
||||
// UI
|
||||
PreSettingsDraw = Ipc.PreSettingsDraw.Provider( pi, a => Api.PreSettingsPanelDraw += a, a => Api.PreSettingsPanelDraw -= a );
|
||||
PostSettingsDraw = Ipc.PostSettingsDraw.Provider( pi, a => Api.PostSettingsPanelDraw += a, a => Api.PostSettingsPanelDraw -= a );
|
||||
ChangedItemTooltip = Ipc.ChangedItemTooltip.Provider( pi, () => Api.ChangedItemTooltip += OnTooltip, () => Api.ChangedItemTooltip -= OnTooltip );
|
||||
ChangedItemClick = Ipc.ChangedItemClick.Provider( pi, () => Api.ChangedItemClicked += OnClick, () => Api.ChangedItemClicked -= OnClick );
|
||||
|
||||
// Redrawing
|
||||
RedrawAll = Ipc.RedrawAll.Provider( pi, Api.RedrawAll );
|
||||
RedrawObject = Ipc.RedrawObject.Provider( pi, Api.RedrawObject );
|
||||
RedrawObjectByIndex = Ipc.RedrawObjectByIndex.Provider( pi, Api.RedrawObject );
|
||||
RedrawObjectByName = Ipc.RedrawObjectByName.Provider( pi, Api.RedrawObject );
|
||||
GameObjectRedrawn = Ipc.GameObjectRedrawn.Provider( pi, () => Api.GameObjectRedrawn += OnGameObjectRedrawn, () => Api.GameObjectRedrawn -= OnGameObjectRedrawn );
|
||||
|
||||
// Game State
|
||||
GetDrawObjectInfo = Ipc.GetDrawObjectInfo.Provider( pi, Api.GetDrawObjectInfo );
|
||||
GetCutsceneParentIndex = Ipc.GetCutsceneParentIndex.Provider( pi, Api.GetCutsceneParentIndex );
|
||||
CreatingCharacterBase = Ipc.CreatingCharacterBase.Provider( pi,
|
||||
() => Api.CreatingCharacterBase += CreatingCharacterBaseEvent,
|
||||
() => Api.CreatingCharacterBase -= CreatingCharacterBaseEvent );
|
||||
CreatedCharacterBase = Ipc.CreatedCharacterBase.Provider( pi,
|
||||
() => Api.CreatedCharacterBase += CreatedCharacterBaseEvent,
|
||||
() => Api.CreatedCharacterBase -= CreatedCharacterBaseEvent );
|
||||
GameObjectResourcePathResolved = Ipc.GameObjectResourcePathResolved.Provider( pi,
|
||||
() => Api.GameObjectResourceResolved += GameObjectResourceResolvedEvent,
|
||||
() => Api.GameObjectResourceResolved -= GameObjectResourceResolvedEvent );
|
||||
|
||||
// Resolve
|
||||
ResolveDefaultPath = Ipc.ResolveDefaultPath.Provider( pi, Api.ResolveDefaultPath );
|
||||
ResolveInterfacePath = Ipc.ResolveInterfacePath.Provider( pi, Api.ResolveInterfacePath );
|
||||
ResolvePlayerPath = Ipc.ResolvePlayerPath.Provider( pi, Api.ResolvePlayerPath );
|
||||
ResolveCharacterPath = Ipc.ResolveCharacterPath.Provider( pi, Api.ResolvePath );
|
||||
ReverseResolvePath = Ipc.ReverseResolvePath.Provider( pi, Api.ReverseResolvePath );
|
||||
ReverseResolvePathPlayer = Ipc.ReverseResolvePlayerPath.Provider( pi, Api.ReverseResolvePlayerPath );
|
||||
|
||||
// Collections
|
||||
GetCollections = Ipc.GetCollections.Provider( pi, Api.GetCollections );
|
||||
GetCurrentCollectionName = Ipc.GetCurrentCollectionName.Provider( pi, Api.GetCurrentCollection );
|
||||
GetDefaultCollectionName = Ipc.GetDefaultCollectionName.Provider( pi, Api.GetDefaultCollection );
|
||||
GetInterfaceCollectionName = Ipc.GetInterfaceCollectionName.Provider( pi, Api.GetInterfaceCollection );
|
||||
GetCharacterCollectionName = Ipc.GetCharacterCollectionName.Provider( pi, Api.GetCharacterCollection );
|
||||
GetChangedItems = Ipc.GetChangedItems.Provider( pi, Api.GetChangedItemsForCollection );
|
||||
|
||||
// Meta
|
||||
GetPlayerMetaManipulations = Ipc.GetPlayerMetaManipulations.Provider( pi, Api.GetPlayerMetaManipulations );
|
||||
GetMetaManipulations = Ipc.GetMetaManipulations.Provider( pi, Api.GetMetaManipulations );
|
||||
|
||||
// Mods
|
||||
GetMods = Ipc.GetMods.Provider( pi, Api.GetModList );
|
||||
ReloadMod = Ipc.ReloadMod.Provider( pi, Api.ReloadMod );
|
||||
AddMod = Ipc.AddMod.Provider( pi, Api.AddMod );
|
||||
DeleteMod = Ipc.DeleteMod.Provider( pi, Api.DeleteMod );
|
||||
GetModPath = Ipc.GetModPath.Provider( pi, Api.GetModPath );
|
||||
SetModPath = Ipc.SetModPath.Provider( pi, Api.SetModPath );
|
||||
|
||||
// ModSettings
|
||||
|
||||
GetAvailableModSettings = Ipc.GetAvailableModSettings.Provider( pi, Api.GetAvailableModSettings );
|
||||
GetCurrentModSettings = Ipc.GetCurrentModSettings.Provider( pi, Api.GetCurrentModSettings );
|
||||
TryInheritMod = Ipc.TryInheritMod.Provider( pi, Api.TryInheritMod );
|
||||
TrySetMod = Ipc.TrySetMod.Provider( pi, Api.TrySetMod );
|
||||
TrySetModPriority = Ipc.TrySetModPriority.Provider( pi, Api.TrySetModPriority );
|
||||
TrySetModSetting = Ipc.TrySetModSetting.Provider( pi, Api.TrySetModSetting );
|
||||
TrySetModSettings = Ipc.TrySetModSettings.Provider( pi, Api.TrySetModSettings );
|
||||
ModSettingChanged = Ipc.ModSettingChanged.Provider( pi,
|
||||
() => Api.ModSettingChanged += ModSettingChangedEvent,
|
||||
() => Api.ModSettingChanged -= ModSettingChangedEvent );
|
||||
|
||||
// Temporary
|
||||
CreateTemporaryCollection = Ipc.CreateTemporaryCollection.Provider( pi, Api.CreateTemporaryCollection );
|
||||
RemoveTemporaryCollection = Ipc.RemoveTemporaryCollection.Provider( pi, Api.RemoveTemporaryCollection );
|
||||
AddTemporaryModAll = Ipc.AddTemporaryModAll.Provider( pi, Api.AddTemporaryModAll );
|
||||
AddTemporaryMod = Ipc.AddTemporaryMod.Provider( pi, Api.AddTemporaryMod );
|
||||
RemoveTemporaryModAll = Ipc.RemoveTemporaryModAll.Provider( pi, Api.RemoveTemporaryModAll );
|
||||
RemoveTemporaryMod = Ipc.RemoveTemporaryMod.Provider( pi, Api.RemoveTemporaryMod );
|
||||
|
||||
Tester = new IpcTester( pi, this );
|
||||
|
||||
Initialized.Invoke();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Plugin State
|
||||
Initialized.Dispose();
|
||||
ApiVersion.Dispose();
|
||||
ApiVersions.Dispose();
|
||||
|
||||
// Configuration
|
||||
GetModDirectory.Dispose();
|
||||
GetConfiguration.Dispose();
|
||||
ModDirectoryChanged.Dispose();
|
||||
|
||||
// UI
|
||||
PreSettingsDraw.Dispose();
|
||||
PostSettingsDraw.Dispose();
|
||||
ChangedItemTooltip.Dispose();
|
||||
ChangedItemClick.Dispose();
|
||||
|
||||
// Redrawing
|
||||
RedrawAll.Dispose();
|
||||
RedrawObject.Dispose();
|
||||
RedrawObjectByIndex.Dispose();
|
||||
RedrawObjectByName.Dispose();
|
||||
GameObjectRedrawn.Dispose();
|
||||
|
||||
// Game State
|
||||
GetDrawObjectInfo.Dispose();
|
||||
GetCutsceneParentIndex.Dispose();
|
||||
CreatingCharacterBase.Dispose();
|
||||
CreatedCharacterBase.Dispose();
|
||||
GameObjectResourcePathResolved.Dispose();
|
||||
|
||||
// Resolve
|
||||
ResolveDefaultPath.Dispose();
|
||||
ResolveInterfacePath.Dispose();
|
||||
ResolvePlayerPath.Dispose();
|
||||
ResolveCharacterPath.Dispose();
|
||||
ReverseResolvePath.Dispose();
|
||||
ReverseResolvePathPlayer.Dispose();
|
||||
|
||||
// Collections
|
||||
GetCollections.Dispose();
|
||||
GetCurrentCollectionName.Dispose();
|
||||
GetDefaultCollectionName.Dispose();
|
||||
GetInterfaceCollectionName.Dispose();
|
||||
GetCharacterCollectionName.Dispose();
|
||||
GetChangedItems.Dispose();
|
||||
|
||||
// Meta
|
||||
GetPlayerMetaManipulations.Dispose();
|
||||
GetMetaManipulations.Dispose();
|
||||
|
||||
// Mods
|
||||
GetMods.Dispose();
|
||||
ReloadMod.Dispose();
|
||||
AddMod.Dispose();
|
||||
DeleteMod.Dispose();
|
||||
GetModPath.Dispose();
|
||||
SetModPath.Dispose();
|
||||
|
||||
// ModSettings
|
||||
GetAvailableModSettings.Dispose();
|
||||
GetCurrentModSettings.Dispose();
|
||||
TryInheritMod.Dispose();
|
||||
TrySetMod.Dispose();
|
||||
TrySetModPriority.Dispose();
|
||||
TrySetModSetting.Dispose();
|
||||
TrySetModSettings.Dispose();
|
||||
ModSettingChanged.Dispose();
|
||||
|
||||
// Temporary
|
||||
CreateTemporaryCollection.Dispose();
|
||||
RemoveTemporaryCollection.Dispose();
|
||||
AddTemporaryModAll.Dispose();
|
||||
AddTemporaryMod.Dispose();
|
||||
RemoveTemporaryModAll.Dispose();
|
||||
RemoveTemporaryMod.Dispose();
|
||||
|
||||
Disposed.Invoke();
|
||||
Disposed.Dispose();
|
||||
Tester.Dispose();
|
||||
}
|
||||
|
||||
// Wrappers
|
||||
private int DeprecatedVersion()
|
||||
{
|
||||
Penumbra.Log.Warning( $"{Ipc.ApiVersion.Label} is outdated. Please use {Ipc.ApiVersions.Label} instead." );
|
||||
return Api.ApiVersion.Breaking;
|
||||
}
|
||||
|
||||
private void OnClick( MouseButton click, object? item )
|
||||
{
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId( item );
|
||||
ChangedItemClick.Invoke( click, type, id );
|
||||
}
|
||||
|
||||
private void OnTooltip( object? item )
|
||||
{
|
||||
var (type, id) = ChangedItemExtensions.ChangedItemToTypeAndId( item );
|
||||
ChangedItemTooltip.Invoke( type, id );
|
||||
}
|
||||
|
||||
private void OnGameObjectRedrawn( IntPtr objectAddress, int objectTableIndex )
|
||||
=> GameObjectRedrawn.Invoke( objectAddress, objectTableIndex );
|
||||
|
||||
private void CreatingCharacterBaseEvent( IntPtr gameObject, string collectionName, IntPtr modelId, IntPtr customize, IntPtr equipData )
|
||||
=> CreatingCharacterBase.Invoke( gameObject, collectionName, modelId, customize, equipData );
|
||||
|
||||
private void CreatedCharacterBaseEvent( IntPtr gameObject, string collectionName, IntPtr drawObject )
|
||||
=> CreatedCharacterBase.Invoke( gameObject, collectionName, drawObject );
|
||||
|
||||
private void GameObjectResourceResolvedEvent( IntPtr gameObject, string gamePath, string localPath )
|
||||
=> GameObjectResourcePathResolved.Invoke( gameObject, gamePath, localPath );
|
||||
|
||||
private void ModSettingChangedEvent( ModSettingChange type, string collection, string mod, bool inherited )
|
||||
=> ModSettingChanged.Invoke( type, collection, mod, inherited );
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
using EmbedIO;
|
||||
using EmbedIO.Routing;
|
||||
using EmbedIO.WebApi;
|
||||
using Penumbra.GameData.Enums;
|
||||
using System.Threading.Tasks;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Api;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Penumbra.Mods;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
@ -269,10 +270,10 @@ public partial class ModCollection
|
|||
var config = settings.Settings[ groupIndex ];
|
||||
switch( group.Type )
|
||||
{
|
||||
case SelectType.Single:
|
||||
case GroupType.Single:
|
||||
AddSubMod( group[ ( int )config ], mod );
|
||||
break;
|
||||
case SelectType.Multi:
|
||||
case GroupType.Multi:
|
||||
{
|
||||
foreach( var (option, _) in group.WithIndex()
|
||||
.Where( p => ( ( 1 << p.Item2 ) & config ) != 0 )
|
||||
|
|
|
|||
|
|
@ -2,20 +2,10 @@ using Penumbra.Mods;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
// Different types a mod setting can change:
|
||||
public enum ModSettingChange
|
||||
{
|
||||
Inheritance, // it was set to inherit from other collections or not inherit anymore
|
||||
EnableState, // it was enabled or disabled
|
||||
Priority, // its priority was changed
|
||||
Setting, // a specific setting was changed
|
||||
MultiInheritance, // multiple mods were set to inherit from other collections or not inherit anymore.
|
||||
MultiEnableState, // multiple mods were enabled or disabled at once.
|
||||
}
|
||||
|
||||
public partial class ModCollection
|
||||
{
|
||||
// If the change type is a bool, oldValue will be 1 for true and 0 for false.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using Penumbra.Mods;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Collections;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using OtterGui;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Util;
|
||||
using SharpCompress.Archives.Zip;
|
||||
|
|
@ -162,7 +163,7 @@ public partial class TexToolsImporter
|
|||
foreach( var group in page.ModGroups.Where( group => group.GroupName.Length > 0 && group.OptionList.Length > 0 ) )
|
||||
{
|
||||
var allOptions = group.OptionList.Where( option => option.Name.Length > 0 && option.ModsJsons.Length > 0 ).ToList();
|
||||
var (numGroups, maxOptions) = group.SelectionType == SelectType.Single
|
||||
var (numGroups, maxOptions) = group.SelectionType == GroupType.Single
|
||||
? ( 1, allOptions.Count )
|
||||
: ( 1 + allOptions.Count / IModGroup.MaxMultiOptions, IModGroup.MaxMultiOptions );
|
||||
_currentGroupName = GetGroupName( group.GroupName, groupNames );
|
||||
|
|
@ -177,7 +178,7 @@ public partial class TexToolsImporter
|
|||
?? new DirectoryInfo( Path.Combine( _currentModDirectory.FullName,
|
||||
numGroups == 1 ? $"Group {groupPriority + 1}" : $"Group {groupPriority + 1}, Part {groupId + 1}" ) );
|
||||
|
||||
uint? defaultSettings = group.SelectionType == SelectType.Multi ? 0u : null;
|
||||
uint? defaultSettings = group.SelectionType == GroupType.Multi ? 0u : null;
|
||||
for( var i = 0; i + optionIdx < allOptions.Count && i < maxOptions; ++i )
|
||||
{
|
||||
var option = allOptions[ i + optionIdx ];
|
||||
|
|
@ -195,7 +196,7 @@ public partial class TexToolsImporter
|
|||
|
||||
if( option.IsChecked )
|
||||
{
|
||||
defaultSettings = group.SelectionType == SelectType.Multi
|
||||
defaultSettings = group.SelectionType == GroupType.Multi
|
||||
? ( defaultSettings!.Value | ( 1u << i ) )
|
||||
: ( uint )i;
|
||||
}
|
||||
|
|
@ -207,7 +208,7 @@ public partial class TexToolsImporter
|
|||
|
||||
// Handle empty options for single select groups without creating a folder for them.
|
||||
// We only want one of those at most, and it should usually be the first option.
|
||||
if( group.SelectionType == SelectType.Single )
|
||||
if( group.SelectionType == GroupType.Single )
|
||||
{
|
||||
var empty = group.OptionList.FirstOrDefault( o => o.Name.Length > 0 && o.ModsJsons.Length == 0 );
|
||||
if( empty != null )
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Mods;
|
||||
|
||||
namespace Penumbra.Import;
|
||||
|
|
@ -34,7 +35,7 @@ internal class ModPackPage
|
|||
internal class ModGroup
|
||||
{
|
||||
public string GroupName = string.Empty;
|
||||
public SelectType SelectionType = SelectType.Single;
|
||||
public GroupType SelectionType = GroupType.Single;
|
||||
public OptionList[] OptionList = Array.Empty< OptionList >();
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ internal class OptionList
|
|||
public string ImagePath = string.Empty;
|
||||
public SimpleMod[] ModsJsons = Array.Empty< SimpleMod >();
|
||||
public string GroupName = string.Empty;
|
||||
public SelectType SelectionType = SelectType.Single;
|
||||
public GroupType SelectionType = GroupType.Single;
|
||||
public bool IsChecked = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Dalamud.Game.ClientState.Objects.Enums;
|
|||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop.Structs;
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ public unsafe partial class PathResolver
|
|||
try
|
||||
{
|
||||
var modelPtr = &a;
|
||||
CreatingCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection, ( IntPtr )modelPtr, b, c );
|
||||
CreatingCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection.Name, ( IntPtr )modelPtr, b, c );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
|
|
@ -163,7 +163,7 @@ public unsafe partial class PathResolver
|
|||
if( LastGameObject != null && ret != IntPtr.Zero )
|
||||
{
|
||||
_drawObjectToObject[ ret ] = ( _lastCreatedCollection!, LastGameObject->ObjectIndex );
|
||||
CreatedCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection, ret );
|
||||
CreatedCharacterBase?.Invoke( ( IntPtr )LastGameObject, _lastCreatedCollection!.ModCollection.Name, ret );
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
using Penumbra.Util;
|
||||
|
|
@ -16,7 +17,7 @@ public sealed partial class Mod
|
|||
public delegate void ModOptionChangeDelegate( ModOptionChangeType type, Mod mod, int groupIdx, int optionIdx, int movedToIdx );
|
||||
public event ModOptionChangeDelegate ModOptionChanged;
|
||||
|
||||
public void ChangeModGroupType( Mod mod, int groupIdx, SelectType type )
|
||||
public void ChangeModGroupType( Mod mod, int groupIdx, GroupType type )
|
||||
{
|
||||
var group = mod._groups[ groupIdx ];
|
||||
if( group.Type == type )
|
||||
|
|
@ -61,7 +62,7 @@ public sealed partial class Mod
|
|||
ModOptionChanged.Invoke( ModOptionChangeType.GroupRenamed, mod, groupIdx, -1, -1 );
|
||||
}
|
||||
|
||||
public void AddModGroup( Mod mod, SelectType type, string newName )
|
||||
public void AddModGroup( Mod mod, GroupType type, string newName )
|
||||
{
|
||||
if( !VerifyFileName( mod, null, newName, true ) )
|
||||
{
|
||||
|
|
@ -70,7 +71,7 @@ public sealed partial class Mod
|
|||
|
||||
var maxPriority = mod._groups.Count == 0 ? 0 : mod._groups.Max( o => o.Priority ) + 1;
|
||||
|
||||
mod._groups.Add( type == SelectType.Multi
|
||||
mod._groups.Add( type == GroupType.Multi
|
||||
? new MultiModGroup { Name = newName, Priority = maxPriority }
|
||||
: new SingleModGroup { Name = newName, Priority = maxPriority } );
|
||||
ModOptionChanged.Invoke( ModOptionChangeType.GroupAdded, mod, mod._groups.Count - 1, -1, -1 );
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using Dalamud.Utility;
|
||||
using OtterGui.Classes;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Import;
|
||||
|
||||
|
|
@ -62,12 +63,12 @@ public partial class Mod
|
|||
}
|
||||
|
||||
// Create a file for an option group from given data.
|
||||
internal static void CreateOptionGroup( DirectoryInfo baseFolder, SelectType type, string name,
|
||||
internal static void CreateOptionGroup( DirectoryInfo baseFolder, GroupType type, string name,
|
||||
int priority, int index, uint defaultSettings, string desc, IEnumerable< ISubMod > subMods )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case SelectType.Multi:
|
||||
case GroupType.Multi:
|
||||
{
|
||||
var group = new MultiModGroup()
|
||||
{
|
||||
|
|
@ -80,7 +81,7 @@ public partial class Mod
|
|||
IModGroup.Save( group, baseFolder, index );
|
||||
break;
|
||||
}
|
||||
case SelectType.Single:
|
||||
case GroupType.Single:
|
||||
{
|
||||
var group = new SingleModGroup()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Meta.Manipulations;
|
||||
|
||||
|
|
@ -79,10 +80,10 @@ public partial class Mod
|
|||
try
|
||||
{
|
||||
var json = JObject.Parse( File.ReadAllText( file.FullName ) );
|
||||
switch( json[ nameof( Type ) ]?.ToObject< SelectType >() ?? SelectType.Single )
|
||||
switch( json[ nameof( Type ) ]?.ToObject< GroupType >() ?? GroupType.Single )
|
||||
{
|
||||
case SelectType.Multi: return MultiModGroup.Load( mod, json, groupIdx );
|
||||
case SelectType.Single: return SingleModGroup.Load( mod, json, groupIdx );
|
||||
case GroupType.Multi: return MultiModGroup.Load( mod, json, groupIdx );
|
||||
case GroupType.Single: return SingleModGroup.Load( mod, json, groupIdx );
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Text.RegularExpressions;
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.ByteString;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
|
@ -128,7 +129,7 @@ public sealed partial class Mod
|
|||
|
||||
switch( group.SelectionType )
|
||||
{
|
||||
case SelectType.Multi:
|
||||
case GroupType.Multi:
|
||||
|
||||
var optionPriority = 0;
|
||||
var newMultiGroup = new MultiModGroup()
|
||||
|
|
@ -144,7 +145,7 @@ public sealed partial class Mod
|
|||
}
|
||||
|
||||
break;
|
||||
case SelectType.Single:
|
||||
case GroupType.Single:
|
||||
if( group.Options.Count == 1 )
|
||||
{
|
||||
AddFilesToSubMod( mod._default, mod.ModPath, group.Options[ 0 ], seenMetaFiles );
|
||||
|
|
@ -209,7 +210,7 @@ public sealed partial class Mod
|
|||
public string GroupName = string.Empty;
|
||||
|
||||
[JsonConverter( typeof( Newtonsoft.Json.Converters.StringEnumConverter ) )]
|
||||
public SelectType SelectionType = SelectType.Single;
|
||||
public GroupType SelectionType = GroupType.Single;
|
||||
|
||||
public List< OptionV0 > Options = new();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
|
@ -121,8 +122,7 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
|
|||
CreateLeaf( Root, name, mod );
|
||||
break;
|
||||
case ModPathChangeType.Deleted:
|
||||
var leaf = Root.GetAllDescendants( ISortMode< Mod >.Lexicographical ).OfType< Leaf >().FirstOrDefault( l => l.Value == mod );
|
||||
if( leaf != null )
|
||||
if( FindLeaf( mod, out var leaf ) )
|
||||
{
|
||||
Delete( leaf );
|
||||
}
|
||||
|
|
@ -137,6 +137,16 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
// Search the entire filesystem for the leaf corresponding to a mod.
|
||||
public bool FindLeaf( Mod mod, [NotNullWhen( true )] out Leaf? leaf )
|
||||
{
|
||||
leaf = Root.GetAllDescendants( ISortMode< Mod >.Lexicographical )
|
||||
.OfType< Leaf >()
|
||||
.FirstOrDefault( l => l.Value == mod );
|
||||
return leaf != null;
|
||||
}
|
||||
|
||||
|
||||
// Used for saving and loading.
|
||||
private static string ModToIdentifier( Mod mod )
|
||||
=> mod.ModPath.Name;
|
||||
|
|
@ -144,15 +154,16 @@ public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
|
|||
private static string ModToName( Mod mod )
|
||||
=> mod.Name.Text.FixName();
|
||||
|
||||
private static (string, bool) SaveMod( Mod mod, string fullPath )
|
||||
// Return whether a mod has a custom path or is just a numbered default path.
|
||||
public static bool ModHasDefaultPath( Mod mod, string fullPath )
|
||||
{
|
||||
var regex = new Regex( $@"^{Regex.Escape( ModToName( mod ) )}( \(\d+\))?$" );
|
||||
// Only save pairs with non-default paths.
|
||||
if( regex.IsMatch( fullPath ) )
|
||||
{
|
||||
return ( string.Empty, false );
|
||||
}
|
||||
|
||||
return ( ModToIdentifier( mod ), true );
|
||||
return regex.IsMatch( fullPath );
|
||||
}
|
||||
|
||||
private static (string, bool) SaveMod( Mod mod, string fullPath )
|
||||
// Only save pairs with non-default paths.
|
||||
=> ModHasDefaultPath( mod, fullPath )
|
||||
? ( string.Empty, false )
|
||||
: ( ModToIdentifier( mod ), true );
|
||||
}
|
||||
|
|
@ -3,22 +3,17 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
public enum SelectType
|
||||
{
|
||||
Single,
|
||||
Multi,
|
||||
}
|
||||
|
||||
public interface IModGroup : IEnumerable< ISubMod >
|
||||
{
|
||||
public const int MaxMultiOptions = 32;
|
||||
|
||||
public string Name { get; }
|
||||
public string Description { get; }
|
||||
public SelectType Type { get; }
|
||||
public GroupType Type { get; }
|
||||
public int Priority { get; }
|
||||
public uint DefaultSettings { get; set; }
|
||||
|
||||
|
|
@ -31,8 +26,8 @@ public interface IModGroup : IEnumerable< ISubMod >
|
|||
public bool IsOption
|
||||
=> Type switch
|
||||
{
|
||||
SelectType.Single => Count > 1,
|
||||
SelectType.Multi => Count > 0,
|
||||
GroupType.Single => Count > 1,
|
||||
GroupType.Multi => Count > 0,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
|
@ -90,7 +85,7 @@ public interface IModGroup : IEnumerable< ISubMod >
|
|||
j.WriteStartArray();
|
||||
for( var idx = 0; idx < group.Count; ++idx )
|
||||
{
|
||||
ISubMod.WriteSubMod( j, serializer, group[ idx ], basePath, group.Type == SelectType.Multi ? group.OptionPriority( idx ) : null );
|
||||
ISubMod.WriteSubMod( j, serializer, group[ idx ], basePath, group.Type == GroupType.Multi ? group.OptionPriority( idx ) : null );
|
||||
}
|
||||
|
||||
j.WriteEndArray();
|
||||
|
|
@ -98,7 +93,7 @@ public interface IModGroup : IEnumerable< ISubMod >
|
|||
Penumbra.Log.Debug( $"Saved group file {file} for group {groupIdx + 1}: {group.Name}." );
|
||||
}
|
||||
|
||||
public IModGroup Convert( SelectType type );
|
||||
public IModGroup Convert( GroupType type );
|
||||
public bool MoveOption( int optionIdxFrom, int optionIdxTo );
|
||||
public void UpdatePositions( int from = 0 );
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using Newtonsoft.Json;
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
|
@ -15,8 +16,8 @@ public partial class Mod
|
|||
// Groups that allow all available options to be selected at once.
|
||||
private sealed class MultiModGroup : IModGroup
|
||||
{
|
||||
public SelectType Type
|
||||
=> SelectType.Multi;
|
||||
public GroupType Type
|
||||
=> GroupType.Multi;
|
||||
|
||||
public string Name { get; set; } = "Group";
|
||||
public string Description { get; set; } = "A non-exclusive group of settings.";
|
||||
|
|
@ -79,12 +80,12 @@ public partial class Mod
|
|||
return ret;
|
||||
}
|
||||
|
||||
public IModGroup Convert( SelectType type )
|
||||
public IModGroup Convert( GroupType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case SelectType.Multi: return this;
|
||||
case SelectType.Single:
|
||||
case GroupType.Multi: return this;
|
||||
case GroupType.Single:
|
||||
var multi = new SingleModGroup()
|
||||
{
|
||||
Name = Name,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using Newtonsoft.Json;
|
|||
using Newtonsoft.Json.Linq;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
|
@ -14,8 +15,8 @@ public partial class Mod
|
|||
// Groups that allow only one of their available options to be selected.
|
||||
private sealed class SingleModGroup : IModGroup
|
||||
{
|
||||
public SelectType Type
|
||||
=> SelectType.Single;
|
||||
public GroupType Type
|
||||
=> GroupType.Single;
|
||||
|
||||
public string Name { get; set; } = "Option";
|
||||
public string Description { get; set; } = "A mutually exclusive group of settings.";
|
||||
|
|
@ -72,12 +73,12 @@ public partial class Mod
|
|||
return ret;
|
||||
}
|
||||
|
||||
public IModGroup Convert( SelectType type )
|
||||
public IModGroup Convert( GroupType type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
case SelectType.Single: return this;
|
||||
case SelectType.Multi:
|
||||
case GroupType.Single: return this;
|
||||
case GroupType.Multi:
|
||||
var multi = new MultiModGroup()
|
||||
{
|
||||
Name = Name,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Numerics;
|
||||
using OtterGui;
|
||||
using OtterGui.Filesystem;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.Mods;
|
||||
|
||||
|
|
@ -56,8 +57,8 @@ public class ModSettings
|
|||
var config = Settings[ groupIdx ];
|
||||
Settings[ groupIdx ] = group.Type switch
|
||||
{
|
||||
SelectType.Single => ( uint )Math.Max( Math.Min( group.Count - 1, BitOperations.TrailingZeroCount( config ) ), 0 ),
|
||||
SelectType.Multi => 1u << ( int )config,
|
||||
GroupType.Single => ( uint )Math.Max( Math.Min( group.Count - 1, BitOperations.TrailingZeroCount( config ) ), 0 ),
|
||||
GroupType.Multi => 1u << ( int )config,
|
||||
_ => config,
|
||||
};
|
||||
return config != Settings[ groupIdx ];
|
||||
|
|
@ -70,8 +71,8 @@ public class ModSettings
|
|||
var config = Settings[ groupIdx ];
|
||||
Settings[ groupIdx ] = group.Type switch
|
||||
{
|
||||
SelectType.Single => config >= optionIdx ? config > 1 ? config - 1 : 0 : config,
|
||||
SelectType.Multi => Functions.RemoveBit( config, optionIdx ),
|
||||
GroupType.Single => config >= optionIdx ? config > 1 ? config - 1 : 0 : config,
|
||||
GroupType.Multi => Functions.RemoveBit( config, optionIdx ),
|
||||
_ => config,
|
||||
};
|
||||
return config != Settings[ groupIdx ];
|
||||
|
|
@ -87,8 +88,8 @@ public class ModSettings
|
|||
var config = Settings[ groupIdx ];
|
||||
Settings[ groupIdx ] = group.Type switch
|
||||
{
|
||||
SelectType.Single => config == optionIdx ? ( uint )movedToIdx : config,
|
||||
SelectType.Multi => Functions.MoveBit( config, optionIdx, movedToIdx ),
|
||||
GroupType.Single => config == optionIdx ? ( uint )movedToIdx : config,
|
||||
GroupType.Multi => Functions.MoveBit( config, optionIdx, movedToIdx ),
|
||||
_ => config,
|
||||
};
|
||||
return config != Settings[ groupIdx ];
|
||||
|
|
@ -101,8 +102,8 @@ public class ModSettings
|
|||
private static uint FixSetting( IModGroup group, uint value )
|
||||
=> group.Type switch
|
||||
{
|
||||
SelectType.Single => ( uint )Math.Min( value, group.Count - 1 ),
|
||||
SelectType.Multi => ( uint )( value & ( ( 1ul << group.Count ) - 1 ) ),
|
||||
GroupType.Single => ( uint )Math.Min( value, group.Count - 1 ),
|
||||
GroupType.Multi => ( uint )( value & ( ( 1ul << group.Count ) - 1 ) ),
|
||||
_ => value,
|
||||
};
|
||||
|
||||
|
|
@ -202,7 +203,7 @@ public class ModSettings
|
|||
}
|
||||
|
||||
var group = mod.Groups[ idx ];
|
||||
if( group.Type == SelectType.Single && setting < group.Count )
|
||||
if( group.Type == GroupType.Single && setting < group.Count )
|
||||
{
|
||||
dict.Add( group.Name, new[] { group[ ( int )setting ].Name } );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using OtterGui.Classes;
|
|||
using OtterGui.Log;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.UI;
|
||||
|
|
@ -57,16 +58,16 @@ public class Penumbra : IDalamudPlugin
|
|||
public static FrameworkManager Framework { get; private set; } = null!;
|
||||
public static int ImcExceptions = 0;
|
||||
|
||||
public readonly ResourceLogger ResourceLogger;
|
||||
public readonly PathResolver PathResolver;
|
||||
public readonly ObjectReloader ObjectReloader;
|
||||
public readonly ModFileSystem ModFileSystem;
|
||||
public readonly PenumbraApi Api;
|
||||
public readonly PenumbraIpc Ipc;
|
||||
private readonly ConfigWindow _configWindow;
|
||||
private readonly LaunchButton _launchButton;
|
||||
private readonly WindowSystem _windowSystem;
|
||||
private readonly Changelog _changelog;
|
||||
public readonly ResourceLogger ResourceLogger;
|
||||
public readonly PathResolver PathResolver;
|
||||
public readonly ObjectReloader ObjectReloader;
|
||||
public readonly ModFileSystem ModFileSystem;
|
||||
public readonly PenumbraApi Api;
|
||||
public readonly PenumbraIpcProviders IpcProviders;
|
||||
private readonly ConfigWindow _configWindow;
|
||||
private readonly LaunchButton _launchButton;
|
||||
private readonly WindowSystem _windowSystem;
|
||||
private readonly Changelog _changelog;
|
||||
|
||||
internal WebServer? WebServer;
|
||||
|
||||
|
|
@ -95,9 +96,9 @@ public class Penumbra : IDalamudPlugin
|
|||
ModManager.DiscoverMods();
|
||||
CollectionManager = new ModCollection.Manager( ModManager );
|
||||
CollectionManager.CreateNecessaryCaches();
|
||||
ModFileSystem = ModFileSystem.Load();
|
||||
ObjectReloader = new ObjectReloader();
|
||||
PathResolver = new PathResolver( ResourceLoader );
|
||||
ModFileSystem = ModFileSystem.Load();
|
||||
ObjectReloader = new ObjectReloader();
|
||||
PathResolver = new PathResolver( ResourceLoader );
|
||||
|
||||
Dalamud.Commands.AddHandler( CommandName, new CommandInfo( OnCommand )
|
||||
{
|
||||
|
|
@ -133,8 +134,8 @@ public class Penumbra : IDalamudPlugin
|
|||
ResidentResources.Reload();
|
||||
}
|
||||
|
||||
Api = new PenumbraApi( this );
|
||||
Ipc = new PenumbraIpc( Dalamud.PluginInterface, Api );
|
||||
Api = new PenumbraApi( this );
|
||||
IpcProviders = new PenumbraIpcProviders( Dalamud.PluginInterface, Api );
|
||||
SubscribeItemLinks();
|
||||
if( ImcExceptions > 0 )
|
||||
{
|
||||
|
|
@ -279,7 +280,7 @@ public class Penumbra : IDalamudPlugin
|
|||
{
|
||||
ShutdownWebServer();
|
||||
DisposeInterface();
|
||||
Ipc?.Dispose();
|
||||
IpcProviders?.Dispose();
|
||||
Api?.Dispose();
|
||||
ObjectReloader?.Dispose();
|
||||
ModFileSystem?.Dispose();
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@
|
|||
<ItemGroup>
|
||||
<ProjectReference Include="..\OtterGui\OtterGui.csproj" />
|
||||
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||
<ProjectReference Include="..\Penumbra.Api\Penumbra.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ using System.Collections.Concurrent;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Penumbra.Api.Enums;
|
||||
|
||||
namespace Penumbra.UI.Classes;
|
||||
|
||||
|
|
|
|||
|
|
@ -444,11 +444,11 @@ public partial class ConfigWindow
|
|||
{
|
||||
if( !ImGui.CollapsingHeader( "IPC" ) )
|
||||
{
|
||||
_window._penumbra.Ipc.Tester.UnsubscribeEvents();
|
||||
_window._penumbra.IpcProviders.Tester.UnsubscribeEvents();
|
||||
return;
|
||||
}
|
||||
|
||||
_window._penumbra.Ipc.Tester.Draw();
|
||||
_window._penumbra.IpcProviders.Tester.Draw();
|
||||
}
|
||||
|
||||
// Helper to print a property and its value in a 2-column table.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using Lumina.Data.Parsing;
|
|||
using Lumina.Excel.GeneratedSheets;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using Dalamud.Interface.Components;
|
|||
using ImGuiNET;
|
||||
using OtterGui;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Mods;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
|
@ -236,7 +237,7 @@ public partial class ConfigWindow
|
|||
if( ImGuiUtil.DrawDisabledButton( FontAwesomeIcon.Plus.ToIconString(), window._iconButtonSize,
|
||||
tt, !nameValid, true ) )
|
||||
{
|
||||
Penumbra.ModManager.AddModGroup( mod, SelectType.Single, _newGroupName );
|
||||
Penumbra.ModManager.AddModGroup( mod, GroupType.Single, _newGroupName );
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
|
@ -496,7 +497,7 @@ public partial class ConfigWindow
|
|||
ImGui.TableNextColumn();
|
||||
|
||||
|
||||
if( group.Type == SelectType.Single )
|
||||
if( group.Type == GroupType.Single )
|
||||
{
|
||||
if( ImGui.RadioButton( "##default", group.DefaultSettings == optionIdx ) )
|
||||
{
|
||||
|
|
@ -532,7 +533,7 @@ public partial class ConfigWindow
|
|||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
if( group.Type == SelectType.Multi )
|
||||
if( group.Type == GroupType.Multi )
|
||||
{
|
||||
if( Input.Priority( "##Priority", groupIdx, optionIdx, group.OptionPriority( optionIdx ), out var priority,
|
||||
50 * ImGuiHelpers.GlobalScale ) )
|
||||
|
|
@ -564,7 +565,7 @@ public partial class ConfigWindow
|
|||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
var canAddGroup = mod.Groups[ groupIdx ].Type != SelectType.Multi || mod.Groups[ groupIdx ].Count < IModGroup.MaxMultiOptions;
|
||||
var canAddGroup = mod.Groups[ groupIdx ].Type != GroupType.Multi || mod.Groups[ groupIdx ].Count < IModGroup.MaxMultiOptions;
|
||||
var validName = _newOptionName.Length > 0 && _newOptionNameIdx == groupIdx;
|
||||
var tt = canAddGroup
|
||||
? validName ? "Add a new option to this group." : "Please enter a name for the new option."
|
||||
|
|
@ -636,11 +637,11 @@ public partial class ConfigWindow
|
|||
// Draw a combo to select single or multi group and switch between them.
|
||||
private void DrawGroupCombo( IModGroup group, int groupIdx )
|
||||
{
|
||||
static string GroupTypeName( SelectType type )
|
||||
static string GroupTypeName( GroupType type )
|
||||
=> type switch
|
||||
{
|
||||
SelectType.Single => "Single Group",
|
||||
SelectType.Multi => "Multi Group",
|
||||
GroupType.Single => "Single Group",
|
||||
GroupType.Multi => "Multi Group",
|
||||
_ => "Unknown",
|
||||
};
|
||||
|
||||
|
|
@ -651,16 +652,16 @@ public partial class ConfigWindow
|
|||
return;
|
||||
}
|
||||
|
||||
if( ImGui.Selectable( GroupTypeName( SelectType.Single ), group.Type == SelectType.Single ) )
|
||||
if( ImGui.Selectable( GroupTypeName( GroupType.Single ), group.Type == GroupType.Single ) )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModGroupType( _mod, groupIdx, SelectType.Single );
|
||||
Penumbra.ModManager.ChangeModGroupType( _mod, groupIdx, GroupType.Single );
|
||||
}
|
||||
|
||||
var canSwitchToMulti = group.Count <= IModGroup.MaxMultiOptions;
|
||||
using var style = ImRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, !canSwitchToMulti );
|
||||
if( ImGui.Selectable( GroupTypeName( SelectType.Multi ), group.Type == SelectType.Multi ) && canSwitchToMulti )
|
||||
if( ImGui.Selectable( GroupTypeName( GroupType.Multi ), group.Type == GroupType.Multi ) && canSwitchToMulti )
|
||||
{
|
||||
Penumbra.ModManager.ChangeModGroupType( _mod, groupIdx, SelectType.Multi );
|
||||
Penumbra.ModManager.ChangeModGroupType( _mod, groupIdx, GroupType.Multi );
|
||||
}
|
||||
|
||||
style.Pop();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using OtterGui.Widgets;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.Collections;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Classes;
|
||||
|
|
@ -154,7 +155,7 @@ public partial class ConfigWindow
|
|||
// If a description is provided, add a help marker besides it.
|
||||
private void DrawSingleGroup( IModGroup group, int groupIdx )
|
||||
{
|
||||
if( group.Type != SelectType.Single || !group.IsOption )
|
||||
if( group.Type != GroupType.Single || !group.IsOption )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -193,7 +194,7 @@ public partial class ConfigWindow
|
|||
// If a description is provided, add a help marker in the title.
|
||||
private void DrawMultiGroup( IModGroup group, int groupIdx )
|
||||
{
|
||||
if( group.Type != SelectType.Multi || !group.IsOption )
|
||||
if( group.Type != GroupType.Multi || !group.IsOption )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using System;
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using Penumbra.Api.Enums;
|
||||
using Penumbra.GameData.Enums;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
|
|
|||
|
|
@ -58,26 +58,17 @@
|
|||
"System.ValueTuple": "4.5.0"
|
||||
}
|
||||
},
|
||||
"DirectXTex": {
|
||||
"type": "Project"
|
||||
},
|
||||
"directxtexc": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"DirectXTex": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"ottergui": {
|
||||
"type": "Project"
|
||||
},
|
||||
"ottertex": {
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"DirectXTexC": "[1.0.0, )"
|
||||
}
|
||||
"penumbra.api": {
|
||||
"type": "Project"
|
||||
},
|
||||
"penumbra.gamedata": {
|
||||
"type": "Project"
|
||||
"type": "Project",
|
||||
"dependencies": {
|
||||
"Penumbra.Api": "[1.0.0, )"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue