mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-31 21:03:48 +01:00
Add Byte String stuff, remove Services, cleanup and refactor interop stuff, disable path resolver for the moment
This commit is contained in:
parent
0e8f839471
commit
c3454f1d16
65 changed files with 4707 additions and 3371 deletions
|
|
@ -1,61 +0,0 @@
|
|||
using ImGuiNET;
|
||||
using Penumbra.UI.Custom;
|
||||
|
||||
namespace Penumbra.UI
|
||||
{
|
||||
public partial class SettingsInterface
|
||||
{
|
||||
private class MenuBar
|
||||
{
|
||||
private const string MenuLabel = "Penumbra";
|
||||
private const string MenuItemToggle = "Toggle UI";
|
||||
private const string SlashCommand = "/penumbra";
|
||||
private const string MenuItemRediscover = "Rediscover Mods";
|
||||
private const string MenuItemHide = "Hide Menu Bar";
|
||||
|
||||
#if DEBUG
|
||||
private bool _showDebugBar = true;
|
||||
#else
|
||||
private const bool _showDebugBar = false;
|
||||
#endif
|
||||
|
||||
private readonly SettingsInterface _base;
|
||||
|
||||
public MenuBar( SettingsInterface ui )
|
||||
=> _base = ui;
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if( !_showDebugBar || !ImGui.BeginMainMenuBar() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndMainMenuBar );
|
||||
|
||||
if( !ImGui.BeginMenu( MenuLabel ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
raii.Push( ImGui.EndMenu );
|
||||
|
||||
if( ImGui.MenuItem( MenuItemToggle, SlashCommand, _base._menu.Visible ) )
|
||||
{
|
||||
_base.FlipVisibility();
|
||||
}
|
||||
|
||||
if( ImGui.MenuItem( MenuItemRediscover ) )
|
||||
{
|
||||
_base.ReloadMods();
|
||||
}
|
||||
#if DEBUG
|
||||
if( ImGui.MenuItem( MenuItemHide ) )
|
||||
{
|
||||
_showDebugBar = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +1,65 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ImGuiNET;
|
||||
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 class TabChangedItems
|
||||
{
|
||||
private class TabChangedItems
|
||||
private const string LabelTab = "Changed Items";
|
||||
private readonly SettingsInterface _base;
|
||||
|
||||
private string _filter = string.Empty;
|
||||
private string _filterLower = string.Empty;
|
||||
|
||||
public TabChangedItems( SettingsInterface ui )
|
||||
=> _base = ui;
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
private const string LabelTab = "Changed Items";
|
||||
private readonly ModManager _modManager;
|
||||
private readonly SettingsInterface _base;
|
||||
|
||||
private string _filter = string.Empty;
|
||||
private string _filterLower = string.Empty;
|
||||
|
||||
public TabChangedItems( SettingsInterface ui )
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
{
|
||||
_base = ui;
|
||||
_modManager = Service< ModManager >.Get();
|
||||
return;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
var modManager = Penumbra.ModManager;
|
||||
var items = modManager.Collections.ActiveCollection.Cache?.ChangedItems ?? new Dictionary< string, object? >();
|
||||
var forced = modManager.Collections.ForcedCollection.Cache?.ChangedItems ?? new Dictionary< string, object? >();
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.InputTextWithHint( "##ChangedItemsFilter", "Filter...", ref _filter, 64 ) )
|
||||
{
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
var items = _modManager.Collections.ActiveCollection.Cache?.ChangedItems ?? new Dictionary<string, object?>();
|
||||
var forced = _modManager.Collections.ForcedCollection.Cache?.ChangedItems ?? new Dictionary<string, object?>();
|
||||
_filterLower = _filter.ToLowerInvariant();
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
if( !ImGui.BeginTable( "##ChangedItemsTable", 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, AutoFillSize ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.InputTextWithHint( "##ChangedItemsFilter", "Filter...", ref _filter, 64 ) )
|
||||
{
|
||||
_filterLower = _filter.ToLowerInvariant();
|
||||
}
|
||||
raii.Push( ImGui.EndTable );
|
||||
|
||||
if( !ImGui.BeginTable( "##ChangedItemsTable", 1, ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollY, AutoFillSize ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
var list = items.AsEnumerable();
|
||||
if( forced.Count > 0 )
|
||||
{
|
||||
list = list.Concat( forced ).OrderBy( kvp => kvp.Key );
|
||||
}
|
||||
|
||||
raii.Push( ImGui.EndTable );
|
||||
if( _filter.Any() )
|
||||
{
|
||||
list = list.Where( kvp => kvp.Key.ToLowerInvariant().Contains( _filterLower ) );
|
||||
}
|
||||
|
||||
var list = items.AsEnumerable();
|
||||
if( forced.Count > 0 )
|
||||
{
|
||||
list = list.Concat( forced ).OrderBy( kvp => kvp.Key );
|
||||
}
|
||||
|
||||
if( _filter.Any() )
|
||||
{
|
||||
list = list.Where( kvp => kvp.Key.ToLowerInvariant().Contains( _filterLower ) );
|
||||
}
|
||||
|
||||
foreach( var (name, data) in list )
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
_base.DrawChangedItem( name, data, ImGui.GetStyle().ScrollbarSize );
|
||||
}
|
||||
foreach( var (name, data) in list )
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
_base.DrawChangedItem( name, data, ImGui.GetStyle().ScrollbarSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ public partial class SettingsInterface
|
|||
{
|
||||
private const string CharacterCollectionHelpPopup = "Character Collection Information";
|
||||
private readonly Selector _selector;
|
||||
private readonly ModManager _manager;
|
||||
private string _collectionNames = null!;
|
||||
private string _collectionNamesWithNone = null!;
|
||||
private ModCollection[] _collections = null!;
|
||||
|
|
@ -32,7 +31,7 @@ public partial class SettingsInterface
|
|||
|
||||
private void UpdateNames()
|
||||
{
|
||||
_collections = _manager.Collections.Collections.Values.Prepend( ModCollection.Empty ).ToArray();
|
||||
_collections = Penumbra.ModManager.Collections.Collections.Values.Prepend( ModCollection.Empty ).ToArray();
|
||||
_collectionNames = string.Join( "\0", _collections.Skip( 1 ).Select( c => c.Name ) ) + '\0';
|
||||
_collectionNamesWithNone = "None\0" + _collectionNames;
|
||||
UpdateIndices();
|
||||
|
|
@ -52,18 +51,18 @@ public partial class SettingsInterface
|
|||
}
|
||||
|
||||
private void UpdateIndex()
|
||||
=> _currentCollectionIndex = GetIndex( _manager.Collections.CurrentCollection ) - 1;
|
||||
=> _currentCollectionIndex = GetIndex( Penumbra.ModManager.Collections.CurrentCollection ) - 1;
|
||||
|
||||
public void UpdateForcedIndex()
|
||||
=> _currentForcedIndex = GetIndex( _manager.Collections.ForcedCollection );
|
||||
=> _currentForcedIndex = GetIndex( Penumbra.ModManager.Collections.ForcedCollection );
|
||||
|
||||
public void UpdateDefaultIndex()
|
||||
=> _currentDefaultIndex = GetIndex( _manager.Collections.DefaultCollection );
|
||||
=> _currentDefaultIndex = GetIndex( Penumbra.ModManager.Collections.DefaultCollection );
|
||||
|
||||
private void UpdateCharacterIndices()
|
||||
{
|
||||
_currentCharacterIndices.Clear();
|
||||
foreach( var kvp in _manager.Collections.CharacterCollection )
|
||||
foreach( var kvp in Penumbra.ModManager.Collections.CharacterCollection )
|
||||
{
|
||||
_currentCharacterIndices[ kvp.Key ] = GetIndex( kvp.Value );
|
||||
}
|
||||
|
|
@ -80,16 +79,16 @@ public partial class SettingsInterface
|
|||
public TabCollections( Selector selector )
|
||||
{
|
||||
_selector = selector;
|
||||
_manager = Service< ModManager >.Get();
|
||||
UpdateNames();
|
||||
}
|
||||
|
||||
private void CreateNewCollection( Dictionary< string, ModSettings > settings )
|
||||
{
|
||||
if( _manager.Collections.AddCollection( _newCollectionName, settings ) )
|
||||
var manager = Penumbra.ModManager;
|
||||
if( manager.Collections.AddCollection( _newCollectionName, settings ) )
|
||||
{
|
||||
UpdateNames();
|
||||
SetCurrentCollection( _manager.Collections.Collections[ _newCollectionName ], true );
|
||||
SetCurrentCollection( manager.Collections.Collections[ _newCollectionName ], true );
|
||||
}
|
||||
|
||||
_newCollectionName = string.Empty;
|
||||
|
|
@ -99,9 +98,10 @@ public partial class SettingsInterface
|
|||
{
|
||||
if( ImGui.Button( "Clean Settings" ) )
|
||||
{
|
||||
var changes = ModFunctions.CleanUpCollection( _manager.Collections.CurrentCollection.Settings,
|
||||
_manager.BasePath.EnumerateDirectories() );
|
||||
_manager.Collections.CurrentCollection.UpdateSettings( changes );
|
||||
var manager = Penumbra.ModManager;
|
||||
var changes = ModFunctions.CleanUpCollection( manager.Collections.CurrentCollection.Settings,
|
||||
manager.BasePath.EnumerateDirectories() );
|
||||
manager.Collections.CurrentCollection.UpdateSettings( changes );
|
||||
}
|
||||
|
||||
ImGuiCustom.HoverTooltip(
|
||||
|
|
@ -126,9 +126,10 @@ public partial class SettingsInterface
|
|||
|
||||
var hover = ImGui.IsItemHovered();
|
||||
ImGui.SameLine();
|
||||
var manager = Penumbra.ModManager;
|
||||
if( ImGui.Button( "Duplicate Current Collection" ) && _newCollectionName.Length > 0 )
|
||||
{
|
||||
CreateNewCollection( _manager.Collections.CurrentCollection.Settings );
|
||||
CreateNewCollection( manager.Collections.CurrentCollection.Settings );
|
||||
}
|
||||
|
||||
hover |= ImGui.IsItemHovered();
|
||||
|
|
@ -139,13 +140,13 @@ public partial class SettingsInterface
|
|||
ImGui.SetTooltip( "Please enter a name before creating a collection." );
|
||||
}
|
||||
|
||||
var deleteCondition = _manager.Collections.Collections.Count > 1
|
||||
&& _manager.Collections.CurrentCollection.Name != ModCollection.DefaultCollection;
|
||||
var deleteCondition = manager.Collections.Collections.Count > 1
|
||||
&& manager.Collections.CurrentCollection.Name != ModCollection.DefaultCollection;
|
||||
ImGui.SameLine();
|
||||
if( ImGuiCustom.DisableButton( "Delete Current Collection", deleteCondition ) )
|
||||
{
|
||||
_manager.Collections.RemoveCollection( _manager.Collections.CurrentCollection.Name );
|
||||
SetCurrentCollection( _manager.Collections.CurrentCollection, true );
|
||||
manager.Collections.RemoveCollection( manager.Collections.CurrentCollection.Name );
|
||||
SetCurrentCollection( manager.Collections.CurrentCollection, true );
|
||||
UpdateNames();
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ public partial class SettingsInterface
|
|||
return;
|
||||
}
|
||||
|
||||
_manager.Collections.SetCurrentCollection( _collections[ idx + 1 ] );
|
||||
Penumbra.ModManager.Collections.SetCurrentCollection( _collections[ idx + 1 ] );
|
||||
_currentCollectionIndex = idx;
|
||||
_selector.Cache.TriggerListReset();
|
||||
if( _selector.Mod != null )
|
||||
|
|
@ -207,7 +208,7 @@ public partial class SettingsInterface
|
|||
ImGui.SetNextItemWidth( SettingsMenu.InputTextWidth );
|
||||
if( ImGui.Combo( "##Default Collection", ref index, _collectionNamesWithNone ) && index != _currentDefaultIndex )
|
||||
{
|
||||
_manager.Collections.SetDefaultCollection( _collections[ index ] );
|
||||
Penumbra.ModManager.Collections.SetDefaultCollection( _collections[ index ] );
|
||||
_currentDefaultIndex = index;
|
||||
}
|
||||
|
||||
|
|
@ -224,17 +225,18 @@ public partial class SettingsInterface
|
|||
{
|
||||
var index = _currentForcedIndex;
|
||||
ImGui.SetNextItemWidth( SettingsMenu.InputTextWidth );
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, _manager.Collections.CharacterCollection.Count == 0 );
|
||||
var manager = Penumbra.ModManager;
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f, manager.Collections.CharacterCollection.Count == 0 );
|
||||
if( ImGui.Combo( "##Forced Collection", ref index, _collectionNamesWithNone )
|
||||
&& index != _currentForcedIndex
|
||||
&& _manager.Collections.CharacterCollection.Count > 0 )
|
||||
&& index != _currentForcedIndex
|
||||
&& manager.Collections.CharacterCollection.Count > 0 )
|
||||
{
|
||||
_manager.Collections.SetForcedCollection( _collections[ index ] );
|
||||
manager.Collections.SetForcedCollection( _collections[ index ] );
|
||||
_currentForcedIndex = index;
|
||||
}
|
||||
|
||||
style.Pop();
|
||||
if( _manager.Collections.CharacterCollection.Count == 0 && ImGui.IsItemHovered() )
|
||||
if( manager.Collections.CharacterCollection.Count == 0 && ImGui.IsItemHovered() )
|
||||
{
|
||||
ImGui.SetTooltip(
|
||||
"Forced Collections only provide value if you have at least one Character Collection. There is no need to set one until then." );
|
||||
|
|
@ -260,7 +262,7 @@ public partial class SettingsInterface
|
|||
if( ImGuiCustom.DisableButton( "Create New Character Collection",
|
||||
_newCharacterName.Length > 0 && Penumbra.Config.HasReadCharacterCollectionDesc ) )
|
||||
{
|
||||
_manager.Collections.CreateCharacterCollection( _newCharacterName );
|
||||
Penumbra.ModManager.Collections.CreateCharacterCollection( _newCharacterName );
|
||||
_currentCharacterIndices[ _newCharacterName ] = 0;
|
||||
_newCharacterName = string.Empty;
|
||||
}
|
||||
|
|
@ -342,14 +344,15 @@ public partial class SettingsInterface
|
|||
DrawDefaultCollectionSelector();
|
||||
DrawForcedCollectionSelector();
|
||||
|
||||
foreach( var name in _manager.Collections.CharacterCollection.Keys.ToArray() )
|
||||
var manager = Penumbra.ModManager;
|
||||
foreach( var name in manager.Collections.CharacterCollection.Keys.ToArray() )
|
||||
{
|
||||
var idx = _currentCharacterIndices[ name ];
|
||||
var tmp = idx;
|
||||
ImGui.SetNextItemWidth( SettingsMenu.InputTextWidth );
|
||||
if( ImGui.Combo( $"##{name}collection", ref tmp, _collectionNamesWithNone ) && idx != tmp )
|
||||
{
|
||||
_manager.Collections.SetCharacterCollection( name, _collections[ tmp ] );
|
||||
manager.Collections.SetCharacterCollection( name, _collections[ tmp ] );
|
||||
_currentCharacterIndices[ name ] = tmp;
|
||||
}
|
||||
|
||||
|
|
@ -360,7 +363,7 @@ public partial class SettingsInterface
|
|||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.FramePadding, Vector2.One * ImGuiHelpers.GlobalScale * 1.5f );
|
||||
if( ImGui.Button( $"{FontAwesomeIcon.Trash.ToIconString()}##{name}" ) )
|
||||
{
|
||||
_manager.Collections.RemoveCharacterCollection( name );
|
||||
manager.Collections.RemoveCharacterCollection( name );
|
||||
}
|
||||
|
||||
style.Pop();
|
||||
|
|
|
|||
131
Penumbra/UI/MenuTabs/TabDebug.Model.cs
Normal file
131
Penumbra/UI/MenuTabs/TabDebug.Model.cs
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using ImGuiNET;
|
||||
using Penumbra.UI.Custom;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
public partial class SettingsInterface
|
||||
{
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
private unsafe struct RenderModel
|
||||
{
|
||||
[FieldOffset( 0x18 )]
|
||||
public RenderModel* PreviousModel;
|
||||
|
||||
[FieldOffset( 0x20 )]
|
||||
public RenderModel* NextModel;
|
||||
|
||||
[FieldOffset( 0x30 )]
|
||||
public ResourceHandle* ResourceHandle;
|
||||
|
||||
[FieldOffset( 0x40 )]
|
||||
public Skeleton* Skeleton;
|
||||
|
||||
[FieldOffset( 0x58 )]
|
||||
public void** BoneList;
|
||||
|
||||
[FieldOffset( 0x60 )]
|
||||
public int BoneListCount;
|
||||
|
||||
[FieldOffset( 0x68 )]
|
||||
private void* UnkDXBuffer1;
|
||||
|
||||
[FieldOffset( 0x70 )]
|
||||
private void* UnkDXBuffer2;
|
||||
|
||||
[FieldOffset( 0x78 )]
|
||||
private void* UnkDXBuffer3;
|
||||
|
||||
[FieldOffset( 0x90 )]
|
||||
public void** Materials;
|
||||
|
||||
[FieldOffset( 0x98 )]
|
||||
public int MaterialCount;
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
private unsafe struct Material
|
||||
{
|
||||
[FieldOffset( 0x10 )]
|
||||
public ResourceHandle* ResourceHandle;
|
||||
|
||||
[FieldOffset( 0x28 )]
|
||||
public void* MaterialData;
|
||||
|
||||
[FieldOffset( 0x48 )]
|
||||
public Texture* Tex1;
|
||||
|
||||
[FieldOffset( 0x60 )]
|
||||
public Texture* Tex2;
|
||||
|
||||
[FieldOffset( 0x78 )]
|
||||
public Texture* Tex3;
|
||||
}
|
||||
|
||||
private static unsafe void DrawPlayerModelInfo()
|
||||
{
|
||||
var player = Dalamud.ClientState.LocalPlayer;
|
||||
var name = player?.Name.ToString() ?? "NULL";
|
||||
if( !ImGui.CollapsingHeader( $"Player Model Info: {name}##Draw" ) || player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var model = ( CharacterBase* )( ( Character* )player.Address )->GameObject.GetDrawObject();
|
||||
if( model == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !ImGui.BeginTable( $"##{name}DrawTable", 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Slot" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Imc Ptr" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Imc File" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Model Ptr" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Model File" );
|
||||
|
||||
for( var i = 0; i < model->SlotCount; ++i )
|
||||
{
|
||||
var imc = ( ResourceHandle* )model->IMCArray[ i ];
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( $"Slot {i}" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( imc == null ? "NULL" : $"0x{( ulong )imc:X}" );
|
||||
ImGui.TableNextColumn();
|
||||
if( imc != null )
|
||||
{
|
||||
ImGui.Text( imc->FileName.ToString() );
|
||||
}
|
||||
|
||||
var mdl = ( RenderModel* )model->ModelArray[ i ];
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( mdl == null ? "NULL" : $"0x{( ulong )mdl:X}" );
|
||||
if( mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
if( mdl != null )
|
||||
{
|
||||
ImGui.Text( mdl->ResourceHandle->FileName.ToString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing.Text;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.String;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Api;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.GameData.Util;
|
||||
|
|
@ -16,6 +20,8 @@ using Penumbra.Meta;
|
|||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
using ResourceHandle = Penumbra.Interop.Structs.ResourceHandle;
|
||||
using Utf8String = Penumbra.GameData.ByteString.Utf8String;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
|
|
@ -143,7 +149,7 @@ public partial class SettingsInterface
|
|||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
|
||||
var manager = Service< ModManager >.Get();
|
||||
var manager = Penumbra.ModManager;
|
||||
PrintValue( "Active Collection", manager.Collections.ActiveCollection.Name );
|
||||
PrintValue( " has Cache", ( manager.Collections.ActiveCollection.Cache != null ).ToString() );
|
||||
PrintValue( "Current Collection", manager.Collections.CurrentCollection.Name );
|
||||
|
|
@ -164,7 +170,7 @@ public partial class SettingsInterface
|
|||
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 Enabled", _penumbra.ResourceLoader.IsEnabled.ToString() );
|
||||
}
|
||||
|
||||
private void DrawDebugTabRedraw()
|
||||
|
|
@ -281,7 +287,7 @@ public partial class SettingsInterface
|
|||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
|
||||
foreach( var collection in Service< ModManager >.Get().Collections.Collections.Values.Where( c => c.Cache != null ) )
|
||||
foreach( var collection in Penumbra.ModManager.Collections.Collections.Values.Where( c => c.Cache != null ) )
|
||||
{
|
||||
var manip = collection.Cache!.MetaManipulations;
|
||||
var files = ( Dictionary< GamePath, MetaManager.FileInformation >? )manip.GetType()
|
||||
|
|
@ -363,8 +369,7 @@ public partial class SettingsInterface
|
|||
return;
|
||||
}
|
||||
|
||||
var manager = Service< ModManager >.Get();
|
||||
var cache = manager.Collections.CurrentCollection.Cache;
|
||||
var cache = Penumbra.ModManager.Collections.CurrentCollection.Cache;
|
||||
if( cache == null || !ImGui.BeginTable( "##MissingFilesDebugList", 1, ImGuiTableFlags.RowBg, -Vector2.UnitX ) )
|
||||
{
|
||||
return;
|
||||
|
|
@ -385,6 +390,86 @@ public partial class SettingsInterface
|
|||
}
|
||||
}
|
||||
|
||||
private unsafe void DrawDebugTabReplacedResources()
|
||||
{
|
||||
if( !ImGui.CollapsingHeader( "Replaced Resources##Debug" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_penumbra.ResourceLoader.UpdateDebugInfo();
|
||||
|
||||
if( _penumbra.ResourceLoader.DebugList.Count == 0
|
||||
|| !ImGui.BeginTable( "##ReplacedResourcesDebugList", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit, -Vector2.UnitX ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var end = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
|
||||
foreach( var data in _penumbra.ResourceLoader.DebugList.Values.ToArray() )
|
||||
{
|
||||
var refCountManip = data.ManipulatedResource == null ? 0 : data.ManipulatedResource->RefCount;
|
||||
var refCountOrig = data.OriginalResource == null ? 0 : data.OriginalResource->RefCount;
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( data.ManipulatedPath.ToString() );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( ( ( ulong )data.ManipulatedResource ).ToString( "X" ) );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( refCountManip.ToString() );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( data.OriginalPath.ToString() );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( ( ( ulong )data.OriginalResource ).ToString( "X" ) );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( refCountOrig.ToString() );
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void DrawPathResolverDebug()
|
||||
{
|
||||
if( !ImGui.CollapsingHeader( "Path Resolver##Debug" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//if( ImGui.TreeNodeEx( "Draw Object to Object" ) )
|
||||
//{
|
||||
// using var end = ImGuiRaii.DeferredEnd( ImGui.TreePop );
|
||||
// if( ImGui.BeginTable( "###DrawObjectResolverTable", 4, ImGuiTableFlags.SizingFixedFit ) )
|
||||
// {
|
||||
// end.Push( ImGui.EndTable );
|
||||
// foreach( var (ptr, idx) in _penumbra.PathResolver._drawObjectToObject )
|
||||
// {
|
||||
// ImGui.TableNextColumn();
|
||||
// ImGui.Text( ptr.ToString( "X" ) );
|
||||
// ImGui.TableNextColumn();
|
||||
// ImGui.Text( idx.ToString() );
|
||||
// ImGui.TableNextColumn();
|
||||
// ImGui.Text( Dalamud.Objects[ idx ]?.Address.ToString() ?? "NULL" );
|
||||
// ImGui.TableNextColumn();
|
||||
// ImGui.Text( Dalamud.Objects[ idx ]?.Name.ToString() ?? "NULL" );
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//if( ImGui.TreeNodeEx( "Path Collections" ) )
|
||||
//{
|
||||
// using var end = ImGuiRaii.DeferredEnd( ImGui.TreePop );
|
||||
// if( ImGui.BeginTable( "###PathCollectionResolverTable", 2, ImGuiTableFlags.SizingFixedFit ) )
|
||||
// {
|
||||
// end.Push( ImGui.EndTable );
|
||||
// foreach( var (path, collection) in _penumbra.PathResolver._pathCollections )
|
||||
// {
|
||||
// ImGui.TableNextColumn();
|
||||
// ImGuiNative.igTextUnformatted( path.Path, path.Path + path.Length );
|
||||
// ImGui.TableNextColumn();
|
||||
// ImGui.Text( collection.Name );
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
private void DrawDebugTab()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( "Debug Tab" ) )
|
||||
|
|
@ -396,8 +481,16 @@ public partial class SettingsInterface
|
|||
|
||||
DrawDebugTabGeneral();
|
||||
ImGui.NewLine();
|
||||
DrawDebugTabReplacedResources();
|
||||
ImGui.NewLine();
|
||||
DrawResourceProblems();
|
||||
ImGui.NewLine();
|
||||
DrawDebugTabMissingFiles();
|
||||
ImGui.NewLine();
|
||||
DrawPlayerModelInfo();
|
||||
ImGui.NewLine();
|
||||
DrawPathResolverDebug();
|
||||
ImGui.NewLine();
|
||||
DrawDebugTabRedraw();
|
||||
ImGui.NewLine();
|
||||
DrawDebugTabPlayers();
|
||||
|
|
|
|||
|
|
@ -1,148 +0,0 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Render;
|
||||
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using ImGuiNET;
|
||||
using Lumina.Models.Models;
|
||||
using Penumbra.UI.Custom;
|
||||
using DalamudCharacter = Dalamud.Game.ClientState.Objects.Types.Character;
|
||||
|
||||
namespace Penumbra.UI
|
||||
{
|
||||
public partial class SettingsInterface
|
||||
{
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
private unsafe struct RenderModel
|
||||
{
|
||||
[FieldOffset(0x18)]
|
||||
public RenderModel* PreviousModel;
|
||||
[FieldOffset( 0x20 )]
|
||||
public RenderModel* NextModel;
|
||||
|
||||
[FieldOffset( 0x30 )]
|
||||
public ResourceHandle* ResourceHandle;
|
||||
|
||||
[FieldOffset( 0x40 )]
|
||||
public Skeleton* Skeleton;
|
||||
|
||||
[FieldOffset( 0x58 )]
|
||||
public void** BoneList;
|
||||
[FieldOffset( 0x60 )]
|
||||
public int BoneListCount;
|
||||
|
||||
[FieldOffset( 0x68 )]
|
||||
private void* UnkDXBuffer1;
|
||||
|
||||
[FieldOffset( 0x70 )]
|
||||
private void* UnkDXBuffer2;
|
||||
|
||||
[FieldOffset( 0x78 )]
|
||||
private void* UnkDXBuffer3;
|
||||
|
||||
[FieldOffset( 0x90 )]
|
||||
public void** Materials;
|
||||
|
||||
[FieldOffset( 0x98 )]
|
||||
public int MaterialCount;
|
||||
}
|
||||
|
||||
[StructLayout( LayoutKind.Explicit )]
|
||||
private unsafe struct Material
|
||||
{
|
||||
[FieldOffset(0x10)]
|
||||
public ResourceHandle* ResourceHandle;
|
||||
[FieldOffset(0x28)]
|
||||
public void* MaterialData;
|
||||
|
||||
[FieldOffset( 0x48 )]
|
||||
public Texture* Tex1;
|
||||
[FieldOffset( 0x60 )]
|
||||
public Texture* Tex2;
|
||||
[FieldOffset( 0x78 )]
|
||||
public Texture* Tex3;
|
||||
}
|
||||
|
||||
private static unsafe void DrawPlayerModelInfo( DalamudCharacter character )
|
||||
{
|
||||
var name = character.Name.ToString();
|
||||
if( !ImGui.CollapsingHeader( $"{name}##Draw" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var model = ( CharacterBase* )( ( Character* )character.Address )->GameObject.GetDrawObject();
|
||||
if( model == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !ImGui.BeginTable( $"##{name}DrawTable", 5, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Slot" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Imc Ptr" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Imc File" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Model Ptr" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.TableHeader( "Model File" );
|
||||
|
||||
for( var i = 0; i < model->SlotCount; ++i )
|
||||
{
|
||||
var imc = ( ResourceHandle* )model->IMCArray[ i ];
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( $"Slot {i}" );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( imc == null ? "NULL" : $"0x{( ulong )imc:X}" );
|
||||
ImGui.TableNextColumn();
|
||||
if( imc != null )
|
||||
{
|
||||
ImGui.Text( imc->FileName.ToString() );
|
||||
}
|
||||
|
||||
var mdl = ( RenderModel* )model->ModelArray[ i ];
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( mdl == null ? "NULL" : $"0x{( ulong )mdl:X}" );
|
||||
if( mdl == null || mdl->ResourceHandle == null || mdl->ResourceHandle->Category != ResourceCategory.Chara )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
if( mdl != null )
|
||||
{
|
||||
ImGui.Text( mdl->ResourceHandle->FileName.ToString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPlayerModelTab()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( "Model Debug" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
var player = Dalamud.ClientState.LocalPlayer;
|
||||
if( player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DrawPlayerModelInfo( player );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,215 +3,210 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Dalamud.Interface;
|
||||
using ImGuiNET;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Util;
|
||||
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 class TabEffective
|
||||
{
|
||||
private class TabEffective
|
||||
private const string LabelTab = "Effective Changes";
|
||||
|
||||
private string _gamePathFilter = string.Empty;
|
||||
private string _gamePathFilterLower = string.Empty;
|
||||
private string _filePathFilter = string.Empty;
|
||||
private string _filePathFilterLower = string.Empty;
|
||||
|
||||
private readonly float _leftTextLength =
|
||||
ImGui.CalcTextSize( "chara/human/c0000/obj/body/b0000/material/v0000/mt_c0000b0000_b.mtrl" ).X / ImGuiHelpers.GlobalScale + 40;
|
||||
|
||||
private float _arrowLength = 0;
|
||||
|
||||
private static void DrawLine( string path, string name )
|
||||
{
|
||||
private const string LabelTab = "Effective Changes";
|
||||
private readonly ModManager _modManager;
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.CopyOnClickSelectable( path );
|
||||
|
||||
private string _gamePathFilter = string.Empty;
|
||||
private string _gamePathFilterLower = string.Empty;
|
||||
private string _filePathFilter = string.Empty;
|
||||
private string _filePathFilterLower = string.Empty;
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltLeft );
|
||||
ImGui.SameLine();
|
||||
ImGuiCustom.CopyOnClickSelectable( name );
|
||||
}
|
||||
|
||||
private readonly float _leftTextLength =
|
||||
ImGui.CalcTextSize( "chara/human/c0000/obj/body/b0000/material/v0000/mt_c0000b0000_b.mtrl" ).X / ImGuiHelpers.GlobalScale + 40;
|
||||
|
||||
private float _arrowLength = 0;
|
||||
|
||||
public TabEffective()
|
||||
=> _modManager = Service< ModManager >.Get();
|
||||
|
||||
|
||||
private static void DrawLine( string path, string name )
|
||||
private void DrawFilters()
|
||||
{
|
||||
if( _arrowLength == 0 )
|
||||
{
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.CopyOnClickSelectable( path );
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGuiCustom.PrintIcon( FontAwesomeIcon.LongArrowAltLeft );
|
||||
ImGui.SameLine();
|
||||
ImGuiCustom.CopyOnClickSelectable( name );
|
||||
using var font = ImGuiRaii.PushFont( UiBuilder.IconFont );
|
||||
_arrowLength = ImGui.CalcTextSize( FontAwesomeIcon.LongArrowAltLeft.ToIconString() ).X / ImGuiHelpers.GlobalScale;
|
||||
}
|
||||
|
||||
private void DrawFilters()
|
||||
ImGui.SetNextItemWidth( _leftTextLength * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( "##effective_changes_gfilter", "Filter game path...", ref _gamePathFilter, 256 ) )
|
||||
{
|
||||
if( _arrowLength == 0 )
|
||||
_gamePathFilterLower = _gamePathFilter.ToLowerInvariant();
|
||||
}
|
||||
|
||||
ImGui.SameLine( ( _leftTextLength + _arrowLength ) * ImGuiHelpers.GlobalScale + 3 * ImGui.GetStyle().ItemSpacing.X );
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.InputTextWithHint( "##effective_changes_ffilter", "Filter file path...", ref _filePathFilter, 256 ) )
|
||||
{
|
||||
_filePathFilterLower = _filePathFilter.ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckFilters( KeyValuePair< GamePath, FullPath > kvp )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Key.ToString().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !_filePathFilter.Any() || kvp.Value.FullName.ToLowerInvariant().Contains( _filePathFilterLower );
|
||||
}
|
||||
|
||||
private bool CheckFilters( KeyValuePair< GamePath, GamePath > kvp )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Key.ToString().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !_filePathFilter.Any() || kvp.Value.ToString().Contains( _filePathFilterLower );
|
||||
}
|
||||
|
||||
private bool CheckFilters( (string, string, string) kvp )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Item1.ToLowerInvariant().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !_filePathFilter.Any() || kvp.Item3.Contains( _filePathFilterLower );
|
||||
}
|
||||
|
||||
private void DrawFilteredRows( ModCollectionCache? active, ModCollectionCache? forced )
|
||||
{
|
||||
void DrawFileLines( ModCollectionCache cache )
|
||||
{
|
||||
foreach( var (gp, fp) in cache.ResolvedFiles.Where( CheckFilters ) )
|
||||
{
|
||||
using var font = ImGuiRaii.PushFont( UiBuilder.IconFont );
|
||||
_arrowLength = ImGui.CalcTextSize( FontAwesomeIcon.LongArrowAltLeft.ToIconString() ).X / ImGuiHelpers.GlobalScale;
|
||||
DrawLine( gp, fp.FullName );
|
||||
}
|
||||
|
||||
ImGui.SetNextItemWidth( _leftTextLength * ImGuiHelpers.GlobalScale );
|
||||
if( ImGui.InputTextWithHint( "##effective_changes_gfilter", "Filter game path...", ref _gamePathFilter, 256 ) )
|
||||
foreach( var (gp, fp) in cache.SwappedFiles.Where( CheckFilters ) )
|
||||
{
|
||||
_gamePathFilterLower = _gamePathFilter.ToLowerInvariant();
|
||||
DrawLine( gp, fp );
|
||||
}
|
||||
|
||||
ImGui.SameLine( ( _leftTextLength + _arrowLength ) * ImGuiHelpers.GlobalScale + 3 * ImGui.GetStyle().ItemSpacing.X );
|
||||
ImGui.SetNextItemWidth( -1 );
|
||||
if( ImGui.InputTextWithHint( "##effective_changes_ffilter", "Filter file path...", ref _filePathFilter, 256 ) )
|
||||
foreach( var (mp, mod, _) in cache.MetaManipulations.Manipulations
|
||||
.Select( p => ( p.Item1.IdentifierString(), p.Item2.Data.Meta.Name, p.Item2.Data.Meta.LowerName ) )
|
||||
.Where( CheckFilters ) )
|
||||
{
|
||||
_filePathFilterLower = _filePathFilter.ToLowerInvariant();
|
||||
DrawLine( mp, mod );
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckFilters( KeyValuePair< GamePath, FullPath > kvp )
|
||||
if( active != null )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Key.ToString().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !_filePathFilter.Any() || kvp.Value.FullName.ToLowerInvariant().Contains( _filePathFilterLower );
|
||||
DrawFileLines( active );
|
||||
}
|
||||
|
||||
private bool CheckFilters( KeyValuePair< GamePath, GamePath > kvp )
|
||||
if( forced != null )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Key.ToString().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
DrawFileLines( forced );
|
||||
}
|
||||
}
|
||||
|
||||
return !_filePathFilter.Any() || kvp.Value.ToString().Contains( _filePathFilterLower );
|
||||
public void Draw()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private bool CheckFilters( (string, string, string) kvp )
|
||||
{
|
||||
if( _gamePathFilter.Any() && !kvp.Item1.ToLowerInvariant().Contains( _gamePathFilterLower ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
return !_filePathFilter.Any() || kvp.Item3.Contains( _filePathFilterLower );
|
||||
DrawFilters();
|
||||
|
||||
const ImGuiTableFlags flags = ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX;
|
||||
|
||||
var modManager = Penumbra.ModManager;
|
||||
var activeCollection = modManager.Collections.ActiveCollection.Cache;
|
||||
var forcedCollection = modManager.Collections.ForcedCollection.Cache;
|
||||
|
||||
var (activeResolved, activeSwap, activeMeta) = activeCollection != null
|
||||
? ( activeCollection.ResolvedFiles.Count, activeCollection.SwappedFiles.Count, activeCollection.MetaManipulations.Count )
|
||||
: ( 0, 0, 0 );
|
||||
var (forcedResolved, forcedSwap, forcedMeta) = forcedCollection != null
|
||||
? ( forcedCollection.ResolvedFiles.Count, forcedCollection.SwappedFiles.Count, forcedCollection.MetaManipulations.Count )
|
||||
: ( 0, 0, 0 );
|
||||
var totalLines = activeResolved + forcedResolved + activeSwap + forcedSwap + activeMeta + forcedMeta;
|
||||
if( totalLines == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
private void DrawFilteredRows( ModCollectionCache? active, ModCollectionCache? forced )
|
||||
if( ImGui.BeginTable( "##effective_changes", 2, flags, AutoFillSize ) )
|
||||
{
|
||||
void DrawFileLines( ModCollectionCache cache )
|
||||
raii.Push( ImGui.EndTable );
|
||||
ImGui.TableSetupColumn( "##tableGamePathCol", ImGuiTableColumnFlags.None, _leftTextLength * ImGuiHelpers.GlobalScale );
|
||||
|
||||
if( _filePathFilter.Any() || _gamePathFilter.Any() )
|
||||
{
|
||||
foreach( var (gp, fp) in cache.ResolvedFiles.Where( CheckFilters ) )
|
||||
DrawFilteredRows( activeCollection, forcedCollection );
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiListClipperPtr clipper;
|
||||
unsafe
|
||||
{
|
||||
DrawLine( gp, fp.FullName );
|
||||
clipper = new ImGuiListClipperPtr( ImGuiNative.ImGuiListClipper_ImGuiListClipper() );
|
||||
}
|
||||
|
||||
foreach( var (gp, fp) in cache.SwappedFiles.Where( CheckFilters ) )
|
||||
clipper.Begin( totalLines );
|
||||
|
||||
|
||||
while( clipper.Step() )
|
||||
{
|
||||
DrawLine( gp, fp );
|
||||
}
|
||||
|
||||
foreach( var (mp, mod, _) in cache.MetaManipulations.Manipulations
|
||||
.Select( p => ( p.Item1.IdentifierString(), p.Item2.Data.Meta.Name, p.Item2.Data.Meta.LowerName ) )
|
||||
.Where( CheckFilters ) )
|
||||
{
|
||||
DrawLine( mp, mod );
|
||||
}
|
||||
}
|
||||
|
||||
if( active != null )
|
||||
{
|
||||
DrawFileLines( active );
|
||||
}
|
||||
|
||||
if( forced != null )
|
||||
{
|
||||
DrawFileLines( forced );
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
DrawFilters();
|
||||
|
||||
const ImGuiTableFlags flags = ImGuiTableFlags.RowBg | ImGuiTableFlags.ScrollX;
|
||||
|
||||
var activeCollection = _modManager.Collections.ActiveCollection.Cache;
|
||||
var forcedCollection = _modManager.Collections.ForcedCollection.Cache;
|
||||
|
||||
var (activeResolved, activeSwap, activeMeta) = activeCollection != null
|
||||
? ( activeCollection.ResolvedFiles.Count, activeCollection.SwappedFiles.Count, activeCollection.MetaManipulations.Count )
|
||||
: ( 0, 0, 0 );
|
||||
var (forcedResolved, forcedSwap, forcedMeta) = forcedCollection != null
|
||||
? ( forcedCollection.ResolvedFiles.Count, forcedCollection.SwappedFiles.Count, forcedCollection.MetaManipulations.Count )
|
||||
: ( 0, 0, 0 );
|
||||
var totalLines = activeResolved + forcedResolved + activeSwap + forcedSwap + activeMeta + forcedMeta;
|
||||
if( totalLines == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( ImGui.BeginTable( "##effective_changes", 2, flags, AutoFillSize ) )
|
||||
{
|
||||
raii.Push( ImGui.EndTable );
|
||||
ImGui.TableSetupColumn( "##tableGamePathCol", ImGuiTableColumnFlags.None, _leftTextLength * ImGuiHelpers.GlobalScale );
|
||||
|
||||
if( _filePathFilter.Any() || _gamePathFilter.Any() )
|
||||
{
|
||||
DrawFilteredRows( activeCollection, forcedCollection );
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiListClipperPtr clipper;
|
||||
unsafe
|
||||
for( var actualRow = clipper.DisplayStart; actualRow < clipper.DisplayEnd; actualRow++ )
|
||||
{
|
||||
clipper = new ImGuiListClipperPtr( ImGuiNative.ImGuiListClipper_ImGuiListClipper() );
|
||||
}
|
||||
|
||||
clipper.Begin( totalLines );
|
||||
|
||||
|
||||
while( clipper.Step() )
|
||||
{
|
||||
for( var actualRow = clipper.DisplayStart; actualRow < clipper.DisplayEnd; actualRow++ )
|
||||
var row = actualRow;
|
||||
ImGui.TableNextRow();
|
||||
if( row < activeResolved )
|
||||
{
|
||||
var row = actualRow;
|
||||
ImGui.TableNextRow();
|
||||
if( row < activeResolved )
|
||||
{
|
||||
var (gamePath, file) = activeCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file.FullName );
|
||||
}
|
||||
else if( ( row -= activeResolved ) < activeSwap )
|
||||
{
|
||||
var (gamePath, swap) = activeCollection!.SwappedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, swap );
|
||||
}
|
||||
else if( ( row -= activeSwap ) < activeMeta )
|
||||
{
|
||||
var (manip, mod) = activeCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
else if( ( row -= activeMeta ) < forcedResolved )
|
||||
{
|
||||
var (gamePath, file) = forcedCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file.FullName );
|
||||
}
|
||||
else if( ( row -= forcedResolved ) < forcedSwap )
|
||||
{
|
||||
var (gamePath, swap) = forcedCollection!.SwappedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, swap );
|
||||
}
|
||||
else
|
||||
{
|
||||
row -= forcedSwap;
|
||||
var (manip, mod) = forcedCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
var (gamePath, file) = activeCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file.FullName );
|
||||
}
|
||||
else if( ( row -= activeResolved ) < activeSwap )
|
||||
{
|
||||
var (gamePath, swap) = activeCollection!.SwappedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, swap );
|
||||
}
|
||||
else if( ( row -= activeSwap ) < activeMeta )
|
||||
{
|
||||
var (manip, mod) = activeCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
else if( ( row -= activeMeta ) < forcedResolved )
|
||||
{
|
||||
var (gamePath, file) = forcedCollection!.ResolvedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, file.FullName );
|
||||
}
|
||||
else if( ( row -= forcedResolved ) < forcedSwap )
|
||||
{
|
||||
var (gamePath, swap) = forcedCollection!.SwappedFiles.ElementAt( row );
|
||||
DrawLine( gamePath, swap );
|
||||
}
|
||||
else
|
||||
{
|
||||
row -= forcedSwap;
|
||||
var (manip, mod) = forcedCollection!.MetaManipulations.Manipulations.ElementAt( row );
|
||||
DrawLine( manip.IdentifierString(), mod.Data.Meta.Name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -219,5 +214,4 @@ namespace Penumbra.UI
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,188 +8,182 @@ using System.Windows.Forms;
|
|||
using Dalamud.Logging;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Importer;
|
||||
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 class TabImport
|
||||
{
|
||||
private class TabImport
|
||||
private const string LabelTab = "Import Mods";
|
||||
private const string LabelImportButton = "Import TexTools Modpacks";
|
||||
private const string LabelFileDialog = "Pick one or more modpacks.";
|
||||
private const string LabelFileImportRunning = "Import in progress...";
|
||||
private const string FileTypeFilter = "TexTools TTMP Modpack (*.ttmp2)|*.ttmp*|All files (*.*)|*.*";
|
||||
private const string TooltipModpack1 = "Writing modpack to disk before extracting...";
|
||||
|
||||
private const uint ColorRed = 0xFF0000C8;
|
||||
private const uint ColorYellow = 0xFF00C8C8;
|
||||
|
||||
private static readonly Vector2 ImportBarSize = new(-1, 0);
|
||||
|
||||
private bool _isImportRunning;
|
||||
private string _errorMessage = string.Empty;
|
||||
private TexToolsImport? _texToolsImport;
|
||||
private readonly SettingsInterface _base;
|
||||
|
||||
public readonly HashSet< string > NewMods = new();
|
||||
|
||||
public TabImport( SettingsInterface ui )
|
||||
=> _base = ui;
|
||||
|
||||
public bool IsImporting()
|
||||
=> _isImportRunning;
|
||||
|
||||
private void RunImportTask()
|
||||
{
|
||||
private const string LabelTab = "Import Mods";
|
||||
private const string LabelImportButton = "Import TexTools Modpacks";
|
||||
private const string LabelFileDialog = "Pick one or more modpacks.";
|
||||
private const string LabelFileImportRunning = "Import in progress...";
|
||||
private const string FileTypeFilter = "TexTools TTMP Modpack (*.ttmp2)|*.ttmp*|All files (*.*)|*.*";
|
||||
private const string TooltipModpack1 = "Writing modpack to disk before extracting...";
|
||||
|
||||
private const uint ColorRed = 0xFF0000C8;
|
||||
private const uint ColorYellow = 0xFF00C8C8;
|
||||
|
||||
private static readonly Vector2 ImportBarSize = new( -1, 0 );
|
||||
|
||||
private bool _isImportRunning;
|
||||
private string _errorMessage = string.Empty;
|
||||
private TexToolsImport? _texToolsImport;
|
||||
private readonly SettingsInterface _base;
|
||||
private readonly ModManager _manager;
|
||||
|
||||
public readonly HashSet< string > NewMods = new();
|
||||
|
||||
public TabImport( SettingsInterface ui )
|
||||
_isImportRunning = true;
|
||||
Task.Run( async () =>
|
||||
{
|
||||
_base = ui;
|
||||
_manager = Service< ModManager >.Get();
|
||||
}
|
||||
|
||||
public bool IsImporting()
|
||||
=> _isImportRunning;
|
||||
|
||||
private void RunImportTask()
|
||||
{
|
||||
_isImportRunning = true;
|
||||
Task.Run( async () =>
|
||||
try
|
||||
{
|
||||
try
|
||||
var picker = new OpenFileDialog
|
||||
{
|
||||
var picker = new OpenFileDialog
|
||||
Multiselect = true,
|
||||
Filter = FileTypeFilter,
|
||||
CheckFileExists = true,
|
||||
Title = LabelFileDialog,
|
||||
};
|
||||
|
||||
var result = await picker.ShowDialogAsync();
|
||||
|
||||
if( result == DialogResult.OK )
|
||||
{
|
||||
_errorMessage = string.Empty;
|
||||
|
||||
foreach( var fileName in picker.FileNames )
|
||||
{
|
||||
Multiselect = true,
|
||||
Filter = FileTypeFilter,
|
||||
CheckFileExists = true,
|
||||
Title = LabelFileDialog,
|
||||
};
|
||||
PluginLog.Information( $"-> {fileName} START" );
|
||||
|
||||
var result = await picker.ShowDialogAsync();
|
||||
|
||||
if( result == DialogResult.OK )
|
||||
{
|
||||
_errorMessage = string.Empty;
|
||||
|
||||
foreach( var fileName in picker.FileNames )
|
||||
try
|
||||
{
|
||||
PluginLog.Information( $"-> {fileName} START" );
|
||||
|
||||
try
|
||||
_texToolsImport = new TexToolsImport( Penumbra.ModManager.BasePath );
|
||||
var dir = _texToolsImport.ImportModPack( new FileInfo( fileName ) );
|
||||
if( dir.Name.Any() )
|
||||
{
|
||||
_texToolsImport = new TexToolsImport( _manager.BasePath );
|
||||
var dir = _texToolsImport.ImportModPack( new FileInfo( fileName ) );
|
||||
if( dir.Name.Any() )
|
||||
{
|
||||
NewMods.Add( dir.Name );
|
||||
}
|
||||
NewMods.Add( dir.Name );
|
||||
}
|
||||
|
||||
PluginLog.Information( $"-> {fileName} OK!" );
|
||||
}
|
||||
catch( Exception ex )
|
||||
{
|
||||
PluginLog.LogError( ex, "Failed to import modpack at {0}", fileName );
|
||||
_errorMessage = ex.Message;
|
||||
}
|
||||
PluginLog.Information( $"-> {fileName} OK!" );
|
||||
}
|
||||
|
||||
var directory = _texToolsImport?.ExtractedDirectory;
|
||||
_texToolsImport = null;
|
||||
_base.ReloadMods();
|
||||
if( directory != null )
|
||||
catch( Exception ex )
|
||||
{
|
||||
_base._menu.InstalledTab.Selector.SelectModOnUpdate( directory.Name );
|
||||
PluginLog.LogError( ex, "Failed to import modpack at {0}", fileName );
|
||||
_errorMessage = ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
var directory = _texToolsImport?.ExtractedDirectory;
|
||||
_texToolsImport = null;
|
||||
_base.ReloadMods();
|
||||
if( directory != null )
|
||||
{
|
||||
_base._menu.InstalledTab.Selector.SelectModOnUpdate( directory.Name );
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Error opening file picker dialogue:\n{e}" );
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Error opening file picker dialogue:\n{e}" );
|
||||
}
|
||||
|
||||
_isImportRunning = false;
|
||||
} );
|
||||
}
|
||||
_isImportRunning = false;
|
||||
} );
|
||||
}
|
||||
|
||||
private void DrawImportButton()
|
||||
private void DrawImportButton()
|
||||
{
|
||||
if( !Penumbra.ModManager.Valid )
|
||||
{
|
||||
if( !_manager.Valid )
|
||||
{
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f );
|
||||
ImGui.Button( LabelImportButton );
|
||||
style.Pop();
|
||||
using var style = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f );
|
||||
ImGui.Button( LabelImportButton );
|
||||
style.Pop();
|
||||
|
||||
using var color = ImGuiRaii.PushColor( ImGuiCol.Text, ColorRed );
|
||||
ImGui.Text( "Can not import since the mod directory path is not valid." );
|
||||
ImGui.Dummy( Vector2.UnitY * ImGui.GetTextLineHeightWithSpacing() );
|
||||
color.Pop();
|
||||
|
||||
ImGui.Text( "Please set the mod directory in the settings tab." );
|
||||
ImGui.Text( "This folder should preferably be close to the root directory of your (preferably SSD) drive, for example" );
|
||||
color.Push( ImGuiCol.Text, ColorYellow );
|
||||
ImGui.Text( " D:\\ffxivmods" );
|
||||
color.Pop();
|
||||
ImGui.Text( "You can return to this tab once you've done that." );
|
||||
}
|
||||
else if( ImGui.Button( LabelImportButton ) )
|
||||
{
|
||||
RunImportTask();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawImportProgress()
|
||||
{
|
||||
ImGui.Button( LabelFileImportRunning );
|
||||
|
||||
if( _texToolsImport == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch( _texToolsImport.State )
|
||||
{
|
||||
case ImporterState.None: break;
|
||||
case ImporterState.WritingPackToDisk:
|
||||
ImGui.Text( TooltipModpack1 );
|
||||
break;
|
||||
case ImporterState.ExtractingModFiles:
|
||||
{
|
||||
var str =
|
||||
$"{_texToolsImport.CurrentModPack} - {_texToolsImport.CurrentProgress} of {_texToolsImport.TotalProgress} files";
|
||||
|
||||
ImGui.ProgressBar( _texToolsImport.Progress, ImportBarSize, str );
|
||||
break;
|
||||
}
|
||||
case ImporterState.Done: break;
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawFailedImportMessage()
|
||||
{
|
||||
using var color = ImGuiRaii.PushColor( ImGuiCol.Text, ColorRed );
|
||||
ImGui.Text( $"One or more of your modpacks failed to import:\n\t\t{_errorMessage}" );
|
||||
ImGui.Text( "Can not import since the mod directory path is not valid." );
|
||||
ImGui.Dummy( Vector2.UnitY * ImGui.GetTextLineHeightWithSpacing() );
|
||||
color.Pop();
|
||||
|
||||
ImGui.Text( "Please set the mod directory in the settings tab." );
|
||||
ImGui.Text( "This folder should preferably be close to the root directory of your (preferably SSD) drive, for example" );
|
||||
color.Push( ImGuiCol.Text, ColorYellow );
|
||||
ImGui.Text( " D:\\ffxivmods" );
|
||||
color.Pop();
|
||||
ImGui.Text( "You can return to this tab once you've done that." );
|
||||
}
|
||||
else if( ImGui.Button( LabelImportButton ) )
|
||||
{
|
||||
RunImportTask();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawImportProgress()
|
||||
{
|
||||
ImGui.Button( LabelFileImportRunning );
|
||||
|
||||
if( _texToolsImport == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
switch( _texToolsImport.State )
|
||||
{
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
case ImporterState.None: break;
|
||||
case ImporterState.WritingPackToDisk:
|
||||
ImGui.Text( TooltipModpack1 );
|
||||
break;
|
||||
case ImporterState.ExtractingModFiles:
|
||||
{
|
||||
return;
|
||||
}
|
||||
var str =
|
||||
$"{_texToolsImport.CurrentModPack} - {_texToolsImport.CurrentProgress} of {_texToolsImport.TotalProgress} files";
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
ImGui.ProgressBar( _texToolsImport.Progress, ImportBarSize, str );
|
||||
break;
|
||||
}
|
||||
case ImporterState.Done: break;
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
|
||||
if( !_isImportRunning )
|
||||
{
|
||||
DrawImportButton();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImportProgress();
|
||||
}
|
||||
private void DrawFailedImportMessage()
|
||||
{
|
||||
using var color = ImGuiRaii.PushColor( ImGuiCol.Text, ColorRed );
|
||||
ImGui.Text( $"One or more of your modpacks failed to import:\n\t\t{_errorMessage}" );
|
||||
}
|
||||
|
||||
if( _errorMessage.Any() )
|
||||
{
|
||||
DrawFailedImportMessage();
|
||||
}
|
||||
public void Draw()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( LabelTab ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
if( !_isImportRunning )
|
||||
{
|
||||
DrawImportButton();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawImportProgress();
|
||||
}
|
||||
|
||||
if( _errorMessage.Any() )
|
||||
{
|
||||
DrawFailedImportMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,42 +1,37 @@
|
|||
using System.Collections.Generic;
|
||||
using ImGuiNET;
|
||||
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 class TabInstalled
|
||||
{
|
||||
private class TabInstalled
|
||||
private const string LabelTab = "Installed Mods";
|
||||
|
||||
public readonly Selector Selector;
|
||||
public readonly ModPanel ModPanel;
|
||||
|
||||
public TabInstalled( SettingsInterface ui, HashSet< string > newMods )
|
||||
{
|
||||
private const string LabelTab = "Installed Mods";
|
||||
Selector = new Selector( ui, newMods );
|
||||
ModPanel = new ModPanel( ui, Selector, newMods );
|
||||
}
|
||||
|
||||
private readonly ModManager _modManager;
|
||||
public readonly Selector Selector;
|
||||
public readonly ModPanel ModPanel;
|
||||
|
||||
public TabInstalled( SettingsInterface ui, HashSet< string > newMods )
|
||||
public void Draw()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( LabelTab );
|
||||
if( !ret )
|
||||
{
|
||||
Selector = new Selector( ui, newMods );
|
||||
ModPanel = new ModPanel( ui, Selector, newMods );
|
||||
_modManager = Service< ModManager >.Get();
|
||||
return;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
var ret = ImGui.BeginTabItem( LabelTab );
|
||||
if( !ret )
|
||||
{
|
||||
return;
|
||||
}
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
Selector.Draw();
|
||||
ImGui.SameLine();
|
||||
ModPanel.Draw();
|
||||
}
|
||||
Selector.Draw();
|
||||
ImGui.SameLine();
|
||||
ModPanel.Draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -112,7 +112,7 @@ namespace Penumbra.UI
|
|||
var groupName = group.GroupName;
|
||||
if( ImGuiCustom.BeginFramedGroupEdit( ref groupName ) )
|
||||
{
|
||||
if( _modManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
if( Penumbra.ModManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
if( newName.Length == 0 )
|
||||
{
|
||||
_modManager.RemoveModOption( i, group, Mod.Data );
|
||||
Penumbra.ModManager.RemoveModOption( i, group, Mod.Data );
|
||||
}
|
||||
else if( newName != opt.OptionName )
|
||||
{
|
||||
|
|
@ -189,7 +189,7 @@ namespace Penumbra.UI
|
|||
var groupName = group.GroupName;
|
||||
if( ImGui.InputText( $"##{groupName}_add", ref groupName, 64, ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
if( _modManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
if( Penumbra.ModManager.ChangeModGroup( group.GroupName, groupName, Mod.Data ) && Mod.Data.Meta.RefreshHasGroupsWithConfig() )
|
||||
{
|
||||
_selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ namespace Penumbra.UI
|
|||
{
|
||||
if( newName.Length == 0 )
|
||||
{
|
||||
_modManager.RemoveModOption( code, group, Mod.Data );
|
||||
Penumbra.ModManager.RemoveModOption( code, group, Mod.Data );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -267,7 +267,7 @@ namespace Penumbra.UI
|
|||
if( ImGui.InputTextWithHint( LabelNewSingleGroupEdit, "Add new Single Group...", ref newGroup, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
_modManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Single );
|
||||
Penumbra.ModManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Single );
|
||||
// Adds empty group, so can not change filters.
|
||||
}
|
||||
}
|
||||
|
|
@ -280,7 +280,7 @@ namespace Penumbra.UI
|
|||
if( ImGui.InputTextWithHint( LabelNewMultiGroup, "Add new Multi Group...", ref newGroup, 64,
|
||||
ImGuiInputTextFlags.EnterReturnsTrue ) )
|
||||
{
|
||||
_modManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Multi );
|
||||
Penumbra.ModManager.ChangeModGroup( "", newGroup, Mod.Data, SelectType.Multi );
|
||||
// Adds empty group, so can not change filters.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ namespace Penumbra.UI
|
|||
if( ImGui.BeginPopup( $"##MetaPopup{manipIdx}" ) )
|
||||
{
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndPopup );
|
||||
var defaults = ( EqpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var defaults = ( EqpEntry )Penumbra.MetaDefaults.GetDefaultValue( list[ manipIdx ] )!;
|
||||
var attributes = Eqp.EqpAttributes[ id.Slot ];
|
||||
|
||||
foreach( var flag in attributes )
|
||||
|
|
@ -254,7 +254,7 @@ namespace Penumbra.UI
|
|||
|
||||
private bool DrawGmpRow( int manipIdx, IList< MetaManipulation > list )
|
||||
{
|
||||
var defaults = ( GmpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var defaults = ( GmpEntry )Penumbra.MetaDefaults.GetDefaultValue( list[ manipIdx ] )!;
|
||||
var ret = false;
|
||||
var id = list[ manipIdx ].GmpIdentifier;
|
||||
var val = list[ manipIdx ].GmpValue;
|
||||
|
|
@ -364,7 +364,7 @@ namespace Penumbra.UI
|
|||
|
||||
private bool DrawEqdpRow( int manipIdx, IList< MetaManipulation > list )
|
||||
{
|
||||
var defaults = ( EqdpEntry )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var defaults = ( EqdpEntry )Penumbra.MetaDefaults.GetDefaultValue( list[ manipIdx ] )!;
|
||||
var ret = false;
|
||||
var id = list[ manipIdx ].EqdpIdentifier;
|
||||
var val = list[ manipIdx ].EqdpValue;
|
||||
|
|
@ -401,7 +401,7 @@ namespace Penumbra.UI
|
|||
|
||||
private bool DrawEstRow( int manipIdx, IList< MetaManipulation > list )
|
||||
{
|
||||
var defaults = ( ushort )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var defaults = ( ushort )Penumbra.MetaDefaults.GetDefaultValue( list[ manipIdx ] )!;
|
||||
var ret = false;
|
||||
var id = list[ manipIdx ].EstIdentifier;
|
||||
var val = list[ manipIdx ].EstValue;
|
||||
|
|
@ -433,7 +433,7 @@ namespace Penumbra.UI
|
|||
|
||||
private bool DrawImcRow( int manipIdx, IList< MetaManipulation > list )
|
||||
{
|
||||
var defaults = ( ImcFile.ImageChangeData )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var defaults = ( ImcFile.ImageChangeData )Penumbra.MetaDefaults.GetDefaultValue( list[ manipIdx ] )!;
|
||||
var ret = false;
|
||||
var id = list[ manipIdx ].ImcIdentifier;
|
||||
var val = list[ manipIdx ].ImcValue;
|
||||
|
|
@ -492,7 +492,7 @@ namespace Penumbra.UI
|
|||
|
||||
private bool DrawRspRow( int manipIdx, IList< MetaManipulation > list )
|
||||
{
|
||||
var defaults = ( float )Service< MetaDefaults >.Get().GetDefaultValue( list[ manipIdx ] )!;
|
||||
var defaults = ( float )Penumbra.MetaDefaults.GetDefaultValue( list[ manipIdx ] )!;
|
||||
var ret = false;
|
||||
var id = list[ manipIdx ].RspIdentifier;
|
||||
var val = list[ manipIdx ].RspValue;
|
||||
|
|
@ -694,7 +694,7 @@ namespace Penumbra.UI
|
|||
&& newManip != null
|
||||
&& list.All( m => m.Identifier != newManip.Value.Identifier ) )
|
||||
{
|
||||
var def = Service< MetaDefaults >.Get().GetDefaultValue( newManip.Value );
|
||||
var def = Penumbra.MetaDefaults.GetDefaultValue( newManip.Value );
|
||||
if( def != null )
|
||||
{
|
||||
var manip = newManip.Value.Type switch
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ public partial class SettingsInterface
|
|||
|
||||
private readonly SettingsInterface _base;
|
||||
private readonly Selector _selector;
|
||||
private readonly ModManager _modManager;
|
||||
private readonly HashSet< string > _newMods;
|
||||
public readonly PluginDetails Details;
|
||||
|
||||
|
|
@ -68,7 +67,6 @@ public partial class SettingsInterface
|
|||
_newMods = newMods;
|
||||
Details = new PluginDetails( _base, _selector );
|
||||
_currentWebsite = Meta?.Website ?? "";
|
||||
_modManager = Service< ModManager >.Get();
|
||||
}
|
||||
|
||||
private Mod.Mod? Mod
|
||||
|
|
@ -79,11 +77,12 @@ public partial class SettingsInterface
|
|||
|
||||
private void DrawName()
|
||||
{
|
||||
var name = Meta!.Name;
|
||||
if( ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 ) && _modManager.RenameMod( name, Mod!.Data ) )
|
||||
var name = Meta!.Name;
|
||||
var modManager = Penumbra.ModManager;
|
||||
if( ImGuiCustom.InputOrText( _editMode, LabelEditName, ref name, 64 ) && modManager.RenameMod( name, Mod!.Data ) )
|
||||
{
|
||||
_selector.SelectModOnUpdate( Mod.Data.BasePath.Name );
|
||||
if( !_modManager.Config.ModSortOrder.ContainsKey( Mod!.Data.BasePath.Name ) )
|
||||
if( !modManager.Config.ModSortOrder.ContainsKey( Mod!.Data.BasePath.Name ) )
|
||||
{
|
||||
Mod.Data.Rename( name );
|
||||
}
|
||||
|
|
@ -286,7 +285,7 @@ public partial class SettingsInterface
|
|||
{
|
||||
ImGui.OpenPopup( LabelOverWriteDir );
|
||||
}
|
||||
else if( _modManager.RenameModFolder( Mod.Data, newDir ) )
|
||||
else if( Penumbra.ModManager.RenameModFolder( Mod.Data, newDir ) )
|
||||
{
|
||||
_selector.ReloadCurrentMod();
|
||||
ImGui.CloseCurrentPopup();
|
||||
|
|
@ -301,12 +300,12 @@ public partial class SettingsInterface
|
|||
if( sourceUri.Equals( targetUri ) )
|
||||
{
|
||||
var tmpFolder = new DirectoryInfo( TempFile.TempFileName( dir.Parent! ).FullName );
|
||||
if( _modManager.RenameModFolder( Mod.Data, tmpFolder ) )
|
||||
if( Penumbra.ModManager.RenameModFolder( Mod.Data, tmpFolder ) )
|
||||
{
|
||||
if( !_modManager.RenameModFolder( Mod.Data, newDir ) )
|
||||
if( !Penumbra.ModManager.RenameModFolder( Mod.Data, newDir ) )
|
||||
{
|
||||
PluginLog.Error( "Could not recapitalize folder after renaming, reverting rename." );
|
||||
_modManager.RenameModFolder( Mod.Data, dir );
|
||||
Penumbra.ModManager.RenameModFolder( Mod.Data, dir );
|
||||
}
|
||||
|
||||
_selector.ReloadCurrentMod();
|
||||
|
|
@ -364,17 +363,14 @@ public partial class SettingsInterface
|
|||
ImGui.Text(
|
||||
$"The mod directory {newDir} already exists.\nDo you want to merge / overwrite both mods?\nThis may corrupt the resulting mod in irrecoverable ways." );
|
||||
var buttonSize = ImGuiHelpers.ScaledVector2( 120, 0 );
|
||||
if( ImGui.Button( "Yes", buttonSize ) )
|
||||
if( ImGui.Button( "Yes", buttonSize ) && MergeFolderInto( dir, newDir ) )
|
||||
{
|
||||
if( MergeFolderInto( dir, newDir ) )
|
||||
{
|
||||
Service< ModManager >.Get()!.RenameModFolder( Mod.Data, newDir, false );
|
||||
Penumbra.ModManager.RenameModFolder( Mod.Data, newDir, false );
|
||||
|
||||
_selector.SelectModOnUpdate( _newName );
|
||||
_selector.SelectModOnUpdate( _newName );
|
||||
|
||||
closeParent = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
closeParent = true;
|
||||
ImGui.CloseCurrentPopup();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
|
@ -580,7 +576,7 @@ public partial class SettingsInterface
|
|||
|
||||
DrawMaterialChangeRow();
|
||||
|
||||
DrawSortOrder( Mod!.Data, _modManager, _selector );
|
||||
DrawSortOrder( Mod!.Data, Penumbra.ModManager, _selector );
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ public partial class SettingsInterface
|
|||
ImGui.CloseCurrentPopup();
|
||||
var mod = Mod;
|
||||
Cache.RemoveMod( mod );
|
||||
_modManager.DeleteMod( mod.Data.BasePath );
|
||||
Penumbra.ModManager.DeleteMod( mod.Data.BasePath );
|
||||
ModFileSystem.InvokeChange();
|
||||
ClearSelection();
|
||||
}
|
||||
|
|
@ -166,7 +166,7 @@ public partial class SettingsInterface
|
|||
|
||||
var metaFile = new FileInfo( Path.Combine( newDir.FullName, "meta.json" ) );
|
||||
modMeta.SaveToFile( metaFile );
|
||||
_modManager.AddMod( newDir );
|
||||
Penumbra.ModManager.AddMod( newDir );
|
||||
ModFileSystem.InvokeChange();
|
||||
SelectModOnUpdate( newDir.Name );
|
||||
}
|
||||
|
|
@ -464,7 +464,7 @@ public partial class SettingsInterface
|
|||
return;
|
||||
}
|
||||
|
||||
if( _index >= 0 && _modManager.UpdateMod( Mod.Data, reloadMeta, recomputeMeta, force ) )
|
||||
if( _index >= 0 && Penumbra.ModManager.UpdateMod( Mod.Data, reloadMeta, recomputeMeta, force ) )
|
||||
{
|
||||
SelectModOnUpdate( Mod.Data.BasePath.Name );
|
||||
_base._menu.InstalledTab.ModPanel.Details.ResetState();
|
||||
|
|
@ -526,11 +526,11 @@ public partial class SettingsInterface
|
|||
}
|
||||
|
||||
Cache.TriggerFilterReset();
|
||||
var collection = _modManager.Collections.CurrentCollection;
|
||||
var collection = Penumbra.ModManager.Collections.CurrentCollection;
|
||||
if( collection.Cache != null )
|
||||
{
|
||||
collection.CalculateEffectiveFileList( _modManager.TempPath, metaManips,
|
||||
collection == _modManager.Collections.ActiveCollection );
|
||||
collection.CalculateEffectiveFileList( Penumbra.ModManager.TempPath, metaManips,
|
||||
collection == Penumbra.ModManager.Collections.ActiveCollection );
|
||||
}
|
||||
|
||||
collection.Save();
|
||||
|
|
@ -597,7 +597,6 @@ public partial class SettingsInterface
|
|||
private partial class Selector
|
||||
{
|
||||
private readonly SettingsInterface _base;
|
||||
private readonly ModManager _modManager;
|
||||
public readonly ModListCache Cache;
|
||||
|
||||
private float _selectorScalingFactor = 1;
|
||||
|
|
@ -605,14 +604,13 @@ public partial class SettingsInterface
|
|||
public Selector( SettingsInterface ui, IReadOnlySet< string > newMods )
|
||||
{
|
||||
_base = ui;
|
||||
_modManager = Service< ModManager >.Get();
|
||||
Cache = new ModListCache( _modManager, newMods );
|
||||
Cache = new ModListCache( Penumbra.ModManager, newMods );
|
||||
}
|
||||
|
||||
private void DrawCollectionButton( string label, string tooltipLabel, float size, ModCollection collection )
|
||||
{
|
||||
if( collection == ModCollection.Empty
|
||||
|| collection == _modManager.Collections.CurrentCollection )
|
||||
|| collection == Penumbra.ModManager.Collections.CurrentCollection )
|
||||
{
|
||||
using var _ = ImGuiRaii.PushStyle( ImGuiStyleVar.Alpha, 0.5f );
|
||||
ImGui.Button( label, Vector2.UnitX * size );
|
||||
|
|
@ -641,10 +639,10 @@ public partial class SettingsInterface
|
|||
- 4 * ImGui.GetStyle().ItemSpacing.X )
|
||||
/ 2, 5f );
|
||||
ImGui.SameLine();
|
||||
DrawCollectionButton( "Default", "default", buttonSize, _modManager.Collections.DefaultCollection );
|
||||
DrawCollectionButton( "Default", "default", buttonSize, Penumbra.ModManager.Collections.DefaultCollection );
|
||||
|
||||
ImGui.SameLine();
|
||||
DrawCollectionButton( "Forced", "forced", buttonSize, _modManager.Collections.ForcedCollection );
|
||||
DrawCollectionButton( "Forced", "forced", buttonSize, Penumbra.ModManager.Collections.ForcedCollection );
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth( comboSize );
|
||||
|
|
@ -655,7 +653,7 @@ public partial class SettingsInterface
|
|||
private void DrawFolderContent( ModFolder folder, ref int idx )
|
||||
{
|
||||
// Collection may be manipulated.
|
||||
foreach( var item in folder.GetItems( _modManager.Config.SortFoldersFirst ).ToArray() )
|
||||
foreach( var item in folder.GetItems( Penumbra.ModManager.Config.SortFoldersFirst ).ToArray() )
|
||||
{
|
||||
if( item is ModFolder sub )
|
||||
{
|
||||
|
|
@ -785,7 +783,7 @@ public partial class SettingsInterface
|
|||
style.Push( ImGuiStyleVar.IndentSpacing, 12.5f );
|
||||
|
||||
var modIndex = 0;
|
||||
DrawFolderContent( _modManager.StructuredMods, ref modIndex );
|
||||
DrawFolderContent( Penumbra.ModManager.StructuredMods, ref modIndex );
|
||||
style.Pop();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Dalamud.Interface;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource;
|
||||
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
|
||||
using FFXIVClientStructs.STD;
|
||||
using ImGuiNET;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.UI.Custom;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
|
@ -21,16 +24,22 @@ public partial class SettingsInterface
|
|||
: $"({type:X8}) {( char )byte1}{( char )byte2}{( char )byte3}{( char )byte4} - {count}###{label}{type}Debug";
|
||||
}
|
||||
|
||||
private unsafe void DrawResourceMap( string label, StdMap< uint, Pointer< ResourceHandle > >* typeMap )
|
||||
private unsafe void DrawResourceMap( ResourceCategory category, uint ext, StdMap< uint, Pointer< ResourceHandle > >* map )
|
||||
{
|
||||
if( typeMap == null || !ImGui.TreeNodeEx( label ) )
|
||||
if( map == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var label = GetNodeLabel( ( uint )category, ext, map->Count );
|
||||
if( !ImGui.TreeNodeEx( label ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.TreePop );
|
||||
|
||||
if( typeMap->Count == 0 || !ImGui.BeginTable( $"##{label}_table", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg ) )
|
||||
if( map->Count == 0 || !ImGui.BeginTable( $"##{label}_table", 4, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.RowBg ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -44,21 +53,19 @@ public partial class SettingsInterface
|
|||
ImGui.TableSetupColumn( "Refs", ImGuiTableColumnFlags.WidthFixed, 30 * ImGuiHelpers.GlobalScale );
|
||||
ImGui.TableHeadersRow();
|
||||
|
||||
var node = typeMap->SmallestValue;
|
||||
while( !node->IsNil )
|
||||
ResourceLoader.IterateResourceMap( map, ( hash, r ) =>
|
||||
{
|
||||
ImGui.TableNextRow();
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( $"0x{node->KeyValuePair.Item1:X8}" );
|
||||
ImGui.Text( $"0x{hash:X8}" );
|
||||
ImGui.TableNextColumn();
|
||||
var address = $"0x{( ulong )node->KeyValuePair.Item2.Value:X}";
|
||||
var address = $"0x{( ulong )r:X}";
|
||||
ImGui.Text( address );
|
||||
if( ImGui.IsItemClicked() )
|
||||
{
|
||||
ImGui.SetClipboardText( address );
|
||||
}
|
||||
|
||||
ref var name = ref node->KeyValuePair.Item2.Value->FileName;
|
||||
ref var name = ref r->FileName;
|
||||
ImGui.TableNextColumn();
|
||||
if( name.Capacity > 15 )
|
||||
{
|
||||
|
|
@ -72,30 +79,73 @@ public partial class SettingsInterface
|
|||
}
|
||||
}
|
||||
|
||||
//ImGui.Text( node->KeyValuePair.Item2.Value->FileName.ToString() );
|
||||
if( ImGui.IsItemClicked() )
|
||||
{
|
||||
var data = ( ( Interop.Structs.ResourceHandle* )r )->GetData();
|
||||
ImGui.SetClipboardText( string.Join( " ",
|
||||
new ReadOnlySpan< byte >( ( byte* )data.Data, data.Length ).ToArray().Select( b => b.ToString( "X2" ) ) ) );
|
||||
//ImGuiNative.igSetClipboardText( ( byte* )Structs.ResourceHandle.GetData( ( IntPtr )r ) );
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( node->KeyValuePair.Item2.Value->RefCount.ToString() );
|
||||
node = node->Next();
|
||||
}
|
||||
ImGui.Text( r->RefCount.ToString() );
|
||||
} );
|
||||
}
|
||||
|
||||
private unsafe void DrawCategoryContainer( ResourceCategory category, ResourceGraph.CategoryContainer container )
|
||||
private unsafe void DrawCategoryContainer( ResourceCategory category,
|
||||
StdMap< uint, Pointer< StdMap< uint, Pointer< ResourceHandle > > > >* map )
|
||||
{
|
||||
var map = container.MainMap;
|
||||
if( map == null || !ImGui.TreeNodeEx( $"({( uint )category:D2}) {category} - {map->Count}###{( uint )category}Debug" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.TreePop );
|
||||
ResourceLoader.IterateExtMap( map, ( ext, map ) => DrawResourceMap( category, ext, map ) );
|
||||
}
|
||||
|
||||
var node = map->SmallestValue;
|
||||
while( !node->IsNil )
|
||||
|
||||
private static unsafe void DrawResourceProblems()
|
||||
{
|
||||
if( !ImGui.CollapsingHeader( "Resource Problems##ResourceManager" )
|
||||
|| !ImGui.BeginTable( "##ProblemsTable", 6, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit ) )
|
||||
{
|
||||
DrawResourceMap( GetNodeLabel( ( uint )category, node->KeyValuePair.Item1, node->KeyValuePair.Item2.Value->Count ),
|
||||
node->KeyValuePair.Item2.Value );
|
||||
node = node->Next();
|
||||
return;
|
||||
}
|
||||
|
||||
using var end = ImGuiRaii.DeferredEnd( ImGui.EndTable );
|
||||
|
||||
ResourceLoader.IterateResources( ( _, r ) =>
|
||||
{
|
||||
if( r->RefCount < 10000 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( r->Category.ToString() );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( r->FileType.ToString( "X" ) );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( r->Id.ToString( "X" ) );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( ( ( ulong )r ).ToString( "X" ) );
|
||||
ImGui.TableNextColumn();
|
||||
ImGui.Text( r->RefCount.ToString() );
|
||||
ImGui.TableNextColumn();
|
||||
ref var name = ref r->FileName;
|
||||
if( name.Capacity > 15 )
|
||||
{
|
||||
ImGuiNative.igTextUnformatted( name.BufferPtr, name.BufferPtr + name.Length );
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed( byte* ptr = name.Buffer )
|
||||
{
|
||||
ImGuiNative.igTextUnformatted( ptr, ptr + name.Length );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private unsafe void DrawResourceManagerTab()
|
||||
|
|
@ -107,7 +157,7 @@ public partial class SettingsInterface
|
|||
|
||||
using var raii = ImGuiRaii.DeferredEnd( ImGui.EndTabItem );
|
||||
|
||||
var resourceHandler = *( ResourceManager** )Dalamud.SigScanner.GetStaticAddressFromSig( "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 32 C0" );
|
||||
var resourceHandler = *ResourceLoader.ResourceManager;
|
||||
|
||||
if( resourceHandler == null )
|
||||
{
|
||||
|
|
@ -120,20 +170,6 @@ public partial class SettingsInterface
|
|||
return;
|
||||
}
|
||||
|
||||
DrawCategoryContainer( ResourceCategory.Common, resourceHandler->ResourceGraph->CommonContainer );
|
||||
DrawCategoryContainer( ResourceCategory.BgCommon, resourceHandler->ResourceGraph->BgCommonContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Bg, resourceHandler->ResourceGraph->BgContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Cut, resourceHandler->ResourceGraph->CutContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Chara, resourceHandler->ResourceGraph->CharaContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Shader, resourceHandler->ResourceGraph->ShaderContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Ui, resourceHandler->ResourceGraph->UiContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Sound, resourceHandler->ResourceGraph->SoundContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Vfx, resourceHandler->ResourceGraph->VfxContainer );
|
||||
DrawCategoryContainer( ResourceCategory.UiScript, resourceHandler->ResourceGraph->UiScriptContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Exd, resourceHandler->ResourceGraph->ExdContainer );
|
||||
DrawCategoryContainer( ResourceCategory.GameScript, resourceHandler->ResourceGraph->GameScriptContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Music, resourceHandler->ResourceGraph->MusicContainer );
|
||||
DrawCategoryContainer( ResourceCategory.SqpackTest, resourceHandler->ResourceGraph->SqpackTestContainer );
|
||||
DrawCategoryContainer( ResourceCategory.Debug, resourceHandler->ResourceGraph->DebugContainer );
|
||||
ResourceLoader.IterateGraphs( DrawCategoryContainer );
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,12 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Logging;
|
||||
using ImGuiNET;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.UI.Custom;
|
||||
using Penumbra.Util;
|
||||
|
||||
|
|
@ -71,7 +71,8 @@ public partial class SettingsInterface
|
|||
+ "It should also be placed near the root of a logical drive - the shorter the total path to this folder, the better.\n"
|
||||
+ "Definitely do not place it in your Dalamud directory or any sub-directory thereof." );
|
||||
ImGui.SameLine();
|
||||
DrawOpenDirectoryButton( 0, _base._modManager.BasePath, _base._modManager.Valid );
|
||||
var modManager = Penumbra.ModManager;
|
||||
DrawOpenDirectoryButton( 0, modManager.BasePath, modManager.Valid );
|
||||
ImGui.EndGroup();
|
||||
|
||||
if( _config.ModDirectory == _newModDirectory || !_newModDirectory.Any() )
|
||||
|
|
@ -82,7 +83,7 @@ public partial class SettingsInterface
|
|||
if( save || DrawPressEnterWarning( _config.ModDirectory ) )
|
||||
{
|
||||
_base._menu.InstalledTab.Selector.ClearSelection();
|
||||
_base._modManager.DiscoverMods( _newModDirectory );
|
||||
modManager.DiscoverMods( _newModDirectory );
|
||||
_base._menu.InstalledTab.Selector.Cache.TriggerListReset();
|
||||
_newModDirectory = _config.ModDirectory;
|
||||
}
|
||||
|
|
@ -99,7 +100,8 @@ public partial class SettingsInterface
|
|||
+ "A directory 'penumbrametatmp' will be created as a sub-directory to the specified directory.\n"
|
||||
+ "If none is specified (i.e. this is blank) this directory will be created in the root directory instead.\n" );
|
||||
ImGui.SameLine();
|
||||
DrawOpenDirectoryButton( 1, _base._modManager.TempPath, _base._modManager.TempWritable );
|
||||
var modManager = Penumbra.ModManager;
|
||||
DrawOpenDirectoryButton( 1, modManager.TempPath, modManager.TempWritable );
|
||||
ImGui.EndGroup();
|
||||
|
||||
if( _newTempDirectory == _config.TempDirectory )
|
||||
|
|
@ -109,7 +111,7 @@ public partial class SettingsInterface
|
|||
|
||||
if( save || DrawPressEnterWarning( _config.TempDirectory ) )
|
||||
{
|
||||
_base._modManager.SetTempDirectory( _newTempDirectory );
|
||||
modManager.SetTempDirectory( _newTempDirectory );
|
||||
_newTempDirectory = _config.TempDirectory;
|
||||
}
|
||||
}
|
||||
|
|
@ -119,7 +121,7 @@ public partial class SettingsInterface
|
|||
if( ImGui.Button( "Rediscover Mods" ) )
|
||||
{
|
||||
_base._menu.InstalledTab.Selector.ClearSelection();
|
||||
_base._modManager.DiscoverMods();
|
||||
Penumbra.ModManager.DiscoverMods();
|
||||
_base._menu.InstalledTab.Selector.Cache.TriggerListReset();
|
||||
}
|
||||
|
||||
|
|
@ -208,26 +210,26 @@ public partial class SettingsInterface
|
|||
|
||||
private void DrawLogLoadedFilesBox()
|
||||
{
|
||||
ImGui.Checkbox( "Log Loaded Files", ref _base._penumbra.ResourceLoader.LogAllFiles );
|
||||
ImGui.SameLine();
|
||||
var regex = _base._penumbra.ResourceLoader.LogFileFilter?.ToString() ?? string.Empty;
|
||||
var tmp = regex;
|
||||
ImGui.SetNextItemWidth( SettingsMenu.InputTextWidth );
|
||||
if( ImGui.InputTextWithHint( "##LogFilter", "Matching this Regex...", ref tmp, 64 ) && tmp != regex )
|
||||
{
|
||||
try
|
||||
{
|
||||
var newRegex = tmp.Length > 0 ? new Regex( tmp, RegexOptions.Compiled ) : null;
|
||||
_base._penumbra.ResourceLoader.LogFileFilter = newRegex;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Debug( "Could not create regex:\n{Exception}", e );
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
ImGuiComponents.HelpMarker( "Log all loaded files that match the given Regex to the PluginLog." );
|
||||
//ImGui.Checkbox( "Log Loaded Files", ref _base._penumbra.ResourceLoader.LogAllFiles );
|
||||
//ImGui.SameLine();
|
||||
//var regex = _base._penumbra.ResourceLoader.LogFileFilter?.ToString() ?? string.Empty;
|
||||
//var tmp = regex;
|
||||
//ImGui.SetNextItemWidth( SettingsMenu.InputTextWidth );
|
||||
//if( ImGui.InputTextWithHint( "##LogFilter", "Matching this Regex...", ref tmp, 64 ) && tmp != regex )
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// var newRegex = tmp.Length > 0 ? new Regex( tmp, RegexOptions.Compiled ) : null;
|
||||
// _base._penumbra.ResourceLoader.LogFileFilter = newRegex;
|
||||
// }
|
||||
// catch( Exception e )
|
||||
// {
|
||||
// PluginLog.Debug( "Could not create regex:\n{Exception}", e );
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//ImGui.SameLine();
|
||||
//ImGuiComponents.HelpMarker( "Log all loaded files that match the given Regex to the PluginLog." );
|
||||
}
|
||||
|
||||
private void DrawDisableNotificationsBox()
|
||||
|
|
@ -307,7 +309,7 @@ public partial class SettingsInterface
|
|||
{
|
||||
if( ImGui.Button( "Reload Resident Resources" ) )
|
||||
{
|
||||
Service< ResidentResources >.Get().ReloadResidentResources();
|
||||
Penumbra.ResidentResources.Reload();
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
|
@ -325,6 +327,11 @@ public partial class SettingsInterface
|
|||
DrawReloadResourceButton();
|
||||
}
|
||||
|
||||
public static unsafe void Text( Utf8String s )
|
||||
{
|
||||
ImGuiNative.igTextUnformatted( ( byte* )s.Path, ( byte* )s.Path + s.Length );
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if( !ImGui.BeginTabItem( "Settings" ) )
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.UI;
|
||||
|
||||
|
|
@ -15,17 +13,13 @@ public partial class SettingsInterface : IDisposable
|
|||
private readonly Penumbra _penumbra;
|
||||
|
||||
private readonly ManageModsButton _manageModsButton;
|
||||
private readonly MenuBar _menuBar;
|
||||
private readonly SettingsMenu _menu;
|
||||
private readonly ModManager _modManager;
|
||||
|
||||
public SettingsInterface( Penumbra penumbra )
|
||||
{
|
||||
_penumbra = penumbra;
|
||||
_manageModsButton = new ManageModsButton( this );
|
||||
_menuBar = new MenuBar( this );
|
||||
_menu = new SettingsMenu( this );
|
||||
_modManager = Service< ModManager >.Get();
|
||||
|
||||
Dalamud.PluginInterface.UiBuilder.DisableGposeUiHide = true;
|
||||
Dalamud.PluginInterface.UiBuilder.Draw += Draw;
|
||||
|
|
@ -51,31 +45,31 @@ public partial class SettingsInterface : IDisposable
|
|||
|
||||
public void Draw()
|
||||
{
|
||||
_menuBar.Draw();
|
||||
_menu.Draw();
|
||||
}
|
||||
|
||||
private void ReloadMods()
|
||||
{
|
||||
_menu.InstalledTab.Selector.ClearSelection();
|
||||
_modManager.DiscoverMods( Penumbra.Config.ModDirectory );
|
||||
Penumbra.ModManager.DiscoverMods( Penumbra.Config.ModDirectory );
|
||||
_menu.InstalledTab.Selector.Cache.TriggerListReset();
|
||||
}
|
||||
|
||||
private void SaveCurrentCollection( bool recalculateMeta )
|
||||
{
|
||||
var current = _modManager.Collections.CurrentCollection;
|
||||
var current = Penumbra.ModManager.Collections.CurrentCollection;
|
||||
current.Save();
|
||||
RecalculateCurrent( recalculateMeta );
|
||||
}
|
||||
|
||||
private void RecalculateCurrent( bool recalculateMeta )
|
||||
{
|
||||
var current = _modManager.Collections.CurrentCollection;
|
||||
var modManager = Penumbra.ModManager;
|
||||
var current = modManager.Collections.CurrentCollection;
|
||||
if( current.Cache != null )
|
||||
{
|
||||
current.CalculateEffectiveFileList( _modManager.TempPath, recalculateMeta,
|
||||
current == _modManager.Collections.ActiveCollection );
|
||||
current.CalculateEffectiveFileList( modManager.TempPath, recalculateMeta,
|
||||
current == modManager.Collections.ActiveCollection );
|
||||
_menu.InstalledTab.Selector.Cache.TriggerFilterReset();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ public partial class SettingsInterface
|
|||
CollectionsTab.Draw();
|
||||
_importTab.Draw();
|
||||
|
||||
if( Service< ModManager >.Get().Valid && !_importTab.IsImporting() )
|
||||
if( Penumbra.ModManager.Valid && !_importTab.IsImporting() )
|
||||
{
|
||||
_browserTab.Draw();
|
||||
InstalledTab.Draw();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue