diff --git a/Penumbra/Interop/MetaFileManager.cs b/Penumbra/Interop/MetaFileManager.cs
deleted file mode 100644
index c49efa1e..00000000
--- a/Penumbra/Interop/MetaFileManager.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-using Dalamud.Utility.Signatures;
-using FFXIVClientStructs.FFXIV.Client.System.Memory;
-using Penumbra.GameData;
-
-namespace Penumbra.Interop;
-
-public unsafe class MetaFileManager
-{
- public MetaFileManager()
- {
- SignatureHelper.Initialise( this );
- }
-
- // Allocate in the games space for file storage.
- // We only need this if using any meta file.
- [Signature( Sigs.GetFileSpace )]
- private readonly IntPtr _getFileSpaceAddress = IntPtr.Zero;
-
- public IMemorySpace* GetFileSpace()
- => ( ( delegate* unmanaged< IMemorySpace* > )_getFileSpaceAddress )();
-
- public void* AllocateFileMemory( ulong length, ulong alignment = 0 )
- => GetFileSpace()->Malloc( length, alignment );
-
- public void* AllocateFileMemory( int length, int alignment = 0 )
- => AllocateFileMemory( ( ulong )length, ( ulong )alignment );
-
- public void* AllocateDefaultMemory( ulong length, ulong alignment = 0 )
- => GetFileSpace()->Malloc( length, alignment );
-
- public void* AllocateDefaultMemory( int length, int alignment = 0 )
- => IMemorySpace.GetDefaultSpace()->Malloc( ( ulong )length, ( ulong )alignment );
-
- public void Free( IntPtr ptr, int length )
- => IMemorySpace.Free( ( void* )ptr, ( ulong )length );
-}
\ No newline at end of file
diff --git a/Penumbra/Interop/Resolver/CutsceneCharacters.cs b/Penumbra/Interop/Resolver/CutsceneCharacters.cs
index 9cf765d0..06b4f228 100644
--- a/Penumbra/Interop/Resolver/CutsceneCharacters.cs
+++ b/Penumbra/Interop/Resolver/CutsceneCharacters.cs
@@ -4,7 +4,8 @@ using System.Diagnostics;
using System.Linq;
using Dalamud.Game.ClientState.Objects;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
-
+using Penumbra.Interop.Services;
+
namespace Penumbra.Interop.Resolver;
public class CutsceneCharacters : IDisposable
diff --git a/Penumbra/Interop/Resolver/IdentifiedCollectionCache.cs b/Penumbra/Interop/Resolver/IdentifiedCollectionCache.cs
index cad29dc0..7135eebb 100644
--- a/Penumbra/Interop/Resolver/IdentifiedCollectionCache.cs
+++ b/Penumbra/Interop/Resolver/IdentifiedCollectionCache.cs
@@ -5,6 +5,7 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Penumbra.Collections;
using Penumbra.GameData.Actors;
+using Penumbra.Interop.Services;
using Penumbra.Services;
namespace Penumbra.Interop.Resolver;
diff --git a/Penumbra/Interop/Resolver/PathResolver.Subfiles.cs b/Penumbra/Interop/Resolver/PathResolver.Subfiles.cs
index 37059bf6..da976f0b 100644
--- a/Penumbra/Interop/Resolver/PathResolver.Subfiles.cs
+++ b/Penumbra/Interop/Resolver/PathResolver.Subfiles.cs
@@ -11,6 +11,7 @@ using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
+using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;
diff --git a/Penumbra/Interop/Resolver/PathResolver.cs b/Penumbra/Interop/Resolver/PathResolver.cs
index 2d94516d..4050d2f1 100644
--- a/Penumbra/Interop/Resolver/PathResolver.cs
+++ b/Penumbra/Interop/Resolver/PathResolver.cs
@@ -9,6 +9,7 @@ using OtterGui.Classes;
using Penumbra.Collections;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
+using Penumbra.Interop.Services;
using Penumbra.Interop.Structs;
using Penumbra.Services;
using Penumbra.String;
diff --git a/Penumbra/Interop/FontReloader.cs b/Penumbra/Interop/Services/FontReloader.cs
similarity index 68%
rename from Penumbra/Interop/FontReloader.cs
rename to Penumbra/Interop/Services/FontReloader.cs
index f7e8af27..51f8abc2 100644
--- a/Penumbra/Interop/FontReloader.cs
+++ b/Penumbra/Interop/Services/FontReloader.cs
@@ -1,11 +1,13 @@
using FFXIVClientStructs.FFXIV.Client.System.Framework;
using FFXIVClientStructs.FFXIV.Component.GUI;
using Penumbra.GameData;
+
+namespace Penumbra.Interop.Services;
-namespace Penumbra.Interop;
-
-// Handle font reloading via game functions.
-// May cause a interface flicker while reloading.
+///
+/// Handle font reloading via game functions.
+/// May cause a interface flicker while reloading.
+///
public unsafe class FontReloader
{
public bool Valid
@@ -19,7 +21,7 @@ public unsafe class FontReloader
Penumbra.Log.Error("Could not reload fonts, function could not be found.");
}
- private readonly AtkModule* _atkModule = null!;
+ private readonly AtkModule* _atkModule = null!;
private readonly delegate* unmanaged _reloadFontsFunc = null!;
public FontReloader()
@@ -36,7 +38,7 @@ public unsafe class FontReloader
if (atkModule == null)
return;
- _atkModule = &atkModule->AtkModule;
- _reloadFontsFunc = ((delegate* unmanaged< AtkModule*, bool, bool, void >*)_atkModule->vtbl)[Offsets.ReloadFontsVfunc];
+ _atkModule = &atkModule->AtkModule;
+ _reloadFontsFunc = ((delegate* unmanaged*)_atkModule->vtbl)[Offsets.ReloadFontsVfunc];
}
}
diff --git a/Penumbra/Interop/GameEventManager.cs b/Penumbra/Interop/Services/GameEventManager.cs
similarity index 93%
rename from Penumbra/Interop/GameEventManager.cs
rename to Penumbra/Interop/Services/GameEventManager.cs
index 1080e7b8..e6f84f53 100644
--- a/Penumbra/Interop/GameEventManager.cs
+++ b/Penumbra/Interop/Services/GameEventManager.cs
@@ -6,8 +6,8 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using OtterGui.Log;
using Penumbra.Interop.Structs;
-
-namespace Penumbra.Interop;
+
+namespace Penumbra.Interop.Services;
public unsafe class GameEventManager : IDisposable
{
@@ -56,7 +56,7 @@ public unsafe class GameEventManager : IDisposable
_characterDtorHook.Original(character);
}
- public delegate void CharacterDestructorEvent(Character* character);
+ public delegate void CharacterDestructorEvent(Character* character);
public event CharacterDestructorEvent? CharacterDestructor;
#endregion
@@ -89,7 +89,7 @@ public unsafe class GameEventManager : IDisposable
return _copyCharacterHook.Original(target, source, unk);
}
- public delegate void CopyCharacterEvent(Character* target, Character* source);
+ public delegate void CopyCharacterEvent(Character* target, Character* source);
public event CopyCharacterEvent? CopyCharacter;
#endregion
@@ -121,7 +121,7 @@ public unsafe class GameEventManager : IDisposable
return _resourceHandleDestructorHook!.Original(handle);
}
- public delegate void ResourceHandleDestructorEvent(ResourceHandle* handle);
+ public delegate void ResourceHandleDestructorEvent(ResourceHandle* handle);
public event ResourceHandleDestructorEvent? ResourceHandleDestructor;
#endregion
diff --git a/Penumbra/Interop/Services/MetaFileManager.cs b/Penumbra/Interop/Services/MetaFileManager.cs
new file mode 100644
index 00000000..382a6c84
--- /dev/null
+++ b/Penumbra/Interop/Services/MetaFileManager.cs
@@ -0,0 +1,37 @@
+using System;
+using Dalamud.Utility.Signatures;
+using FFXIVClientStructs.FFXIV.Client.System.Memory;
+using Penumbra.GameData;
+
+namespace Penumbra.Interop.Services;
+
+public unsafe class MetaFileManager
+{
+ public MetaFileManager()
+ {
+ SignatureHelper.Initialise(this);
+ }
+
+ // Allocate in the games space for file storage.
+ // We only need this if using any meta file.
+ [Signature(Sigs.GetFileSpace)]
+ private readonly IntPtr _getFileSpaceAddress = IntPtr.Zero;
+
+ public IMemorySpace* GetFileSpace()
+ => ((delegate* unmanaged)_getFileSpaceAddress)();
+
+ public void* AllocateFileMemory(ulong length, ulong alignment = 0)
+ => GetFileSpace()->Malloc(length, alignment);
+
+ public void* AllocateFileMemory(int length, int alignment = 0)
+ => AllocateFileMemory((ulong)length, (ulong)alignment);
+
+ public void* AllocateDefaultMemory(ulong length, ulong alignment = 0)
+ => GetFileSpace()->Malloc(length, alignment);
+
+ public void* AllocateDefaultMemory(int length, int alignment = 0)
+ => IMemorySpace.GetDefaultSpace()->Malloc((ulong)length, (ulong)alignment);
+
+ public void Free(IntPtr ptr, int length)
+ => IMemorySpace.Free((void*)ptr, (ulong)length);
+}
\ No newline at end of file
diff --git a/Penumbra/Interop/ResidentResourceManager.cs b/Penumbra/Interop/Services/ResidentResourceManager.cs
similarity index 59%
rename from Penumbra/Interop/ResidentResourceManager.cs
rename to Penumbra/Interop/Services/ResidentResourceManager.cs
index ac732d7c..cd20b889 100644
--- a/Penumbra/Interop/ResidentResourceManager.cs
+++ b/Penumbra/Interop/Services/ResidentResourceManager.cs
@@ -1,21 +1,21 @@
using Dalamud.Utility.Signatures;
using Penumbra.GameData;
-
-namespace Penumbra.Interop;
+
+namespace Penumbra.Interop.Services;
public unsafe class ResidentResourceManager
{
// A static pointer to the resident resource manager address.
- [Signature( Sigs.ResidentResourceManager, ScanType = ScanType.StaticAddress )]
+ [Signature(Sigs.ResidentResourceManager, ScanType = ScanType.StaticAddress)]
private readonly Structs.ResidentResourceManager** _residentResourceManagerAddress = null;
// Some attach and physics files are stored in the resident resource manager, and we need to manually trigger a reload of them to get them to apply.
- public delegate void* ResidentResourceDelegate( void* residentResourceManager );
+ public delegate void* ResidentResourceDelegate(void* residentResourceManager);
- [Signature( Sigs.LoadPlayerResources )]
+ [Signature(Sigs.LoadPlayerResources)]
public readonly ResidentResourceDelegate LoadPlayerResources = null!;
- [Signature( Sigs.UnloadPlayerResources )]
+ [Signature(Sigs.UnloadPlayerResources)]
public readonly ResidentResourceDelegate UnloadPlayerResources = null!;
public Structs.ResidentResourceManager* Address
@@ -23,17 +23,17 @@ public unsafe class ResidentResourceManager
public ResidentResourceManager()
{
- SignatureHelper.Initialise( this );
+ SignatureHelper.Initialise(this);
}
// Reload certain player resources by force.
public void Reload()
{
- if( Address != null && Address->NumResources > 0 )
+ if (Address != null && Address->NumResources > 0)
{
- Penumbra.Log.Debug( "Reload of resident resources triggered." );
- UnloadPlayerResources.Invoke( Address );
- LoadPlayerResources.Invoke( Address );
+ Penumbra.Log.Debug("Reload of resident resources triggered.");
+ UnloadPlayerResources.Invoke(Address);
+ LoadPlayerResources.Invoke(Address);
}
}
}
\ No newline at end of file
diff --git a/Penumbra/Mods/Manager/ModOptionChangeType.cs b/Penumbra/Mods/Manager/ModOptionChangeType.cs
index b4c4947e..3e6ff5c6 100644
--- a/Penumbra/Mods/Manager/ModOptionChangeType.cs
+++ b/Penumbra/Mods/Manager/ModOptionChangeType.cs
@@ -22,11 +22,13 @@ public enum ModOptionChangeType
public static class ModOptionChangeTypeExtension
{
- // Give information for each type of change.
- // If requiresSaving, collections need to be re-saved after this change.
- // If requiresReloading, caches need to be manipulated after this change.
- // If wasPrepared, caches have already removed the mod beforehand, then need add it again when this event is fired.
- // Otherwise, caches need to reload the mod itself.
+ ///
+ /// Give information for each type of change.
+ /// If requiresSaving, collections need to be re-saved after this change.
+ /// If requiresReloading, caches need to be manipulated after this change.
+ /// If wasPrepared, caches have already removed the mod beforehand, then need add it again when this event is fired.
+ /// Otherwise, caches need to reload the mod itself.
+ ///
public static void HandlingInfo( this ModOptionChangeType type, out bool requiresSaving, out bool requiresReloading, out bool wasPrepared )
{
( requiresSaving, requiresReloading, wasPrepared ) = type switch
diff --git a/Penumbra/Penumbra.cs b/Penumbra/Penumbra.cs
index e34bad28..563e6de9 100644
--- a/Penumbra/Penumbra.cs
+++ b/Penumbra/Penumbra.cs
@@ -27,9 +27,10 @@ using Penumbra.Interop.Resolver;
using Penumbra.Mods;
using CharacterUtility = Penumbra.Interop.CharacterUtility;
using DalamudUtil = Dalamud.Utility.Util;
-using ResidentResourceManager = Penumbra.Interop.ResidentResourceManager;
+using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager;
using Penumbra.Services;
-
+using Penumbra.Interop.Services;
+
namespace Penumbra;
public class Penumbra : IDalamudPlugin
diff --git a/Penumbra/PenumbraNew.cs b/Penumbra/PenumbraNew.cs
index fc1d5e84..429cd5ae 100644
--- a/Penumbra/PenumbraNew.cs
+++ b/Penumbra/PenumbraNew.cs
@@ -10,6 +10,7 @@ using Penumbra.GameData.Data;
using Penumbra.Interop;
using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver;
+using Penumbra.Interop.Services;
using Penumbra.Services;
using Penumbra.UI.Classes;
using Penumbra.Util;
diff --git a/Penumbra/Services/FilenameService.cs b/Penumbra/Services/FilenameService.cs
index 27934da8..0e883149 100644
--- a/Penumbra/Services/FilenameService.cs
+++ b/Penumbra/Services/FilenameService.cs
@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.IO;
using Dalamud.Plugin;
using OtterGui.Filesystem;
+using Penumbra.Collections;
+using Penumbra.Mods;
namespace Penumbra.Services;
@@ -25,12 +27,24 @@ public class FilenameService
ActiveCollectionsFile = Path.Combine(pi.ConfigDirectory.FullName, "active_collections.json");
}
+ /// Obtain the path of a collection file given its name. Returns an empty string if the collection is temporary.
+ public string CollectionFile(ModCollection collection)
+ => collection.Index >= 0 ? Path.Combine(CollectionDirectory, $"{collection.Name.RemoveInvalidPathSymbols()}.json") : string.Empty;
+
+ /// Obtain the path of a collection file given its name.
public string CollectionFile(string collectionName)
=> Path.Combine(CollectionDirectory, $"{collectionName.RemoveInvalidPathSymbols()}.json");
- public string LocalDataFile(string modPath)
- => Path.Combine(LocalDataDirectory, $"{modPath}.json");
+ /// Obtain the path of the local data file given a mod directory. Returns an empty string if the mod is temporary.
+ public string LocalDataFile(IModReadable mod)
+ => mod.IsTemporary ? string.Empty : LocalDataFile(mod.ModPath.FullName);
+
+ /// Obtain the path of the local data file given a mod directory.
+ public string LocalDataFile(string modDirectory)
+ => Path.Combine(LocalDataDirectory, $"{Path.GetFileName(modDirectory)}.json");
+
+ /// Enumerate all collection files.
public IEnumerable CollectionFiles
{
get
@@ -40,6 +54,7 @@ public class FilenameService
}
}
+ /// Enumerate all local data files.
public IEnumerable LocalDataFiles
{
get
@@ -48,4 +63,12 @@ public class FilenameService
return directory.Exists ? directory.EnumerateFiles("*.json") : Array.Empty();
}
}
+
+ /// Obtain the path of the meta file for a given mod. Returns an empty string if the mod is temporary.
+ public string ModMetaPath(IModReadable mod)
+ => mod.IsTemporary ? string.Empty : ModMetaPath(mod.ModPath.FullName);
+
+ /// Obtain the path of the meta file given a mod directory.
+ public string ModMetaPath(string modDirectory)
+ => Path.Combine(modDirectory, "meta.json");
}
diff --git a/Penumbra/UI/ConfigWindow.SettingsTab.cs b/Penumbra/UI/ConfigWindow.SettingsTab.cs
index d4aa093f..e6948019 100644
--- a/Penumbra/UI/ConfigWindow.SettingsTab.cs
+++ b/Penumbra/UI/ConfigWindow.SettingsTab.cs
@@ -11,7 +11,7 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using OtterGui.Widgets;
-using Penumbra.Interop;
+using Penumbra.Interop.Services;
using Penumbra.Services;
using Penumbra.UI.Classes;
diff --git a/Penumbra/UI/ConfigWindow.cs b/Penumbra/UI/ConfigWindow.cs
index 2786a86b..f212feab 100644
--- a/Penumbra/UI/ConfigWindow.cs
+++ b/Penumbra/UI/ConfigWindow.cs
@@ -7,7 +7,7 @@ using OtterGui;
using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.Api.Enums;
-using Penumbra.Interop;
+using Penumbra.Interop.Services;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI.Classes;
@@ -35,7 +35,7 @@ public sealed partial class ConfigWindow : Window, IDisposable
public void SelectMod(Mod mod)
=> _selector.SelectByValue(mod);
-
+
public ConfigWindow(CommunicatorService communicator, StartTracker timer, FontReloader fontReloader, Penumbra penumbra, ResourceWatcher watcher)
: base(GetLabel())
{