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\SeFileDescriptor.cs" />
<Compile Include="ResourceMod.cs" />
<Compile Include="Penumbra.cs" />
<Compile Include="ResourceLoader.cs" />
<Compile Include="Structs\ResourceHandle.cs" />
<Compile Include="SettingsInterface.cs" />
<Compile Include="Util\Crc32.cs" />

View file

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

View file

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

View file

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