Add a toggle to advanced settings that uses reflection to change the Synchronous Load option in Dalamud.

This commit is contained in:
Ottermandias 2022-12-27 18:09:59 +01:00
parent ef19af481b
commit 5cd4b49fee
3 changed files with 134 additions and 0 deletions

View file

@ -1,3 +1,4 @@
using System;
using Dalamud.Data;
using Dalamud.Game;
using Dalamud.Game.ClientState;
@ -9,6 +10,8 @@ using Dalamud.Game.Gui;
using Dalamud.Interface;
using Dalamud.IoC;
using Dalamud.Plugin;
using System.Linq;
using System.Reflection;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
@ -33,4 +36,119 @@ public class Dalamud
[PluginService][RequiredVersion("1.0")] public static GameGui GameGui { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static KeyState KeyState { get; private set; } = null!;
// @formatter:on
private static readonly object? DalamudConfig;
private static readonly object? SettingsWindow;
private static readonly MethodInfo? SaveDalamudConfig;
public const string WaitingForPluginsOption = "IsResumeGameAfterPluginLoad";
static Dalamud()
{
try
{
var serviceType = typeof( DalamudPluginInterface ).Assembly.DefinedTypes.FirstOrDefault( t => t.Name == "Service`1" && t.IsGenericType );
var configType = typeof( DalamudPluginInterface ).Assembly.DefinedTypes.FirstOrDefault( t => t.Name == "DalamudConfiguration" );
var interfaceType = typeof( DalamudPluginInterface ).Assembly.DefinedTypes.FirstOrDefault( t => t.Name == "DalamudInterface" );
if( serviceType == null || configType == null || interfaceType == null )
{
return;
}
var configService = serviceType.MakeGenericType( configType );
var interfaceService = serviceType.MakeGenericType( interfaceType );
var configGetter = configService.GetMethod( "Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic );
var interfaceGetter = interfaceService.GetMethod( "Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic );
if( configGetter == null || interfaceGetter == null )
{
return;
}
DalamudConfig = configGetter.Invoke( null, null );
if( DalamudConfig != null )
{
SaveDalamudConfig = DalamudConfig.GetType().GetMethod( "Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
if( SaveDalamudConfig == null )
{
DalamudConfig = null;
}
var inter = interfaceGetter.Invoke( null, null );
SettingsWindow = inter?.GetType().GetField( "settingsWindow", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )?.GetValue( inter );
if( SettingsWindow == null )
{
DalamudConfig = null;
SaveDalamudConfig = null;
}
}
}
catch
{
DalamudConfig = null;
SaveDalamudConfig = null;
SettingsWindow = null;
}
}
public static bool GetDalamudConfig< T >( string fieldName, out T? value )
{
value = default;
try
{
if( DalamudConfig == null )
{
return false;
}
var getter = DalamudConfig.GetType().GetProperty( fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
if( getter == null )
{
return false;
}
var result = getter.GetValue( DalamudConfig );
if( result is not T v )
{
return false;
}
value = v;
return true;
}
catch( Exception e )
{
Penumbra.Log.Error( $"Error while fetching Dalamud Config {fieldName}:\n{e}" );
return false;
}
}
public static bool SetDalamudConfig< T >( string fieldName, in T? value, string? windowFieldName = null )
{
try
{
if( DalamudConfig == null )
{
return false;
}
var getter = DalamudConfig.GetType().GetProperty( fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
if( getter == null )
{
return false;
}
getter.SetValue( DalamudConfig, value );
if( windowFieldName != null )
{
SettingsWindow!.GetType().GetField( windowFieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )?.SetValue( SettingsWindow, value );
}
SaveDalamudConfig!.Invoke( DalamudConfig, null );
return true;
}
catch( Exception e )
{
Penumbra.Log.Error( $"Error while fetching Dalamud Config {fieldName}:\n{e}" );
return false;
}
}
}

View file

@ -330,6 +330,7 @@ public class Penumbra : IDalamudPlugin
sb.Append( $"> **`Free Drive Space: `** {( drive != null ? Functions.HumanReadableSize( drive.AvailableFreeSpace ) : "Unknown" )}\n" );
sb.Append( $"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\n" );
sb.Append( $"> **`Debug Mode: `** {Config.DebugMode}\n" );
sb.Append( $"> **`Synchronous Load (Dalamud): `** {(Dalamud.GetDalamudConfig( Dalamud.WaitingForPluginsOption, out bool v ) ? v.ToString() : "Unknown")}\n" );
sb.Append( $"> **`Logging: `** Full: {Config.EnableFullResourceLogging}, Resource: {Config.EnableResourceLogging}\n" );
sb.Append( $"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n" );
sb.AppendLine( "**Mods**" );

View file

@ -30,6 +30,7 @@ public partial class ConfigWindow
"Normally, metadata changes that equal their default values, which are sometimes exported by TexTools, are discarded. "
+ "Toggle this to keep them, for example if an option in a mod is supposed to disable a metadata change from a prior option.",
Penumbra.Config.KeepDefaultMetaChanges, v => Penumbra.Config.KeepDefaultMetaChanges = v );
DrawWaitForPluginsReflection();
DrawRequestedResourceLogging();
DrawEnableHttpApiBox();
DrawEnableDebugModeBox();
@ -158,5 +159,19 @@ public partial class ConfigWindow
FontReloader.Reload();
}
}
private static void DrawWaitForPluginsReflection()
{
if( !Dalamud.GetDalamudConfig( Dalamud.WaitingForPluginsOption, out bool value ) )
{
using var disabled = ImRaii.Disabled();
Checkbox( "Wait for Plugins on Startup (Disabled, can not access Dalamud Configuration)", string.Empty, false, v => { } );
}
else
{
Checkbox( "Wait for Plugins on Startup", "This changes a setting in the Dalamud Configuration found at /xlsettings -> General.", value,
v => Dalamud.SetDalamudConfig( Dalamud.WaitingForPluginsOption, v, "doWaitForPluginsOnStartup" ) );
}
}
}
}