From 36250d5e5469dd5eba4c54a3c2ebd29ed625c8ad Mon Sep 17 00:00:00 2001 From: Adam <893184+NotAdam@users.noreply.github.com> Date: Wed, 2 Sep 2020 22:54:21 +1000 Subject: [PATCH] merge in upstream player resource reloading --- Penumbra/Penumbra.csproj | 2 +- Penumbra/Plugin.cs | 20 +++++----- Penumbra/{Penumbra.cs => ResourceLoader.cs} | 44 ++++++++++++++++++++- Penumbra/SettingsInterface.cs | 12 ++++++ 4 files changed, 65 insertions(+), 13 deletions(-) rename Penumbra/{Penumbra.cs => ResourceLoader.cs} (78%) diff --git a/Penumbra/Penumbra.csproj b/Penumbra/Penumbra.csproj index 03a3bda3..28f920c1 100644 --- a/Penumbra/Penumbra.csproj +++ b/Penumbra/Penumbra.csproj @@ -80,7 +80,7 @@ - + diff --git a/Penumbra/Plugin.cs b/Penumbra/Plugin.cs index c455f954..f6ab017c 100644 --- a/Penumbra/Plugin.cs +++ b/Penumbra/Plugin.cs @@ -13,7 +13,7 @@ namespace Penumbra public DalamudPluginInterface PluginInterface { get; set; } public Configuration Configuration { get; set; } - public Penumbra Penumbra { get; set; } + public ResourceLoader ResourceLoader { get; set; } public ModManager ModManager { get; set; } @@ -26,13 +26,10 @@ namespace Penumbra Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration(); Configuration.Initialize( PluginInterface ); - SettingsInterface = new SettingsInterface( this ); - PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw; - ModManager = new ModManager( new DirectoryInfo( Configuration.BaseFolder ) ); ModManager.DiscoverMods(); - Penumbra = new Penumbra( this ); + ResourceLoader = new ResourceLoader( this ); PluginInterface.CommandManager.AddHandler( CommandName, new CommandInfo( OnCommand ) @@ -40,8 +37,11 @@ namespace Penumbra HelpMessage = "/penumbra 0 will disable penumbra, /penumbra 1 will enable it." } ); - Penumbra.Init(); - Penumbra.Enable(); + ResourceLoader.Init(); + ResourceLoader.Enable(); + + SettingsInterface = new SettingsInterface( this ); + PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw; } public void Dispose() @@ -51,7 +51,7 @@ namespace Penumbra PluginInterface.CommandManager.RemoveHandler( CommandName ); PluginInterface.Dispose(); - Penumbra.Dispose(); + ResourceLoader.Dispose(); } private void OnCommand( string command, string args ) @@ -60,9 +60,9 @@ namespace Penumbra Configuration.IsEnabled = args[ 0 ] == '1'; if( Configuration.IsEnabled ) - Penumbra.Enable(); + ResourceLoader.Enable(); else - Penumbra.Disable(); + ResourceLoader.Disable(); } } } \ No newline at end of file diff --git a/Penumbra/Penumbra.cs b/Penumbra/ResourceLoader.cs similarity index 78% rename from Penumbra/Penumbra.cs rename to Penumbra/ResourceLoader.cs index 08b530b9..dfc6a19b 100644 --- a/Penumbra/Penumbra.cs +++ b/Penumbra/ResourceLoader.cs @@ -11,7 +11,7 @@ using Penumbra.Extensions; namespace Penumbra { - public class Penumbra : IDisposable + public class ResourceLoader : IDisposable { public Plugin Plugin { get; set; } @@ -31,6 +31,10 @@ namespace Penumbra public unsafe delegate void* GetResourceAsyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType, uint* pResourceHash, char* pPath, void* pUnknown, bool isUnknown ); + public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager ); + + public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager ); + // Hooks public Hook< GetResourceSyncPrototype > GetResourceSyncHook { get; private set; } @@ -41,7 +45,18 @@ namespace Penumbra public ReadFilePrototype ReadFile { get; private set; } - public Penumbra( Plugin plugin ) + public LoadPlayerResourcesPrototype LoadPlayerResources { get; private set; } + public UnloadPlayerResourcesPrototype UnloadPlayerResources { get; private set; } + + // Object addresses + private IntPtr _playerResourceManagerAddress; + public IntPtr PlayerResourceManagerPtr => Marshal.ReadIntPtr( _playerResourceManagerAddress ); + + + public bool LogAllFiles = false; + + + public ResourceLoader( Plugin plugin ) { Plugin = plugin; Crc32 = new Crc32(); @@ -73,6 +88,22 @@ namespace Penumbra new GetResourceAsyncPrototype( GetResourceAsyncHandler ) ); ReadFile = Marshal.GetDelegateForFunctionPointer< ReadFilePrototype >( readFileAddress ); + + ///// + + var loadPlayerResourcesAddress = + scanner.ScanText( + "E8 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? BA ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? 48 8B 48 30 48 8B 01 FF 50 10 48 85 C0 74 0A " ); + var unloadPlayerResourcesAddress = + scanner.ScanText( "41 55 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 4C 8B E9 48 83 C1 08" ); + + _playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" ); + + LoadPlayerResources = + Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress ); + UnloadPlayerResources = + Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress ); + ReadFile = Marshal.GetDelegateForFunctionPointer< ReadFilePrototype >( readFileAddress ); } @@ -95,6 +126,9 @@ namespace Penumbra { var gameFsPath = Marshal.PtrToStringAnsi( new IntPtr( pPath ) ); + if( LogAllFiles ) + PluginLog.Log( "[ReadSqPack] {0}", gameFsPath ); + var candidate = Plugin.ModManager.GetCandidateForGameFile( gameFsPath ); // path must be < 260 because statically defined array length :( @@ -156,6 +190,12 @@ namespace Penumbra return ReadFile( pFileHandler, pFileDesc, priority, isSync ); } + public unsafe void ReloadPlayerResource() + { + UnloadPlayerResources( PlayerResourceManagerPtr ); + LoadPlayerResources( PlayerResourceManagerPtr ); + } + public void Enable() { if( IsEnabled ) diff --git a/Penumbra/SettingsInterface.cs b/Penumbra/SettingsInterface.cs index 6060a334..3aed9516 100644 --- a/Penumbra/SettingsInterface.cs +++ b/Penumbra/SettingsInterface.cs @@ -74,6 +74,11 @@ namespace Penumbra { ReloadMods(); } + + if( ImGui.Button( "Reload Player Resource" ) ) + { + _plugin.ResourceLoader.ReloadPlayerResource(); + } if( !_isImportRunning ) { @@ -127,7 +132,14 @@ namespace Penumbra } if( ImGui.Button( "Save Settings" ) ) + { _plugin.Configuration.Save(); + } + + if( _plugin.ResourceLoader != null ) + { + ImGui.Checkbox( "DEBUG Log all loaded files", ref _plugin.ResourceLoader.LogAllFiles ); + } ImGui.EndTabItem(); }