From 59fa4c4fe4179ca593021f549ceb223d0bb935c9 Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Mon, 3 Jan 2022 11:14:41 +0100 Subject: [PATCH] Temporary fix for E4S crashes. --- Penumbra/Interop/ResourceLoader.cs | 48 ++- Penumbra/UI/MenuTabs/TabDebug.cs | 593 +++++++++++++++-------------- 2 files changed, 343 insertions(+), 298 deletions(-) diff --git a/Penumbra/Interop/ResourceLoader.cs b/Penumbra/Interop/ResourceLoader.cs index 0ce2be54..5cfc23f3 100644 --- a/Penumbra/Interop/ResourceLoader.cs +++ b/Penumbra/Interop/ResourceLoader.cs @@ -5,6 +5,7 @@ using System.Text; using System.Text.RegularExpressions; using Dalamud.Hooking; using Dalamud.Logging; +using Lumina.Excel.GeneratedSheets; using Penumbra.GameData.Util; using Penumbra.Mods; using Penumbra.Structs; @@ -18,6 +19,7 @@ public class ResourceLoader : IDisposable public Penumbra Penumbra { get; set; } public bool IsEnabled { get; set; } + public bool HacksEnabled { get; set; } public Crc32 Crc32 { get; } @@ -126,6 +128,29 @@ public class ResourceLoader : IDisposable LoadMdlFileExternHook = new Hook< LoadMdlFileExternPrototype >( loadMdlFileExternAddress, LoadMdlFileExternDetour ); } + private bool CheckForTerritory() + { + var territory = Dalamud.GameData.GetExcelSheet< TerritoryType >()?.GetRow( Dalamud.ClientState.TerritoryType ); + var bad = territory?.Unknown40 ?? false; + switch( bad ) + { + case true when HacksEnabled: + CheckFileStateHook?.Disable(); + LoadTexFileExternHook?.Disable(); + LoadMdlFileExternHook?.Disable(); + HacksEnabled = false; + return bad; + case false when Penumbra.Config.IsEnabled && !HacksEnabled: + CheckFileStateHook?.Enable(); + LoadTexFileExternHook?.Enable(); + LoadMdlFileExternHook?.Enable(); + HacksEnabled = true; + break; + } + + return bad; + } + private static bool CheckFileStateDetour( IntPtr _, ulong _2 ) => true; @@ -198,6 +223,11 @@ public class ResourceLoader : IDisposable bool isUnknown ) { + if( CheckForTerritory() ) + { + return CallOriginalHandler( isSync, pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown ); + } + string file; var modManager = Service< ModManager >.Get(); @@ -247,6 +277,11 @@ public class ResourceLoader : IDisposable private unsafe byte ReadSqpackHandler( IntPtr pFileHandler, SeFileDescriptor* pFileDesc, int priority, bool isSync ) { + if( CheckForTerritory() ) + { + return ReadSqpackHook?.Original( pFileHandler, pFileDesc, priority, isSync ) ?? 0; + } + if( ReadFile == null || pFileDesc == null || pFileDesc->ResourceHandle == null ) { PluginLog.Error( "THIS SHOULD NOT HAPPEN" ); @@ -286,7 +321,12 @@ public class ResourceLoader : IDisposable return; } - if( ReadSqpackHook == null || GetResourceSyncHook == null || GetResourceAsyncHook == null || CheckFileStateHook == null || LoadTexFileExternHook == null || LoadMdlFileExternHook == null) + if( ReadSqpackHook == null + || GetResourceSyncHook == null + || GetResourceAsyncHook == null + || CheckFileStateHook == null + || LoadTexFileExternHook == null + || LoadMdlFileExternHook == null ) { PluginLog.Error( "[GetResourceHandler] Could not activate hooks because at least one was not set." ); return; @@ -299,7 +339,8 @@ public class ResourceLoader : IDisposable LoadTexFileExternHook.Enable(); LoadMdlFileExternHook.Enable(); - IsEnabled = true; + IsEnabled = true; + HacksEnabled = true; } public void Disable() @@ -315,7 +356,8 @@ public class ResourceLoader : IDisposable CheckFileStateHook?.Disable(); LoadTexFileExternHook?.Disable(); LoadMdlFileExternHook?.Disable(); - IsEnabled = false; + IsEnabled = false; + HacksEnabled = false; } public void Dispose() diff --git a/Penumbra/UI/MenuTabs/TabDebug.cs b/Penumbra/UI/MenuTabs/TabDebug.cs index a57697d0..ea46be36 100644 --- a/Penumbra/UI/MenuTabs/TabDebug.cs +++ b/Penumbra/UI/MenuTabs/TabDebug.cs @@ -17,39 +17,39 @@ using Penumbra.Mods; using Penumbra.UI.Custom; using Penumbra.Util; -namespace Penumbra.UI +namespace Penumbra.UI; + +public partial class SettingsInterface { - public partial class SettingsInterface + private static void DrawDebugTabPlayers() { - private static void DrawDebugTabPlayers() + if( !ImGui.CollapsingHeader( "Players##Debug" ) ) { - if( !ImGui.CollapsingHeader( "Players##Debug" ) ) - { - return; - } + return; + } - var players = Penumbra.PlayerWatcher.WatchedPlayers().ToArray(); - var count = players.Sum( s => Math.Max(1, s.Item2.Length) ); - if( count == 0 ) - { - return; - } + var players = Penumbra.PlayerWatcher.WatchedPlayers().ToArray(); + var count = players.Sum( s => Math.Max( 1, s.Item2.Length ) ); + if( count == 0 ) + { + return; + } - if( !ImGui.BeginTable( "##ObjectTable", 13, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX, - new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 4 * count ) ) ) - { - return; - } + if( !ImGui.BeginTable( "##ObjectTable", 13, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX, + new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 4 * count ) ) ) + { + return; + } - using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); + using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); - var identifier = GameData.GameData.GetIdentifier(); + var identifier = GameData.GameData.GetIdentifier(); - foreach( var (actor, equip) in players.SelectMany( kvp => kvp.Item2.Any() - ? kvp.Item2 - .Select( x => ( $"{kvp.Item1} ({x.Item1})", x.Item2 ) ) - : new[] { ( kvp.Item1, new CharacterEquipment() ) } ) ) - { + foreach( var (actor, equip) in players.SelectMany( kvp => kvp.Item2.Any() + ? kvp.Item2 + .Select( x => ( $"{kvp.Item1} ({x.Item1})", x.Item2 ) ) + : new[] { ( kvp.Item1, new CharacterEquipment() ) } ) ) + { // @formatter:off ImGui.TableNextRow(); ImGui.TableNextColumn(); @@ -115,295 +115,298 @@ namespace Penumbra.UI ImGui.Text( identifier.Identify( equip.LFinger.Set, 0, equip.LFinger.Variant, EquipSlot.LFinger )?.Name.ToString() ?? "Unknown" ); ImGui.TableNextColumn(); ImGui.Text( identifier.Identify( equip.RFinger.Set, 0, equip.RFinger.Variant, EquipSlot.LFinger )?.Name.ToString() ?? "Unknown" ); - // @formatter:on - } + // @formatter:on + } + } + + private static void PrintValue( string name, string value ) + { + ImGui.TableNextRow(); + ImGui.TableNextColumn(); + ImGui.Text( name ); + ImGui.TableNextColumn(); + ImGui.Text( value ); + } + + private void DrawDebugTabGeneral() + { + if( !ImGui.CollapsingHeader( "General##Debug" ) ) + { + return; } - private static void PrintValue( string name, string value ) + if( !ImGui.BeginTable( "##DebugGeneralTable", 2, ImGuiTableFlags.SizingFixedFit, + new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 1 ) ) ) { - ImGui.TableNextRow(); - ImGui.TableNextColumn(); - ImGui.Text( name ); - ImGui.TableNextColumn(); - ImGui.Text( value ); + return; } - private static void DrawDebugTabGeneral() + using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); + + var manager = Service< ModManager >.Get(); + PrintValue( "Active Collection", manager.Collections.ActiveCollection.Name ); + PrintValue( " has Cache", ( manager.Collections.ActiveCollection.Cache != null ).ToString() ); + PrintValue( "Current Collection", manager.Collections.CurrentCollection.Name ); + PrintValue( " has Cache", ( manager.Collections.CurrentCollection.Cache != null ).ToString() ); + PrintValue( "Default Collection", manager.Collections.DefaultCollection.Name ); + PrintValue( " has Cache", ( manager.Collections.DefaultCollection.Cache != null ).ToString() ); + PrintValue( "Forced Collection", manager.Collections.ForcedCollection.Name ); + PrintValue( " has Cache", ( manager.Collections.ForcedCollection.Cache != null ).ToString() ); + PrintValue( "Mod Manager BasePath", manager.BasePath?.Name ?? "NULL" ); + PrintValue( "Mod Manager BasePath-Full", manager.BasePath?.FullName ?? "NULL" ); + PrintValue( "Mod Manager BasePath IsRooted", Path.IsPathRooted( Penumbra.Config.ModDirectory ).ToString() ); + PrintValue( "Mod Manager BasePath Exists", + manager.BasePath != null ? Directory.Exists( manager.BasePath.FullName ).ToString() : false.ToString() ); + PrintValue( "Mod Manager Valid", manager.Valid.ToString() ); + PrintValue( "Mod Manager Temp Path", manager.TempPath?.FullName ?? "NULL" ); + PrintValue( "Mod Manager Temp Path IsRooted", + ( !Penumbra.Config.TempDirectory.Any() || Path.IsPathRooted( Penumbra.Config.TempDirectory ) ).ToString() ); + PrintValue( "Mod Manager Temp Path Exists", + manager.TempPath != null ? Directory.Exists( manager.TempPath.FullName ).ToString() : false.ToString() ); + PrintValue( "Mod Manager Temp Path IsWritable", manager.TempWritable.ToString() ); + PrintValue( "Resource Loader Enabled", _penumbra.ResourceLoader.IsEnabled.ToString() ); + PrintValue( "Resource Loader Hacks Enabled", _penumbra.ResourceLoader.HacksEnabled.ToString() ); + } + + private void DrawDebugTabRedraw() + { + if( !ImGui.CollapsingHeader( "Redrawing##Debug" ) ) { - if( !ImGui.CollapsingHeader( "General##Debug" ) ) - { - return; - } - - if( !ImGui.BeginTable( "##DebugGeneralTable", 2, ImGuiTableFlags.SizingFixedFit, - new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 1 ) ) ) - { - return; - } - - using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); - - var manager = Service< ModManager >.Get(); - PrintValue( "Active Collection", manager.Collections.ActiveCollection.Name ); - PrintValue( " has Cache", (manager.Collections.ActiveCollection.Cache != null).ToString() ); - PrintValue( "Current Collection", manager.Collections.CurrentCollection.Name ); - PrintValue( " has Cache", ( manager.Collections.CurrentCollection.Cache != null ).ToString() ); - PrintValue( "Default Collection", manager.Collections.DefaultCollection.Name ); - PrintValue( " has Cache", ( manager.Collections.DefaultCollection.Cache != null ).ToString() ); - PrintValue( "Forced Collection", manager.Collections.ForcedCollection.Name ); - PrintValue( " has Cache", ( manager.Collections.ForcedCollection.Cache != null ).ToString() ); - PrintValue( "Mod Manager BasePath", manager.BasePath?.Name ?? "NULL" ); - PrintValue( "Mod Manager BasePath-Full", manager.BasePath?.FullName ?? "NULL" ); - PrintValue( "Mod Manager BasePath IsRooted", Path.IsPathRooted( Penumbra.Config.ModDirectory ).ToString() ); - PrintValue( "Mod Manager BasePath Exists", manager.BasePath != null ? Directory.Exists( manager.BasePath.FullName ).ToString() : false.ToString() ); - PrintValue( "Mod Manager Valid", manager.Valid.ToString() ); - PrintValue( "Mod Manager Temp Path", manager.TempPath?.FullName ?? "NULL" ); - PrintValue( "Mod Manager Temp Path IsRooted", - ( !Penumbra.Config.TempDirectory.Any() || Path.IsPathRooted( Penumbra.Config.TempDirectory ) ).ToString() ); - PrintValue( "Mod Manager Temp Path Exists", manager.TempPath != null ? Directory.Exists( manager.TempPath.FullName ).ToString() : false.ToString() ); - PrintValue( "Mod Manager Temp Path IsWritable", manager.TempWritable.ToString() ); + return; } - private void DrawDebugTabRedraw() + var queue = ( Queue< (int, string, RedrawType) >? )_penumbra.ObjectReloader.GetType() + .GetField( "_objectIds", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ) + ?? new Queue< (int, string, RedrawType) >(); + + var currentFrame = ( int? )_penumbra.ObjectReloader.GetType() + .GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var changedSettings = ( bool? )_penumbra.ObjectReloader.GetType() + .GetField( "_changedSettings", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var currentObjectId = ( uint? )_penumbra.ObjectReloader.GetType() + .GetField( "_currentObjectId", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var currentObjectName = ( string? )_penumbra.ObjectReloader.GetType() + .GetField( "_currentObjectName", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var currentObjectStartState = ( ObjectReloader.LoadingFlags? )_penumbra.ObjectReloader.GetType() + .GetField( "_currentObjectStartState", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var currentRedrawType = ( RedrawType? )_penumbra.ObjectReloader.GetType() + .GetField( "_currentRedrawType", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var (currentObject, currentObjectIdx) = ( (GameObject?, int) )_penumbra.ObjectReloader.GetType() + .GetMethod( "FindCurrentObject", BindingFlags.NonPublic | BindingFlags.Instance )? + .Invoke( _penumbra.ObjectReloader, Array.Empty< object >() )!; + + var currentRender = currentObject != null + ? ( ObjectReloader.LoadingFlags? )Marshal.ReadInt32( ObjectReloader.RenderPtr( currentObject ) ) + : null; + + var waitFrames = ( int? )_penumbra.ObjectReloader.GetType() + .GetField( "_waitFrames", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var wasTarget = ( bool? )_penumbra.ObjectReloader.GetType() + .GetField( "_wasTarget", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + var gPose = ( bool? )_penumbra.ObjectReloader.GetType() + .GetField( "_inGPose", BindingFlags.Instance | BindingFlags.NonPublic ) + ?.GetValue( _penumbra.ObjectReloader ); + + using var raii = new ImGuiRaii.EndStack(); + if( ImGui.BeginTable( "##RedrawData", 2, ImGuiTableFlags.SizingFixedFit, + new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 7 ) ) ) { - if( !ImGui.CollapsingHeader( "Redrawing##Debug" ) ) - { - return; - } - - var queue = ( Queue< (int, string, RedrawType) >? )_penumbra.ObjectReloader.GetType() - .GetField( "_objectIds", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ) - ?? new Queue< (int, string, RedrawType) >(); - - var currentFrame = ( int? )_penumbra.ObjectReloader.GetType() - .GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var changedSettings = ( bool? )_penumbra.ObjectReloader.GetType() - .GetField( "_changedSettings", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var currentObjectId = ( uint? )_penumbra.ObjectReloader.GetType() - .GetField( "_currentObjectId", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var currentObjectName = ( string? )_penumbra.ObjectReloader.GetType() - .GetField( "_currentObjectName", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var currentObjectStartState = ( ObjectReloader.LoadingFlags? )_penumbra.ObjectReloader.GetType() - .GetField( "_currentObjectStartState", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var currentRedrawType = ( RedrawType? )_penumbra.ObjectReloader.GetType() - .GetField( "_currentRedrawType", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var (currentObject, currentObjectIdx) = ( (GameObject?, int) )_penumbra.ObjectReloader.GetType() - .GetMethod( "FindCurrentObject", BindingFlags.NonPublic | BindingFlags.Instance )? - .Invoke( _penumbra.ObjectReloader, Array.Empty< object >() )!; - - var currentRender = currentObject != null - ? ( ObjectReloader.LoadingFlags? )Marshal.ReadInt32( ObjectReloader.RenderPtr( currentObject ) ) - : null; - - var waitFrames = ( int? )_penumbra.ObjectReloader.GetType() - .GetField( "_waitFrames", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var wasTarget = ( bool? )_penumbra.ObjectReloader.GetType() - .GetField( "_wasTarget", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - var gPose = ( bool? )_penumbra.ObjectReloader.GetType() - .GetField( "_inGPose", BindingFlags.Instance | BindingFlags.NonPublic ) - ?.GetValue( _penumbra.ObjectReloader ); - - using var raii = new ImGuiRaii.EndStack(); - if( ImGui.BeginTable( "##RedrawData", 2, ImGuiTableFlags.SizingFixedFit, - new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 7 ) ) ) - { - raii.Push( ImGui.EndTable ); - PrintValue( "Current Wait Frame", waitFrames?.ToString() ?? "null" ); - PrintValue( "Current Frame", currentFrame?.ToString() ?? "null" ); - PrintValue( "Currently in GPose", gPose?.ToString() ?? "null" ); - PrintValue( "Current Changed Settings", changedSettings?.ToString() ?? "null" ); - PrintValue( "Current Object Id", currentObjectId?.ToString( "X8" ) ?? "null" ); - PrintValue( "Current Object Name", currentObjectName ?? "null" ); - PrintValue( "Current Object Start State", ( ( int? )currentObjectStartState )?.ToString( "X8" ) ?? "null" ); - PrintValue( "Current Object Was Target", wasTarget?.ToString() ?? "null" ); - PrintValue( "Current Object Redraw", currentRedrawType?.ToString() ?? "null" ); - PrintValue( "Current Object Address", currentObject?.Address.ToString( "X16" ) ?? "null" ); - PrintValue( "Current Object Index", currentObjectIdx >= 0 ? currentObjectIdx.ToString() : "null" ); - PrintValue( "Current Object Render Flags", ( ( int? )currentRender )?.ToString( "X8" ) ?? "null" ); - } - - if( queue.Any() - && ImGui.BeginTable( "##RedrawTable", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX, - new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * queue.Count ) ) ) - { - raii.Push( ImGui.EndTable ); - foreach( var (objectId, objectName, redraw) in queue ) - { - ImGui.TableNextRow(); - ImGui.TableNextColumn(); - ImGui.Text( objectName ); - ImGui.TableNextColumn(); - ImGui.Text( $"0x{objectId:X8}" ); - ImGui.TableNextColumn(); - ImGui.Text( redraw.ToString() ); - } - } - - if( queue.Any() && ImGui.Button( "Clear" ) ) - { - queue.Clear(); - _penumbra.ObjectReloader.GetType() - .GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic )?.SetValue( _penumbra.ObjectReloader, 0 ); - } + raii.Push( ImGui.EndTable ); + PrintValue( "Current Wait Frame", waitFrames?.ToString() ?? "null" ); + PrintValue( "Current Frame", currentFrame?.ToString() ?? "null" ); + PrintValue( "Currently in GPose", gPose?.ToString() ?? "null" ); + PrintValue( "Current Changed Settings", changedSettings?.ToString() ?? "null" ); + PrintValue( "Current Object Id", currentObjectId?.ToString( "X8" ) ?? "null" ); + PrintValue( "Current Object Name", currentObjectName ?? "null" ); + PrintValue( "Current Object Start State", ( ( int? )currentObjectStartState )?.ToString( "X8" ) ?? "null" ); + PrintValue( "Current Object Was Target", wasTarget?.ToString() ?? "null" ); + PrintValue( "Current Object Redraw", currentRedrawType?.ToString() ?? "null" ); + PrintValue( "Current Object Address", currentObject?.Address.ToString( "X16" ) ?? "null" ); + PrintValue( "Current Object Index", currentObjectIdx >= 0 ? currentObjectIdx.ToString() : "null" ); + PrintValue( "Current Object Render Flags", ( ( int? )currentRender )?.ToString( "X8" ) ?? "null" ); } - private static void DrawDebugTabTempFiles() + if( queue.Any() + && ImGui.BeginTable( "##RedrawTable", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX, + new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * queue.Count ) ) ) { - if( !ImGui.CollapsingHeader( "Temporary Files##Debug" ) ) - { - return; - } - - if( !ImGui.BeginTable( "##tempFileTable", 4, ImGuiTableFlags.SizingFixedFit ) ) - { - return; - } - - using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); - - foreach( var collection in Service< ModManager >.Get().Collections.Collections.Values.Where( c => c.Cache != null ) ) - { - var manip = collection.Cache!.MetaManipulations; - var files = ( Dictionary< GamePath, MetaManager.FileInformation >? )manip.GetType() - .GetField( "_currentFiles", BindingFlags.NonPublic | BindingFlags.Instance )?.GetValue( manip ) - ?? new Dictionary< GamePath, MetaManager.FileInformation >(); - - - foreach( var (file, info) in files ) - { - ImGui.TableNextRow(); - ImGui.TableNextColumn(); - ImGui.Text( info.CurrentFile?.FullName ?? "None" ); - ImGui.TableNextColumn(); - ImGui.Text( file ); - ImGui.TableNextColumn(); - info.CurrentFile?.Refresh(); - ImGui.Text( info.CurrentFile?.Exists ?? false ? "Exists" : "Missing" ); - ImGui.TableNextColumn(); - ImGui.Text( info.Changed ? "Data Changed" : "Unchanged" ); - } - } - } - - private void DrawDebugTabIpc() - { - if( !ImGui.CollapsingHeader( "IPC##Debug" ) ) - { - return; - } - - var ipc = _penumbra.Ipc; - ImGui.Text( $"API Version: {ipc.Api.ApiVersion}" ); - ImGui.Text( "Available subscriptions:" ); - using var indent = ImGuiRaii.PushIndent(); - if( ipc.ProviderApiVersion != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderApiVersion ); - } - - if( ipc.ProviderRedrawName != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderRedrawName ); - } - - if( ipc.ProviderRedrawObject != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderRedrawObject ); - } - - if( ipc.ProviderRedrawAll != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderRedrawAll ); - } - - if( ipc.ProviderResolveDefault != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderResolveDefault ); - } - - if( ipc.ProviderResolveCharacter != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderResolveCharacter ); - } - - if( ipc.ProviderChangedItemTooltip != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderChangedItemTooltip ); - } - - if( ipc.ProviderChangedItemClick != null ) - { - ImGui.Text( PenumbraIpc.LabelProviderChangedItemClick ); - } - } - - private void DrawDebugTabMissingFiles() - { - if( !ImGui.CollapsingHeader( "Missing Files##Debug" ) ) - { - return; - } - - var manager = Service< ModManager >.Get(); - var cache = manager.Collections.CurrentCollection.Cache; - if( cache == null || !ImGui.BeginTable( "##MissingFilesDebugList", 1, ImGuiTableFlags.RowBg, -Vector2.UnitX ) ) - { - return; - } - - using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); - - foreach( var file in cache.MissingFiles ) + raii.Push( ImGui.EndTable ); + foreach( var (objectId, objectName, redraw) in queue ) { ImGui.TableNextRow(); ImGui.TableNextColumn(); - if( ImGui.Selectable( file.FullName ) ) - { - ImGui.SetClipboardText( file.FullName ); - } - - ImGuiCustom.HoverTooltip( "Click to copy to clipboard." ); + ImGui.Text( objectName ); + ImGui.TableNextColumn(); + ImGui.Text( $"0x{objectId:X8}" ); + ImGui.TableNextColumn(); + ImGui.Text( redraw.ToString() ); } } - private void DrawDebugTab() + if( queue.Any() && ImGui.Button( "Clear" ) ) { - if( !ImGui.BeginTabItem( "Debug Tab" ) ) - { - return; - } - - using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem ); - - DrawDebugTabGeneral(); - ImGui.NewLine(); - DrawDebugTabMissingFiles(); - ImGui.NewLine(); - DrawDebugTabRedraw(); - ImGui.NewLine(); - DrawDebugTabPlayers(); - ImGui.NewLine(); - DrawDebugTabTempFiles(); - ImGui.NewLine(); - DrawDebugTabIpc(); - ImGui.NewLine(); + queue.Clear(); + _penumbra.ObjectReloader.GetType() + .GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic )?.SetValue( _penumbra.ObjectReloader, 0 ); } } + + private static void DrawDebugTabTempFiles() + { + if( !ImGui.CollapsingHeader( "Temporary Files##Debug" ) ) + { + return; + } + + if( !ImGui.BeginTable( "##tempFileTable", 4, ImGuiTableFlags.SizingFixedFit ) ) + { + return; + } + + using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); + + foreach( var collection in Service< ModManager >.Get().Collections.Collections.Values.Where( c => c.Cache != null ) ) + { + var manip = collection.Cache!.MetaManipulations; + var files = ( Dictionary< GamePath, MetaManager.FileInformation >? )manip.GetType() + .GetField( "_currentFiles", BindingFlags.NonPublic | BindingFlags.Instance )?.GetValue( manip ) + ?? new Dictionary< GamePath, MetaManager.FileInformation >(); + + + foreach( var (file, info) in files ) + { + ImGui.TableNextRow(); + ImGui.TableNextColumn(); + ImGui.Text( info.CurrentFile?.FullName ?? "None" ); + ImGui.TableNextColumn(); + ImGui.Text( file ); + ImGui.TableNextColumn(); + info.CurrentFile?.Refresh(); + ImGui.Text( info.CurrentFile?.Exists ?? false ? "Exists" : "Missing" ); + ImGui.TableNextColumn(); + ImGui.Text( info.Changed ? "Data Changed" : "Unchanged" ); + } + } + } + + private void DrawDebugTabIpc() + { + if( !ImGui.CollapsingHeader( "IPC##Debug" ) ) + { + return; + } + + var ipc = _penumbra.Ipc; + ImGui.Text( $"API Version: {ipc.Api.ApiVersion}" ); + ImGui.Text( "Available subscriptions:" ); + using var indent = ImGuiRaii.PushIndent(); + if( ipc.ProviderApiVersion != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderApiVersion ); + } + + if( ipc.ProviderRedrawName != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderRedrawName ); + } + + if( ipc.ProviderRedrawObject != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderRedrawObject ); + } + + if( ipc.ProviderRedrawAll != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderRedrawAll ); + } + + if( ipc.ProviderResolveDefault != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderResolveDefault ); + } + + if( ipc.ProviderResolveCharacter != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderResolveCharacter ); + } + + if( ipc.ProviderChangedItemTooltip != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderChangedItemTooltip ); + } + + if( ipc.ProviderChangedItemClick != null ) + { + ImGui.Text( PenumbraIpc.LabelProviderChangedItemClick ); + } + } + + private void DrawDebugTabMissingFiles() + { + if( !ImGui.CollapsingHeader( "Missing Files##Debug" ) ) + { + return; + } + + var manager = Service< ModManager >.Get(); + var cache = manager.Collections.CurrentCollection.Cache; + if( cache == null || !ImGui.BeginTable( "##MissingFilesDebugList", 1, ImGuiTableFlags.RowBg, -Vector2.UnitX ) ) + { + return; + } + + using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable ); + + foreach( var file in cache.MissingFiles ) + { + ImGui.TableNextRow(); + ImGui.TableNextColumn(); + if( ImGui.Selectable( file.FullName ) ) + { + ImGui.SetClipboardText( file.FullName ); + } + + ImGuiCustom.HoverTooltip( "Click to copy to clipboard." ); + } + } + + private void DrawDebugTab() + { + if( !ImGui.BeginTabItem( "Debug Tab" ) ) + { + return; + } + + using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem ); + + DrawDebugTabGeneral(); + ImGui.NewLine(); + DrawDebugTabMissingFiles(); + ImGui.NewLine(); + DrawDebugTabRedraw(); + ImGui.NewLine(); + DrawDebugTabPlayers(); + ImGui.NewLine(); + DrawDebugTabTempFiles(); + ImGui.NewLine(); + DrawDebugTabIpc(); + ImGui.NewLine(); + } } \ No newline at end of file