merge in upstream player resource reloading

This commit is contained in:
Adam 2020-09-02 22:54:21 +10:00
parent 0e7650f89b
commit 36250d5e54
4 changed files with 65 additions and 13 deletions

View file

@ -80,7 +80,7 @@
<Compile Include="Structs\FileMode.cs" /> <Compile Include="Structs\FileMode.cs" />
<Compile Include="Structs\SeFileDescriptor.cs" /> <Compile Include="Structs\SeFileDescriptor.cs" />
<Compile Include="ResourceMod.cs" /> <Compile Include="ResourceMod.cs" />
<Compile Include="Penumbra.cs" /> <Compile Include="ResourceLoader.cs" />
<Compile Include="Structs\ResourceHandle.cs" /> <Compile Include="Structs\ResourceHandle.cs" />
<Compile Include="SettingsInterface.cs" /> <Compile Include="SettingsInterface.cs" />
<Compile Include="Util\Crc32.cs" /> <Compile Include="Util\Crc32.cs" />

View file

@ -13,7 +13,7 @@ namespace Penumbra
public DalamudPluginInterface PluginInterface { get; set; } public DalamudPluginInterface PluginInterface { get; set; }
public Configuration Configuration { get; set; } public Configuration Configuration { get; set; }
public Penumbra Penumbra { get; set; } public ResourceLoader ResourceLoader { get; set; }
public ModManager ModManager { get; set; } public ModManager ModManager { get; set; }
@ -26,13 +26,10 @@ namespace Penumbra
Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration(); Configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
Configuration.Initialize( PluginInterface ); Configuration.Initialize( PluginInterface );
SettingsInterface = new SettingsInterface( this );
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
ModManager = new ModManager( new DirectoryInfo( Configuration.BaseFolder ) ); ModManager = new ModManager( new DirectoryInfo( Configuration.BaseFolder ) );
ModManager.DiscoverMods(); ModManager.DiscoverMods();
Penumbra = new Penumbra( this ); ResourceLoader = new ResourceLoader( this );
PluginInterface.CommandManager.AddHandler( CommandName, new CommandInfo( OnCommand ) PluginInterface.CommandManager.AddHandler( CommandName, new CommandInfo( OnCommand )
@ -40,8 +37,11 @@ namespace Penumbra
HelpMessage = "/penumbra 0 will disable penumbra, /penumbra 1 will enable it." HelpMessage = "/penumbra 0 will disable penumbra, /penumbra 1 will enable it."
} ); } );
Penumbra.Init(); ResourceLoader.Init();
Penumbra.Enable(); ResourceLoader.Enable();
SettingsInterface = new SettingsInterface( this );
PluginInterface.UiBuilder.OnBuildUi += SettingsInterface.Draw;
} }
public void Dispose() public void Dispose()
@ -51,7 +51,7 @@ namespace Penumbra
PluginInterface.CommandManager.RemoveHandler( CommandName ); PluginInterface.CommandManager.RemoveHandler( CommandName );
PluginInterface.Dispose(); PluginInterface.Dispose();
Penumbra.Dispose(); ResourceLoader.Dispose();
} }
private void OnCommand( string command, string args ) private void OnCommand( string command, string args )
@ -60,9 +60,9 @@ namespace Penumbra
Configuration.IsEnabled = args[ 0 ] == '1'; Configuration.IsEnabled = args[ 0 ] == '1';
if( Configuration.IsEnabled ) if( Configuration.IsEnabled )
Penumbra.Enable(); ResourceLoader.Enable();
else else
Penumbra.Disable(); ResourceLoader.Disable();
} }
} }
} }

View file

@ -11,7 +11,7 @@ using Penumbra.Extensions;
namespace Penumbra namespace Penumbra
{ {
public class Penumbra : IDisposable public class ResourceLoader : IDisposable
{ {
public Plugin Plugin { get; set; } public Plugin Plugin { get; set; }
@ -31,6 +31,10 @@ namespace Penumbra
public unsafe delegate void* GetResourceAsyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType, public unsafe delegate void* GetResourceAsyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType,
uint* pResourceHash, char* pPath, void* pUnknown, bool isUnknown ); uint* pResourceHash, char* pPath, void* pUnknown, bool isUnknown );
public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager );
public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager );
// Hooks // Hooks
public Hook< GetResourceSyncPrototype > GetResourceSyncHook { get; private set; } public Hook< GetResourceSyncPrototype > GetResourceSyncHook { get; private set; }
@ -41,7 +45,18 @@ namespace Penumbra
public ReadFilePrototype ReadFile { get; private set; } 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; Plugin = plugin;
Crc32 = new Crc32(); Crc32 = new Crc32();
@ -73,6 +88,22 @@ namespace Penumbra
new GetResourceAsyncPrototype( GetResourceAsyncHandler ) ); new GetResourceAsyncPrototype( GetResourceAsyncHandler ) );
ReadFile = Marshal.GetDelegateForFunctionPointer< ReadFilePrototype >( readFileAddress ); 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 ) ); var gameFsPath = Marshal.PtrToStringAnsi( new IntPtr( pPath ) );
if( LogAllFiles )
PluginLog.Log( "[ReadSqPack] {0}", gameFsPath );
var candidate = Plugin.ModManager.GetCandidateForGameFile( gameFsPath ); var candidate = Plugin.ModManager.GetCandidateForGameFile( gameFsPath );
// path must be < 260 because statically defined array length :( // path must be < 260 because statically defined array length :(
@ -156,6 +190,12 @@ namespace Penumbra
return ReadFile( pFileHandler, pFileDesc, priority, isSync ); return ReadFile( pFileHandler, pFileDesc, priority, isSync );
} }
public unsafe void ReloadPlayerResource()
{
UnloadPlayerResources( PlayerResourceManagerPtr );
LoadPlayerResources( PlayerResourceManagerPtr );
}
public void Enable() public void Enable()
{ {
if( IsEnabled ) if( IsEnabled )

View file

@ -74,6 +74,11 @@ namespace Penumbra
{ {
ReloadMods(); ReloadMods();
} }
if( ImGui.Button( "Reload Player Resource" ) )
{
_plugin.ResourceLoader.ReloadPlayerResource();
}
if( !_isImportRunning ) if( !_isImportRunning )
{ {
@ -127,7 +132,14 @@ namespace Penumbra
} }
if( ImGui.Button( "Save Settings" ) ) if( ImGui.Button( "Save Settings" ) )
{
_plugin.Configuration.Save(); _plugin.Configuration.Save();
}
if( _plugin.ResourceLoader != null )
{
ImGui.Checkbox( "DEBUG Log all loaded files", ref _plugin.ResourceLoader.LogAllFiles );
}
ImGui.EndTabItem(); ImGui.EndTabItem();
} }