Clarified GameUtils name and turned to service.

This commit is contained in:
Ottermandias 2021-03-04 16:33:50 +01:00
parent 925e9fef27
commit b97d0ddc37
5 changed files with 38 additions and 30 deletions

View file

@ -4,10 +4,12 @@ using Dalamud.Plugin;
using Penumbra.Structs;
using Reloaded.Hooks.Definitions.X64;
namespace Penumbra.Game
namespace Penumbra.Hooks
{
public class GameUtils
public class GameResourceManagement
{
private const int NumResources = 85;
[Function( CallingConventions.Microsoft )]
public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager );
@ -15,7 +17,7 @@ namespace Penumbra.Game
public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager );
[Function( CallingConventions.Microsoft )]
public unsafe delegate void* LoadCharacterResourcesPrototype( CharacterResourceManager *pCharacterResourceManager );
public unsafe delegate void* LoadCharacterResourcesPrototype( CharacterResourceManager* pCharacterResourceManager );
[Function( CallingConventions.Microsoft )]
public unsafe delegate void* UnloadCharacterResourcePrototype( IntPtr resource );
@ -30,10 +32,11 @@ namespace Penumbra.Game
private readonly IntPtr _playerResourceManagerAddress;
public IntPtr PlayerResourceManagerPtr => Marshal.ReadIntPtr( _playerResourceManagerAddress );
private readonly IntPtr _characterResourceManagerAddress;
public unsafe CharacterResourceManager* CharacterResourceManagerPtr =>
( CharacterResourceManager* )Marshal.ReadIntPtr( _characterResourceManagerAddress ).ToPointer();
public GameUtils( DalamudPluginInterface pluginInterface )
public GameResourceManagement( DalamudPluginInterface pluginInterface )
{
var scanner = pluginInterface.TargetModuleScanner;
@ -42,16 +45,18 @@ namespace Penumbra.Game
"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" );
var loadCharacterResourcesAddress = scanner.ScanText( "E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
var loadCharacterResourcesAddress = scanner.ScanText( "E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
var unloadCharacterResourceAddress = scanner.ScanText( "E8 ?? ?? ?? FF 4C 89 37 48 83 C7 08 48 83 ED 01 75 ?? 48 8B CB" );
_playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
_characterResourceManagerAddress = scanner.GetStaticAddressFromSig( "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
_playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
_characterResourceManagerAddress =
scanner.GetStaticAddressFromSig( "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
LoadPlayerResources = Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress );
UnloadPlayerResources = Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress );
LoadPlayerResources = Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress );
UnloadPlayerResources = Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress );
LoadCharacterResources = Marshal.GetDelegateForFunctionPointer< LoadCharacterResourcesPrototype >( loadCharacterResourcesAddress );
UnloadCharacterResource = Marshal.GetDelegateForFunctionPointer<UnloadCharacterResourcePrototype>( unloadCharacterResourceAddress );
UnloadCharacterResource =
Marshal.GetDelegateForFunctionPointer< UnloadCharacterResourcePrototype >( unloadCharacterResourceAddress );
}
public unsafe void ReloadPlayerResources()
@ -62,34 +67,33 @@ namespace Penumbra.Game
LoadPlayerResources( PlayerResourceManagerPtr );
}
public unsafe string ResourceToPath( byte *resource ) =>
Marshal.PtrToStringAnsi( new IntPtr( *(char **)( resource + 9 * 8 ) ) );
public unsafe string ResourceToPath( byte* resource )
=> Marshal.PtrToStringAnsi( new IntPtr( *( char** )( resource + 9 * 8 ) ) )!;
public unsafe void ReloadCharacterResources()
public unsafe void ReloadCharacterResources()
{
var oldResources = new IntPtr[85];
var resources = new IntPtr(&CharacterResourceManagerPtr->Resources);
var pResources = (void **)resources.ToPointer();
var oldResources = new IntPtr[NumResources];
var resources = new IntPtr( &CharacterResourceManagerPtr->Resources );
var pResources = ( void** )resources.ToPointer();
Marshal.Copy( resources, oldResources, 0, 85 );
Marshal.Copy( resources, oldResources, 0, NumResources );
LoadCharacterResources( CharacterResourceManagerPtr );
for( var i = 0; i < 85; i++ )
for( var i = 0; i < NumResources; i++ )
{
if( oldResources[ i ].ToPointer() == pResources[ i ] )
{
PluginLog.Debug($"Unchanged resource: {ResourceToPath( ( byte* )oldResources[i].ToPointer() )}");
PluginLog.Debug( $"Unchanged resource: {ResourceToPath( ( byte* )oldResources[ i ].ToPointer() )}" );
continue;
}
PluginLog.Debug( "Freeing " +
$"{ResourceToPath( ( byte* )oldResources[i].ToPointer() )}, replaced with " +
$"{ResourceToPath( ( byte* )pResources[i] )}" );
$"{ResourceToPath( ( byte* )oldResources[ i ].ToPointer() )}, replaced with " +
$"{ResourceToPath( ( byte* )pResources[ i ] )}" );
UnloadCharacterResource( oldResources[ i ] );
}
}
}
}

View file

@ -35,9 +35,11 @@ namespace Penumbra.Models
try
{
var meta = JsonConvert.DeserializeObject< ModMeta >( File.ReadAllText( filePath ), JsonSettings );
meta.HasGroupWithConfig = meta.Groups.Count > 0
&& meta.Groups.Values.Any( G => G.SelectionType == SelectType.Multi || G.Options.Count > 1 );
if( meta != null )
{
meta.HasGroupWithConfig = meta.Groups.Count > 0
&& meta.Groups.Values.Any( G => G.SelectionType == SelectType.Multi || G.Options.Count > 1 );
}
return meta;
}
catch( Exception )

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Dalamud.Plugin;
using Penumbra.Hooks;
using Penumbra.Models;
using Penumbra.Util;
@ -65,7 +66,7 @@ namespace Penumbra.Mods
if (changedSettings)
Mods.Save();
_plugin!.GameUtils!.ReloadPlayerResources();
Service<GameResourceManagement>.Get().ReloadPlayerResources();
}
private void ProcessSwappedFiles( Dictionary< GamePath, string > registeredFiles, ResourceMod mod, ModInfo settings )

View file

@ -28,7 +28,6 @@ namespace Penumbra
public Configuration? Configuration { get; set; }
public ResourceLoader? ResourceLoader { get; set; }
public SettingsInterface? SettingsInterface { get; set; }
public GameUtils? GameUtils { get; set; }
public SoundShit? SoundShit { get; set; }
private WebServer? _webServer;
@ -41,8 +40,9 @@ namespace Penumbra
Configuration.Initialize( PluginInterface );
SoundShit = new SoundShit( this );
GameUtils = new GameUtils( PluginInterface );
var gameUtils = Service< GameResourceManagement >.Set( PluginInterface );
var modManager = Service< ModManager >.Set( this );
modManager.DiscoverMods( Configuration.CurrentCollection );
@ -56,7 +56,7 @@ namespace Penumbra
ResourceLoader.Init();
ResourceLoader.Enable();
GameUtils.ReloadPlayerResources();
gameUtils.ReloadPlayerResources();
SettingsInterface = new SettingsInterface( this );

View file

@ -1,5 +1,6 @@
using System.Diagnostics;
using ImGuiNET;
using Penumbra.Hooks;
namespace Penumbra.UI
{
@ -131,7 +132,7 @@ namespace Penumbra.UI
{
if( ImGui.Button( LabelReloadResource ) )
{
_base._plugin!.GameUtils!.ReloadPlayerResources();
Service<GameResourceManagement>.Get().ReloadPlayerResources();
}
}