Some further stuff.

This commit is contained in:
Ottermandias 2023-03-17 13:19:23 +01:00
parent 0df12a34cb
commit 3fc724b7ee
15 changed files with 106 additions and 73 deletions

View file

@ -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 );
}

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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.
/// <summary>
/// Handle font reloading via game functions.
/// May cause a interface flicker while reloading.
/// </summary>
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<AtkModule*, bool, bool, void> _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*, bool, bool, void>*)_atkModule->vtbl)[Offsets.ReloadFontsVfunc];
}
}

View file

@ -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

View file

@ -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<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);
}

View file

@ -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);
}
}
}

View file

@ -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.
/// <summary>
/// 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.
/// </summary>
public static void HandlingInfo( this ModOptionChangeType type, out bool requiresSaving, out bool requiresReloading, out bool wasPrepared )
{
( requiresSaving, requiresReloading, wasPrepared ) = type switch

View file

@ -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

View file

@ -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;

View file

@ -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");
}
/// <summary> Obtain the path of a collection file given its name. Returns an empty string if the collection is temporary. </summary>
public string CollectionFile(ModCollection collection)
=> collection.Index >= 0 ? Path.Combine(CollectionDirectory, $"{collection.Name.RemoveInvalidPathSymbols()}.json") : string.Empty;
/// <summary> Obtain the path of a collection file given its name. </summary>
public string CollectionFile(string collectionName)
=> Path.Combine(CollectionDirectory, $"{collectionName.RemoveInvalidPathSymbols()}.json");
public string LocalDataFile(string modPath)
=> Path.Combine(LocalDataDirectory, $"{modPath}.json");
/// <summary> Obtain the path of the local data file given a mod directory. Returns an empty string if the mod is temporary. </summary>
public string LocalDataFile(IModReadable mod)
=> mod.IsTemporary ? string.Empty : LocalDataFile(mod.ModPath.FullName);
/// <summary> Obtain the path of the local data file given a mod directory. </summary>
public string LocalDataFile(string modDirectory)
=> Path.Combine(LocalDataDirectory, $"{Path.GetFileName(modDirectory)}.json");
/// <summary> Enumerate all collection files. </summary>
public IEnumerable<FileInfo> CollectionFiles
{
get
@ -40,6 +54,7 @@ public class FilenameService
}
}
/// <summary> Enumerate all local data files. </summary>
public IEnumerable<FileInfo> LocalDataFiles
{
get
@ -48,4 +63,12 @@ public class FilenameService
return directory.Exists ? directory.EnumerateFiles("*.json") : Array.Empty<FileInfo>();
}
}
/// <summary> Obtain the path of the meta file for a given mod. Returns an empty string if the mod is temporary. </summary>
public string ModMetaPath(IModReadable mod)
=> mod.IsTemporary ? string.Empty : ModMetaPath(mod.ModPath.FullName);
/// <summary> Obtain the path of the meta file given a mod directory. </summary>
public string ModMetaPath(string modDirectory)
=> Path.Combine(modDirectory, "meta.json");
}

View file

@ -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;

View file

@ -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())
{